+ uint32_t result = 0;
+ const struct util_format_description *desc;
+ unsigned i;
+ boolean uniform = TRUE;
+ const uint32_t sign_bit[4] = {
+ R300_TX_FORMAT_SIGNED_X,
+ R300_TX_FORMAT_SIGNED_Y,
+ R300_TX_FORMAT_SIGNED_Z,
+ R300_TX_FORMAT_SIGNED_W,
+ };
+
+ desc = util_format_description(format);
+
+ /* Colorspace (return non-RGB formats directly). */
+ switch (desc->colorspace) {
+ /* Depth stencil formats.
+ * Swizzles are added in r300_merge_textures_and_samplers. */
+ case UTIL_FORMAT_COLORSPACE_ZS:
+ switch (format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ return R300_TX_FORMAT_X16;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ return R300_TX_FORMAT_W24_FP;
+ default:
+ return ~0; /* Unsupported. */
+ }
+
+ /* YUV formats. */
+ case UTIL_FORMAT_COLORSPACE_YUV:
+ result |= R300_TX_FORMAT_YUV_TO_RGB;
+
+ switch (format) {
+ case PIPE_FORMAT_UYVY:
+ return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
+ case PIPE_FORMAT_YUYV:
+ return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
+ default:
+ return ~0; /* Unsupported/unknown. */
+ }
+
+ /* Add gamma correction. */
+ case UTIL_FORMAT_COLORSPACE_SRGB:
+ result |= R300_TX_FORMAT_GAMMA;
+ break;
+
+ default:
+ switch (format) {
+ /* Same as YUV but without the YUR->RGB conversion. */
+ case PIPE_FORMAT_R8G8_B8G8_UNORM:
+ return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
+ case PIPE_FORMAT_G8R8_G8B8_UNORM:
+ return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
+ default:;
+ }
+ }
+
+ result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view);
+
+ /* S3TC formats. */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+ if (!util_format_s3tc_enabled) {
+ return ~0; /* Unsupported. */
+ }
+
+ switch (format) {
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT1_SRGB:
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return R300_TX_FORMAT_DXT1 | result;
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return R300_TX_FORMAT_DXT3 | result;
+ case PIPE_FORMAT_DXT5_RGBA:
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return R300_TX_FORMAT_DXT5 | result;
+ default:
+ return ~0; /* Unsupported/unknown. */
+ }
+ }
+
+ /* Add sign. */
+ for (i = 0; i < desc->nr_channels; i++) {
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
+ result |= sign_bit[i];
+ }
+ }
+
+ /* This is truly a special format.
+ * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2)
+ * in the sampler unit. Also known as D3DFMT_CxV8U8. */
+ if (format == PIPE_FORMAT_R8G8Bx_SNORM) {
+ return R300_TX_FORMAT_CxV8U8 | result;
+ }
+
+ /* RGTC formats. */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
+ switch (format) {
+ case PIPE_FORMAT_RGTC1_UNORM:
+ case PIPE_FORMAT_RGTC1_SNORM:
+ return R500_TX_FORMAT_ATI1N | result;
+ case PIPE_FORMAT_RGTC2_UNORM:
+ case PIPE_FORMAT_RGTC2_SNORM:
+ return R400_TX_FORMAT_ATI2N | result;
+ default:
+ return ~0; /* Unsupported/unknown. */
+ }
+ }
+
+ /* See whether the components are of the same size. */
+ for (i = 1; i < desc->nr_channels; i++) {
+ uniform = uniform && desc->channel[0].size == desc->channel[i].size;
+ }
+
+ /* Non-uniform formats. */
+ if (!uniform) {
+ switch (desc->nr_channels) {
+ case 3:
+ if (desc->channel[0].size == 5 &&
+ desc->channel[1].size == 6 &&
+ desc->channel[2].size == 5) {
+ return R300_TX_FORMAT_Z5Y6X5 | result;
+ }
+ if (desc->channel[0].size == 5 &&
+ desc->channel[1].size == 5 &&
+ desc->channel[2].size == 6) {
+ return R300_TX_FORMAT_Z6Y5X5 | result;
+ }
+ return ~0; /* Unsupported/unknown. */
+
+ case 4:
+ if (desc->channel[0].size == 5 &&
+ desc->channel[1].size == 5 &&
+ desc->channel[2].size == 5 &&
+ desc->channel[3].size == 1) {
+ return R300_TX_FORMAT_W1Z5Y5X5 | result;
+ }
+ if (desc->channel[0].size == 10 &&
+ desc->channel[1].size == 10 &&
+ desc->channel[2].size == 10 &&
+ desc->channel[3].size == 2) {
+ return R300_TX_FORMAT_W2Z10Y10X10 | result;
+ }
+ }
+ return ~0; /* Unsupported/unknown. */
+ }
+
+ /* And finally, uniform formats. */
+ switch (desc->channel[0].type) {
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ case UTIL_FORMAT_TYPE_SIGNED:
+ if (!desc->channel[0].normalized &&
+ desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
+ return ~0;
+ }
+
+ switch (desc->channel[0].size) {
+ case 4:
+ switch (desc->nr_channels) {
+ case 2:
+ return R300_TX_FORMAT_Y4X4 | result;
+ case 4:
+ return R300_TX_FORMAT_W4Z4Y4X4 | result;
+ }
+ return ~0;
+
+ case 8:
+ switch (desc->nr_channels) {
+ case 1:
+ return R300_TX_FORMAT_X8 | result;
+ case 2:
+ return R300_TX_FORMAT_Y8X8 | result;
+ case 4:
+ return R300_TX_FORMAT_W8Z8Y8X8 | result;
+ }
+ return ~0;
+
+ case 16:
+ switch (desc->nr_channels) {
+ case 1:
+ return R300_TX_FORMAT_X16 | result;
+ case 2:
+ return R300_TX_FORMAT_Y16X16 | result;
+ case 4:
+ return R300_TX_FORMAT_W16Z16Y16X16 | result;
+ }
+ }
+ return ~0;
+
+ case UTIL_FORMAT_TYPE_FLOAT:
+ switch (desc->channel[0].size) {
+ case 16:
+ switch (desc->nr_channels) {
+ case 1:
+ return R300_TX_FORMAT_16F | result;
+ case 2:
+ return R300_TX_FORMAT_16F_16F | result;
+ case 4:
+ return R300_TX_FORMAT_16F_16F_16F_16F | result;
+ }
+ return ~0;
+
+ case 32:
+ switch (desc->nr_channels) {
+ case 1:
+ return R300_TX_FORMAT_32F | result;
+ case 2:
+ return R300_TX_FORMAT_32F_32F | result;
+ case 4:
+ return R300_TX_FORMAT_32F_32F_32F_32F | result;
+ }
+ }
+ }
+
+ return ~0; /* Unsupported/unknown. */
+}
+
+uint32_t r500_tx_format_msb_bit(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_RGTC1_UNORM:
+ case PIPE_FORMAT_RGTC1_SNORM:
+ return R500_TXFORMAT_MSB;
+ default:
+ return 0;
+ }
+}
+
+/* Buffer formats. */
+
+/* Colorbuffer formats. This is the unswizzled format of the RB3D block's
+ * output. For the swizzling of the targets, check the shader's format. */
+static uint32_t r300_translate_colorformat(enum pipe_format format)
+{
+ switch (format) {
+ /* 8-bit buffers. */
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8_SNORM:
+ return R300_COLOR_FORMAT_I8;
+
+ /* 16-bit buffers. */
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return R300_COLOR_FORMAT_RGB565;