[Mesa-dev] [PATCH 12/12] i965: Enable ARB_shader_atomic_counter_ops
Ian Romanick
idr at freedesktop.org
Tue Jul 19 20:13:14 UTC 2016
From: Ian Romanick <ian.d.romanick at intel.com>
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Iago Toral Quiroga <itoral at 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
More information about the mesa-dev
mailing list