glsl: process uniform samplers declared bindless
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 11 May 2017 15:26:49 +0000 (17:26 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 14 Jun 2017 08:04:36 +0000 (10:04 +0200)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/compiler/glsl/link_uniforms.cpp
src/compiler/glsl/shader_cache.cpp
src/mesa/program/program.c

index 7c3ca75416d2b10b6424f3e8bfb6b10f51b930f6..c962f98d59f21d9e79cabdfab2ede71fa5e4ffbd 100644 (file)
@@ -418,10 +418,16 @@ public:
                               struct string_to_uint_map *map,
                               struct gl_uniform_storage *uniforms,
                               union gl_constant_value *values)
-      : prog(prog), map(map), uniforms(uniforms), values(values)
+      : prog(prog), map(map), uniforms(uniforms), values(values),
+        bindless_targets(NULL)
    {
    }
 
+   virtual ~parcel_out_uniform_storage()
+   {
+      free(this->bindless_targets);
+   }
+
    void start_shader(gl_shader_stage shader_type)
    {
       assert(shader_type < MESA_SHADER_STAGES);
@@ -434,6 +440,11 @@ public:
       this->next_subroutine = 0;
       this->record_array_count = 1;
       memset(this->targets, 0, sizeof(this->targets));
+
+      this->num_bindless_samplers = 0;
+      this->next_bindless_sampler = 0;
+      free(this->bindless_targets);
+      this->bindless_targets = NULL;
    }
 
    void set_and_process(ir_variable *var)
@@ -441,6 +452,7 @@ public:
       current_var = var;
       field_counter = 0;
       this->record_next_sampler = new string_to_uint_map;
+      this->record_next_bindless_sampler = new string_to_uint_map;
       this->record_next_image = new string_to_uint_map;
 
       buffer_block_index = -1;
@@ -502,6 +514,7 @@ public:
          process(var);
       }
       delete this->record_next_sampler;
+      delete this->record_next_bindless_sampler;
       delete this->record_next_image;
    }
 
@@ -578,18 +591,39 @@ private:
       if (base_type->is_sampler()) {
          uniform->opaque[shader_type].active = true;
 
-         if (!set_opaque_indices(base_type, uniform, name, this->next_sampler,
-                                 this->record_next_sampler))
-            return;
-
          const gl_texture_index target = base_type->sampler_index();
          const unsigned shadow = base_type->sampler_shadow;
-         for (unsigned i = uniform->opaque[shader_type].index;
-              i < MIN2(this->next_sampler, MAX_SAMPLERS);
-              i++) {
-            this->targets[i] = target;
-            this->shader_samplers_used |= 1U << i;
-            this->shader_shadow_samplers |= shadow << i;
+
+         if (current_var->data.bindless) {
+            if (!set_opaque_indices(base_type, uniform, name,
+                                    this->next_bindless_sampler,
+                                    this->record_next_bindless_sampler))
+               return;
+
+            this->num_bindless_samplers = this->next_bindless_sampler;
+
+            this->bindless_targets = (gl_texture_index *)
+               realloc(this->bindless_targets,
+                       this->num_bindless_samplers * sizeof(gl_texture_index));
+
+            for (unsigned i = uniform->opaque[shader_type].index;
+                 i < this->num_bindless_samplers;
+                 i++) {
+               this->bindless_targets[i] = target;
+            }
+         } else {
+            if (!set_opaque_indices(base_type, uniform, name,
+                                    this->next_sampler,
+                                    this->record_next_sampler))
+               return;
+
+            for (unsigned i = uniform->opaque[shader_type].index;
+                 i < MIN2(this->next_sampler, MAX_SAMPLERS);
+                 i++) {
+               this->targets[i] = target;
+               this->shader_samplers_used |= 1U << i;
+               this->shader_shadow_samplers |= shadow << i;
+            }
          }
       }
    }
@@ -827,6 +861,7 @@ private:
 
    struct gl_uniform_storage *uniforms;
    unsigned next_sampler;
+   unsigned next_bindless_sampler;
    unsigned next_image;
    unsigned next_subroutine;
 
@@ -859,6 +894,11 @@ private:
     */
    struct string_to_uint_map *record_next_image;
 
+   /* Map for temporarily storing next bindless sampler index when handling
+    * bindless samplers in struct arrays.
+    */
+   struct string_to_uint_map *record_next_bindless_sampler;
+
 public:
    union gl_constant_value *values;
 
