diff options
Diffstat (limited to 'src/gallium/drivers/nv04/nv04_miptree.c')
-rw-r--r-- | src/gallium/drivers/nv04/nv04_miptree.c | 93 |
1 files changed, 55 insertions, 38 deletions
diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 094c38256b4..01cb8ecbf31 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -11,7 +11,7 @@ nv04_miptree_layout(struct nv04_miptree *nv04mt) struct pipe_texture *pt = &nv04mt->base; uint width = pt->width[0], height = pt->height[0]; uint offset = 0; - int nr_faces, l, f; + int nr_faces, l; nr_faces = 1; @@ -22,31 +22,26 @@ nv04_miptree_layout(struct nv04_miptree *nv04mt) pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); - nv04mt->level[l].pitch = pt->width[0] * pt->block.size; + nv04mt->level[l].pitch = pt->width[0]; nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63; - nv04mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); - } - for (f = 0; f < nr_faces; f++) { - for (l = 0; l <= pt->last_level; l++) { - nv04mt->level[l].image_offset[f] = offset; - offset += nv04mt->level[l].pitch * pt->height[l]; - } + for (l = 0; l <= pt->last_level; l++) { + + nv04mt->level[l].image_offset = offset; + offset += nv04mt->level[l].pitch * pt->height[l]; } nv04mt->total_size = offset; } static struct pipe_texture * -nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) +nv04_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { - struct pipe_winsys *ws = screen->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv04_miptree *mt; mt = MALLOC(sizeof(struct nv04_miptree)); @@ -54,13 +49,19 @@ nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) return NULL; mt->base = *pt; mt->base.refcount = 1; - mt->base.screen = screen; + mt->base.screen = pscreen; + mt->shadow_tex = NULL; + mt->shadow_surface = NULL; + + //mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; nv04_miptree_layout(mt); - mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, - mt->total_size); + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL | + NOUVEAU_BUFFER_USAGE_TEXTURE, + mt->total_size); if (!mt->buffer) { + printf("failed %d byte alloc\n",mt->total_size); FREE(mt); return NULL; } @@ -69,22 +70,29 @@ nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) } static void -nv04_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) +nv04_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) { - struct pipe_texture *mt = *pt; - - *pt = NULL; - if (--mt->refcount <= 0) { - struct nv04_miptree *nv04mt = (struct nv04_miptree *)mt; - int l; - - pipe_buffer_reference(screen, &nv04mt->buffer, NULL); - for (l = 0; l <= mt->last_level; l++) { - if (nv04mt->level[l].image_offset) - FREE(nv04mt->level[l].image_offset); - } - FREE(nv04mt); + struct pipe_texture *pt = *ppt; + struct nv04_miptree *mt = (struct nv04_miptree *)pt; + int l; + + *ppt = NULL; + if (--pt->refcount) + return; + + pipe_buffer_reference(pscreen, &mt->buffer, NULL); + for (l = 0; l <= pt->last_level; l++) { + if (mt->level[l].image_offset) + FREE(mt->level[l].image_offset); } + + if (mt->shadow_tex) { + assert(mt->shadow_surface); + pscreen->tex_surface_release(pscreen, &mt->shadow_surface); + nv04_miptree_release(pscreen, &mt->shadow_tex); + } + + FREE(mt); } static struct pipe_surface * @@ -92,7 +100,6 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { - struct pipe_winsys *ws = pscreen->winsys; struct nv04_miptree *nv04mt = (struct nv04_miptree *)pt; struct pipe_surface *ps; @@ -102,19 +109,20 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(pscreen, &ps->buffer, nv04mt->buffer); ps->format = pt->format; - ps->block = pt->block; ps->width = pt->width[level]; ps->height = pt->height[level]; + ps->block = pt->block; ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; ps->stride = nv04mt->level[level].pitch; + ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; ps->refcount = 1; + ps->face = face; + ps->level = level; + ps->zslice = zslice; - if (pt->target == PIPE_TEXTURE_CUBE) { - ps->offset = nv04mt->level[level].image_offset[face]; - } else { - ps->offset = nv04mt->level[level].image_offset[0]; - } + ps->offset = nv04mt->level[level].image_offset; return ps; } @@ -123,10 +131,19 @@ static void nv04_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { + struct pipe_surface *ps = *psurface; + + *psurface = NULL; + if (--ps->refcount > 0) + return; + + pipe_texture_reference(&ps->texture, NULL); + pipe_buffer_reference(pscreen->winsys, &ps->buffer, NULL); + FREE(ps); } void -nv04_init_miptree_functions(struct pipe_screen *pscreen) +nv04_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv04_miptree_create; pscreen->texture_release = nv04_miptree_release; |