From a48a5b32f087d22b56368cf3ff6866eaf00db2d0 Mon Sep 17 00:00:00 2001 From: xebra Date: Fri, 13 Jul 2018 18:35:44 +0900 Subject: [PATCH] [spline/bezier]Unify hardware tessellation of bezier and spline. --- GPU/Common/DrawEngineCommon.cpp | 2 +- GPU/Common/DrawEngineCommon.h | 13 ++-- GPU/Common/SplineCommon.cpp | 126 +++++++++++++------------------- GPU/D3D11/DrawEngineD3D11.cpp | 55 ++++++++------ GPU/D3D11/DrawEngineD3D11.h | 45 +++++------- GPU/Directx9/DrawEngineDX9.cpp | 8 +- GPU/Directx9/DrawEngineDX9.h | 18 ++--- GPU/GLES/DrawEngineGLES.cpp | 6 +- GPU/GLES/DrawEngineGLES.h | 28 +++---- GPU/Vulkan/DrawEngineVulkan.cpp | 11 +-- GPU/Vulkan/DrawEngineVulkan.h | 28 +++---- 11 files changed, 153 insertions(+), 187 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index abee27048b..0d2a8de032 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -741,7 +741,7 @@ void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, } } -void DrawEngineCommon::TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) { +void TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) { bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0; diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index de8a467f4a..9211905606 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -53,6 +53,12 @@ inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) { struct SimpleVertex; +class TessellationDataTransfer { +public: + void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType); + virtual void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) = 0; +}; + class DrawEngineCommon { public: DrawEngineCommon(); @@ -173,12 +179,5 @@ protected: // Hardware tessellation int numPatches; - class TessellationDataTransfer { - public: - virtual ~TessellationDataTransfer() {} - void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType); - // Send spline/bezier's control points to vertex shader through floating point texture. - virtual void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) = 0; - }; TessellationDataTransfer *tessDataTransfer; }; diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index ea8776ccb8..7e07807228 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -89,6 +89,10 @@ public: u32 ToKey(int tess, int count, int type) { return tess; } + + int CalcSize(int tess, int count) { + return tess + 1; + } }; class Spline3DWeight { @@ -231,6 +235,10 @@ public: 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) { + return (count - 3) * tess + 1; + } }; static WeightCache bezierWeightsCache; @@ -248,28 +256,6 @@ bool CanUseHardwareTessellation(GEPatchPrimType prim) { return false; } -// Prepare mesh of one patch for "Instanced Tessellation". -static void TessellateSplinePatchHardware(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch) { - SimpleVertex *&vertices = (SimpleVertex*&)dest; - - float inv_u = 1.0f / (float)spatch.tess_u; - float inv_v = 1.0f / (float)spatch.tess_v; - - // Generating simple input vertices for the spline-computing vertex shader. - for (int tile_v = 0; tile_v < spatch.tess_v + 1; ++tile_v) { - for (int tile_u = 0; tile_u < spatch.tess_u + 1; ++tile_u) { - SimpleVertex &vert = vertices[tile_v * (spatch.tess_u + 1) + tile_u]; - vert.pos.x = (float)tile_u; - vert.pos.y = (float)tile_v; - // For texcoord generation - vert.nrm.x = (float)tile_u * inv_u; - vert.nrm.y = (float)tile_v * inv_v; - } - } - - BuildIndex(indices, count, spatch.tess_u, spatch.tess_v, spatch.primType); -} - // Tessellate single patch (4x4 control points) template class Tessellator { @@ -309,29 +295,6 @@ public: } }; -// Prepare mesh of one patch for "Instanced Tessellation". -static void TessellateBezierPatchHardware(u8 *&dest, u16 *indices, int &count, int tess_u, int tess_v, GEPatchPrimType primType) { - SimpleVertex *&vertices = (SimpleVertex*&)dest; - - float inv_u = 1.0f / (float)tess_u; - float inv_v = 1.0f / (float)tess_v; - - // Generating simple input vertices for the bezier-computing vertex shader. - for (int tile_v = 0; tile_v < tess_v + 1; ++tile_v) { - for (int tile_u = 0; tile_u < tess_u + 1; ++tile_u) { - SimpleVertex &vert = vertices[tile_v * (tess_u + 1) + tile_u]; - - vert.pos.x = (float)tile_u; - vert.pos.y = (float)tile_v; - // For texcoord generation - vert.nrm.x = (float)tile_u * inv_u; - vert.nrm.y = (float)tile_v * inv_v; - } - } - - BuildIndex(indices, count, tess_u, tess_v, primType); -} - class SimpleBufferManager { private: u8 *buf_; @@ -466,7 +429,8 @@ public: }; template -static void SoftwareTessellation(SimpleVertex *vertices, u16 *indices, int &count, const Patch &patch, int origVertType, const SimpleVertex *const *points, SimpleBufferManager &managedBuf, Cache &weightsCache) { +static void SoftwareTessellation(SimpleVertex *vertices, u16 *indices, int &count, 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); @@ -475,8 +439,31 @@ static void SoftwareTessellation(SimpleVertex *vertices, u16 *indices, int &coun surface.Tessellate(vertices, indices, count, origVertType); } -// This maps GEPatchPrimType to GEPrimitiveType. -const GEPrimitiveType primType[] = { GE_PRIM_TRIANGLES, GE_PRIM_LINES, GE_PRIM_POINTS, GE_PRIM_POINTS }; +template +static void HardwareTessellation(SimpleVertex *vertices, u16 *indices, int &count, 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); + tessDataTransfer->SendDataToShader(points, patch.count_u * patch.count_v, origVertType, weights); + + // Generating simple input vertices for the spline-computing vertex shader. + float inv_u = 1.0f / (float)patch.tess_u; + float inv_v = 1.0f / (float)patch.tess_v; + for (int tile_v = 0; tile_v <= patch.tess_v; ++tile_v) { + for (int tile_u = 0; tile_u <= patch.tess_u; ++tile_u) { + SimpleVertex &vert = vertices[tile_v * (patch.tess_u + 1) + tile_u]; + vert.pos.x = (float)tile_u; + vert.pos.y = (float)tile_v; + // For texcoord generation + vert.nrm.x = (float)tile_u * inv_u; + vert.nrm.y = (float)tile_v * inv_v; + } + } + BuildIndex(indices, count, patch.tess_u, patch.tess_v, patch.primType); +} 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, int *bytesRead) { PROFILE_THIS_SCOPE("spline"); @@ -536,14 +523,8 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi patch.patchFacing = patchFacing; if (CanUseHardwareTessellation(prim_type)) { - const u32 key_u = splineWeightsCache.ToKey(tess_u, count_u, type_u); - const u32 key_v = splineWeightsCache.ToKey(tess_v, count_v, type_v); - Weight2D weights(splineWeightsCache, key_u, key_v); - weights.size_u = (count_u - 3) * tess_u + 1; - weights.size_v = (count_v - 3) * tess_v + 1; - tessDataTransfer->SendDataToShader(points, count_u * count_v, origVertType, weights); - TessellateSplinePatchHardware(dest, quadIndices_, count, patch); - numPatches = (count_u - 3) * (count_v - 3); + HardwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, splineWeightsCache, tessDataTransfer); + numPatches = patch.num_patches_u * patch.num_patches_v; } else { patch.Init(SPLINE_BUFFER_SIZE / vertexSize); SoftwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, managedBuf, splineWeightsCache); @@ -621,27 +602,20 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi u8 *dest = splineBuffer; u16 *inds = quadIndices_; - // Bezier patches share less control points than spline patches. Otherwise they are pretty much the same (except bezier don't support the open/close thing) - int num_patches_u = (count_u - 1) / 3; - int num_patches_v = (count_v - 1) / 3; - if (CanUseHardwareTessellation(prim_type)) { - Weight2D weights(bezierWeightsCache, tess_u, tess_v); - weights.size_u = tess_u + 1; - weights.size_v = tess_v + 1; - tessDataTransfer->SendDataToShader(points, count_u * count_v, origVertType, weights); - TessellateBezierPatchHardware(dest, inds, count, tess_u, tess_v, prim_type); - numPatches = num_patches_u * num_patches_v; - } else { - BezierPatch patch; - patch.tess_u = tess_u; - patch.tess_v = tess_v; - patch.count_u = count_u; - patch.count_v = count_v; - patch.num_patches_u = (count_u - 1) / 3; - patch.num_patches_v = (count_v - 1) / 3; - patch.primType = prim_type; - patch.patchFacing = patchFacing; + BezierPatch patch; + patch.tess_u = tess_u; + patch.tess_v = tess_v; + patch.count_u = count_u; + patch.count_v = count_v; + patch.num_patches_u = (count_u - 1) / 3; + patch.num_patches_v = (count_v - 1) / 3; + patch.primType = prim_type; + patch.patchFacing = patchFacing; + if (CanUseHardwareTessellation(prim_type)) { + HardwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, bezierWeightsCache, tessDataTransfer); + numPatches = patch.num_patches_u * patch.num_patches_v; + } else { patch.Init(SPLINE_BUFFER_SIZE / vertexSize); SoftwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, managedBuf, bezierWeightsCache); } diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 1a77479851..537951fb49 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -111,7 +111,8 @@ void DrawEngineD3D11::InitDeviceObjects() { pushVerts_ = new PushBufferD3D11(device_, VERTEX_PUSH_SIZE, D3D11_BIND_VERTEX_BUFFER); pushInds_ = new PushBufferD3D11(device_, INDEX_PUSH_SIZE, D3D11_BIND_INDEX_BUFFER); - tessDataTransfer = new TessellationDataTransferD3D11(context_, device_); + tessDataTransferD3D11 = new TessellationDataTransferD3D11(context_, device_); + tessDataTransfer = tessDataTransferD3D11; } void DrawEngineD3D11::ClearTrackedVertexArrays() { @@ -137,7 +138,7 @@ void DrawEngineD3D11::Resized() { void DrawEngineD3D11::DestroyDeviceObjects() { ClearTrackedVertexArrays(); ClearInputLayoutMap(); - delete tessDataTransfer; + delete tessDataTransferD3D11; delete pushVerts_; delete pushInds_; depthStencilCache_.Iterate([&](const uint64_t &key, ID3D11DepthStencilState *ds) { @@ -692,7 +693,22 @@ rotateVBO: GPUDebug::NotifyDraw(); } -void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { +TessellationDataTransferD3D11::TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device) + : context_(context), device_(device) { + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; +} + +TessellationDataTransferD3D11::~TessellationDataTransferD3D11() { + for (int i = 0; i < 3; ++i) { + if (buf[i]) buf[i]->Release(); + if (view[i]) view[i]->Release(); + } +} + +void TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { struct TessData { float pos[3]; float pad1; float uv[2]; float pad2[2]; @@ -701,13 +717,11 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const Simp if (prevSize < size) { prevSize = size; - if (buf[0]) { - buf[0]->Release(); - view[0]->Release(); - } + if (buf[0]) buf[0]->Release(); + if (view[0]) view[0]->Release(); + desc.ByteWidth = size * sizeof(TessData); desc.StructureByteStride = sizeof(TessData); - device_->CreateBuffer(&desc, nullptr, &buf[0]); device_->CreateShaderResourceView(buf[0], nullptr, &view[0]); context_->VSSetShaderResources(0, 1, &view[0]); @@ -727,17 +741,14 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const Simp context_->Unmap(buf[0], 0); - // Weights U - if (prevSizeWeights[0] < weights.size_u) { - prevSizeWeights[0] = weights.size_u; - if (buf[1]) { - buf[1]->Release(); - view[1]->Release(); - } + if (prevSizeWU < weights.size_u) { + prevSizeWU = weights.size_u; + if (buf[1]) buf[1]->Release(); + if (view[1]) view[1]->Release(); + desc.ByteWidth = weights.size_u * sizeof(Weight); desc.StructureByteStride = sizeof(Weight); - device_->CreateBuffer(&desc, nullptr, &buf[1]); device_->CreateShaderResourceView(buf[1], nullptr, &view[1]); context_->VSSetShaderResources(1, 1, &view[1]); @@ -747,15 +758,13 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const Simp context_->Unmap(buf[1], 0); // Weights V - if (prevSizeWeights[1] < weights.size_v) { - prevSizeWeights[1] = weights.size_v; - if (buf[2]) { - buf[2]->Release(); - view[2]->Release(); - } + if (prevSizeWV < weights.size_v) { + prevSizeWV = weights.size_v; + if (buf[2]) buf[2]->Release(); + if (view[2]) view[2]->Release(); + desc.ByteWidth = weights.size_v * sizeof(Weight); desc.StructureByteStride = sizeof(Weight); - device_->CreateBuffer(&desc, nullptr, &buf[2]); device_->CreateShaderResourceView(buf[2], nullptr, &view[2]); context_->VSSetShaderResources(2, 1, &view[2]); diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index c910e2d365..a74dd03458 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -99,6 +99,22 @@ public: u8 flags; }; +class TessellationDataTransferD3D11 : public TessellationDataTransfer { +private: + ID3D11DeviceContext *context_; + ID3D11Device *device_; + ID3D11Buffer *buf[3]{}; + ID3D11ShaderResourceView *view[3]{}; + D3D11_BUFFER_DESC desc{}; + int prevSize = 0; + int prevSizeWU = 0, prevSizeWV = 0; +public: + TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device); + ~TessellationDataTransferD3D11(); + // Send spline/bezier's control points and weights to vertex shader through structured shader buffer. + void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; +}; + // Handles transform, lighting and drawing. class DrawEngineD3D11 : public DrawEngineCommon { public: @@ -199,32 +215,5 @@ private: D3D11DynamicState dynState_{}; // Hardware tessellation - class TessellationDataTransferD3D11 : public TessellationDataTransfer { - private: - ID3D11DeviceContext *context_; - ID3D11Device *device_; - ID3D11Buffer *buf[3]; - ID3D11ShaderResourceView *view[3]; - D3D11_BUFFER_DESC desc; - int prevSize = 0; - int prevSizeWeights[2] = {}; - public: - TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device) - : TessellationDataTransfer(), context_(context), device_(device), buf(), view(), desc() { - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - } - ~TessellationDataTransferD3D11() { - for (int i = 0; i < 3; ++i) { - if (buf[i]) { - buf[i]->Release(); - view[i]->Release(); - } - } - } - - void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; - }; + TessellationDataTransferD3D11 *tessDataTransferD3D11; }; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index b7ad1027a9..4300e18c86 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -101,7 +101,8 @@ DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : vai_(256), vertexDeclMap InitDeviceObjects(); - tessDataTransfer = new TessellationDataTransferDX9(); + tessDataTransferDX9 = new TessellationDataTransferDX9(); + tessDataTransfer = tessDataTransferDX9; device_->CreateVertexDeclaration(TransformedVertexElements, &transformedVertexDecl_); } @@ -121,7 +122,7 @@ DrawEngineDX9::~DrawEngineDX9() { } }); vertexDeclMap_.Clear(); - delete tessDataTransfer; + delete tessDataTransferDX9; } void DrawEngineDX9::InitDeviceObjects() { @@ -624,7 +625,8 @@ rotateVBO: GPUDebug::NotifyDraw(); } -void DrawEngineDX9::TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { +void TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { + // TODO } } // namespace diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h index be54128be2..32c0db6e0f 100644 --- a/GPU/Directx9/DrawEngineDX9.h +++ b/GPU/Directx9/DrawEngineDX9.h @@ -97,6 +97,13 @@ public: u8 flags; }; +class TessellationDataTransferDX9 : public TessellationDataTransfer { +public: + TessellationDataTransferDX9() {} + ~TessellationDataTransferDX9() {} + void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; +}; + // Handles transform, lighting and drawing. class DrawEngineDX9 : public DrawEngineCommon { public: @@ -158,16 +165,7 @@ private: FramebufferManagerDX9 *framebufferManager_ = nullptr; // Hardware tessellation - class TessellationDataTransferDX9 : public TessellationDataTransfer { - private: - int data_tex[3]; - public: - TessellationDataTransferDX9() : TessellationDataTransfer(), data_tex() { - } - ~TessellationDataTransferDX9() { - } - void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; - }; + TessellationDataTransferDX9 *tessDataTransferDX9; }; } // namespace diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 6fd3d68ced..957eda68bc 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -97,7 +97,7 @@ DrawEngineGLES::~DrawEngineGLES() { FreeMemoryPages(decIndex, DECODED_INDEX_BUFFER_SIZE); FreeMemoryPages(splineBuffer, SPLINE_BUFFER_SIZE); - delete tessDataTransfer; + delete tessDataTransferGLES; } void DrawEngineGLES::DeviceLost() { @@ -656,7 +656,7 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const { return decJitCache_->IsInSpace(ptr); } -void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { +void TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0; int sizeColor = hasColor ? size : 1; @@ -703,7 +703,7 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const Simple } -void DrawEngineGLES::TessellationDataTransferGLES::EndFrame() { +void TessellationDataTransferGLES::EndFrame() { for (int i = 0; i < 3; i++) { if (data_tex[i]) { renderManager_->DeleteTexture(data_tex[i]); diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 07707a435b..52605374d9 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -110,6 +110,21 @@ public: u8 flags; }; +class TessellationDataTransferGLES : public TessellationDataTransfer { +private: + GLRTexture *data_tex[3]{}; + GLRenderManager *renderManager_; +public: + TessellationDataTransferGLES(GLRenderManager *renderManager) + : renderManager_(renderManager) { } + ~TessellationDataTransferGLES() { + EndFrame(); + } + // Send spline/bezier's control points and weights to vertex shader through floating point texture. + void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; + void EndFrame(); // Queues textures for deletion. +}; + // Handles transform, lighting and drawing. class DrawEngineGLES : public DrawEngineCommon { public: @@ -208,18 +223,5 @@ private: int bufferDecimationCounter_ = 0; // Hardware tessellation - class TessellationDataTransferGLES : public TessellationDataTransfer { - private: - GLRTexture *data_tex[3]{}; - GLRenderManager *renderManager_; - public: - TessellationDataTransferGLES(GLRenderManager *renderManager) - : renderManager_(renderManager) { } - ~TessellationDataTransferGLES() { - EndFrame(); - } - void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; - void EndFrame(); // Queues textures for deletion. - }; TessellationDataTransferGLES *tessDataTransferGLES; }; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index c8b2c43da1..bcd9648c76 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -212,7 +212,7 @@ void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) { } void DrawEngineVulkan::DestroyDeviceObjects() { - delete tessDataTransfer; + delete tessDataTransferVulkan; tessDataTransfer = tessDataTransferVulkan = nullptr; for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { @@ -1014,14 +1014,7 @@ void DrawEngineVulkan::UpdateUBOs(FrameData *frame) { } } -DrawEngineVulkan::TessellationDataTransferVulkan::TessellationDataTransferVulkan(VulkanContext *vulkan) - : TessellationDataTransfer(), vulkan_(vulkan) { -} - -DrawEngineVulkan::TessellationDataTransferVulkan::~TessellationDataTransferVulkan() { -} - -void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { +void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) { // SSBOs that are not simply float1 or float2 need to be padded up to a float4 size. vec3 members // also need to be 16-byte aligned, hence the padding. struct TessData { diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 8cb4c82350..ad2cb30954 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -117,6 +117,20 @@ public: class VulkanRenderManager; +class TessellationDataTransferVulkan : public TessellationDataTransfer { +public: + TessellationDataTransferVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {} + + void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; } + // Send spline/bezier's control points and weights to vertex shader through structured shader buffer. + void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; + const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; } +private: + VulkanContext *vulkan_; + VulkanPushBuffer *push_; // Updated each frame. + VkDescriptorBufferInfo bufInfo_[3]{}; +}; + // Handles transform, lighting and drawing. class DrawEngineVulkan : public DrawEngineCommon { public: @@ -278,19 +292,5 @@ private: int tessOffset_ = 0; // Hardware tessellation - class TessellationDataTransferVulkan : public TessellationDataTransfer { - public: - TessellationDataTransferVulkan(VulkanContext *vulkan); - ~TessellationDataTransferVulkan(); - - void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; } - void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override; - const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; } - private: - VulkanContext *vulkan_; - VulkanPushBuffer *push_; // Updated each frame. - - VkDescriptorBufferInfo bufInfo_[3] = {}; - }; TessellationDataTransferVulkan *tessDataTransferVulkan; };