Mesa (main): gallium: add hook on getting canonical format
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Apr 19 08:48:38 UTC 2022
Module: Mesa
Branch: main
Commit: 606e42027e61aa759eb7ac69403e13816f8ccde1
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=606e42027e61aa759eb7ac69403e13816f8ccde1
Author: Juan A. Suarez Romero <jasuarez at igalia.com>
Date: Wed Apr 13 20:06:21 2022 +0200
gallium: add hook on getting canonical format
On swizzled copies canonical formats are used to reduce the formats to a
simpler subset.
Nevertheless, it is possible that some of the canonical formats defined
in Gallium are actually not supported by the drivers themselves.
This provides a driver-defined hook that can be used to provide an
alternative canonical format in case the canonical one defined by
Gallium is not supported by the driver.
Signed-off-by: Juan A. Suarez Romero <jasuarez at igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15693>
---
src/gallium/include/pipe/p_context.h | 10 ++++++
src/mesa/state_tracker/st_cb_copyimage.c | 53 +++++++++++++++++++-------------
2 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 75e30da09f9..c5b20f4cd23 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -999,6 +999,16 @@ struct pipe_context {
bool to_device, bool migrate_content);
/*@}*/
+ /**
+ * Return an equivalent canonical format which has the same component sizes
+ * and swizzles as the original, and it is supported by the driver. Gallium
+ * already does a first canonicalization step (see get_canonical_format()
+ * on st_cb_copyimage.c) and it calls this function (if defined) to get an
+ * alternative format if the picked is not supported by the driver.
+ */
+ enum pipe_format (*get_canonical_format)(struct pipe_context *context,
+ enum pipe_format format);
+
/**
* Get the default sample position for an individual sample point.
*
diff --git a/src/mesa/state_tracker/st_cb_copyimage.c b/src/mesa/state_tracker/st_cb_copyimage.c
index 25ae78045b2..72c7bcda0c5 100644
--- a/src/mesa/state_tracker/st_cb_copyimage.c
+++ b/src/mesa/state_tracker/st_cb_copyimage.c
@@ -54,7 +54,8 @@
* formats are not supported. (same as ARB_copy_image)
*/
static enum pipe_format
-get_canonical_format(enum pipe_format format)
+get_canonical_format(struct pipe_context *pipe,
+ enum pipe_format format)
{
const struct util_format_description *desc =
util_format_description(format);
@@ -62,7 +63,7 @@ get_canonical_format(enum pipe_format format)
/* Packed formats. Return the equivalent array format. */
if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
format == PIPE_FORMAT_R9G9B9E5_FLOAT)
- return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R8G8B8A8_UINT);
if (desc->nr_channels == 4 &&
desc->channel[0].size == 10 &&
@@ -72,32 +73,40 @@ get_canonical_format(enum pipe_format format)
if (desc->swizzle[0] == PIPE_SWIZZLE_X &&
desc->swizzle[1] == PIPE_SWIZZLE_Y &&
desc->swizzle[2] == PIPE_SWIZZLE_Z)
- return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R8G8B8A8_UINT);
return PIPE_FORMAT_NONE;
}
#define RETURN_FOR_SWIZZLE1(x, format) \
if (desc->swizzle[0] == PIPE_SWIZZLE_##x) \
- return format
+ return (pipe->get_canonical_format ? \
+ pipe->get_canonical_format(pipe, format) : \
+ format)
#define RETURN_FOR_SWIZZLE2(x, y, format) \
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
desc->swizzle[1] == PIPE_SWIZZLE_##y) \
- return format
+ return (pipe->get_canonical_format ? \
+ pipe->get_canonical_format(pipe, format) : \
+ format)
#define RETURN_FOR_SWIZZLE3(x, y, z, format) \
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
desc->swizzle[1] == PIPE_SWIZZLE_##y && \
desc->swizzle[2] == PIPE_SWIZZLE_##z) \
- return format
+ return (pipe->get_canonical_format ? \
+ pipe->get_canonical_format(pipe, format) : \
+ format)
#define RETURN_FOR_SWIZZLE4(x, y, z, w, format) \
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
desc->swizzle[1] == PIPE_SWIZZLE_##y && \
desc->swizzle[2] == PIPE_SWIZZLE_##z && \
desc->swizzle[3] == PIPE_SWIZZLE_##w) \
- return format
+ return (pipe->get_canonical_format ? \
+ pipe->get_canonical_format(pipe, format) : \
+ format)
/* Array formats. */
if (desc->is_array) {
@@ -208,40 +217,42 @@ has_identity_swizzle(const struct util_format_description *desc)
* Return a canonical format for the given bits and channel size.
*/
static enum pipe_format
-canonical_format_from_bits(unsigned bits, unsigned channel_size)
+canonical_format_from_bits(struct pipe_context *pipe,
+ unsigned bits,
+ unsigned channel_size)
{
switch (bits) {
case 8:
if (channel_size == 8)
- return get_canonical_format(PIPE_FORMAT_R8_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R8_UINT);
break;
case 16:
if (channel_size == 8)
- return get_canonical_format(PIPE_FORMAT_R8G8_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R8G8_UINT);
if (channel_size == 16)
- return get_canonical_format(PIPE_FORMAT_R16_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R16_UINT);
break;
case 32:
if (channel_size == 8)
- return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R8G8B8A8_UINT);
if (channel_size == 16)
- return get_canonical_format(PIPE_FORMAT_R16G16_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R16G16_UINT);
if (channel_size == 32)
- return get_canonical_format(PIPE_FORMAT_R32_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R32_UINT);
break;
case 64:
if (channel_size == 16)
- return get_canonical_format(PIPE_FORMAT_R16G16B16A16_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R16G16B16A16_UINT);
if (channel_size == 32)
- return get_canonical_format(PIPE_FORMAT_R32G32_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R32G32_UINT);
break;
case 128:
if (channel_size == 32)
- return get_canonical_format(PIPE_FORMAT_R32G32B32A32_UINT);
+ return get_canonical_format(pipe, PIPE_FORMAT_R32G32B32A32_UINT);
break;
}
@@ -296,8 +307,8 @@ swizzled_copy(struct pipe_context *pipe,
* about the channel type from this point on.
* Only the swizzle and channel size.
*/
- blit_src_format = get_canonical_format(src->format);
- blit_dst_format = get_canonical_format(dst->format);
+ blit_src_format = get_canonical_format(pipe, src->format);
+ blit_dst_format = get_canonical_format(pipe, dst->format);
assert(blit_src_format != PIPE_FORMAT_NONE);
assert(blit_dst_format != PIPE_FORMAT_NONE);
@@ -318,14 +329,14 @@ swizzled_copy(struct pipe_context *pipe,
* e.g. R32 -> BGRA8 is realized as RGBA8 -> BGRA8
*/
blit_src_format =
- canonical_format_from_bits(bits, dst_desc->channel[0].size);
+ canonical_format_from_bits(pipe, bits, dst_desc->channel[0].size);
} else if (has_identity_swizzle(dst_desc)) {
/* Dst is unswizzled and src can be swizzled, so dst is typecast
* to an equivalent src-compatible format.
* e.g. BGRA8 -> R32 is realized as BGRA8 -> RGBA8
*/
blit_dst_format =
- canonical_format_from_bits(bits, src_desc->channel[0].size);
+ canonical_format_from_bits(pipe, bits, src_desc->channel[0].size);
} else {
assert(!"This should have been handled by handle_complex_copy.");
return;
More information about the mesa-commit
mailing list