diff options
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/Makefile | 12 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_miptree.c | 160 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_query.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 87 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_surface.c | 38 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tex.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_transfer.c | 211 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 4 |
13 files changed, 311 insertions, 252 deletions
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index be30400c039..612aea28a34 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -3,7 +3,7 @@ include $(TOP)/configs/current LIBNAME = nv50 -DRIVER_SOURCES = \ +C_SOURCES = \ nv50_clear.c \ nv50_context.c \ nv50_draw.c \ @@ -15,15 +15,7 @@ DRIVER_SOURCES = \ nv50_state_validate.c \ nv50_surface.c \ nv50_tex.c \ + nv50_transfer.c \ nv50_vbo.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template - -symlinks: - diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 1e9d45cb340..313e435e7a5 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -64,10 +64,8 @@ struct nv50_rasterizer_stateobj { }; struct nv50_miptree_level { - struct pipe_buffer **image; int *image_offset; - unsigned image_dirty_cpu[512/32]; - unsigned image_dirty_gpu[512/32]; + unsigned pitch; }; struct nv50_miptree { @@ -200,8 +198,4 @@ extern boolean nv50_state_validate(struct nv50_context *nv50); /* nv50_tex.c */ extern void nv50_tex_validate(struct nv50_context *); -/* nv50_miptree.c */ -extern void nv50_miptree_sync(struct pipe_screen *, struct nv50_miptree *, - unsigned level, unsigned image); - #endif diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 91091d53f57..dc4688ccdc4 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -29,7 +29,6 @@ static struct pipe_texture * nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) { - struct pipe_winsys *ws = pscreen->winsys; struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); struct pipe_texture *pt = &mt->base; unsigned usage, width = tmp->width[0], height = tmp->height[0]; @@ -37,7 +36,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) int i, l; mt->base = *tmp; - mt->base.refcount = 1; + pipe_reference_init(&mt->base.reference, 1); mt->base.screen = pscreen; usage = PIPE_BUFFER_USAGE_PIXEL; @@ -72,7 +71,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); lvl->image_offset = CALLOC(mt->image_nr, sizeof(int)); - lvl->image = CALLOC(mt->image_nr, sizeof(struct pipe_buffer *)); + lvl->pitch = align(pt->width[l] * pt->block.size, 64); width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); @@ -88,14 +87,13 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) size = align(size, 64); size *= align(pt->height[l], 8) * pt->block.size; - lvl->image[i] = ws->buffer_create(ws, 256, 0, size); lvl->image_offset[i] = mt->total_size; mt->total_size += size; } } - mt->buffer = ws->buffer_create(ws, 256, usage, mt->total_size); + mt->buffer = pscreen->buffer_create(pscreen, 256, usage, mt->total_size); if (!mt->buffer) { FREE(mt); return NULL; @@ -120,119 +118,23 @@ nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, return NULL; mt->base = *pt; - mt->base.refcount = 1; + pipe_reference_init(&mt->base.reference, 1); mt->base.screen = pscreen; mt->image_nr = 1; + mt->level[0].pitch = *stride; mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - pipe_buffer_reference(pscreen, &mt->buffer, pb); + pipe_buffer_reference(&mt->buffer, pb); return &mt->base; } -static INLINE void -mark_dirty(uint32_t *flags, unsigned image) -{ - flags[image / 32] |= (1 << (image % 32)); -} - -static INLINE void -mark_clean(uint32_t *flags, unsigned image) -{ - flags[image / 32] &= ~(1 << (image % 32)); -} - -static INLINE int -is_dirty(uint32_t *flags, unsigned image) -{ - return !!(flags[image / 32] & (1 << (image % 32))); -} - static void -nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) -{ - struct pipe_texture *pt = *ppt; - - *ppt = NULL; - - if (--pt->refcount <= 0) { - struct nv50_miptree *mt = nv50_miptree(pt); - - pipe_buffer_reference(pscreen, &mt->buffer, NULL); - FREE(mt); - } -} - -void -nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt, - unsigned level, unsigned image) +nv50_miptree_destroy(struct pipe_texture *pt) { - struct nv50_screen *nvscreen = nv50_screen(pscreen); - struct nv50_miptree_level *lvl = &mt->level[level]; - struct pipe_surface *dst, *src; - unsigned face = 0, zslice = 0; - - if (!is_dirty(lvl->image_dirty_cpu, image)) - return; - - if (mt->base.target == PIPE_TEXTURE_CUBE) - face = image; - else - if (mt->base.target == PIPE_TEXTURE_3D) - zslice = image; - - /* Mark as clean already - so we don't continually call this function - * trying to get a GPU_WRITE pipe_surface! - */ - mark_clean(lvl->image_dirty_cpu, image); - - /* Pretend we're doing CPU access so we get the backing pipe_surface - * and not a view into the larger miptree. - */ - src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, - PIPE_BUFFER_USAGE_CPU_READ); - - /* Pretend we're only reading with the GPU so surface doesn't get marked - * as dirtied by the GPU. - */ - dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - nv50_surface_do_copy(nvscreen, dst, 0, 0, src, 0, 0, dst->width, dst->height); - - pscreen->tex_surface_release(pscreen, &dst); - pscreen->tex_surface_release(pscreen, &src); -} - -/* The reverse of the above */ -static void -nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt, - unsigned level, unsigned image) -{ - struct nv50_screen *nvscreen = nv50_screen(pscreen); - struct nv50_miptree_level *lvl = &mt->level[level]; - struct pipe_surface *dst, *src; - unsigned face = 0, zslice = 0; - - if (!is_dirty(lvl->image_dirty_gpu, image)) - return; - - if (mt->base.target == PIPE_TEXTURE_CUBE) - face = image; - else - if (mt->base.target == PIPE_TEXTURE_3D) - zslice = image; - - mark_clean(lvl->image_dirty_gpu, image); - - src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice, - PIPE_BUFFER_USAGE_CPU_READ); - - nv50_surface_do_copy(nvscreen, dst, 0, 0, src, 0, 0, dst->width, dst->height); + struct nv50_miptree *mt = nv50_miptree(pt); - pscreen->tex_surface_release(pscreen, &dst); - pscreen->tex_surface_release(pscreen, &src); + pipe_buffer_reference(&mt->buffer, NULL); + FREE(mt); } static struct pipe_surface * @@ -260,52 +162,24 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->format = pt->format; 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 = ps->width * ps->block.size; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; - ps->refcount = 1; + pipe_reference_init(&ps->reference, 1); ps->face = face; ps->level = level; ps->zslice = zslice; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { - assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE)); - nv50_miptree_sync_cpu(pscreen, mt, level, img); - - ps->offset = 0; - pipe_texture_reference(&ps->texture, pt); - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - mark_dirty(lvl->image_dirty_cpu, img); - } else { - nv50_miptree_sync(pscreen, mt, level, img); - - ps->offset = lvl->image_offset[img]; - pipe_texture_reference(&ps->texture, pt); - - if (flags & PIPE_BUFFER_USAGE_GPU_WRITE) - mark_dirty(lvl->image_dirty_gpu, img); - } + ps->offset = lvl->image_offset[img]; return ps; } static void -nv50_miptree_surface_del(struct pipe_screen *pscreen, - struct pipe_surface **psurface) +nv50_miptree_surface_del(struct pipe_surface *ps) { - struct pipe_surface *ps = *psurface; struct nv50_surface *s = nv50_surface(ps); - *psurface = NULL; - - if (--ps->refcount <= 0) { - pipe_texture_reference(&ps->texture, NULL); - FREE(s); - } + pipe_texture_reference(&ps->texture, NULL); + FREE(s); } void @@ -313,8 +187,8 @@ nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) { pscreen->texture_create = nv50_miptree_create; pscreen->texture_blanket = nv50_miptree_blanket; - pscreen->texture_release = nv50_miptree_release; + pscreen->texture_destroy = nv50_miptree_destroy; pscreen->get_tex_surface = nv50_miptree_surface_new; - pscreen->tex_surface_release = nv50_miptree_surface_del; + pscreen->tex_surface_destroy = nv50_miptree_surface_del; } diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 14c5d47e790..2d15868ae84 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1603,7 +1603,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { struct nouveau_channel *chan = nv50->screen->nvws->channel; struct nouveau_grobj *tesla = nv50->screen->tesla; - struct pipe_winsys *ws = nv50->pipe.winsys; + struct pipe_screen *screen = nv50->pipe.screen; struct nv50_program_exec *e; struct nouveau_stateobj *so; const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR; @@ -1611,7 +1611,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) boolean upload = FALSE; if (!p->buffer) { - p->buffer = ws->buffer_create(ws, 0x100, 0, p->exec_size * 4); + p->buffer = screen->buffer_create(screen, 0x100, 0, p->exec_size * 4); upload = TRUE; } @@ -1719,6 +1719,7 @@ nv50_vertprog_validate(struct nv50_context *nv50) so_method(so, tesla, 0x140c, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.vertprog); + so_ref(NULL, &so); } void @@ -1758,6 +1759,7 @@ nv50_fragprog_validate(struct nv50_context *nv50) so_method(so, tesla, 0x1414, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.fragprog); + so_ref(NULL, &so); } void @@ -1775,7 +1777,7 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) p->exec_size = 0; if (p->buffer) - pipe_buffer_reference(pscreen, &p->buffer, NULL); + pipe_buffer_reference(&p->buffer, NULL); nv50->screen->nvws->res_free(&p->data); diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 20745ceab8b..a2c56f99a89 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -41,13 +41,13 @@ nv50_query(struct pipe_query *pipe) static struct pipe_query * nv50_query_create(struct pipe_context *pipe, unsigned type) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_screen *screen = pipe->winsys; struct nv50_query *q = CALLOC_STRUCT(nv50_query); assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER); q->type = type; - q->buffer = ws->buffer_create(ws, 256, 0, 16); + q->buffer = screen->buffer_create(screen, 256, 0, 16); if (!q->buffer) { FREE(q); return NULL; @@ -62,7 +62,7 @@ nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) struct nv50_query *q = nv50_query(pq); if (q) { - pipe_buffer_reference(pipe->screen, &q->buffer, NULL); + pipe_buffer_reference(&q->buffer, NULL); FREE(q); } } @@ -90,11 +90,12 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) struct nouveau_channel *chan = nv50->screen->nvws->channel; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_query *q = nv50_query(pq); + struct nouveau_bo *bo = nv50->screen->nvws->get_bo(q->buffer); WAIT_RING (chan, 5); BEGIN_RING(chan, tesla, 0x1b00, 4); - OUT_RELOCh(chan, q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCh(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RING (chan, 0x00000000); OUT_RING (chan, 0x0100f002); FIRE_RING (chan); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 58d7a621a80..29805645948 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -29,10 +29,6 @@ #include "nouveau/nouveau_stateobj.h" -#define NV5X_GRCLASS5097_CHIPSETS 0x00000001 -#define NV8X_GRCLASS8297_CHIPSETS 0x00000050 -#define NV9X_GRCLASS8297_CHIPSETS 0x00000014 - static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, @@ -124,9 +120,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: return 0; - case NOUVEAU_CAP_HW_VTXBUF: + case NOUVEAU_CAP_HW_VTXBUF: return 1; - case NOUVEAU_CAP_HW_IDXBUF: + case NOUVEAU_CAP_HW_IDXBUF: return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); @@ -173,36 +169,38 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; screen->nvws = nvws; - /* 2D object */ - ret = nvws->grobj_alloc(nvws, NV50_2D, &screen->eng2d); + /* DMA engine object */ + ret = nvws->grobj_alloc(nvws, 0x5039, &screen->m2mf); if (ret) { - NOUVEAU_ERR("Error creating 2D object: %d\n", ret); + NOUVEAU_ERR("Error creating M2MF object: %d\n", ret); nv50_screen_destroy(&screen->pipe); return NULL; } - /* 3D object */ - if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { - NOUVEAU_ERR("Not a G8x chipset\n"); + /* 2D object */ + ret = nvws->grobj_alloc(nvws, NV50_2D, &screen->eng2d); + if (ret) { + NOUVEAU_ERR("Error creating 2D object: %d\n", ret); nv50_screen_destroy(&screen->pipe); return NULL; } + /* 3D object */ switch (chipset & 0xf0) { case 0x50: - if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) - tesla_class = 0x5097; + tesla_class = 0x5097; break; case 0x80: - if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) - tesla_class = 0x8297; - break; case 0x90: - if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) - tesla_class = 0x8297; + tesla_class = 0x8297; break; - default: + case 0xa0: + tesla_class = 0x8397; break; + default: + NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset); + nv50_screen_destroy(&screen->pipe); + return NULL; } if (tesla_class == 0) { @@ -226,6 +224,31 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } + /* Setup the pipe */ + screen->pipe.winsys = ws; + + screen->pipe.destroy = nv50_screen_destroy; + + screen->pipe.get_name = nv50_screen_get_name; + screen->pipe.get_vendor = nv50_screen_get_vendor; + screen->pipe.get_param = nv50_screen_get_param; + screen->pipe.get_paramf = nv50_screen_get_paramf; + + screen->pipe.is_format_supported = nv50_screen_is_format_supported; + + nv50_screen_init_miptree_functions(&screen->pipe); + nv50_transfer_init_screen_functions(&screen->pipe); + u_simple_screen_init(&screen->pipe); + + /* Static M2MF init */ + so = so_new(32, 0); + so_method(so, screen->m2mf, 0x0180, 3); + so_data (so, screen->sync->handle); + so_data (so, screen->nvws->channel->vram->handle); + so_data (so, screen->nvws->channel->vram->handle); + so_emit(nvws, so); + so_ref (NULL, &so); + /* Static 2D init */ so = so_new(64, 0); so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4); @@ -268,7 +291,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 8); /* Shared constant buffer */ - screen->constbuf = ws->buffer_create(ws, 0, 0, 128 * 4 * 4); + screen->constbuf = screen->pipe.buffer_create(&screen->pipe, 0, 0, 128 * 4 * 4); if (nvws->res_init(&screen->vp_data_heap, 0, 128)) { NOUVEAU_ERR("Error initialising constant buffer\n"); nv50_screen_destroy(&screen->pipe); @@ -287,7 +310,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) * blocks. At some point we *may* want to go the NVIDIA way of doing * things? */ - screen->tic = ws->buffer_create(ws, 0, 0, 32 * 8 * 4); + screen->tic = screen->pipe.buffer_create(&screen->pipe, 0, 0, 32 * 8 * 4); so_method(so, screen->tesla, 0x1280, 3); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); @@ -301,7 +324,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, 0x00000800); - screen->tsc = ws->buffer_create(ws, 0, 0, 32 * 8 * 4); + screen->tsc = screen->pipe.buffer_create(&screen->pipe, 0, 0, 32 * 8 * 4); so_method(so, screen->tesla, 0x1280, 3); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); @@ -333,24 +356,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 1); so_emit(nvws, so); - so_ref(so, &screen->static_init); + so_ref (so, &screen->static_init); + so_ref (NULL, &so); nvws->push_flush(nvws, 0, NULL); - screen->pipe.winsys = ws; - - screen->pipe.destroy = nv50_screen_destroy; - - screen->pipe.get_name = nv50_screen_get_name; - screen->pipe.get_vendor = nv50_screen_get_vendor; - screen->pipe.get_param = nv50_screen_get_param; - screen->pipe.get_paramf = nv50_screen_get_paramf; - - screen->pipe.is_format_supported = nv50_screen_is_format_supported; - - nv50_screen_init_miptree_functions(&screen->pipe); - nv50_surface_init_screen_functions(&screen->pipe); - u_simple_screen_init(&screen->pipe); - return &screen->pipe; } diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index c888ca071c8..db567aaac89 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -12,6 +12,7 @@ struct nv50_screen { struct nouveau_grobj *tesla; struct nouveau_grobj *eng2d; + struct nouveau_grobj *m2mf; struct nouveau_notifier *sync; struct pipe_buffer *constbuf; @@ -29,6 +30,6 @@ nv50_screen(struct pipe_screen *screen) return (struct nv50_screen *)screen; } -void nv50_surface_init_screen_functions(struct pipe_screen *); +void nv50_transfer_init_screen_functions(struct pipe_screen *); #endif diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 787ff958ec7..ba852194cdd 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -85,6 +85,7 @@ nv50_blend_state_create(struct pipe_context *pipe, bso->pipe = *cso; so_ref(so, &bso->so); + so_ref(NULL, &so); return (void *)bso; } @@ -352,6 +353,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, rso->pipe = *cso; so_ref(so, &rso->so); + so_ref(NULL, &so); return (void *)rso; } @@ -438,6 +440,7 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, zsa->pipe = *cso; so_ref(so, &zsa->so); + so_ref(NULL, &so); return (void *)zsa; } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 948112ffa9f..85098a78a25 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -124,6 +124,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data (so, h); so_ref(so, &nv50->state.fb); + so_ref(NULL, &so); } static void @@ -214,6 +215,7 @@ nv50_state_validate(struct nv50_context *nv50) so_data (so, fui(nv50->blend_colour.color[2])); so_data (so, fui(nv50->blend_colour.color[3])); so_ref(so, &nv50->state.blend_colour); + so_ref(NULL, &so); } if (nv50->dirty & NV50_NEW_STIPPLE) { @@ -222,6 +224,7 @@ nv50_state_validate(struct nv50_context *nv50) for (i = 0; i < 32; i++) so_data(so, nv50->stipple.stipple[i]); so_ref(so, &nv50->state.stipple); + so_ref(NULL, &so); } if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) { @@ -243,6 +246,7 @@ nv50_state_validate(struct nv50_context *nv50) so_data(so, (8192 << 16)); } so_ref(so, &nv50->state.scissor); + so_ref(NULL, &so); nv50->state.dirty |= NV50_NEW_SCISSOR; } scissor_uptodate: @@ -250,7 +254,7 @@ scissor_uptodate: if (nv50->dirty & NV50_NEW_VIEWPORT) { unsigned bypass; - if (!nv50->rasterizer->pipe.bypass_clipping) + if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport) bypass = 0; else bypass = 1; @@ -283,6 +287,7 @@ scissor_uptodate: } so_ref(so, &nv50->state.viewport); + so_ref(NULL, &so); } viewport_uptodate: @@ -296,6 +301,7 @@ viewport_uptodate: for (i = 0; i < nv50->sampler_nr; i++) so_datap (so, nv50->sampler[i], 8); so_ref(so, &nv50->state.tsc_upload); + so_ref(NULL, &so); } if (nv50->dirty & NV50_NEW_TEXTURE) diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index f2dd2eb30be..0cc5168144d 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -51,6 +51,7 @@ nv50_format(enum pipe_format format) static int nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) { + struct nv50_miptree *mt = nv50_miptree(ps->texture); struct nouveau_channel *chan = screen->nvws->channel; struct nouveau_grobj *eng2d = screen->eng2d; struct nouveau_bo *bo; @@ -70,7 +71,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) OUT_RING (chan, format); OUT_RING (chan, 1); BEGIN_RING(chan, eng2d, mthd + 0x14, 5); - OUT_RING (chan, ps->stride); + OUT_RING (chan, mt->level[0].pitch); OUT_RING (chan, ps->width); OUT_RING (chan, ps->height); OUT_RELOCh(chan, bo, ps->offset, flags); @@ -143,7 +144,7 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, } static void -nv50_surface_copy(struct pipe_context *pipe, boolean flip, +nv50_surface_copy(struct pipe_context *pipe, struct pipe_surface *dest, unsigned destx, unsigned desty, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) @@ -153,16 +154,8 @@ nv50_surface_copy(struct pipe_context *pipe, boolean flip, assert(src->format == dest->format); - if (flip) { - desty += height; - while (height--) { - nv50_surface_do_copy(screen, dest, destx, desty--, src, - srcx, srcy++, width, 1); - } - } else { - nv50_surface_do_copy(screen, dest, destx, desty, src, srcx, + nv50_surface_do_copy(screen, dest, destx, desty, src, srcx, srcy, width, height); - } } static void @@ -197,23 +190,6 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, OUT_RING (chan, height); } -static void * -nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps, - unsigned flags ) -{ - struct pipe_winsys *ws = screen->winsys; - - return ws->buffer_map(ws, nv50_surface_buffer(ps), flags); -} - -static void -nv50_surface_unmap(struct pipe_screen *pscreen, struct pipe_surface *ps) -{ - struct pipe_winsys *ws = pscreen->winsys; - - ws->buffer_unmap(ws, nv50_surface_buffer(ps)); -} - void nv50_init_surface_functions(struct nv50_context *nv50) { @@ -221,10 +197,4 @@ nv50_init_surface_functions(struct nv50_context *nv50) nv50->pipe.surface_fill = nv50_surface_fill; } -void -nv50_surface_init_screen_functions(struct pipe_screen *pscreen) -{ - pscreen->surface_map = nv50_surface_map; - pscreen->surface_unmap = nv50_surface_unmap; -} diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 675f9b20cbc..223c8a3a456 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -135,7 +135,7 @@ nv50_tex_validate(struct nv50_context *nv50) { struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_stateobj *so; - int unit, level, image; + int unit; so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); so_method(so, tesla, 0x0f00, 1); @@ -144,13 +144,6 @@ nv50_tex_validate(struct nv50_context *nv50) for (unit = 0; unit < nv50->miptree_nr; unit++) { struct nv50_miptree *mt = nv50->miptree[unit]; - for (level = 0; level <= mt->base.last_level; level++) { - for (image = 0; image < mt->image_nr; image++) { - nv50_miptree_sync(&nv50->screen->pipe, mt, - level, image); - } - } - if (nv50_tex_construct(so, mt)) { NOUVEAU_ERR("failed tex validate\n"); so_ref(NULL, &so); @@ -159,5 +152,6 @@ nv50_tex_validate(struct nv50_context *nv50) } so_ref(so, &nv50->state.tic_upload); + so_ref(NULL, &so); } diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c new file mode 100644 index 00000000000..747195b4f63 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -0,0 +1,211 @@ + +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" + +#include "nv50_context.h" + +struct nv50_transfer { + struct pipe_transfer base; + struct pipe_buffer *buffer; + struct nv50_miptree_level *level; + int level_pitch; + int level_width; + int level_height; + int level_x; + int level_y; +}; + +static void +nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src, + int src_pitch, int sx, int sy, int sw, int sh, + struct pipe_buffer *dst, int dst_pitch, int dx, int dy, + int dw, int dh, int cpp, int width, int height, + unsigned src_reloc, unsigned dst_reloc) +{ + struct nv50_screen *screen = nv50_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + struct nouveau_channel *chan = nvws->channel; + struct nouveau_grobj *m2mf = screen->m2mf; + struct nouveau_bo *src_bo = nvws->get_bo(src); + struct nouveau_bo *dst_bo = nvws->get_bo(dst); + unsigned src_offset = 0, dst_offset = 0; + + src_reloc |= NOUVEAU_BO_RD; + dst_reloc |= NOUVEAU_BO_WR; + + WAIT_RING (chan, 14); + + if (!src_bo->tiled) { + BEGIN_RING(chan, m2mf, 0x0200, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, m2mf, 0x0314, 1); + OUT_RING (chan, src_pitch); + src_offset = (sy * src_pitch) + (sx * cpp); + } else { + BEGIN_RING(chan, m2mf, 0x0200, 6); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, sw * cpp); + OUT_RING (chan, sh); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + } + + if (!dst_bo->tiled) { + BEGIN_RING(chan, m2mf, 0x021c, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, m2mf, 0x0318, 1); + OUT_RING (chan, dst_pitch); + dst_offset = (dy * dst_pitch) + (dx * cpp); + } else { + BEGIN_RING(chan, m2mf, 0x021c, 6); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dw * cpp); + OUT_RING (chan, dh); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + } + + while (height) { + int line_count = height > 2047 ? 2047 : height; + + WAIT_RING (chan, 15); + BEGIN_RING(chan, m2mf, 0x0238, 2); + OUT_RELOCh(chan, src_bo, src_offset, src_reloc); + OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc); + BEGIN_RING(chan, m2mf, 0x030c, 2); + OUT_RELOCl(chan, src_bo, src_offset, src_reloc); + OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc); + if (src_bo->tiled) { + BEGIN_RING(chan, m2mf, 0x0218, 1); + OUT_RING (chan, (dy << 16) | sx); + } else { + src_offset += (line_count * src_pitch); + } + if (dst_bo->tiled) { + BEGIN_RING(chan, m2mf, 0x0234, 1); + OUT_RING (chan, (sy << 16) | dx); + } else { + dst_offset += (line_count * dst_pitch); + } + BEGIN_RING(chan, m2mf, 0x031c, 4); + OUT_RING (chan, width * cpp); + OUT_RING (chan, line_count); + OUT_RING (chan, 0x00000101); + OUT_RING (chan, 0); + FIRE_RING (chan); + + height -= line_count; + sy += line_count; + dy += line_count; + } +} + +static struct pipe_transfer * +nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + enum pipe_transfer_usage usage, + unsigned x, unsigned y, unsigned w, unsigned h) +{ + struct nv50_miptree *mt = nv50_miptree(pt); + struct nv50_miptree_level *lvl = &mt->level[level]; + struct nv50_transfer *tx; + unsigned image = 0; + + if (pt->target == PIPE_TEXTURE_CUBE) + image = face; + else + if (pt->target == PIPE_TEXTURE_3D) + image = zslice; + + tx = CALLOC_STRUCT(nv50_transfer); + if (!tx) + return NULL; + + pipe_texture_reference(&tx->base.texture, pt); + tx->base.format = pt->format; + tx->base.width = w; + tx->base.height = h; + tx->base.block = pt->block; + tx->base.nblocksx = pt->nblocksx[level]; + tx->base.nblocksy = pt->nblocksy[level]; + tx->base.stride = (w * pt->block.size); + tx->base.usage = usage; + + tx->level = lvl; + tx->level_pitch = lvl->pitch; + tx->level_width = mt->base.width[level]; + tx->level_height = mt->base.height[level]; + tx->level_x = x; + tx->level_y = y; + tx->buffer = + pipe_buffer_create(pscreen, 0, NOUVEAU_BUFFER_USAGE_TRANSFER, + w * tx->base.block.size * h); + + if (usage != PIPE_TRANSFER_WRITE) { + nv50_transfer_rect_m2mf(pscreen, mt->buffer, tx->level_pitch, + x, y, tx->level_width, tx->level_height, + tx->buffer, tx->base.stride, 0, 0, + tx->base.width, tx->base.height, + tx->base.block.size, w, h, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, + NOUVEAU_BO_GART); + } + + return &tx->base; +} + +static void +nv50_transfer_del(struct pipe_transfer *ptx) +{ + struct nv50_transfer *tx = (struct nv50_transfer *)ptx; + struct nv50_miptree *mt = nv50_miptree(ptx->texture); + + if (ptx->usage != PIPE_TRANSFER_READ) { + struct pipe_screen *pscreen = ptx->texture->screen; + nv50_transfer_rect_m2mf(pscreen, tx->buffer, tx->base.stride, + 0, 0, tx->base.width, tx->base.height, + mt->buffer, tx->level_pitch, + tx->level_x, tx->level_y, + tx->level_width, tx->level_height, + tx->base.block.size, tx->base.width, + tx->base.height, NOUVEAU_BO_GART, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART); + } + + pipe_buffer_reference(&tx->buffer, NULL); + pipe_texture_reference(&ptx->texture, NULL); + FREE(ptx); +} + +static void * +nv50_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) +{ + struct nv50_transfer *tx = (struct nv50_transfer *)ptx; + unsigned flags = 0; + + if (ptx->usage & PIPE_TRANSFER_WRITE) + flags |= PIPE_BUFFER_USAGE_CPU_WRITE; + if (ptx->usage & PIPE_TRANSFER_READ) + flags |= PIPE_BUFFER_USAGE_CPU_READ; + + return pipe_buffer_map(pscreen, tx->buffer, flags); +} + +static void +nv50_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) +{ + struct nv50_transfer *tx = (struct nv50_transfer *)ptx; + + pipe_buffer_unmap(pscreen, tx->buffer); +} + +void +nv50_transfer_init_screen_functions(struct pipe_screen *pscreen) +{ + pscreen->get_tex_transfer = nv50_transfer_new; + pscreen->tex_transfer_destroy = nv50_transfer_del; + pscreen->transfer_map = nv50_transfer_map; + pscreen->transfer_unmap = nv50_transfer_unmap; +} diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 0c970adb03a..0749c906914 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -202,7 +202,7 @@ nv50_vbo_validate(struct nv50_context *nv50) { struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_stateobj *vtxbuf, *vtxfmt; - int i, vpi = 0; + int i; vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2); vtxfmt = so_new(nv50->vtxelt_nr + 1, 0); @@ -250,5 +250,7 @@ nv50_vbo_validate(struct nv50_context *nv50) so_ref (vtxfmt, &nv50->state.vtxfmt); so_ref (vtxbuf, &nv50->state.vtxbuf); + so_ref (NULL, &vtxbuf); + so_ref (NULL, &vtxfmt); } |