nv40: some cleanups

This commit is contained in:
Ben Skeggs 2008-01-02 23:44:24 +11:00
parent 720fd7b5e9
commit 732540f997
4 changed files with 136 additions and 119 deletions

View 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;
}

View 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;

View 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;
struct nv40_query *q;
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;
q = calloc(1, sizeof(struct nv40_query));
q->type = query_type;
nv40query = malloc(sizeof(struct nv40_query));
nv40query->type = query_type;
nv40query->id = id;
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;
}

View file

@ -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;
}