Stop using the vtbl, and use real transfers for buffers too.tags/mesa-7.9-rc1
| @@ -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; | |||
| } | |||
| @@ -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, | |||
| @@ -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; | |||
| } | |||
| @@ -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, | |||