return;
/* For !has_hw_atomics, the atomic counters have been rewritten to be above
- * the SSBO range.
+ * the SSBOs used by the program.
*/
- unsigned buffer_base = st->ctx->Const.Program[stage].MaxShaderStorageBlocks;
-
+ unsigned buffer_base = prog->info.num_ssbos;
+ unsigned used_bindings = 0;
for (i = 0; i < prog->sh.data->NumAtomicBuffers; i++) {
struct gl_active_atomic_buffer *atomic =
&prog->sh.data->AtomicBuffers[i];
st->pipe->set_shader_buffers(st->pipe, shader_type,
buffer_base + atomic->Binding, 1, &sb, 0x1);
+ used_bindings = MAX2(atomic->Binding + 1, used_bindings);
}
+ st->last_used_atomic_bindings[shader_type] = used_bindings;
}
void
ST_STATE(ST_NEW_FS_ATOMICS, st_bind_fs_atomics)
ST_STATE(ST_NEW_GS_ATOMICS, st_bind_gs_atomics)
+/* SSBOs depend on the _atomics having been updated first in the
+ * !has_hw_atomics case.
+ */
ST_STATE(ST_NEW_VS_SSBOS, st_bind_vs_ssbos)
ST_STATE(ST_NEW_TCS_SSBOS, st_bind_tcs_ssbos)
ST_STATE(ST_NEW_TES_SSBOS, st_bind_tes_ssbos)
{
unsigned i;
struct pipe_shader_buffer buffers[MAX_SHADER_STORAGE_BUFFERS];
- struct gl_program_constants *c;
if (!prog || !st->pipe->set_shader_buffers)
return;
- c = &st->ctx->Const.Program[prog->info.stage];
-
for (i = 0; i < prog->info.num_ssbos; i++) {
struct gl_buffer_binding *binding;
struct st_buffer_object *st_obj;
st->pipe->set_shader_buffers(st->pipe, shader_type, 0,
prog->info.num_ssbos, buffers,
prog->sh.ShaderStorageBlocksWriteAccess);
- /* clear out any stale shader buffers */
- if (prog->info.num_ssbos < c->MaxShaderStorageBlocks)
+
+ /* Clear out any stale shader buffers (or lowered atomic counters). */
+ int num_ssbos = prog->info.num_ssbos;
+ if (!st->has_hw_atomics)
+ num_ssbos += st->last_used_atomic_bindings[shader_type];
+ if (st->last_num_ssbos[shader_type] > num_ssbos) {
st->pipe->set_shader_buffers(
st->pipe, shader_type,
- prog->info.num_ssbos,
- c->MaxShaderStorageBlocks - prog->info.num_ssbos,
+ num_ssbos,
+ st->last_num_ssbos[shader_type] - num_ssbos,
NULL, 0);
+ st->last_num_ssbos[shader_type] = num_ssbos;
+ }
}
void st_bind_vs_ssbos(struct st_context *st)
/* The number of vertex buffers from the last call of validate_arrays. */
unsigned last_num_vbuffers;
+ unsigned last_used_atomic_bindings[PIPE_SHADER_TYPES];
+ unsigned last_num_ssbos[PIPE_SHADER_TYPES];
+
int32_t draw_stamp;
int32_t read_stamp;
nir_remove_dead_variables(nir, mask);
if (!st->has_hw_atomics)
- NIR_PASS_V(nir, nir_lower_atomics_to_ssbo,
- st->ctx->Const.Program[nir->info.stage].MaxShaderStorageBlocks);
+ NIR_PASS_V(nir, nir_lower_atomics_to_ssbo, prog->info.num_ssbos);
st_finalize_nir_before_variants(nir);
resource = buffer;
} else {
st_src_reg buffer(PROGRAM_BUFFER,
- ctx->Const.Program[shader->Stage].MaxShaderStorageBlocks +
+ prog->info.num_ssbos +
location->data.binding,
GLSL_TYPE_ATOMIC_UINT);
if (!st_context(ctx)->has_hw_atomics) {
for (i = 0; i < prog->info.num_abos; i++) {
- unsigned index = (frag_const->MaxShaderStorageBlocks +
+ unsigned index = (prog->info.num_ssbos +
prog->sh.AtomicBuffers[i]->Binding);
assert(prog->sh.AtomicBuffers[i]->Binding <
frag_const->MaxAtomicBuffers);