From 6273780e508dde4f5518794c04f87cb37adf9830 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Wed, 23 Mar 2022 13:41:06 +0100 Subject: [PATCH] vkd3d: Accurately validate dual source blend state. We need to check RTVFormats and IO signature. If both RTVFormat uses non-null format and IO signature has an active entry, we must fail compilation. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/state.c | 51 ++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 7585b09d..3a134d5c 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -2887,7 +2887,37 @@ static HRESULT d3d12_pipeline_state_validate_blend_state(struct d3d12_pipeline_s const struct d3d12_pipeline_state_desc *desc, const struct vkd3d_shader_signature *sig) { const struct vkd3d_format *format; - unsigned int i, j; + unsigned int i, j, register_index; + + if (is_dual_source_blending(&desc->blend_state.RenderTarget[0])) + { + /* If we enable dual source blending, we must fail an RT index > 0 which has + * an IO-sig entry with non-NULL format. */ + for (i = 0; i < sig->element_count; i++) + { + register_index = sig->elements[i].register_index; + if (register_index >= ARRAY_SIZE(desc->rtv_formats.RTFormats)) + { + WARN("Register index %u out of bounds.\n", register_index); + return E_INVALIDARG; + } + + if (register_index > 0) + { + if (desc->rtv_formats.RTFormats[register_index] != DXGI_FORMAT_UNKNOWN) + { + WARN("Cannot enable dual-source blending for active RT %u.\n", register_index); + return E_INVALIDARG; + } + + if (desc->blend_state.IndependentBlendEnable && desc->blend_state.RenderTarget[i].BlendEnable) + { + WARN("Blend enable cannot be set for render target %u when dual source blending is used.\n", i); + return E_INVALIDARG; + } + } + } + } for (i = 0; i < desc->rtv_formats.NumRenderTargets; i++) { @@ -3145,25 +3175,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s sizeof(graphics->blend_attachments[0]) * (ARRAY_SIZE(graphics->blend_attachments) - 1)); } - if (compile_args.dual_source_blending && rt_count > 1) - { - WARN("Only one render target is allowed when dual source blending is used.\n"); - hr = E_INVALIDARG; - goto fail; - } - if (compile_args.dual_source_blending && desc->blend_state.IndependentBlendEnable) - { - for (i = 1; i < ARRAY_SIZE(desc->blend_state.RenderTarget); ++i) - { - if (desc->blend_state.RenderTarget[i].BlendEnable) - { - WARN("Blend enable cannot be set for render target %u when dual source blending is used.\n", i); - hr = E_INVALIDARG; - goto fail; - } - } - } - graphics->xfb_enabled = false; if (so_desc->NumEntries) {