summaryrefslogtreecommitdiffstats
path: root/src/intel/blorp
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel/blorp')
-rw-r--r--src/intel/blorp/blorp_blit.c48
-rw-r--r--src/intel/blorp/blorp_priv.h6
2 files changed, 54 insertions, 0 deletions
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index d54dd1ecc0d..8b64cd7bad2 100644
--- a/src/intel/blorp/blorp_blit.c
+++ b/src/intel/blorp/blorp_blit.c
@@ -26,6 +26,7 @@
#include "blorp_priv.h"
+#include "util/format_rgb9e5.h"
/* header-only include needed for _mesa_unorm_to_float and friends. */
#include "mesa/main/format_utils.h"
@@ -949,6 +950,36 @@ swizzle_color(struct nir_builder *b, nir_ssa_def *color,
select_color_channel(b, color, data_type, swizzle.a));
}
+static nir_ssa_def *
+convert_color(struct nir_builder *b, nir_ssa_def *color,
+ const struct brw_blorp_blit_prog_key *key)
+{
+ /* All of our color conversions end up generating a single-channel color
+ * value that we need to write out.
+ */
+ nir_ssa_def *value;
+
+ if (key->dst_format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) {
+ /* The destination image is bound as R32_UNORM but the data needs to be
+ * in R24_UNORM_X8_TYPELESS. The bottom 24 are the actual data and the
+ * top 8 need to be zero. We can accomplish this by simply multiplying
+ * by a factor to scale things down.
+ */
+ float factor = (float)((1 << 24) - 1) / (float)UINT32_MAX;
+ value = nir_fmul(b, nir_fsat(b, nir_channel(b, color, 0)),
+ nir_imm_float(b, factor));
+ } else if (key->dst_format == ISL_FORMAT_L8_UNORM_SRGB) {
+ value = nir_format_linear_to_srgb(b, color);
+ } else if (key->dst_format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
+ value = nir_format_pack_r9g9b9e5(b, color);
+ } else {
+ unreachable("Unsupported format conversion");
+ }
+
+ nir_ssa_def *u = nir_ssa_undef(b, 1, 32);
+ return nir_vec4(b, value, u, u, u);
+}
+
/**
* Generator for WM programs used in BLORP blits.
*
@@ -1321,6 +1352,9 @@ brw_blorp_build_nir_shader(struct blorp_context *blorp, void *mem_ctx,
color = bit_cast_color(&b, color, key);
}
+ if (key->dst_format)
+ color = convert_color(&b, color, key);
+
if (key->dst_rgb) {
/* The destination image is bound as a red texture three times as wide
* as the actual image. Our shader is effectively running one color
@@ -1862,6 +1896,20 @@ try_blorp_blit(struct blorp_batch *batch,
wm_prog_key->dst_rgb = true;
wm_prog_key->need_dst_offset = true;
+ } else if (params->dst.view.format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) {
+ wm_prog_key->dst_format = params->dst.view.format;
+ params->dst.view.format = ISL_FORMAT_R32_UNORM;
+ } else if (params->dst.view.format == ISL_FORMAT_A4B4G4R4_UNORM) {
+ params->dst.view.swizzle =
+ isl_swizzle_compose(params->dst.view.swizzle,
+ ISL_SWIZZLE(ALPHA, RED, GREEN, BLUE));
+ params->dst.view.format = ISL_FORMAT_B4G4R4A4_UNORM;
+ } else if (params->dst.view.format == ISL_FORMAT_L8_UNORM_SRGB) {
+ wm_prog_key->dst_format = params->dst.view.format;
+ params->dst.view.format = ISL_FORMAT_R8_UNORM;
+ } else if (params->dst.view.format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
+ wm_prog_key->dst_format = params->dst.view.format;
+ params->dst.view.format = ISL_FORMAT_R32_UINT;
}
if (devinfo->gen <= 7 && !devinfo->is_haswell &&
diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h
index 1c2cb20acf0..97f5d298339 100644
--- a/src/intel/blorp/blorp_priv.h
+++ b/src/intel/blorp/blorp_priv.h
@@ -272,6 +272,12 @@ struct brw_blorp_blit_prog_key
/* Number of bits per channel in the destination image. */
uint8_t dst_bpc;
+ /* The format of the destination if format-specific workarounds are needed
+ * and 0 (ISL_FORMAT_R32G32B32A32_FLOAT) if the destination is natively
+ * renderable.
+ */
+ enum isl_format dst_format;
+
/* Type of the data to be read from the texture (one of
* nir_type_(int|uint|float)).
*/