From 05e505a844ce024033c196d9cfeef236780cdbf5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 1 Sep 2018 17:56:01 +0200 Subject: [PATCH] [dxbc] Implement pixel shader output component mapping --- src/dxbc/dxbc_compiler.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/dxbc/dxbc_compiler.h | 1 + 2 files changed, 37 insertions(+) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 924acead..10ef7baf 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5202,6 +5202,41 @@ namespace dxvk { } } } + + + void DxbcCompiler::emitOutputMapping() { + // For pixel shaders, we need to swizzle the + // output vectors using some spec constants. + for (uint32_t i = 0; i < m_oRegs.size(); i++) { + if (m_oRegs[i].id == 0 || m_oRegs[i].type.ccount < 2) + continue; + + DxbcRegisterValue vector = emitValueLoad(m_oRegs[i]); + + uint32_t specTypeId = getScalarTypeId(DxbcScalarType::Uint32); + uint32_t compTypeId = getScalarTypeId(vector.type.ctype); + + std::array scalars; + + for (uint32_t c = 0; c < vector.type.ccount; c++) { + const char* components = "rgba"; + + uint32_t specId = m_module.specConst32(specTypeId, c); + m_module.decorateSpecId(specId, uint32_t(DxvkSpecConstantId::ColorComponentMappings) + 4 * i + c); + m_module.setDebugName(specId, str::format("omap", i, ".", components[c]).c_str()); + + scalars[c] = m_module.opVectorExtractDynamic(compTypeId, vector.id, specId); + } + + vector.id = m_module.opCompositeConstruct( + getVectorTypeId(vector.type), + vector.type.ccount, + scalars.data()); + + emitValueStore(m_oRegs[i], vector, + DxbcRegMask::firstN(vector.type.ccount)); + } + } DxbcRegisterValue DxbcCompiler::emitVsSystemValueLoad( @@ -6114,6 +6149,7 @@ namespace dxvk { } this->emitOutputSetup(); + this->emitOutputMapping(); this->emitFunctionEnd(); } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index dfac4a41..5060b66a 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -947,6 +947,7 @@ namespace dxvk { void emitInputSetup(uint32_t vertexCount); void emitOutputSetup(); + void emitOutputMapping(); ////////////////////////////////////////// // System value load methods (per shader)