summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50/nv50_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_context.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
new file mode 100644
index 0000000000..e5054e34f6
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -0,0 +1,122 @@
+#include "draw/draw_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_winsys.h"
+#include "pipe/p_util.h"
+
+#include "nv50_context.h"
+#include "nv50_screen.h"
+
+static void
+nv50_flush(struct pipe_context *pipe, unsigned flags)
+{
+ struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nouveau_winsys *nvws = nv50->nvws;
+
+ if (flags & PIPE_FLUSH_WAIT) {
+ nvws->notifier_reset(nv50->sync, 0);
+ BEGIN_RING(tesla, 0x104, 1);
+ OUT_RING (0);
+ BEGIN_RING(tesla, 0x100, 1);
+ OUT_RING (0);
+ }
+
+ FIRE_RING();
+
+ if (flags & PIPE_FLUSH_WAIT)
+ nvws->notifier_wait(nv50->sync, 0, 0, 2000);
+}
+
+static void
+nv50_destroy(struct pipe_context *pipe)
+{
+ struct nv50_context *nv50 = (struct nv50_context *)pipe;
+
+ draw_destroy(nv50->draw);
+ free(nv50);
+}
+
+static boolean
+nv50_init_hwctx(struct nv50_context *nv50, int tesla_class)
+{
+ struct nouveau_winsys *nvws = nv50->nvws;
+ int ret;
+
+ if ((ret = nvws->grobj_alloc(nvws, tesla_class, &nv50->tesla))) {
+ NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
+ return FALSE;
+ }
+
+ BEGIN_RING(tesla, NV50TCL_DMA_NOTIFY, 1);
+ OUT_RING (nv50->sync->handle);
+
+ FIRE_RING ();
+ return TRUE;
+}
+
+#define GRCLASS5097_CHIPSETS 0x00000000
+#define GRCLASS8297_CHIPSETS 0x00000010
+struct pipe_context *
+nv50_create(struct pipe_screen *pscreen)
+{
+ struct pipe_winsys *pipe_winsys = pscreen->winsys;
+ struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
+ unsigned chipset = nv50_screen(pscreen)->chipset;
+ struct nv50_context *nv50;
+ int tesla_class, ret;
+
+ if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
+ NOUVEAU_ERR("Not a G8x chipset\n");
+ return NULL;
+ }
+
+ if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) {
+ tesla_class = 0x5097;
+ } else
+ if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) {
+ tesla_class = 0x8297;
+ } else {
+ NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
+ return NULL;
+ }
+
+ nv50 = CALLOC_STRUCT(nv50_context);
+ if (!nv50)
+ return NULL;
+ nv50->chipset = chipset;
+ nv50->nvws = nvws;
+
+ if ((ret = nvws->notifier_alloc(nvws, 1, &nv50->sync))) {
+ NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
+ free(nv50);
+ return NULL;
+ }
+
+ if (!nv50_init_hwctx(nv50, tesla_class)) {
+ free(nv50);
+ return NULL;
+ }
+
+ nv50->pipe.winsys = pipe_winsys;
+ nv50->pipe.screen = pscreen;
+
+ nv50->pipe.destroy = nv50_destroy;
+
+ nv50->pipe.draw_arrays = nv50_draw_arrays;
+ nv50->pipe.draw_elements = nv50_draw_elements;
+ nv50->pipe.clear = nv50_clear;
+
+ nv50->pipe.flush = nv50_flush;
+
+ nv50_init_miptree_functions(nv50);
+ nv50_init_surface_functions(nv50);
+ nv50_init_state_functions(nv50);
+ nv50_init_query_functions(nv50);
+
+ nv50->draw = draw_create();
+ assert(nv50->draw);
+ draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
+
+ return &nv50->pipe;
+}
+
+