Merge branch 'upstream-gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / gallium / drivers / nv50 / nv50_context.c
1 #include "draw/draw_context.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_winsys.h"
4 #include "pipe/p_util.h"
5
6 #include "nv50_context.h"
7 #include "nv50_screen.h"
8
9 static void
10 nv50_flush(struct pipe_context *pipe, unsigned flags)
11 {
12 struct nv50_context *nv50 = (struct nv50_context *)pipe;
13 struct nouveau_winsys *nvws = nv50->nvws;
14
15 if (flags & PIPE_FLUSH_WAIT) {
16 nvws->notifier_reset(nv50->sync, 0);
17 BEGIN_RING(tesla, 0x104, 1);
18 OUT_RING (0);
19 BEGIN_RING(tesla, 0x100, 1);
20 OUT_RING (0);
21 }
22
23 FIRE_RING();
24
25 if (flags & PIPE_FLUSH_WAIT)
26 nvws->notifier_wait(nv50->sync, 0, 0, 2000);
27 }
28
29 static void
30 nv50_destroy(struct pipe_context *pipe)
31 {
32 struct nv50_context *nv50 = (struct nv50_context *)pipe;
33
34 draw_destroy(nv50->draw);
35 free(nv50);
36 }
37
38 static boolean
39 nv50_init_hwctx(struct nv50_context *nv50, int tesla_class)
40 {
41 struct nouveau_winsys *nvws = nv50->nvws;
42 int ret;
43
44 if ((ret = nvws->grobj_alloc(nvws, tesla_class, &nv50->tesla))) {
45 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
46 return FALSE;
47 }
48
49 BEGIN_RING(tesla, NV50TCL_DMA_NOTIFY, 1);
50 OUT_RING (nv50->sync->handle);
51
52 FIRE_RING ();
53 return TRUE;
54 }
55
56 #define GRCLASS5097_CHIPSETS 0x00000000
57 #define GRCLASS8297_CHIPSETS 0x00000010
58 struct pipe_context *
59 nv50_create(struct pipe_screen *pscreen)
60 {
61 struct pipe_winsys *pipe_winsys = pscreen->winsys;
62 struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
63 unsigned chipset = nv50_screen(pscreen)->chipset;
64 struct nv50_context *nv50;
65 int tesla_class, ret;
66
67 if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
68 NOUVEAU_ERR("Not a G8x chipset\n");
69 return NULL;
70 }
71
72 if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) {
73 tesla_class = 0x5097;
74 } else
75 if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) {
76 tesla_class = 0x8297;
77 } else {
78 NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
79 return NULL;
80 }
81
82 nv50 = CALLOC_STRUCT(nv50_context);
83 if (!nv50)
84 return NULL;
85 nv50->chipset = chipset;
86 nv50->nvws = nvws;
87
88 if ((ret = nvws->notifier_alloc(nvws, 1, &nv50->sync))) {
89 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
90 free(nv50);
91 return NULL;
92 }
93
94 if (!nv50_init_hwctx(nv50, tesla_class)) {
95 free(nv50);
96 return NULL;
97 }
98
99 nv50->pipe.winsys = pipe_winsys;
100 nv50->pipe.screen = pscreen;
101
102 nv50->pipe.destroy = nv50_destroy;
103
104 nv50->pipe.draw_arrays = nv50_draw_arrays;
105 nv50->pipe.draw_elements = nv50_draw_elements;
106 nv50->pipe.clear = nv50_clear;
107
108 nv50->pipe.flush = nv50_flush;
109
110 nv50_init_miptree_functions(nv50);
111 nv50_init_surface_functions(nv50);
112 nv50_init_state_functions(nv50);
113 nv50_init_query_functions(nv50);
114
115 nv50->draw = draw_create();
116 assert(nv50->draw);
117 draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
118
119 return &nv50->pipe;
120 }
121
122