summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util/u_format.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-09-04 11:53:28 +0100
committerJosé Fonseca <jfonseca@vmware.com>2010-09-05 10:17:51 +0100
commitb8684b2458bc9bdcfd6b43dc7c2b8c2d485105fd (patch)
treee1ce0bd91ab5ec2ba11e1ce1d3deeacf6d679d6f /src/gallium/auxiliary/util/u_format.c
parent00989d5bfc29f632886066d048a366ff4d2d03bc (diff)
util: Helper function to determined whether two formats can be memcpy'ed.
These are the non-trivial conversions that this function recognizes, which was produced by u_format_compatible_test.c: b8g8r8a8_unorm -> b8g8r8x8_unorm a8r8g8b8_unorm -> x8r8g8b8_unorm b5g5r5a1_unorm -> b5g5r5x1_unorm b4g4r4a4_unorm -> b4g4r4x4_unorm l8_unorm -> r8_unorm i8_unorm -> l8_unorm i8_unorm -> a8_unorm i8_unorm -> r8_unorm l16_unorm -> r16_unorm z24_unorm_s8_uscaled -> z24x8_unorm s8_uscaled_z24_unorm -> x8z24_unorm r8g8b8a8_unorm -> r8g8b8x8_unorm a8b8g8r8_srgb -> x8b8g8r8_srgb b8g8r8a8_srgb -> b8g8r8x8_srgb a8r8g8b8_srgb -> x8r8g8b8_srgb a8b8g8r8_unorm -> x8b8g8r8_unorm r10g10b10a2_uscaled -> r10g10b10x2_uscaled r10sg10sb10sa2u_norm -> r10g10b10x2_snorm State trackers and pipe drivers should be updated to take advantage of this knowledge, e.g., in surface_copy.
Diffstat (limited to 'src/gallium/auxiliary/util/u_format.c')
-rw-r--r--src/gallium/auxiliary/util/u_format.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index 43d09f19607..a4ee91b0cf9 100644
--- a/src/gallium/auxiliary/util/u_format.c
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -121,6 +121,54 @@ util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_
boolean
+util_is_format_compatible(const struct util_format_description *src_desc,
+ const struct util_format_description *dst_desc)
+{
+ unsigned chan;
+
+ if (src_desc->format == dst_desc->format) {
+ return TRUE;
+ }
+
+ if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
+ dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
+ return FALSE;
+ }
+
+ if (src_desc->block.bits != dst_desc->block.bits ||
+ src_desc->nr_channels != dst_desc->nr_channels ||
+ src_desc->colorspace != dst_desc->colorspace) {
+ return FALSE;
+ }
+
+ for (chan = 0; chan < 4; ++chan) {
+ if (src_desc->channel[chan].size !=
+ dst_desc->channel[chan].size) {
+ return FALSE;
+ }
+ }
+
+ for (chan = 0; chan < 4; ++chan) {
+ enum util_format_swizzle swizzle = dst_desc->swizzle[chan];
+
+ if (swizzle < 4) {
+ if (src_desc->swizzle[chan] != swizzle) {
+ return FALSE;
+ }
+ if ((src_desc->channel[swizzle].type !=
+ dst_desc->channel[swizzle].type) ||
+ (src_desc->channel[swizzle].normalized !=
+ dst_desc->channel[swizzle].normalized)) {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+boolean
util_format_fits_8unorm(const struct util_format_description *format_desc)
{
unsigned chan;
@@ -193,7 +241,10 @@ util_format_translate(enum pipe_format dst_format,
unsigned dst_step;
unsigned src_step;
- if (dst_format == src_format) {
+ dst_format_desc = util_format_description(dst_format);
+ src_format_desc = util_format_description(src_format);
+
+ if (util_is_format_compatible(src_format_desc, dst_format_desc)) {
/*
* Trivial case.
*/
@@ -204,9 +255,6 @@ util_format_translate(enum pipe_format dst_format,
return;
}
- dst_format_desc = util_format_description(dst_format);
- src_format_desc = util_format_description(src_format);
-
assert(dst_x % dst_format_desc->block.width == 0);
assert(dst_y % dst_format_desc->block.height == 0);
assert(src_x % src_format_desc->block.width == 0);