spirv: Pull offset/stride from the pointer for OpArrayLength
authorJason Ekstrand <jason.ekstrand@intel.com>
Sat, 12 Jan 2019 16:32:13 +0000 (10:32 -0600)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 5 Mar 2019 16:06:50 +0000 (10:06 -0600)
We can't pull it from the variable type because it might be an array of
blocks and not just the one block.  While we're here, throw in some
error checking.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable@lists.freedesktop.org
src/compiler/spirv/vtn_variables.c

index 51152520bb66afda3fb8af98c34c109819a68e19..f2bf09034ca9468f2b1766a19902665e01bff123 100644 (file)
@@ -2438,9 +2438,17 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
    case SpvOpArrayLength: {
       struct vtn_pointer *ptr =
          vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
+      const uint32_t field = w[4];
 
-      const uint32_t offset = ptr->var->type->offsets[w[4]];
-      const uint32_t stride = ptr->var->type->members[w[4]]->stride;
+      vtn_fail_if(ptr->type->base_type != vtn_base_type_struct,
+                  "OpArrayLength must take a pointer to a structure type");
+      vtn_fail_if(field != ptr->type->length - 1 ||
+                  ptr->type->members[field]->base_type != vtn_base_type_array,
+                  "OpArrayLength must reference the last memeber of the "
+                  "structure and that must be an array");
+
+      const uint32_t offset = ptr->type->offsets[field];
+      const uint32_t stride = ptr->type->members[field]->stride;
 
       if (!ptr->block_index) {
          struct vtn_access_chain chain = {