From 4c0404d3c6e5d3eb43bb40e7f6127daebe55b227 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 17 Nov 2017 11:41:46 +0100 Subject: [PATCH] [dxbc] Removes shader input/output interfaces for now, needs more work --- src/dxbc/gen/dxbc_gen_common.cpp | 66 ++++++++++++++++++++++++++ src/dxbc/gen/dxbc_gen_common.h | 11 +++++ src/dxbc/gen/dxbc_gen_pixel.cpp | 64 ++++++++++++------------- src/dxbc/gen/dxbc_gen_pixel.h | 6 +-- src/dxbc/gen/dxbc_gen_vertex.cpp | 80 ++++++++------------------------ src/dxbc/gen/dxbc_gen_vertex.h | 8 ++-- 6 files changed, 133 insertions(+), 102 deletions(-) diff --git a/src/dxbc/gen/dxbc_gen_common.cpp b/src/dxbc/gen/dxbc_gen_common.cpp index 2463ba59..5fc29a63 100644 --- a/src/dxbc/gen/dxbc_gen_common.cpp +++ b/src/dxbc/gen/dxbc_gen_common.cpp @@ -102,6 +102,33 @@ namespace dxvk { return result; } + + DxbcValue DxbcCodeGen::opAdd(const DxbcValue& a, const DxbcValue& b) { + DxbcValue result; + result.type = a.type; + + switch (result.type.componentType) { + case DxbcScalarType::Sint32: + case DxbcScalarType::Sint64: + case DxbcScalarType::Uint32: + case DxbcScalarType::Uint64: + result.valueId = m_module.opIAdd( + this->defValueType(result.type), + a.valueId, b.valueId); + break; + + case DxbcScalarType::Float32: + case DxbcScalarType::Float64: + result.valueId = m_module.opFAdd( + this->defValueType(result.type), + a.valueId, b.valueId); + break; + } + + return result; + } + + DxbcValue DxbcCodeGen::opNeg(const DxbcValue& src) { DxbcValue result; result.type = src.type; @@ -128,6 +155,41 @@ namespace dxvk { } + DxbcValue DxbcCodeGen::opSaturate(const DxbcValue& src) { + const uint32_t typeId = this->defValueType(src.type); + + std::array const0; + std::array const1; + + uint32_t const0Id = 0; + uint32_t const1Id = 0; + + if (src.type.componentType == DxbcScalarType::Float32) { + const0Id = m_module.constf32(0.0f); + const1Id = m_module.constf32(1.0f); + } else if (src.type.componentType == DxbcScalarType::Float64) { + const0Id = m_module.constf64(0.0); + const1Id = m_module.constf64(1.0); + } + + for (uint32_t i = 0; i < src.type.componentCount; i++) { + const0.at(i) = const0Id; + const1.at(i) = const1Id; + } + + if (src.type.componentCount > 1) { + const0Id = m_module.constComposite(typeId, src.type.componentCount, const0.data()); + const1Id = m_module.constComposite(typeId, src.type.componentCount, const1.data()); + } + + DxbcValue result; + result.type = src.type; + result.valueId = m_module.opFClamp( + typeId, src.valueId, const0Id, const1Id); + return result; + } + + DxbcValue DxbcCodeGen::regCast( const DxbcValue& src, const DxbcValueType& type) { @@ -163,6 +225,8 @@ namespace dxvk { indices[dstIndex++] = swizzle[i]; } + // If the swizzle combined with the mask can be reduced + // to a no-op, we don't need to insert any instructions. bool isIdentitySwizzle = dstIndex == src.type.componentCount; for (uint32_t i = 0; i < dstIndex && isIdentitySwizzle; i++) @@ -171,6 +235,8 @@ namespace dxvk { if (isIdentitySwizzle) return src; + // Use OpCompositeExtract if the resulting vector contains + // only one component, and OpVectorShuffle if it is a vector. DxbcValue result; result.type = DxbcValueType(src.type.componentType, dstIndex); diff --git a/src/dxbc/gen/dxbc_gen_common.h b/src/dxbc/gen/dxbc_gen_common.h index 6d7c9a15..fa208225 100644 --- a/src/dxbc/gen/dxbc_gen_common.h +++ b/src/dxbc/gen/dxbc_gen_common.h @@ -132,9 +132,20 @@ namespace dxvk { DxbcValue opAbs( const DxbcValue& src); + DxbcValue opAdd( + const DxbcValue& a, + const DxbcValue& b); + + DxbcValue opMul( + const DxbcValue& a, + const DxbcValue& b); + DxbcValue opNeg( const DxbcValue& src); + DxbcValue opSaturate( + const DxbcValue& src); + /** * \brief Casts register value to another type * diff --git a/src/dxbc/gen/dxbc_gen_pixel.cpp b/src/dxbc/gen/dxbc_gen_pixel.cpp index a9d9b46f..57ccd0a0 100644 --- a/src/dxbc/gen/dxbc_gen_pixel.cpp +++ b/src/dxbc/gen/dxbc_gen_pixel.cpp @@ -33,46 +33,22 @@ namespace dxvk { DxbcSystemValue sv) { switch (regType) { case DxbcOperandType::Input: { - if (sv == DxbcSystemValue::None) { - if (m_vRegs.at(regId).valueId == 0) { - m_vRegs.at(regId) = this->defVar( - DxbcValueType(DxbcScalarType::Float32, 4), - spv::StorageClassInput); - m_module.setDebugName(m_vRegs.at(regId).valueId, - str::format("v", regId).c_str()); - m_module.decorateLocation( - m_vRegs.at(regId).valueId, regId); - m_entryPointInterfaces.push_back( - m_vRegs.at(regId).valueId); - } - } else { - if (m_vRegsSv.at(regId).valueId == 0) { - m_vRegsSv.at(regId) = this->defVar( - DxbcValueType(DxbcScalarType::Float32, 4), - spv::StorageClassPrivate); - m_module.setDebugName(m_vRegsSv.at(regId).valueId, - str::format("sv", regId).c_str()); - } + if (m_vRegs.at(regId).valueId == 0) { + m_vRegs.at(regId) = this->defVar( + DxbcValueType(DxbcScalarType::Float32, 4), + spv::StorageClassPrivate); + m_module.setDebugName(m_vRegs.at(regId).valueId, + str::format("v", regId).c_str()); } } break; case DxbcOperandType::Output: { - if (sv != DxbcSystemValue::None) { - throw DxvkError(str::format( - "DxbcPsCodeGen::dclInterfaceVar: Cannot map output register to system value: ", - sv)); - } - if (m_oRegs.at(regId).valueId == 0) { m_oRegs.at(regId) = this->defVar( DxbcValueType(DxbcScalarType::Float32, 4), - spv::StorageClassOutput); + spv::StorageClassPrivate); m_module.setDebugName(m_oRegs.at(regId).valueId, str::format("o", regId).c_str()); - m_module.decorateLocation( - m_oRegs.at(regId).valueId, regId); - m_entryPointInterfaces.push_back( - m_oRegs.at(regId).valueId); } } break; @@ -89,13 +65,11 @@ namespace dxvk { uint32_t regId) { switch (regType) { case DxbcOperandType::Input: - return m_vRegsSv.at(regId).valueId != 0 - ? m_vRegsSv.at(regId) - : m_vRegs .at(regId); + return m_vRegs.at(regId); case DxbcOperandType::Output: return m_oRegs.at(regId); - + default: throw DxvkError(str::format( "DxbcPsCodeGen::ptrInterfaceVar: Unhandled operand type: ", @@ -143,6 +117,26 @@ namespace dxvk { } + void DxbcPsCodeGen::dclSvInputReg(DxbcSystemValue sv) { + switch (sv) { + case DxbcSystemValue::Position: { + m_svPosition = this->defVar( + DxbcValueType(DxbcScalarType::Float32, 4), + spv::StorageClassInput); + m_entryPointInterfaces.push_back( + m_svPosition.valueId); + + m_module.setDebugName(m_svPosition.valueId, "sv_position"); + m_module.decorateBuiltIn(m_svPosition.valueId, spv::BuiltInFragCoord); + } break; + + default: + throw DxvkError(str::format( + "DxbcPsCodeGen::dclSvInputReg: Unhandled SV: ", sv)); + } + } + + void DxbcPsCodeGen::prepareSvInputs() { } diff --git a/src/dxbc/gen/dxbc_gen_pixel.h b/src/dxbc/gen/dxbc_gen_pixel.h index eb280491..226c745a 100644 --- a/src/dxbc/gen/dxbc_gen_pixel.h +++ b/src/dxbc/gen/dxbc_gen_pixel.h @@ -35,14 +35,14 @@ namespace dxvk { private: uint32_t m_function = 0; + uint32_t m_psIn = 0; DxbcPointer m_svPosition; std::array m_vRegs; - std::array m_vRegsSv; - std::array m_oRegs; + std::array m_oRegs; - std::vector m_svInputs; + void dclSvInputReg(DxbcSystemValue sv); void prepareSvInputs(); void prepareSvOutputs(); diff --git a/src/dxbc/gen/dxbc_gen_vertex.cpp b/src/dxbc/gen/dxbc_gen_vertex.cpp index 262d454b..33a9a374 100644 --- a/src/dxbc/gen/dxbc_gen_vertex.cpp +++ b/src/dxbc/gen/dxbc_gen_vertex.cpp @@ -18,11 +18,12 @@ namespace dxvk { spv::FunctionControlMaskNone); m_module.opLabel(m_module.allocateId()); - m_outPerVertex = m_module.newVar( + // Declare per-vertex builtin output block + m_vsPerVertex = m_module.newVar( m_module.defPointerType(this->defPerVertexBlock(), spv::StorageClassOutput), spv::StorageClassOutput); - m_entryPointInterfaces.push_back(m_outPerVertex); - m_module.setDebugName(m_outPerVertex, "vs_out"); + m_entryPointInterfaces.push_back(m_vsPerVertex); + m_module.setDebugName(m_vsPerVertex, "vs_per_vertex"); } @@ -39,26 +40,12 @@ namespace dxvk { DxbcSystemValue sv) { switch (regType) { case DxbcOperandType::Input: { - if (sv == DxbcSystemValue::None) { - if (m_vRegs.at(regId).valueId == 0) { - m_vRegs.at(regId) = this->defVar( - DxbcValueType(DxbcScalarType::Float32, 4), - spv::StorageClassInput); - m_module.setDebugName(m_vRegs.at(regId).valueId, - str::format("v", regId).c_str()); - m_module.decorateLocation( - m_vRegs.at(regId).valueId, regId); - m_entryPointInterfaces.push_back( - m_vRegs.at(regId).valueId); - } - } else { - if (m_vRegsSv.at(regId).valueId == 0) { - m_vRegsSv.at(regId) = this->defVar( - DxbcValueType(DxbcScalarType::Float32, 4), - spv::StorageClassPrivate); - m_module.setDebugName(m_vRegsSv.at(regId).valueId, - str::format("sv", regId).c_str()); - } + if (m_vRegs.at(regId).valueId == 0) { + m_vRegs.at(regId) = this->defVar( + DxbcValueType(DxbcScalarType::Float32, 4), + spv::StorageClassPrivate); + m_module.setDebugName(m_vRegs.at(regId).valueId, + str::format("v", regId).c_str()); } } break; @@ -66,18 +53,9 @@ namespace dxvk { if (m_oRegs.at(regId).valueId == 0) { m_oRegs.at(regId) = this->defVar( DxbcValueType(DxbcScalarType::Float32, 4), - spv::StorageClassOutput); + spv::StorageClassPrivate); m_module.setDebugName(m_oRegs.at(regId).valueId, str::format("o", regId).c_str()); - m_module.decorateLocation( - m_oRegs.at(regId).valueId, regId); - m_entryPointInterfaces.push_back( - m_oRegs.at(regId).valueId); - } - - if (sv != DxbcSystemValue::None) { - m_svOutputs.push_back(DxbcSvMapping { - regId, regMask, sv }); } } break; @@ -94,9 +72,7 @@ namespace dxvk { uint32_t regId) { switch (regType) { case DxbcOperandType::Input: - return m_vRegsSv.at(regId).valueId != 0 - ? m_vRegsSv.at(regId) - : m_vRegs .at(regId); + return m_vRegs.at(regId); case DxbcOperandType::Output: return m_oRegs.at(regId); @@ -148,34 +124,18 @@ namespace dxvk { } + void DxbcVsCodeGen::dclSvInputReg(DxbcSystemValue sv) { + + } + + void DxbcVsCodeGen::prepareSvInputs() { - // TODO implement + } void DxbcVsCodeGen::prepareSvOutputs() { - for (const auto& sv : m_svOutputs) { - DxbcValue val = this->regLoad(m_oRegs.at(sv.regId)); -// val = this->regExtract(val, sv.regMask); - - DxbcPointer dst; - - switch (sv.sv) { - case DxbcSystemValue::Position: - dst = this->ptrBuiltInPosition(); - break; - - default: - Logger::err(str::format( - "DxbcVsCodeGen::prepareSvOutputs: Unsupported system value: ", - sv.sv)); - } - - if (dst.valueId != 0) { -// val = this->regCast(val, dst.type.valueType); - this->regStore(dst, val, DxbcComponentMask()); - } - } + } @@ -188,7 +148,7 @@ namespace dxvk { spv::StorageClassOutput); result.valueId = m_module.opAccessChain( this->defPointerType(result.type), - m_outPerVertex, 1, &memberId); + m_vsPerVertex, 1, &memberId); return result; } diff --git a/src/dxbc/gen/dxbc_gen_vertex.h b/src/dxbc/gen/dxbc_gen_vertex.h index 9c66c526..890065c3 100644 --- a/src/dxbc/gen/dxbc_gen_vertex.h +++ b/src/dxbc/gen/dxbc_gen_vertex.h @@ -35,14 +35,14 @@ namespace dxvk { private: uint32_t m_function = 0; - uint32_t m_outPerVertex = 0; + uint32_t m_vsPerVertex = 0; + uint32_t m_vsOut = 0; + std::array m_vsIn; std::array m_vRegs; - std::array m_vRegsSv; std::array m_oRegs; - std::vector m_svInputs; - std::vector m_svOutputs; + void dclSvInputReg(DxbcSystemValue sv); void prepareSvInputs(); void prepareSvOutputs();