• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009-2010 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 <stdbool.h>
28 #include "main/state.h"
29 #include "nouveau_driver.h"
30 #include "nouveau_context.h"
31 #include "nouveau_fbo.h"
32 #include "nouveau_util.h"
33 #include "nv_object.xml.h"
34 #include "nv10_3d.xml.h"
35 #include "nv04_driver.h"
36 #include "nv10_driver.h"
37 
38 static GLboolean
use_fast_zclear(struct gl_context * ctx,GLbitfield buffers)39 use_fast_zclear(struct gl_context *ctx, GLbitfield buffers)
40 {
41 	struct nouveau_context *nctx = to_nouveau_context(ctx);
42 	struct gl_framebuffer *fb = ctx->DrawBuffer;
43 
44 	if (buffers & BUFFER_BIT_STENCIL) {
45 		/*
46 		 * The stencil test is bypassed when fast Z clears are
47 		 * enabled.
48 		 */
49 		nctx->hierz.clear_blocked = GL_TRUE;
50 		context_dirty(ctx, ZCLEAR);
51 		return GL_FALSE;
52 	}
53 
54 	return !nctx->hierz.clear_blocked &&
55 		fb->_Xmax == fb->Width && fb->_Xmin == 0 &&
56 		fb->_Ymax == fb->Height && fb->_Ymin == 0;
57 }
58 
59 GLboolean
nv10_use_viewport_zclear(struct gl_context * ctx)60 nv10_use_viewport_zclear(struct gl_context *ctx)
61 {
62 	struct nouveau_context *nctx = to_nouveau_context(ctx);
63 	struct gl_framebuffer *fb = ctx->DrawBuffer;
64 	struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
65 
66 	return context_eng3d(ctx)->oclass < NV17_3D_CLASS &&
67 		!nctx->hierz.clear_blocked && depthRb &&
68 		(_mesa_get_format_bits(depthRb->Format,
69 				       GL_DEPTH_BITS) >= 24);
70 }
71 
72 float
nv10_transform_depth(struct gl_context * ctx,float z)73 nv10_transform_depth(struct gl_context *ctx, float z)
74 {
75 	struct nouveau_context *nctx = to_nouveau_context(ctx);
76 
77 	if (nv10_use_viewport_zclear(ctx))
78 		return 2097152.0 * (z + (nctx->hierz.clear_seq & 7));
79 	else
80 		return ctx->DrawBuffer->_DepthMaxF * z;
81 }
82 
83 static void
nv10_zclear(struct gl_context * ctx,GLbitfield * buffers)84 nv10_zclear(struct gl_context *ctx, GLbitfield *buffers)
85 {
86 	/*
87 	 * Pre-nv17 cards don't have native support for fast Z clears,
88 	 * but in some cases we can still "clear" the Z buffer without
89 	 * actually blitting to it if we're willing to sacrifice a few
90 	 * bits of depth precision.
91 	 *
92 	 * Each time a clear is requested we modify the viewport
93 	 * transform in such a way that the old contents of the depth
94 	 * buffer are clamped to the requested clear value when
95 	 * they're read by the GPU.
96 	 */
97 	struct nouveau_context *nctx = to_nouveau_context(ctx);
98 	struct gl_framebuffer *fb = ctx->DrawBuffer;
99 	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb);
100 	struct nouveau_surface *s = &to_nouveau_renderbuffer(
101 		fb->Attachment[BUFFER_DEPTH].Renderbuffer)->surface;
102 
103 	if (nv10_use_viewport_zclear(ctx)) {
104 		int x, y, w, h;
105 		float z = ctx->Depth.Clear;
106 		uint32_t value = pack_zs_f(s->format, z, 0);
107 
108 		get_scissors(fb, &x, &y, &w, &h);
109 		*buffers &= ~BUFFER_BIT_DEPTH;
110 
111 		if (use_fast_zclear(ctx, *buffers)) {
112 			if (nfb->hierz.clear_value != value) {
113 				/* Don't fast clear if we're changing
114 				 * the depth value. */
115 				nfb->hierz.clear_value = value;
116 
117 			} else if (z == 0.0) {
118 				nctx->hierz.clear_seq++;
119 				context_dirty(ctx, ZCLEAR);
120 
121 				if ((nctx->hierz.clear_seq & 7) != 0 &&
122 				    nctx->hierz.clear_seq != 1)
123 					/* We didn't wrap around -- no need to
124 					 * clear the depth buffer for real. */
125 					return;
126 
127 			} else if (z == 1.0) {
128 				nctx->hierz.clear_seq--;
129 				context_dirty(ctx, ZCLEAR);
130 
131 				if ((nctx->hierz.clear_seq & 7) != 7)
132 					/* No wrap around */
133 					return;
134 			}
135 		}
136 
137 		value = pack_zs_f(s->format,
138 				  (z + (nctx->hierz.clear_seq & 7)) / 8, 0);
139 		context_drv(ctx)->surface_fill(ctx, s, ~0, value, x, y, w, h);
140 	}
141 }
142 
143 static void
nv17_zclear(struct gl_context * ctx,GLbitfield * buffers)144 nv17_zclear(struct gl_context *ctx, GLbitfield *buffers)
145 {
146 	struct nouveau_context *nctx = to_nouveau_context(ctx);
147 	struct nouveau_pushbuf *push = context_push(ctx);
148 	struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(
149 		ctx->DrawBuffer);
150 	struct nouveau_surface *s = &to_nouveau_renderbuffer(
151 		nfb->base.Attachment[BUFFER_DEPTH].Renderbuffer)->surface;
152 
153 	/* Clear the hierarchical depth buffer */
154 	BEGIN_NV04(push, NV17_3D(HIERZ_FILL_VALUE), 1);
155 	PUSH_DATA (push, pack_zs_f(s->format, ctx->Depth.Clear, 0));
156 	BEGIN_NV04(push, NV17_3D(HIERZ_BUFFER_CLEAR), 1);
157 	PUSH_DATA (push, 1);
158 
159 	/* Mark the depth buffer as cleared */
160 	if (use_fast_zclear(ctx, *buffers)) {
161 		if (nctx->hierz.clear_seq)
162 			*buffers &= ~BUFFER_BIT_DEPTH;
163 
164 		nfb->hierz.clear_value =
165 			pack_zs_f(s->format, ctx->Depth.Clear, 0);
166 		nctx->hierz.clear_seq++;
167 
168 		context_dirty(ctx, ZCLEAR);
169 	}
170 }
171 
172 static void
nv10_clear(struct gl_context * ctx,GLbitfield buffers)173 nv10_clear(struct gl_context *ctx, GLbitfield buffers)
174 {
175 	struct nouveau_context *nctx = to_nouveau_context(ctx);
176 	struct nouveau_pushbuf *push = context_push(ctx);
177 
178 	nouveau_validate_framebuffer(ctx);
179 
180 	nouveau_pushbuf_bufctx(push, nctx->hw.bufctx);
181 	if (nouveau_pushbuf_validate(push)) {
182 		nouveau_pushbuf_bufctx(push, NULL);
183 		return;
184 	}
185 
186 	if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask) {
187 		if (context_eng3d(ctx)->oclass >= NV17_3D_CLASS)
188 			nv17_zclear(ctx, &buffers);
189 		else
190 			nv10_zclear(ctx, &buffers);
191 
192 		/* Emit the zclear state if it's dirty */
193 		_mesa_update_state(ctx);
194 	}
195 
196 	nouveau_pushbuf_bufctx(push, NULL);
197 	nouveau_clear(ctx, buffers);
198 }
199 
200 static void
nv10_hwctx_init(struct gl_context * ctx)201 nv10_hwctx_init(struct gl_context *ctx)
202 {
203 	struct nouveau_pushbuf *push = context_push(ctx);
204 	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
205 	struct nv04_fifo *fifo = hw->chan->data;
206 	int i;
207 
208 	BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
209 	PUSH_DATA (push, hw->eng3d->handle);
210 	BEGIN_NV04(push, NV10_3D(DMA_NOTIFY), 1);
211 	PUSH_DATA (push, hw->ntfy->handle);
212 
213 	BEGIN_NV04(push, NV10_3D(DMA_TEXTURE0), 3);
214 	PUSH_DATA (push, fifo->vram);
215 	PUSH_DATA (push, fifo->gart);
216 	PUSH_DATA (push, fifo->gart);
217 	BEGIN_NV04(push, NV10_3D(DMA_COLOR), 2);
218 	PUSH_DATA (push, fifo->vram);
219 	PUSH_DATA (push, fifo->vram);
220 
221 	BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
222 	PUSH_DATA (push, 0);
223 
224 	BEGIN_NV04(push, NV10_3D(RT_HORIZ), 2);
225 	PUSH_DATA (push, 0);
226 	PUSH_DATA (push, 0);
227 
228 	BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1);
229 	PUSH_DATA (push, 0x7ff << 16 | 0x800);
230 	BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1);
231 	PUSH_DATA (push, 0x7ff << 16 | 0x800);
232 
233 	for (i = 1; i < 8; i++) {
234 		BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(i)), 1);
235 		PUSH_DATA (push, 0);
236 		BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(i)), 1);
237 		PUSH_DATA (push, 0);
238 	}
239 
240 	BEGIN_NV04(push, SUBC_3D(0x290), 1);
241 	PUSH_DATA (push, 0x10 << 16 | 1);
242 	BEGIN_NV04(push, SUBC_3D(0x3f4), 1);
243 	PUSH_DATA (push, 0);
244 
245 	BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
246 	PUSH_DATA (push, 0);
247 
248 	if (context_eng3d(ctx)->oclass >= NV17_3D_CLASS) {
249 		BEGIN_NV04(push, NV17_3D(UNK01AC), 2);
250 		PUSH_DATA (push, fifo->vram);
251 		PUSH_DATA (push, fifo->vram);
252 
253 		BEGIN_NV04(push, SUBC_3D(0xd84), 1);
254 		PUSH_DATA (push, 0x3);
255 
256 		BEGIN_NV04(push, NV17_3D(COLOR_MASK_ENABLE), 1);
257 		PUSH_DATA (push, 1);
258 	}
259 
260 	if (context_eng3d(ctx)->oclass >= NV15_3D_CLASS) {
261 		BEGIN_NV04(push, SUBC_3D(0x120), 3);
262 		PUSH_DATA (push, 0);
263 		PUSH_DATA (push, 1);
264 		PUSH_DATA (push, 2);
265 
266 		BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
267 		PUSH_DATA (push, 0);
268 	}
269 
270 	BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
271 	PUSH_DATA (push, 0);
272 
273 	/* Set state */
274 	BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 1);
275 	PUSH_DATA (push, 0);
276 	BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_ENABLE), 1);
277 	PUSH_DATA (push, 0);
278 	BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_FUNC), 2);
279 	PUSH_DATA (push, 0x207);
280 	PUSH_DATA (push, 0);
281 	BEGIN_NV04(push, NV10_3D(TEX_ENABLE(0)), 2);
282 	PUSH_DATA (push, 0);
283 	PUSH_DATA (push, 0);
284 
285 	BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1);
286 	PUSH_DATA (push, 0);
287 	BEGIN_NV04(push, NV10_3D(DITHER_ENABLE), 2);
288 	PUSH_DATA (push, 1);
289 	PUSH_DATA (push, 0);
290 	BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1);
291 	PUSH_DATA (push, 0);
292 	BEGIN_NV04(push, NV10_3D(VERTEX_WEIGHT_ENABLE), 2);
293 	PUSH_DATA (push, 0);
294 	PUSH_DATA (push, 0);
295 	BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 4);
296 	PUSH_DATA (push, 1);
297 	PUSH_DATA (push, 0);
298 	PUSH_DATA (push, 0);
299 	PUSH_DATA (push, 0x8006);
300 	BEGIN_NV04(push, NV10_3D(STENCIL_MASK), 8);
301 	PUSH_DATA (push, 0xff);
302 	PUSH_DATA (push, 0x207);
303 	PUSH_DATA (push, 0);
304 	PUSH_DATA (push, 0xff);
305 	PUSH_DATA (push, 0x1e00);
306 	PUSH_DATA (push, 0x1e00);
307 	PUSH_DATA (push, 0x1e00);
308 	PUSH_DATA (push, 0x1d01);
309 	BEGIN_NV04(push, NV10_3D(NORMALIZE_ENABLE), 1);
310 	PUSH_DATA (push, 0);
311 	BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 2);
312 	PUSH_DATA (push, 0);
313 	PUSH_DATA (push, 0);
314 	BEGIN_NV04(push, NV10_3D(LIGHT_MODEL), 1);
315 	PUSH_DATA (push, 0);
316 	BEGIN_NV04(push, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1);
317 	PUSH_DATA (push, 0);
318 	BEGIN_NV04(push, NV10_3D(ENABLED_LIGHTS), 1);
319 	PUSH_DATA (push, 0);
320 	BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_POINT_ENABLE), 3);
321 	PUSH_DATA (push, 0);
322 	PUSH_DATA (push, 0);
323 	PUSH_DATA (push, 0);
324 	BEGIN_NV04(push, NV10_3D(DEPTH_FUNC), 1);
325 	PUSH_DATA (push, 0x201);
326 	BEGIN_NV04(push, NV10_3D(DEPTH_WRITE_ENABLE), 1);
327 	PUSH_DATA (push, 0);
328 	BEGIN_NV04(push, NV10_3D(DEPTH_TEST_ENABLE), 1);
329 	PUSH_DATA (push, 0);
330 	BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_FACTOR), 2);
331 	PUSH_DATA (push, 0);
332 	PUSH_DATA (push, 0);
333 	BEGIN_NV04(push, NV10_3D(POINT_SIZE), 1);
334 	PUSH_DATA (push, 8);
335 	BEGIN_NV04(push, NV10_3D(POINT_PARAMETERS_ENABLE), 2);
336 	PUSH_DATA (push, 0);
337 	PUSH_DATA (push, 0);
338 	BEGIN_NV04(push, NV10_3D(LINE_WIDTH), 1);
339 	PUSH_DATA (push, 8);
340 	BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1);
341 	PUSH_DATA (push, 0);
342 	BEGIN_NV04(push, NV10_3D(POLYGON_MODE_FRONT), 2);
343 	PUSH_DATA (push, 0x1b02);
344 	PUSH_DATA (push, 0x1b02);
345 	BEGIN_NV04(push, NV10_3D(CULL_FACE), 2);
346 	PUSH_DATA (push, 0x405);
347 	PUSH_DATA (push, 0x901);
348 	BEGIN_NV04(push, NV10_3D(POLYGON_SMOOTH_ENABLE), 1);
349 	PUSH_DATA (push, 0);
350 	BEGIN_NV04(push, NV10_3D(CULL_FACE_ENABLE), 1);
351 	PUSH_DATA (push, 0);
352 	BEGIN_NV04(push, NV10_3D(TEX_GEN_MODE(0, 0)), 8);
353 	for (i = 0; i < 8; i++)
354 		PUSH_DATA (push, 0);
355 
356 	BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(0)), 2);
357 	PUSH_DATA (push, 0);
358 	PUSH_DATA (push, 0);
359 	BEGIN_NV04(push, NV10_3D(FOG_COEFF(0)), 3);
360 	PUSH_DATA (push, 0x3fc00000);	/* -1.50 */
361 	PUSH_DATA (push, 0xbdb8aa0a);	/* -0.09 */
362 	PUSH_DATA (push, 0);		/*  0.00 */
363 
364 	BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
365 	PUSH_DATA (push, 0);
366 
367 	BEGIN_NV04(push, NV10_3D(FOG_MODE), 2);
368 	PUSH_DATA (push, 0x802);
369 	PUSH_DATA (push, 2);
370 	/* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
371 	 * using texturing, except when using the texture matrix
372 	 */
373 	BEGIN_NV04(push, NV10_3D(VIEW_MATRIX_ENABLE), 1);
374 	PUSH_DATA (push, 6);
375 	BEGIN_NV04(push, NV10_3D(COLOR_MASK), 1);
376 	PUSH_DATA (push, 0x01010101);
377 
378 	/* Set vertex component */
379 	BEGIN_NV04(push, NV10_3D(VERTEX_COL_4F_R), 4);
380 	PUSH_DATAf(push, 1.0);
381 	PUSH_DATAf(push, 0.0);
382 	PUSH_DATAf(push, 0.0);
383 	PUSH_DATAf(push, 1.0);
384 	BEGIN_NV04(push, NV10_3D(VERTEX_COL2_3F_R), 3);
385 	PUSH_DATA (push, 0);
386 	PUSH_DATA (push, 0);
387 	PUSH_DATA (push, 0);
388 	BEGIN_NV04(push, NV10_3D(VERTEX_NOR_3F_X), 3);
389 	PUSH_DATA (push, 0);
390 	PUSH_DATA (push, 0);
391 	PUSH_DATAf(push, 1.0);
392 	BEGIN_NV04(push, NV10_3D(VERTEX_TX0_4F_S), 4);
393 	PUSH_DATAf(push, 0.0);
394 	PUSH_DATAf(push, 0.0);
395 	PUSH_DATAf(push, 0.0);
396 	PUSH_DATAf(push, 1.0);
397 	BEGIN_NV04(push, NV10_3D(VERTEX_TX1_4F_S), 4);
398 	PUSH_DATAf(push, 0.0);
399 	PUSH_DATAf(push, 0.0);
400 	PUSH_DATAf(push, 0.0);
401 	PUSH_DATAf(push, 1.0);
402 	BEGIN_NV04(push, NV10_3D(VERTEX_FOG_1F), 1);
403 	PUSH_DATAf(push, 0.0);
404 	BEGIN_NV04(push, NV10_3D(EDGEFLAG_ENABLE), 1);
405 	PUSH_DATA (push, 1);
406 
407 	BEGIN_NV04(push, NV10_3D(DEPTH_RANGE_NEAR), 2);
408 	PUSH_DATAf(push, 0.0);
409 	PUSH_DATAf(push, 16777216.0);
410 
411 	PUSH_KICK (push);
412 }
413 
414 static void
nv10_context_destroy(struct gl_context * ctx)415 nv10_context_destroy(struct gl_context *ctx)
416 {
417 	struct nouveau_context *nctx = to_nouveau_context(ctx);
418 
419 	nv04_surface_takedown(ctx);
420 	nv10_swtnl_destroy(ctx);
421 	nv10_vbo_destroy(ctx);
422 
423 	nouveau_object_del(&nctx->hw.eng3d);
424 
425 	nouveau_context_deinit(ctx);
426 	free(ctx);
427 }
428 
429 static struct gl_context *
nv10_context_create(struct nouveau_screen * screen,gl_api api,const struct gl_config * visual,struct gl_context * share_ctx)430 nv10_context_create(struct nouveau_screen *screen, gl_api api,
431 		    const struct gl_config *visual,
432 		    struct gl_context *share_ctx)
433 {
434 	struct nouveau_context *nctx;
435 	struct gl_context *ctx;
436 	unsigned celsius_class;
437 	int ret;
438 
439 	nctx = CALLOC_STRUCT(nouveau_context);
440 	if (!nctx)
441 		return NULL;
442 
443 	ctx = &nctx->base;
444 
445 	if (!nouveau_context_init(ctx, api, screen, visual, share_ctx))
446 		goto fail;
447 
448 	ctx->Extensions.ARB_texture_env_crossbar = true;
449 	ctx->Extensions.ARB_texture_env_combine = true;
450 	ctx->Extensions.ARB_texture_env_dot3 = true;
451 	ctx->Extensions.EXT_texture_env_dot3 = true;
452 	ctx->Extensions.NV_fog_distance = true;
453 	ctx->Extensions.NV_texture_rectangle = true;
454 	if (ctx->Mesa_DXTn) {
455 		ctx->Extensions.EXT_texture_compression_s3tc = true;
456 		ctx->Extensions.ANGLE_texture_compression_dxt = true;
457 	}
458 
459 	/* GL constants. */
460 	ctx->Const.MaxTextureLevels = 12;
461 	ctx->Const.MaxTextureCoordUnits = NV10_TEXTURE_UNITS;
462 	ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = NV10_TEXTURE_UNITS;
463 	ctx->Const.MaxTextureUnits = NV10_TEXTURE_UNITS;
464 	ctx->Const.MaxTextureMaxAnisotropy = 2;
465 	ctx->Const.MaxTextureLodBias = 15;
466 	ctx->Driver.Clear = nv10_clear;
467 
468 	/* 2D engine. */
469 	ret = nv04_surface_init(ctx);
470 	if (!ret)
471 		goto fail;
472 
473 	/* 3D engine. */
474 	if (context_chipset(ctx) >= 0x17 && context_chipset(ctx) != 0x1a)
475 		celsius_class = NV17_3D_CLASS;
476 	else if (context_chipset(ctx) >= 0x11)
477 		celsius_class = NV15_3D_CLASS;
478 	else
479 		celsius_class = NV10_3D_CLASS;
480 
481 	ret = nouveau_object_new(context_chan(ctx), 0xbeef0001, celsius_class,
482 				 NULL, 0, &nctx->hw.eng3d);
483 	if (ret)
484 		goto fail;
485 
486 	nv10_hwctx_init(ctx);
487 	nv10_vbo_init(ctx);
488 	nv10_swtnl_init(ctx);
489 
490 	return ctx;
491 
492 fail:
493 	nv10_context_destroy(ctx);
494 	return NULL;
495 }
496 
497 const struct nouveau_driver nv10_driver = {
498 	.context_create = nv10_context_create,
499 	.context_destroy = nv10_context_destroy,
500 	.surface_copy = nv04_surface_copy,
501 	.surface_fill = nv04_surface_fill,
502 	.emit = (nouveau_state_func[]) {
503 		nv10_emit_alpha_func,
504 		nv10_emit_blend_color,
505 		nv10_emit_blend_equation,
506 		nv10_emit_blend_func,
507 		nv10_emit_clip_plane,
508 		nv10_emit_clip_plane,
509 		nv10_emit_clip_plane,
510 		nv10_emit_clip_plane,
511 		nv10_emit_clip_plane,
512 		nv10_emit_clip_plane,
513 		nv10_emit_color_mask,
514 		nv10_emit_color_material,
515 		nv10_emit_cull_face,
516 		nv10_emit_front_face,
517 		nv10_emit_depth,
518 		nv10_emit_dither,
519 		nv10_emit_frag,
520 		nv10_emit_framebuffer,
521 		nv10_emit_fog,
522 		nv10_emit_light_enable,
523 		nv10_emit_light_model,
524 		nv10_emit_light_source,
525 		nv10_emit_light_source,
526 		nv10_emit_light_source,
527 		nv10_emit_light_source,
528 		nv10_emit_light_source,
529 		nv10_emit_light_source,
530 		nv10_emit_light_source,
531 		nv10_emit_light_source,
532 		nv10_emit_line_stipple,
533 		nv10_emit_line_mode,
534 		nv10_emit_logic_opcode,
535 		nv10_emit_material_ambient,
536 		nouveau_emit_nothing,
537 		nv10_emit_material_diffuse,
538 		nouveau_emit_nothing,
539 		nv10_emit_material_specular,
540 		nouveau_emit_nothing,
541 		nv10_emit_material_shininess,
542 		nouveau_emit_nothing,
543 		nv10_emit_modelview,
544 		nv10_emit_point_mode,
545 		nv10_emit_point_parameter,
546 		nv10_emit_polygon_mode,
547 		nv10_emit_polygon_offset,
548 		nv10_emit_polygon_stipple,
549 		nv10_emit_projection,
550 		nv10_emit_render_mode,
551 		nv10_emit_scissor,
552 		nv10_emit_shade_model,
553 		nv10_emit_stencil_func,
554 		nv10_emit_stencil_mask,
555 		nv10_emit_stencil_op,
556 		nv10_emit_tex_env,
557 		nv10_emit_tex_env,
558 		nouveau_emit_nothing,
559 		nouveau_emit_nothing,
560 		nv10_emit_tex_gen,
561 		nv10_emit_tex_gen,
562 		nouveau_emit_nothing,
563 		nouveau_emit_nothing,
564 		nv10_emit_tex_mat,
565 		nv10_emit_tex_mat,
566 		nouveau_emit_nothing,
567 		nouveau_emit_nothing,
568 		nv10_emit_tex_obj,
569 		nv10_emit_tex_obj,
570 		nouveau_emit_nothing,
571 		nouveau_emit_nothing,
572 		nv10_emit_viewport,
573 		nv10_emit_zclear
574 	},
575 	.num_emit = NUM_NV10_STATE,
576 };
577