nv40: some cleanups
authorBen Skeggs <skeggsb@gmail.com>
Wed, 2 Jan 2008 12:44:24 +0000 (23:44 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Wed, 2 Jan 2008 12:44:24 +0000 (23:44 +1100)
src/mesa/pipe/nv40/nv40_context.c
src/mesa/pipe/nv40/nv40_context.h
src/mesa/pipe/nv40/nv40_query.c
src/mesa/pipe/nv40/nv40_surface.c

index e7d0a18..442ff04 100644 (file)
@@ -6,46 +6,6 @@
 #include "nv40_context.h"
 #include "nv40_dma.h"
 
-static boolean
-nv40_is_format_supported(struct pipe_context *pipe, enum pipe_format format,
-                        uint type)
-{
-       switch (type) {
-       case PIPE_SURFACE:
-               switch (format) {
-               case PIPE_FORMAT_A8R8G8B8_UNORM:
-               case PIPE_FORMAT_R5G6B5_UNORM: 
-               case PIPE_FORMAT_Z24S8_UNORM:
-               case PIPE_FORMAT_Z16_UNORM:
-                       return TRUE;
-               default:
-                       break;
-               }
-               break;
-       case PIPE_TEXTURE:
-               switch (format) {
-               case PIPE_FORMAT_A8R8G8B8_UNORM:
-               case PIPE_FORMAT_A1R5G5B5_UNORM:
-               case PIPE_FORMAT_A4R4G4B4_UNORM:
-               case PIPE_FORMAT_R5G6B5_UNORM: 
-               case PIPE_FORMAT_U_L8:
-               case PIPE_FORMAT_U_A8:
-               case PIPE_FORMAT_U_I8:
-               case PIPE_FORMAT_U_A8_L8:
-               case PIPE_FORMAT_Z16_UNORM:
-               case PIPE_FORMAT_Z24S8_UNORM:
-                       return TRUE;
-               default:
-                       break;
-               }
-               break;
-       default:
-               assert(0);
-       };
-
-       return FALSE;
-}
-
 static const char *
 nv40_get_name(struct pipe_context *pipe)
 {
@@ -149,8 +109,21 @@ static void
 nv40_destroy(struct pipe_context *pipe)
 {
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
+       struct nouveau_winsys *nvws = nv40->nvws;
+
+       if (nv40->draw)
+               draw_destroy(nv40->draw);
+
+       nvws->res_free(&nv40->vertprog.exec_heap);
+       nvws->res_free(&nv40->vertprog.data_heap);
+
+       nvws->res_free(&nv40->query_heap);
+       nvws->notifier_free(&nv40->query);
+
+       nvws->notifier_free(&nv40->sync);
+
+       nvws->grobj_free(&nv40->curie);
 
-       draw_destroy(nv40->draw);
        free(nv40);
 }
 
@@ -160,14 +133,8 @@ nv40_init_hwctx(struct nv40_context *nv40, int curie_class)
        struct nouveau_winsys *nvws = nv40->nvws;
        int ret;
 
-       if ((ret = nvws->notifier_alloc(nvws, nv40->num_query_objects,
-                                       &nv40->query))) {
-               NOUVEAU_ERR("Error creating query notifier objects: %d\n", ret);
-               return FALSE;
-       }
-
-       if ((ret = nvws->grobj_alloc(nvws, curie_class,
-                                    &nv40->curie))) {
+       ret = nvws->grobj_alloc(nvws, curie_class, &nv40->curie);
+       if (ret) {
                NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
                return FALSE;
        }
@@ -237,12 +204,12 @@ nv40_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
        }
 
        if (GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) {
-               curie_class = 0x4097;
+               curie_class = NV40TCL;
        } else
        if (GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) {
-               curie_class = 0x4497;
+               curie_class = NV44TCL;
        } else {
-               NOUVEAU_ERR("Unknown NV4X chipset: NV%02x\n", chipset);
+               NOUVEAU_ERR("Unknown NV4x chipset: NV%02x\n", chipset);
                return NULL;
        }
 
@@ -252,37 +219,46 @@ nv40_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
        nv40->chipset = chipset;
        nv40->nvws = nvws;
 
-       if ((ret = nvws->notifier_alloc(nvws, 1, &nv40->sync))) {
+       /* Notifier for sync purposes */
+       ret = nvws->notifier_alloc(nvws, 1, &nv40->sync);
+       if (ret) {
                NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
-               free(nv40);
+               nv40_destroy(&nv40->pipe);
                return NULL;
        }
 
-       nv40->num_query_objects = 32;
-       nv40->query_objects = calloc(nv40->num_query_objects,
-                                    sizeof(struct pipe_query_object *));
-       if (!nv40->query_objects) {
-               free(nv40);
+       /* Query objects */
+       ret = nvws->notifier_alloc(nvws, 32, &nv40->query);
+       if (ret) {
+               NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
+               nv40_destroy(&nv40->pipe);
                return NULL;
        }
 
+       ret = nvws->res_init(&nv40->query_heap, 0, 32);
+       if (ret) {
+               NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
+               nv40_destroy(&nv40->pipe);
+               return NULL;
+       }
+
+       /* Vtxprog resources */
        if (nvws->res_init(&nv40->vertprog.exec_heap, 0, 512) ||
            nvws->res_init(&nv40->vertprog.data_heap, 0, 256)) {
-               nvws->res_free(&nv40->vertprog.exec_heap);
-               nvws->res_free(&nv40->vertprog.data_heap);
-               free(nv40);
+               nv40_destroy(&nv40->pipe);
                return NULL;
        }
 
+       /* Static curie initialisation */
        if (!nv40_init_hwctx(nv40, curie_class)) {
-               free(nv40);
+               nv40_destroy(&nv40->pipe);
                return NULL;
        }
 
+       /* Pipe context setup */
        nv40->pipe.winsys = pipe_winsys;
 
        nv40->pipe.destroy = nv40_destroy;
-       nv40->pipe.is_format_supported = nv40_is_format_supported;
        nv40->pipe.get_name = nv40_get_name;
        nv40->pipe.get_vendor = nv40_get_vendor;
        nv40->pipe.get_param = nv40_get_param;
@@ -305,5 +281,4 @@ nv40_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
 
        return &nv40->pipe;
 }
-
-               
+       
index 934f68e..975b109 100644 (file)
@@ -34,8 +34,7 @@ struct nv40_context {
 
        /* query objects */
        struct nouveau_notifier *query;
-       boolean *query_objects;
-       uint num_query_objects;
+       struct nouveau_resource *query_heap;
 
        uint32_t dirty;
 
index f51b34b..6e5fcae 100644 (file)
@@ -3,94 +3,97 @@
 #include "nv40_context.h"
 #include "nv40_dma.h"
 
-/*XXX: Maybe go notifier per-query one day?  not sure if PRAMIN space is
- *     plentiful enough however.. */
 struct nv40_query {
+       struct nouveau_resource *object;
        unsigned type;
-       int id;
+       boolean ready;
+       uint64_t result;
 };
 #define nv40_query(o) ((struct nv40_query *)(o))
 
 static struct pipe_query *
 nv40_query_create(struct pipe_context *pipe, unsigned query_type)
 {
-       struct nv40_context *nv40 = nv40_context(pipe);
-       struct nv40_query *nv40query;
-       int id;
-
-       for (id = 0; id < nv40->num_query_objects; id++) {
-               if (nv40->query_objects[id] == 0)
-                       break;
-       }
-       
-       if (id == nv40->num_query_objects)
-               return NULL;
-       nv40->query_objects[id] = TRUE;
+       struct nv40_query *q;
 
-       nv40query = malloc(sizeof(struct nv40_query));
-       nv40query->type = query_type;
-       nv40query->id = id;
+       q = calloc(1, sizeof(struct nv40_query));
+       q->type = query_type;
 
-       return (struct pipe_query *)nv40query;
+       return (struct pipe_query *)q;
 }
 
 static void
-nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *q)
+nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
 {
        struct nv40_context *nv40 = nv40_context(pipe);
-       struct nv40_query *nv40query = nv40_query(q);
+       struct nv40_query *q = nv40_query(pq);
 
-       assert(nv40->query_objects[nv40query->id]);
-       nv40->query_objects[nv40query->id] = FALSE;
-       free(nv40query);
+       if (q->object)
+               nv40->nvws->res_free(&q->object);
+       free(q);
 }
 
 static void
-nv40_query_begin(struct pipe_context *pipe, struct pipe_query *q)
+nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
 {
        struct nv40_context *nv40 = nv40_context(pipe);
-       struct nv40_query *nv40query = nv40_query(q);
+       struct nv40_query *q = nv40_query(pq);
 
-       assert(nv40query->type == PIPE_QUERY_OCCLUSION_COUNTER);
+       assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
-       nv40->nvws->notifier_reset(nv40->query, nv40query->id);
+       if (nv40->nvws->res_alloc(nv40->query_heap, 1, NULL, &q->object))
+               assert(0);
+       nv40->nvws->notifier_reset(nv40->query, q->object->start);
 
        BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1);
        OUT_RING  (1);
        BEGIN_RING(curie, NV40TCL_QUERY_UNK17CC, 1);
        OUT_RING  (1);
+
+       q->ready = FALSE;
 }
 
 static void
-nv40_query_end(struct pipe_context *pipe, struct pipe_query *q)
+nv40_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 {
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
-       struct nv40_query *nv40query = nv40_query(q);
+       struct nv40_query *q = nv40_query(pq);
 
        BEGIN_RING(curie, NV40TCL_QUERY_GET, 1);
        OUT_RING  ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) |
-                  ((nv40query->id * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT));
+                  ((q->object->start * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT));
        FIRE_RING();
 }
 
 static boolean
-nv40_query_result(struct pipe_context *pipe, struct pipe_query *q,
+nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq,
                  boolean wait, uint64_t *result)
 {
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
-       struct nv40_query *nv40query = nv40_query(q);
+       struct nv40_query *q = nv40_query(pq);
        struct nouveau_winsys *nvws = nv40->nvws;
-       boolean status;
-
-       status = nvws->notifier_status(nv40->query, nv40query->id);
-       if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
-               if (wait == FALSE)
-                       return FALSE;
-               nvws->notifier_wait(nv40->query, nv40query->id,
-                                   NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
+
+       assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
+
+       if (!q->ready) {
+               unsigned status;
+
+               status = nvws->notifier_status(nv40->query, q->object->start);
+               if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
+                       if (wait == FALSE)
+                               return FALSE;
+                       nvws->notifier_wait(nv40->query, q->object->start,
+                                           NV_NOTIFY_STATE_STATUS_COMPLETED,
+                                           0);
+               }
+
+               q->result = nvws->notifier_retval(nv40->query,
+                                                 q->object->start);
+               q->ready = TRUE;
+               nvws->res_free(&q->object);
        }
 
-       *result = nvws->notifier_retval(nv40->query, nv40query->id);
+       *result = q->result;
        return TRUE;
 }
 
index 6a16a28..ed144c6 100644 (file)
 #include "pipe/p_inlines.h"
 #include "pipe/util/p_tile.h"
 
+static boolean
+nv40_surface_format_supported(struct pipe_context *pipe,
+                             enum pipe_format format, uint type)
+{
+       switch (type) {
+       case PIPE_SURFACE:
+               switch (format) {
+               case PIPE_FORMAT_A8R8G8B8_UNORM:
+               case PIPE_FORMAT_R5G6B5_UNORM: 
+               case PIPE_FORMAT_Z24S8_UNORM:
+               case PIPE_FORMAT_Z16_UNORM:
+                       return TRUE;
+               default:
+                       break;
+               }
+               break;
+       case PIPE_TEXTURE:
+               switch (format) {
+               case PIPE_FORMAT_A8R8G8B8_UNORM:
+               case PIPE_FORMAT_A1R5G5B5_UNORM:
+               case PIPE_FORMAT_A4R4G4B4_UNORM:
+               case PIPE_FORMAT_R5G6B5_UNORM: 
+               case PIPE_FORMAT_U_L8:
+               case PIPE_FORMAT_U_A8:
+               case PIPE_FORMAT_U_I8:
+               case PIPE_FORMAT_U_A8_L8:
+               case PIPE_FORMAT_Z16_UNORM:
+               case PIPE_FORMAT_Z24S8_UNORM:
+                       return TRUE;
+               default:
+                       break;
+               }
+               break;
+       default:
+               assert(0);
+       };
+
+       return FALSE;
+}
+
 static struct pipe_surface *
-nv40_get_tex_surface(struct pipe_context *pipe,
-                     struct pipe_texture *pt,
+nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt,
                      unsigned face, unsigned level, unsigned zslice)
 {
        struct pipe_winsys *ws = pipe->winsys;
@@ -103,12 +142,13 @@ nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
 void
 nv40_init_surface_functions(struct nv40_context *nv40)
 {
-   nv40->pipe.get_tex_surface = nv40_get_tex_surface;
-   nv40->pipe.get_tile = pipe_get_tile_raw;
-   nv40->pipe.put_tile = pipe_put_tile_raw;
-   nv40->pipe.get_tile_rgba = pipe_get_tile_rgba;
-   nv40->pipe.put_tile_rgba = pipe_put_tile_rgba;
-   nv40->pipe.surface_data = nv40_surface_data;
-   nv40->pipe.surface_copy = nv40_surface_copy;
-   nv40->pipe.surface_fill = nv40_surface_fill;
+       nv40->pipe.is_format_supported = nv40_surface_format_supported;
+       nv40->pipe.get_tex_surface = nv40_get_tex_surface;
+       nv40->pipe.get_tile = pipe_get_tile_raw;
+       nv40->pipe.put_tile = pipe_put_tile_raw;
+       nv40->pipe.get_tile_rgba = pipe_get_tile_rgba;
+       nv40->pipe.put_tile_rgba = pipe_put_tile_rgba;
+       nv40->pipe.surface_data = nv40_surface_data;
+       nv40->pipe.surface_copy = nv40_surface_copy;
+       nv40->pipe.surface_fill = nv40_surface_fill;
 }