summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-02-08 18:00:05 -0800
committerJason Ekstrand <[email protected]>2018-05-09 11:16:33 -0700
commit906c32ce875b8d0aec73d226aae15eadcfc5f457 (patch)
tree5e6e8c977b1213001faf2c1ea622b40d37e1cd1a
parent1ef4f5aff1bb80685a7d8407ce74040f7494068f (diff)
intel/blorp: Add swizzle support for all hardware
This commit makes blorp capable of swizzling anything even on hardware that doesn't support texture swizzle. Reviewed-by: Topi Pohjolainen <[email protected]>
-rw-r--r--src/intel/blorp/blorp_blit.c64
-rw-r--r--src/intel/blorp/blorp_priv.h6
2 files changed, 69 insertions, 1 deletions
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index 7d717da0912..5cfc1a90ac0 100644
--- a/src/intel/blorp/blorp_blit.c
+++ b/src/intel/blorp/blorp_blit.c
@@ -933,6 +933,40 @@ bit_cast_color(struct nir_builder *b, nir_ssa_def *color,
}
}
+static nir_ssa_def *
+select_color_channel(struct nir_builder *b, nir_ssa_def *color,
+ nir_alu_type data_type,
+ enum isl_channel_select chan)
+{
+ if (chan == ISL_CHANNEL_SELECT_ZERO) {
+ return nir_imm_int(b, 0);
+ } else if (chan == ISL_CHANNEL_SELECT_ONE) {
+ switch (data_type) {
+ case nir_type_int:
+ case nir_type_uint:
+ return nir_imm_int(b, 1);
+ case nir_type_float:
+ return nir_imm_float(b, 1);
+ default:
+ unreachable("Invalid data type");
+ }
+ } else {
+ assert((unsigned)(chan - ISL_CHANNEL_SELECT_RED) < 4);
+ return nir_channel(b, color, chan - ISL_CHANNEL_SELECT_RED);
+ }
+}
+
+static nir_ssa_def *
+swizzle_color(struct nir_builder *b, nir_ssa_def *color,
+ struct isl_swizzle swizzle, nir_alu_type data_type)
+{
+ return nir_vec4(b,
+ select_color_channel(b, color, data_type, swizzle.r),
+ select_color_channel(b, color, data_type, swizzle.g),
+ select_color_channel(b, color, data_type, swizzle.b),
+ select_color_channel(b, color, data_type, swizzle.a));
+}
+
/**
* Generator for WM programs used in BLORP blits.
*
@@ -1289,8 +1323,21 @@ brw_blorp_build_nir_shader(struct blorp_context *blorp, void *mem_ctx,
}
}
- if (key->dst_bpc != key->src_bpc)
+ if (!isl_swizzle_is_identity(key->src_swizzle)) {
+ color = swizzle_color(&b, color, key->src_swizzle,
+ key->texture_data_type);
+ }
+
+ if (!isl_swizzle_is_identity(key->dst_swizzle)) {
+ color = swizzle_color(&b, color, isl_swizzle_invert(key->dst_swizzle),
+ nir_type_int);
+ }
+
+ if (key->dst_bpc != key->src_bpc) {
+ assert(isl_swizzle_is_identity(key->src_swizzle));
+ assert(isl_swizzle_is_identity(key->dst_swizzle));
color = bit_cast_color(&b, color, key);
+ }
if (key->dst_rgb) {
/* The destination image is bound as a red texture three times as wide
@@ -1835,6 +1882,21 @@ try_blorp_blit(struct blorp_batch *batch,
wm_prog_key->need_dst_offset = true;
}
+ if (devinfo->gen <= 7 && !devinfo->is_haswell &&
+ !isl_swizzle_is_identity(params->src.view.swizzle)) {
+ wm_prog_key->src_swizzle = params->src.view.swizzle;
+ params->src.view.swizzle = ISL_SWIZZLE_IDENTITY;
+ } else {
+ wm_prog_key->src_swizzle = ISL_SWIZZLE_IDENTITY;
+ }
+
+ if (!isl_swizzle_supports_rendering(devinfo, params->dst.view.swizzle)) {
+ wm_prog_key->dst_swizzle = params->dst.view.swizzle;
+ params->dst.view.swizzle = ISL_SWIZZLE_IDENTITY;
+ } else {
+ wm_prog_key->dst_swizzle = ISL_SWIZZLE_IDENTITY;
+ }
+
if (params->src.tile_x_sa || params->src.tile_y_sa) {
assert(wm_prog_key->need_src_offset);
surf_get_intratile_offset_px(&params->src,
diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h
index 3811ec6fbc0..1c2cb20acf0 100644
--- a/src/intel/blorp/blorp_priv.h
+++ b/src/intel/blorp/blorp_priv.h
@@ -243,6 +243,9 @@ struct brw_blorp_blit_prog_key
/* Actual MSAA layout used by the source image. */
enum isl_msaa_layout src_layout;
+ /* The swizzle to apply to the source in the shader */
+ struct isl_swizzle src_swizzle;
+
/* Number of bits per channel in the source image. */
uint8_t src_bpc;
@@ -263,6 +266,9 @@ struct brw_blorp_blit_prog_key
/* Actual MSAA layout used by the destination image. */
enum isl_msaa_layout dst_layout;
+ /* The swizzle to apply to the destination in the shader */
+ struct isl_swizzle dst_swizzle;
+
/* Number of bits per channel in the destination image. */
uint8_t dst_bpc;