mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
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@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15693>
This commit is contained in:
parent
21bfbc74ee
commit
606e42027e
2 changed files with 42 additions and 21 deletions
|
|
@ -999,6 +999,16 @@ struct pipe_context {
|
||||||
bool to_device, bool migrate_content);
|
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.
|
* Get the default sample position for an individual sample point.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@
|
||||||
* formats are not supported. (same as ARB_copy_image)
|
* formats are not supported. (same as ARB_copy_image)
|
||||||
*/
|
*/
|
||||||
static enum pipe_format
|
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 =
|
const struct util_format_description *desc =
|
||||||
util_format_description(format);
|
util_format_description(format);
|
||||||
|
|
@ -62,7 +63,7 @@ get_canonical_format(enum pipe_format format)
|
||||||
/* Packed formats. Return the equivalent array format. */
|
/* Packed formats. Return the equivalent array format. */
|
||||||
if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
|
if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
|
||||||
format == PIPE_FORMAT_R9G9B9E5_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 &&
|
if (desc->nr_channels == 4 &&
|
||||||
desc->channel[0].size == 10 &&
|
desc->channel[0].size == 10 &&
|
||||||
|
|
@ -72,32 +73,40 @@ get_canonical_format(enum pipe_format format)
|
||||||
if (desc->swizzle[0] == PIPE_SWIZZLE_X &&
|
if (desc->swizzle[0] == PIPE_SWIZZLE_X &&
|
||||||
desc->swizzle[1] == PIPE_SWIZZLE_Y &&
|
desc->swizzle[1] == PIPE_SWIZZLE_Y &&
|
||||||
desc->swizzle[2] == PIPE_SWIZZLE_Z)
|
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;
|
return PIPE_FORMAT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RETURN_FOR_SWIZZLE1(x, format) \
|
#define RETURN_FOR_SWIZZLE1(x, format) \
|
||||||
if (desc->swizzle[0] == PIPE_SWIZZLE_##x) \
|
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) \
|
#define RETURN_FOR_SWIZZLE2(x, y, format) \
|
||||||
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
|
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
|
||||||
desc->swizzle[1] == PIPE_SWIZZLE_##y) \
|
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) \
|
#define RETURN_FOR_SWIZZLE3(x, y, z, format) \
|
||||||
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
|
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
|
||||||
desc->swizzle[1] == PIPE_SWIZZLE_##y && \
|
desc->swizzle[1] == PIPE_SWIZZLE_##y && \
|
||||||
desc->swizzle[2] == PIPE_SWIZZLE_##z) \
|
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) \
|
#define RETURN_FOR_SWIZZLE4(x, y, z, w, format) \
|
||||||
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
|
if (desc->swizzle[0] == PIPE_SWIZZLE_##x && \
|
||||||
desc->swizzle[1] == PIPE_SWIZZLE_##y && \
|
desc->swizzle[1] == PIPE_SWIZZLE_##y && \
|
||||||
desc->swizzle[2] == PIPE_SWIZZLE_##z && \
|
desc->swizzle[2] == PIPE_SWIZZLE_##z && \
|
||||||
desc->swizzle[3] == PIPE_SWIZZLE_##w) \
|
desc->swizzle[3] == PIPE_SWIZZLE_##w) \
|
||||||
return format
|
return (pipe->get_canonical_format ? \
|
||||||
|
pipe->get_canonical_format(pipe, format) : \
|
||||||
|
format)
|
||||||
|
|
||||||
/* Array formats. */
|
/* Array formats. */
|
||||||
if (desc->is_array) {
|
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.
|
* Return a canonical format for the given bits and channel size.
|
||||||
*/
|
*/
|
||||||
static enum pipe_format
|
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) {
|
switch (bits) {
|
||||||
case 8:
|
case 8:
|
||||||
if (channel_size == 8)
|
if (channel_size == 8)
|
||||||
return get_canonical_format(PIPE_FORMAT_R8_UINT);
|
return get_canonical_format(pipe, PIPE_FORMAT_R8_UINT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
if (channel_size == 8)
|
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)
|
if (channel_size == 16)
|
||||||
return get_canonical_format(PIPE_FORMAT_R16_UINT);
|
return get_canonical_format(pipe, PIPE_FORMAT_R16_UINT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
if (channel_size == 8)
|
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)
|
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)
|
if (channel_size == 32)
|
||||||
return get_canonical_format(PIPE_FORMAT_R32_UINT);
|
return get_canonical_format(pipe, PIPE_FORMAT_R32_UINT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 64:
|
case 64:
|
||||||
if (channel_size == 16)
|
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)
|
if (channel_size == 32)
|
||||||
return get_canonical_format(PIPE_FORMAT_R32G32_UINT);
|
return get_canonical_format(pipe, PIPE_FORMAT_R32G32_UINT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 128:
|
case 128:
|
||||||
if (channel_size == 32)
|
if (channel_size == 32)
|
||||||
return get_canonical_format(PIPE_FORMAT_R32G32B32A32_UINT);
|
return get_canonical_format(pipe, PIPE_FORMAT_R32G32B32A32_UINT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,8 +307,8 @@ swizzled_copy(struct pipe_context *pipe,
|
||||||
* about the channel type from this point on.
|
* about the channel type from this point on.
|
||||||
* Only the swizzle and channel size.
|
* Only the swizzle and channel size.
|
||||||
*/
|
*/
|
||||||
blit_src_format = get_canonical_format(src->format);
|
blit_src_format = get_canonical_format(pipe, src->format);
|
||||||
blit_dst_format = get_canonical_format(dst->format);
|
blit_dst_format = get_canonical_format(pipe, dst->format);
|
||||||
|
|
||||||
assert(blit_src_format != PIPE_FORMAT_NONE);
|
assert(blit_src_format != PIPE_FORMAT_NONE);
|
||||||
assert(blit_dst_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
|
* e.g. R32 -> BGRA8 is realized as RGBA8 -> BGRA8
|
||||||
*/
|
*/
|
||||||
blit_src_format =
|
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)) {
|
} else if (has_identity_swizzle(dst_desc)) {
|
||||||
/* Dst is unswizzled and src can be swizzled, so dst is typecast
|
/* Dst is unswizzled and src can be swizzled, so dst is typecast
|
||||||
* to an equivalent src-compatible format.
|
* to an equivalent src-compatible format.
|
||||||
* e.g. BGRA8 -> R32 is realized as BGRA8 -> RGBA8
|
* e.g. BGRA8 -> R32 is realized as BGRA8 -> RGBA8
|
||||||
*/
|
*/
|
||||||
blit_dst_format =
|
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 {
|
} else {
|
||||||
assert(!"This should have been handled by handle_complex_copy.");
|
assert(!"This should have been handled by handle_complex_copy.");
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue