diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index d6f629cf9c..4a5c932b7e 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -24,6 +24,7 @@ #include "pipe/p_screen.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -46,6 +47,60 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; +unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view) +{ + unsigned i; + unsigned char swizzle[4]; + unsigned result = 0; + 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 swizzle_bit[4] = { + R300_TX_FORMAT_X, + R300_TX_FORMAT_Y, + R300_TX_FORMAT_Z, + R300_TX_FORMAT_W + }; + + if (swizzle_view) { + /* Combine two sets of swizzles. */ + for (i = 0; i < 4; i++) { + swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? + swizzle_format[swizzle_view[i]] : swizzle_view[i]; + } + } else { + memcpy(swizzle, swizzle_format, 4); + } + + /* Get swizzle. */ + for (i = 0; i < 4; i++) { + switch (swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_Y: + result |= swizzle_bit[1] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + result |= swizzle_bit[2] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + result |= swizzle_bit[3] << 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: /* UTIL_FORMAT_SWIZZLE_X */ + result |= swizzle_bit[0] << swizzle_shift[i]; + } + } + return result; +} + /* Translate a pipe_format into a useful texture format for sampling. * * Some special formats are translated directly using R300_EASY_TX_FORMAT, @@ -65,38 +120,26 @@ uint32_t r300_translate_texformat(enum pipe_format format, const struct util_format_description *desc; unsigned 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 swizzle_bit[4] = { - R300_TX_FORMAT_X, - R300_TX_FORMAT_Y, - R300_TX_FORMAT_Z, - R300_TX_FORMAT_W - }; 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, }; - unsigned char swizzle[4]; desc = util_format_description(format); /* Colorspace (return non-RGB formats directly). */ switch (desc->colorspace) { - /* Depth stencil formats. */ + /* 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_EASY_TX_FORMAT(X, X, X, X, X16); + return R300_TX_FORMAT_X16; case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); + return R300_TX_FORMAT_W24_FP; default: return ~0; /* Unsupported. */ } @@ -130,46 +173,14 @@ uint32_t r300_translate_texformat(enum pipe_format format, } } - /* Get swizzle. */ - if (swizzle_view) { - /* Compose two sets of swizzles. */ - for (i = 0; i < 4; i++) { - swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? - desc->swizzle[swizzle_view[i]] : swizzle_view[i]; - } - } else { - memcpy(swizzle, desc->swizzle, sizeof(swizzle)); - } - - /* Add swizzle. */ - for (i = 0; i < 4; i++) { - switch (swizzle[i]) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_NONE: - result |= swizzle_bit[0] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Y: - result |= swizzle_bit[1] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Z: - result |= swizzle_bit[2] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_W: - result |= swizzle_bit[3] << 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. */ - } - } + 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: @@ -920,6 +931,7 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, fprintf(stderr, "r300: texture_create: " "Got invalid texture dimensions: %ix%ix%i\n", base->width0, base->height0, base->depth0); + FREE(tex); return NULL; } @@ -948,7 +960,7 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, util_format_short_name(base->format)); tex->buffer = rws->buffer_create(rws, 2048, - PIPE_BIND_SAMPLER_VIEW, /* XXX */ + base->bind, tex->size); rws->buffer_set_tiling(rws, tex->buffer, tex->pitch[0], |