r300g: add support for PIPE_FORMAT_x8R8G8B8_*
authorMarek Olšák <marek.olsak@amd.com>
Sun, 24 Apr 2016 11:23:52 +0000 (13:23 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 9 May 2016 11:11:40 +0000 (13:11 +0200)
And set endian swap for packed formats the way it should be done
in theory.

This allows big endian to work again, but it can still be buggy.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71789

Cc: 11.1 11.2 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/r300/r300_reg.h
src/gallium/drivers/r300/r300_texture.c

index 9c373c5d1115e5bcde3115cadf825ee3cfc0e0a2..9c93b84ee5f4c0c068e473d402c9757864665a3c 100644 (file)
@@ -1700,10 +1700,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define R300_TX_OFFSET_6                    0x4558
 #define R300_TX_OFFSET_7                    0x455C
 
-#       define R300_TXO_ENDIAN_NO_SWAP           (0 << 0)
-#       define R300_TXO_ENDIAN_BYTE_SWAP         (1 << 0)
-#       define R300_TXO_ENDIAN_WORD_SWAP         (2 << 0)
-#       define R300_TXO_ENDIAN_HALFDW_SWAP       (3 << 0)
+#       define R300_TXO_ENDIAN(x)                ((x) << 0)
 #       define R300_TXO_MACRO_TILE_LINEAR        (0 << 2)
 #       define R300_TXO_MACRO_TILE_TILED         (1 << 2)
 #       define R300_TXO_MACRO_TILE(x)            ((x) << 2)
@@ -2418,10 +2415,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #       define R300_COLOR_MICROTILE_ENABLE        (1 << 17)
 #       define R300_COLOR_MICROTILE_ENABLE_SQUARE (2 << 17) /* Only available in 16-bit */
 #       define R300_COLOR_MICROTILE(x)            ((x) << 17)
-#       define R300_COLOR_ENDIAN_NO_SWAP          (0 << 19)
-#       define R300_COLOR_ENDIAN_WORD_SWAP        (1 << 19)
-#       define R300_COLOR_ENDIAN_DWORD_SWAP       (2 << 19)
-#       define R300_COLOR_ENDIAN_HALF_DWORD_SWAP  (3 << 19)
+#       define R300_COLOR_ENDIAN(x)               ((x) << 19)
 #      define R500_COLOR_FORMAT_ARGB10101010     (0 << 21)
 #      define R500_COLOR_FORMAT_UV1010           (1 << 21)
 #      define R500_COLOR_FORMAT_CI8              (2 << 21) /* 2D only */
@@ -2693,10 +2687,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #       define R300_DEPTHMICROTILE_TILED        (1 << 17)
 #       define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17)
 #       define R300_DEPTHMICROTILE(x)           ((x) << 17)
-#       define R300_DEPTHENDIAN_NO_SWAP         (0 << 18)
-#       define R300_DEPTHENDIAN_WORD_SWAP       (1 << 18)
-#       define R300_DEPTHENDIAN_DWORD_SWAP      (2 << 18)
-#       define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18)
+#       define R300_DEPTHENDIAN(x)              ((x) << 19)
+
+#define R300_SURF_NO_SWAP         0
+#define R300_SURF_WORD_SWAP       1
+#define R300_SURF_DWORD_SWAP      2
+#define R300_SURF_HALF_DWORD_SWAP 3
 
 /* Z Buffer Clear Value */
 #define R300_ZB_DEPTHCLEARVALUE                  0x4f28
index df016734d35323777c60cedea77595295c02ac97..14372da62e422218aed875eda236f88222f23714 100644 (file)
 
 #include "pipe/p_screen.h"
 
+/* These formats are supported by swapping their bytes.
+ * The swizzles must be set exactly like their non-swapped counterparts,
+ * because byte-swapping is what reverses the component order, not swizzling.
+ *
+ * This function returns the format that must be used to program CB and TX
+ * swizzles.
+ */
+static enum pipe_format r300_unbyteswap_array_format(enum pipe_format format)
+{
+    /* Only BGRA 8888 array formats are supported for simplicity of
+     * the implementation. */
+    switch (format) {
+    case PIPE_FORMAT_A8R8G8B8_UNORM:
+        return PIPE_FORMAT_B8G8R8A8_UNORM;
+    case PIPE_FORMAT_A8R8G8B8_SRGB:
+        return PIPE_FORMAT_B8G8R8A8_SRGB;
+    case PIPE_FORMAT_X8R8G8B8_UNORM:
+        return PIPE_FORMAT_B8G8R8X8_UNORM;
+    case PIPE_FORMAT_X8R8G8B8_SRGB:
+        return PIPE_FORMAT_B8G8R8X8_SRGB;
+    default:
+        return format;
+    }
+}
+
+static unsigned r300_get_endian_swap(enum pipe_format format)
+{
+    const struct util_format_description *desc;
+    unsigned swap_size;
+
+    if (r300_unbyteswap_array_format(format) != format)
+        return R300_SURF_DWORD_SWAP;
+
+    if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG)
+        return R300_SURF_NO_SWAP;
+
+    desc = util_format_description(format);
+    if (!desc)
+        return R300_SURF_NO_SWAP;
+
+    /* Compressed formats should be in the little endian format. */
+    if (desc->block.width != 1 || desc->block.height != 1)
+        return R300_SURF_NO_SWAP;
+
+    swap_size = desc->is_array ? desc->channel[0].size : desc->block.bits;
+
+    switch (swap_size) {
+    default: /* shouldn't happen? */
+    case 8:
+        return R300_SURF_NO_SWAP;
+    case 16:
+        return R300_SURF_WORD_SWAP;
+    case 32:
+        return R300_SURF_DWORD_SWAP;
+    }
+}
+
 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
                                    const unsigned char *swizzle_view,
                                    boolean dxtc_swizzle)
