r300g: make r300_translate_texformat private

Unlikely to increase performance from inlining.

And partially expose it through r300_is_sampler_format_supported.
This commit is contained in:
Marek Olšák 2010-02-20 21:33:53 +01:00
parent 2a30c268bd
commit 5c14fd1743
3 changed files with 246 additions and 235 deletions

View File

@ -222,7 +222,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
/* 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) {
r300_is_sampler_format_supported(format)) {
retval |= PIPE_TEXTURE_USAGE_SAMPLER;
}

View File

@ -44,6 +44,250 @@ static const unsigned microblock_table[5][3][2] = {
{{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
};
/* Translate a pipe_format into a useful texture format for sampling.
*
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
* but the majority of them is translated in a generic way, automatically
* supporting all the formats hw can support.
*
* R300_EASY_TX_FORMAT swizzles the texture.
* Note the signature of R300_EASY_TX_FORMAT:
* R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
*
* The FORMAT specifies how the texture sampler will treat the texture, and
* makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
static uint32_t r300_translate_texformat(enum pipe_format format)
{
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];
}
}
/* 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 &&
desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
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. */
}
boolean r300_is_sampler_format_supported(enum pipe_format format)
{
return r300_translate_texformat(format) != ~0;
}
static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex)
{
struct r300_texture_state* state = &tex->state;

View File

@ -42,240 +42,7 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
struct pipe_texture *tex,
enum pipe_format new_format);
/* Translate a pipe_format into a useful texture format for sampling.
*
* R300_EASY_TX_FORMAT swizzles the texture.
* Note the signature of R300_EASY_TX_FORMAT:
* R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
*
* The FORMAT specifies how the texture sampler will treat the texture, and
* makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
{
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];
}
}
/* 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 &&
desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
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. */
}
boolean r300_is_sampler_format_supported(enum pipe_format format);
struct r300_video_surface
{