Skip to content

Commit

Permalink
[spline/bezier]Modify D3D11 hwtess texture buffer to structured shade…
Browse files Browse the repository at this point in the history
…r buffer.
  • Loading branch information
xebra committed Jun 26, 2018
1 parent aa927e0 commit 4fab160
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 88 deletions.
91 changes: 29 additions & 62 deletions GPU/D3D11/DrawEngineD3D11.cpp
Expand Up @@ -695,71 +695,38 @@ void DrawEngineD3D11::DoFlush() {
#endif #endif
} }


void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const float * pos, const float * tex, const float * col, int size, bool hasColor, bool hasTexCoords) { void DrawEngineD3D11::TessellationDataTransferD3D11::PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) {
// Position struct TessData {
float pos[3]; float pad1;
float uv[2]; float pad2[2];
float color[4];
};

if (prevSize < size) { if (prevSize < size) {
prevSize = size; prevSize = size;
if (data_tex[0]) { if (buf) {
data_tex[0]->Release(); buf->Release();
view[0]->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);

// 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; desc.ByteWidth = size * sizeof(TessData);
context_->UpdateSubresource(data_tex[1], 0, &dstBox, tex, 0, 0); desc.StructureByteStride = sizeof(TessData);
}


// Color device_->CreateBuffer(&desc, nullptr, &buf);
int sizeColor = hasColor ? size : 1; device_->CreateShaderResourceView(buf, 0, &view);
if (prevSizeCol < sizeColor) { context_->VSSetShaderResources(0, 1, &view);
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; D3D11_MAPPED_SUBRESOURCE map;
context_->UpdateSubresource(data_tex[2], 0, &dstBox, col, 0, 0); context_->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
uint8_t *data = (uint8_t *)map.pData;

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);
} }
28 changes: 13 additions & 15 deletions GPU/D3D11/DrawEngineD3D11.h
Expand Up @@ -203,27 +203,25 @@ class DrawEngineD3D11 : public DrawEngineCommon {
private: private:
ID3D11DeviceContext *context_; ID3D11DeviceContext *context_;
ID3D11Device *device_; ID3D11Device *device_;
ID3D11Texture1D *data_tex[3]; ID3D11Buffer *buf;
ID3D11ShaderResourceView *view[3]; ID3D11ShaderResourceView *view;
D3D11_TEXTURE1D_DESC desc; D3D11_BUFFER_DESC desc;
D3D11_BOX dstBox;
public: public:
TessellationDataTransferD3D11(ID3D11DeviceContext *context_, ID3D11Device *device_) TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device)
: TessellationDataTransfer(), context_(context_), device_(device_), data_tex(), view(), desc(), dstBox{0, 0, 0, 1, 1, 1} { : TessellationDataTransfer(), context_(context), device_(device), buf(), view(), desc() {
desc.CPUAccessFlags = 0; desc.Usage = D3D11_USAGE_DYNAMIC;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.ArraySize = 1;
desc.MipLevels = 1;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 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) {
if (data_tex[i]) { buf->Release();
data_tex[i]->Release(); view->Release();
view[i]->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; void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override;
}; };
}; };
23 changes: 12 additions & 11 deletions GPU/Directx9/VertexShaderGeneratorDX9.cpp
Expand Up @@ -263,9 +263,12 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
// Hardware tessellation // Hardware tessellation
if (doSpline || doBezier) { if (doSpline || doBezier) {
if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) { if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) {
WRITE(p, "Texture1D<float3> u_tess_pos_tex : register(t0);\n"); WRITE(p, "struct TessData {\n");
WRITE(p, "Texture1D<float3> u_tess_tex_tex : register(t1);\n"); WRITE(p, " float3 pos; float pad1;\n");
WRITE(p, "Texture1D<float4> u_tess_col_tex : register(t2);\n"); WRITE(p, " float2 tex; float2 pad2;\n");
WRITE(p, " float4 col;\n");
WRITE(p, "};");
WRITE(p, "StructuredBuffer<TessData> 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" }; const char *init[3] = { "0.0, 0.0", "0.0, 0.0, 0.0", "0.0, 0.0, 0.0, 0.0" };
Expand Down Expand Up @@ -401,17 +404,15 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
WRITE(p, " float3 _pos[16];\n"); WRITE(p, " float3 _pos[16];\n");
WRITE(p, " float2 _tex[16];\n"); WRITE(p, " float2 _tex[16];\n");
WRITE(p, " float4 _col[16];\n"); WRITE(p, " float4 _col[16];\n");
WRITE(p, " int idx;\n"); WRITE(p, " int index;\n");
WRITE(p, " int2 index;\n");
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) { 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 = (%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] = tess_data[index].pos;\n", i * 4 + j);
WRITE(p, " _pos[%i] = u_tess_pos_tex.Load(index).xyz;\n", i * 4 + j);
if (doTexture && hasTexcoord && hasTexcoordTess) 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) 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"); WRITE(p, " float2 weights[4];\n");
Expand Down Expand Up @@ -441,7 +442,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
if (hasColorTess) if (hasColorTess)
WRITE(p, " float4 col = tess_sample(_col, weights);\n"); WRITE(p, " float4 col = tess_sample(_col, weights);\n");
else 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) { if (hasNormal) {
// Curved surface is probably always need to compute normal(not sampling from control points) // Curved surface is probably always need to compute normal(not sampling from control points)
Expand Down

0 comments on commit 4fab160

Please sign in to comment.