summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r--src/gallium/drivers/r300/r300_texture.c64
1 files changed, 47 insertions, 17 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 34105aa4bc..cee56bccdc 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -260,16 +260,26 @@ uint32_t r300_translate_texformat(enum pipe_format format,
return ~0; /* Unsupported/unknown. */
}
+ /* Find the first non-VOID channel. */
+ for (i = 0; i < 4; i++) {
+ if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+ break;
+ }
+ }
+
+ if (i == 4)
+ return ~0; /* Unsupported/unknown. */
+
/* And finally, uniform formats. */
- switch (desc->channel[0].type) {
+ switch (desc->channel[i].type) {
case UTIL_FORMAT_TYPE_UNSIGNED:
case UTIL_FORMAT_TYPE_SIGNED:
- if (!desc->channel[0].normalized &&
+ if (!desc->channel[i].normalized &&
desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
return ~0;
}
- switch (desc->channel[0].size) {
+ switch (desc->channel[i].size) {
case 4:
switch (desc->nr_channels) {
case 2:
@@ -303,7 +313,7 @@ uint32_t r300_translate_texformat(enum pipe_format format,
return ~0;
case UTIL_FORMAT_TYPE_FLOAT:
- switch (desc->channel[0].size) {
+ switch (desc->channel[i].size) {
case 16:
switch (desc->nr_channels) {
case 1:
@@ -359,6 +369,11 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
return R300_COLOR_FORMAT_I8;
/* 16-bit buffers. */
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ return R300_COLOR_FORMAT_UV88;
+
case PIPE_FORMAT_B5G6R5_UNORM:
return R300_COLOR_FORMAT_RGB565;
@@ -443,15 +458,25 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
desc = util_format_description(format);
+ /* Find the first non-VOID channel. */
+ for (i = 0; i < 4; i++) {
+ if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
+ break;
+ }
+ }
+
+ if (i == 4)
+ return ~0; /* Unsupported/unknown. */
+
/* Specifies how the shader output is written to the fog unit. */
- if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
- if (desc->channel[0].size == 32) {
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
+ if (desc->channel[i].size == 32) {
modifier |= R300_US_OUT_FMT_C4_32_FP;
} else {
modifier |= R300_US_OUT_FMT_C4_16_FP;
}
} else {
- if (desc->channel[0].size == 16) {
+ if (desc->channel[i].size == 16) {
modifier |= R300_US_OUT_FMT_C4_16;
} else {
/* C4_8 seems to be used for the formats whose pixel size
@@ -468,7 +493,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
/* Add swizzles and return. */
switch (format) {
- /* 8-bit outputs.
+ /* 8-bit outputs, one channel.
* COLORFORMAT_I8 stores the C2 component. */
case PIPE_FORMAT_A8_UNORM:
return modifier | R300_C2_SEL_A;
@@ -478,6 +503,14 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
case PIPE_FORMAT_R8_SNORM:
return modifier | R300_C2_SEL_R;
+ /* 16-bit outputs, two channels.
+ * COLORFORMAT_UV88 stores C2 and C0. */
+ case PIPE_FORMAT_L8A8_UNORM:
+ return modifier | R300_C0_SEL_A | R300_C2_SEL_R;
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ return modifier | R300_C0_SEL_G | R300_C2_SEL_R;
+
/* BGRA outputs. */
case PIPE_FORMAT_B5G6R5_UNORM:
case PIPE_FORMAT_B5G5R5A1_UNORM:
@@ -556,18 +589,15 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
out->tile_config = 0;
/* Set sampler state. */
- out->format0 = R300_TX_WIDTH((u_minify(pt->width0, level) - 1) & 0x7ff) |
- R300_TX_HEIGHT((u_minify(pt->height0, level) - 1) & 0x7ff);
+ out->format0 =
+ R300_TX_WIDTH((u_minify(desc->width0, level) - 1) & 0x7ff) |
+ R300_TX_HEIGHT((u_minify(desc->height0, level) - 1) & 0x7ff) |
+ R300_TX_DEPTH(util_logbase2(u_minify(desc->depth0, level)) & 0xf);
if (desc->uses_stride_addressing) {
/* rectangles love this */
out->format0 |= R300_TX_PITCH_EN;
out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff;
- } else {
- /* Power of two textures (3D, mipmaps, and no pitch),
- * also NPOT textures with a width being POT. */
- out->format0 |=
- R300_TX_DEPTH(util_logbase2(u_minify(pt->depth0, level)) & 0xf);
}
if (pt->target == PIPE_TEXTURE_CUBE) {
@@ -580,10 +610,10 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
/* large textures on r500 */
if (is_r500)
{
- if (pt->width0 > 2048) {
+ if (desc->width0 > 2048) {
out->format2 |= R500_TXWIDTH_BIT11;
}
- if (pt->height0 > 2048) {
+ if (desc->height0 > 2048) {
out->format2 |= R500_TXHEIGHT_BIT11;
}
}