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