diff options
author | Jason Ekstrand <[email protected]> | 2016-09-06 18:44:52 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2016-09-08 10:45:23 -0700 |
commit | a00bd7bc274c9d014883c08a5144f2a1db10ab80 (patch) | |
tree | 477faddfe880e703ce12548360473feb74e33560 /src | |
parent | f5505730d3a574f151205366643e2dabec6514b3 (diff) |
nir/spirv: Refactor variable deocration handling
Previously, we dind't apply variable decorations to the members of a split
structure variable. This doesn't quite work, unfortunately, because things
such as the "flat" qualifier may get applied to an entire structure instead
of propagated to the members. This fixes 9 of the new CTS tests in the
dEQP-VK.glsl.linkage.varying.struct.* group.
Signed-off-by: Jason Ekstrand <[email protected]>
Cc: "12.0" <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/spirv/vtn_variables.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 5d5460ce29f..43bb3bcadf0 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1026,21 +1026,17 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, 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]; } - /* 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. + /* Location is odd. If applied to a split structure, we have to walk the + * whole thing and accumulate the location. It's easier to handle as a + * special case. */ if (dec->decoration == SpvDecorationLocation) { unsigned location = dec->literals[0]; @@ -1061,10 +1057,10 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, assert(!"Location must be on input or output variable"); } - if (nir_var) { + if (vtn_var->var) { /* This handles the member and lone variable cases */ - nir_var->data.location = location; - nir_var->data.explicit_location = true; + vtn_var->var->data.location = location; + vtn_var->var->data.explicit_location = true; } else { /* This handles the structure member case */ assert(vtn_var->members); @@ -1079,12 +1075,30 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, } } return; + } else { + if (vtn_var->var) { + assert(member <= 0); + apply_var_decoration(b, vtn_var->var, dec); + } else if (vtn_var->members) { + if (member >= 0) { + assert(vtn_var->members); + apply_var_decoration(b, vtn_var->members[member], dec); + } else { + unsigned length = + glsl_get_length(glsl_without_array(vtn_var->type->type)); + for (unsigned i = 0; i < length; i++) + apply_var_decoration(b, vtn_var->members[i], dec); + } + } else { + /* A few variables, those with external storage, have no actual + * nir_variables associated with them. Fortunately, all decorations + * we care about for those variables are on the type only. + */ + assert(vtn_var->mode == vtn_variable_mode_ubo || + vtn_var->mode == vtn_variable_mode_ssbo || + vtn_var->mode == vtn_variable_mode_push_constant); + } } - - if (nir_var == NULL) - return; - - apply_var_decoration(b, nir_var, dec); } /* Tries to compute the size of an interface block based on the strides and |