[Mesa-dev] [PATCH] intel/blorp/copy: Properly handle clear colors for CCS_E images
Jason Ekstrand
jason at jlekstrand.net
Fri Jan 20 21:17:20 UTC 2017
In order to handle CCS_E, we stomp the image format to a UINT format and
then do some bitcasting logic in the shader. This works fine since SKL
render compression only considers the channel layout of the format and
not the format itself. In order for this to work on images that have
been fast-cleared, we need to also convert the clear color so that, when
interpreted as UINT, it provides the same bit value as it would have in
the original format. This fixes a bunch of OpenGL ES CTS tests for
copy_image when we start using CCS more aggressively.
Cc: "17.0" <mesa-stable at lists.freedesktop.org>
Cc: Ben Widawsky <ben at bwidawsk.net>
Cc: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/intel/blorp/blorp_blit.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index 1cbd940..111f1c1 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 =
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list