Stop using the vtbl, and use real transfers for buffers too.
#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);
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)
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;
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;
buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
if (!buffer->bo)
goto fail;
-
+
return &buffer->base;
fail:
FREE(buffer);
return NULL;
}
-
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)
{
FREE(ps);
}
-static void
+void
nvfx_miptree_destroy(struct pipe_screen *screen, struct pipe_resource *pt)
{
struct nvfx_miptree *mt = (struct nvfx_miptree *)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)
{
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);
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,
#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 *
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,
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;
}
{
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;
}
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;
};
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,
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,