[Mesa-dev] [PATCH 13/29] i965/vec4: Obtain atomic counter locations by recursing through the visitor.

Francisco Jerez currojerez at riseup.net
Sat May 2 08:29:40 PDT 2015


Until now atomic counter built-ins were handled in a way that
prevented the visitor from encountering atomic counter IR variables
and dereferences directly.  With the new intrinsic lowering code it's
going to be more convenient to be able to call back into the visitor
to let it handle the ugly details of atomic counter array
dereferences, and it will make sharing the rest of the atomic
intrinsic handling code easier.
---
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 123 +++++++++++++------------
 1 file changed, 63 insertions(+), 60 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index d218f19..22586de 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -1066,28 +1066,32 @@ vec4_visitor::visit(ir_variable *ir)
       break;
 
    case ir_var_uniform:
-      reg = new(this->mem_ctx) dst_reg(UNIFORM, this->uniforms);
+      if (ir->type->contains_atomic()) {
+         reg = new(this->mem_ctx) dst_reg(ir->data.atomic.offset);
 
-      /* Thanks to the lower_ubo_reference pass, we will see only
-       * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO
-       * variables, so no need for them to be in variable_ht.
-       *
-       * Some uniforms, such as samplers and atomic counters, have no actual
-       * storage, so we should ignore them.
-       */
-      if (ir->is_in_uniform_block() || type_size(ir->type) == 0)
+      } else if (ir->is_in_uniform_block() || type_size(ir->type) == 0) {
+         /* Thanks to the lower_ubo_reference pass, we will see only
+          * ir_binop_ubo_load expressions and not ir_dereference_variable for
+          * UBO variables, so no need for them to be in variable_ht.
+          *
+          * Some uniforms such as samplers have no actual storage, so we
+          * should ignore them.
+          */
          return;
+      } else {
+         reg = new(this->mem_ctx) dst_reg(UNIFORM, this->uniforms);
 
-      /* Track how big the whole uniform variable is, in case we need to put a
-       * copy of its data into pull constants for array access.
-       */
-      assert(this->uniforms < uniform_array_size);
-      this->uniform_size[this->uniforms] = type_size(ir->type);
+         /* Track how big the whole uniform variable is, in case we need to
+          * put a copy of its data into pull constants for array access.
+          */
+         assert(this->uniforms < uniform_array_size);
+         this->uniform_size[this->uniforms] = type_size(ir->type);
 
-      if (!strncmp(ir->name, "gl_", 3)) {
-	 setup_builtin_uniform_values(ir);
-      } else {
-	 setup_uniform_values(ir);
+         if (!strncmp(ir->name, "gl_", 3)) {
+            setup_builtin_uniform_values(ir);
+         } else {
+            setup_uniform_values(ir);
+         }
       }
       break;
 
@@ -2053,45 +2057,56 @@ vec4_visitor::visit(ir_dereference_array *ir)
    ir->array->accept(this);
    src = this->result;
 
-   if (constant_index) {
-      src.reg_offset += constant_index->value.i[0] * array_stride;
-   } else {
-      /* Variable index array dereference.  It eats the "vec4" of the
-       * base of the array and an index that offsets the Mesa register
-       * index.
-       */
-      ir->array_index->accept(this);
+   if (ir->array->type->contains_atomic()) {
+      dst_reg tmp(this, glsl_type::uint_type);
 
-      src_reg index_reg;
+      ir->array_index->accept(this);
+      emit(MUL(tmp, this->result, ATOMIC_COUNTER_SIZE));
+      emit(ADD(tmp, src_reg(tmp), src));
+      this->result = src_reg(tmp);
 
-      if (array_stride == 1) {
-	 index_reg = this->result;
+   } else {
+      if (constant_index) {
+         src.reg_offset += constant_index->value.i[0] * array_stride;
       } else {
-	 index_reg = src_reg(this, glsl_type::int_type);
+         /* Variable index array dereference.  It eats the "vec4" of the
+          * base of the array and an index that offsets the Mesa register
+          * index.
+          */
+         ir->array_index->accept(this);
 
-	 emit(MUL(dst_reg(index_reg), this->result, src_reg(array_stride)));
-      }
+         src_reg index_reg;
 
-      if (src.reladdr) {
-	 src_reg temp = src_reg(this, glsl_type::int_type);
+         if (array_stride == 1) {
+            index_reg = this->result;
+         } else {
+            index_reg = src_reg(this, glsl_type::int_type);
 
-	 emit(ADD(dst_reg(temp), *src.reladdr, index_reg));
+            emit(MUL(dst_reg(index_reg), this->result, src_reg(array_stride)));
+         }
 
-	 index_reg = temp;
-      }
+         if (src.reladdr) {
+            src_reg temp = src_reg(this, glsl_type::int_type);
 
-      src.reladdr = ralloc(mem_ctx, src_reg);
-      memcpy(src.reladdr, &index_reg, sizeof(index_reg));
-   }
+            emit(ADD(dst_reg(temp), *src.reladdr, index_reg));
 
-   /* If the type is smaller than a vec4, replicate the last channel out. */
-   if (ir->type->is_scalar() || ir->type->is_vector() || ir->type->is_matrix())
-      src.swizzle = brw_swizzle_for_size(ir->type->vector_elements);
-   else
-      src.swizzle = BRW_SWIZZLE_NOOP;
-   src.type = brw_type_for_base_type(ir->type);
+            index_reg = temp;
+         }
+
+         src.reladdr = ralloc(mem_ctx, src_reg);
+         memcpy(src.reladdr, &index_reg, sizeof(index_reg));
+      }
+
+      /* If the type is smaller than a vec4, replicate the last channel out. */
+      if (ir->type->is_scalar() || ir->type->is_vector() ||
+          ir->type->is_matrix())
+         src.swizzle = brw_swizzle_for_size(ir->type->vector_elements);
+      else
+         src.swizzle = BRW_SWIZZLE_NOOP;
+      src.type = brw_type_for_base_type(ir->type);
 
-   this->result = src;
+      this->result = src;
+   }
 }
 
 void
@@ -2421,19 +2436,7 @@ vec4_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
    ir_variable *location = deref->variable_referenced();
    unsigned surf_index = (prog_data->base.binding_table.abo_start +
                           location->data.binding);
-
-   /* Calculate the surface offset */
-   src_reg offset(this, glsl_type::uint_type);
-   ir_dereference_array *deref_array = deref->as_dereference_array();
-   if (deref_array) {
-      deref_array->array_index->accept(this);
-
-      src_reg tmp(this, glsl_type::uint_type);
-      emit(MUL(dst_reg(tmp), this->result, ATOMIC_COUNTER_SIZE));
-      emit(ADD(dst_reg(offset), tmp, location->data.atomic.offset));
-   } else {
-      offset = location->data.atomic.offset;
-   }
+   const src_reg offset = visit_result(deref);
 
    /* Emit the appropriate machine instruction */
    const char *callee = ir->callee->function_name();
-- 
2.3.5



More information about the mesa-dev mailing list