[Mesa-dev] [PATCH 23/29] i965/fs: Revisit GLSL IR atomic counter intrinsic translation.
Francisco Jerez
currojerez at riseup.net
Sat May 2 08:29:50 PDT 2015
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
More information about the mesa-dev
mailing list