Module: Mesa Branch: staging/20.2 Commit: 8c2ad9f9cba6c57c26cf34f1d9333fed8b0884f6 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8c2ad9f9cba6c57c26cf34f1d9333fed8b0884f6
Author: Rhys Perry <[email protected]> Date: Wed Oct 7 20:07:42 2020 +0100 spirv: replace discard with demote for incorrect HLSL->SPIR-V translations Fixes artifacts on decals in Path of Exile. Signed-off-by: Rhys Perry <[email protected]> Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]> Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3610 Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7062> (cherry picked from commit 037d9fb278c44bf5bd8fea6c6c78af321555d141) --- .pick_status.json | 2 +- src/compiler/spirv/spirv_to_nir.c | 21 +++++++++++++++++++-- src/compiler/spirv/vtn_cfg.c | 4 +++- src/compiler/spirv/vtn_private.h | 8 ++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 57809707fbd..bb8abac0eb0 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -5332,7 +5332,7 @@ "description": "spirv: replace discard with demote for incorrect HLSL->SPIR-V translations", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 423831cc0ec..88fbfe8c460 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -4086,6 +4086,8 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, (count > 3) ? vtn_value(b, w[3], vtn_value_type_string)->str : ""; vtn_info("Parsing SPIR-V from %s %u source file %s", lang, version, file); + + b->source_lang = w[1]; break; } @@ -4340,6 +4342,7 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode, case SpvCapabilityDemoteToHelperInvocationEXT: spv_check_supported(demote_to_helper_invocation, cap); + b->uses_demote_to_helper_invocation = true; break; case SpvCapabilityShaderClockKHR: @@ -5423,7 +5426,7 @@ vtn_create_builder(const uint32_t *words, size_t word_count, goto fail; } - uint16_t generator_id = words[2] >> 16; + b->generator_id = words[2] >> 16; uint16_t generator_version = words[2]; /* In GLSLang commit 8297936dd6eb3, their handling of barrier() was fixed @@ -5432,7 +5435,7 @@ vtn_create_builder(const uint32_t *words, size_t word_count, * GLSLang fix caused them to bump to generator version 3. */ b->wa_glslang_cs_barrier = - (generator_id == vtn_generator_glslang_reference_front_end && + (b->generator_id == vtn_generator_glslang_reference_front_end && generator_version < 3); /* words[2] == generator magic */ @@ -5545,6 +5548,20 @@ spirv_to_nir(const uint32_t *words, size_t word_count, words = vtn_foreach_instruction(b, words, word_end, vtn_handle_preamble_instruction); + /* DirectXShaderCompiler and glslang/shaderc both create OpKill from HLSL's + * discard/clip, which uses demote semantics. DirectXShaderCompiler will use + * demote if the extension is enabled, so we disable this workaround in that + * case. + * + * Related glslang issue: https://github.com/KhronosGroup/glslang/issues/2416 + */ + bool glslang = b->generator_id == vtn_generator_glslang_reference_front_end || + b->generator_id == vtn_generator_shaderc_over_glslang; + bool dxsc = b->generator_id == vtn_generator_spiregg; + b->convert_discard_to_demote = ((dxsc && !b->uses_demote_to_helper_invocation) || + (glslang && b->source_lang == SpvSourceLanguageHLSL)) && + options->caps.demote_to_helper_invocation; + if (b->entry_point == NULL) { vtn_fail("Entry point not found"); ralloc_free(b); diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index 7db2b0b4081..19b14bab810 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -939,8 +939,10 @@ vtn_emit_branch(struct vtn_builder *b, enum vtn_branch_type branch_type, nir_jump(&b->nb, nir_jump_return); break; case vtn_branch_type_discard: { + nir_intrinsic_op op = + b->convert_discard_to_demote ? nir_intrinsic_demote : nir_intrinsic_discard; nir_intrinsic_instr *discard = - nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_discard); + nir_intrinsic_instr_create(b->nb.shader, op); nir_builder_instr_insert(&b->nb, &discard->instr); break; } diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 5824bbeea3d..db11bcab73f 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -666,9 +666,17 @@ struct vtn_builder { unsigned value_id_bound; struct vtn_value *values; + /* Information on the origin of the SPIR-V */ + enum vtn_generator generator_id; + SpvSourceLanguage source_lang; + /* True if we need to fix up CS OpControlBarrier */ bool wa_glslang_cs_barrier; + /* Workaround discard bugs in HLSL -> SPIR-V compilers */ + bool uses_demote_to_helper_invocation; + bool convert_discard_to_demote; + gl_shader_stage entry_point_stage; const char *entry_point_name; struct vtn_value *entry_point; _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
