From 0154d0856d2eb07e0dd30213785405712ee97ccc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Feb 2018 18:07:24 +0100 Subject: [PATCH] [dxbc] Added push constant definition block This will be used to fake a draw's instance ID when per-instance data fetch rates other than 1 are used. --- src/dxbc/dxbc_compiler.cpp | 63 +++++++++++++++++++++++++++++--------- src/dxbc/dxbc_compiler.h | 8 +++++ 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 1d9fd27a..1c2dcc8e 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -6,6 +6,8 @@ namespace dxvk { constexpr uint32_t PerVertex_CullDist = 1; constexpr uint32_t PerVertex_ClipDist = 2; + constexpr uint32_t PushConstant_InstanceId = 0; + DxbcCompiler::DxbcCompiler( const DxbcOptions& options, const DxbcProgramVersion& version, @@ -33,19 +35,7 @@ namespace dxvk { m_oRegs.at(i) = 0; } - // Set up common capabilities for all shaders - m_module.enableCapability(spv::CapabilityShader); - m_module.enableCapability(spv::CapabilityImageQuery); - - // Initialize the shader module with capabilities - // etc. Each shader type has its own peculiarities. - switch (m_version.type()) { - case DxbcProgramType::VertexShader: this->emitVsInit(); break; - case DxbcProgramType::GeometryShader: this->emitGsInit(); break; - case DxbcProgramType::PixelShader: this->emitPsInit(); break; - case DxbcProgramType::ComputeShader: this->emitCsInit(); break; - default: throw DxvkError("DxbcCompiler: Unsupported program type"); - } + this->emitInit(); } @@ -4480,6 +4470,25 @@ namespace dxvk { } + void DxbcCompiler::emitInit() { + // Set up common capabilities for all shaders + m_module.enableCapability(spv::CapabilityShader); + m_module.enableCapability(spv::CapabilityImageQuery); + + m_pushConstantBlock = getPushConstantBlockId(); + + // Initialize the shader module with capabilities + // etc. Each shader type has its own peculiarities. + switch (m_version.type()) { + case DxbcProgramType::VertexShader: emitVsInit(); break; + case DxbcProgramType::GeometryShader: emitGsInit(); break; + case DxbcProgramType::PixelShader: emitPsInit(); break; + case DxbcProgramType::ComputeShader: emitCsInit(); break; + default: throw DxvkError("DxbcCompiler: Unsupported program type"); + } + } + + void DxbcCompiler::emitVsInit() { m_module.enableCapability(spv::CapabilityClipDistance); m_module.enableCapability(spv::CapabilityCullDistance); @@ -4898,11 +4907,37 @@ namespace dxvk { // m_module.memberDecorateBuiltIn(typeId, PerVertex_ClipDist, spv::BuiltInClipDistance); m_module.decorateBlock(typeId); - m_module.setDebugName(typeId, "per_vertex"); + m_module.setDebugName(typeId, "s_per_vertex"); m_module.setDebugMemberName(typeId, PerVertex_Position, "position"); // m_module.setDebugMemberName(typeId, PerVertex_CullDist, "cull_dist"); // m_module.setDebugMemberName(typeId, PerVertex_ClipDist, "clip_dist"); return typeId; } + + uint32_t DxbcCompiler::getPushConstantBlockId() { + uint32_t t_u32 = m_module.defIntType(32, 0); + + std::array members; + members[PushConstant_InstanceId] = t_u32; + + uint32_t typeId = m_module.defStructTypeUnique( + members.size(), members.data()); + + m_module.memberDecorateOffset(typeId, 0, 0); + m_module.decorateBlock(typeId); + + m_module.setDebugName(typeId, "s_push_constant"); + m_module.setDebugMemberName(typeId, PerVertex_Position, "instance_id"); + + uint32_t ptrTypeId = m_module.defPointerType( + typeId, spv::StorageClassPushConstant); + + uint32_t varId = m_module.newVar( + ptrTypeId, spv::StorageClassPushConstant); + + m_module.setDebugName(varId, "push_constant"); + return varId; + } + } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 2b206403..b9a1579c 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -369,6 +369,10 @@ namespace dxvk { uint32_t m_uavCtrStructType = 0; uint32_t m_uavCtrPointerType = 0; + //////////////////////////////// + // Push constant block variable + uint32_t m_pushConstantBlock = 0; + /////////////////////////////////////////////////// // Entry point description - we'll need to declare // the function ID and all input/output variables. @@ -777,6 +781,8 @@ namespace dxvk { ///////////////////////////////// // Shader initialization methods + void emitInit(); + void emitVsInit(); void emitHsInit(); void emitGsInit(); @@ -849,6 +855,8 @@ namespace dxvk { uint32_t getPerVertexBlockId(); + uint32_t getPushConstantBlockId(); + }; } \ No newline at end of file