spirv: Don't fail if multiple ordering semantics bits are set
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 29 Oct 2019 19:09:38 +0000 (12:09 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 29 Oct 2019 21:53:46 +0000 (14:53 -0700)
Vulkan requires that only one bit for the ordering is set, but old
versions of GLSLang just set all the bits.  This was fixed as part of
https://github.com/KhronosGroup/glslang/commit/c51287d744fb6e7e9ccc09f6f8451e6c64b1dad6
but we can still find older versions (or shaders compiled with it)
around.

So instead of failing, emit a warning and fallback to the effective
result of any combination of multiple bits: AcquireRelease.

Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/2018
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/spirv/spirv_to_nir.c

index e436f28de6012dd940f19785964328318d8b423d..4c1da666261c3e07c3d6faf7b31c64bfc9faa594 100644 (file)
@@ -1954,12 +1954,22 @@ vtn_split_barrier_semantics(struct vtn_builder *b,
    *before = SpvMemorySemanticsMaskNone;
    *after = SpvMemorySemanticsMaskNone;
 
-   const SpvMemorySemanticsMask order_semantics =
+   SpvMemorySemanticsMask order_semantics =
       semantics & (SpvMemorySemanticsAcquireMask |
                    SpvMemorySemanticsReleaseMask |
                    SpvMemorySemanticsAcquireReleaseMask |
                    SpvMemorySemanticsSequentiallyConsistentMask);
 
+   if (util_bitcount(order_semantics) > 1) {
+      /* Old GLSLang versions incorrectly set all the ordering bits.  This was
+       * fixed in c51287d744fb6e7e9ccc09f6f8451e6c64b1dad6 of glslang repo,
+       * and it is in GLSLang since revision "SPIRV99.1321" (from Jul-2016).
+       */
+      vtn_warn("Multiple memory ordering semantics specified, "
+               "assuming AcquireRelease.");
+      order_semantics = SpvMemorySemanticsAcquireReleaseMask;
+   }
+
    const SpvMemorySemanticsMask av_vis_semantics =
       semantics & (SpvMemorySemanticsMakeAvailableMask |
                    SpvMemorySemanticsMakeVisibleMask);
@@ -1979,9 +1989,6 @@ vtn_split_barrier_semantics(struct vtn_builder *b,
    if (other_semantics)
       vtn_warn("Ignoring unhandled memory semantics: %u\n", other_semantics);
 
-   vtn_fail_if(util_bitcount(order_semantics) > 1,
-               "Multiple memory ordering bits specified");
-
    /* SequentiallyConsistent is treated as AcquireRelease. */
 
    /* The RELEASE barrier happens BEFORE the operation, and it is usually
@@ -2016,10 +2023,24 @@ vtn_emit_scoped_memory_barrier(struct vtn_builder *b, SpvScope scope,
                                SpvMemorySemanticsMask semantics)
 {
    nir_memory_semantics nir_semantics = 0;
-   switch (semantics & (SpvMemorySemanticsAcquireMask |
-                        SpvMemorySemanticsReleaseMask |
-                        SpvMemorySemanticsAcquireReleaseMask |
-                        SpvMemorySemanticsSequentiallyConsistentMask)) {
+
+   SpvMemorySemanticsMask order_semantics =
+      semantics & (SpvMemorySemanticsAcquireMask |
+                   SpvMemorySemanticsReleaseMask |
+                   SpvMemorySemanticsAcquireReleaseMask |
+                   SpvMemorySemanticsSequentiallyConsistentMask);
+
+   if (util_bitcount(order_semantics) > 1) {
+      /* Old GLSLang versions incorrectly set all the ordering bits.  This was
+       * fixed in c51287d744fb6e7e9ccc09f6f8451e6c64b1dad6 of glslang repo,
+       * and it is in GLSLang since revision "SPIRV99.1321" (from Jul-2016).
+       */
+      vtn_warn("Multiple memory ordering semantics bits specified, "
+               "assuming AcquireRelease.");
+      order_semantics = SpvMemorySemanticsAcquireReleaseMask;
+   }
+
+   switch (order_semantics) {
    case 0:
       /* Not an ordering barrier. */
       break;
@@ -2039,7 +2060,7 @@ vtn_emit_scoped_memory_barrier(struct vtn_builder *b, SpvScope scope,
       break;
 
    default:
-      vtn_fail("Multiple memory ordering bits specified");
+      unreachable("Invalid memory order semantics");
    }
 
    if (semantics & SpvMemorySemanticsMakeAvailableMask) {