From 40dd45d0c6aa4a9d727c09225967e9c3b1f45854 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 30 Jun 2016 10:38:16 -0700 Subject: [PATCH] i965: Enable ARB_shader_atomic_counter_ops Signed-off-by: Ian Romanick Reviewed-by: Iago Toral Quiroga --- 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 2016cee3478..54b93989007 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -3793,23 +3793,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 23f05b826ad..17e95bcb1f8 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -612,6 +612,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 13f74a2b8d7..1d834a4be71 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -739,11 +739,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); @@ -752,7 +762,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 53bd7cc6737..eef81e22f91 100644 --- a/src/mesa/drivers/dri/i965/intel_extensions.c +++ b/src/mesa/drivers/dri/i965/intel_extensions.c @@ -346,6 +346,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;