From e668c6501766634e29a715126417b7ce9336bfe7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 27 Dec 2017 14:32:07 +0100 Subject: [PATCH] [d3d11] Experimental support for typed shader buffer views --- src/d3d11/d3d11_context.cpp | 4 +- src/d3d11/d3d11_device.cpp | 71 ++++++++++++++++++++++------- tests/d3d11/test_d3d11_triangle.cpp | 24 ++++++++-- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index f459959d..d6d5098e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1696,9 +1696,9 @@ namespace dxvk { if (resView != nullptr) { // Figure out what we have to bind based on the resource type if (resView->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { - Logger::warn("D3D11: Texel buffers not yet supported"); + // TODO support raw and structured buffers m_context->bindResourceTexelBuffer( - slotId + i, nullptr); + slotId + i, resView->GetDXVKBufferView()); } else { m_context->bindResourceImage( slotId + i, resView->GetDXVKImageView()); diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 4723969f..eb420b70 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -146,8 +146,42 @@ namespace dxvk { } if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { - Logger::err("D3D11: Shader resource views for buffers not yet supported"); - return E_INVALIDARG; + auto resource = static_cast(pResource); + + // TODO implement raw and structured buffers + if (pDesc->Format == DXGI_FORMAT_UNKNOWN) { + Logger::err("D3D11Device: Raw and structured buffers not yet supported"); + return E_INVALIDARG; + } + + // Typed buffer views support uncompressed color formats only + const VkFormat format = m_dxgiAdapter->LookupFormat( + pDesc->Format, DxgiFormatMode::Color).format; + const DxvkFormatInfo* formatInfo = imageFormatInfo(format); + + if (formatInfo->flags.test(DxvkFormatFlag::BlockCompressed)) { + Logger::err("D3D11Device: Compressed formats for buffer views not supported"); + return E_INVALIDARG; + } + + DxvkBufferViewCreateInfo viewInfo; + viewInfo.format = format; + viewInfo.rangeOffset = formatInfo->elementSize * pDesc->Buffer.FirstElement; + viewInfo.rangeLength = formatInfo->elementSize * pDesc->Buffer.NumElements; + + if (ppSRView == nullptr) + return S_FALSE; + + try { + *ppSRView = ref(new D3D11ShaderResourceView( + this, pResource, desc, + m_dxvkDevice->createBufferView( + resource->GetBufferSlice().buffer(), viewInfo))); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } } else { // Retrieve info about the image D3D11TextureInfo textureInfo; @@ -249,7 +283,7 @@ namespace dxvk { } if (ppSRView == nullptr) - return S_OK; + return S_FALSE; try { *ppSRView = ref(new D3D11ShaderResourceView( @@ -353,7 +387,7 @@ namespace dxvk { // Create the actual image view if requested if (ppRTView == nullptr) - return S_OK; + return S_FALSE; try { *ppRTView = ref(new D3D11RenderTargetView( @@ -363,7 +397,7 @@ namespace dxvk { return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); - return DXGI_ERROR_DRIVER_INTERNAL_ERROR; + return E_FAIL; } } @@ -447,7 +481,7 @@ namespace dxvk { // Create the actual image view if requested if (ppDepthStencilView == nullptr) - return S_OK; + return S_FALSE; try { *ppDepthStencilView = ref(new D3D11DepthStencilView( @@ -457,7 +491,7 @@ namespace dxvk { return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); - return DXGI_ERROR_DRIVER_INTERNAL_ERROR; + return E_FAIL; } } @@ -571,7 +605,7 @@ namespace dxvk { return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); - return E_INVALIDARG; + return E_FAIL; } } @@ -723,9 +757,10 @@ namespace dxvk { } } - if (ppBlendState != nullptr) + if (ppBlendState != nullptr) { *ppBlendState = m_bsStateObjects.Create(this, desc); - return S_OK; + return S_OK; + } return S_FALSE; } @@ -753,9 +788,10 @@ namespace dxvk { desc.BackFace = stencilOp; } - if (ppDepthStencilState != nullptr) + if (ppDepthStencilState != nullptr) { *ppDepthStencilState = m_dsStateObjects.Create(this, desc); - return S_OK; + return S_OK; + } return S_FALSE; } @@ -779,9 +815,10 @@ namespace dxvk { desc.AntialiasedLineEnable = FALSE; } - if (ppRasterizerState != nullptr) + if (ppRasterizerState != nullptr) { *ppRasterizerState = m_rsStateObjects.Create(this, desc); - return S_OK; + return S_OK; + } return S_FALSE; } @@ -827,7 +864,7 @@ namespace dxvk { // Create sampler object if the application requests it if (ppSamplerState == nullptr) - return S_OK; + return S_FALSE; try { *ppSamplerState = ref(new D3D11SamplerState(this, @@ -835,7 +872,7 @@ namespace dxvk { return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); - return S_OK; + return E_FAIL; } } @@ -1147,7 +1184,7 @@ namespace dxvk { return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); - return E_INVALIDARG; + return E_FAIL; } } diff --git a/tests/d3d11/test_d3d11_triangle.cpp b/tests/d3d11/test_d3d11_triangle.cpp index 67c888a0..aa951007 100644 --- a/tests/d3d11/test_d3d11_triangle.cpp +++ b/tests/d3d11/test_d3d11_triangle.cpp @@ -17,8 +17,10 @@ struct Vertex { }; const std::string g_vertexShaderCode = + "Buffer buf : register(t0);\n" "struct vs_out {\n" " float4 pos : SV_POSITION;\n" + " float4 color : COLOR;\n" " uint vid : VID;\n" " uint iid : IID;\n" "};\n" @@ -27,6 +29,7 @@ const std::string g_vertexShaderCode = " uint iid : SV_INSTANCEID) {\n" " vs_out result;\n" " result.pos = vsIn;\n" + " result.color = buf[vid];\n" " result.vid = vid;\n" " result.iid = iid;\n" " return result;\n" @@ -35,12 +38,14 @@ const std::string g_vertexShaderCode = const std::string g_pixelShaderCode = "struct vs_out {\n" " float4 pos : SV_POSITION;\n" + " float4 color : COLOR;\n" " uint vid : VID;\n" " uint iid : IID;\n" "};\n" "cbuffer c_buffer { float4 ccolor[2]; };\n" "float4 main(vs_out ps_in) : SV_TARGET {\n" - " return 0.5f * (ccolor[min(ps_in.vid, 1u)] + ccolor[min(ps_in.iid, 1u)]);\n" + " return ps_in.color;\n" +// " return 0.5f * (ccolor[min(ps_in.vid, 1u)] + ccolor[min(ps_in.iid, 1u)]);\n" "}\n"; class TriangleApp { @@ -157,15 +162,17 @@ public: if (FAILED(m_device->CreateBuffer(&indexDesc, &indexDataInfo, &m_indexBuffer))) throw DxvkError("Failed to create index buffer"); - std::array constantData = {{ + std::array constantData = {{ { 0.03f, 0.03f, 0.03f, 1.0f }, { 1.00f, 0.00f, 0.00f, 1.0f }, + { 1.00f, 1.00f, 0.00f, 1.0f }, }}; D3D11_BUFFER_DESC constantDesc; constantDesc.ByteWidth = sizeof(Vertex) * constantData.size(); constantDesc.Usage = D3D11_USAGE_IMMUTABLE; - constantDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER + | D3D11_BIND_SHADER_RESOURCE; constantDesc.CPUAccessFlags = 0; constantDesc.MiscFlags = 0; constantDesc.StructureByteStride = 0; @@ -178,6 +185,15 @@ public: if (FAILED(m_device->CreateBuffer(&constantDesc, &constantDataInfo, &m_constantBuffer))) throw DxvkError("Failed to create constant buffer"); + D3D11_SHADER_RESOURCE_VIEW_DESC constantViewDesc; + constantViewDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + constantViewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + constantViewDesc.Buffer.FirstElement = 0; + constantViewDesc.Buffer.NumElements = 3; + + if (FAILED(m_device->CreateShaderResourceView(m_constantBuffer.ptr(), &constantViewDesc, &m_constantView))) + throw DxvkError("Failed to create texel buffer view"); + Com vertexShaderBlob; Com pixelShaderBlob; @@ -250,6 +266,7 @@ public: m_context->ClearRenderTargetView(m_bufferView.ptr(), color); m_context->VSSetShader(m_vertexShader.ptr(), nullptr, 0); + m_context->VSSetShaderResources(0, 1, &m_constantView); m_context->PSSetShader(m_pixelShader.ptr(), nullptr, 0); m_context->PSSetConstantBuffers(0, 1, &m_constantBuffer); @@ -328,6 +345,7 @@ private: Com m_buffer; Com m_bufferView; Com m_constantBuffer; + Com m_constantView; Com m_indexBuffer; Com m_vertexBuffer; Com m_vertexFormat;