diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 9dbee21e..63a6e112 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -3,8 +3,10 @@ namespace dxvk { DxbcCompiler::DxbcCompiler( - const DxbcProgramVersion& version) - : m_gen(DxbcCodeGen::create(version)) { } + const DxbcProgramVersion& version, + const Rc& isgn, + const Rc& osgn) + : m_gen(DxbcCodeGen::create(version, isgn, osgn)) { } DxbcCompiler::~DxbcCompiler() { diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index a40a8f5c..aa007640 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -15,11 +15,13 @@ namespace dxvk { public: DxbcCompiler( - const DxbcProgramVersion& version); + const DxbcProgramVersion& version, + const Rc& isgn, + const Rc& osgn); ~DxbcCompiler(); void processInstruction( - const DxbcInstruction& ins); + const DxbcInstruction& ins); SpirvCodeBuffer finalize(); diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index e1d1b6f8..c6819e37 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -44,7 +44,10 @@ namespace dxvk { if (m_shexChunk == nullptr) throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); - DxbcCompiler compiler(m_shexChunk->version()); + DxbcCompiler compiler( + m_shexChunk->version(), + m_isgnChunk, m_osgnChunk); + for (auto ins : *m_shexChunk) compiler.processInstruction(ins); return compiler.finalize(); diff --git a/src/dxbc/gen/dxbc_gen_common.cpp b/src/dxbc/gen/dxbc_gen_common.cpp index 5fc29a63..eea20667 100644 --- a/src/dxbc/gen/dxbc_gen_common.cpp +++ b/src/dxbc/gen/dxbc_gen_common.cpp @@ -329,13 +329,15 @@ namespace dxvk { Rc DxbcCodeGen::create( - const DxbcProgramVersion& version) { + const DxbcProgramVersion& version, + const Rc& isgn, + const Rc& osgn) { switch (version.type()) { case DxbcProgramType::PixelShader: - return new DxbcPsCodeGen(); + return new DxbcPsCodeGen(osgn); case DxbcProgramType::VertexShader: - return new DxbcVsCodeGen(); + return new DxbcVsCodeGen(isgn); default: throw DxvkError(str::format( diff --git a/src/dxbc/gen/dxbc_gen_common.h b/src/dxbc/gen/dxbc_gen_common.h index b643da63..9a8d2cba 100644 --- a/src/dxbc/gen/dxbc_gen_common.h +++ b/src/dxbc/gen/dxbc_gen_common.h @@ -1,5 +1,6 @@ #pragma once +#include "../dxbc_chunk_isgn.h" #include "../dxbc_common.h" #include "../dxbc_decoder.h" #include "../dxbc_type.h" @@ -112,7 +113,9 @@ namespace dxvk { virtual SpirvCodeBuffer finalize() = 0; static Rc create( - const DxbcProgramVersion& version); + const DxbcProgramVersion& version, + const Rc& isgn, + const Rc& osgn); protected: diff --git a/src/dxbc/gen/dxbc_gen_pixel.cpp b/src/dxbc/gen/dxbc_gen_pixel.cpp index 296183e7..2bd6c0bc 100644 --- a/src/dxbc/gen/dxbc_gen_pixel.cpp +++ b/src/dxbc/gen/dxbc_gen_pixel.cpp @@ -2,7 +2,8 @@ namespace dxvk { - DxbcPsCodeGen::DxbcPsCodeGen() { + DxbcPsCodeGen::DxbcPsCodeGen( + const Rc& osgn) { m_module.enableCapability(spv::CapabilityShader); m_module.enableCapability(spv::CapabilityCullDistance); m_module.enableCapability(spv::CapabilityClipDistance); @@ -17,6 +18,22 @@ namespace dxvk { m_module.defVoidType(), 0, nullptr), spv::FunctionControlMaskNone); m_module.opLabel(m_module.allocateId()); + + // Declare outputs based on the input signature + for (auto e = osgn->begin(); e != osgn->end(); e++) { + if (e->systemValue == DxbcSystemValue::None) { + m_psOut.at(e->registerId) = this->defVar( + DxbcValueType(e->componentType, e->componentMask.componentCount()), + spv::StorageClassOutput); + m_module.decorateLocation( + m_psOut.at(e->registerId).valueId, + e->registerId); + m_module.setDebugName(m_psOut.at(e->registerId).valueId, + str::format("ps_out", e->registerId).c_str()); + m_entryPointInterfaces.push_back( + m_psOut.at(e->registerId).valueId); + } + } } @@ -142,7 +159,17 @@ namespace dxvk { void DxbcPsCodeGen::prepareSvOutputs() { + // TODO properly re-implement this + std::array masks = { 0x0, 0x1, 0x3, 0x7, 0xF }; + for (uint32_t i = 0; i < m_psOut.size(); i++) { + if ((m_psOut.at(i).valueId != 0) && (m_oRegs.at(i).valueId != 0)) { + DxbcValue srcValue = this->regLoad(m_oRegs.at(i)); + srcValue = this->regCast(srcValue, m_psOut.at(i).type.valueType); + this->regStore(m_psOut.at(i), srcValue, DxbcComponentMask( + masks.at(m_psOut.at(i).type.valueType.componentCount))); + } + } } } \ No newline at end of file diff --git a/src/dxbc/gen/dxbc_gen_pixel.h b/src/dxbc/gen/dxbc_gen_pixel.h index 915d659e..5433ea8b 100644 --- a/src/dxbc/gen/dxbc_gen_pixel.h +++ b/src/dxbc/gen/dxbc_gen_pixel.h @@ -11,7 +11,8 @@ namespace dxvk { public: - DxbcPsCodeGen(); + DxbcPsCodeGen( + const Rc& osgn); ~DxbcPsCodeGen(); void dclInterfaceVar( @@ -41,6 +42,7 @@ namespace dxvk { std::array m_vRegs; std::array m_oRegs; + std::array m_psOut; void dclSvInputReg(DxbcSystemValue sv); diff --git a/src/dxbc/gen/dxbc_gen_vertex.cpp b/src/dxbc/gen/dxbc_gen_vertex.cpp index 2c78d938..15a76911 100644 --- a/src/dxbc/gen/dxbc_gen_vertex.cpp +++ b/src/dxbc/gen/dxbc_gen_vertex.cpp @@ -2,7 +2,7 @@ namespace dxvk { - DxbcVsCodeGen::DxbcVsCodeGen() { + DxbcVsCodeGen::DxbcVsCodeGen(const Rc& isgn) { m_module.enableCapability(spv::CapabilityShader); m_module.enableCapability(spv::CapabilityCullDistance); m_module.enableCapability(spv::CapabilityClipDistance); @@ -24,6 +24,22 @@ namespace dxvk { spv::StorageClassOutput); m_entryPointInterfaces.push_back(m_vsPerVertex); m_module.setDebugName(m_vsPerVertex, "vs_per_vertex"); + + // Declare vertex inputs based on the input signature + for (auto e = isgn->begin(); e != isgn->end(); e++) { + if (e->systemValue == DxbcSystemValue::None) { + m_vsIn.at(e->registerId) = this->defVar( + DxbcValueType(e->componentType, 4), + spv::StorageClassInput); + m_module.decorateLocation( + m_vsIn.at(e->registerId).valueId, + e->registerId); + m_module.setDebugName(m_vsIn.at(e->registerId).valueId, + str::format("vs_in", e->registerId).c_str()); + m_entryPointInterfaces.push_back( + m_vsIn.at(e->registerId).valueId); + } + } } @@ -47,6 +63,11 @@ namespace dxvk { m_module.setDebugName(m_vRegs.at(regId).valueId, str::format("v", regId).c_str()); } + + if (sv != DxbcSystemValue::None) { + m_svIn.push_back(DxbcSvMapping { + regId, regMask, sv }); + } } break; case DxbcOperandType::Output: { @@ -57,6 +78,11 @@ namespace dxvk { m_module.setDebugName(m_oRegs.at(regId).valueId, str::format("o", regId).c_str()); } + + if (sv != DxbcSystemValue::None) { + m_svOut.push_back(DxbcSvMapping { + regId, regMask, sv }); + } } break; default: @@ -129,12 +155,35 @@ namespace dxvk { void DxbcVsCodeGen::prepareSvInputs() { + DxbcValueType targetType(DxbcScalarType::Float32, 4); + // Copy vertex inputs to the actual shader input registers + for (uint32_t i = 0; i < m_vsIn.size(); i++) { + if ((m_vsIn.at(i).valueId != 0) && (m_vRegs.at(i).valueId != 0)) { + DxbcValue srcValue = this->regLoad(m_vsIn.at(i)); + srcValue = this->regCast(srcValue, targetType); + this->regStore(m_vRegs.at(i), srcValue, + DxbcComponentMask(true, true, true, true)); + } + } + + // TODO system values } void DxbcVsCodeGen::prepareSvOutputs() { + // TODO add user-defined shader outputs + for (const auto& mapping : m_svOut) { + DxbcValue srcValue = this->regLoad(m_oRegs.at(mapping.regId)); + + switch (mapping.sv) { + case DxbcSystemValue::Position: { + this->regStore(this->ptrBuiltInPosition(), srcValue, + DxbcComponentMask(true, true, true, true)); + } break; + } + } } diff --git a/src/dxbc/gen/dxbc_gen_vertex.h b/src/dxbc/gen/dxbc_gen_vertex.h index 9b2586ef..24dd47bd 100644 --- a/src/dxbc/gen/dxbc_gen_vertex.h +++ b/src/dxbc/gen/dxbc_gen_vertex.h @@ -11,7 +11,8 @@ namespace dxvk { public: - DxbcVsCodeGen(); + DxbcVsCodeGen( + const Rc& isgn); ~DxbcVsCodeGen(); void dclInterfaceVar( @@ -42,6 +43,9 @@ namespace dxvk { std::array m_vRegs; std::array m_oRegs; + std::vector m_svIn; + std::vector m_svOut; + void dclSvInputReg(DxbcSystemValue sv); void prepareSvInputs(); diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 9717a1af..13e508c1 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -184,54 +184,72 @@ namespace dxvk { AddFormat( DXGI_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT, {}, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); AddFormat( DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, {}, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT); AddFormat( DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB, {}, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT); AddFormat( DXGI_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT, {}, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); AddFormat( DXGI_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM, {}, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT); + + AddFormat( + DXGI_FORMAT_R32G32B32_FLOAT, + VK_FORMAT_R32G32B32_SFLOAT, {}, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT); + + AddFormat( + DXGI_FORMAT_R32G32B32A32_FLOAT, + VK_FORMAT_R32G32B32A32_SFLOAT, {}, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT); AddFormat( DXGI_FORMAT_D24_UNORM_S8_UINT, diff --git a/tests/meson.build b/tests/meson.build index 16eeef6c..b6efa377 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,6 +1,6 @@ lib_d3d11 = dxvk_compiler.find_library('d3d11') lib_dxgi = dxvk_compiler.find_library('dxgi') -lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler') +lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler_47') subdir('d3d11') subdir('dxbc')