nvfx: new 2D: unify textures and buffers
authorLuca Barbieri <luca@luca-barbieri.com>
Tue, 3 Aug 2010 20:49:19 +0000 (22:49 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Sat, 21 Aug 2010 18:42:14 +0000 (20:42 +0200)
Stop using the vtbl, and use real transfers for buffers too.

src/gallium/drivers/nvfx/nvfx_buffer.c
src/gallium/drivers/nvfx/nvfx_miptree.c
src/gallium/drivers/nvfx/nvfx_resource.c
src/gallium/drivers/nvfx/nvfx_resource.h

index 4482d96..44680e5 100644 (file)
@@ -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;
 }
-
index 530d705..559e832 100644 (file)
@@ -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,
index 10cdeed..1c921b4 100644 (file)
@@ -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;
 }
index be1845d..ff86f6d 100644 (file)
 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,