[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