[Mesa-dev] [PATCH 17/23] i965: Import GLSL IR image intrinsic translation code.

Francisco Jerez currojerez at riseup.net
Tue Apr 28 11:44:28 PDT 2015


---
 src/mesa/drivers/dri/i965/brw_ir_glsl_intrinsics.h | 136 +++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_reg.h                |   1 +
 2 files changed, 137 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_ir_glsl_intrinsics.h b/src/mesa/drivers/dri/i965/brw_ir_glsl_intrinsics.h
index cc838e9..df7b1a3 100644
--- a/src/mesa/drivers/dri/i965/brw_ir_glsl_intrinsics.h
+++ b/src/mesa/drivers/dri/i965/brw_ir_glsl_intrinsics.h
@@ -95,6 +95,142 @@ namespace brw {
       if (ir->return_deref)
          vbld.MOV(dst_reg(v->visit_result(ir->return_deref)), tmp);
    }
+
+   namespace detail {
+      /**
+       * Get the appropriate atomic op for an image atomic intrinsic.
+       */
+      inline unsigned
+      get_image_atomic_op(const char *callee, const glsl_type *type)
+      {
+         const glsl_base_type base_type = (glsl_base_type)type->sampler_type;
+
+         if (!strcmp("__intrinsic_image_atomic_add", callee))
+            return BRW_AOP_ADD;
+
+         else if (!strcmp("__intrinsic_image_atomic_min", callee))
+            return (base_type == GLSL_TYPE_UINT ? BRW_AOP_UMIN : BRW_AOP_IMIN);
+
+         else if (!strcmp("__intrinsic_image_atomic_max", callee))
+            return (base_type == GLSL_TYPE_UINT ? BRW_AOP_UMAX : BRW_AOP_IMAX);
+
+         else if (!strcmp("__intrinsic_image_atomic_and", callee))
+            return BRW_AOP_AND;
+
+         else if (!strcmp("__intrinsic_image_atomic_or", callee))
+            return BRW_AOP_OR;
+
+         else if (!strcmp("__intrinsic_image_atomic_xor", callee))
+            return BRW_AOP_XOR;
+
+         else if (!strcmp("__intrinsic_image_atomic_exchange", callee))
+            return BRW_AOP_MOV;
+
+         else if (!strcmp("__intrinsic_image_atomic_comp_swap", callee))
+            return BRW_AOP_CMPWR;
+
+         else
+            unreachable("Not reachable.");
+      }
+
+      /**
+       * Return true if the image is a 1D array and the implementation
+       * requires the array index to be passed in as the Z component of the
+       * coordinate vector.
+       */
+      template<typename B>
+      inline bool
+      needs_zero_y_image_coordinate(const B &bld, const ir_variable *image)
+      {
+         const glsl_type *type = image->type->without_array();
+         const mesa_format format =
+            _mesa_get_shader_image_format(image->data.image_format);
+         /* HSW in vec4 mode and our software coordinate handling for untyped
+          * reads want the array index to be at the Z component.
+          */
+         const bool array_index_at_z =
+            (bld.devinfo->is_haswell && B::dst_reg::traits::chan_size == 4) ||
+            (!image->data.image_write_only &&
+             !image_format_info::has_matching_typed_format(bld.devinfo, format));
+
+         return (type->sampler_dimensionality == GLSL_SAMPLER_DIM_1D &&
+                 type->sampler_array && array_index_at_z);
+      }
+
+      /**
+       * Transform image coordinates into the form expected by the
+       * implementation.
+       */
+      template<typename B, typename S>
+      S
+      fix_image_address(const B &bld, const ir_variable *image, const S &addr)
+      {
+         if (needs_zero_y_image_coordinate(bld, image)) {
+            const typename B::dst_reg tmp = bld.natural_reg(addr.type);
+
+            bld.MOV(writemask(tmp, WRITEMASK_XZW),
+                    swizzle(addr, BRW_SWIZZLE_XWYZ));
+            bld.MOV(writemask(tmp, WRITEMASK_Y), 0);
+
+            return tmp;
+         } else {
+            return addr;
+         }
+      }
+   }
+
+   /**
+    * Entry point for translating GLSL IR image intrinsics.
+    */
+   template<typename V, typename B>
+   void
+   visit_image_intrinsic(V *v, const B &bld, ir_call *ir)
+   {
+      using namespace detail;
+      using namespace image_access;
+      typedef typename B::vector_builder::src_reg src_reg;
+      typename B::vector_builder vbld = bld.vector();
+
+      /* Get the referenced image variable and type. */
+      const ir_variable *var = static_cast<ir_dereference *>(
+         ir->actual_parameters.get_head())->variable_referenced();
+      const glsl_type *type = var->type->without_array();
+
+      /* Visit the arguments of the image intrinsic. */
+      const unsigned first_src_idx =
+         (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS ? 3 : 2);
+      const src_reg image = visit_argument<src_reg>(v, ir, 0);
+      const src_reg addr = fix_image_address(vbld, var,
+                                             visit_argument<src_reg>(v, ir, 1));
+      const src_reg src0 = visit_argument<src_reg>(v, ir, first_src_idx);
+      const src_reg src1 = visit_argument<src_reg>(v, ir, first_src_idx + 1);
+
+      /* Get some metadata from the image intrinsic. */
+      const char *callee = ir->callee->function_name();
+      const unsigned dims = (type->coordinate_components() +
+                             (needs_zero_y_image_coordinate(bld, var) ? 1 : 0));
+      const mesa_format format =
+         (var->data.image_write_only ? MESA_FORMAT_NONE :
+          _mesa_get_shader_image_format(var->data.image_format));
+      src_reg tmp;
+
+      /* Emit an image load, store or atomic op. */
+      if (!strcmp("__intrinsic_image_load", callee))
+         tmp = emit_image_load(vbld, image, addr, format, dims);
+
+      else if (!strcmp("__intrinsic_image_store", callee))
+         emit_image_store(vbld, image, addr, src0, format, dims);
+
+      else
+         tmp = emit_image_atomic(vbld, image, addr, src0, src1,
+                                 dims, (ir->return_deref ? 1 : 0),
+                                 get_image_atomic_op(callee, type));
+
+      /* Assign the result. */
+      if (ir->return_deref)
+         vbld.MOV(dst_vector(v->visit_result(ir->return_deref),
+                             ir->return_deref->type->vector_elements), tmp);
+   }
 }
 
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_reg.h b/src/mesa/drivers/dri/i965/brw_reg.h
index 668f83c..1db2252b 100644
--- a/src/mesa/drivers/dri/i965/brw_reg.h
+++ b/src/mesa/drivers/dri/i965/brw_reg.h
@@ -82,6 +82,7 @@ struct brw_device_info;
 #define BRW_SWIZZLE_ZZZZ      BRW_SWIZZLE4(2,2,2,2)
 #define BRW_SWIZZLE_WWWW      BRW_SWIZZLE4(3,3,3,3)
 #define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
+#define BRW_SWIZZLE_XWYZ      BRW_SWIZZLE4(0,3,1,2)
 #define BRW_SWIZZLE_XZXZ      BRW_SWIZZLE4(0,2,0,2)
 #define BRW_SWIZZLE_YZXW      BRW_SWIZZLE4(1,2,0,3)
 #define BRW_SWIZZLE_YZYZ      BRW_SWIZZLE4(1,2,1,2)
-- 
2.3.5



More information about the mesa-dev mailing list