unsigned next_subroutine;
/* per-shader stage */
+ unsigned next_bindless_image_index;
+ unsigned next_bindless_sampler_index;
unsigned next_image_index;
unsigned next_sampler_index;
unsigned num_shader_samplers;
const struct glsl_type *type,
struct nir_link_uniforms_state *state)
{
- if (!state->params || uniform->is_shader_storage || glsl_contains_opaque(type))
+ if (!state->params || uniform->is_shader_storage ||
+ (glsl_contains_opaque(type) && !state->current_var->data.bindless))
return;
unsigned num_params = glsl_get_aoa_size(type);
unsigned values = glsl_get_component_slots(type);
const struct glsl_type *type_no_array = glsl_without_array(type);
if (glsl_type_is_sampler(type_no_array)) {
- struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
bool init_idx;
- unsigned sampler_index =
- get_next_index(state, uniform, &state->next_sampler_index,
- &init_idx);
+ unsigned *next_index = state->current_var->data.bindless ?
+ &state->next_bindless_sampler_index :
+ &state->next_sampler_index;
+ int sampler_index =
+ get_next_index(state, uniform, next_index, &init_idx);
+ struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
- /* Samplers (bound or bindless) are counted as two components as
- * specified by ARB_bindless_texture.
- */
- state->num_shader_samplers += values / 2;
+ if (state->current_var->data.bindless) {
+ if (init_idx) {
+ sh->Program->sh.BindlessSamplers =
+ rerzalloc(sh->Program, sh->Program->sh.BindlessSamplers,
+ struct gl_bindless_sampler,
+ sh->Program->sh.NumBindlessSamplers,
+ state->next_bindless_sampler_index);
+
+ for (unsigned j = sh->Program->sh.NumBindlessSamplers;
+ j < state->next_bindless_sampler_index; j++) {
+ sh->Program->sh.BindlessSamplers[j].target =
+ glsl_get_sampler_target(type_no_array);
+ }
- uniform->opaque[stage].active = true;
- uniform->opaque[stage].index = sampler_index;
+ sh->Program->sh.NumBindlessSamplers =
+ state->next_bindless_sampler_index;
+ }
- if (init_idx) {
- const unsigned shadow =
- glsl_sampler_type_is_shadow(type_no_array);
- for (unsigned i = sampler_index;
- i < MIN2(state->next_sampler_index, MAX_SAMPLERS);
- i++) {
- sh->Program->sh.SamplerTargets[i] =
- glsl_get_sampler_target(type_no_array);
- state->shader_samplers_used |= 1U << i;
- state->shader_shadow_samplers |= shadow << i;
+ if (!state->var_is_in_block)
+ state->num_shader_uniform_components += values;
+
+ } else {
+ /* Samplers (bound or bindless) are counted as two components
+ * as specified by ARB_bindless_texture.
+ */
+ state->num_shader_samplers += values / 2;
+
+ if (init_idx) {
+ const unsigned shadow =
+ glsl_sampler_type_is_shadow(type_no_array);
+ for (unsigned i = sampler_index;
+ i < MIN2(state->next_sampler_index, MAX_SAMPLERS);
+ i++) {
+ sh->Program->sh.SamplerTargets[i] =
+ glsl_get_sampler_target(type_no_array);
+ state->shader_samplers_used |= 1U << i;
+ state->shader_shadow_samplers |= shadow << i;
+ }
}
}
- } else if (glsl_type_is_image(type_no_array)) {
- struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
- int image_index = state->next_image_index;
- /* TODO: handle structs when bindless support is added */
- state->next_image_index += MAX2(1, uniform->array_elements);
-
- /* Images (bound or bindless) are counted as two components as
- * specified by ARB_bindless_texture.
- */
- state->num_shader_images += values / 2;
uniform->opaque[stage].active = true;
- uniform->opaque[stage].index = image_index;
+ uniform->opaque[stage].index = sampler_index;
+ } else if (glsl_type_is_image(type_no_array)) {
+ struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
/* Set image access qualifiers */
enum gl_access_qualifier image_access =
GL_READ_ONLY) :
((image_access & ACCESS_NON_READABLE) ? GL_WRITE_ONLY :
GL_READ_WRITE);
- for (unsigned i = image_index;
- i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS);
- i++) {
- sh->Program->sh.ImageAccess[i] = access;
+
+ int image_index;
+ if (state->current_var->data.bindless) {
+ image_index = state->next_bindless_image_index;
+ state->next_bindless_image_index +=
+ MAX2(1, uniform->array_elements);
+
+ sh->Program->sh.BindlessImages =
+ rerzalloc(sh->Program, sh->Program->sh.BindlessImages,
+ struct gl_bindless_image,
+ sh->Program->sh.NumBindlessImages,
+ state->next_bindless_image_index);
+
+ for (unsigned j = sh->Program->sh.NumBindlessImages;
+ j < state->next_bindless_image_index; j++) {
+ sh->Program->sh.BindlessImages[j].access = access;
+ }
+
+ sh->Program->sh.NumBindlessImages =
+ state->next_bindless_image_index;
+
+ } else {
+ image_index = state->next_image_index;
+ state->next_image_index += MAX2(1, uniform->array_elements);
+
+ /* Images (bound or bindless) are counted as two components as
+ * specified by ARB_bindless_texture.
+ */
+ state->num_shader_images += values / 2;
+
+ for (unsigned i = image_index;
+ i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS);
+ i++) {
+ sh->Program->sh.ImageAccess[i] = access;
+ }
}
+
+ uniform->opaque[stage].active = true;
+ uniform->opaque[stage].index = image_index;
+
+ if (!uniform->is_shader_storage)
+ state->num_shader_uniform_components += values;
}
struct hash_entry *entry =
state->num_hidden_uniforms++;
uniform->is_shader_storage = nir_variable_is_in_ssbo(state->current_var);
+ uniform->is_bindless = state->current_var->data.bindless;
/* Set fields whose default value depend on the variable being inside a
* block.
}
uniform->block_index = buffer_block_index;
-
- /* @FIXME: the initialization of the following will be done as we
- * implement support for their specific features, like SSBO, atomics,
- * etc.
- */
uniform->builtin = is_gl_identifier(uniform->name);
uniform->atomic_buffer_index = -1;
- uniform->is_bindless = false;
/* The following are not for features not supported by ARB_gl_spirv */
uniform->num_compatible_subroutines = 0;
if (glsl_type_is_sampler(type_no_array)) {
bool init_idx;
+ unsigned *next_index = state->current_var->data.bindless ?
+ &state->next_bindless_sampler_index : &state->next_sampler_index;
int sampler_index =
- get_next_index(state, uniform, &state->next_sampler_index,
- &init_idx);
+ get_next_index(state, uniform, next_index, &init_idx);
- /* Samplers (bound or bindless) are counted as two components as
- * specified by ARB_bindless_texture.
- */
- state->num_shader_samplers += values / 2;
+ if (state->current_var->data.bindless) {
- uniform->opaque[stage].active = true;
- uniform->opaque[stage].index = sampler_index;
+ if (init_idx) {
+ stage_program->sh.BindlessSamplers =
+ rerzalloc(stage_program, stage_program->sh.BindlessSamplers,
+ struct gl_bindless_sampler,
+ stage_program->sh.NumBindlessSamplers,
+ state->next_bindless_sampler_index);
+
+ for (unsigned j = stage_program->sh.NumBindlessSamplers;
+ j < state->next_bindless_sampler_index; j++) {
+ stage_program->sh.BindlessSamplers[j].target =
+ glsl_get_sampler_target(type_no_array);
+ }
- if (init_idx) {
- const unsigned shadow = glsl_sampler_type_is_shadow(type_no_array);
- for (unsigned i = sampler_index;
- i < MIN2(state->next_sampler_index, MAX_SAMPLERS);
- i++) {
- stage_program->sh.SamplerTargets[i] =
- glsl_get_sampler_target(type_no_array);
- state->shader_samplers_used |= 1U << i;
- state->shader_shadow_samplers |= shadow << i;
+ stage_program->sh.NumBindlessSamplers =
+ state->next_bindless_sampler_index;
}
- }
- } else if (glsl_type_is_image(type_no_array)) {
- /* @FIXME: image_index should match that of the same image
- * uniform in other shaders. This means we need to match image
- * uniforms by location (GLSL does it by variable name, but we
- * want to avoid that).
- */
- int image_index = state->next_image_index;
- state->next_image_index += entries;
- /* Images (bound or bindless) are counted as two components as
- * specified by ARB_bindless_texture.
- */
- state->num_shader_images += values / 2;
+ if (!state->var_is_in_block)
+ state->num_shader_uniform_components += values;
+
+ } else {
+ /* Samplers (bound or bindless) are counted as two components as
+ * specified by ARB_bindless_texture.
+ */
+ state->num_shader_samplers += values / 2;
+
+ if (init_idx) {
+ const unsigned shadow =
+ glsl_sampler_type_is_shadow(type_no_array);
+ for (unsigned i = sampler_index;
+ i < MIN2(state->next_sampler_index, MAX_SAMPLERS);
+ i++) {
+ stage_program->sh.SamplerTargets[i] =
+ glsl_get_sampler_target(type_no_array);
+ state->shader_samplers_used |= 1U << i;
+ state->shader_shadow_samplers |= shadow << i;
+ }
+ }
+ }
uniform->opaque[stage].active = true;
- uniform->opaque[stage].index = image_index;
+ uniform->opaque[stage].index = sampler_index;
+ } else if (glsl_type_is_image(type_no_array)) {
/* Set image access qualifiers */
enum gl_access_qualifier image_access =
GL_READ_ONLY) :
((image_access & ACCESS_NON_READABLE) ? GL_WRITE_ONLY :
GL_READ_WRITE);
- for (unsigned i = image_index;
- i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS);
- i++) {
- stage_program->sh.ImageAccess[i] = access;
+
+ int image_index;
+ if (state->current_var->data.bindless) {
+ image_index = state->next_bindless_image_index;
+ state->next_bindless_image_index += entries;
+
+ stage_program->sh.BindlessImages =
+ rerzalloc(stage_program, stage_program->sh.BindlessImages,
+ struct gl_bindless_image,
+ stage_program->sh.NumBindlessImages,
+ state->next_bindless_image_index);
+
+ for (unsigned j = stage_program->sh.NumBindlessImages;
+ j < state->next_bindless_image_index; j++) {
+ stage_program->sh.BindlessImages[j].access = access;
+ }
+
+ stage_program->sh.NumBindlessImages =
+ state->next_bindless_image_index;
+
+ } else {
+ image_index = state->next_image_index;
+ state->next_image_index += entries;
+
+ /* Images (bound or bindless) are counted as two components as
+ * specified by ARB_bindless_texture.
+ */
+ state->num_shader_images += values / 2;
+
+ for (unsigned i = image_index;
+ i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS);
+ i++) {
+ stage_program->sh.ImageAccess[i] = access;
+ }
}
+ uniform->opaque[stage].active = true;
+ uniform->opaque[stage].index = image_index;
+
if (!uniform->is_shader_storage)
state->num_shader_uniform_components += values;
} else {
state.referenced_uniforms =
_mesa_hash_table_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
+ state.next_bindless_image_index = 0;
+ state.next_bindless_sampler_index = 0;
state.next_image_index = 0;
state.next_sampler_index = 0;
state.num_shader_samplers = 0;