From 5aabc912739a99ddaee482e54b9ca3fc76a092f1 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 12 May 2021 15:44:02 +1000 Subject: glsl: add missing support for explicit components in interface blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Part-of: --- src/compiler/glsl/ast_to_hir.cpp | 12 ++++++++++++ src/compiler/glsl/link_interface_blocks.cpp | 3 +++ src/compiler/glsl/lower_named_interface_blocks.cpp | 5 +++++ src/compiler/glsl_types.cpp | 5 +++++ 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 @@ -1372,6 +1372,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, -- cgit v1.2.1