[Mesa-dev] [PATCH 4/8] glsl: fix count_attribute_slots to allow for different 64-bit handling

Dave Airlie airlied at gmail.com
Tue Dec 8 22:06:48 PST 2015


From: Dave Airlie <airlied at redhat.com>

So vertex shader input attributes are handled different than internal
varyings between shader stages, dvec3 and dvec4 only count as
one slot for vertex attributes, but for internal varyings, they
count as 2.

This patch comments all the uses of this API to clarify what we
pass in, except one which needs further investigation

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/glsl/ir_set_program_inouts.cpp |  7 ++++++-
 src/glsl/link_varyings.cpp         |  6 ++++--
 src/glsl/linker.cpp                |  5 +++--
 src/glsl/nir/glsl_types.cpp        | 18 +++++++++++++-----
 src/glsl/nir/glsl_types.h          |  5 ++++-
 5 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
index 782f1b1..838b5e7 100644
--- a/src/glsl/ir_set_program_inouts.cpp
+++ b/src/glsl/ir_set_program_inouts.cpp
@@ -146,6 +146,7 @@ void
 ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
 {
    const glsl_type *type = var->type;
+   bool vertex_input = false;
    if (this->shader_stage == MESA_SHADER_GEOMETRY &&
        var->data.mode == ir_var_shader_in && type->is_array()) {
       type = type->fields.array;
@@ -169,7 +170,11 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
       type = type->fields.array;
    }
 
-   mark(this->prog, var, 0, type->count_attribute_slots(),
+   if (this->shader_stage == MESA_SHADER_VERTEX &&
+       var->data.mode == ir_var_shader_in)
+      vertex_input = true;
+
+   mark(this->prog, var, 0, type->count_attribute_slots(vertex_input),
         this->shader_stage);
 }
 
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 71750d1..9f6467b 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1712,7 +1712,8 @@ check_against_output_limit(struct gl_context *ctx,
 
       if (var && var->data.mode == ir_var_shader_out &&
           var_counts_against_varying_limit(producer->Stage, var)) {
-         output_vectors += var->type->count_attribute_slots();
+         /* outputs for fragment shader can't be doubles */
+         output_vectors += var->type->count_attribute_slots(false);
       }
    }
 
@@ -1753,7 +1754,8 @@ check_against_input_limit(struct gl_context *ctx,
 
       if (var && var->data.mode == ir_var_shader_in &&
           var_counts_against_varying_limit(consumer->Stage, var)) {
-         input_vectors += var->type->count_attribute_slots();
+         /* vertex inputs aren't varying counted */
+         input_vectors += var->type->count_attribute_slots(false);
       }
    }
 
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 89659c7..1670036 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2466,7 +2466,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
          return false;
       }
 
-      const unsigned slots = var->type->count_attribute_slots();
+      const unsigned slots = var->type->count_attribute_slots(false);
 
       /* If the variable is not a built-in and has a location statically
        * assigned in the shader (presumably via a layout qualifier), make sure
@@ -2995,7 +2995,8 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
             foreach_in_list(ir_instruction, node, sh->ir) {
                ir_variable *var = node->as_variable();
                if (var && var->data.mode == ir_var_shader_out)
-                  fragment_outputs += var->type->count_attribute_slots();
+                  /* since there are no double fs outputs - pass false */
+                  fragment_outputs += var->type->count_attribute_slots(false);
             }
          }
       }
diff --git a/src/glsl/nir/glsl_types.cpp b/src/glsl/nir/glsl_types.cpp
index 3cf2f03..44d3056 100644
--- a/src/glsl/nir/glsl_types.cpp
+++ b/src/glsl/nir/glsl_types.cpp
@@ -1640,7 +1640,7 @@ glsl_type::std430_size(bool row_major) const
 }
 
 unsigned
-glsl_type::count_attribute_slots() const
+glsl_type::count_attribute_slots(bool vertex_input_slots) const
 {
    /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
     *
@@ -1661,27 +1661,35 @@ glsl_type::count_attribute_slots() const
     * allows varying structs, the number of varying slots taken up by a
     * varying struct is simply equal to the sum of the number of slots taken
     * up by each element.
+    *
+    * Doubles are counted different depending on whether they are vertex
+    * inputs or everything else. Vertex inputs from ARB_vertex_attrib_64bit
+    * take one location no matter what size they are, otherwise dvec3/4
+    * take two locations.
     */
    switch (this->base_type) {
    case GLSL_TYPE_UINT:
    case GLSL_TYPE_INT:
    case GLSL_TYPE_FLOAT:
    case GLSL_TYPE_BOOL:
-   case GLSL_TYPE_DOUBLE:
       return this->matrix_columns;
-
+   case GLSL_TYPE_DOUBLE:
+      if (this->vector_elements > 2 && !vertex_input_slots)
+         return this->matrix_columns * 2;
+      else
+         return this->matrix_columns;
    case GLSL_TYPE_STRUCT:
    case GLSL_TYPE_INTERFACE: {
       unsigned size = 0;
 
       for (unsigned i = 0; i < this->length; i++)
-         size += this->fields.structure[i].type->count_attribute_slots();
+         size += this->fields.structure[i].type->count_attribute_slots(vertex_input_slots);
 
       return size;
    }
 
    case GLSL_TYPE_ARRAY:
-      return this->length * this->fields.array->count_attribute_slots();
+      return this->length * this->fields.array->count_attribute_slots(vertex_input_slots);
 
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_IMAGE:
diff --git a/src/glsl/nir/glsl_types.h b/src/glsl/nir/glsl_types.h
index 26f25a1..0b83727 100644
--- a/src/glsl/nir/glsl_types.h
+++ b/src/glsl/nir/glsl_types.h
@@ -324,8 +324,11 @@ struct glsl_type {
     * varying slots the type will use up in the absence of varying packing
     * (and thus, it can be used to measure the number of varying slots used by
     * the varyings that are generated by lower_packed_varyings).
+    *
+    * For vertex shader attributes - doubles only take one slot.
+    * For inter-shader varyings - dvec3/dvec4 take two slots.
     */
-   unsigned count_attribute_slots() const;
+   unsigned count_attribute_slots(bool vertex_input_slots) const;
 
    /**
     * Alignment in bytes of the start of this type in a std140 uniform
-- 
2.5.0



More information about the mesa-dev mailing list