[Mesa-dev] [PATCH 19/23] i965/fs: Switch atomic counters to the new intrinsic translation code.
Francisco Jerez
currojerez at riseup.net
Tue Apr 28 11:44:30 PDT 2015
---
src/mesa/drivers/dri/i965/brw_fs.h | 9 --
src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 26 ++---
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 166 ++-------------------------
3 files changed, 19 insertions(+), 182 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index e33a5f4..3aefead 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -398,13 +398,6 @@ public:
void emit_shader_time_end();
fs_inst *SHADER_TIME_ADD(enum shader_time_shader_type type, fs_reg value);
- void emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
- fs_reg dst, fs_reg offset, fs_reg src0,
- fs_reg src1);
-
- void emit_untyped_surface_read(unsigned surf_index, fs_reg dst,
- fs_reg offset);
-
void emit_interpolate_expression(ir_expression *ir);
bool try_rewrite_rhs_to_dst(ir_assignment *ir,
@@ -433,8 +426,6 @@ public:
void dump_instruction(backend_instruction *inst);
void dump_instruction(backend_instruction *inst, FILE *file);
- void visit_atomic_counter_intrinsic(ir_call *ir);
-
const void *const key;
const struct brw_sampler_prog_key_data *key_tex;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 555987d..6ef9fa8 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -27,6 +27,9 @@
#include "program/prog_to_nir.h"
#include "brw_fs.h"
#include "brw_nir.h"
+#include "brw_nir_intrinsics.h"
+
+using namespace brw;
void
fs_visitor::emit_nir_code()
@@ -1288,25 +1291,12 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
case nir_intrinsic_atomic_counter_inc:
case nir_intrinsic_atomic_counter_dec:
case nir_intrinsic_atomic_counter_read: {
- unsigned surf_index = prog_data->binding_table.abo_start +
- (unsigned) instr->const_index[0];
- fs_reg offset = fs_reg(get_nir_src(instr->src[0]));
+ const bool uses_kill = (stage == MESA_SHADER_FRAGMENT &&
+ ((brw_wm_prog_data *)prog_data)->uses_kill);
+ fs_builder bld = fs_builder(devinfo, mem_ctx, alloc, instructions,
+ dispatch_width, stage, uses_kill);
- switch (instr->intrinsic) {
- case nir_intrinsic_atomic_counter_inc:
- emit_untyped_atomic(BRW_AOP_INC, surf_index, dest, offset,
- fs_reg(), fs_reg());
- break;
- case nir_intrinsic_atomic_counter_dec:
- emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dest, offset,
- fs_reg(), fs_reg());
- break;
- case nir_intrinsic_atomic_counter_read:
- emit_untyped_surface_read(surf_index, dest, offset);
- break;
- default:
- unreachable("Unreachable");
- }
+ emit_atomic_counter_intrinsic(this, bld, instr);
break;
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index f3a5d4d..db4d42c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -41,11 +41,13 @@
#include "brw_wm.h"
#include "brw_vec4.h"
#include "brw_fs.h"
+#include "brw_ir_glsl_intrinsics.h"
#include "main/uniforms.h"
#include "glsl/glsl_types.h"
#include "glsl/ir_optimization.h"
#include "program/sampler.h"
+using namespace brw;
fs_reg *
fs_visitor::emit_vs_system_value(int location)
@@ -3159,55 +3161,22 @@ fs_visitor::visit(ir_loop_jump *ir)
}
void
-fs_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
-{
- ir_dereference *deref = static_cast<ir_dereference *>(
- ir->actual_parameters.get_head());
- ir_variable *location = deref->variable_referenced();
- unsigned surf_index = (stage_prog_data->binding_table.abo_start +
- location->data.binding);
-
- /* Calculate the surface offset */
- fs_reg offset = vgrf(glsl_type::uint_type);
- ir_dereference_array *deref_array = deref->as_dereference_array();
-
- if (deref_array) {
- deref_array->array_index->accept(this);
-
- fs_reg tmp = vgrf(glsl_type::uint_type);
- emit(MUL(tmp, this->result, fs_reg(ATOMIC_COUNTER_SIZE)));
- emit(ADD(offset, tmp, fs_reg(location->data.atomic.offset)));
- } else {
- offset = fs_reg(location->data.atomic.offset);
- }
-
- /* Emit the appropriate machine instruction */
- const char *callee = ir->callee->function_name();
- ir->return_deref->accept(this);
- fs_reg dst = this->result;
-
- if (!strcmp("__intrinsic_atomic_read", callee)) {
- emit_untyped_surface_read(surf_index, dst, offset);
-
- } else if (!strcmp("__intrinsic_atomic_increment", callee)) {
- emit_untyped_atomic(BRW_AOP_INC, surf_index, dst, offset,
- fs_reg(), fs_reg());
-
- } else if (!strcmp("__intrinsic_atomic_predecrement", callee)) {
- emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dst, offset,
- fs_reg(), fs_reg());
- }
-}
-
-void
fs_visitor::visit(ir_call *ir)
{
const char *callee = ir->callee->function_name();
+ const bool uses_kill = (stage == MESA_SHADER_FRAGMENT &&
+ ((brw_wm_prog_data *)prog_data)->uses_kill);
+ fs_builder bld(devinfo, mem_ctx, alloc, instructions, dispatch_width,
+ stage, uses_kill);
+
+ bld.set_annotation(current_annotation);
+ bld.set_base_ir(base_ir);
if (!strcmp("__intrinsic_atomic_read", callee) ||
!strcmp("__intrinsic_atomic_increment", callee) ||
!strcmp("__intrinsic_atomic_predecrement", callee)) {
- visit_atomic_counter_intrinsic(ir);
+ brw::visit_atomic_counter_intrinsic(this, bld, ir);
+
} else {
unreachable("Unsupported intrinsic.");
}
@@ -3258,119 +3227,6 @@ fs_visitor::visit(ir_end_primitive *)
unreachable("not reached");
}
-void
-fs_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,
- fs_reg dst, fs_reg offset, fs_reg src0,
- fs_reg src1)
-{
- int reg_width = dispatch_width / 8;
- int length = 0;
-
- fs_reg *sources = ralloc_array(mem_ctx, fs_reg, 4);
-
- sources[0] = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
- /* Initialize the sample mask in the message header. */
- emit(MOV(sources[0], fs_reg(0u)))
- ->force_writemask_all = true;
-
- if (stage == MESA_SHADER_FRAGMENT) {
- if (((brw_wm_prog_data*)this->prog_data)->uses_kill) {
- emit(MOV(channel(sources[0], 7), brw_flag_reg(0, 1)))
- ->force_writemask_all = true;
- } else {
- emit(MOV(channel(sources[0], 7),
- retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD)))
- ->force_writemask_all = true;
- }
- } else {
- /* The execution mask is part of the side-band information sent together with
- * the message payload to the data port. It's implicitly ANDed with the sample
- * mask sent in the header to compute the actual set of channels that execute
- * the atomic operation.
- */
- assert(stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_COMPUTE);
- emit(MOV(channel(sources[0], 7),
- fs_reg(0xffffu)))->force_writemask_all = true;
- }
- length++;
-
- /* Set the atomic operation offset. */
- sources[1] = vgrf(glsl_type::uint_type);
- emit(MOV(sources[1], offset));
- length++;
-
- /* Set the atomic operation arguments. */
- if (src0.file != BAD_FILE) {
- sources[length] = vgrf(glsl_type::uint_type);
- emit(MOV(sources[length], src0));
- length++;
- }
-
- if (src1.file != BAD_FILE) {
- sources[length] = vgrf(glsl_type::uint_type);
- emit(MOV(sources[length], src1));
- length++;
- }
-
- int mlen = 1 + (length - 1) * reg_width;
- fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
- BRW_REGISTER_TYPE_UD);
- emit(LOAD_PAYLOAD(src_payload, sources, length));
-
- /* Emit the instruction. */
- fs_inst *inst = emit(SHADER_OPCODE_UNTYPED_ATOMIC, dst, src_payload,
- fs_reg(surf_index), fs_reg(atomic_op));
- inst->mlen = mlen;
-}
-
-void
-fs_visitor::emit_untyped_surface_read(unsigned surf_index, fs_reg dst,
- fs_reg offset)
-{
- int reg_width = dispatch_width / 8;
-
- fs_reg *sources = ralloc_array(mem_ctx, fs_reg, 2);
-
- sources[0] = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
- /* Initialize the sample mask in the message header. */
- emit(MOV(sources[0], fs_reg(0u)))
- ->force_writemask_all = true;
-
- if (stage == MESA_SHADER_FRAGMENT) {
- if (((brw_wm_prog_data*)this->prog_data)->uses_kill) {
- emit(MOV(channel(sources[0], 7), brw_flag_reg(0, 1)))
- ->force_writemask_all = true;
- } else {
- emit(MOV(channel(sources[0], 7),
- retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UD)))
- ->force_writemask_all = true;
- }
- } else {
- /* The execution mask is part of the side-band information sent together with
- * the message payload to the data port. It's implicitly ANDed with the sample
- * mask sent in the header to compute the actual set of channels that execute
- * the atomic operation.
- */
- assert(stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_COMPUTE);
- emit(MOV(channel(sources[0], 7),
- fs_reg(0xffffu)))->force_writemask_all = true;
- }
-
- /* Set the surface read offset. */
- sources[1] = vgrf(glsl_type::uint_type);
- emit(MOV(sources[1], offset));
-
- int mlen = 1 + reg_width;
- fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
- BRW_REGISTER_TYPE_UD);
- fs_inst *inst = emit(LOAD_PAYLOAD(src_payload, sources, 2));
-
- /* Emit the instruction. */
- inst = emit(SHADER_OPCODE_UNTYPED_SURFACE_READ, dst, src_payload,
- fs_reg(surf_index), fs_reg(1));
- inst->mlen = mlen;
-}
-
fs_inst *
fs_visitor::emit(fs_inst *inst)
{
--
2.3.5
More information about the mesa-dev
mailing list