<div dir="ltr">On 29 October 2013 16:37, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">This can deal with all the 15 32-bit untyped atomic operations the<br>
hardware supports, but only INC and PREDEC are going to be exposed<br>
through the API for now.<br>
<br>
v2: Represent atomics as GLSL intrinsics.  Add support for variably<br>
    indexed atomic counter arrays.<br>
---<br>
 src/mesa/drivers/dri/i965/brw_vec4.h           |   9 +++<br>
</div> src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 100 ++++++++++++++++++++++++-<br>
 2 files changed, 107 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h<br>
index a479646..1f29e57 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_vec4.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h<br>
@@ -489,6 +489,13 @@ public:<br>
<div class="im">    void emit_shader_time_write(enum shader_time_shader_type type,<br>
                                src_reg value);<br>
<br>
+   void emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,<br>
+                            dst_reg dst, src_reg offset, src_reg src0,<br>
+                            src_reg src1);<br>
+<br>
+   void emit_untyped_surface_read(unsigned surf_index, dst_reg dst,<br>
+                                  src_reg offset);<br>
+<br>
    src_reg get_scratch_offset(vec4_instruction *inst,<br>
                              src_reg *reladdr, int reg_offset);<br>
    src_reg get_pull_constant_offset(vec4_instruction *inst,<br>
</div>@@ -514,6 +521,8 @@ public:<br>
<div class="im"><br>
    void dump_instruction(backend_instruction *inst);<br>
<br>
+   void visit_atomic_counter_intrinsic(ir_call *ir);<br>
+<br>
 protected:<br>
    void emit_vertex();<br>
</div>    void lower_attributes_to_hw_regs(const int *attribute_map,<br>
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp<br>
index 7f2ca95..7f8d49c 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp<br>
@@ -975,7 +975,7 @@ vec4_visitor::visit(ir_variable *ir)<br>
        * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO<br>
        * variables, so no need for them to be in variable_ht.<br>
        */<br>
-      if (ir->is_in_uniform_block())<br>
+      if (ir->is_in_uniform_block() || ir->type->contains_atomic())<br></blockquote><div><br></div><div>As with the previous patch, the comment above this "if" statement should be updated to explain why it's ok to return when encountering a variable that contains an atomic.<br>
<br>With that fixed, this patch is:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

          return;<br>
<br>
       /* Track how big the whole uniform variable is, in case we need to put a<br>
@@ -2160,9 +2160,56 @@ vec4_visitor::visit(ir_constant *ir)<br>
<div class="im"> }<br>
<br>
 void<br>
+vec4_visitor::visit_atomic_counter_intrinsic(ir_call *ir)<br>
+{<br>
+   ir_dereference *deref = static_cast<ir_dereference *>(<br>
+      ir->actual_parameters.get_head());<br>
+   ir_variable *location = deref->variable_referenced();<br>
</div>+   unsigned surf_index = (prog_data->base.binding_table.abo_start +<br>
+                          location->atomic.buffer_index);<br>
<div><div class="h5">+<br>
+   /* Calculate the surface offset */<br>
+   src_reg offset(this, glsl_type::uint_type);<br>
+   ir_dereference_array *deref_array = deref->as_dereference_array();<br>
+   if (deref_array) {<br>
+      deref_array->array_index->accept(this);<br>
+<br>
+      src_reg tmp(this, glsl_type::uint_type);<br>
+      emit(MUL(dst_reg(tmp), this->result, ATOMIC_COUNTER_SIZE));<br>
+      emit(ADD(dst_reg(offset), tmp, location->atomic.offset));<br>
+   } else {<br>
+      offset = location->atomic.offset;<br>
+   }<br>
+<br>
+   /* Emit the appropriate machine instruction */<br>
+   const char *callee = ir->callee->function_name();<br>
+   dst_reg dst = get_assignment_lhs(ir->return_deref, this);<br>
+<br>
+   if (!strcmp("__intrinsic_atomic_read", callee)) {<br>
+      emit_untyped_surface_read(surf_index, dst, offset);<br>
+<br>
+   } else if (!strcmp("__intrinsic_atomic_increment", callee)) {<br>
+      emit_untyped_atomic(BRW_AOP_INC, surf_index, dst, offset,<br>
+                          src_reg(), src_reg());<br>
+<br>
+   } else if (!strcmp("__intrinsic_atomic_predecrement", callee)) {<br>
+      emit_untyped_atomic(BRW_AOP_PREDEC, surf_index, dst, offset,<br>
+                          src_reg(), src_reg());<br>
+   }<br>
+}<br>
+<br>
+void<br>
 vec4_visitor::visit(ir_call *ir)<br>
 {<br>
-   assert(!"not reached");<br>
+   const char *callee = ir->callee->function_name();<br>
+<br>
+   if (!strcmp("__intrinsic_atomic_read", callee) ||<br>
+       !strcmp("__intrinsic_atomic_increment", callee) ||<br>
+       !strcmp("__intrinsic_atomic_predecrement", callee)) {<br>
+      visit_atomic_counter_intrinsic(ir);<br>
+   } else {<br>
+      assert(!"Unsupported intrinsic.");<br>
+   }<br>
 }<br>
<br>
 void<br>
</div></div>@@ -2557,6 +2604,55 @@ vec4_visitor::visit(ir_end_primitive *)<br>
<div class="HOEnZb"><div class="h5"> }<br>
<br>
 void<br>
