From 4e2080a86e0cbb93c72bbf4acace53867fac8276 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Tue, 3 Aug 2010 22:49:19 +0200 Subject: [PATCH] nvfx: new 2D: unify textures and buffers Stop using the vtbl, and use real transfers for buffers too. --- src/gallium/drivers/nvfx/nvfx_buffer.c | 77 +------------------------------- src/gallium/drivers/nvfx/nvfx_miptree.c | 35 +-------------- src/gallium/drivers/nvfx/nvfx_resource.c | 55 ++++++++++++++--------- src/gallium/drivers/nvfx/nvfx_resource.h | 16 +++---- 4 files changed, 46 insertions(+), 137 deletions(-) diff --git a/src/gallium/drivers/nvfx/nvfx_buffer.c b/src/gallium/drivers/nvfx/nvfx_buffer.c index 4482d96..44680e5 100644 --- a/src/gallium/drivers/nvfx/nvfx_buffer.c +++ b/src/gallium/drivers/nvfx/nvfx_buffer.c @@ -7,13 +7,7 @@ #include "nouveau/nouveau_winsys.h" #include "nvfx_resource.h" - -/* Currently using separate implementations for buffers and textures, - * even though gallium has a unified abstraction of these objects. - * Eventually these should be combined, and mechanisms like transfers - * be adapted to work for both buffer and texture uploads. - */ -static void nvfx_buffer_destroy(struct pipe_screen *pscreen, +void nvfx_buffer_destroy(struct pipe_screen *pscreen, struct pipe_resource *presource) { struct nvfx_resource *buffer = nvfx_resource(presource); @@ -22,70 +16,6 @@ static void nvfx_buffer_destroy(struct pipe_screen *pscreen, FREE(buffer); } - - - -/* Utility functions for transfer create/destroy are hooked in and - * just record the arguments to those functions. - */ -static void * -nvfx_buffer_transfer_map( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - struct nvfx_resource *buffer = nvfx_resource(transfer->resource); - uint8_t *map; - - map = nouveau_screen_bo_map_range( pipe->screen, - buffer->bo, - transfer->box.x, - transfer->box.width, - nouveau_screen_transfer_flags(transfer->usage) ); - if (map == NULL) - return NULL; - - return map + transfer->box.x; -} - - - -static void nvfx_buffer_transfer_flush_region( struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct nvfx_resource *buffer = nvfx_resource(transfer->resource); - - nouveau_screen_bo_map_flush_range(pipe->screen, - buffer->bo, - transfer->box.x + box->x, - box->width); -} - -static void nvfx_buffer_transfer_unmap( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - struct nvfx_resource *buffer = nvfx_resource(transfer->resource); - - nouveau_screen_bo_unmap(pipe->screen, buffer->bo); -} - - - - -struct u_resource_vtbl nvfx_buffer_vtbl = -{ - u_default_resource_get_handle, /* get_handle */ - nvfx_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - u_default_get_transfer, /* get_transfer */ - u_default_transfer_destroy, /* transfer_destroy */ - nvfx_buffer_transfer_map, /* transfer_map */ - nvfx_buffer_transfer_flush_region, /* transfer_flush_region */ - nvfx_buffer_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ -}; - - - struct pipe_resource * nvfx_buffer_create(struct pipe_screen *pscreen, const struct pipe_resource *template) @@ -98,7 +28,6 @@ nvfx_buffer_create(struct pipe_screen *pscreen, buffer->base = *template; buffer->base.flags |= NVFX_RESOURCE_FLAG_LINEAR; - buffer->vtbl = &nvfx_buffer_vtbl; pipe_reference_init(&buffer->base.reference, 1); buffer->base.screen = pscreen; @@ -132,7 +61,6 @@ nvfx_user_buffer_create(struct pipe_screen *pscreen, return NULL; pipe_reference_init(&buffer->base.reference, 1); - buffer->vtbl = &nvfx_buffer_vtbl; buffer->base.flags = NVFX_RESOURCE_FLAG_LINEAR; buffer->base.screen = pscreen; buffer->base.format = PIPE_FORMAT_R8_UNORM; @@ -145,11 +73,10 @@ nvfx_user_buffer_create(struct pipe_screen *pscreen, buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes); if (!buffer->bo) goto fail; - + return &buffer->base; fail: FREE(buffer); return NULL; } - diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c index 530d705..559e832 100644 --- a/src/gallium/drivers/nvfx/nvfx_miptree.c +++ b/src/gallium/drivers/nvfx/nvfx_miptree.c @@ -98,23 +98,6 @@ nvfx_miptree_layout(struct nvfx_miptree *mt) return offset; } -static boolean -nvfx_miptree_get_handle(struct pipe_screen *pscreen, - struct pipe_resource *ptexture, - struct winsys_handle *whandle) -{ - struct nvfx_miptree* mt = (struct nvfx_miptree*)ptexture; - - if (!mt || !mt->base.bo) - return FALSE; - - return nouveau_screen_bo_get_handle(pscreen, - mt->base.bo, - mt->linear_pitch, - whandle); -} - - static void nvfx_miptree_surface_final_destroy(struct pipe_surface* ps) { @@ -124,7 +107,7 @@ nvfx_miptree_surface_final_destroy(struct pipe_surface* ps) FREE(ps); } -static void +void nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt) { struct nvfx_miptree *mt = (struct nvfx_miptree *)pt; @@ -133,19 +116,6 @@ nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt) FREE(mt); } -struct u_resource_vtbl nvfx_miptree_vtbl = -{ - nvfx_miptree_get_handle, /* get_handle */ - nvfx_miptree_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - nvfx_transfer_new, /* get_transfer */ - util_staging_transfer_destroy, /* transfer_destroy */ - nvfx_transfer_map, /* transfer_map */ - u_default_transfer_flush_region, /* transfer_flush_region */ - nvfx_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ -}; - static struct nvfx_miptree* nvfx_miptree_create_skeleton(struct pipe_screen *pscreen, const struct pipe_resource *pt) { @@ -159,7 +129,6 @@ nvfx_miptree_create_skeleton(struct pipe_screen *pscreen, const struct pipe_reso return NULL; mt->base.base = *pt; - mt->base.vtbl = &nvfx_miptree_vtbl; util_dirty_surfaces_init(&mt->dirty_surfaces); pipe_reference_init(&mt->base.base.reference, 1); @@ -221,8 +190,6 @@ nvfx_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource return &mt->base.base; } -/* Surface helpers, not strictly required to implement the resource vtbl: - */ struct pipe_surface * nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, diff --git a/src/gallium/drivers/nvfx/nvfx_resource.c b/src/gallium/drivers/nvfx/nvfx_resource.c index 10cdeed..1c921b4 100644 --- a/src/gallium/drivers/nvfx/nvfx_resource.c +++ b/src/gallium/drivers/nvfx/nvfx_resource.c @@ -1,23 +1,16 @@ #include "pipe/p_context.h" +#include "util/u_staging.h" #include "nvfx_resource.h" +#include "nvfx_transfer.h" #include "nouveau/nouveau_screen.h" - -/* This doesn't look quite right - this query is supposed to ask - * whether the particular context has references to the resource in - * any unflushed rendering command buffer, and hence requires a - * pipe->flush() for serializing some modification to that resource. - * - * This seems to be answering the question of whether the resource is - * currently on hardware. - */ static unsigned int nvfx_resource_is_referenced(struct pipe_context *pipe, - struct pipe_resource *resource, + struct pipe_resource *pr, unsigned face, unsigned level) { - return nouveau_reference_flags(nvfx_resource(resource)->bo); + return !!nouveau_reference_flags(nvfx_resource(pr)->bo); } static struct pipe_resource * @@ -30,6 +23,15 @@ nvfx_resource_create(struct pipe_screen *screen, return nvfx_miptree_create(screen, template); } +static void +nvfx_resource_destroy(struct pipe_screen *screen, struct pipe_resource *pr) +{ + if (pr->target == PIPE_BUFFER) + return nvfx_buffer_destroy(screen, pr); + else + return nvfx_miptree_destroy(screen, pr); +} + static struct pipe_resource * nvfx_resource_from_handle(struct pipe_screen * screen, const struct pipe_resource *template, @@ -41,15 +43,28 @@ nvfx_resource_from_handle(struct pipe_screen * screen, return nvfx_miptree_from_handle(screen, template, whandle); } +static boolean +nvfx_resource_get_handle(struct pipe_screen *pscreen, + struct pipe_resource *pr, + struct winsys_handle *whandle) +{ + struct nvfx_resource* res = (struct nvfx_resource*)pr; + + if (!res || !res->bo) + return FALSE; + + return nouveau_screen_bo_get_handle(pscreen, res->bo, nvfx_subresource_pitch(pr, 0), whandle); +} + void nvfx_init_resource_functions(struct pipe_context *pipe) { - pipe->get_transfer = u_get_transfer_vtbl; - pipe->transfer_map = u_transfer_map_vtbl; - pipe->transfer_flush_region = u_transfer_flush_region_vtbl; - pipe->transfer_unmap = u_transfer_unmap_vtbl; - pipe->transfer_destroy = u_transfer_destroy_vtbl; - pipe->transfer_inline_write = u_transfer_inline_write_vtbl; + pipe->get_transfer = nvfx_transfer_new; + pipe->transfer_map = nvfx_transfer_map; + pipe->transfer_flush_region = u_default_transfer_flush_region; + pipe->transfer_unmap = nvfx_transfer_unmap; + pipe->transfer_destroy = util_staging_transfer_destroy; + pipe->transfer_inline_write = u_default_transfer_inline_write; pipe->is_resource_referenced = nvfx_resource_is_referenced; } @@ -58,10 +73,10 @@ nvfx_screen_init_resource_functions(struct pipe_screen *pscreen) { pscreen->resource_create = nvfx_resource_create; pscreen->resource_from_handle = nvfx_resource_from_handle; - pscreen->resource_get_handle = u_resource_get_handle_vtbl; - pscreen->resource_destroy = u_resource_destroy_vtbl; + pscreen->resource_get_handle = nvfx_resource_get_handle; + pscreen->resource_destroy = nvfx_resource_destroy; pscreen->user_buffer_create = nvfx_user_buffer_create; - + pscreen->get_tex_surface = nvfx_miptree_surface_new; pscreen->tex_surface_destroy = nvfx_miptree_surface_del; } diff --git a/src/gallium/drivers/nvfx/nvfx_resource.h b/src/gallium/drivers/nvfx/nvfx_resource.h index be1845d..ff86f6d 100644 --- a/src/gallium/drivers/nvfx/nvfx_resource.h +++ b/src/gallium/drivers/nvfx/nvfx_resource.h @@ -12,16 +12,8 @@ struct pipe_resource; struct nv04_region; - -/* This gets further specialized into either buffer or texture - * structures. In the future we'll want to remove much of that - * distinction, but for now try to keep as close to the existing code - * as possible and use the vtbl struct to choose between the two - * underlying implementations. - */ struct nvfx_resource { struct pipe_resource base; - struct u_resource_vtbl *vtbl; struct nouveau_bo *bo; }; @@ -105,6 +97,10 @@ nvfx_screen_init_resource_functions(struct pipe_screen *pscreen); struct pipe_resource * nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt); +void +nvfx_miptree_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource); + struct pipe_resource * nvfx_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, @@ -114,6 +110,10 @@ struct pipe_resource * nvfx_buffer_create(struct pipe_screen *pscreen, const struct pipe_resource *template); +void +nvfx_buffer_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource); + struct pipe_resource * nvfx_user_buffer_create(struct pipe_screen *screen, void *ptr, -- 2.7.4