[Mesa-dev] [PATCH] mesa: Fix transform feedback of unsubscripted arrays.

Paul Berry stereotype441 at gmail.com
Wed Jan 4 14:32:20 PST 2012


On 4 January 2012 11:38, Ian Romanick <idr at freedesktop.org> wrote:

> On 01/03/2012 10:35 PM, Paul Berry wrote:
>
>> It is not explicitly stated in the GL 3.0 spec that transform feedback
>> can be performed on a whole varying array (without supplying a
>> subscript).  However, it seems clear from context that this was the
>> intent.  Section 2.15 (TransformFeedback) says this:
>>
>>     When writing varying variables that are arrays, individual array
>>     elements are written in order.
>>
>> And section 2.20.3 (Shader Variables), says this, in the description
>> of GetTransformFeedbackVarying:
>>
>>     For the selected varying variable, its type is returned into
>>     type. The size of the varying is returned into size. The value in
>>     size is in units of the type returned in type.
>>
>> If it were not possible to perform transform feedback on an
>> unsubscripted array, the returned size would always be 1.
>>
>> This patch fixes the linker so that transform feedback on an
>> unsubscripted array is supported.
>>
>> Fixes piglit tests "EXT_transform_feedback/**builtin-varyings
>> gl_ClipDistance[{4,8}]-no-**subscript" and
>> "EXT_transform_feedback/**output_type *[2]-no-subscript".
>>
>> Note: on back-ends that set
>> gl_shader_compiler_options::**LowerClipDistance (for example i965),
>> tests "EXT_transform_feedback/**builtin-varyings
>> gl_ClipDistance[{1,2,3,5,6,7}]**" still fail.  I hope to address this in
>> a later patch.
>>
>
> Other than the one comment below, which can be addressed later, this patch
> is
>
> Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
>
>  ---
>>  src/glsl/linker.cpp |   99 ++++++++++++++++++++++++++++--**
>> ---------------------
>>  1 files changed, 54 insertions(+), 45 deletions(-)
>>
>> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
>> index 45edafb..883a635 100644
>> --- a/src/glsl/linker.cpp
>> +++ b/src/glsl/linker.cpp
>> @@ -1426,12 +1426,12 @@ private:
>>     /**
>>      * True if the declaration in orig_name represents an array.
>>      */
>> -   bool is_array;
>> +   bool is_subscripted;
>>
>>     /**
>> -    * If is_array is true, the array index that was specified in
>> orig_name.
>> +    * If is_subscripted is true, the subscript that was specified in
>> orig_name.
>>      */
>> -   unsigned array_index;
>> +   unsigned array_subscript;
>>
>>     /**
>>      * Which component to extract from the vertex shader output location
>> that
>> @@ -1460,6 +1460,12 @@ private:
>>
>>     /** Type of the varying returned by glGetTransformFeedbackVarying(**)
>> */
>>     GLenum type;
>> +
>> +   /**
>> +    * If location != -1, the size that should be returned by
>> +    * glGetTransformFeedbackVarying(**).
>> +    */
>> +   unsigned size;
>>  };
>>
>>
>> @@ -1484,14 +1490,14 @@ tfeedback_decl::init(struct gl_context *ctx,
>> struct gl_shader_program *prog,
>>
>>     if (bracket) {
>>        this->var_name = ralloc_strndup(mem_ctx, input, bracket - input);
>> -      if (sscanf(bracket, "[%u]",&this->array_index) != 1) {
>> +      if (sscanf(bracket, "[%u]",&this->array_subscript) != 1) {
>>
>>           linker_error(prog, "Cannot parse transform feedback varying
>> %s", input);
>>           return false;
>>        }
>> -      this->is_array = true;
>> +      this->is_subscripted = true;
>>     } else {
>>        this->var_name = ralloc_strdup(mem_ctx, input);
>> -      this->is_array = false;
>> +      this->is_subscripted = false;
>>     }
>>
>>     /* For drivers that lower gl_ClipDistance to gl_ClipDistanceMESA, we
>> need
>> @@ -1501,8 +1507,10 @@ tfeedback_decl::init(struct gl_context *ctx,
>> struct gl_shader_program *prog,
>>     if (ctx->ShaderCompilerOptions[**MESA_SHADER_VERTEX].**
>> LowerClipDistance&&
>>         strcmp(this->var_name, "gl_ClipDistance") == 0) {
>>        this->var_name = "gl_ClipDistanceMESA";
>> -      this->single_component = this->array_index % 4;
>> -      this->array_index /= 4;
>> +      if (this->is_subscripted) {
>> +         this->single_component = this->array_subscript % 4;
>> +         this->array_subscript /= 4;
>> +      }
>>     }
>>
>>     return true;
>> @@ -1518,9 +1526,9 @@ tfeedback_decl::is_same(const tfeedback_decl&x,
>> const tfeedback_decl&y)
>>  {
>>     if (strcmp(x.var_name, y.var_name) != 0)
>>        return false;
>> -   if (x.is_array != y.is_array)
>> +   if (x.is_subscripted != y.is_subscripted)
>>        return false;
>> -   if (x.is_array&&  x.array_index != y.array_index)
>> +   if (x.is_subscripted&&  x.array_subscript != y.array_subscript)
>>
>>        return false;
>>     if (x.single_component != y.single_component)
>>        return false;
>> @@ -1542,37 +1550,39 @@ tfeedback_decl::assign_**location(struct
>> gl_context *ctx,
>>  {
>>     if (output_var->type->is_array()) {
>>        /* Array variable */
>> -      if (!this->is_array) {
>> -         linker_error(prog, "Transform feedback varying %s found, "
>> -                      "but array dereference required for varying
>> %s[%d]).",
>> -                      this->orig_name,
>> -                     output_var->name, output_var->type->length);
>> -         return false;
>> -      }
>> -      /* Check array bounds. */
>> -      if (this->array_index>=
>> -          (unsigned) output_var->type->array_size()**) {
>> -         linker_error(prog, "Transform feedback varying %s has index "
>> -                      "%i, but the array size is %i.",
>> -                      this->orig_name, this->array_index,
>> -                      output_var->type->array_size()**);
>> -         return false;
>> -      }
>>        const unsigned matrix_cols =
>>           output_var->type->fields.**array->matrix_columns;
>> -      this->location = output_var->location + this->array_index *
>> matrix_cols;
>> +
>> +      if (this->is_subscripted) {
>> +         /* Check array bounds. */
>> +         if (this->array_subscript>=
>> +             (unsigned) output_var->type->array_size()**) {
>> +            linker_error(prog, "Transform feedback varying %s has index "
>> +                         "%i, but the array size is %i.",
>> +                         this->orig_name, this->array_subscript,
>> +                         output_var->type->array_size()**);
>> +            return false;
>> +         }
>> +         this->location =
>> +            output_var->location + this->array_subscript * matrix_cols;
>> +         this->size = 1;
>> +      } else {
>> +         this->location = output_var->location;
>> +         this->size = (unsigned) output_var->type->array_size()**;
>> +      }
>>        this->vector_elements = output_var->type->fields.**
>> array->vector_elements;
>>        this->matrix_columns = matrix_cols;
>> -      this->type = GL_NONE;
>> +      this->type = output_var->type->fields.**array->gl_type;
>>     } else {
>>        /* Regular variable (scalar, vector, or matrix) */
>> -      if (this->is_array) {
>> +      if (this->is_subscripted) {
>>           linker_error(prog, "Transform feedback varying %s found, "
>>                        "but it's an array ([] expected).",
>>                        this->orig_name);
>>
>
> I hadn't noticed this before, but this error message seems to not match
> the condition.  The output variable (the varying) is not an array, but the
> transform feedback setting included an array subscript.  Right?
>
>
You're right, that's a bogus error message.  I'll submit a follow-up patch
that fixes it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20120104/2a91f614/attachment.html>


More information about the mesa-dev mailing list