diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 940a1c3bb9..2fc921dc37 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -90,6 +90,12 @@ static Vec3f ScreenToDrawing(const Vec3f& coords) { return ret; } +u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType) { + const u32 vertTypeID = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24); + VertexDecoder *dec = GetVertexDecoder(vertTypeID); + return DrawEngineCommon::NormalizeVertices(outPtr, bufPtr, inPtr, dec, lowerBound, upperBound, vertType); +} + // This code is HIGHLY unoptimized! // // It does the simplest and safest test possible: If all points of a bbox is outside a single of diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index a71eb502d3..a100e728b4 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -51,8 +51,8 @@ public: // Same for SubmitPrim virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) = 0; - 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, u32 vertType); - void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, u32 vertType); + 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); + 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); protected: // Preprocessing for spline/bezier diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index b73cc90eb0..435c5d317d 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -15,13 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -/* -#define WIN32_LEAN_AND_MEAN -#include -#undef min -#undef max -*/ - #include #include @@ -33,7 +26,7 @@ #include "GPU/Common/SplineCommon.h" #include "GPU/Common/DrawEngineCommon.h" #include "GPU/ge_constants.h" -#include "GPU/GPUState.h" +#include "GPU/GPUState.h" // only needed for UVScale stuff #if defined(_M_SSE) #include @@ -228,7 +221,9 @@ static void _SplinePatchLowQuality(u8 *&dest, u16 *indices, int &count, const Sp tu_width /= (float)(tile_max_u - tile_min_u); tv_height /= (float)(tile_max_v - tile_min_v); - GEPatchPrimType prim_type = gstate.getPatchPrimitiveType(); + GEPatchPrimType prim_type = spatch.primType; + bool computeNormals = spatch.computeNormals; + bool patchFacing = spatch.patchFacing; int i = 0; for (int tile_v = tile_min_v; tile_v < tile_max_v; ++tile_v) { @@ -257,10 +252,10 @@ static void _SplinePatchLowQuality(u8 *&dest, u16 *indices, int &count, const Sp // Generate normal if lighting is enabled (otherwise there's no point). // This is a really poor quality algorithm, we get facet normals. - if (gstate.isLightingEnabled()) { + if (computeNormals) { Vec3Packedf norm = Cross(v1.pos - v0.pos, v2.pos - v0.pos); norm.Normalize(); - if (gstate.patchfacing & 1) + if (patchFacing) norm *= -1.0f; v0.nrm = norm; v1.nrm = norm; @@ -446,9 +441,9 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp delete[] knot_v; // Hacky normal generation through central difference. - if (gstate.isLightingEnabled() && !origNrm) { + if (spatch.computeNormals && !origNrm) { #ifdef _M_SSE - const __m128 facing = (gstate.patchfacing & 1) != 0 ? _mm_set_ps1(-1.0f) : _mm_set_ps1(1.0f); + const __m128 facing = spatch.patchFacing ? _mm_set_ps1(-1.0f) : _mm_set_ps1(1.0f); #endif for (int v = 0; v < patch_div_t + 1; v++) { @@ -480,7 +475,7 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp const Vec3Packedf &down = vertices[b * (patch_div_s + 1) + u].pos - vertices[t * (patch_div_s + 1) + u].pos; vertices[v * (patch_div_s + 1) + u].nrm = Cross(right, down).Normalized(); - if (gstate.patchfacing & 1) { + if (spatch.patchfacing) { vertices[v * (patch_div_s + 1) + u].nrm *= -1.0f; } #endif @@ -492,7 +487,7 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp } } - GEPatchPrimType prim_type = gstate.getPatchPrimitiveType(); + GEPatchPrimType prim_type = spatch.primType; // Tesselate. for (int tile_v = 0; tile_v < patch_div_t; ++tile_v) { for (int tile_u = 0; tile_u < patch_div_s; ++tile_u) { @@ -566,7 +561,7 @@ static void _BezierPatchLowQuality(u8 *&dest, u16 *&indices, int &count, int tes float u_base = patch.u_index / 3.0f; float v_base = patch.v_index / 3.0f; - GEPatchPrimType prim_type = gstate.getPatchPrimitiveType(); + GEPatchPrimType prim_type = patch.primType; for (int tile_v = 0; tile_v < 3; tile_v++) { for (int tile_u = 0; tile_u < 3; tile_u++) { @@ -593,10 +588,10 @@ static void _BezierPatchLowQuality(u8 *&dest, u16 *&indices, int &count, int tes // Generate normal if lighting is enabled (otherwise there's no point). // This is a really poor quality algorithm, we get facet normals. - if (gstate.isLightingEnabled()) { + if (patch.computeNormals) { Vec3Packedf norm = Cross(v1.pos - v0.pos, v2.pos - v0.pos); norm.Normalize(); - if (gstate.patchfacing & 1) + if (patch.patchFacing) norm *= -1.0f; v0.nrm = norm; v1.nrm = norm; @@ -641,7 +636,7 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te Vec3Packedf *derivU3 = derivU1 + (tess_u + 1) * 2; Vec3Packedf *derivU4 = derivU1 + (tess_u + 1) * 3; - bool computeNormals = gstate.isLightingEnabled(); + bool computeNormals = patch.computeNormals; // Precompute the horizontal curves to we only have to evaluate the vertical ones. for (int i = 0; i < tess_u + 1; i++) { @@ -685,7 +680,7 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te Vec3Packedf derivV = Bernstein3DDerivative(pos1, pos2, pos3, pos4, bv); vert.nrm = Cross(derivU, derivV).Normalized(); - if (gstate.patchfacing & 1) + if (patch.patchFacing) vert.nrm *= -1.0f; } else { @@ -713,7 +708,7 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te delete[] derivU1; delete[] horiz; - GEPatchPrimType prim_type = gstate.getPatchPrimitiveType(); + GEPatchPrimType prim_type = patch.primType; // Combine the vertices into triangles. for (int tile_v = 0; tile_v < tess_v; ++tile_v) { for (int tile_u = 0; tile_u < tess_u; ++tile_u) { @@ -745,15 +740,9 @@ void TesselateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int } -u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType) { - const u32 vertTypeID = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24); - VertexDecoder *dec = GetVertexDecoder(vertTypeID); - return DrawEngineCommon::NormalizeVertices(outPtr, bufPtr, inPtr, dec, lowerBound, upperBound, vertType); -} - const GEPrimitiveType primType[] = { GE_PRIM_TRIANGLES, GE_PRIM_LINES, GE_PRIM_POINTS }; -void DrawEngineCommon::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, u32 vertType) { +void DrawEngineCommon::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) { PROFILE_THIS_SCOPE("spline"); DispatchFlush(); @@ -807,6 +796,8 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi patch.count_v = count_v; patch.points = points; patch.computeNormals = computeNormals; + patch.primType = prim_type; + patch.patchFacing = patchFacing; int maxVertexCount = SPLINE_BUFFER_SIZE / vertexSize; TesselateSplinePatch(dest, quadIndices_, count, patch, origVertType, maxVertexCount); @@ -835,7 +826,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi } } -void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, u32 vertType) { +void DrawEngineCommon::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) { PROFILE_THIS_SCOPE("bezier"); DispatchFlush(); @@ -884,6 +875,9 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi patch.u_index = patch_u * 3; patch.v_index = patch_v * 3; patch.index = patch_v * num_patches_u + patch_u; + patch.primType = prim_type; + patch.computeNormals = computeNormals; + patch.patchFacing = patchFacing; } } diff --git a/GPU/Common/SplineCommon.h b/GPU/Common/SplineCommon.h index 428f617fb5..978537cfde 100644 --- a/GPU/Common/SplineCommon.h +++ b/GPU/Common/SplineCommon.h @@ -19,6 +19,7 @@ #include "Common/CommonTypes.h" #include "GPU/Math3D.h" +#include "GPU/ge_constants.h" // PSP compatible format so we can use the end of the pipeline in beziers etc struct SimpleVertex { @@ -55,6 +56,9 @@ struct BezierPatch { int u_index, v_index; int index; + GEPatchPrimType primType; + bool computeNormals; + bool patchFacing; struct SamplingParams { float fracU; @@ -116,6 +120,8 @@ struct SplinePatchLocal { int type_u; int type_v; bool computeNormals; + bool patchFacing; + GEPatchPrimType primType; }; enum quality { diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 458755230f..900f9873b0 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -832,7 +832,9 @@ void DIRECTX9_GPU::Execute_Bezier(u32 op, u32 diff) { GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); int bz_ucount = op & 0xFF; int bz_vcount = (op >> 8) & 0xFF; - transformDraw_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, gstate.vertType); + bool computeNormals = gstate.isLightingEnabled(); + bool patchFacing = gstate.patchfacing & 1; + transformDraw_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType); } void DIRECTX9_GPU::Execute_Spline(u32 op, u32 diff) { @@ -876,7 +878,9 @@ void DIRECTX9_GPU::Execute_Spline(u32 op, u32 diff) { int sp_vtype = (op >> 18) & 0x3; GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); bool computeNormals = gstate.isLightingEnabled(); - transformDraw_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, gstate.vertType); + bool patchFacing = gstate.patchfacing & 1; + u32 vertType = gstate.vertType; + transformDraw_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType); } void DIRECTX9_GPU::Execute_ViewportType(u32 op, u32 diff) { diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index 48bcb449db..4fab1d65fb 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -917,7 +917,9 @@ void GLES_GPU::Execute_Bezier(u32 op, u32 diff) { GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); int bz_ucount = op & 0xFF; int bz_vcount = (op >> 8) & 0xFF; - transformDraw_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(),bz_ucount, bz_vcount, patchPrim, gstate.vertType); + bool computeNormals = gstate.isLightingEnabled(); + bool patchFacing = gstate.patchfacing & 1; + transformDraw_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType); } void GLES_GPU::Execute_Spline(u32 op, u32 diff) { @@ -961,7 +963,9 @@ void GLES_GPU::Execute_Spline(u32 op, u32 diff) { int sp_vtype = (op >> 18) & 0x3; GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); bool computeNormals = gstate.isLightingEnabled(); - transformDraw_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, gstate.vertType); + bool patchFacing = gstate.patchfacing & 1; + u32 vertType = gstate.vertType; + transformDraw_.SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType); } void GLES_GPU::Execute_BoundingBox(u32 op, u32 diff) { diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index d8ea168b7f..6ea653df95 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -213,8 +213,7 @@ struct SplinePatch { SplinePatch *TransformUnit::patchBuffer_ = 0; int TransformUnit::patchBufferSize_ = 0; -void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type) -{ +void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type) { VertexDecoder vdecoder; VertexDecoderOptions options; memset(&options, 0, sizeof(options));