glsl: count atomic counters correctly
authorAndres Gomez <agomez@igalia.com>
Thu, 30 Jun 2016 13:37:11 +0000 (16:37 +0300)
committerAndres Gomez <agomez@igalia.com>
Thu, 30 Jun 2016 20:55:32 +0000 (23:55 +0300)
Currently the linker uses the uniform count for the total number of
atomic counters. However uniforms don't include the innermost array
dimension in their count, but atomic counters are expected to include
them.

Although the spec doesn't directly state this, it's clear how offsets
will be assigned for arrays.

From OpenGL 4.2 (Core Profile), page 98:

  "  * Arrays of type atomic_uint are stored in memory by element
       order, with array element member zero at the lowest offset. The
       difference in offsets between each pair of elements in the
       array in basic machine units is referred to as the array
       stride, and is constant across the entire array. The stride can
       be queried by calling GetIntegerv with a pname of
       ATOMIC_COUNTER_- ARRAY_STRIDE after a program is linked."

From that it is clear how arrays of atomic counters will interact with
GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE.

For other kinds of uniforms it's also clear that each entry in an
array counts against the relevant limits.

Hence, although inferred, this is the expected behavior.

Fixes GL44-CTS.arrays_of_arrays_gl.AtomicDeclaration

Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
Signed-off-by: Andres Gomez <agomez@igalia.com>
src/compiler/glsl/link_atomics.cpp

index fa845e9d1eb4c42096eb843283119e4b0bfe2c7b..05e18db20ed916158e5101b67f6780688f50f270 100644 (file)
@@ -103,9 +103,9 @@ namespace {
                            const unsigned shader_stage)
    {
       /* FIXME: Arrays of arrays get counted separately. For example:
-       * x1[3][3][2] = 9 counters
-       * x2[3][2]    = 3 counters
-       * x3[2]       = 1 counter
+       * x1[3][3][2] = 9 uniforms, 18 atomic counters
+       * x2[3][2]    = 3 uniforms, 6 atomic counters
+       * x3[2]       = 1 uniform, 2 atomic counters
        *
        * However this code marks all the counters as active even when they
        * might not be used.
@@ -129,7 +129,13 @@ namespace {
 
          buf->push_back(*uniform_loc, var);
 
-         buf->stage_references[shader_stage]++;
+         /* When checking for atomic counters we should count every member in
+          * an array as an atomic counter reference.
+          */
+         if (t->is_array())
+            buf->stage_references[shader_stage] += t->length;
+         else
+            buf->stage_references[shader_stage]++;
          buf->size = MAX2(buf->size, *offset + t->atomic_size());
 
          storage->offset = *offset;