intel/blorp: Add swizzle support for all hardware
authorJason Ekstrand <jason.ekstrand@intel.com>
Thu, 9 Feb 2017 02:00:05 +0000 (18:00 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 9 May 2018 18:16:33 +0000 (11:16 -0700)
This commit makes blorp capable of swizzling anything even on hardware
that doesn't support texture swizzle.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/intel/blorp/blorp_blit.c
src/intel/blorp/blorp_priv.h

index 7d717da0912cc389accd5d7b72f039c48d515ced..5cfc1a90ac0c0187217b3491a0db4de47cf70db4 100644 (file)
@@ -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,
index 3811ec6fbc00ce611c877c184a6e12e05eda0428..1c2cb20acf0e3accc4d9a6269b363b1ce9485285 100644 (file)
@@ -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;