mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-10 03:50:13 +01:00
nvfx: new 2D: unify textures and buffers
Stop using the vtbl, and use real transfers for buffers too.
This commit is contained in:
parent
0481ed25c9
commit
4e2080a86e
4 changed files with 46 additions and 137 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue