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);
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)
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;
process(var);
}
delete this->record_next_sampler;
+ delete this->record_next_bindless_sampler;
delete this->record_next_image;
}
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;
+ }
}
}
}
struct gl_uniform_storage *uniforms;
unsigned next_sampler;
+ unsigned next_bindless_sampler;
unsigned next_image;
unsigned next_subroutine;
*/
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;
* 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
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,
{
assert(shader->Program);
struct gl_program *glprog = shader->Program;
+ unsigned i;
blob_write_bytes(metadata, glprog->TexturesUsed,
sizeof(glprog->TexturesUsed));
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);
}
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);
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);
}