From b44cad4d3202d08737a1da6299b8c7c2b485cedf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Apr 2019 22:41:40 +0200 Subject: [PATCH] [dxbc] Replace computeResourceSlotId by light-weight alternatives Slightly reduces overhead of D3D11 binding methods. --- src/d3d11/d3d11_context.cpp | 44 ++++---------- src/dxbc/dxbc_compiler.cpp | 30 ++++----- src/dxbc/dxbc_util.cpp | 42 ------------- src/dxbc/dxbc_util.h | 117 +++++++++++++++++++++++++++++------- 4 files changed, 119 insertions(+), 114 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 1a3fa5d0..72d25cfd 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3116,8 +3116,7 @@ namespace dxvk { DxbcProgramType ShaderStage, const D3D11CommonShader* pShaderModule) { // Bind the shader and the ICB at once - const uint32_t slotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::ConstantBuffer, + uint32_t slotId = computeConstantBufferBinding(ShaderStage, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); EmitCs([ @@ -3359,9 +3358,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - const uint32_t slotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::ConstantBuffer, - StartSlot); + uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumBuffers; i++) { auto newBuffer = static_cast(ppConstantBuffers[i]); @@ -3391,9 +3388,7 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { - const uint32_t slotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::ConstantBuffer, - StartSlot); + uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumBuffers; i++) { auto newBuffer = static_cast(ppConstantBuffers[i]); @@ -3442,9 +3437,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - const uint32_t slotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::ImageSampler, - StartSlot); + uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumSamplers; i++) { auto sampler = static_cast(ppSamplers[i]); @@ -3463,9 +3456,7 @@ namespace dxvk { UINT StartSlot, UINT NumResources, ID3D11ShaderResourceView* const* ppResources) { - const uint32_t slotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::ShaderResource, - StartSlot); + uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumResources; i++) { auto resView = static_cast(ppResources[i]); @@ -3485,13 +3476,8 @@ namespace dxvk { UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) { - const uint32_t uavSlotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::UnorderedAccessView, - StartSlot); - - const uint32_t ctrSlotId = computeResourceSlotId( - ShaderStage, DxbcBindingType::UavCounter, - StartSlot); + uint32_t uavSlotId = computeUavBinding (ShaderStage, StartSlot); + uint32_t ctrSlotId = computeUavCounterBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumUAVs; i++) { auto uav = static_cast(ppUnorderedAccessViews[i]); @@ -3613,8 +3599,7 @@ namespace dxvk { void D3D11DeviceContext::RestoreConstantBuffers( DxbcProgramType Stage, D3D11ConstantBufferBindings& Bindings) { - const uint32_t slotId = computeResourceSlotId( - Stage, DxbcBindingType::ConstantBuffer, 0); + uint32_t slotId = computeConstantBufferBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) BindConstantBuffer(slotId + i, &Bindings[i]); @@ -3624,8 +3609,7 @@ namespace dxvk { void D3D11DeviceContext::RestoreSamplers( DxbcProgramType Stage, D3D11SamplerBindings& Bindings) { - const uint32_t slotId = computeResourceSlotId( - Stage, DxbcBindingType::ImageSampler, 0); + uint32_t slotId = computeSamplerBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) BindSampler(slotId + i, Bindings[i].ptr()); @@ -3635,8 +3619,7 @@ namespace dxvk { void D3D11DeviceContext::RestoreShaderResources( DxbcProgramType Stage, D3D11ShaderResourceBindings& Bindings) { - const uint32_t slotId = computeResourceSlotId( - Stage, DxbcBindingType::ShaderResource, 0); + uint32_t slotId = computeSrvBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) BindShaderResource(slotId + i, Bindings[i].ptr()); @@ -3646,11 +3629,8 @@ namespace dxvk { void D3D11DeviceContext::RestoreUnorderedAccessViews( DxbcProgramType Stage, D3D11UnorderedAccessBindings& Bindings) { - const uint32_t uavSlotId = computeResourceSlotId( - Stage, DxbcBindingType::UnorderedAccessView, 0); - - const uint32_t ctrSlotId = computeResourceSlotId( - Stage, DxbcBindingType::UavCounter, 0); + uint32_t uavSlotId = computeUavBinding (Stage, 0); + uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) { BindUnorderedAccessView( diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index d4eb355f..ada36dae 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -777,9 +777,8 @@ namespace dxvk { // Compute the DXVK binding slot index for the buffer. // D3D11 needs to bind the actual buffers to this slot. - const uint32_t bindingId = computeResourceSlotId( - m_programInfo.type(), DxbcBindingType::ConstantBuffer, - regIdx); + uint32_t bindingId = computeConstantBufferBinding( + m_programInfo.type(), regIdx); m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); @@ -828,8 +827,8 @@ namespace dxvk { m_samplers.at(samplerId).typeId = samplerType; // Compute binding slot index for the sampler - const uint32_t bindingId = computeResourceSlotId( - m_programInfo.type(), DxbcBindingType::ImageSampler, samplerId); + uint32_t bindingId = computeSamplerBinding( + m_programInfo.type(), samplerId); m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); @@ -959,11 +958,9 @@ namespace dxvk { // Compute the DXVK binding slot index for the resource. // D3D11 needs to bind the actual resource to this slot. - const uint32_t bindingId = computeResourceSlotId( - m_programInfo.type(), isUav - ? DxbcBindingType::UnorderedAccessView - : DxbcBindingType::ShaderResource, - registerId); + uint32_t bindingId = isUav + ? computeUavBinding(m_programInfo.type(), registerId) + : computeSrvBinding(m_programInfo.type(), registerId); m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); @@ -1076,11 +1073,9 @@ namespace dxvk { : 0; // Compute the DXVK binding slot index for the resource. - uint32_t bindingId = computeResourceSlotId( - m_programInfo.type(), isUav - ? DxbcBindingType::UnorderedAccessView - : DxbcBindingType::ShaderResource, - registerId); + uint32_t bindingId = isUav + ? computeUavBinding(m_programInfo.type(), registerId) + : computeSrvBinding(m_programInfo.type(), registerId); if (m_moduleInfo.options.useRawSsbo) { uint32_t elemType = getScalarTypeId(DxbcScalarType::Uint32); @@ -1398,9 +1393,8 @@ namespace dxvk { m_module.setDebugName(varId, str::format("u", regId, "_meta").c_str()); - const uint32_t bindingId = computeResourceSlotId( - m_programInfo.type(), DxbcBindingType::UavCounter, - regId); + uint32_t bindingId = computeUavCounterBinding( + m_programInfo.type(), regId); m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); diff --git a/src/dxbc/dxbc_util.cpp b/src/dxbc/dxbc_util.cpp index 60b019da..848f8ad7 100644 --- a/src/dxbc/dxbc_util.cpp +++ b/src/dxbc/dxbc_util.cpp @@ -2,48 +2,6 @@ namespace dxvk { - uint32_t computeResourceSlotId( - DxbcProgramType shaderStage, - DxbcBindingType bindingType, - uint32_t bindingIndex) { - // First resource slot index for per-stage resources - const uint32_t stageOffset = 128 + 160 * uint32_t(shaderStage); - - if (shaderStage == DxbcProgramType::ComputeShader) { - // 0 - 15: Constant buffers - // 16 - 31: Samplers - // 32 - 159: Shader resources - // 160 - 223: Unordered access views - // 224 - 287: UAV counter buffers - switch (bindingType) { - case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0; - case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 16; - case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 32; - case DxbcBindingType::UnorderedAccessView:return bindingIndex + stageOffset + 160; - case DxbcBindingType::UavCounter: return bindingIndex + stageOffset + 224; - default: Logger::err("computeResourceSlotId: Invalid resource type"); - } - } else { - // Global resource slots - // 0 - 63: Unordered access views - // 64 - 128: UAV counter buffers - // Per-stage resource slots: - // 0 - 15: Constant buffers - // 16 - 31: Samplers - // 32 - 159: Shader resources - switch (bindingType) { - case DxbcBindingType::UnorderedAccessView:return bindingIndex + 0; - case DxbcBindingType::UavCounter: return bindingIndex + 64; - case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0; - case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 16; - case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 32; - default: Logger::err("computeResourceSlotId: Invalid resource type"); - } - } - - return 0; - } - uint32_t primitiveVertexCount(DxbcPrimitive primitive) { static const std::array s_vertexCounts = { 0, // Undefined diff --git a/src/dxbc/dxbc_util.h b/src/dxbc/dxbc_util.h index f830b96b..4bc49620 100644 --- a/src/dxbc/dxbc_util.h +++ b/src/dxbc/dxbc_util.h @@ -4,35 +4,108 @@ #include "dxbc_enums.h" namespace dxvk { - + /** - * \brief Resource type - * - * The type of a shader resource. Used - * to determine the DXVK resource slot. + * \brief Binding numbers and properties */ - enum DxbcBindingType : uint32_t { - ConstantBuffer = 0, - ShaderResource = 1, - ImageSampler = 2, - UnorderedAccessView = 3, - StreamOutputBuffer = 4, - UavCounter = 5, + enum DxbcBindingProperties : uint32_t { + DxbcConstBufBindingIndex = 0, + DxbcConstBufBindingCount = 16, + DxbcSamplerBindingIndex = DxbcConstBufBindingIndex + + DxbcConstBufBindingCount, + DxbcSamplerBindingCount = 16, + DxbcResourceBindingIndex = DxbcSamplerBindingIndex + + DxbcSamplerBindingCount, + DxbcResourceBindingCount = 128, + DxbcStageBindingCount = DxbcConstBufBindingCount + + DxbcSamplerBindingCount + + DxbcResourceBindingCount, + DxbcUavBindingIndex = DxbcStageBindingCount * 6, + DxbcUavBindingCount = 64, }; + + + /** + * \brief Computes first binding index for a given stage + * + * \param [in] stage The shader stage + * \returns Index of first binding + */ + inline uint32_t computeStageBindingOffset(DxbcProgramType stage) { + return DxbcStageBindingCount * uint32_t(stage); + } + + + /** + * \brief Computes first UAV binding index offset for a given stage + * + * \param [in] stage The shader stage + * \returns Index of first UAV binding + */ + inline uint32_t computeStageUavBindingOffset(DxbcProgramType stage) { + return DxbcUavBindingIndex + + DxbcUavBindingCount * (stage == DxbcProgramType::ComputeShader ? 2 : 0); + } + + + /** + * \brief Computes constant buffer binding index + * + * \param [in] stage Shader stage + * \param [in] index Constant buffer index + * \returns Binding index + */ + inline uint32_t computeConstantBufferBinding(DxbcProgramType stage, uint32_t index) { + return computeStageBindingOffset(stage) + DxbcConstBufBindingIndex + index; + } + + + /** + * \brief Computes sampler binding index + * + * \param [in] stage Shader stage + * \param [in] index Sampler index + * \returns Binding index + */ + inline uint32_t computeSamplerBinding(DxbcProgramType stage, uint32_t index) { + return computeStageBindingOffset(stage) + DxbcSamplerBindingIndex + index; + } + + + /** + * \brief Computes resource binding index + * + * \param [in] stage Shader stage + * \param [in] index Resource index + * \returns Binding index + */ + inline uint32_t computeSrvBinding(DxbcProgramType stage, uint32_t index) { + return computeStageBindingOffset(stage) + DxbcResourceBindingIndex + index; + } + + + /** + * \brief Computes UAV binding offset + * + * \param [in] stage Shader stage + * \param [in] index UAV index + * \returns Binding index + */ + inline uint32_t computeUavBinding(DxbcProgramType stage, uint32_t index) { + return computeStageUavBindingOffset(stage) + index; + } /** - * \brief Computes the DXVK resource slot for a binding - * - * \param [in] shaderStage The target shader stage - * \param [in] bindingType Type of the resource - * \param [in] bindingIndex Resource binding index - * \returns DXVK resource slot index + * \brief Computes UAV counter binding offset + * + * \param [in] stage Shader stage + * \param [in] index UAV index + * \returns Binding index */ - uint32_t computeResourceSlotId( - DxbcProgramType shaderStage, - DxbcBindingType bindingType, - uint32_t bindingIndex); + inline uint32_t computeUavCounterBinding(DxbcProgramType stage, uint32_t index) { + return computeStageUavBindingOffset(stage) + DxbcUavBindingCount + index; + } /** * \brief Primitive vertex count