aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-05-24 14:17:16 -0700
committerJason Ekstrand <[email protected]>2016-05-24 21:12:56 -0700
commit998829f4045a98d16797e9d2f5094c35eb272909 (patch)
tree8b4b6ec6c0a0b864ae53748980b2434978085cf8 /src/compiler
parent961369d597ae44bd0c03660cd49ced43973ad269 (diff)
nir/spirv: Handle location decorations on structure members
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/spirv/vtn_variables.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index d156fb468c8..8abd8ee9a0f 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -901,8 +901,27 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
case SpvDecorationDescriptorSet:
vtn_var->descriptor_set = dec->literals[0];
return;
+ default:
+ break;
+ }
- case SpvDecorationLocation: {
+ /* Now we handle decorations that apply to a particular nir_variable */
+ nir_variable *nir_var = vtn_var->var;
+ if (val->value_type == vtn_value_type_access_chain) {
+ assert(val->access_chain->length == 0);
+ assert(val->access_chain->var == void_var);
+ assert(member == -1);
+ } else {
+ assert(val->value_type == vtn_value_type_type);
+ if (member != -1)
+ nir_var = vtn_var->members[member];
+ }
+
+ /* Location is odd in that it can apply in three different cases: To a
+ * non-split variable, to a whole split variable, or to one structure
+ * member of a split variable.
+ */
+ if (dec->decoration == SpvDecorationLocation) {
unsigned location = dec->literals[0];
bool is_vertex_input;
if (b->shader->stage == MESA_SHADER_FRAGMENT &&
@@ -921,10 +940,12 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
assert(!"Location must be on input or output variable");
}
- if (vtn_var->var) {
- vtn_var->var->data.location = location;
- vtn_var->var->data.explicit_location = true;
+ if (nir_var) {
+ /* This handles the member and lone variable cases */
+ nir_var->data.location = location;
+ nir_var->data.explicit_location = true;
} else {
+ /* This handles the structure member case */
assert(vtn_var->members);
unsigned length =
glsl_get_length(glsl_without_array(vtn_var->type->type));
@@ -939,22 +960,6 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
return;
}
- default:
- break;
- }
-
- /* Now we handle decorations that apply to a particular nir_variable */
- nir_variable *nir_var = vtn_var->var;
- if (val->value_type == vtn_value_type_access_chain) {
- assert(val->access_chain->length == 0);
- assert(val->access_chain->var == void_var);
- assert(member == -1);
- } else {
- assert(val->value_type == vtn_value_type_type);
- if (member != -1)
- nir_var = vtn_var->members[member];
- }
-
if (nir_var == NULL)
return;
@@ -1037,6 +1042,9 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
case SpvDecorationPatch:
unreachable("Tessellation not yet supported");
+ case SpvDecorationLocation:
+ unreachable("Handled above");
+
case SpvDecorationBlock:
case SpvDecorationBufferBlock:
case SpvDecorationArrayStride: