From 172bfdaa9e80342ade3f023f72d455d76713b866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 24 Apr 2016 13:23:52 +0200 Subject: [PATCH] r300g: add support for PIPE_FORMAT_x8R8G8B8_* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Michel Dänzer --- src/gallium/drivers/r300/r300_reg.h | 20 +++---- src/gallium/drivers/r300/r300_texture.c | 72 +++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 9c373c5d111..9c93b84ee5f 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -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 diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index df016734d35..14372da62e4 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -38,6 +38,63 @@ #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);