mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-05 22:04:22 +01:00
Merge pull request #11221 from xebra/improve_tess_cherrypick
Modify D3D11 hwtess texture buffer to structured shader buffer.
This commit is contained in:
4 files changed
+54
-88
No files matched your search
@@ -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);
|
||||
}
|
||||
+13
-15
@@ -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;
|
||||
};
|
||||
};
|
||||
@@ -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)
|
||||
|
||||
@@ -199,7 +199,7 @@ static void ExpandBezier(int &count, int op, const std::vector<SimpleVertex> &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];
|
||||
|
||||
Reference in new issue
Block a user