Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PPGe: Use texture windows for atlas text #18126

Merged
merged 1 commit into from
Sep 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PPGe: Use texture windows for atlas text.
This makes it software rendering, which correctly applies clamp/wrap
limits at 512x512, still has readable text.  Other textures may still be
wrong.
unknownbrackets committed Sep 11, 2023
commit 3c7b05c3e83ee297e85bd70352a22f0859c1a455
71 changes: 55 additions & 16 deletions Core/Util/PPGeDraw.cpp
Original file line number Diff line number Diff line change
@@ -197,9 +197,11 @@ static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color

static void EndVertexDataAndDraw(int prim) {
_assert_msg_(vertexStart != 0, "Missing matching call to BeginVertexData()");
NotifyMemInfo(MemBlockFlags::WRITE, vertexStart, dataWritePtr - vertexStart, "PPGe Vertex");
WriteCmdAddrWithBase(GE_CMD_VADDR, vertexStart);
WriteCmd(GE_CMD_PRIM, (prim << 16) | vertexCount);
if (vertexCount != 0) {
NotifyMemInfo(MemBlockFlags::WRITE, vertexStart, dataWritePtr - vertexStart, "PPGe Vertex");
WriteCmdAddrWithBase(GE_CMD_VADDR, vertexStart);
WriteCmd(GE_CMD_PRIM, (prim << 16) | vertexCount);
}
vertexStart = 0;
}

@@ -822,30 +824,67 @@ static void PPGeResetCurrentText() {
char_lines_metrics = zeroBox;
}

// Draws some text using the one font we have.
// Mostly rewritten.
void PPGeDrawCurrentText(u32 color)
{
if (dlPtr)
{
// Draws some text using the one font we have in the atlas.
void PPGeDrawCurrentText(u32 color) {
// If the atlas is larger than 512x512, need to use windows into it.
bool useTextureWindow = atlasWidth > 512 || atlasHeight > 512;
uint32_t texturePosX = 0;
uint32_t texturePosY = 0;

// Use half the available size just in case a character straddles a boundary.
const float textureMaxPosX = !useTextureWindow ? 1.0f : atlasWidth / 256.0f;
const float textureMaxPosY = !useTextureWindow ? 1.0f : atlasHeight / 256.0f;
// These are the actual scale used.
const float textureWindowW = !useTextureWindow ? atlasWidth : 512.0f;
const float textureWindowH = !useTextureWindow ? atlasHeight : 512.0f;
const float textureScaleX = !useTextureWindow ? 1.0f : atlasWidth / 512.0f;
const float textureScaleY = !useTextureWindow ? 1.0f : atlasWidth / 512.0f;

if (dlPtr) {
float scale = char_lines_metrics.scale;

if (useTextureWindow) {
WriteCmd(GE_CMD_TEXWRAP, 0);
WriteCmd(GE_CMD_TEXSIZE0, 9 | (9 << 8));
}

BeginVertexData();
for (auto i = char_lines.begin(); i != char_lines.end(); ++i)
{
for (auto j = i->begin(); j != i->end(); ++j)
{
for (auto i = char_lines.begin(); i != char_lines.end(); ++i) {
for (auto j = i->begin(); j != i->end(); ++j) {
const AtlasChar &c = *j->c;

int wantedPosX = (int)floorf(c.sx * textureMaxPosX);
int wantedPosY = (int)floorf(c.sy * textureMaxPosY);
if (useTextureWindow && wantedPosX != texturePosX || wantedPosY != texturePosY) {
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);

uint32_t offset = atlasWidth * wantedPosY * 256 + wantedPosX * 256;
WriteCmd(GE_CMD_TEXADDR0, (atlasPtr & 0xFFFFF0) + offset / 2);
texturePosX = wantedPosX;
texturePosY = wantedPosY;

BeginVertexData();
}

float sx = (c.sx - texturePosX / textureMaxPosX) * textureScaleX;
float sy = (c.sy - texturePosY / textureMaxPosY) * textureScaleY;
float ex = (c.ex - texturePosX / textureMaxPosX) * textureScaleX;
float ey = (c.ey - texturePosY / textureMaxPosY) * textureScaleY;

float cx1 = j->x;
float cy1 = j->y;
const AtlasChar &c = *j->c;
float cx2 = cx1 + c.pw * scale;
float cy2 = cy1 + c.ph * scale;
Vertex(cx1, cy1, c.sx, c.sy, atlasWidth, atlasHeight, color);
Vertex(cx2, cy2, c.ex, c.ey, atlasWidth, atlasHeight, color);
Vertex(cx1, cy1, sx, sy, textureWindowW, textureWindowH, color);
Vertex(cx2, cy2, ex, ey, textureWindowW, textureWindowH, color);
}
}
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}
PPGeResetCurrentText();
if (useTextureWindow) {
PPGeSetDefaultTexture();
}
}

// Return a value such that (1 << value) >= x
2 changes: 1 addition & 1 deletion GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
@@ -2801,7 +2801,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
plan.w = gstate.getTextureWidth(0);
plan.h = gstate.getTextureHeight(0);

bool isPPGETexture = entry->addr > 0x05000000 && entry->addr < PSP_GetKernelMemoryEnd();
bool isPPGETexture = entry->addr >= PSP_GetKernelMemoryBase() && entry->addr < PSP_GetKernelMemoryEnd();

// Don't scale the PPGe texture.
if (isPPGETexture) {