diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 06b896be8ace..8905653757f7 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -86,11 +86,11 @@ class Bezier3DWeight { return weights; } - u32 ToKey(int tess, int count, int type) { + static u32 ToKey(int tess, int count, int type) { return tess; } - int CalcSize(int tess, int count) { + static int CalcSize(int tess, int count) { return tess + 1; } }; @@ -228,25 +228,25 @@ class Spline3DWeight { return weights; } - u32 ToKey(int tess, int count, int type) { + static u32 ToKey(int tess, int count, int type) { return tess | (count << 8) | (type << 16); } - void FromKey(u32 key, int &tess, int &count, int &type) { + static void FromKey(u32 key, int &tess, int &count, int &type) { tess = key & 0xFF; count = (key >> 8) & 0xFF; type = (key >> 16) & 0xFF; } - int CalcSize(int tess, int count) { + static int CalcSize(int tess, int count) { return (count - 3) * tess + 1; } }; -static WeightCache bezierWeightsCache; -static WeightCache splineWeightsCache; +template +static WeightCache weightsCache; void DrawEngineCommon::ClearSplineBezierWeights() { - bezierWeightsCache.Clear(); - splineWeightsCache.Clear(); + weightsCache.Clear(); + weightsCache.Clear(); } bool CanUseHardwareTessellation(GEPatchPrimType prim) { @@ -428,25 +428,27 @@ class SubdivisionSurface { } }; -template +template static void SoftwareTessellation(OutputBuffers &output, const Patch &patch, u32 origVertType, - const SimpleVertex *const *points, SimpleBufferManager &managedBuf, Cache &weightsCache) { - u32 key_u = weightsCache.ToKey(patch.tess_u, patch.count_u, patch.type_u); - u32 key_v = weightsCache.ToKey(patch.tess_v, patch.count_v, patch.type_v); - Weight2D weights(weightsCache, key_u, key_v); + const SimpleVertex *const *points, SimpleBufferManager &managedBuf) { + using WeightType = Patch::WeightType; + u32 key_u = WeightType::ToKey(patch.tess_u, patch.count_u, patch.type_u); + u32 key_v = WeightType::ToKey(patch.tess_v, patch.count_v, patch.type_v); + Weight2D weights(weightsCache, key_u, key_v); SubdivisionSurface surface(managedBuf, points, patch, weights); surface.Tessellate(output, origVertType); } -template +template static void HardwareTessellation(OutputBuffers &output, const Patch &patch, u32 origVertType, - const SimpleVertex *const *points, Cache &weightsCache, TessellationDataTransfer *tessDataTransfer) { - u32 key_u = weightsCache.ToKey(patch.tess_u, patch.count_u, patch.type_u); - u32 key_v = weightsCache.ToKey(patch.tess_v, patch.count_v, patch.type_v); - Weight2D weights(weightsCache, key_u, key_v); - weights.size_u = weightsCache.CalcSize(patch.tess_u, patch.count_u); - weights.size_v = weightsCache.CalcSize(patch.tess_v, patch.count_v); + const SimpleVertex *const *points, TessellationDataTransfer *tessDataTransfer) { + using WeightType = Patch::WeightType; + u32 key_u = WeightType::ToKey(patch.tess_u, patch.count_u, patch.type_u); + u32 key_v = WeightType::ToKey(patch.tess_v, patch.count_v, patch.type_v); + Weight2D weights(weightsCache, key_u, key_v); + weights.size_u = WeightType::CalcSize(patch.tess_u, patch.count_u); + weights.size_v = WeightType::CalcSize(patch.tess_v, patch.count_v); tessDataTransfer->SendDataToShader(points, patch.count_u * patch.count_v, origVertType, weights); // Generating simple input vertices for the spline-computing vertex shader. @@ -525,11 +527,11 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi patch.patchFacing = patchFacing; if (CanUseHardwareTessellation(prim_type)) { - HardwareTessellation(output, patch, origVertType, points, splineWeightsCache, tessDataTransfer); + HardwareTessellation(output, patch, origVertType, points, tessDataTransfer); numPatches = patch.num_patches_u * patch.num_patches_v; } else { patch.Init(SPLINE_BUFFER_SIZE / vertexSize); - SoftwareTessellation(output, patch, origVertType, points, managedBuf, splineWeightsCache); + SoftwareTessellation(output, patch, origVertType, points, managedBuf); } u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT; @@ -616,11 +618,11 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi patch.patchFacing = patchFacing; if (CanUseHardwareTessellation(prim_type)) { - HardwareTessellation(output, patch, origVertType, points, bezierWeightsCache, tessDataTransfer); + HardwareTessellation(output, patch, origVertType, points, tessDataTransfer); numPatches = patch.num_patches_u * patch.num_patches_v; } else { patch.Init(SPLINE_BUFFER_SIZE / vertexSize); - SoftwareTessellation(output, patch, origVertType, points, managedBuf, bezierWeightsCache); + SoftwareTessellation(output, patch, origVertType, points, managedBuf); } u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT; diff --git a/GPU/Common/SplineCommon.h b/GPU/Common/SplineCommon.h index bcb23e76b285..0b44413cfe1a 100644 --- a/GPU/Common/SplineCommon.h +++ b/GPU/Common/SplineCommon.h @@ -45,9 +45,14 @@ enum SplineQuality { HIGH_QUALITY = 2, }; +class Bezier3DWeight; +class Spline3DWeight; + // We decode all vertices into a common format for easy interpolation and stuff. // Not fast but can be optimized later. struct BezierPatch { + using WeightType = Bezier3DWeight; + int tess_u; int tess_v; int count_u; @@ -104,6 +109,8 @@ struct BezierPatch { }; struct SplinePatchLocal { + using WeightType = Spline3DWeight; + int tess_u; int tess_v; int count_u;