For some texture formats we need to take endian_format into account when
configuring their swizzling. We also need to take into account those
formats when we use staging textures.

Signed-off-by: Oded Gabbay <oded.gab...@gmail.com>
---
 src/gallium/drivers/r600/r600_state_common.c | 35 +++++++++++++++++++++++++++-
 src/gallium/drivers/radeon/r600_texture.c    |  6 +++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index 2e2f67e..c1e9598 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -2227,6 +2227,9 @@ uint32_t r600_translate_texformat(struct pipe_screen 
*screen,
        bool is_srgb_valid = FALSE;
        const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
        const unsigned char swizzle_yyyy[4] = {1, 1, 1, 1};
+       const unsigned char swizzle_xxxy[4] = {0, 0, 0, 1};
+       const unsigned char swizzle_zyx1[4] = {2, 1, 0, 5};
+       const unsigned char swizzle_zyxw[4] = {2, 1, 0, 3};
 
        int i;
        const uint32_t sign_bit[4] = {
@@ -2235,11 +2238,41 @@ uint32_t r600_translate_texformat(struct pipe_screen 
*screen,
                S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
                S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
        };
+
+       /* Need to replace the specified texture formats in case of big-endian.
+        * These formats are formats that have channels with number of bits
+        * not divisible by 8.
+        * Mesa conversion functions don't swap bits for those formats, and 
because
+        * we transmit this over a serial bus to the GPU (PCIe), the
+        * bit-endianess is important!!!
+        * In case we have an "opposite" format, just use that for the swizzling
+        * information. If we don't have such an "opposite" format, we need
+        * to use a fixed swizzle info instead (see below)
+        */
+       if (format == PIPE_FORMAT_R4A4_UNORM && endianformat == PIPE_ENDIAN_BIG)
+               format = PIPE_FORMAT_A4R4_UNORM;
+
        desc = util_format_description(format);
 
        /* Depth and stencil swizzling is handled separately. */
        if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) {
-               word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, 
FALSE);
+               /* Need to check for specific texture formats that don't have
+                * an "opposite" format we can use. For those formats, we 
directly
+                * specify the swizzling, which is the LE swizzling as defined 
in
+                * u_format.csv
+                */
+               if (endianformat == PIPE_ENDIAN_BIG) {
+                       if (format == PIPE_FORMAT_L4A4_UNORM)
+                               word4 |= 
r600_get_swizzle_combined(swizzle_xxxy, swizzle_view, FALSE);
+                       else if (format == PIPE_FORMAT_B4G4R4A4_UNORM)
+                               word4 |= 
r600_get_swizzle_combined(swizzle_zyxw, swizzle_view, FALSE);
+                       else if (format == PIPE_FORMAT_B4G4R4X4_UNORM || format 
== PIPE_FORMAT_B5G6R5_UNORM)
+                               word4 |= 
r600_get_swizzle_combined(swizzle_zyx1, swizzle_view, FALSE);
+                       else
+                               word4 |= 
r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE);
+               } else {
+                       word4 |= r600_get_swizzle_combined(desc->swizzle, 
swizzle_view, FALSE);
+               }
        }
 
        /* Colorspace (return non-RGB formats directly). */
diff --git a/src/gallium/drivers/radeon/r600_texture.c 
b/src/gallium/drivers/radeon/r600_texture.c
index cd2f775..de02da1 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1294,6 +1294,12 @@ static void *r600_texture_transfer_map(struct 
pipe_context *ctx,
                 * be set to native endianess */
                switch (trans->staging->b.b.format)
                {
+               case PIPE_FORMAT_B5G6R5_UNORM:
+               case PIPE_FORMAT_B4G4R4A4_UNORM:
+               case PIPE_FORMAT_B4G4R4X4_UNORM:
+                       trans->staging->b.b.endian_format = PIPE_ENDIAN_NATIVE;
+                       break;
+
                default:
                        trans->staging->b.b.endian_format = 
texture->endian_format;
                        break;
-- 
2.5.5

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to