This is a rewrite of the GLSL IR atomic counter intrinsics translation code based on the recently introduced surface builder.
v2: Drop VEC4 suport. --- src/mesa/drivers/dri/i965/brw_fs.h | 3 +- src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 79 ++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 0834ca5..6d3701c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -59,6 +59,7 @@ namespace { namespace brw { class fs_live_variables; + class fs_builder; } /** @@ -445,7 +446,7 @@ public: void dump_instruction(backend_instruction *inst); void dump_instruction(backend_instruction *inst, FILE *file); - void visit_atomic_counter_intrinsic(ir_call *ir); + void visit_atomic_counter_intrinsic(const brw::fs_builder &bld, 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_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 9c394ba..57076c5 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -42,11 +42,13 @@ #include "brw_cs.h" #include "brw_vec4.h" #include "brw_fs.h" +#include "brw_fs_surface_builder.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) @@ -3160,43 +3162,76 @@ fs_visitor::visit(ir_loop_jump *ir) } } +/** + * Process the i-th parameter passed to an intrinsic call. + */ +static fs_reg +visit_argument(fs_visitor *v, ir_call *ir, unsigned i) +{ + unsigned j = 0; + + foreach_in_list(ir_dereference, arg, &ir->actual_parameters) { + if (j++ == i) + return v->visit_result(arg); + } + + return fs_reg(); +} + void -fs_visitor::visit_atomic_counter_intrinsic(ir_call *ir) +fs_visitor::visit_atomic_counter_intrinsic(const fs_builder &bld, 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); - const fs_reg offset = visit_result(deref); - - /* Emit the appropriate machine instruction */ - const char *callee = ir->callee->function_name(); - ir->return_deref->accept(this); - fs_reg dst = this->result; + using namespace surface_access; - if (!strcmp("__intrinsic_atomic_read", callee)) { - emit_untyped_surface_read(surf_index, dst, offset); + /* Get the referenced atomic counter variable. */ + const ir_variable *var = static_cast<ir_dereference *>( + ir->actual_parameters.get_head())->variable_referenced(); - } else if (!strcmp("__intrinsic_atomic_increment", callee)) { - emit_untyped_atomic(BRW_AOP_INC, surf_index, dst, offset, - fs_reg(), fs_reg()); + /* Visit the arguments of the atomic intrinsic. */ + const fs_reg offset = visit_argument(this, ir, 0); + const fs_reg surface(stage_prog_data->binding_table.abo_start + + var->data.binding); - } else if (!strcmp("__intrinsic_atomic_predecrement", callee)) { - emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dst, offset, - fs_reg(), fs_reg()); - } + /* Get some metadata from the atomic intrinsic. */ + const char *callee = ir->callee->function_name(); + const unsigned rsize = (ir->return_deref ? 1 : 0); + fs_reg tmp; + + /* Emit a surface read or atomic op. */ + if (!strcmp("__intrinsic_atomic_read", callee)) + tmp = surface_access::emit_untyped_read(bld, surface, offset, 1, 1); + + else if (!strcmp("__intrinsic_atomic_increment", callee)) + tmp = surface_access::emit_untyped_atomic( + bld, surface, offset, fs_reg(), fs_reg(), + 1, rsize, BRW_AOP_INC); + + else if (!strcmp("__intrinsic_atomic_predecrement", callee)) + tmp = surface_access::emit_untyped_atomic( + bld, surface, offset, fs_reg(), fs_reg(), + 1, rsize, BRW_AOP_PREDEC); + + /* Assign the result. */ + if (ir->return_deref) + bld.MOV(visit_result(ir->return_deref), tmp); } 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); + visit_atomic_counter_intrinsic(bld, ir); } else { unreachable("Unsupported intrinsic."); } -- 2.3.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev