mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[dxvk] Use SPIR-V pass to swizzle FS outputs instead of spec constants
This commit is contained in:
parent
c401167161
commit
568aae8667
@ -732,17 +732,8 @@ namespace dxvk {
|
||||
|
||||
// Remapping fragment shader outputs would require spec constants
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
VkFormat rtFormat = state.rt.getColorFormat(i);
|
||||
|
||||
if (rtFormat && (m_fsOut & (1u << i)) && state.omBlend[i].colorWriteMask()) {
|
||||
auto mapping = state.omSwizzle[i].mapping();
|
||||
|
||||
if (mapping.r != VK_COMPONENT_SWIZZLE_R
|
||||
|| mapping.g != VK_COMPONENT_SWIZZLE_G
|
||||
|| mapping.b != VK_COMPONENT_SWIZZLE_B
|
||||
|| mapping.a != VK_COMPONENT_SWIZZLE_A)
|
||||
return false;
|
||||
}
|
||||
if (writesRenderTarget(state, i) && !util::isIdentityMapping(state.omSwizzle[i].mapping()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -813,14 +804,6 @@ namespace dxvk {
|
||||
// Set up some specialization constants
|
||||
DxvkSpecConstants specData;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
if ((m_fsOut & (1 << i)) != 0) {
|
||||
specData.set(uint32_t(DxvkSpecConstantId::ColorComponentMappings) + i,
|
||||
state.omSwizzle[i].rIndex() << 0 | state.omSwizzle[i].gIndex() << 4 |
|
||||
state.omSwizzle[i].bIndex() << 8 | state.omSwizzle[i].aIndex() << 12, 0x3210u);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumSpecConstants; i++)
|
||||
specData.set(getSpecId(i), state.sc.specConstants[i], 0u);
|
||||
|
||||
@ -907,9 +890,15 @@ namespace dxvk {
|
||||
DxvkShaderModuleCreateInfo info;
|
||||
|
||||
// Fix up fragment shader outputs for dual-source blending
|
||||
if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||
if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
|
||||
info.fsDualSrcBlend = state.useDualSourceBlending();
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
if (writesRenderTarget(state, i))
|
||||
info.rtSwizzles[i] = state.omSwizzle[i].mapping();
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with undefined shader inputs
|
||||
uint32_t consumedInputs = shaderInfo.inputMask;
|
||||
uint32_t providedInputs = 0;
|
||||
@ -927,7 +916,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs;
|
||||
|
||||
return shader->getCode(m_bindings, info);
|
||||
}
|
||||
|
||||
@ -957,6 +945,20 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
bool DxvkGraphicsPipeline::writesRenderTarget(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
uint32_t target) const {
|
||||
if (!(m_fsOut & (1u << target)))
|
||||
return false;
|
||||
|
||||
if (!state.omBlend[target].colorWriteMask())
|
||||
return false;
|
||||
|
||||
VkFormat rtFormat = state.rt.getColorFormat(target);
|
||||
return rtFormat != VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
|
||||
bool DxvkGraphicsPipeline::validatePipelineState(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
bool trusted) const {
|
||||
|
@ -432,6 +432,10 @@ namespace dxvk {
|
||||
Rc<DxvkShader> getPrevStageShader(
|
||||
VkShaderStageFlagBits stage) const;
|
||||
|
||||
bool writesRenderTarget(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
uint32_t target) const;
|
||||
|
||||
bool validatePipelineState(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
bool trusted) const;
|
||||
|
@ -140,6 +140,10 @@ namespace dxvk {
|
||||
for (uint32_t u : bit::BitMask(state.undefinedInputs))
|
||||
eliminateInput(spirvCode, u);
|
||||
|
||||
// Emit fragment shader swizzles as necessary
|
||||
if (m_info.stage == VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||
emitOutputSwizzles(spirvCode, m_info.outputMask, state.rtSwizzles.data());
|
||||
|
||||
return spirvCode;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user