X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_lower_atomics.c;h=6b046bc426ea9a095eab73ea809ec217cb51e377;hb=9063bf7ad8a9175c4eddba5d06d887c507f6b5be;hp=70381a7968a07c5cdbc08b647e415f67d51eecb0;hpb=3124ce699bb3844e793f00e00bfbea5c91744f90;p=mesa.git diff --git a/src/compiler/nir/nir_lower_atomics.c b/src/compiler/nir/nir_lower_atomics.c index 70381a7968a..6b046bc426e 100644 --- a/src/compiler/nir/nir_lower_atomics.c +++ b/src/compiler/nir/nir_lower_atomics.c @@ -30,19 +30,15 @@ #include "main/config.h" #include -typedef struct { - const struct gl_shader_program *shader_program; - nir_shader *shader; -} lower_atomic_state; - /* * replace atomic counter intrinsics that use a variable with intrinsics * that directly store the buffer index and byte offset */ -static void +static bool lower_instr(nir_intrinsic_instr *instr, - lower_atomic_state *state) + const struct gl_shader_program *shader_program, + nir_shader *shader, bool use_binding_as_idx) { nir_intrinsic_op op; switch (instr->intrinsic) { @@ -58,23 +54,59 @@ lower_instr(nir_intrinsic_instr *instr, op = nir_intrinsic_atomic_counter_dec; break; + case nir_intrinsic_atomic_counter_add_var: + op = nir_intrinsic_atomic_counter_add; + break; + + case nir_intrinsic_atomic_counter_min_var: + op = nir_intrinsic_atomic_counter_min; + break; + + case nir_intrinsic_atomic_counter_max_var: + op = nir_intrinsic_atomic_counter_max; + break; + + case nir_intrinsic_atomic_counter_and_var: + op = nir_intrinsic_atomic_counter_and; + break; + + case nir_intrinsic_atomic_counter_or_var: + op = nir_intrinsic_atomic_counter_or; + break; + + case nir_intrinsic_atomic_counter_xor_var: + op = nir_intrinsic_atomic_counter_xor; + break; + + case nir_intrinsic_atomic_counter_exchange_var: + op = nir_intrinsic_atomic_counter_exchange; + break; + + case nir_intrinsic_atomic_counter_comp_swap_var: + op = nir_intrinsic_atomic_counter_comp_swap; + break; + default: - return; + return false; } if (instr->variables[0]->var->data.mode != nir_var_uniform && instr->variables[0]->var->data.mode != nir_var_shader_storage && instr->variables[0]->var->data.mode != nir_var_shared) - return; /* atomics passed as function arguments can't be lowered */ + return false; /* atomics passed as function arguments can't be lowered */ void *mem_ctx = ralloc_parent(instr); unsigned uniform_loc = instr->variables[0]->var->data.location; + unsigned idx = use_binding_as_idx ? + instr->variables[0]->var->data.binding : + shader_program->data->UniformStorage[uniform_loc].opaque[shader->info.stage].index; + nir_intrinsic_instr *new_instr = nir_intrinsic_instr_create(mem_ctx, op); - nir_intrinsic_set_base(new_instr, - state->shader_program->UniformStorage[uniform_loc].opaque[state->shader->stage].index); + nir_intrinsic_set_base(new_instr, idx); - nir_load_const_instr *offset_const = nir_load_const_instr_create(mem_ctx, 1); + nir_load_const_instr *offset_const = + nir_load_const_instr_create(mem_ctx, 1, 32); offset_const->value.u32[0] = instr->variables[0]->var->data.offset; nir_instr_insert_before(&instr->instr, &offset_const->instr); @@ -83,7 +115,6 @@ lower_instr(nir_intrinsic_instr *instr, nir_deref *tail = &instr->variables[0]->deref; while (tail->child != NULL) { - assert(tail->child->deref_type == nir_deref_type_array); nir_deref_array *deref_array = nir_deref_as_array(tail->child); tail = tail->child; @@ -95,7 +126,7 @@ lower_instr(nir_intrinsic_instr *instr, if (deref_array->deref_array_type == nir_deref_array_type_indirect) { nir_load_const_instr *atomic_counter_size = - nir_load_const_instr_create(mem_ctx, 1); + nir_load_const_instr_create(mem_ctx, 1, 32); atomic_counter_size->value.u32[0] = child_array_elements * ATOMIC_COUNTER_SIZE; nir_instr_insert_before(&instr->instr, &atomic_counter_size->instr); @@ -123,6 +154,12 @@ lower_instr(nir_intrinsic_instr *instr, new_instr->src[0].is_ssa = true; new_instr->src[0].ssa = offset_def; + /* Copy the other sources, if any, from the original instruction to the new + * instruction. + */ + for (unsigned i = 0; i < nir_intrinsic_infos[instr->intrinsic].num_srcs; i++) + nir_src_copy(&new_instr->src[i + 1], &instr->src[i], new_instr); + if (instr->dest.is_ssa) { nir_ssa_dest_init(&new_instr->instr, &new_instr->dest, instr->dest.ssa.num_components, 32, NULL); @@ -134,34 +171,32 @@ lower_instr(nir_intrinsic_instr *instr, nir_instr_insert_before(&instr->instr, &new_instr->instr); nir_instr_remove(&instr->instr); -} - -static bool -lower_block(nir_block *block, void *state) -{ - nir_foreach_instr_safe(block, instr) { - if (instr->type == nir_instr_type_intrinsic) - lower_instr(nir_instr_as_intrinsic(instr), - (lower_atomic_state *) state); - } return true; } -void +bool nir_lower_atomics(nir_shader *shader, - const struct gl_shader_program *shader_program) + const struct gl_shader_program *shader_program, + bool use_binding_as_idx) { - lower_atomic_state state = { - .shader = shader, - .shader_program = shader_program, - }; + bool progress = false; - nir_foreach_function(shader, function) { + nir_foreach_function(function, shader) { if (function->impl) { - nir_foreach_block(function->impl, lower_block, (void *) &state); + nir_foreach_block(block, function->impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type == nir_instr_type_intrinsic) + progress |= lower_instr(nir_instr_as_intrinsic(instr), + shader_program, shader, + use_binding_as_idx); + } + } + nir_metadata_preserve(function->impl, nir_metadata_block_index | nir_metadata_dominance); } } + + return progress; }