diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_texture.c | 115 |
1 files changed, 71 insertions, 44 deletions
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index ff812c09f8..6cdea3d285 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -27,12 +27,37 @@ static int minify(int i) return MAX2(1, i >> 1); } +static void r300_setup_texture_state(struct r300_texture* tex, + unsigned width, + unsigned height, + unsigned pitch) +{ + struct r300_texture_state* state = &tex->state; + + state->format0 = R300_TX_WIDTH((width - 1) & 0x7ff) | + R300_TX_HEIGHT((height - 1) & 0x7ff) | R300_TX_PITCH_EN; + + /* XXX */ + state->format1 = R300_TX_FORMAT_A8R8G8B8; + + state->format2 = pitch - 1; + + /* XXX + if (width > 2048) { + state->pitch |= R300_TXWIDTH_11; + } + if (height > 2048) { + state->pitch |= R300_TXHEIGHT_11; + } */ +} + static void r300_setup_miptree(struct r300_texture* tex) { struct pipe_texture* base = &tex->tex; int stride, size, offset; + int i; - for (int i = 0; i <= base->last_level; i++) { + for (i = 0; i <= base->last_level; i++) { if (i > 0) { base->width[i] = minify(base->width[i-1]); base->height[i] = minify(base->height[i-1]); @@ -43,13 +68,16 @@ static void r300_setup_miptree(struct r300_texture* tex) base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]); /* Radeons enjoy things in multiples of 32. */ - /* XXX NPOT -> 64, not 32 */ + /* XXX this can be 32 when POT */ stride = (base->nblocksx[i] * base->block.size + 63) & ~63; size = stride * base->nblocksy[i] * base->depth[i]; - /* XXX 64 for NPOT */ tex->offset[i] = (tex->size + 63) & ~63; tex->size = tex->offset[i] + size; + + if (i == 0) { + tex->stride = stride; + } } } @@ -67,12 +95,16 @@ static struct pipe_texture* } tex->tex = *template; - tex->tex.refcount = 1; + pipe_reference_init(&tex->tex.reference, 1); tex->tex.screen = screen; r300_setup_miptree(tex); - tex->buffer = screen->buffer_create(screen, 63, + /* XXX */ + r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], + tex->tex.width[0]); + + tex->buffer = screen->buffer_create(screen, 64, PIPE_BUFFER_USAGE_PIXEL, tex->size); @@ -84,24 +116,13 @@ static struct pipe_texture* return (struct pipe_texture*)tex; } -static void r300_texture_release(struct pipe_screen* screen, - struct pipe_texture** texture) +static void r300_texture_destroy(struct pipe_texture* texture) { - if (!*texture) { - return; - } - - (*texture)->refcount--; - - if ((*texture)->refcount <= 0) { - struct r300_texture* tex = (struct r300_texture*)*texture; + struct r300_texture* tex = (struct r300_texture*)texture; - pipe_buffer_reference(screen, &tex->buffer, NULL); + pipe_buffer_reference(&tex->buffer, NULL); - FREE(tex); - } - - *texture = NULL; + FREE(tex); } static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, @@ -119,17 +140,11 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, offset = tex->offset[level]; if (surface) { - surface->refcount = 1; + pipe_reference_init(&surface->reference, 1); pipe_texture_reference(&surface->texture, texture); surface->format = texture->format; surface->width = texture->width[level]; surface->height = texture->height[level]; - surface->block = texture->block; - surface->nblocksx = texture->nblocksx[level]; - surface->nblocksy = texture->nblocksy[level]; - /* XXX save the actual stride instead plz kthnxbai */ - surface->stride = - (texture->nblocksx[level] * texture->block.size + 63) & ~63; surface->offset = offset; surface->usage = flags; surface->status = PIPE_SURFACE_STATUS_DEFINED; @@ -138,19 +153,10 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, return surface; } -static void r300_tex_surface_release(struct pipe_screen* screen, - struct pipe_surface** surface) +static void r300_tex_surface_destroy(struct pipe_surface* s) { - struct pipe_surface* s = *surface; - - s->refcount--; - - if (s->refcount <= 0) { - pipe_texture_reference(&s->texture, NULL); - FREE(s); - } - - *surface = NULL; + pipe_texture_reference(&s->texture, NULL); + FREE(s); } static struct pipe_texture* @@ -173,12 +179,15 @@ static struct pipe_texture* } tex->tex = *base; - tex->tex.refcount = 1; + pipe_reference_init(&tex->tex.reference, 1); tex->tex.screen = screen; - /* XXX tex->stride = *stride; */ + tex->stride = *stride; + + r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], + tex->stride); - pipe_buffer_reference(screen, &tex->buffer, buffer); + pipe_buffer_reference(&tex->buffer, buffer); return (struct pipe_texture*)tex; } @@ -186,8 +195,26 @@ static struct pipe_texture* void r300_init_screen_texture_functions(struct pipe_screen* screen) { screen->texture_create = r300_texture_create; - screen->texture_release = r300_texture_release; + screen->texture_destroy = r300_texture_destroy; screen->get_tex_surface = r300_get_tex_surface; - screen->tex_surface_release = r300_tex_surface_release; + screen->tex_surface_destroy = r300_tex_surface_destroy; screen->texture_blanket = r300_texture_blanket; } + +boolean r300_get_texture_buffer(struct pipe_texture* texture, + struct pipe_buffer** buffer, + unsigned* stride) +{ + struct r300_texture* tex = (struct r300_texture*)texture; + if (!tex) { + return FALSE; + } + + pipe_buffer_reference(buffer, tex->buffer); + + if (stride) { + *stride = tex->stride; + } + + return TRUE; +} |