diff options
author | Timothy Arceri <tarceri@itsqueeze.com> | 2021-05-12 15:44:02 +1000 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-05-13 08:07:53 +0000 |
commit | 5aabc912739a99ddaee482e54b9ca3fc76a092f1 (patch) | |
tree | f4a4f774e1ab94cfe9f4e4d2ff39acf935c4fcb0 | |
parent | 1a71d6aa6e13179526b41e627f00af25b1612556 (diff) | |
download | mesa-5aabc912739a99ddaee482e54b9ca3fc76a092f1.tar.gz |
glsl: add missing support for explicit components in interface blocks
From the ARB_enhanced_layouts spec:
"As with input layout qualifiers, all shaders except compute shaders
allow *location* layout qualifiers on output variable declarations,
output block declarations, and output block member declarations. Of
these, variables and block members (but not blocks) additionally
allow the *component* layout qualifier."
We previously had compile tests in piglit to make sure this was not a
compile error but no execution tests.
Fixes: d99a040bbf2c ("i965: enable ARB_enhanced_layouts for gen8+")
Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10763>
-rw-r--r-- | src/compiler/glsl/ast_to_hir.cpp | 12 | ||||
-rw-r--r-- | src/compiler/glsl/link_interface_blocks.cpp | 3 | ||||
-rw-r--r-- | src/compiler/glsl/lower_named_interface_blocks.cpp | 5 | ||||
-rw-r--r-- | src/compiler/glsl_types.cpp | 5 | ||||
-rw-r--r-- | src/compiler/glsl_types.h | 11 |
5 files changed, 34 insertions, 2 deletions
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index ba5321fc430..bee30a241c3 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -7564,6 +7564,18 @@ ast_process_struct_or_iface_block_members(exec_list *instructions, } } + if (qual->flags.q.explicit_component) { + unsigned qual_component; + if (process_qualifier_constant(state, &loc, "component", + qual->component, &qual_component)) { + validate_component_layout_for_type(state, &loc, fields[i].type, + qual_component); + fields[i].component = qual_component; + } + } else { + fields[i].component = -1; + } + /* Offset can only be used with std430 and std140 layouts an initial * value of 0 is used for error detection. */ diff --git a/src/compiler/glsl/link_interface_blocks.cpp b/src/compiler/glsl/link_interface_blocks.cpp index d954a89e903..7899cf56809 100644 --- a/src/compiler/glsl/link_interface_blocks.cpp +++ b/src/compiler/glsl/link_interface_blocks.cpp @@ -56,6 +56,9 @@ interstage_member_mismatch(struct gl_shader_program *prog, if (c->fields.structure[i].location != p->fields.structure[i].location) return true; + if (c->fields.structure[i].component != + p->fields.structure[i].component) + return true; if (c->fields.structure[i].patch != p->fields.structure[i].patch) return true; diff --git a/src/compiler/glsl/lower_named_interface_blocks.cpp b/src/compiler/glsl/lower_named_interface_blocks.cpp index 01c50932a9a..98d27b7109e 100644 --- a/src/compiler/glsl/lower_named_interface_blocks.cpp +++ b/src/compiler/glsl/lower_named_interface_blocks.cpp @@ -180,7 +180,12 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) (ir_variable_mode) var->data.mode); } new_var->data.location = iface_t->fields.structure[i].location; + new_var->data.location_frac = + iface_t->fields.structure[i].component >= 0 ? + iface_t->fields.structure[i].component : 0; new_var->data.explicit_location = (new_var->data.location >= 0); + new_var->data.explicit_component = + (iface_t->fields.structure[i].component >= 0); new_var->data.offset = iface_t->fields.structure[i].offset; new_var->data.explicit_xfb_offset = (iface_t->fields.structure[i].offset >= 0); diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index cfeea9e8914..334c05e73bb 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -1244,6 +1244,9 @@ glsl_type::record_compare(const glsl_type *b, bool match_name, if (match_locations && this->fields.structure[i].location != b->fields.structure[i].location) return false; + if (this->fields.structure[i].component + != b->fields.structure[i].component) + return false; if (this->fields.structure[i].offset != b->fields.structure[i].offset) return false; @@ -2949,6 +2952,7 @@ encode_glsl_struct_field(blob *blob, const glsl_struct_field *struct_field) encode_type_to_blob(blob, struct_field->type); blob_write_string(blob, struct_field->name); blob_write_uint32(blob, struct_field->location); + blob_write_uint32(blob, struct_field->component); blob_write_uint32(blob, struct_field->offset); blob_write_uint32(blob, struct_field->xfb_buffer); blob_write_uint32(blob, struct_field->xfb_stride); @@ -2962,6 +2966,7 @@ decode_glsl_struct_field_from_blob(blob_reader *blob, glsl_struct_field *struct_ struct_field->type = decode_type_from_blob(blob); struct_field->name = blob_read_string(blob); struct_field->location = blob_read_uint32(blob); + struct_field->component = blob_read_uint32(blob); struct_field->offset = blob_read_uint32(blob); struct_field->xfb_buffer = blob_read_uint32(blob); struct_field->xfb_stride = blob_read_uint32(blob); diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index 8157bceb64b..62b10885b4e 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -1373,6 +1373,12 @@ struct glsl_struct_field { int location; /** + * For interface blocks, members may explicitly assign the component used + * by a varying. Ignored for structs. + */ + int component; + + /** * For interface blocks, members may have an explicit byte offset * specified; -1 otherwise. Also used for xfb_offset layout qualifier. * @@ -1391,6 +1397,7 @@ struct glsl_struct_field { * -1 otherwise. */ int xfb_stride; + /** * Layout format, applicable to image variables only. */ @@ -1455,8 +1462,8 @@ struct glsl_struct_field { }; #ifdef __cplusplus #define DEFAULT_CONSTRUCTORS(_type, _name) \ - type(_type), name(_name), location(-1), offset(-1), xfb_buffer(0), \ - xfb_stride(0), image_format(PIPE_FORMAT_NONE), flags(0) \ + type(_type), name(_name), location(-1), component(-1), offset(-1), \ + xfb_buffer(0), xfb_stride(0), image_format(PIPE_FORMAT_NONE), flags(0) \ glsl_struct_field(const struct glsl_type *_type, int _precision, |