From 31772af4a5eaae62d2e60626f76ae6b8a885ed85 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 23 Mar 2018 19:48:07 +0100 Subject: [PATCH] [dxbc] Count clipping and culling planes --- src/dxbc/dxbc_analysis.cpp | 28 ++++++++++++++++++++++++++-- src/dxbc/dxbc_analysis.h | 19 +++++++++++++++++++ src/dxbc/dxbc_compiler.cpp | 28 ++++++++++++++-------------- src/dxbc/dxbc_decoder.h | 2 +- src/dxbc/dxbc_module.cpp | 1 + 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/dxbc/dxbc_analysis.cpp b/src/dxbc/dxbc_analysis.cpp index 4dce43551..3ad6d21e7 100644 --- a/src/dxbc/dxbc_analysis.cpp +++ b/src/dxbc/dxbc_analysis.cpp @@ -5,9 +5,17 @@ namespace dxvk { DxbcAnalyzer::DxbcAnalyzer( const DxbcOptions& options, const DxbcProgramVersion& version, + const Rc& isgn, + const Rc& osgn, DxbcAnalysisInfo& analysis) - : m_analysis(&analysis) { - + : m_isgn (isgn), + m_osgn (osgn), + m_analysis(&analysis) { + // Get number of clipping and culling planes from the + // input and output signatures. We will need this to + // declare the shader input and output interfaces. + m_analysis->clipCullIn = getClipCullInfo(m_isgn); + m_analysis->clipCullOut = getClipCullInfo(m_osgn); } @@ -37,4 +45,20 @@ namespace dxvk { } } + + DxbcClipCullInfo DxbcAnalyzer::getClipCullInfo(const Rc& sgn) const { + DxbcClipCullInfo result; + + for (auto e = sgn->begin(); e != sgn->end(); e++) { + const uint32_t componentCount = e->componentMask.popCount(); + + if (e->systemValue == DxbcSystemValue::ClipDistance) + result.numClipPlanes += componentCount; + if (e->systemValue == DxbcSystemValue::CullDistance) + result.numCullPlanes += componentCount; + } + + return result; + } + } \ No newline at end of file diff --git a/src/dxbc/dxbc_analysis.h b/src/dxbc/dxbc_analysis.h index d46778780..d51ede59c 100644 --- a/src/dxbc/dxbc_analysis.h +++ b/src/dxbc/dxbc_analysis.h @@ -21,11 +21,22 @@ namespace dxvk { bool accessAtomicOp = false; }; + /** + * \brief Counts cull and clip distances + */ + struct DxbcClipCullInfo { + uint32_t numClipPlanes = 0; + uint32_t numCullPlanes = 0; + }; + /** * \brief Shader analysis info */ struct DxbcAnalysisInfo { std::array uavInfos; + + DxbcClipCullInfo clipCullIn; + DxbcClipCullInfo clipCullOut; }; /** @@ -42,6 +53,8 @@ namespace dxvk { DxbcAnalyzer( const DxbcOptions& options, const DxbcProgramVersion& version, + const Rc& isgn, + const Rc& osgn, DxbcAnalysisInfo& analysis); ~DxbcAnalyzer(); @@ -55,8 +68,14 @@ namespace dxvk { private: + Rc m_isgn; + Rc m_osgn; + DxbcAnalysisInfo* m_analysis = nullptr; + DxbcClipCullInfo getClipCullInfo( + const Rc& sgn) const; + }; } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 8818779dc..a8ddbbdb5 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1314,7 +1314,7 @@ namespace dxvk { DxbcRegisterValue dst; dst.type.ctype = ins.dst[0].dataType; - dst.type.ccount = ins.dst[0].mask.setCount(); + dst.type.ccount = ins.dst[0].mask.popCount(); const uint32_t typeId = getVectorTypeId(dst.type); @@ -1547,7 +1547,7 @@ namespace dxvk { const DxbcRegisterValue selectTrue = emitRegisterLoad(ins.src[1], ins.dst[0].mask); const DxbcRegisterValue selectFalse = emitRegisterLoad(ins.src[2], ins.dst[0].mask); - const uint32_t componentCount = ins.dst[0].mask.setCount(); + const uint32_t componentCount = ins.dst[0].mask.popCount(); // We'll compare against a vector of zeroes to generate a // boolean vector, which in turn will be used by OpSelect @@ -1593,7 +1593,7 @@ namespace dxvk { emitRegisterLoad(ins.src[1], ins.dst[0].mask), }; - const uint32_t componentCount = ins.dst[0].mask.setCount(); + const uint32_t componentCount = ins.dst[0].mask.popCount(); // Condition, which is a boolean vector used // to select between the ~0u and 0u vectors. @@ -1792,7 +1792,7 @@ namespace dxvk { if (ins.dst[0].type != DxbcOperandType::Null) { DxbcRegisterValue quotient; quotient.type.ctype = ins.dst[0].dataType; - quotient.type.ccount = ins.dst[0].mask.setCount(); + quotient.type.ccount = ins.dst[0].mask.popCount(); quotient.id = m_module.opUDiv( getVectorTypeId(quotient.type), @@ -1805,7 +1805,7 @@ namespace dxvk { if (ins.dst[1].type != DxbcOperandType::Null) { DxbcRegisterValue remainder; remainder.type.ctype = ins.dst[1].dataType; - remainder.type.ccount = ins.dst[1].mask.setCount(); + remainder.type.ccount = ins.dst[1].mask.popCount(); remainder.id = m_module.opUMod( getVectorTypeId(remainder.type), @@ -1836,7 +1836,7 @@ namespace dxvk { DxbcRegisterValue result; result.type.ctype = ins.dst[1].dataType; - result.type.ccount = ins.dst[1].mask.setCount(); + result.type.ccount = ins.dst[1].mask.popCount(); result.id = m_module.opIMul( getVectorTypeId(result.type), src.at(0).id, src.at(1).id); @@ -1863,7 +1863,7 @@ namespace dxvk { DxbcRegisterValue result; result.type.ctype = ins.dst[0].dataType; - result.type.ccount = ins.dst[0].mask.setCount(); + result.type.ccount = ins.dst[0].mask.popCount(); switch (ins.op) { case DxbcOpcode::IShl: @@ -3705,7 +3705,7 @@ namespace dxvk { DxbcRegSwizzle swizzle, DxbcRegMask writeMask) { if (value.type.ccount == 1) - return emitRegisterExtend(value, writeMask.setCount()); + return emitRegisterExtend(value, writeMask.popCount()); std::array indices; @@ -3764,7 +3764,7 @@ namespace dxvk { const uint32_t typeId = getVectorTypeId(result.type); - if (srcMask.setCount() == 0) { + if (srcMask.popCount() == 0) { // Nothing to do if the insertion mask is empty result.id = dstValue.id; } else if (dstValue.type.ccount == 1) { @@ -4361,7 +4361,7 @@ namespace dxvk { // Create result vector DxbcRegisterValue result; result.type.ctype = DxbcScalarType::Uint32; - result.type.ccount = writeMask.setCount(); + result.type.ccount = writeMask.popCount(); result.id = result.type.ccount > 1 ? m_module.opCompositeConstruct(getVectorTypeId(result.type), result.type.ccount, swizzleIds.data()) @@ -4587,9 +4587,9 @@ namespace dxvk { // If the source value consists of only one component, // it is stored in all components of the destination. if (value.type.ccount == 1) - value = emitRegisterExtend(value, writeMask.setCount()); + value = emitRegisterExtend(value, writeMask.popCount()); - if (ptr.type.ccount == writeMask.setCount()) { + if (ptr.type.ccount == writeMask.popCount()) { // Simple case: We write to the entire register m_module.opStore(ptr.id, value.id); } else { @@ -4679,7 +4679,7 @@ namespace dxvk { } result.type.ctype = DxbcScalarType::Uint32; - result.type.ccount = writeMask.setCount(); + result.type.ccount = writeMask.popCount(); result.id = indices.at(0); if (indexId > 1) { @@ -5354,7 +5354,7 @@ namespace dxvk { && e->registerId != 0xFFFFFFFF /* depth */) { DxbcRegisterInfo info; info.type.ctype = e->componentType; - info.type.ccount = e->componentMask.setCount(); + info.type.ccount = e->componentMask.popCount(); info.type.alength = 0; info.sclass = spv::StorageClassOutput; diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index d3d3fdf12..8bc4d9838 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -150,7 +150,7 @@ namespace dxvk { return (m_mask >> id) & 1; } - uint32_t setCount() const { + uint32_t popCount() const { const uint8_t n[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; return n[m_mask & 0xF]; diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index 22cc049f8..5ab1ba856 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -49,6 +49,7 @@ namespace dxvk { DxbcAnalyzer analyzer(options, m_shexChunk->version(), + m_isgnChunk, m_osgnChunk, analysisInfo); DxbcCompiler compiler(options,