From 4fab160e1978b634479a4a59973cb6a0889d5512 Mon Sep 17 00:00:00 2001 From: xebra Date: Mon, 29 Jan 2018 14:14:57 +0900 Subject: [PATCH 1/2] [spline/bezier]Modify D3D11 hwtess texture buffer to structured shader buffer. --- GPU/D3D11/DrawEngineD3D11.cpp | 89 +++++++---------------- GPU/D3D11/DrawEngineD3D11.h | 28 ++++--- GPU/Directx9/VertexShaderGeneratorDX9.cpp | 23 +++--- 3 files changed, 53 insertions(+), 87 deletions(-) diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 2e09aee228..be7ffd9e83 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -695,71 +695,38 @@ rotateVBO: #endif } -void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const float * pos, const float * tex, const float * col, int size, bool hasColor, bool hasTexCoords) { - // Position +void DrawEngineD3D11::TessellationDataTransferD3D11::PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) { + struct TessData { + float pos[3]; float pad1; + float uv[2]; float pad2[2]; + float color[4]; + }; + if (prevSize < size) { prevSize = size; - if (data_tex[0]) { - data_tex[0]->Release(); - view[0]->Release(); + if (buf) { + buf->Release(); + view->Release(); } - desc.Width = size; - desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - HRESULT hr = device_->CreateTexture1D(&desc, nullptr, &data_tex[0]); - if (FAILED(hr)) { - INFO_LOG(G3D, "Failed to create D3D texture for HW tessellation"); - data_tex[0]->Release(); - return; // TODO: Turn off HW tessellation if texture creation error occured. - } - hr = device_->CreateShaderResourceView(data_tex[0], nullptr, &view[0]); - ASSERT_SUCCESS(hr); - context_->VSSetShaderResources(0, 1, &view[0]); - } - dstBox.right = size; - context_->UpdateSubresource(data_tex[0], 0, &dstBox, pos, 0, 0); + desc.ByteWidth = size * sizeof(TessData); + desc.StructureByteStride = sizeof(TessData); - // Texcoords - if (hasTexCoords) { - if (prevSizeTex < size) { - prevSizeTex = size; - if (data_tex[1]) { - data_tex[1]->Release(); - view[1]->Release(); - } - desc.Width = size; - desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - HRESULT hr = device_->CreateTexture1D(&desc, nullptr, &data_tex[1]); - if (FAILED(hr)) { - INFO_LOG(G3D, "Failed to create D3D texture for HW tessellation"); - data_tex[1]->Release(); - return; - } - hr = device_->CreateShaderResourceView(data_tex[1], nullptr, &view[1]); - context_->VSSetShaderResources(1, 1, &view[1]); - } - dstBox.right = size; - context_->UpdateSubresource(data_tex[1], 0, &dstBox, tex, 0, 0); + device_->CreateBuffer(&desc, nullptr, &buf); + device_->CreateShaderResourceView(buf, 0, &view); + context_->VSSetShaderResources(0, 1, &view); } + D3D11_MAPPED_SUBRESOURCE map; + context_->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + uint8_t *data = (uint8_t *)map.pData; - // Color - int sizeColor = hasColor ? size : 1; - if (prevSizeCol < sizeColor) { - prevSizeCol = sizeColor; - if (data_tex[2]) { - data_tex[2]->Release(); - view[2]->Release(); - } - desc.Width = sizeColor; - desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - HRESULT hr = device_->CreateTexture1D(&desc, nullptr, &data_tex[2]); - if (FAILED(hr)) { - INFO_LOG(G3D, "Failed to create D3D texture for HW tessellation"); - data_tex[2]->Release(); - return; - } - hr = device_->CreateShaderResourceView(data_tex[2], nullptr, &view[2]); - context_->VSSetShaderResources(2, 1, &view[2]); - } - dstBox.right = sizeColor; - context_->UpdateSubresource(data_tex[2], 0, &dstBox, col, 0, 0); + pos = (float *)(data); + tex = (float *)(data + offsetof(TessData, uv)); + col = (float *)(data + offsetof(TessData, color)); + posStride = sizeof(TessData) / sizeof(float); + colStride = hasColor ? (sizeof(TessData) / sizeof(float)) : 0; + texStride = sizeof(TessData) / sizeof(float); +} + +void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const float * pos, const float * tex, const float * col, int size, bool hasColor, bool hasTexCoords) { + context_->Unmap(buf, 0); } diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 9d4589baae..8b797a3d2d 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -203,27 +203,25 @@ private: private: ID3D11DeviceContext *context_; ID3D11Device *device_; - ID3D11Texture1D *data_tex[3]; - ID3D11ShaderResourceView *view[3]; - D3D11_TEXTURE1D_DESC desc; - D3D11_BOX dstBox; + ID3D11Buffer *buf; + ID3D11ShaderResourceView *view; + D3D11_BUFFER_DESC desc; public: - TessellationDataTransferD3D11(ID3D11DeviceContext *context_, ID3D11Device *device_) - : TessellationDataTransfer(), context_(context_), device_(device_), data_tex(), view(), desc(), dstBox{0, 0, 0, 1, 1, 1} { - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.ArraySize = 1; - desc.MipLevels = 1; + 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 (data_tex[i]) { - data_tex[i]->Release(); - view[i]->Release(); - } + if (buf) { + buf->Release(); + view->Release(); } } + + void PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) override; void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override; }; }; diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 227c51223c..5aafb19d18 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -263,9 +263,12 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage // Hardware tessellation if (doSpline || doBezier) { if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) { - WRITE(p, "Texture1D u_tess_pos_tex : register(t0);\n"); - WRITE(p, "Texture1D u_tess_tex_tex : register(t1);\n"); - WRITE(p, "Texture1D u_tess_col_tex : register(t2);\n"); + WRITE(p, "struct TessData {\n"); + WRITE(p, " float3 pos; float pad1;\n"); + WRITE(p, " float2 tex; float2 pad2;\n"); + WRITE(p, " float4 col;\n"); + WRITE(p, "};"); + WRITE(p, "StructuredBuffer tess_data : register(t0);\n"); } const char *init[3] = { "0.0, 0.0", "0.0, 0.0, 0.0", "0.0, 0.0, 0.0, 0.0" }; @@ -401,17 +404,15 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage WRITE(p, " float3 _pos[16];\n"); WRITE(p, " float2 _tex[16];\n"); WRITE(p, " float4 _col[16];\n"); - WRITE(p, " int idx;\n"); - WRITE(p, " int2 index;\n"); + WRITE(p, " int index;\n"); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - WRITE(p, " idx = (%i + v%s) * u_spline_count_u + (%i + u%s);\n", i, doBezier ? " * 3" : "", j, doBezier ? " * 3" : ""); - WRITE(p, " index = int2(idx, 0);\n"); - WRITE(p, " _pos[%i] = u_tess_pos_tex.Load(index).xyz;\n", i * 4 + j); + WRITE(p, " index = (%i + v%s) * u_spline_count_u + (%i + u%s);\n", i, doBezier ? " * 3" : "", j, doBezier ? " * 3" : ""); + WRITE(p, " _pos[%i] = tess_data[index].pos;\n", i * 4 + j); if (doTexture && hasTexcoord && hasTexcoordTess) - WRITE(p, " _tex[%i] = u_tess_tex_tex.Load(index).xy;\n", i * 4 + j); + WRITE(p, " _tex[%i] = tess_data[index].tex;\n", i * 4 + j); if (hasColor && hasColorTess) - WRITE(p, " _col[%i] = u_tess_col_tex.Load(index).rgba;\n", i * 4 + j); + WRITE(p, " _col[%i] = tess_data[index].col;\n", i * 4 + j); } } WRITE(p, " float2 weights[4];\n"); @@ -441,7 +442,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage if (hasColorTess) WRITE(p, " float4 col = tess_sample(_col, weights);\n"); else - WRITE(p, " float4 col = u_tess_col_tex.Load(int2(0, 0)).rgba;\n"); + WRITE(p, " float4 col = tess_data[0].col;\n"); } if (hasNormal) { // Curved surface is probably always need to compute normal(not sampling from control points) From 55b9daa736dd41904e3cd1b35e848f6290c24dc8 Mon Sep 17 00:00:00 2001 From: xebra Date: Wed, 27 Jun 2018 01:25:08 +0900 Subject: [PATCH 2/2] GE Debugger:Fix indices memory allocation of bezier. --- Windows/GEDebugger/VertexPreview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index c17c6d3638..42e006efd0 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -199,7 +199,7 @@ static void ExpandBezier(int &count, int op, const std::vector &si } generatedVerts.resize((tess_u + 1) * (tess_v + 1) * total_patches); - generatedInds.resize(tess_u * tess_v * 6); + generatedInds.resize(tess_u * tess_v * 6 * total_patches); count = 0; u8 *dest = (u8 *)&generatedVerts[0];