@@ -118,6 +175,7 @@ uint32_t r300_translate_texformat(enum pipe_format format,
         R300_TX_FORMAT_SIGNED_X,
     };
 
+    format = r300_unbyteswap_array_format(format);
     desc = util_format_description(format);
 
     /* Colorspace (return non-RGB formats directly). */
@@ -400,6 +458,8 @@ uint32_t r500_tx_format_msb_bit(enum pipe_format format)
  * output. For the swizzling of the targets, check the shader's format. */
 static uint32_t r300_translate_colorformat(enum pipe_format format)
 {
+    format = r300_unbyteswap_array_format(format);
+
     switch (format) {
         /* 8-bit buffers. */
         case PIPE_FORMAT_A8_UNORM:
@@ -534,6 +594,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
     const struct util_format_description *desc;
     boolean uniform_sign;
 
+    format = r300_unbyteswap_array_format(format);
     desc = util_format_description(format);
 
     /* Find the first non-VOID channel. */
@@ -730,6 +791,8 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
 
 static uint32_t r300_translate_colormask_swizzle(enum pipe_format format)
 {
+    format = r300_unbyteswap_array_format(format);
+
     switch (format) {
     case PIPE_FORMAT_A8_UNORM:
     case PIPE_FORMAT_A8_SNORM:
@@ -918,7 +981,8 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
     }
 
     out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
-                       R300_TXO_MICRO_TILE(desc->microtile);
+                       R300_TXO_MICRO_TILE(desc->microtile) |
+                       R300_TXO_ENDIAN(r300_get_endian_swap(format));
 }
 
 static void r300_texture_setup_fb_state(struct r300_surface *surf)
@@ -933,7 +997,8 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
         surf->pitch =
                 stride |
                 R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
-                R300_DEPTHMICROTILE(tex->tex.microtile);
+                R300_DEPTHMICROTILE(tex->tex.microtile) |
+                R300_DEPTHENDIAN(r300_get_endian_swap(surf->base.format));
         surf->format = r300_translate_zsformat(surf->base.format);
         surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level];
         surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
@@ -944,7 +1009,8 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
                 stride |
                 r300_translate_colorformat(format) |
                 R300_COLOR_TILE(tex->tex.macrotile[level]) |
-                R300_COLOR_MICROTILE(tex->tex.microtile);
+                R300_COLOR_MICROTILE(tex->tex.microtile) |
+                R300_COLOR_ENDIAN(r300_get_endian_swap(format));
         surf->format = r300_translate_out_fmt(format);
         surf->colormask_swizzle =
             r300_translate_colormask_swizzle(format);