Module: Mesa
Branch: main
Commit: 5aabc912739a99ddaee482e54b9ca3fc76a092f1
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=5aabc912739a99ddaee482e54b9ca3fc76a092f1

Author: Timothy Arceri <[email protected]>
Date:   Wed May 12 15:44:02 2021 +1000

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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10763>

---

 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,

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to