diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 63a6e1123..812e7b6e3 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -96,9 +96,18 @@ namespace dxvk { if (hasSv) sv = ins.readEnum(op.length()); + const bool hasInterpolationMode = + opcode == DxbcOpcode::DclInputPs + || opcode == DxbcOpcode::DclInputPsSiv; + + DxbcInterpolationMode im = DxbcInterpolationMode::Undefined; + + if (hasInterpolationMode) + im = op.token().interpolationMode(); + m_gen->dclInterfaceVar( op.token().type(), regId, regDim, - op.token().componentMask(), sv); + op.token().componentMask(), sv, im); } break; default: diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 3bafe3428..96838e16a 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -287,6 +287,17 @@ namespace dxvk { return DxbcComponentMask(bit::extract(m_token, 4, 5)); } + /** + * \brief Interpolatin mode + * + * Used by input declarations in pixel shaders. + * Undefined for all other instructions. + */ + DxbcInterpolationMode interpolationMode() const { + return static_cast( + bit::extract(m_token, 11, 14)); + } + /** * \brief Operand type * diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 0f8060862..418ec8174 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -415,6 +415,18 @@ namespace dxvk { }; + enum class DxbcInterpolationMode : uint32_t { + Undefined = 0, + Constant = 1, + Linear = 2, + LinearCentroid = 3, + LinearNoPerspective = 4, + LinearNoperspectiveCentroid = 5, + LinearSample = 6, + LinearNoPerspectiveSample = 7, + }; + + enum class DxbcGlobalFlag : uint32_t { RefactoringAllowed = 0, DoublePrecision = 1, diff --git a/src/dxbc/gen/dxbc_gen_common.h b/src/dxbc/gen/dxbc_gen_common.h index 9a8d2cba0..14d9f9f61 100644 --- a/src/dxbc/gen/dxbc_gen_common.h +++ b/src/dxbc/gen/dxbc_gen_common.h @@ -95,11 +95,12 @@ namespace dxvk { DxbcComponentMask mask); virtual void dclInterfaceVar( - DxbcOperandType regType, - uint32_t regId, - uint32_t regDim, - DxbcComponentMask regMask, - DxbcSystemValue sv) = 0; + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv, + DxbcInterpolationMode im) = 0; virtual DxbcPointer ptrInterfaceVar( DxbcOperandType regType, diff --git a/src/dxbc/gen/dxbc_gen_pixel.cpp b/src/dxbc/gen/dxbc_gen_pixel.cpp index 1dd116dc6..375b08632 100644 --- a/src/dxbc/gen/dxbc_gen_pixel.cpp +++ b/src/dxbc/gen/dxbc_gen_pixel.cpp @@ -56,11 +56,12 @@ namespace dxvk { void DxbcPsCodeGen::dclInterfaceVar( - DxbcOperandType regType, - uint32_t regId, - uint32_t regDim, - DxbcComponentMask regMask, - DxbcSystemValue sv) { + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv, + DxbcInterpolationMode im) { switch (regType) { case DxbcOperandType::Input: { if (m_vRegs.at(regId).valueId == 0) { @@ -91,8 +92,8 @@ namespace dxvk { DxbcPointer DxbcPsCodeGen::ptrInterfaceVar( - DxbcOperandType regType, - uint32_t regId) { + DxbcOperandType regType, + uint32_t regId) { switch (regType) { case DxbcOperandType::Input: return m_vRegs.at(regId); @@ -109,9 +110,9 @@ namespace dxvk { DxbcPointer DxbcPsCodeGen::ptrInterfaceVarIndexed( - DxbcOperandType regType, - uint32_t regId, - const DxbcValue& index) { + DxbcOperandType regType, + uint32_t regId, + const DxbcValue& index) { throw DxvkError(str::format( "DxbcPsCodeGen::ptrInterfaceVarIndexed:\n", "Pixel shaders do not support indexed interface variables")); @@ -140,6 +141,7 @@ namespace dxvk { spv::ExecutionModelFragment, "main", m_entryPointInterfaces.size(), m_entryPointInterfaces.data()); + m_module.setOriginUpperLeft(m_entryPointId); m_module.setDebugName(m_entryPointId, "main"); return m_module.compile(); diff --git a/src/dxbc/gen/dxbc_gen_pixel.h b/src/dxbc/gen/dxbc_gen_pixel.h index b07dc56b1..044000805 100644 --- a/src/dxbc/gen/dxbc_gen_pixel.h +++ b/src/dxbc/gen/dxbc_gen_pixel.h @@ -16,20 +16,21 @@ namespace dxvk { ~DxbcPsCodeGen(); void dclInterfaceVar( - DxbcOperandType regType, - uint32_t regId, - uint32_t regDim, - DxbcComponentMask regMask, - DxbcSystemValue sv); + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv, + DxbcInterpolationMode im); DxbcPointer ptrInterfaceVar( - DxbcOperandType regType, - uint32_t regId); + DxbcOperandType regType, + uint32_t regId); DxbcPointer ptrInterfaceVarIndexed( - DxbcOperandType regType, - uint32_t regId, - const DxbcValue& index); + DxbcOperandType regType, + uint32_t regId, + const DxbcValue& index); SpirvCodeBuffer finalize() final; diff --git a/src/dxbc/gen/dxbc_gen_vertex.cpp b/src/dxbc/gen/dxbc_gen_vertex.cpp index 6e745deb3..f64196f6e 100644 --- a/src/dxbc/gen/dxbc_gen_vertex.cpp +++ b/src/dxbc/gen/dxbc_gen_vertex.cpp @@ -62,11 +62,12 @@ namespace dxvk { void DxbcVsCodeGen::dclInterfaceVar( - DxbcOperandType regType, - uint32_t regId, - uint32_t regDim, - DxbcComponentMask regMask, - DxbcSystemValue sv) { + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv, + DxbcInterpolationMode im) { switch (regType) { case DxbcOperandType::Input: { if (m_vRegs.at(regId).valueId == 0) { @@ -107,8 +108,8 @@ namespace dxvk { DxbcPointer DxbcVsCodeGen::ptrInterfaceVar( - DxbcOperandType regType, - uint32_t regId) { + DxbcOperandType regType, + uint32_t regId) { switch (regType) { case DxbcOperandType::Input: return m_vRegs.at(regId); @@ -125,9 +126,9 @@ namespace dxvk { DxbcPointer DxbcVsCodeGen::ptrInterfaceVarIndexed( - DxbcOperandType regType, - uint32_t regId, - const DxbcValue& index) { + DxbcOperandType regType, + uint32_t regId, + const DxbcValue& index) { throw DxvkError(str::format( "DxbcVsCodeGen::ptrInterfaceVarIndexed:\n", "Vertex shaders do not support indexed interface variables")); diff --git a/src/dxbc/gen/dxbc_gen_vertex.h b/src/dxbc/gen/dxbc_gen_vertex.h index 8d8dac6e4..58d517c70 100644 --- a/src/dxbc/gen/dxbc_gen_vertex.h +++ b/src/dxbc/gen/dxbc_gen_vertex.h @@ -16,20 +16,21 @@ namespace dxvk { ~DxbcVsCodeGen(); void dclInterfaceVar( - DxbcOperandType regType, - uint32_t regId, - uint32_t regDim, - DxbcComponentMask regMask, - DxbcSystemValue sv); + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv, + DxbcInterpolationMode im); DxbcPointer ptrInterfaceVar( - DxbcOperandType regType, - uint32_t regId); + DxbcOperandType regType, + uint32_t regId); DxbcPointer ptrInterfaceVarIndexed( - DxbcOperandType regType, - uint32_t regId, - const DxbcValue& index); + DxbcOperandType regType, + uint32_t regId, + const DxbcValue& index); SpirvCodeBuffer finalize() final; diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index ce9b73574..c4f78b40f 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -95,6 +95,14 @@ namespace dxvk { } + void SpirvModule::setOriginUpperLeft( + uint32_t entryPointId) { + m_execModeInfo.putIns (spv::OpExecutionMode, 3); + m_execModeInfo.putWord(entryPointId); + m_execModeInfo.putWord(spv::ExecutionModeOriginUpperLeft); + } + + void SpirvModule::setDebugName( uint32_t expressionId, const char* debugName) { diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index d68524e05..9bf8a19e4 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -46,6 +46,9 @@ namespace dxvk { uint32_t y, uint32_t z); + void setOriginUpperLeft( + uint32_t entryPointId); + void setDebugName( uint32_t expressionId, const char* debugName);