summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/nir/spirv/spirv_to_nir.c1
-rw-r--r--src/glsl/nir/spirv/vtn_private.h3
-rw-r--r--src/glsl/nir/spirv/vtn_variables.c60
3 files changed, 47 insertions, 17 deletions
diff --git a/src/glsl/nir/spirv/spirv_to_nir.c b/src/glsl/nir/spirv/spirv_to_nir.c
index 7d9d0981269..32188e5f364 100644
--- a/src/glsl/nir/spirv/spirv_to_nir.c
+++ b/src/glsl/nir/spirv/spirv_to_nir.c
@@ -585,6 +585,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
val->type = rzalloc(b, struct vtn_type);
val->type->is_builtin = false;
+ val->type->val = val;
switch (opcode) {
case SpvOpTypeVoid:
diff --git a/src/glsl/nir/spirv/vtn_private.h b/src/glsl/nir/spirv/vtn_private.h
index e0f4b220c4c..3840d8c4b65 100644
--- a/src/glsl/nir/spirv/vtn_private.h
+++ b/src/glsl/nir/spirv/vtn_private.h
@@ -196,6 +196,9 @@ struct vtn_ssa_value {
struct vtn_type {
const struct glsl_type *type;
+ /* The value that declares this type. Used for finding decorations */
+ struct vtn_value *val;
+
/* for matrices, whether the matrix is stored row-major */
bool row_major;
diff --git a/src/glsl/nir/spirv/vtn_variables.c b/src/glsl/nir/spirv/vtn_variables.c
index 8171a5fc156..5c372774126 100644
--- a/src/glsl/nir/spirv/vtn_variables.c
+++ b/src/glsl/nir/spirv/vtn_variables.c
@@ -887,6 +887,43 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
case SpvDecorationDescriptorSet:
vtn_var->descriptor_set = dec->literals[0];
return;
+
+ case SpvDecorationLocation: {
+ unsigned location = dec->literals[0];
+ bool is_vertex_input;
+ if (b->shader->stage == MESA_SHADER_FRAGMENT &&
+ vtn_var->mode == vtn_variable_mode_output) {
+ is_vertex_input = false;
+ location += FRAG_RESULT_DATA0;
+ } else if (b->shader->stage == MESA_SHADER_VERTEX &&
+ vtn_var->mode == vtn_variable_mode_input) {
+ is_vertex_input = true;
+ location += VERT_ATTRIB_GENERIC0;
+ } else if (vtn_var->mode == vtn_variable_mode_input ||
+ vtn_var->mode == vtn_variable_mode_output) {
+ is_vertex_input = false;
+ location += VARYING_SLOT_VAR0;
+ } else {
+ 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;
+ } else {
+ assert(vtn_var->members);
+ unsigned length = glsl_get_length(vtn_var->type->type);
+ for (unsigned i = 0; i < length; i++) {
+ vtn_var->members[i]->data.location = location;
+ vtn_var->members[i]->data.explicit_location = true;
+ location +=
+ glsl_count_attribute_slots(vtn_var->members[i]->interface_type,
+ is_vertex_input);
+ }
+ }
+ return;
+ }
+
default:
break;
}
@@ -899,7 +936,6 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
assert(member == -1);
} else {
assert(val->value_type == vtn_value_type_type);
- assert(vtn_var->type == val->type);
if (member != -1)
nir_var = vtn_var->members[member];
}
@@ -932,22 +968,6 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
case SpvDecorationNonWritable:
nir_var->data.read_only = true;
break;
- case SpvDecorationLocation:
- nir_var->data.location = dec->literals[0];
- if (b->shader->stage == MESA_SHADER_FRAGMENT &&
- nir_var->data.mode == nir_var_shader_out) {
- nir_var->data.location += FRAG_RESULT_DATA0;
- } else if (b->shader->stage == MESA_SHADER_VERTEX &&
- nir_var->data.mode == nir_var_shader_in) {
- nir_var->data.location += VERT_ATTRIB_GENERIC0;
- } else if (nir_var->data.mode == nir_var_shader_in ||
- nir_var->data.mode == nir_var_shader_out) {
- nir_var->data.location += VARYING_SLOT_VAR0;
- } else {
- assert(!"Location must be on input or output variable");
- }
- nir_var->data.explicit_location = true;
- break;
case SpvDecorationComponent:
nir_var->data.location_frac = dec->literals[0];
break;
@@ -1201,7 +1221,13 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
var->var->interface_type = interface_type->type;
var->var->data.mode = nir_mode;
}
+
+ /* For inputs and outputs, we need to grab locations and builtin
+ * information from the interface type.
+ */
+ vtn_foreach_decoration(b, interface_type->val, var_decoration_cb, var);
break;
+
case vtn_variable_mode_param:
unreachable("Not created through OpVariable");
}