summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-01-02 23:44:24 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-01-02 23:44:24 +1100
commit732540f997ef0501ccbc1237148bc44aaba38d66 (patch)
tree2e1f4ac9634df9da2700246105b043d5355d7450
parent720fd7b5e993c7e77e5b1fc75edeedd110532e0e (diff)
nv40: some cleanups
-rw-r--r--src/mesa/pipe/nv40/nv40_context.c107
-rw-r--r--src/mesa/pipe/nv40/nv40_context.h3
-rw-r--r--src/mesa/pipe/nv40/nv40_query.c87
-rw-r--r--src/mesa/pipe/nv40/nv40_surface.c60
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;
}