diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 318f8c24..789ea968 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2,8 +2,9 @@ namespace dxvk { - DxbcCompiler::DxbcCompiler(DxbcProgramVersion version) { - + DxbcCompiler::DxbcCompiler(DxbcProgramVersion version) + : m_version(version) { + this->enableCapability(spv::CapabilityShader); } @@ -19,8 +20,36 @@ namespace dxvk { Rc DxbcCompiler::finalize() { - return new DxvkShader(VK_SHADER_STAGE_COMPUTE_BIT, - DxvkSpirvCodeBuffer(), 0, nullptr); + DxvkSpirvCodeBuffer codeBuffer; + codeBuffer.putHeader(m_counter.numIds()); + codeBuffer.append(m_spirvCapabilities); + codeBuffer.append(m_spirvProgramCode); + + return new DxvkShader(this->shaderStage(), + std::move(codeBuffer), 0, nullptr); + } + + + VkShaderStageFlagBits DxbcCompiler::shaderStage() const { + switch (m_version.type()) { + case DxbcProgramType::PixelShader : return VK_SHADER_STAGE_FRAGMENT_BIT; + case DxbcProgramType::VertexShader : return VK_SHADER_STAGE_VERTEX_BIT; + case DxbcProgramType::GeometryShader : return VK_SHADER_STAGE_GEOMETRY_BIT; + case DxbcProgramType::HullShader : return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + case DxbcProgramType::DomainShader : return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + case DxbcProgramType::ComputeShader : return VK_SHADER_STAGE_COMPUTE_BIT; + } + + throw DxvkError("DxbcCompiler::shaderStage: Unknown program type"); + } + + + void DxbcCompiler::enableCapability(spv::Capability cap) { + if (m_capabilities.find(cap) == m_capabilities.end()) { + m_spirvCapabilities.putIns (spv::OpCapability, 2); + m_spirvCapabilities.putWord(cap); + m_capabilities.insert(cap); + } } } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 20a0d5cc..11b33317 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "../dxvk/dxvk_shader.h" #include "dxbc_chunk_shex.h" @@ -34,6 +36,18 @@ namespace dxvk { private: + DxbcProgramVersion m_version; + DxvkSpirvIdCounter m_counter; + + std::unordered_set m_capabilities; + + DxvkSpirvCodeBuffer m_spirvCapabilities; + DxvkSpirvCodeBuffer m_spirvProgramCode; + + VkShaderStageFlagBits shaderStage() const; + + void enableCapability(spv::Capability cap); + }; } \ No newline at end of file