Browse Source

r300g: add support for all missing non-FP sampler formats

The idea is to directly parse the format description in
r300_translate_texformat and return ~0 if the format is unsupported.
tags/7.8-rc1
Marek Olšák 15 years ago
parent
commit
ca0e88ce92

+ 14
- 50
src/gallium/drivers/r300/r300_screen.c View File

@@ -210,6 +210,8 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
{
uint32_t retval = 0;
boolean is_r500 = r300_screen(screen)->caps->is_r500;
boolean is_z24 = format == PIPE_FORMAT_Z24X8_UNORM ||
format == PIPE_FORMAT_Z24S8_UNORM;

if (target >= PIPE_MAX_TEXTURE_TYPES) {
debug_printf("r300: Implementation error: Received bogus texture "
@@ -217,32 +219,18 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
return FALSE;
}

/* Check sampler format support. */
if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) &&
(is_r500 || !is_z24) && /* Z24 cannot be sampled from on non-r5xx. */
r300_translate_texformat(format) != ~0) {
retval |= PIPE_TEXTURE_USAGE_SAMPLER;
}

switch (format) {
/* Supported formats. */
/* Colorbuffer */
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_L8_UNORM:
retval = usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY);
break;

/* Texture */
case PIPE_FORMAT_A8R8G8B8_SRGB:
case PIPE_FORMAT_R8G8B8A8_SRGB:
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
case PIPE_FORMAT_DXT3_RGBA:
case PIPE_FORMAT_DXT5_RGBA:
case PIPE_FORMAT_YCBCR:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_A8L8_SRGB:
case PIPE_FORMAT_A8L8_UNORM:
retval = usage & PIPE_TEXTURE_USAGE_SAMPLER;
break;

/* Colorbuffer or texture */
case PIPE_FORMAT_R5G6B5_UNORM:
case PIPE_FORMAT_A1R5G5B5_UNORM:
case PIPE_FORMAT_A4R4G4B4_UNORM:
@@ -251,47 +239,23 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_I8_UNORM:
retval = usage &
retval |= usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY |
PIPE_TEXTURE_USAGE_SAMPLER);
PIPE_TEXTURE_USAGE_PRIMARY);
break;

/* Z buffer or texture */
/* ZS buffer */
case PIPE_FORMAT_Z16_UNORM:
retval = usage &
(PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_SAMPLER);
break;

/* 24bit Z buffer can only be used as a texture on R500. */
case PIPE_FORMAT_Z24X8_UNORM:
/* Z buffer with stencil or texture */
case PIPE_FORMAT_Z24S8_UNORM:
retval = usage &
(PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
(is_r500 ? PIPE_TEXTURE_USAGE_SAMPLER : 0));
retval = usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
break;

/* Definitely unsupported formats. */
/* Non-usable Z buffer/stencil formats. */
case PIPE_FORMAT_Z32_UNORM:
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
SCREEN_DBG(r300_screen(screen), DBG_TEX,
"r300: Note: Got unsupported format: %s in %s\n",
util_format_name(format), __FUNCTION__);
return FALSE;

/* XXX Add all remaining gallium-supported formats,
* see util/u_format.csv. */

default:
/* Unknown format... */
debug_printf("r300: Warning: Got unknown format: %s in %s\n",
util_format_name(format), __FUNCTION__);
break;
default:;
}

/* If usage was a mask that contained multiple bits, and not all of them

+ 0
- 1
src/gallium/drivers/r300/r300_state_inlines.h View File

@@ -338,7 +338,6 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
/* case PIPE_FORMAT_S8_UNORM: ??? */
return R300_COLOR_FORMAT_I8;
/* 16-bit buffers */
case PIPE_FORMAT_R5G6B5_UNORM:

+ 220
- 73
src/gallium/drivers/r300/r300_texture.h View File

