spirv: Ignore ArrayStride in OpPtrAccessChain for Workgroup
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 1 Jul 2019 23:06:13 +0000 (16:06 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 2 Jul 2019 19:15:01 +0000 (12:15 -0700)
From OpPtrAccessChain description in the SPIR-V spec (1.4 rev 1):

    For objects in the Uniform, StorageBuffer, or PushConstant storage
    classes, the element’s address or location is calculated using a
    stride, which will be the Base-type’s Array Stride when the Base
    type is decorated with ArrayStride. For all other objects, the
    implementation will calculate the element’s address or location.

For non-CL shaders the driver should layout the Workgroup storage
class, so override any explicitly set ArrayStride in the shader.  This
currently fixes only the lower_workgroup_access_to_offsets case, which
is used by anv.

Reviewed-by: Juan A. Suarez <jasuarez@igalia.com>
src/compiler/spirv/spirv_to_nir.c

index df281f27a15e3c9c4a510e4e61adacc2f8883382..b9eb69c724721850669c1a5ff456de2f13fc3a51 100644 (file)
@@ -1396,15 +1396,17 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
             default:
                break;
             }
-         }
-
-         if (storage_class == SpvStorageClassWorkgroup &&
-             b->options->lower_workgroup_access_to_offsets) {
+         } else if (storage_class == SpvStorageClassWorkgroup &&
+                    b->options->lower_workgroup_access_to_offsets) {
+            /* Workgroup is laid out by the implementation. */
             uint32_t size, align;
             val->type->deref = vtn_type_layout_std430(b, val->type->deref,
                                                       &size, &align);
             val->type->length = size;
             val->type->align = align;
+
+            /* Override any ArrayStride previously set. */
+            val->type->stride = size;
          }
       }
       break;