+/* 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)
+{
+ /* FIXME: Disabled on little endian because of a reported regression:
+ * https://bugs.freedesktop.org/show_bug.cgi?id=98869 */
+ if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG)
+ return 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;
+ }
+}
+