fix(gx): correct improper batching of strings in BATCHEDRENDERFONTDESC::RenderBatch

This commit is contained in:
fallenoak 2025-12-20 15:03:52 -06:00
parent 3643263ce9
commit fe217c3ac3
No known key found for this signature in database
GPG Key ID: 7628F8E61AEA070D

View File

@ -140,8 +140,9 @@ void BATCHEDRENDERFONTDESC::RenderBatch() {
} }
int32_t maxBatchCapacity = 2048; int32_t maxBatchCapacity = 2048;
int32_t batchCapacity = maxBatchCapacity;
CGxBuf* vertexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Vertex, 0x18, maxBatchCapacity); CGxBuf* vertexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Vertex, sizeof(CGxVertexPCT), maxBatchCapacity);
char* vertexData = g_theGxDevicePtr->BufLock(vertexStream); char* vertexData = g_theGxDevicePtr->BufLock(vertexStream);
CGxVertexPCT* vertexBuf = reinterpret_cast<CGxVertexPCT*>(vertexData); CGxVertexPCT* vertexBuf = reinterpret_cast<CGxVertexPCT*>(vertexData);
@ -149,47 +150,53 @@ void BATCHEDRENDERFONTDESC::RenderBatch() {
auto& textureCache = this->m_face->m_textureCache[i]; auto& textureCache = this->m_face->m_textureCache[i];
auto texture = textureCache.m_texture; auto texture = textureCache.m_texture;
if (texture) { if (!texture) {
continue;
}
auto gxTex = TextureGetGxTex(reinterpret_cast<CTexture*>(texture), 1, nullptr); auto gxTex = TextureGetGxTex(reinterpret_cast<CTexture*>(texture), 1, nullptr);
if (gxTex) { if (!gxTex) {
continue;
}
GxRsSet(GxRs_Texture0, gxTex); GxRsSet(GxRs_Texture0, gxTex);
for (auto string = this->m_strings.Head(); string; string = this->m_strings.Next(string)) { for (auto string = this->m_strings.Head(); string; string = this->m_strings.Next(string)) {
auto line = string->m_textLines[i]; auto line = string->m_textLines[i];
if (line) { if (!line) {
continue;
}
int32_t vertsNeeded = string->CalculateVertsNeeded(i); int32_t vertsNeeded = string->CalculateVertsNeeded(i);
int32_t batchOffset = 0; int32_t sliceOffset = 0;
int32_t batchCapacity = maxBatchCapacity;
while (vertsNeeded) { while (vertsNeeded) {
int32_t batchCount = std::min(vertsNeeded, batchCapacity); int32_t sliceSize = std::min(vertsNeeded, batchCapacity);
string->WriteGeometry(vertexBuf, i, batchOffset, batchCount); string->WriteGeometry(vertexBuf, i, sliceOffset, sliceSize);
vertsNeeded -= batchCount; vertsNeeded -= sliceSize;
batchOffset += batchCount; sliceOffset += sliceSize;
batchCapacity -= batchCount; batchCapacity -= sliceSize;
vertexBuf += batchCount; vertexBuf += sliceSize;
if (!batchCapacity) { if (!batchCapacity) {
vertexBuf = this->UnlockVertexPtrAndRender(vertexStream, maxBatchCapacity); vertexBuf = this->UnlockVertexPtrAndRender(vertexStream, maxBatchCapacity);
batchCapacity = maxBatchCapacity; batchCapacity = maxBatchCapacity;
} }
} }
}
// Render used portion of buffer and reset
if (batchCapacity != maxBatchCapacity) { if (batchCapacity != maxBatchCapacity) {
vertexBuf = this->UnlockVertexPtrAndRender(vertexStream, maxBatchCapacity - batchCapacity); vertexBuf = this->UnlockVertexPtrAndRender(vertexStream, maxBatchCapacity - batchCapacity);
batchCapacity = maxBatchCapacity; batchCapacity = maxBatchCapacity;
} }
} }
}
}
}
}
g_theGxDevicePtr->BufUnlock(vertexStream, 0); GxBufUnlock(vertexStream, 0);
} }
CGxStringBatch::~CGxStringBatch() { CGxStringBatch::~CGxStringBatch() {