mesa: Fix computation of transform feedback num_components.
authorPaul Berry <stereotype441@gmail.com>
Wed, 4 Jan 2012 20:21:55 +0000 (12:21 -0800)
committerPaul Berry <stereotype441@gmail.com>
Wed, 11 Jan 2012 15:57:56 +0000 (07:57 -0800)
The function tfeedback_decl::num_components() was not correctly
accounting for transform feedback of whole arrays and gl_ClipDistance.
The bug was hard to notice in tests, because it only affected the
checks for MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS and
MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS.

This patch fixes the computation, and adds an assertion to verify
num_components() even when MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS
and MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS are not exceeded.

The assertion requires keeping track of components_so_far in
tfeedback_decl::store(); this will be useful in a future patch to fix
non-multiple-of-4-sized gl_ClipDistance.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/glsl/linker.cpp

index e8472d4469775e3d0fcb7845eedfecb4e4c5b8da..f32c2175f5945125f47390c4a212ef453b3771af 100644 (file)
@@ -1408,7 +1408,10 @@ public:
     */
    unsigned num_components() const
    {
-      return this->vector_elements * this->matrix_columns;
+      if (this->single_component == -1)
+         return this->vector_elements * this->matrix_columns * this->size;
+      else
+         return 1;
    }
 
 private:
@@ -1631,6 +1634,7 @@ tfeedback_decl::store(struct gl_shader_program *prog,
                    this->orig_name);
       return false;
    }
+   unsigned components_so_far = 0;
    for (unsigned index = 0; index < this->size; ++index) {
       for (unsigned v = 0; v < this->matrix_columns; ++v) {
          unsigned num_components =
@@ -1644,8 +1648,10 @@ tfeedback_decl::store(struct gl_shader_program *prog,
             this->single_component >= 0 ? this->single_component : 0;
          ++info->NumOutputs;
          info->BufferStride[buffer] += num_components;
+         components_so_far += num_components;
       }
    }
+   assert(components_so_far == this->num_components());
 
    info->Varyings[varying].Name = ralloc_strdup(prog, this->orig_name);
    info->Varyings[varying].Type = this->type;