glsl: order indices for images inside a struct array
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 11 May 2017 15:43:19 +0000 (17:43 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 12 May 2017 08:30:37 +0000 (10:30 +0200)
ARB_bindless_texture allows images to be declared inside
structures. This is similar to samplers.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/compiler/glsl/link_uniforms.cpp

index 0d1e65cf31e9951b0c4f252115cf6237953022df..c5db1d62cb15e7fde01e2354e096befa955865e5 100644 (file)
@@ -441,6 +441,7 @@ public:
       current_var = var;
       field_counter = 0;
       this->record_next_sampler = new string_to_uint_map;
+      this->record_next_image = new string_to_uint_map;
 
       buffer_block_index = -1;
       if (var->is_in_buffer_block()) {
@@ -501,6 +502,7 @@ public:
          process(var);
       }
       delete this->record_next_sampler;
+      delete this->record_next_image;
    }
 
    int buffer_block_index;
@@ -593,27 +595,26 @@ private:
    }
 
    void handle_images(const glsl_type *base_type,
-                      struct gl_uniform_storage *uniform)
+                      struct gl_uniform_storage *uniform, const char *name)
    {
       if (base_type->is_image()) {
-         uniform->opaque[shader_type].index = this->next_image;
          uniform->opaque[shader_type].active = true;
 
+         if (!set_opaque_indices(base_type, uniform, name, this->next_image,
+                                 this->record_next_image))
+            return;
+
          /* Set image access qualifiers */
          const GLenum access =
             (current_var->data.memory_read_only ? GL_READ_ONLY :
              current_var->data.memory_write_only ? GL_WRITE_ONLY :
                 GL_READ_WRITE);
 
-         const unsigned first = this->next_image;
-
-         /* Increment the image index by 1 for non-arrays and by the
-          * number of array elements for arrays.
-          */
-         this->next_image += MAX2(1, uniform->array_elements);
-
-         for (unsigned i = first; i < MIN2(next_image, MAX_IMAGE_UNIFORMS); i++)
+         for (unsigned i = uniform->opaque[shader_type].index;
+              i < MIN2(this->next_image, MAX_IMAGE_UNIFORMS);
+              i++) {
             prog->_LinkedShaders[shader_type]->Program->sh.ImageAccess[i] = access;
+         }
       }
    }
 
@@ -705,7 +706,7 @@ private:
 
       /* This assigns uniform indices to sampler and image uniforms. */
       handle_samplers(base_type, &this->uniforms[id], name);
-      handle_images(base_type, &this->uniforms[id]);
+      handle_images(base_type, &this->uniforms[id], name);
       handle_subroutines(base_type, &this->uniforms[id]);
 
       /* For array of arrays or struct arrays the base location may have
@@ -852,6 +853,11 @@ private:
     */
    struct string_to_uint_map *record_next_sampler;
 
+   /* Map for temporarily storing next imager index when handling images in
+    * struct arrays.
+    */
+   struct string_to_uint_map *record_next_image;
+
 public:
    union gl_constant_value *values;