Permalink
Browse files

[spline/bezier]Modify D3D11 hwtess texture buffer to structured shade…

…r buffer.
  • Loading branch information...
xebra committed Jan 29, 2018
1 parent aa927e0 commit 4fab160e1978b634479a4a59973cb6a0889d5512
Showing with 54 additions and 88 deletions.
  1. +29 −62 GPU/D3D11/DrawEngineD3D11.cpp
  2. +13 −15 GPU/D3D11/DrawEngineD3D11.h
  3. +12 −11 GPU/Directx9/VertexShaderGeneratorDX9.cpp
@@ -695,71 +695,38 @@ void DrawEngineD3D11::DoFlush() {
#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();
}
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]);
if (buf) {
buf->Release();
view->Release();
}
dstBox.right = size;
context_->UpdateSubresource(data_tex[1], 0, &dstBox, tex, 0, 0);
}
desc.ByteWidth = size * sizeof(TessData);
desc.StructureByteStride = sizeof(TessData);
// 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]);
device_->CreateBuffer(&desc, nullptr, &buf);
device_->CreateShaderResourceView(buf, 0, &view);
context_->VSSetShaderResources(0, 1, &view);
}
dstBox.right = sizeColor;
context_->UpdateSubresource(data_tex[2], 0, &dstBox, col, 0, 0);
D3D11_MAPPED_SUBRESOURCE map;
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);
}
@@ -203,27 +203,25 @@ class DrawEngineD3D11 : public DrawEngineCommon {
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;
};
};
@@ -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<float3> u_tess_pos_tex : register(t0);\n");
WRITE(p, "Texture1D<float3> u_tess_tex_tex : register(t1);\n");
WRITE(p, "Texture1D<float4> 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<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" };
@@ -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)

0 comments on commit 4fab160

Please sign in to comment.