+vec4_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index,<br>
+                                  dst_reg dst, src_reg offset,<br>
+                                  src_reg src0, src_reg src1)<br>
+{<br>
+   unsigned mlen = 0;<br>
+<br>
+   /* Set the atomic operation offset. */<br>
+   emit(MOV(brw_writemask(brw_uvec_mrf(8, mlen, 0), WRITEMASK_X), offset));<br>
+   mlen++;<br>
+<br>
+   /* Set the atomic operation arguments. */<br>
+   if (src0.file != BAD_FILE) {<br>
+      emit(MOV(brw_writemask(brw_uvec_mrf(8, mlen, 0), WRITEMASK_X), src0));<br>
+      mlen++;<br>
+   }<br>
+<br>
+   if (src1.file != BAD_FILE) {<br>
+      emit(MOV(brw_writemask(brw_uvec_mrf(8, mlen, 0), WRITEMASK_X), src1));<br>
+      mlen++;<br>
+   }<br>
+<br>
+   /* Emit the instruction.  Note that this maps to the normal SIMD8<br>
+    * untyped atomic message on Ivy Bridge, but that's OK because<br>
+    * unused channels will be masked out.<br>
+    */<br>
+   vec4_instruction *inst = emit(SHADER_OPCODE_UNTYPED_ATOMIC, dst,<br>
+                                 src_reg(atomic_op), src_reg(surf_index));<br>
+   inst->base_mrf = 0;<br>
+   inst->mlen = mlen;<br>
+}<br>
+<br>
+void<br>
+vec4_visitor::emit_untyped_surface_read(unsigned surf_index, dst_reg dst,<br>
+                                        src_reg offset)<br>
+{<br>
+   /* Set the surface read offset. */<br>
+   emit(MOV(brw_writemask(brw_uvec_mrf(8, 0, 0), WRITEMASK_X), offset));<br>
+<br>
+   /* Emit the instruction.  Note that this maps to the normal SIMD8<br>
+    * untyped surface read message, but that's OK because unused<br>
+    * channels will be masked out.<br>
+    */<br>
+   vec4_instruction *inst = emit(SHADER_OPCODE_UNTYPED_SURFACE_READ,<br>
+                                 dst, src_reg(surf_index));<br>
+   inst->base_mrf = 0;<br>
+   inst->mlen = 1;<br>
+}<br>
+<br>
+void<br>
 vec4_visitor::emit_ndc_computation()<br>
 {<br>
    /* Get the position */<br>
--<br>
1.8.3.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>