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.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index 1cbd9403c98..111f1c13a81 100644
--- a/src/intel/blorp/blorp_blit.c
+++ b/src/intel/blorp/blorp_blit.c
@@ -26,6 +26,9 @@
#include "blorp_priv.h"
#include "brw_meta_util.h"
+/* header-only include needed for _mesa_unorm_to_float and friends. */
+#include "mesa/main/format_utils.h"
+
#define FILE_DEBUG_FLAG DEBUG_BLORP
static const bool split_blorp_blit_debug = false;
@@ -2204,6 +2207,75 @@ get_ccs_compatible_uint_format(const struct isl_format_layout *fmtl)
}
}
+/* Takes an isl_color_value and returns a color value that is the original
+ * color value only bit-casted to a UINT format. This value, together with
+ * the format from get_ccs_compatible_uint_format, will yield the same bit
+ * value as the original color and format.
+ */
+static union isl_color_value
+bitcast_color_value_to_uint(union isl_color_value color,
+ const struct isl_format_layout *fmtl)
+{
+ /* All CCS formats have the same number of bits in each channel */
+ const struct isl_channel_layout *chan = &fmtl->channels.r;
+
+ union isl_color_value bits;
+ switch (chan->type) {
+ case ISL_UINT:
+ case ISL_SINT:
+ /* Hardware will ignore the high bits so there's no need to cast */
+ bits = color;
+ break;
+
+ case ISL_UNORM:
+ for (unsigned i = 0; i < 4; i++)
+ bits.u32[i] = _mesa_float_to_unorm(color.f32[i], chan->bits);
+ break;
+
+ case ISL_SNORM:
+ for (unsigned i = 0; i < 4; i++)
+ bits.i32[i] = _mesa_float_to_snorm(color.f32[i], chan->bits);
+ break;
+
+ case ISL_SFLOAT:
+ switch (chan->bits) {
+ case 16:
+ for (unsigned i = 0; i < 4; i++)
+ bits.u32[i] = _mesa_float_to_half(color.f32[i]);
+ break;
+
+ case 32:
+ bits = color;
+ break;
+
+ default:
+ unreachable("Invalid float format size");
+ }
+ break;
+
+ default:
+ unreachable("Invalid channel type");
+ }
+
+ switch (fmtl->format) {
+ case ISL_FORMAT_B8G8R8A8_UNORM:
+ case ISL_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case ISL_FORMAT_B8G8R8X8_UNORM:
+ case ISL_FORMAT_B8G8R8X8_UNORM_SRGB: {
+ /* If it's a BGRA format, we need to swap blue and red */
+ uint32_t tmp = bits.u32[0];
+ bits.u32[0] = bits.u32[2];
+ bits.u32[2] = tmp;
+ break;
+ }
+
+ default:
+ break; /* Nothing to do */
+ }
+
+ return bits;
+}
+
static void
surf_convert_to_uncompressed(const struct isl_device *isl_dev,
struct brw_blorp_surface_info *info,
@@ -2320,6 +2392,16 @@ blorp_copy(struct blorp_batch *batch,
params.src.view.format = get_copy_format_for_bpb(isl_dev, src_fmtl->bpb);
}
+ if (params.src.aux_usage == ISL_AUX_USAGE_CCS_E) {
+ params.src.clear_color =
+ bitcast_color_value_to_uint(params.src.clear_color, src_fmtl);
+ }
+
+ if (params.dst.aux_usage == ISL_AUX_USAGE_CCS_E) {
+ params.dst.clear_color =
+ bitcast_color_value_to_uint(params.dst.clear_color, dst_fmtl);
+ }
+
wm_prog_key.src_bpc =
isl_format_get_layout(params.src.view.format)->channels.r.bits;
wm_prog_key.dst_bpc =