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

Reply via email to