@@ -873,6 +913,16 @@ public:
     * Mask of samplers used by the current shader stage for shadows.
     */
    unsigned shader_shadow_samplers;
+
+   /**
+    * Number of bindless samplers used by the current shader stage.
+    */
+   unsigned num_bindless_samplers;
+
+   /**
+    * Texture targets for bindless samplers used by the current stage.
+    */
+   gl_texture_index *bindless_targets;
 };
 
 static bool
@@ -1259,6 +1309,17 @@ link_assign_uniform_storage(struct gl_context *ctx,
       shader->Program->SamplersUsed = parcel.shader_samplers_used;
       shader->shadow_samplers = parcel.shader_shadow_samplers;
 
+      if (parcel.num_bindless_samplers > 0) {
+         shader->Program->sh.NumBindlessSamplers = parcel.num_bindless_samplers;
+         shader->Program->sh.BindlessSamplers =
+            rzalloc_array(shader->Program, gl_bindless_sampler,
+                          parcel.num_bindless_samplers);
+         for (unsigned j = 0; j < parcel.num_bindless_samplers; j++) {
+            shader->Program->sh.BindlessSamplers[j].target =
+               parcel.bindless_targets[j];
+         }
+      }
+
       STATIC_ASSERT(sizeof(shader->Program->sh.SamplerTargets) ==
                     sizeof(parcel.targets));
       memcpy(shader->Program->sh.SamplerTargets,
index 1ad8fdd62a408215e6593de1772fde67665965be..8220c85f276ca4e5a8207444eaac1f72b70ee684 100644 (file)
@@ -1129,6 +1129,7 @@ write_shader_metadata(struct blob *metadata, gl_linked_shader *shader)
 {
    assert(shader->Program);
    struct gl_program *glprog = shader->Program;
+   unsigned i;
 
    blob_write_bytes(metadata, glprog->TexturesUsed,
                     sizeof(glprog->TexturesUsed));
@@ -1145,6 +1146,13 @@ write_shader_metadata(struct blob *metadata, gl_linked_shader *shader)
    blob_write_bytes(metadata, glprog->sh.ImageUnits,
                     sizeof(glprog->sh.ImageUnits));
 
+   blob_write_uint32(metadata, glprog->sh.NumBindlessSamplers);
+   blob_write_uint32(metadata, glprog->sh.HasBoundBindlessSampler);
+   for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) {
+      blob_write_bytes(metadata, &glprog->sh.BindlessSamplers[i],
+                       sizeof(struct gl_bindless_sampler));
+   }
+
    write_shader_parameters(metadata, glprog->Parameters);
 }
 
@@ -1153,6 +1161,8 @@ read_shader_metadata(struct blob_reader *metadata,
                      struct gl_program *glprog,
                      gl_linked_shader *linked)
 {
+   unsigned i;
+
    blob_copy_bytes(metadata, (uint8_t *) glprog->TexturesUsed,
                    sizeof(glprog->TexturesUsed));
    glprog->SamplersUsed = blob_read_uint64(metadata);
@@ -1168,6 +1178,19 @@ read_shader_metadata(struct blob_reader *metadata,
    blob_copy_bytes(metadata, (uint8_t *) glprog->sh.ImageUnits,
                    sizeof(glprog->sh.ImageUnits));
 
+   glprog->sh.NumBindlessSamplers = blob_read_uint32(metadata);
+   glprog->sh.HasBoundBindlessSampler = blob_read_uint32(metadata);
+   if (glprog->sh.NumBindlessSamplers > 0) {
+      glprog->sh.BindlessSamplers =
+         rzalloc_array(glprog, gl_bindless_sampler,
+                       glprog->sh.NumBindlessSamplers);
+
+      for (i = 0; i < glprog->sh.NumBindlessSamplers; i++) {
+         blob_copy_bytes(metadata, (uint8_t *) &glprog->sh.BindlessSamplers[i],
+                         sizeof(struct gl_bindless_sampler));
+      }
+   }
+
    glprog->Parameters = _mesa_new_parameter_list();
    read_shader_parameters(metadata, glprog->Parameters);
 }
index 277e6ce2d864d978ab8b346e587d5f718de29761..b5533c725793892f72f531c05cbbb996b1fd934f 100644 (file)
@@ -271,6 +271,10 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
       ralloc_free(prog->nir);
    }
 
+   if (prog->sh.BindlessSamplers) {
+      ralloc_free(prog->sh.BindlessSamplers);
+   }
+
    ralloc_free(prog);
 }