@@ -52,81 +52,228 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
* makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
{
switch (format) {
/* X8 */
case PIPE_FORMAT_A8_UNORM:
return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8);
case PIPE_FORMAT_I8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, X8);
case PIPE_FORMAT_L8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, ONE, X8);
case PIPE_FORMAT_L8_SRGB:
return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) |
R300_TX_FORMAT_GAMMA;
/* X16 */
case PIPE_FORMAT_A4R4G4B4_UNORM:
return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_Z16_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, X16);
case PIPE_FORMAT_R16_SNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, X16) |
R300_TX_FORMAT_SIGNED;
/* Z5Y6X5 */
case PIPE_FORMAT_R5G6B5_UNORM:
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
/* W1Z5Y5X5*/
case PIPE_FORMAT_A1R5G5B5_UNORM:
return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
/* Y8X8 */
case PIPE_FORMAT_A8L8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
case PIPE_FORMAT_A8L8_SRGB:
return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) |
R300_TX_FORMAT_GAMMA;
/* W8Z8Y8X8 */
case PIPE_FORMAT_A8R8G8B8_UNORM:
return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
case PIPE_FORMAT_R8G8B8A8_UNORM:
return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8);
case PIPE_FORMAT_X8R8G8B8_UNORM:
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
case PIPE_FORMAT_R8G8B8X8_UNORM:
return R300_EASY_TX_FORMAT(Y, Z, ONE, X, W8Z8Y8X8);
case PIPE_FORMAT_A8R8G8B8_SRGB:
return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8) |
R300_TX_FORMAT_GAMMA;
case PIPE_FORMAT_R8G8B8A8_SRGB:
return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) |
R300_TX_FORMAT_GAMMA;
/* DXT1 */
case PIPE_FORMAT_DXT1_RGB:
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1);
case PIPE_FORMAT_DXT1_RGBA:
return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1);
/* DXT3 */
case PIPE_FORMAT_DXT3_RGBA:
return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3);
/* DXT5 */
case PIPE_FORMAT_DXT5_RGBA:
return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5);
/* YVYU422 */
case PIPE_FORMAT_YCBCR:
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) |
R300_TX_FORMAT_YUV_TO_RGB;
/* W24_FP */
case PIPE_FORMAT_Z24S8_UNORM:
case PIPE_FORMAT_Z24X8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);

default:
debug_printf("r300: Implementation error: "
"Got unsupported texture format %s in %s\n",
util_format_name(format), __FUNCTION__);
assert(0);
uint32_t result = 0;
const struct util_format_description *desc;
unsigned components = 0, i;
boolean uniform = TRUE;
const uint32_t swizzle_shift[4] = {
R300_TX_FORMAT_R_SHIFT,
R300_TX_FORMAT_G_SHIFT,
R300_TX_FORMAT_B_SHIFT,
R300_TX_FORMAT_A_SHIFT
};
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. */
case UTIL_FORMAT_COLORSPACE_ZS:
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, X16);
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24S8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, 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_YCBCR:
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
case PIPE_FORMAT_YCBCR_REV:
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:;
}

/* Add swizzle. */
for (i = 0; i < 4; i++) {
switch (desc->swizzle[i]) {
case UTIL_FORMAT_SWIZZLE_X:
case UTIL_FORMAT_SWIZZLE_NONE:
result |= R300_TX_FORMAT_X << swizzle_shift[i];
break;
case UTIL_FORMAT_SWIZZLE_Y:
result |= R300_TX_FORMAT_Y << swizzle_shift[i];
break;
case UTIL_FORMAT_SWIZZLE_Z:
result |= R300_TX_FORMAT_Z << swizzle_shift[i];
break;
case UTIL_FORMAT_SWIZZLE_W:
result |= R300_TX_FORMAT_W << swizzle_shift[i];
break;
case UTIL_FORMAT_SWIZZLE_0:
result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
break;
case UTIL_FORMAT_SWIZZLE_1:
result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
break;
default:
return ~0; /* Unsupported. */
}
}

/* Compressed formats. */
if (desc->layout == UTIL_FORMAT_LAYOUT_DXT) {
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. */
}
}

/* Get the number of components. */
for (i = 0; i < 4; i++) {
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
++components;
}
}

/* Add sign. */
for (i = 0; i < components; i++) {
if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
result |= sign_bit[i];
}
}
return 0;

/* See whether the components are of the same size. */
for (i = 1; i < components; i++) {
uniform = uniform && desc->channel[0].size == desc->channel[i].size;
}

/* Non-uniform formats. */
if (!uniform) {
switch (components) {
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) {
return ~0;
}

switch (desc->channel[0].size) {
case 4:
switch (components) {
case 2:
return R300_TX_FORMAT_Y4X4 | result;
case 4:
return R300_TX_FORMAT_W4Z4Y4X4 | result;
}
return ~0;

case 8:
switch (components) {
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 (components) {
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;

/* XXX Enable float textures here. */
#if 0
case UTIL_FORMAT_TYPE_FLOAT:
switch (desc->channel[0].size) {
case 16:
switch (components) {
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 (components) {
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;
}
}
#endif
}

return ~0; /* Unsupported/unknown. */
}

struct r300_video_surface

Loading…
Cancel
Save