From a344d0225f2c2cc7337c0d841e4e48bac2b95969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 20 Dec 2024 20:00:06 +0100 Subject: [PATCH] DepthRaster: Fix bug where we used the wrong vertex count. --- GPU/Common/DepthRaster.cpp | 13 +++++++++---- GPU/Common/DepthRaster.h | 2 +- GPU/Common/DrawEngineCommon.cpp | 20 ++++++++++++++++---- GPU/Common/DrawEngineCommon.h | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/GPU/Common/DepthRaster.cpp b/GPU/Common/DepthRaster.cpp index b0bbb44d27..0810f1778c 100644 --- a/GPU/Common/DepthRaster.cpp +++ b/GPU/Common/DepthRaster.cpp @@ -161,6 +161,8 @@ void DepthRasterTriangle(uint16_t *depthBuf, int stride, int x1, int y1, int x2, // END triangle setup. + // Here we should draw four triangles in a sequence. + // Incrementally compute Fab(x, y) for all the pixels inside the bounding box formed by (startX, endX) and (startY, endY) for (int r = startY; r < endY; r++, row++, @@ -211,7 +213,7 @@ void DepthRasterTriangle(uint16_t *depthBuf, int stride, int x1, int y1, int x2, } // for each row } -void DecodeAndTransformForDepthRaster(float *dest, GEPrimitiveType prim, const float *worldviewproj, const void *vertexData, int count, VertexDecoder *dec, u32 vertTypeID) { +void DecodeAndTransformForDepthRaster(float *dest, GEPrimitiveType prim, const float *worldviewproj, const void *vertexData, int indexLowerBound, int indexUpperBound, VertexDecoder *dec, u32 vertTypeID) { // TODO: Ditch skinned and morphed prims for now since we don't have a fast way to skin without running the full decoder. _dbg_assert_((vertTypeID & (GE_VTYPE_WEIGHT_MASK | GE_VTYPE_MORPHCOUNT_MASK)) == 0); @@ -220,22 +222,25 @@ void DecodeAndTransformForDepthRaster(float *dest, GEPrimitiveType prim, const f Mat4F32 mat(worldviewproj); + const u8 *startPtr = (const u8 *)vertexData + indexLowerBound * vertexStride; + int count = indexUpperBound - indexLowerBound + 1; + switch (vertTypeID & GE_VTYPE_POS_MASK) { case GE_VTYPE_POS_FLOAT: for (int i = 0; i < count; i++) { - const float *data = (const float *)((const u8 *)vertexData + vertexStride * i + offset); + const float *data = (const float *)(startPtr + i * vertexStride + offset); Vec4F32::Load(data).AsVec3ByMatrix44(mat).Store(dest + i * 4); } break; case GE_VTYPE_POS_16BIT: for (int i = 0; i < count; i++) { - const s16 *data = ((const s16 *)((const s8 *)vertexData + i * vertexStride + offset)); + const s16 *data = ((const s16 *)((const s8 *)startPtr + i * vertexStride + offset)); Vec4F32::LoadConvertS16(data).Mul(1.0f / 32768.f).AsVec3ByMatrix44(mat).Store(dest + i * 4); } break; case GE_VTYPE_POS_8BIT: for (int i = 0; i < count; i++) { - const s8 *data = (const s8 *)vertexData + i * vertexStride + offset; + const s8 *data = (const s8 *)startPtr + i * vertexStride + offset; Vec4F32::LoadConvertS8(data).Mul(1.0f / 128.0f).AsVec3ByMatrix44(mat).Store(dest + i * 4); } break; diff --git a/GPU/Common/DepthRaster.h b/GPU/Common/DepthRaster.h index 50e7a2577d..e92c1a1348 100644 --- a/GPU/Common/DepthRaster.h +++ b/GPU/Common/DepthRaster.h @@ -18,6 +18,6 @@ class VertexDecoder; struct TransformedVertex; int DepthRasterClipIndexedTriangles(int *tx, int *ty, int *tz, const float *transformed, const uint16_t *indexBuffer, int count); -void DecodeAndTransformForDepthRaster(float *dest, GEPrimitiveType prim, const float *worldviewproj, const void *vertexData, int count, VertexDecoder *dec, u32 vertTypeID); +void DecodeAndTransformForDepthRaster(float *dest, GEPrimitiveType prim, const float *worldviewproj, const void *vertexData, int indexLowerBound, int indexUpperBound, VertexDecoder *dec, u32 vertTypeID); void DepthRasterConvertTransformed(int *tx, int *ty, int *tz, GEPrimitiveType prim, const TransformedVertex *transformed, int count); void DepthRasterScreenVerts(uint16_t *depth, int depthStride, GEPrimitiveType prim, int x1, int y1, int x2, int y2, const int *tx, const int *ty, const int *tz, int count); diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 70da71a8fa..bbe36fb479 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -903,7 +903,7 @@ bool DrawEngineCommon::DescribeCodePtr(const u8 *ptr, std::string &name) const { } } -void DrawEngineCommon::DepthRasterTransform(GEPrimitiveType prim, VertexDecoder *dec, uint32_t vertTypeID) { +void DrawEngineCommon::DepthRasterTransform(GEPrimitiveType prim, VertexDecoder *dec, uint32_t vertTypeID, int vertexCount) { switch (prim) { case GE_PRIM_INVALID: case GE_PRIM_KEEP_PREVIOUS: @@ -931,8 +931,20 @@ void DrawEngineCommon::DepthRasterTransform(GEPrimitiveType prim, VertexDecoder // Decode. int numDec = 0; for (int i = 0; i < numDrawVerts_; i++) { - DecodeAndTransformForDepthRaster(depthTransformed_ + numDec * 4, prim, worldviewproj, drawVerts_[i].verts, drawVerts_[i].vertexCount, dec, vertTypeID); - numDec += drawVerts_[i].vertexCount; + DeferredVerts &dv = drawVerts_[i]; + + int indexLowerBound = dv.indexLowerBound; + drawVertexOffsets_[i] = numDec - indexLowerBound; + + int indexUpperBound = dv.indexUpperBound; + if (indexUpperBound + 1 - indexLowerBound + numDec >= VERTEX_BUFFER_MAX) { + // Hit our limit! Stop decoding in this draw. + break; + } + + // Decode the verts (and at the same time apply morphing/skinning). Simple. + DecodeAndTransformForDepthRaster(depthTransformed_ + numDec * 4, prim, worldviewproj, dv.verts, indexLowerBound, indexUpperBound, dec, vertTypeID); + numDec += indexUpperBound - indexLowerBound + 1; } int *tx = depthScreenVerts_; @@ -940,7 +952,7 @@ void DrawEngineCommon::DepthRasterTransform(GEPrimitiveType prim, VertexDecoder int *tz = depthScreenVerts_ + DEPTH_SCREENVERTS_COMPONENT_COUNT * 2; // Clip and triangulate using the index buffer. - int outVertCount = DepthRasterClipIndexedTriangles(tx, ty, tz, depthTransformed_, decIndex_, numDec); + int outVertCount = DepthRasterClipIndexedTriangles(tx, ty, tz, depthTransformed_, decIndex_, vertexCount); if (outVertCount & 15) { // Zero padding for (int i = outVertCount; i < ((outVertCount + 16) & ~15); i++) { diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 2df31f2fba..053c4c31f5 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -175,7 +175,7 @@ protected: void ApplyFramebufferRead(FBOTexState *fboTexState); - void DepthRasterTransform(GEPrimitiveType prim, VertexDecoder *dec, uint32_t vertTypeID); + void DepthRasterTransform(GEPrimitiveType prim, VertexDecoder *dec, uint32_t vertTypeID, int vertexCount); void DepthRasterPretransformed(GEPrimitiveType prim, const TransformedVertex *inVerts, int count); static inline int IndexSize(u32 vtype) { diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index e1775722ee..ebe3d022df 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -371,7 +371,7 @@ void DrawEngineVulkan::Flush() { renderManager->Draw(descSetIndex, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount); } if (useDepthRaster_) { - DepthRasterTransform(prim, dec_, dec_->VertexType()); + DepthRasterTransform(prim, dec_, dec_->VertexType(), vertexCount); } } else { PROFILE_THIS_SCOPE("soft");