--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev