summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_texture.c')
-rw-r--r--src/gallium/drivers/r300/r300_texture.c115
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;
+}