diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 590052509c..ce60ded7ca 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -22,41 +22,62 @@ #include "r300_texture.h" -static void r300_setup_texture_state(struct r300_texture* tex, - unsigned width, - unsigned height, - unsigned pitch, - unsigned levels) +static void r300_setup_texture_state(struct r300_texture* tex) { struct r300_texture_state* state = &tex->state; + struct pipe_texture *pt = &tex->tex; - state->format0 = R300_TX_WIDTH((width - 1) & 0x7ff) | - R300_TX_HEIGHT((height - 1) & 0x7ff) | - R300_TX_NUM_LEVELS(levels) | + state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) | + R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff) | + R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf) | + R300_TX_NUM_LEVELS(pt->last_level) | R300_TX_PITCH_EN; /* XXX */ - state->format1 = r300_translate_texformat(tex->tex.format); + state->format1 = r300_translate_texformat(pt->format); + if (pt->target == PIPE_TEXTURE_CUBE) { + state->format1 |= R300_TX_FORMAT_CUBIC_MAP; + } + if (pt->target == PIPE_TEXTURE_3D) { + state->format1 |= R300_TX_FORMAT_3D; + } - state->format2 = pitch - 1; + state->format2 = (r300_texture_get_stride(tex, 0) / pt->block.size) - 1; /* Assume (somewhat foolishly) that oversized textures will * not be permitted by the state tracker. */ - if (width > 2048) { + if (pt->width[0] > 2048) { state->format2 |= R500_TXWIDTH_BIT11; } - if (height > 2048) { + if (pt->height[0] > 2048) { state->format2 |= R500_TXHEIGHT_BIT11; } - debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n", - width, height, pitch, levels); + debug_printf("r300: Set texture state (%dx%d, %d levels)\n", + pt->width[0], pt->height[0], pt->last_level); +} + +/** + * Return the stride, in bytes, of the texture images of the given texture + * at the given level. + */ +unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) +{ + if (tex->stride_override) + return tex->stride_override; + + if (level > tex->tex.last_level) { + debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, level, tex->tex.last_level); + return 0; + } + + return align(pf_get_stride(&tex->tex.block, tex->tex.width[level]), 32); } static void r300_setup_miptree(struct r300_texture* tex) { struct pipe_texture* base = &tex->tex; - int stride, size, offset; + int stride, size; int i; for (i = 0; i <= base->last_level; i++) { @@ -74,7 +95,7 @@ static void r300_setup_miptree(struct r300_texture* tex) * XXX * POT, uncompressed, unmippmapped textures can be aligned to 32, * instead of 64. */ - stride = align(pf_get_stride(&base->block, base->width[i]), 32); + stride = r300_texture_get_stride(tex, i); size = stride * base->nblocksy[i] * base->depth[i]; tex->offset[i] = align(tex->size, 32); @@ -84,10 +105,6 @@ static void r300_setup_miptree(struct r300_texture* tex) "(%dx%dx%d px, pitch %d bytes)\n", i, base->width[i], base->height[i], base->depth[i], stride); - /* Save stride of first level to the texture. */ - if (i == 0) { - tex->stride = stride; - } } } @@ -108,8 +125,7 @@ static struct pipe_texture* r300_setup_miptree(tex); - r300_setup_texture_state(tex, template->width[0], template->height[0], - template->width[0], template->last_level); + r300_setup_texture_state(tex); tex->buffer = screen->buffer_create(screen, 1024, PIPE_BUFFER_USAGE_PIXEL, @@ -189,11 +205,10 @@ static struct pipe_texture* pipe_reference_init(&tex->tex.reference, 1); tex->tex.screen = screen; - tex->stride = *stride; + tex->stride_override = *stride; /* XXX */ - r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], - tex->stride, 0); + r300_setup_texture_state(tex); pipe_buffer_reference(&tex->buffer, buffer); @@ -221,7 +236,7 @@ boolean r300_get_texture_buffer(struct pipe_texture* texture, pipe_buffer_reference(buffer, tex->buffer); if (stride) { - *stride = tex->stride; + *stride = r300_texture_get_stride(tex, 0); } return TRUE; |