Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2023-08-01 17:58:46 +0300
committerPhilip Rebohle <philip.rebohle@tu-dortmund.de>2023-08-01 17:58:46 +0300
commitd66f8385c38abc73c6b4f69a510282334f3faadf (patch)
tree989a833bb802b647cd48135de1eee97ae22873f5
parent007e9f4c89a61ccd05b312145bc03aaf7a91665f (diff)
[dxvk] Disable alpha to coverage if sample mask is writtenatoc-omask
Matches D3D11 behaviour and fixes tree rendering in A Total War Saga: TROY.
-rw-r--r--src/dxvk/dxvk_context.cpp3
-rw-r--r--src/dxvk/dxvk_graphics.cpp21
-rw-r--r--src/dxvk/dxvk_graphics.h2
-rw-r--r--src/dxvk/dxvk_shader.cpp6
4 files changed, 24 insertions, 8 deletions
diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp
index f2a1e862..31e15e28 100644
--- a/src/dxvk/dxvk_context.cpp
+++ b/src/dxvk/dxvk_context.cpp
@@ -5769,7 +5769,8 @@ namespace dxvk {
VkSampleMask sampleMask = m_state.gp.state.ms.sampleMask() & ((1u << sampleCount) - 1u);
m_cmd->cmdSetMultisampleState(sampleCount, sampleMask);
- if (m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable)
+ if (m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable
+ && !m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasSampleMaskExport))
m_cmd->cmdSetAlphaToCoverageState(m_state.gp.state.ms.enableAlphaToCoverage());
}
diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp
index 0f2216ea..76df237d 100644
--- a/src/dxvk/dxvk_graphics.cpp
+++ b/src/dxvk/dxvk_graphics.cpp
@@ -301,9 +301,12 @@ namespace dxvk {
msInfo.minSampleShading = 1.0f;
}
+ // Alpha to coverage is not supported with sample mask exports.
+ cbUseDynamicAlphaToCoverage = !fs || !fs->flags().test(DxvkShaderFlag::ExportsSampleMask);
+
msSampleMask = state.ms.sampleMask() & ((1u << msInfo.rasterizationSamples) - 1);
msInfo.pSampleMask = &msSampleMask;
- msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage();
+ msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage() && cbUseDynamicAlphaToCoverage;
// We need to be fully consistent with the pipeline state here, and
// while we could consistently infer it, just don't take any chances
@@ -325,6 +328,7 @@ namespace dxvk {
&& msInfo.alphaToOneEnable == other.msInfo.alphaToOneEnable
&& msSampleMask == other.msSampleMask
&& cbUseDynamicBlendConstants == other.cbUseDynamicBlendConstants
+ && cbUseDynamicAlphaToCoverage == other.cbUseDynamicAlphaToCoverage
&& feedbackLoop == other.feedbackLoop;
for (uint32_t i = 0; i < rtInfo.colorAttachmentCount && eq; i++)
@@ -364,6 +368,7 @@ namespace dxvk {
hash.add(uint32_t(msInfo.alphaToOneEnable));
hash.add(uint32_t(msSampleMask));
hash.add(uint32_t(cbUseDynamicBlendConstants));
+ hash.add(uint32_t(cbUseDynamicAlphaToCoverage));
hash.add(uint32_t(feedbackLoop));
for (uint32_t i = 0; i < rtInfo.colorAttachmentCount; i++)
@@ -402,7 +407,8 @@ namespace dxvk {
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
- if (device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable)
+ if (device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable
+ && state.cbUseDynamicAlphaToCoverage)
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
}
@@ -944,8 +950,12 @@ namespace dxvk {
if (m_barrier.access & VK_ACCESS_SHADER_WRITE_BIT)
m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors);
- if (m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading))
- m_flags.set(DxvkGraphicsPipelineFlag::HasSampleRateShading);
+ if (m_shaders.fs != nullptr) {
+ if (m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading))
+ m_flags.set(DxvkGraphicsPipelineFlag::HasSampleRateShading);
+ if (m_shaders.fs->flags().test(DxvkShaderFlag::ExportsSampleMask))
+ m_flags.set(DxvkGraphicsPipelineFlag::HasSampleMaskExport);
+ }
}
@@ -1183,7 +1193,8 @@ namespace dxvk {
return false;
if (!canUseDynamicAlphaToCoverage
- && (state.ms.enableAlphaToCoverage()))
+ && (state.ms.enableAlphaToCoverage())
+ && !m_shaders.fs->flags().test(DxvkShaderFlag::ExportsSampleMask))
return false;
}
}
diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h
index 262b3901..435677a8 100644
--- a/src/dxvk/dxvk_graphics.h
+++ b/src/dxvk/dxvk_graphics.h
@@ -31,6 +31,7 @@ namespace dxvk {
HasTransformFeedback,
HasStorageDescriptors,
HasSampleRateShading,
+ HasSampleMaskExport,
};
using DxvkGraphicsPipelineFlags = Flags<DxvkGraphicsPipelineFlag>;
@@ -116,6 +117,7 @@ namespace dxvk {
VkSampleMask msSampleMask = 0u;
VkBool32 cbUseDynamicBlendConstants = VK_FALSE;
+ VkBool32 cbUseDynamicAlphaToCoverage = VK_FALSE;
std::array<VkPipelineColorBlendAttachmentState, MaxNumRenderTargets> cbAttachments = { };
std::array<VkFormat, MaxNumRenderTargets> rtColorFormats = { };
diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp
index 3208c008..dbebf715 100644
--- a/src/dxvk/dxvk_shader.cpp
+++ b/src/dxvk/dxvk_shader.cpp
@@ -1296,8 +1296,10 @@ namespace dxvk {
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
- if (m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable)
- dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
+ if (!m_shaders.fs || !m_shaders.fs->flags().test(DxvkShaderFlag::ExportsSampleMask)) {
+ if (m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable)
+ dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
+ }
}
VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };