summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/dri/nouveau/nouveau_context.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-03-02 14:09:57 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-03-02 14:09:57 +1100
commit0a12e4587ccf2c4fa71e93bb00b4582deb99a82c (patch)
tree2106f92166fb8cf8fe93fb6541a9890b0a8f01ac /src/gallium/winsys/dri/nouveau/nouveau_context.c
parent132def0c4182b8d2251e9d6e2b5b470cb806713c (diff)
nouveau: turn pushbuf macros into inline functions
Diffstat (limited to 'src/gallium/winsys/dri/nouveau/nouveau_context.c')
-rw-r--r--src/gallium/winsys/dri/nouveau/nouveau_context.c93
1 files changed, 73 insertions, 20 deletions
diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c
index 01fada5b89..7915afae22 100644
--- a/src/gallium/winsys/dri/nouveau/nouveau_context.c
+++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c
@@ -21,6 +21,75 @@ static const struct dri_debug_control debug_control[] = {
int __nouveau_debug = 0;
#endif
+static void
+nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
+{
+ nouveau_grobj_free(&nvc->NvNull);
+ nouveau_grobj_free(&nvc->NvCtxSurf2D);
+ nouveau_grobj_free(&nvc->NvImageBlit);
+ nouveau_grobj_free(&nvc->NvGdiRect);
+ nouveau_grobj_free(&nvc->NvM2MF);
+ nouveau_grobj_free(&nvc->Nv2D);
+
+ nouveau_notifier_free(&nvc->sync_notifier);
+
+ nouveau_channel_free(&nvc->channel);
+
+ FREE(nvc);
+}
+
+static struct nouveau_channel_context *
+nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset)
+{
+ struct nouveau_channel_context *nvc;
+ int ret;
+
+ nvc = CALLOC_STRUCT(nouveau_channel_context);
+ if (!nvc)
+ return NULL;
+ nvc->chipset = chipset;
+
+ if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002,
+ &nvc->channel))) {
+ NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
+ nouveau_channel_context_destroy(nvc);
+ return NULL;
+ }
+
+ if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30,
+ &nvc->NvNull))) {
+ NOUVEAU_ERR("Error creating NULL object: %d\n", ret);
+ nouveau_channel_context_destroy(nvc);
+ return NULL;
+ }
+ nvc->next_handle = 0x80000000;
+
+ if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1,
+ &nvc->sync_notifier))) {
+ NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret);
+ nouveau_channel_context_destroy(nvc);
+ return NULL;
+ }
+
+ switch (chipset) {
+ case 0x50:
+ case 0x80:
+ ret = nouveau_surface_channel_create_nv50(nvc);
+ break;
+ default:
+ ret = nouveau_surface_channel_create_nv04(nvc);
+ break;
+ }
+
+ if (ret) {
+ NOUVEAU_ERR("Error initialising surface objects: %d\n", ret);
+ nouveau_channel_context_destroy(nvc);
+ return NULL;
+ }
+
+ return nvc;
+}
+
GLboolean
nouveau_context_create(const __GLcontextModes *glVis,
__DRIcontextPrivate *driContextPriv,
@@ -45,13 +114,6 @@ nouveau_context_create(const __GLcontextModes *glVis,
return GL_FALSE;
}
- if ((ret = nouveau_channel_alloc(nv_screen->device,
- 0x8003d001, 0x8003d002,
- &nv->channel))) {
- NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
- return GL_FALSE;
- }
-
driContextPriv->driverPrivate = (void *)nv;
nv->nv_screen = nv_screen;
nv->dri_screen = driScrnPriv;
@@ -101,16 +163,9 @@ nouveau_context_create(const __GLcontextModes *glVis,
nv->frontbuffer = fb_surf;
}
- if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30,
- &nv->NvNull))) {
- NOUVEAU_ERR("Error creating NULL object: %d\n", ret);
- return GL_FALSE;
- }
- nv->next_handle = 0x80000000;
-
- if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1,
- &nv->sync_notifier))) {
- NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret);
+ nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset);
+ if (!nv->nvc) {
+ NOUVEAU_ERR("Failed initialising GPU channel context\n");
return GL_FALSE;
}
@@ -152,9 +207,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
st_flush(nv->st, PIPE_FLUSH_WAIT);
st_destroy_context(nv->st);
- nouveau_grobj_free(&nv->NvCtxSurf2D);
- nouveau_grobj_free(&nv->NvImageBlit);
- nouveau_channel_free(&nv->channel);
+ nouveau_channel_context_destroy(nv->nvc);
free(nv);
}