From ca21f93d52ba6ebf013ce0620820d59c61779f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 17 Nov 2017 13:36:48 +0100 Subject: [PATCH] GPU: Advance the vertex pointer after BBOX vertices are sent. Fixes #6554, finally! --- GPU/Common/DrawEngineCommon.cpp | 13 ++++++++++--- GPU/Common/DrawEngineCommon.h | 5 ++--- GPU/Common/SplineCommon.cpp | 2 ++ GPU/GPUCommon.cpp | 18 +++++++++++------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index e3a0335456e3..e17111fa0627 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -140,9 +140,11 @@ void DrawEngineCommon::Resized() { ClearTrackedVertexArrays(); } -u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType) { +u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize) { const u32 vertTypeID = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24); VertexDecoder *dec = GetVertexDecoder(vertTypeID); + if (vertexSize) + *vertexSize = dec->VertexSize(); return DrawEngineCommon::NormalizeVertices(outPtr, bufPtr, inPtr, dec, lowerBound, upperBound, vertType); } @@ -150,7 +152,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, // // It does the simplest and safest test possible: If all points of a bbox is outside a single of // our clipping planes, we reject the box. Tighter bounds would be desirable but would take more calculations. -bool DrawEngineCommon::TestBoundingBox(void* control_points, int vertexCount, u32 vertType) { +bool DrawEngineCommon::TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead) { SimpleVertex *corners = (SimpleVertex *)(decoded + 65536 * 12); float *verts = (float *)(decoded + 65536 * 18); @@ -158,25 +160,30 @@ bool DrawEngineCommon::TestBoundingBox(void* control_points, int vertexCount, u3 // and a large vertex format. if ((vertType & 0xFFFFFF) == GE_VTYPE_POS_FLOAT) { verts = (float *)control_points; + *bytesRead = 3 * sizeof(float) * vertexCount; } else if ((vertType & 0xFFFFFF) == GE_VTYPE_POS_8BIT) { const s8 *vtx = (const s8 *)control_points; for (int i = 0; i < vertexCount * 3; i++) { verts[i] = vtx[i] * (1.0f / 128.0f); } + *bytesRead = 3 * sizeof(s8) * vertexCount; } else if ((vertType & 0xFFFFFF) == GE_VTYPE_POS_16BIT) { const s16 *vtx = (const s16*)control_points; for (int i = 0; i < vertexCount * 3; i++) { verts[i] = vtx[i] * (1.0f / 32768.0f); } + *bytesRead = 3 * sizeof(s16) * vertexCount; } else { // Simplify away bones and morph before proceeding u8 *temp_buffer = decoded + 65536 * 24; - NormalizeVertices((u8 *)corners, temp_buffer, (u8 *)control_points, 0, vertexCount, vertType); + int vertexSize = 0; + NormalizeVertices((u8 *)corners, temp_buffer, (u8 *)control_points, 0, vertexCount, vertType, &vertexSize); for (int i = 0; i < vertexCount; i++) { verts[i * 3] = corners[i].pos.x; verts[i * 3 + 1] = corners[i].pos.y; verts[i * 3 + 2] = corners[i].pos.z; } + *bytesRead = vertexSize * vertexCount; } Plane planes[6]; diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index fe40686ef4a0..39a53bb83a9b 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -49,8 +49,6 @@ class DrawEngineCommon { DrawEngineCommon(); virtual ~DrawEngineCommon(); - bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType); - bool GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices); static u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoder *dec, int lowerBound, int upperBound, u32 vertType); @@ -61,6 +59,7 @@ class DrawEngineCommon { // Same for SubmitPrim virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) = 0; + bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead); void SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead); void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead); @@ -79,7 +78,7 @@ class DrawEngineCommon { virtual void ClearTrackedVertexArrays() {} // Preprocessing for spline/bezier - u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType); + u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize = nullptr); // Utility for vertex caching u32 ComputeMiniHash(); diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 8e428b695eee..9afe34aea814 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -855,6 +855,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi GetIndexBounds(indices, count_u * count_v, vertType, &index_lower_bound, &index_upper_bound); VertexDecoder *origVDecoder = GetVertexDecoder((vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24)); + // TODO: If indexing is on, this may be wrong! *bytesRead = count_u * count_v * origVDecoder->VertexSize(); // Real hardware seems to draw nothing when given < 4 either U or V. @@ -971,6 +972,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi GetIndexBounds(indices, count_u*count_v, vertType, &index_lower_bound, &index_upper_bound); VertexDecoder *origVDecoder = GetVertexDecoder((vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24)); + // TODO: If indexing is on, this may be wrong! *bytesRead = count_u * count_v * origVDecoder->VertexSize(); // Real hardware seems to draw nothing when given < 4 either U or V. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 0578ec7bf736..4a836550f183 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1505,13 +1505,17 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) { // Just resetting, nothing to check bounds for. - const u32 data = op & 0x00FFFFFF; - if (data == 0) { + const u32 count = op & 0xFFFFFF; + if (count == 0) { currentList->bboxResult = false; return; } - if (((data & 7) == 0) && data <= 64) { // Sanity check + if (((count & 7) == 0) && count <= 64) { // Sanity check void *control_points = Memory::GetPointer(gstate_c.vertexAddr); + if (!control_points) { + return; + } + if (gstate.vertType & GE_VTYPE_IDX_MASK) { ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Indexed bounding box data not supported."); // Data seems invalid. Let's assume the box test passed. @@ -1520,11 +1524,11 @@ void GPUCommon::Execute_BoundingBox(u32 op, u32 diff) { } // Test if the bounding box is within the drawing region. - if (control_points) { - currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, data, gstate.vertType); - } + int bytesRead; + currentList->bboxResult = drawEngineCommon_->TestBoundingBox(control_points, count, gstate.vertType, &bytesRead); + AdvanceVerts(gstate.vertType, count, bytesRead); } else { - ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Bad bounding box data: %06x", data); + ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Bad bounding box data: %06x", count); // Data seems invalid. Let's assume the box test passed. currentList->bboxResult = true; }