diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2008-01-02 23:44:24 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2008-01-02 23:44:24 +1100 |
commit | 732540f997ef0501ccbc1237148bc44aaba38d66 (patch) | |
tree | 2e1f4ac9634df9da2700246105b043d5355d7450 | |
parent | 720fd7b5e993c7e77e5b1fc75edeedd110532e0e (diff) |
nv40: some cleanups
-rw-r--r-- | src/mesa/pipe/nv40/nv40_context.c | 107 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_context.h | 3 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_query.c | 87 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_surface.c | 60 |
4 files changed, 137 insertions, 120 deletions
diff --git a/src/mesa/pipe/nv40/nv40_context.c b/src/mesa/pipe/nv40/nv40_context.c index e7d0a18637..442ff04e75 100644 --- a/src/mesa/pipe/nv40/nv40_context.c +++ b/src/mesa/pipe/nv40/nv40_context.c @@ -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; } - - + diff --git a/src/mesa/pipe/nv40/nv40_context.h b/src/mesa/pipe/nv40/nv40_context.h index 934f68ef1a..975b1096cc 100644 --- a/src/mesa/pipe/nv40/nv40_context.h +++ b/src/mesa/pipe/nv40/nv40_context.h @@ -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; diff --git a/src/mesa/pipe/nv40/nv40_query.c b/src/mesa/pipe/nv40/nv40_query.c index f51b34b119..6e5fcae8ca 100644 --- a/src/mesa/pipe/nv40/nv40_query.c +++ b/src/mesa/pipe/nv40/nv40_query.c @@ -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; } diff --git a/src/mesa/pipe/nv40/nv40_surface.c b/src/mesa/pipe/nv40/nv40_surface.c index 6a16a280c2..ed144c636c 100644 --- a/src/mesa/pipe/nv40/nv40_surface.c +++ b/src/mesa/pipe/nv40/nv40_surface.c @@ -33,9 +33,48 @@ #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; } |