nir/spirv: Handle location decorations on structure members

This commit is contained in:
Jason Ekstrand
2016-05-24 14:17:16 -07:00
parent 961369d597
commit 998829f404

View File

@@ -901,8 +901,27 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
case SpvDecorationDescriptorSet: case SpvDecorationDescriptorSet:
vtn_var->descriptor_set = dec->literals[0]; vtn_var->descriptor_set = dec->literals[0];
return; 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]; unsigned location = dec->literals[0];
bool is_vertex_input; bool is_vertex_input;
if (b->shader->stage == MESA_SHADER_FRAGMENT && 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"); assert(!"Location must be on input or output variable");
} }
if (vtn_var->var) { if (nir_var) {
vtn_var->var->data.location = location; /* This handles the member and lone variable cases */
vtn_var->var->data.explicit_location = true; nir_var->data.location = location;
nir_var->data.explicit_location = true;
} else { } else {
/* This handles the structure member case */
assert(vtn_var->members); assert(vtn_var->members);
unsigned length = unsigned length =
glsl_get_length(glsl_without_array(vtn_var->type->type)); 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; 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) if (nir_var == NULL)
return; return;
@@ -1037,6 +1042,9 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
case SpvDecorationPatch: case SpvDecorationPatch:
unreachable("Tessellation not yet supported"); unreachable("Tessellation not yet supported");
case SpvDecorationLocation:
unreachable("Handled above");
case SpvDecorationBlock: case SpvDecorationBlock:
case SpvDecorationBufferBlock: case SpvDecorationBufferBlock:
case SpvDecorationArrayStride: case SpvDecorationArrayStride: