From: Ian Romanick <ian.d.roman...@intel.com> Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> Reviewed-by: Iago Toral Quiroga <ito...@igalia.com> --- src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 23 ++++++++++++++++++++--- src/mesa/drivers/dri/i965/brw_shader.cpp | 16 ++++++++++++++++ src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 16 +++++++++++++--- src/mesa/drivers/dri/i965/intel_extensions.c | 1 + 4 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 9a06dfe..90fb7d3 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -3586,23 +3586,40 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr switch (instr->intrinsic) { case nir_intrinsic_atomic_counter_inc: case nir_intrinsic_atomic_counter_dec: - case nir_intrinsic_atomic_counter_read: { + case nir_intrinsic_atomic_counter_read: + case nir_intrinsic_atomic_counter_add: + case nir_intrinsic_atomic_counter_min: + case nir_intrinsic_atomic_counter_max: + case nir_intrinsic_atomic_counter_and: + case nir_intrinsic_atomic_counter_or: + case nir_intrinsic_atomic_counter_xor: + case nir_intrinsic_atomic_counter_exchange: + case nir_intrinsic_atomic_counter_comp_swap: { if (stage == MESA_SHADER_FRAGMENT && instr->intrinsic != nir_intrinsic_atomic_counter_read) ((struct brw_wm_prog_data *)prog_data)->has_side_effects = true; + /* Get some metadata from the image intrinsic. */ + const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; + /* Get the arguments of the atomic intrinsic. */ const fs_reg offset = get_nir_src(instr->src[0]); const unsigned surface = (stage_prog_data->binding_table.abo_start + instr->const_index[0]); + const fs_reg src0 = (info->num_srcs >= 2 + ? get_nir_src(instr->src[1]) : fs_reg()); + const fs_reg src1 = (info->num_srcs >= 3 + ? get_nir_src(instr->src[2]) : fs_reg()); fs_reg tmp; + assert(info->num_srcs <= 3); + /* Emit a surface read or atomic op. */ if (instr->intrinsic == nir_intrinsic_atomic_counter_read) { tmp = emit_untyped_read(bld, brw_imm_ud(surface), offset, 1, 1); } else { - tmp = emit_untyped_atomic(bld, brw_imm_ud(surface), offset, fs_reg(), - fs_reg(), 1, 1, + tmp = emit_untyped_atomic(bld, brw_imm_ud(surface), offset, src0, + src1, 1, 1, get_atomic_counter_op(instr->intrinsic)); } diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index 1036e4c..e53ea7e 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -610,6 +610,22 @@ get_atomic_counter_op(nir_intrinsic_op op) return BRW_AOP_INC; case nir_intrinsic_atomic_counter_dec: return BRW_AOP_PREDEC; + case nir_intrinsic_atomic_counter_add: + return BRW_AOP_ADD; + case nir_intrinsic_atomic_counter_min: + return BRW_AOP_UMIN; + case nir_intrinsic_atomic_counter_max: + return BRW_AOP_UMAX; + case nir_intrinsic_atomic_counter_and: + return BRW_AOP_AND; + case nir_intrinsic_atomic_counter_or: + return BRW_AOP_OR; + case nir_intrinsic_atomic_counter_xor: + return BRW_AOP_XOR; + case nir_intrinsic_atomic_counter_exchange: + return BRW_AOP_MOV; + case nir_intrinsic_atomic_counter_comp_swap: + return BRW_AOP_CMPWR; default: unreachable("Not reachable."); } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index fed8e5f..1908d33 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -730,11 +730,21 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) case nir_intrinsic_atomic_counter_dec: { unsigned surf_index = prog_data->base.binding_table.abo_start + (unsigned) instr->const_index[0]; + const vec4_builder bld = + vec4_builder(this).at_end().annotate(current_annotation, base_ir); + + /* Get some metadata from the image intrinsic. */ + const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic]; + + /* Get the arguments of the atomic intrinsic. */ src_reg offset = get_nir_src(instr->src[0], nir_type_int, instr->num_components); const src_reg surface = brw_imm_ud(surf_index); - const vec4_builder bld = - vec4_builder(this).at_end().annotate(current_annotation, base_ir); + const src_reg src0 = (info->num_srcs >= 2 + ? get_nir_src(instr->src[1]) : src_reg()); + const src_reg src1 = (info->num_srcs >= 3 + ? get_nir_src(instr->src[2]) : src_reg()); + src_reg tmp; dest = get_nir_dest(instr->dest); @@ -743,7 +753,7 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) tmp = emit_untyped_read(bld, surface, offset, 1, 1); } else { tmp = emit_untyped_atomic(bld, surface, offset, - src_reg(), src_reg(), + src0, src1, 1, 1, get_atomic_counter_op(instr->intrinsic)); } diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c index 5ebcba2..94e1c0d 100644 --- a/src/mesa/drivers/dri/i965/intel_extensions.c +++ b/src/mesa/drivers/dri/i965/intel_extensions.c @@ -338,6 +338,7 @@ intelInitExtensions(struct gl_context *ctx) ctx->Extensions.ARB_framebuffer_no_attachments = true; ctx->Extensions.ARB_gpu_shader5 = true; ctx->Extensions.ARB_shader_atomic_counters = true; + ctx->Extensions.ARB_shader_atomic_counter_ops = true; ctx->Extensions.ARB_shader_clock = true; ctx->Extensions.ARB_shader_image_load_store = true; ctx->Extensions.ARB_shader_image_size = true; -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev