From 9e756de7d19307044c9b4a08b285836fbe128589 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 11 May 2017 17:26:49 +0200 Subject: [PATCH] glsl: process uniform samplers declared bindless MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Samuel Pitoiset Reviewed-by: Nicolai Hähnle --- src/compiler/glsl/link_uniforms.cpp | 83 +++++++++++++++++++++++++---- src/compiler/glsl/shader_cache.cpp | 23 ++++++++ src/mesa/program/program.c | 4 ++ 3 files changed, 99 insertions(+), 11 deletions(-) diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp index 7c3ca75416d..c962f98d59f 100644 --- a/src/compiler/glsl/link_uniforms.cpp +++ b/src/compiler/glsl/link_uniforms.cpp @@ -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, diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp index 1ad8fdd62a4..8220c85f276 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -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); } diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index 277e6ce2d86..b5533c72579 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -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); } -- 2.30.2