Home | History | Annotate | Download | only in nouveau
      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 "nouveau_driver.h"
     29 #include "nouveau_context.h"
     30 #include "nouveau_fbo.h"
     31 #include "nouveau_util.h"
     32 #include "nv_object.xml.h"
     33 #include "nv20_3d.xml.h"
     34 #include "nv04_driver.h"
     35 #include "nv10_driver.h"
     36 #include "nv20_driver.h"
     37 
     38 static void
     39 nv20_clear(struct gl_context *ctx, GLbitfield buffers)
     40 {
     41 	struct nouveau_context *nctx = to_nouveau_context(ctx);
     42 	struct nouveau_pushbuf *push = context_push(ctx);
     43 	struct gl_framebuffer *fb = ctx->DrawBuffer;
     44 	uint32_t clear = 0;
     45 
     46 	nouveau_validate_framebuffer(ctx);
     47 
     48 	nouveau_pushbuf_bufctx(push, nctx->hw.bufctx);
     49 	if (nouveau_pushbuf_validate(push)) {
     50 		nouveau_pushbuf_bufctx(push, NULL);
     51 		return;
     52 	}
     53 
     54 	if (buffers & BUFFER_BITS_COLOR) {
     55 		struct nouveau_surface *s = &to_nouveau_renderbuffer(
     56 			fb->_ColorDrawBuffers[0])->surface;
     57 
     58 		if (ctx->Color.ColorMask[0][RCOMP])
     59 			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_R;
     60 		if (ctx->Color.ColorMask[0][GCOMP])
     61 			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_G;
     62 		if (ctx->Color.ColorMask[0][BCOMP])
     63 			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_B;
     64 		if (ctx->Color.ColorMask[0][ACOMP])
     65 			clear |= NV20_3D_CLEAR_BUFFERS_COLOR_A;
     66 
     67 		BEGIN_NV04(push, NV20_3D(CLEAR_VALUE), 1);
     68 		PUSH_DATA (push, pack_rgba_clamp_f(s->format, ctx->Color.ClearColor.f));
     69 
     70 		buffers &= ~BUFFER_BITS_COLOR;
     71 	}
     72 
     73 	if (buffers & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
     74 		struct nouveau_surface *s = &to_nouveau_renderbuffer(
     75 			fb->Attachment[BUFFER_DEPTH].Renderbuffer)->surface;
     76 
     77 		if (buffers & BUFFER_BIT_DEPTH && ctx->Depth.Mask)
     78 			clear |= NV20_3D_CLEAR_BUFFERS_DEPTH;
     79 		if (buffers & BUFFER_BIT_STENCIL && ctx->Stencil.WriteMask[0])
     80 			clear |= NV20_3D_CLEAR_BUFFERS_STENCIL;
     81 
     82 		BEGIN_NV04(push, NV20_3D(CLEAR_DEPTH_VALUE), 1);
     83 		PUSH_DATA (push, pack_zs_f(s->format, ctx->Depth.Clear,
     84 					 ctx->Stencil.Clear));
     85 
     86 		buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
     87 	}
     88 
     89 	BEGIN_NV04(push, NV20_3D(CLEAR_BUFFERS), 1);
     90 	PUSH_DATA (push, clear);
     91 
     92 	nouveau_pushbuf_bufctx(push, NULL);
     93 	nouveau_clear(ctx, buffers);
     94 }
     95 
     96 static void
     97 nv20_hwctx_init(struct gl_context *ctx)
     98 {
     99 	struct nouveau_pushbuf *push = context_push(ctx);
    100 	struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
    101 	struct nv04_fifo *fifo = hw->chan->data;
    102 	int i;
    103 
    104 	BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
    105 	PUSH_DATA (push, hw->eng3d->handle);
    106 	BEGIN_NV04(push, NV20_3D(DMA_NOTIFY), 1);
    107 	PUSH_DATA (push, hw->ntfy->handle);
    108 	BEGIN_NV04(push, NV20_3D(DMA_TEXTURE0), 2);
    109 	PUSH_DATA (push, fifo->vram);
    110 	PUSH_DATA (push, fifo->gart);
    111 	BEGIN_NV04(push, NV20_3D(DMA_COLOR), 2);
    112 	PUSH_DATA (push, fifo->vram);
    113 	PUSH_DATA (push, fifo->vram);
    114 	BEGIN_NV04(push, NV20_3D(DMA_VTXBUF0), 2);
    115 	PUSH_DATA (push, fifo->vram);
    116 	PUSH_DATA (push, fifo->gart);
    117 
    118 	BEGIN_NV04(push, NV20_3D(DMA_QUERY), 1);
    119 	PUSH_DATA (push, 0);
    120 
    121 	BEGIN_NV04(push, NV20_3D(RT_HORIZ), 2);
    122 	PUSH_DATA (push, 0);
    123 	PUSH_DATA (push, 0);
    124 
    125 	BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_HORIZ(0)), 1);
    126 	PUSH_DATA (push, 0xfff << 16 | 0x0);
    127 	BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_VERT(0)), 1);
    128 	PUSH_DATA (push, 0xfff << 16 | 0x0);
    129 
    130 	for (i = 1; i < NV20_3D_VIEWPORT_CLIP_HORIZ__LEN; i++) {
    131 		BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_HORIZ(i)), 1);
    132 		PUSH_DATA (push, 0);
    133 		BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_VERT(i)), 1);
    134 		PUSH_DATA (push, 0);
    135 	}
    136 
    137 	BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_MODE), 1);
    138 	PUSH_DATA (push, 0);
    139 
    140 	BEGIN_NV04(push, SUBC_3D(0x17e0), 3);
    141 	PUSH_DATAf(push, 0.0);
    142 	PUSH_DATAf(push, 0.0);
    143 	PUSH_DATAf(push, 1.0);
    144 
    145 	if (context_chipset(ctx) >= 0x25) {
    146 		BEGIN_NV04(push, NV20_3D(TEX_RCOMP), 1);
    147 		PUSH_DATA (push, NV20_3D_TEX_RCOMP_LEQUAL | 0xdb0);
    148 	} else {
    149 		BEGIN_NV04(push, SUBC_3D(0x1e68), 1);
    150 		PUSH_DATA (push, 0x4b800000); /* 16777216.000000 */
    151 		BEGIN_NV04(push, NV20_3D(TEX_RCOMP), 1);
    152 		PUSH_DATA (push, NV20_3D_TEX_RCOMP_LEQUAL);
    153 	}
    154 
    155 	BEGIN_NV04(push, SUBC_3D(0x290), 1);
    156 	PUSH_DATA (push, 0x10 << 16 | 1);
    157 	BEGIN_NV04(push, SUBC_3D(0x9fc), 1);
    158 	PUSH_DATA (push, 0);
    159 	BEGIN_NV04(push, SUBC_3D(0x1d80), 1);
    160 	PUSH_DATA (push, 1);
    161 	BEGIN_NV04(push, SUBC_3D(0x9f8), 1);
    162 	PUSH_DATA (push, 4);
    163 	BEGIN_NV04(push, SUBC_3D(0x17ec), 3);
    164 	PUSH_DATAf(push, 0.0);
    165 	PUSH_DATAf(push, 1.0);
    166 	PUSH_DATAf(push, 0.0);
    167 
    168 	if (context_chipset(ctx) >= 0x25) {
    169 		BEGIN_NV04(push, SUBC_3D(0x1d88), 1);
    170 		PUSH_DATA (push, 3);
    171 
    172 		BEGIN_NV04(push, NV25_3D(DMA_HIERZ), 1);
    173 		PUSH_DATA (push, fifo->vram);
    174 		BEGIN_NV04(push, NV25_3D(UNK01AC), 1);
    175 		PUSH_DATA (push, fifo->vram);
    176 	}
    177 
    178 	BEGIN_NV04(push, NV20_3D(DMA_FENCE), 1);
    179 	PUSH_DATA (push, 0);
    180 
    181 	BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
    182 	PUSH_DATA (push, 0);
    183 
    184 	BEGIN_NV04(push, NV04_GRAPH(3D, NOTIFY), 1);
    185 	PUSH_DATA (push, 0);
    186 
    187 	BEGIN_NV04(push, SUBC_3D(0x120), 3);
    188 	PUSH_DATA (push, 0);
    189 	PUSH_DATA (push, 1);
    190 	PUSH_DATA (push, 2);
    191 
    192 	if (context_chipset(ctx) >= 0x25) {
    193 		BEGIN_NV04(push, SUBC_3D(0x1da4), 1);
    194 		PUSH_DATA (push, 0);
    195 	}
    196 
    197 	BEGIN_NV04(push, NV20_3D(RT_HORIZ), 2);
    198 	PUSH_DATA (push, 0 << 16 | 0);
    199 	PUSH_DATA (push, 0 << 16 | 0);
    200 
    201 	BEGIN_NV04(push, NV20_3D(ALPHA_FUNC_ENABLE), 1);
    202 	PUSH_DATA (push, 0);
    203 	BEGIN_NV04(push, NV20_3D(ALPHA_FUNC_FUNC), 2);
    204 	PUSH_DATA (push, NV20_3D_ALPHA_FUNC_FUNC_ALWAYS);
    205 	PUSH_DATA (push, 0);
    206 
    207 	for (i = 0; i < NV20_3D_TEX__LEN; i++) {
    208 		BEGIN_NV04(push, NV20_3D(TEX_ENABLE(i)), 1);
    209 		PUSH_DATA (push, 0);
    210 	}
    211 
    212 	BEGIN_NV04(push, NV20_3D(TEX_SHADER_OP), 1);
    213 	PUSH_DATA (push, 0);
    214 	BEGIN_NV04(push, NV20_3D(TEX_SHADER_CULL_MODE), 1);
    215 	PUSH_DATA (push, 0);
    216 
    217 	BEGIN_NV04(push, NV20_3D(RC_IN_ALPHA(0)), 4);
    218 	PUSH_DATA (push, 0x30d410d0);
    219 	PUSH_DATA (push, 0);
    220 	PUSH_DATA (push, 0);
    221 	PUSH_DATA (push, 0);
    222 	BEGIN_NV04(push, NV20_3D(RC_OUT_RGB(0)), 4);
    223 	PUSH_DATA (push, 0x00000c00);
    224 	PUSH_DATA (push, 0);
    225 	PUSH_DATA (push, 0);
    226 	PUSH_DATA (push, 0);
    227 	BEGIN_NV04(push, NV20_3D(RC_ENABLE), 1);
    228 	PUSH_DATA (push, 0x00011101);
    229 	BEGIN_NV04(push, NV20_3D(RC_FINAL0), 2);
    230 	PUSH_DATA (push, 0x130e0300);
    231 	PUSH_DATA (push, 0x0c091c80);
    232 	BEGIN_NV04(push, NV20_3D(RC_OUT_ALPHA(0)), 4);
    233 	PUSH_DATA (push, 0x00000c00);
    234 	PUSH_DATA (push, 0);
    235 	PUSH_DATA (push, 0);
    236 	PUSH_DATA (push, 0);
    237 	BEGIN_NV04(push, NV20_3D(RC_IN_RGB(0)), 4);
    238 	PUSH_DATA (push, 0x20c400c0);
    239 	PUSH_DATA (push, 0);
    240 	PUSH_DATA (push, 0);
    241 	PUSH_DATA (push, 0);
    242 	BEGIN_NV04(push, NV20_3D(RC_COLOR0), 2);
    243 	PUSH_DATA (push, 0);
    244 	PUSH_DATA (push, 0);
    245 	BEGIN_NV04(push, NV20_3D(RC_CONSTANT_COLOR0(0)), 4);
    246 	PUSH_DATA (push, 0x035125a0);
    247 	PUSH_DATA (push, 0);
    248 	PUSH_DATA (push, 0x40002000);
    249 	PUSH_DATA (push, 0);
    250 
    251 	BEGIN_NV04(push, NV20_3D(MULTISAMPLE_CONTROL), 1);
    252 	PUSH_DATA (push, 0xffff0000);
    253 	BEGIN_NV04(push, NV20_3D(BLEND_FUNC_ENABLE), 1);
    254 	PUSH_DATA (push, 0);
    255 	BEGIN_NV04(push, NV20_3D(DITHER_ENABLE), 1);
    256 	PUSH_DATA (push, 0);
    257 	BEGIN_NV04(push, NV20_3D(STENCIL_ENABLE), 1);
    258 	PUSH_DATA (push, 0);
    259 	BEGIN_NV04(push, NV20_3D(BLEND_FUNC_SRC), 4);
    260 	PUSH_DATA (push, NV20_3D_BLEND_FUNC_SRC_ONE);
    261 	PUSH_DATA (push, NV20_3D_BLEND_FUNC_DST_ZERO);
    262 	PUSH_DATA (push, 0);
    263 	PUSH_DATA (push, NV20_3D_BLEND_EQUATION_FUNC_ADD);
    264 	BEGIN_NV04(push, NV20_3D(STENCIL_MASK), 7);
    265 	PUSH_DATA (push, 0xff);
    266 	PUSH_DATA (push, NV20_3D_STENCIL_FUNC_FUNC_ALWAYS);
    267 	PUSH_DATA (push, 0);
    268 	PUSH_DATA (push, 0xff);
    269 	PUSH_DATA (push, NV20_3D_STENCIL_OP_FAIL_KEEP);
    270 	PUSH_DATA (push, NV20_3D_STENCIL_OP_ZFAIL_KEEP);
    271 	PUSH_DATA (push, NV20_3D_STENCIL_OP_ZPASS_KEEP);
    272 
    273 	BEGIN_NV04(push, NV20_3D(COLOR_LOGIC_OP_ENABLE), 2);
    274 	PUSH_DATA (push, 0);
    275 	PUSH_DATA (push, NV20_3D_COLOR_LOGIC_OP_OP_COPY);
    276 	BEGIN_NV04(push, SUBC_3D(0x17cc), 1);
    277 	PUSH_DATA (push, 0);
    278 	if (context_chipset(ctx) >= 0x25) {
    279 		BEGIN_NV04(push, SUBC_3D(0x1d84), 1);
    280 		PUSH_DATA (push, 1);
    281 	}
    282 	BEGIN_NV04(push, NV20_3D(LIGHTING_ENABLE), 1);
    283 	PUSH_DATA (push, 0);
    284 	BEGIN_NV04(push, NV20_3D(LIGHT_MODEL), 1);
    285 	PUSH_DATA (push, NV20_3D_LIGHT_MODEL_VIEWER_NONLOCAL);
    286 	BEGIN_NV04(push, NV20_3D(SEPARATE_SPECULAR_ENABLE), 1);
    287 	PUSH_DATA (push, 0);
    288 	BEGIN_NV04(push, NV20_3D(LIGHT_MODEL_TWO_SIDE_ENABLE), 1);
    289 	PUSH_DATA (push, 0);
    290 	BEGIN_NV04(push, NV20_3D(ENABLED_LIGHTS), 1);
    291 	PUSH_DATA (push, 0);
    292 	BEGIN_NV04(push, NV20_3D(NORMALIZE_ENABLE), 1);
    293 	PUSH_DATA (push, 0);
    294 	BEGIN_NV04(push, NV20_3D(POLYGON_STIPPLE_PATTERN(0)),
    295 		   NV20_3D_POLYGON_STIPPLE_PATTERN__LEN);
    296 	for (i = 0; i < NV20_3D_POLYGON_STIPPLE_PATTERN__LEN; i++) {
    297 		PUSH_DATA (push, 0xffffffff);
    298 	}
    299 
    300 	BEGIN_NV04(push, NV20_3D(POLYGON_OFFSET_POINT_ENABLE), 3);
    301 	PUSH_DATA (push, 0);
    302 	PUSH_DATA (push, 0);
    303 	PUSH_DATA (push, 0);
    304 	BEGIN_NV04(push, NV20_3D(DEPTH_FUNC), 1);
    305 	PUSH_DATA (push, NV20_3D_DEPTH_FUNC_LESS);
    306 	BEGIN_NV04(push, NV20_3D(DEPTH_WRITE_ENABLE), 1);
    307 	PUSH_DATA (push, 0);
    308 	BEGIN_NV04(push, NV20_3D(DEPTH_TEST_ENABLE), 1);
    309 	PUSH_DATA (push, 0);
    310 	BEGIN_NV04(push, NV20_3D(POLYGON_OFFSET_FACTOR), 2);
    311 	PUSH_DATAf(push, 0.0);
    312 	PUSH_DATAf(push, 0.0);
    313 	BEGIN_NV04(push, NV20_3D(DEPTH_CLAMP), 1);
    314 	PUSH_DATA (push, 1);
    315 	if (context_chipset(ctx) < 0x25) {
    316 		BEGIN_NV04(push, SUBC_3D(0x1d84), 1);
    317 		PUSH_DATA (push, 3);
    318 	}
    319 	BEGIN_NV04(push, NV20_3D(POINT_SIZE), 1);
    320 	if (context_chipset(ctx) >= 0x25)
    321 		PUSH_DATAf(push, 1.0);
    322 	else
    323 		PUSH_DATA (push, 8);
    324 
    325 	if (context_chipset(ctx) >= 0x25) {
    326 		BEGIN_NV04(push, NV20_3D(POINT_PARAMETERS_ENABLE), 1);
    327 		PUSH_DATA (push, 0);
    328 		BEGIN_NV04(push, SUBC_3D(0x0a1c), 1);
    329 		PUSH_DATA (push, 0x800);
    330 	} else {
    331 		BEGIN_NV04(push, NV20_3D(POINT_PARAMETERS_ENABLE), 2);
    332 		PUSH_DATA (push, 0);
    333 		PUSH_DATA (push, 0);
    334 	}
    335 
    336 	BEGIN_NV04(push, NV20_3D(LINE_WIDTH), 1);
    337 	PUSH_DATA (push, 8);
    338 	BEGIN_NV04(push, NV20_3D(LINE_SMOOTH_ENABLE), 1);
    339 	PUSH_DATA (push, 0);
    340 	BEGIN_NV04(push, NV20_3D(POLYGON_MODE_FRONT), 2);
    341 	PUSH_DATA (push, NV20_3D_POLYGON_MODE_FRONT_FILL);
    342 	PUSH_DATA (push, NV20_3D_POLYGON_MODE_BACK_FILL);
    343 	BEGIN_NV04(push, NV20_3D(CULL_FACE), 2);
    344 	PUSH_DATA (push, NV20_3D_CULL_FACE_BACK);
    345 	PUSH_DATA (push, NV20_3D_FRONT_FACE_CCW);
    346 	BEGIN_NV04(push, NV20_3D(POLYGON_SMOOTH_ENABLE), 1);
    347 	PUSH_DATA (push, 0);
    348 	BEGIN_NV04(push, NV20_3D(CULL_FACE_ENABLE), 1);
    349 	PUSH_DATA (push, 0);
    350 	BEGIN_NV04(push, NV20_3D(SHADE_MODEL), 1);
    351 	PUSH_DATA (push, NV20_3D_SHADE_MODEL_SMOOTH);
    352 	BEGIN_NV04(push, NV20_3D(POLYGON_STIPPLE_ENABLE), 1);
    353 	PUSH_DATA (push, 0);
    354 
    355 	BEGIN_NV04(push, NV20_3D(TEX_GEN_MODE(0,0)),
    356 		   4 * NV20_3D_TEX_GEN_MODE__ESIZE);
    357 	for (i=0; i < 4 * NV20_3D_TEX_GEN_MODE__LEN; i++)
    358 		PUSH_DATA (push, 0);
    359 
    360 	BEGIN_NV04(push, NV20_3D(FOG_COEFF(0)), 3);
    361 	PUSH_DATAf(push, 1.5);
    362 	PUSH_DATAf(push, -0.090168);
    363 	PUSH_DATAf(push, 0.0);
    364 	BEGIN_NV04(push, NV20_3D(FOG_MODE), 2);
    365 	PUSH_DATA (push, NV20_3D_FOG_MODE_EXP_SIGNED);
    366 	PUSH_DATA (push, NV20_3D_FOG_COORD_FOG);
    367 	BEGIN_NV04(push, NV20_3D(FOG_ENABLE), 2);
    368 	PUSH_DATA (push, 0);
    369 	PUSH_DATA (push, 0);
    370 
    371 	BEGIN_NV04(push, NV20_3D(ENGINE), 1);
    372 	PUSH_DATA (push, NV20_3D_ENGINE_FIXED);
    373 
    374 	for (i = 0; i < NV20_3D_TEX_MATRIX_ENABLE__LEN; i++) {
    375 		BEGIN_NV04(push, NV20_3D(TEX_MATRIX_ENABLE(i)), 1);
    376 		PUSH_DATA (push, 0);
    377 	}
    378 
    379 	BEGIN_NV04(push, NV20_3D(VERTEX_ATTR_4F_X(1)), 4 * 15);
    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 	PUSH_DATAf(push, 0.0);
    385 	PUSH_DATAf(push, 0.0);
    386 	PUSH_DATAf(push, 1.0);
    387 	PUSH_DATAf(push, 1.0);
    388 	PUSH_DATAf(push, 1.0);
    389 	PUSH_DATAf(push, 1.0);
    390 	PUSH_DATAf(push, 1.0);
    391 	PUSH_DATAf(push, 1.0);
    392 	for (i = 0; i < 12; i++) {
    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 	}
    398 
    399 	BEGIN_NV04(push, NV20_3D(EDGEFLAG_ENABLE), 1);
    400 	PUSH_DATA (push, 1);
    401 	BEGIN_NV04(push, NV20_3D(COLOR_MASK), 1);
    402 	PUSH_DATA (push, 0x00010101);
    403 	BEGIN_NV04(push, NV20_3D(CLEAR_VALUE), 1);
    404 	PUSH_DATA (push, 0);
    405 
    406 	BEGIN_NV04(push, NV20_3D(DEPTH_RANGE_NEAR), 2);
    407 	PUSH_DATAf(push, 0.0);
    408 	PUSH_DATAf(push, 16777216.0);
    409 
    410 	BEGIN_NV04(push, NV20_3D(VIEWPORT_TRANSLATE_X), 4);
    411 	PUSH_DATAf(push, 0.0);
    412 	PUSH_DATAf(push, 0.0);
    413 	PUSH_DATAf(push, 0.0);
    414 	PUSH_DATAf(push, 16777215.0);
    415 
    416 	BEGIN_NV04(push, NV20_3D(VIEWPORT_SCALE_X), 4);
    417 	PUSH_DATAf(push, 0.0);
    418 	PUSH_DATAf(push, 0.0);
    419 	PUSH_DATAf(push, 16777215.0 * 0.5);
    420 	PUSH_DATAf(push, 65535.0);
    421 
    422 	PUSH_KICK (push);
    423 }
    424 
    425 static void
    426 nv20_context_destroy(struct gl_context *ctx)
    427 {
    428 	struct nouveau_context *nctx = to_nouveau_context(ctx);
    429 
    430 	nv04_surface_takedown(ctx);
    431 	nv20_swtnl_destroy(ctx);
    432 	nv20_vbo_destroy(ctx);
    433 
    434 	nouveau_object_del(&nctx->hw.eng3d);
    435 
    436 	nouveau_context_deinit(ctx);
    437 	free(ctx);
    438 }
    439 
    440 static struct gl_context *
    441 nv20_context_create(struct nouveau_screen *screen, gl_api api,
    442 		    const struct gl_config *visual,
    443 		    struct gl_context *share_ctx)
    444 {
    445 	struct nouveau_context *nctx;
    446 	struct gl_context *ctx;
    447 	unsigned kelvin_class;
    448 	int ret;
    449 
    450 	nctx = CALLOC_STRUCT(nouveau_context);
    451 	if (!nctx)
    452 		return NULL;
    453 
    454 	ctx = &nctx->base;
    455 
    456 	if (!nouveau_context_init(ctx, api, screen, visual, share_ctx))
    457 		goto fail;
    458 
    459 	ctx->Extensions.ARB_texture_env_crossbar = true;
    460 	ctx->Extensions.ARB_texture_env_combine = true;
    461 	ctx->Extensions.ARB_texture_env_dot3 = true;
    462 	ctx->Extensions.EXT_texture_env_dot3 = true;
    463 	ctx->Extensions.NV_fog_distance = true;
    464 	ctx->Extensions.NV_texture_rectangle = true;
    465 	if (ctx->Mesa_DXTn) {
    466 		ctx->Extensions.EXT_texture_compression_s3tc = true;
    467 		ctx->Extensions.ANGLE_texture_compression_dxt = true;
    468 	}
    469 
    470 	/* GL constants. */
    471 	ctx->Const.MaxTextureCoordUnits = NV20_TEXTURE_UNITS;
    472 	ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = NV20_TEXTURE_UNITS;
    473 	ctx->Const.MaxTextureUnits = NV20_TEXTURE_UNITS;
    474 	ctx->Const.MaxTextureMaxAnisotropy = 8;
    475 	ctx->Const.MaxTextureLodBias = 15;
    476 	ctx->Driver.Clear = nv20_clear;
    477 
    478 	/* 2D engine. */
    479 	ret = nv04_surface_init(ctx);
    480 	if (!ret)
    481 		goto fail;
    482 
    483 	/* 3D engine. */
    484 	if (context_chipset(ctx) >= 0x25)
    485 		kelvin_class = NV25_3D_CLASS;
    486 	else
    487 		kelvin_class = NV20_3D_CLASS;
    488 
    489 	ret = nouveau_object_new(context_chan(ctx), 0xbeef0001, kelvin_class,
    490 				 NULL, 0, &nctx->hw.eng3d);
    491 	if (ret)
    492 		goto fail;
    493 
    494 	nv20_hwctx_init(ctx);
    495 	nv20_vbo_init(ctx);
    496 	nv20_swtnl_init(ctx);
    497 
    498 	return ctx;
    499 
    500 fail:
    501 	nv20_context_destroy(ctx);
    502 	return NULL;
    503 }
    504 
    505 const struct nouveau_driver nv20_driver = {
    506 	.context_create = nv20_context_create,
    507 	.context_destroy = nv20_context_destroy,
    508 	.surface_copy = nv04_surface_copy,
    509 	.surface_fill = nv04_surface_fill,
    510 	.emit = (nouveau_state_func[]) {
    511 		nv10_emit_alpha_func,
    512 		nv10_emit_blend_color,
    513 		nv10_emit_blend_equation,
    514 		nv10_emit_blend_func,
    515 		nv20_emit_clip_plane,
    516 		nv20_emit_clip_plane,
    517 		nv20_emit_clip_plane,
    518 		nv20_emit_clip_plane,
    519 		nv20_emit_clip_plane,
    520 		nv20_emit_clip_plane,
    521 		nv10_emit_color_mask,
    522 		nv20_emit_color_material,
    523 		nv10_emit_cull_face,
    524 		nv10_emit_front_face,
    525 		nv10_emit_depth,
    526 		nv10_emit_dither,
    527 		nv20_emit_frag,
    528 		nv20_emit_framebuffer,
    529 		nv20_emit_fog,
    530 		nv10_emit_light_enable,
    531 		nv20_emit_light_model,
    532 		nv20_emit_light_source,
    533 		nv20_emit_light_source,
    534 		nv20_emit_light_source,
    535 		nv20_emit_light_source,
    536 		nv20_emit_light_source,
    537 		nv20_emit_light_source,
    538 		nv20_emit_light_source,
    539 		nv20_emit_light_source,
    540 		nv10_emit_line_stipple,
    541 		nv10_emit_line_mode,
    542 		nv20_emit_logic_opcode,
    543 		nv20_emit_material_ambient,
    544 		nv20_emit_material_ambient,
    545 		nv20_emit_material_diffuse,
    546 		nv20_emit_material_diffuse,
    547 		nv20_emit_material_specular,
    548 		nv20_emit_material_specular,
    549 		nv20_emit_material_shininess,
    550 		nv20_emit_material_shininess,
    551 		nv20_emit_modelview,
    552 		nv20_emit_point_mode,
    553 		nv10_emit_point_parameter,
    554 		nv10_emit_polygon_mode,
    555 		nv10_emit_polygon_offset,
    556 		nv10_emit_polygon_stipple,
    557 		nv20_emit_projection,
    558 		nv10_emit_render_mode,
    559 		nv10_emit_scissor,
    560 		nv10_emit_shade_model,
    561 		nv10_emit_stencil_func,
    562 		nv10_emit_stencil_mask,
    563 		nv10_emit_stencil_op,
    564 		nv20_emit_tex_env,
    565 		nv20_emit_tex_env,
    566 		nv20_emit_tex_env,
    567 		nv20_emit_tex_env,
    568 		nv20_emit_tex_gen,
    569 		nv20_emit_tex_gen,
    570 		nv20_emit_tex_gen,
    571 		nv20_emit_tex_gen,
    572 		nv20_emit_tex_mat,
    573 		nv20_emit_tex_mat,
    574 		nv20_emit_tex_mat,
    575 		nv20_emit_tex_mat,
    576 		nv20_emit_tex_obj,
    577 		nv20_emit_tex_obj,
    578 		nv20_emit_tex_obj,
    579 		nv20_emit_tex_obj,
    580 		nv20_emit_viewport,
    581 		nv20_emit_tex_shader
    582 	},
    583 	.num_emit = NUM_NV20_STATE,
    584 };
    585