Import a classic DRI driver for nv0x-nv2x.
[mesa.git] / src / mesa / drivers / dri / nouveau / nv04_screen.c
1 /*
2 * Copyright (C) 2009 Francisco Jerez.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27 #include "nouveau_driver.h"
28 #include "nouveau_screen.h"
29 #include "nouveau_class.h"
30 #include "nv04_driver.h"
31
32 static const struct nouveau_driver nv04_driver;
33
34 static void
35 nv04_hwctx_init(struct nouveau_screen *screen)
36 {
37 struct nouveau_channel *chan = screen->chan;
38 struct nouveau_grobj *surf3d = screen->surf3d;
39 struct nouveau_grobj *eng3d = screen->eng3d;
40 struct nouveau_grobj *eng3dm = screen->eng3dm;
41
42 BIND_RING(chan, surf3d, 7);
43 BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3);
44 OUT_RING(chan, screen->ntfy->handle);
45 OUT_RING(chan, chan->vram->handle);
46 OUT_RING(chan, chan->vram->handle);
47
48 BEGIN_RING(chan, eng3d, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY, 4);
49 OUT_RING(chan, screen->ntfy->handle);
50 OUT_RING(chan, chan->vram->handle);
51 OUT_RING(chan, chan->gart->handle);
52 OUT_RING(chan, surf3d->handle);
53
54 BEGIN_RING(chan, eng3dm, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY, 4);
55 OUT_RING(chan, screen->ntfy->handle);
56 OUT_RING(chan, chan->vram->handle);
57 OUT_RING(chan, chan->gart->handle);
58 OUT_RING(chan, surf3d->handle);
59
60 FIRE_RING(chan);
61 }
62
63 static void
64 nv04_channel_flush_notify(struct nouveau_channel *chan)
65 {
66 struct nouveau_screen *screen = chan->user_private;
67 struct nouveau_context *nctx = screen->context;
68
69 if (nctx && nctx->fallback < SWRAST) {
70 GLcontext *ctx = &nctx->base;
71
72 /* Flushing seems to clobber the engine context. */
73 context_dirty_i(ctx, TEX_OBJ, 0);
74 context_dirty_i(ctx, TEX_OBJ, 1);
75 context_dirty_i(ctx, TEX_ENV, 0);
76 context_dirty_i(ctx, TEX_ENV, 1);
77 context_dirty(ctx, CONTROL);
78 context_dirty(ctx, BLEND);
79
80 nouveau_state_emit(ctx);
81 }
82 }
83
84 GLboolean
85 nv04_screen_init(struct nouveau_screen *screen)
86 {
87 int ret;
88
89 screen->driver = &nv04_driver;
90 screen->chan->flush_notify = nv04_channel_flush_notify;
91
92 /* 2D engine. */
93 ret = nv04_surface_init(screen);
94 if (!ret)
95 return GL_FALSE;
96
97 /* 3D engine. */
98 ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001,
99 NV04_TEXTURED_TRIANGLE, &screen->eng3d);
100 if (ret)
101 return GL_FALSE;
102
103 ret = nouveau_grobj_alloc(screen->chan, 0xbeef0002,
104 NV04_MULTITEX_TRIANGLE, &screen->eng3dm);
105 if (ret)
106 return GL_FALSE;
107
108 ret = nouveau_grobj_alloc(screen->chan, 0xbeef0003,
109 NV04_CONTEXT_SURFACES_3D, &screen->surf3d);
110 if (ret)
111 return GL_FALSE;
112
113 nv04_hwctx_init(screen);
114
115 return GL_TRUE;
116 }
117
118 static void
119 nv04_screen_destroy(struct nouveau_screen *screen)
120 {
121 if (screen->eng3d)
122 nouveau_grobj_free(&screen->eng3d);
123
124 if (screen->eng3dm)
125 nouveau_grobj_free(&screen->eng3dm);
126
127 if (screen->surf3d)
128 nouveau_grobj_free(&screen->surf3d);
129
130 nv04_surface_takedown(screen);
131 }
132
133 static const struct nouveau_driver nv04_driver = {
134 .screen_destroy = nv04_screen_destroy,
135 .context_create = nv04_context_create,
136 .context_destroy = nv04_context_destroy,
137 .surface_copy = nv04_surface_copy,
138 .surface_fill = nv04_surface_fill,
139 .emit = (nouveau_state_func[]) {
140 nv04_defer_control,
141 nouveau_emit_nothing,
142 nv04_defer_blend,
143 nv04_defer_blend,
144 nouveau_emit_nothing,
145 nouveau_emit_nothing,
146 nouveau_emit_nothing,
147 nouveau_emit_nothing,
148 nouveau_emit_nothing,
149 nouveau_emit_nothing,
150 nv04_defer_control,
151 nouveau_emit_nothing,
152 nv04_defer_control,
153 nouveau_emit_nothing,
154 nv04_defer_control,
155 nv04_defer_control,
156 nouveau_emit_nothing,
157 nv04_emit_framebuffer,
158 nv04_defer_blend,
159 nouveau_emit_nothing,
160 nouveau_emit_nothing,
161 nouveau_emit_nothing,
162 nouveau_emit_nothing,
163 nouveau_emit_nothing,
164 nouveau_emit_nothing,
165 nouveau_emit_nothing,
166 nouveau_emit_nothing,
167 nouveau_emit_nothing,
168 nouveau_emit_nothing,
169 nouveau_emit_nothing,
170 nouveau_emit_nothing,
171 nouveau_emit_nothing,
172 nouveau_emit_nothing,
173 nouveau_emit_nothing,
174 nouveau_emit_nothing,
175 nouveau_emit_nothing,
176 nouveau_emit_nothing,
177 nouveau_emit_nothing,
178 nouveau_emit_nothing,
179 nouveau_emit_nothing,
180 nouveau_emit_nothing,
181 nouveau_emit_nothing,
182 nouveau_emit_nothing,
183 nouveau_emit_nothing,
184 nouveau_emit_nothing,
185 nouveau_emit_nothing,
186 nouveau_emit_nothing,
187 nouveau_emit_nothing,
188 nouveau_emit_nothing,
189 nv04_emit_scissor,
190 nv04_defer_blend,
191 nv04_defer_control,
192 nv04_defer_control,
193 nv04_defer_control,
194 nv04_emit_tex_env,
195 nv04_emit_tex_env,
196 nouveau_emit_nothing,
197 nouveau_emit_nothing,
198 nouveau_emit_nothing,
199 nouveau_emit_nothing,
200 nouveau_emit_nothing,
201 nouveau_emit_nothing,
202 nv04_emit_tex_obj,
203 nv04_emit_tex_obj,
204 nouveau_emit_nothing,
205 nouveau_emit_nothing,
206 nouveau_emit_nothing,
207 nv04_emit_blend,
208 nv04_emit_control,
209 },
210 .num_emit = NUM_NV04_STATE,
211 };