diff --git a/src/compiler/glsl/gl_nir_lower_atomics.c b/src/compiler/glsl/gl_nir_lower_atomics.c index 577c950f6c8..69bdea71ba0 100644 --- a/src/compiler/glsl/gl_nir_lower_atomics.c +++ b/src/compiler/glsl/gl_nir_lower_atomics.c @@ -111,7 +111,14 @@ lower_deref_instr(nir_builder *b, nir_intrinsic_instr *instr, b->cursor = nir_before_instr(&instr->instr); - nir_ssa_def *offset = nir_imm_int(b, var->data.offset); + int offset_value = 0; + int range_base = 0; + if (!b->shader->options->lower_atomic_offset_to_range_base) + offset_value = var->data.offset; + else + range_base = var->data.offset; + + nir_ssa_def *offset = nir_imm_int(b, offset_value); for (nir_deref_instr *d = deref; d->deref_type != nir_deref_type_var; d = nir_deref_instr_parent(d)) { assert(d->deref_type == nir_deref_type_array); @@ -130,6 +137,8 @@ lower_deref_instr(nir_builder *b, nir_intrinsic_instr *instr, * opcode. */ instr->intrinsic = op; + nir_intrinsic_set_range_base(instr, range_base); + nir_instr_rewrite_src(&instr->instr, &instr->src[0], nir_src_for_ssa(offset)); nir_intrinsic_set_base(instr, idx); diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index cb0d31c2d4f..1317b16629b 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3765,6 +3765,11 @@ typedef struct nir_shader_compiler_options { * of adding it to the image index. */ bool lower_image_offset_to_range_base; + + /** store the variable offset into the instrinsic range_base instead + * of adding it to the atomic source + */ + bool lower_atomic_offset_to_range_base; } nir_shader_compiler_options; typedef struct nir_shader { diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 456daed5160..34b3d2bfd48 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -587,15 +587,15 @@ intrinsic("rt_trace_ray", src_comp=[-1, 1, 1, 1, 1, 1, 3, 1, 3, 1, -1], # undefined.") def atomic(name, flags=[]): intrinsic(name + "_deref", src_comp=[-1], dest_comp=1, flags=flags) - intrinsic(name, src_comp=[1], dest_comp=1, indices=[BASE], flags=flags) + intrinsic(name, src_comp=[1], dest_comp=1, indices=[BASE, RANGE_BASE], flags=flags) def atomic2(name): intrinsic(name + "_deref", src_comp=[-1, 1], dest_comp=1) - intrinsic(name, src_comp=[1, 1], dest_comp=1, indices=[BASE]) + intrinsic(name, src_comp=[1, 1], dest_comp=1, indices=[BASE, RANGE_BASE]) def atomic3(name): intrinsic(name + "_deref", src_comp=[-1, 1, 1], dest_comp=1) - intrinsic(name, src_comp=[1, 1, 1], dest_comp=1, indices=[BASE]) + intrinsic(name, src_comp=[1, 1, 1], dest_comp=1, indices=[BASE, RANGE_BASE]) atomic("atomic_counter_inc") atomic("atomic_counter_pre_dec") diff --git a/src/compiler/nir/nir_lower_atomics_to_ssbo.c b/src/compiler/nir/nir_lower_atomics_to_ssbo.c index fe8a6735406..9047aa0ea80 100644 --- a/src/compiler/nir/nir_lower_atomics_to_ssbo.c +++ b/src/compiler/nir/nir_lower_atomics_to_ssbo.c @@ -153,6 +153,10 @@ lower_instr(nir_intrinsic_instr *instr, unsigned ssbo_offset, nir_builder *b, un if (offset_load) new_instr->src[1].ssa = nir_iadd(b, new_instr->src[1].ssa, offset_load); + if (nir_intrinsic_range_base(instr)) + new_instr->src[1].ssa = nir_iadd(b, new_instr->src[1].ssa, + nir_imm_int(b, nir_intrinsic_range_base(instr))); + if (new_instr->intrinsic == nir_intrinsic_load_ssbo) { nir_intrinsic_set_align(new_instr, 4, 0);