nouveau: Always render offscreen, emulate front buffer rendering.
[mesa.git] / src / mesa / drivers / dri / nouveau / nv30_state.c
1 /**************************************************************************
2
3 Copyright 2006 Nouveau
4 All Rights Reserved.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 on the rights to use, copy, modify, merge, publish, distribute, sub
10 license, and/or sell copies of the Software, and to permit persons to whom
11 the Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice (including the next
14 paragraph) shall be included in all copies or substantial portions of the
15 Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
21 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 **************************************************************************/
26
27 #include "nouveau_context.h"
28 #include "nouveau_object.h"
29 #include "nouveau_fifo.h"
30 #include "nouveau_reg.h"
31 #include "nouveau_state.h"
32
33 #include "tnl/t_pipeline.h"
34
35 #include "mtypes.h"
36 #include "colormac.h"
37
38 #define NOUVEAU_CARD_USING_SHADERS (nmesa->screen->card->type >= NV_40)
39
40 static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
41 {
42 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
43 GLubyte ubRef;
44 CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
45
46 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
47 OUT_RING_CACHE(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */
48 OUT_RING_CACHE(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */
49 }
50
51 static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4])
52 {
53 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
54 GLubyte cf[4];
55
56 CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
57 CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
58 CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
59 CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
60
61 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
62 OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
63 }
64
65 static void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
66 {
67 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
68 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
69 OUT_RING_CACHE((modeA<<16) | modeRGB);
70 }
71
72
73 static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
74 GLenum sfactorA, GLenum dfactorA)
75 {
76 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
77 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
78 OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
79 OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
80 }
81
82 static void nv30Clear(GLcontext *ctx, GLbitfield mask)
83 {
84 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
85 GLuint hw_bufs = 0;
86
87 if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
88 hw_bufs |= 0xf0;
89 if (mask & (BUFFER_BIT_DEPTH))
90 hw_bufs |= 0x03;
91
92 if (hw_bufs) {
93 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1);
94 OUT_RING(hw_bufs);
95 }
96 }
97
98 static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4])
99 {
100 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
101 GLubyte c[4];
102 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
103 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
104 OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
105 }
106
107 static void nv30ClearDepth(GLcontext *ctx, GLclampd d)
108 {
109 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
110 nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
111 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
112 OUT_RING_CACHE(nmesa->clear_value);
113 }
114
115 /* we're don't support indexed buffers
116 void (*ClearIndex)(GLcontext *ctx, GLuint index)
117 */
118
119 static void nv30ClearStencil(GLcontext *ctx, GLint s)
120 {
121 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
122 nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
123 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
124 OUT_RING_CACHE(nmesa->clear_value);
125 }
126
127 static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
128 {
129 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
130
131 if (NOUVEAU_CARD_USING_SHADERS)
132 return;
133
134 plane -= GL_CLIP_PLANE0;
135 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
136 OUT_RING_CACHEf(equation[0]);
137 OUT_RING_CACHEf(equation[1]);
138 OUT_RING_CACHEf(equation[2]);
139 OUT_RING_CACHEf(equation[3]);
140 }
141
142 static void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
143 GLboolean bmask, GLboolean amask )
144 {
145 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
146 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
147 OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
148 }
149
150 static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
151 {
152 // TODO I need love
153 }
154
155 static void nv30CullFace(GLcontext *ctx, GLenum mode)
156 {
157 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
158 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1);
159 OUT_RING_CACHE(mode);
160 }
161
162 static void nv30FrontFace(GLcontext *ctx, GLenum mode)
163 {
164 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
165 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
166 OUT_RING_CACHE(mode);
167 }
168
169 static void nv30DepthFunc(GLcontext *ctx, GLenum func)
170 {
171 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
172 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
173 OUT_RING_CACHE(func);
174 }
175
176 static void nv30DepthMask(GLcontext *ctx, GLboolean flag)
177 {
178 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
179 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
180 OUT_RING_CACHE(flag);
181 }
182
183 static void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
184 {
185 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
186 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
187 OUT_RING_CACHEf(nearval);
188 OUT_RING_CACHEf(farval);
189 }
190
191 /** Specify the current buffer for writing */
192 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
193 /** Specify the buffers for writing for fragment programs*/
194 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
195
196 static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
197 {
198 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
199 switch(cap)
200 {
201 case GL_ALPHA_TEST:
202 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
203 OUT_RING_CACHE(state);
204 break;
205 // case GL_AUTO_NORMAL:
206 case GL_BLEND:
207 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
208 OUT_RING_CACHE(state);
209 break;
210 case GL_CLIP_PLANE0:
211 case GL_CLIP_PLANE1:
212 case GL_CLIP_PLANE2:
213 case GL_CLIP_PLANE3:
214 case GL_CLIP_PLANE4:
215 case GL_CLIP_PLANE5:
216 if (NOUVEAU_CARD_USING_SHADERS) {
217 nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current;
218 if (nvs)
219 nvs->translated = GL_FALSE;
220 } else {
221 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
222 OUT_RING_CACHE(state);
223 }
224 break;
225 case GL_COLOR_LOGIC_OP:
226 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
227 OUT_RING_CACHE(state);
228 break;
229 // case GL_COLOR_MATERIAL:
230 // case GL_COLOR_SUM_EXT:
231 // case GL_COLOR_TABLE:
232 // case GL_CONVOLUTION_1D:
233 // case GL_CONVOLUTION_2D:
234 case GL_CULL_FACE:
235 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
236 OUT_RING_CACHE(state);
237 break;
238 case GL_DEPTH_TEST:
239 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
240 OUT_RING_CACHE(state);
241 break;
242 case GL_DITHER:
243 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
244 OUT_RING_CACHE(state);
245 break;
246 case GL_FOG:
247 if (NOUVEAU_CARD_USING_SHADERS)
248 break;
249 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
250 OUT_RING_CACHE(state);
251 break;
252 // case GL_HISTOGRAM:
253 // case GL_INDEX_LOGIC_OP:
254 case GL_LIGHT0:
255 case GL_LIGHT1:
256 case GL_LIGHT2:
257 case GL_LIGHT3:
258 case GL_LIGHT4:
259 case GL_LIGHT5:
260 case GL_LIGHT6:
261 case GL_LIGHT7:
262 {
263 uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
264
265 if (NOUVEAU_CARD_USING_SHADERS)
266 break;
267
268 nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
269 if (nmesa->lighting_enabled)
270 {
271 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
272 OUT_RING_CACHE(nmesa->enabled_lights);
273 }
274 break;
275 }
276 case GL_LIGHTING:
277 if (NOUVEAU_CARD_USING_SHADERS)
278 break;
279
280 nmesa->lighting_enabled=state;
281 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
282 if (nmesa->lighting_enabled)
283 OUT_RING_CACHE(nmesa->enabled_lights);
284 else
285 OUT_RING_CACHE(0x0);
286 break;
287 // case GL_LINE_SMOOTH:
288 // case GL_LINE_STIPPLE:
289 // case GL_MAP1_COLOR_4:
290 // case GL_MAP1_INDEX:
291 // case GL_MAP1_NORMAL:
292 // case GL_MAP1_TEXTURE_COORD_1:
293 // case GL_MAP1_TEXTURE_COORD_2:
294 // case GL_MAP1_TEXTURE_COORD_3:
295 // case GL_MAP1_TEXTURE_COORD_4:
296 // case GL_MAP1_VERTEX_3:
297 // case GL_MAP1_VERTEX_4:
298 // case GL_MAP2_COLOR_4:
299 // case GL_MAP2_INDEX:
300 // case GL_MAP2_NORMAL:
301 // case GL_MAP2_TEXTURE_COORD_1:
302 // case GL_MAP2_TEXTURE_COORD_2:
303 // case GL_MAP2_TEXTURE_COORD_3:
304 // case GL_MAP2_TEXTURE_COORD_4:
305 // case GL_MAP2_VERTEX_3:
306 // case GL_MAP2_VERTEX_4:
307 // case GL_MINMAX:
308 case GL_NORMALIZE:
309 if (nmesa->screen->card->type != NV_44) {
310 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
311 OUT_RING_CACHE(state);
312 }
313 break;
314 // case GL_POINT_SMOOTH:
315 case GL_POLYGON_OFFSET_POINT:
316 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
317 OUT_RING_CACHE(state);
318 break;
319 case GL_POLYGON_OFFSET_LINE:
320 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
321 OUT_RING_CACHE(state);
322 break;
323 case GL_POLYGON_OFFSET_FILL:
324 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
325 OUT_RING_CACHE(state);
326 break;
327 case GL_POLYGON_SMOOTH:
328 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
329 OUT_RING_CACHE(state);
330 break;
331 case GL_POLYGON_STIPPLE:
332 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
333 OUT_RING_CACHE(state);
334 break;
335 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
336 // case GL_POST_CONVOLUTION_COLOR_TABLE:
337 // case GL_RESCALE_NORMAL:
338 case GL_SCISSOR_TEST:
339 /* No enable bit, nv30Scissor will adjust to max range */
340 ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
341 ctx->Scissor.Width, ctx->Scissor.Height);
342 break;
343 // case GL_SEPARABLE_2D:
344 case GL_STENCIL_TEST:
345 // TODO BACK and FRONT ?
346 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
347 OUT_RING_CACHE(state);
348 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
349 OUT_RING_CACHE(state);
350 break;
351 // case GL_TEXTURE_GEN_Q:
352 // case GL_TEXTURE_GEN_R:
353 // case GL_TEXTURE_GEN_S:
354 // case GL_TEXTURE_GEN_T:
355 // case GL_TEXTURE_1D:
356 // case GL_TEXTURE_2D:
357 // case GL_TEXTURE_3D:
358 }
359 }
360
361 static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
362 {
363 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
364
365 if (NOUVEAU_CARD_USING_SHADERS)
366 return;
367
368 switch(pname)
369 {
370 case GL_FOG_MODE:
371 {
372 int mode = 0;
373 /* The modes are different in GL and the card. */
374 switch(ctx->Fog.Mode)
375 {
376 case GL_LINEAR:
377 mode = 0x804;
378 break;
379 case GL_EXP:
380 mode = 0x802;
381 break;
382 case GL_EXP2:
383 mode = 0x803;
384 break;
385 }
386 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1);
387 OUT_RING_CACHE (mode);
388 break;
389 }
390 case GL_FOG_COLOR:
391 {
392 GLubyte c[4];
393 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params);
394 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1);
395 /* nvidia ignores the alpha channel */
396 OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
397 break;
398 }
399 case GL_FOG_DENSITY:
400 case GL_FOG_START:
401 case GL_FOG_END:
402 {
403 GLfloat f=0., c=0.;
404 switch(ctx->Fog.Mode)
405 {
406 case GL_LINEAR:
407 f = -1.0/(ctx->Fog.End - ctx->Fog.Start);
408 c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953;
409 break;
410 case GL_EXP:
411 f = -0.090168*ctx->Fog.Density;
412 c = 1.5;
413 case GL_EXP2:
414 f = -0.212330*ctx->Fog.Density;
415 c = 1.5;
416 }
417 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1);
418 OUT_RING_CACHE(f);
419 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1);
420 OUT_RING_CACHE(c);
421 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1);
422 OUT_RING_CACHE(0); /* Is this always the same? */
423 break;
424 }
425 // case GL_FOG_COORD_SRC:
426 default:
427 break;
428 }
429 }
430
431 static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode)
432 {
433 // TODO I need love (fog and line_smooth hints)
434 }
435
436 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
437
438 enum {
439 SPOTLIGHT_NO_UPDATE,
440 SPOTLIGHT_UPDATE_EXPONENT,
441 SPOTLIGHT_UPDATE_DIRECTION,
442 SPOTLIGHT_UPDATE_ALL
443 };
444
445 static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
446 {
447 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
448 GLint p = light - GL_LIGHT0;
449 struct gl_light *l = &ctx->Light.Light[p];
450 int spotlight_update = SPOTLIGHT_NO_UPDATE;
451
452 if (NOUVEAU_CARD_USING_SHADERS)
453 return;
454
455 /* not sure where the fourth param value goes...*/
456 switch(pname)
457 {
458 case GL_AMBIENT:
459 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
460 OUT_RING_CACHEf(params[0]);
461 OUT_RING_CACHEf(params[1]);
462 OUT_RING_CACHEf(params[2]);
463 break;
464 case GL_DIFFUSE:
465 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
466 OUT_RING_CACHEf(params[0]);
467 OUT_RING_CACHEf(params[1]);
468 OUT_RING_CACHEf(params[2]);
469 break;
470 case GL_SPECULAR:
471 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
472 OUT_RING_CACHEf(params[0]);
473 OUT_RING_CACHEf(params[1]);
474 OUT_RING_CACHEf(params[2]);
475 break;
476 case GL_POSITION:
477 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
478 OUT_RING_CACHEf(params[0]);
479 OUT_RING_CACHEf(params[1]);
480 OUT_RING_CACHEf(params[2]);
481 break;
482 case GL_SPOT_DIRECTION:
483 spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
484 break;
485 case GL_SPOT_EXPONENT:
486 spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
487 break;
488 case GL_SPOT_CUTOFF:
489 spotlight_update = SPOTLIGHT_UPDATE_ALL;
490 break;
491 case GL_CONSTANT_ATTENUATION:
492 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
493 OUT_RING_CACHEf(*params);
494 break;
495 case GL_LINEAR_ATTENUATION:
496 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
497 OUT_RING_CACHEf(*params);
498 break;
499 case GL_QUADRATIC_ATTENUATION:
500 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
501 OUT_RING_CACHEf(*params);
502 break;
503 default:
504 break;
505 }
506
507 switch(spotlight_update) {
508 case SPOTLIGHT_UPDATE_DIRECTION:
509 {
510 GLfloat x,y,z;
511 GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
512 x = spot_light_coef_a * l->_NormDirection[0];
513 y = spot_light_coef_a * l->_NormDirection[1];
514 z = spot_light_coef_a * l->_NormDirection[2];
515 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
516 OUT_RING_CACHEf(x);
517 OUT_RING_CACHEf(y);
518 OUT_RING_CACHEf(z);
519 }
520 break;
521 case SPOTLIGHT_UPDATE_EXPONENT:
522 {
523 GLfloat cc,lc,qc;
524 cc = 1.0; /* FIXME: These need to be correctly computed */
525 lc = 0.0;
526 qc = 2.0;
527 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
528 OUT_RING_CACHEf(cc);
529 OUT_RING_CACHEf(lc);
530 OUT_RING_CACHEf(qc);
531 }
532 break;
533 case SPOTLIGHT_UPDATE_ALL:
534 {
535 GLfloat cc,lc,qc, x,y,z, c;
536 GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
537 cc = 1.0; /* FIXME: These need to be correctly computed */
538 lc = 0.0;
539 qc = 2.0;
540 x = spot_light_coef_a * l->_NormDirection[0];
541 y = spot_light_coef_a * l->_NormDirection[1];
542 z = spot_light_coef_a * l->_NormDirection[2];
543 c = spot_light_coef_a + 1.0;
544 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
545 OUT_RING_CACHEf(cc);
546 OUT_RING_CACHEf(lc);
547 OUT_RING_CACHEf(qc);
548 OUT_RING_CACHEf(x);
549 OUT_RING_CACHEf(y);
550 OUT_RING_CACHEf(z);
551 OUT_RING_CACHEf(c);
552 }
553 break;
554 default:
555 break;
556 }
557 }
558
559 /** Set the lighting model parameters */
560 void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
561
562
563 static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
564 {
565 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
566 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
567 OUT_RING_CACHE((pattern << 16) | factor);
568 }
569
570 static void nv30LineWidth(GLcontext *ctx, GLfloat width)
571 {
572 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
573 GLubyte ubWidth;
574
575 ubWidth = (GLubyte)(width * 8.0) & 0xFF;
576
577 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1);
578 OUT_RING_CACHE(ubWidth);
579 }
580
581 static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode)
582 {
583 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
584 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
585 OUT_RING_CACHE(opcode);
586 }
587
588 static void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
589 {
590 /*TODO: not sure what goes here. */
591 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
592
593 }
594
595 /** Specify the diameter of rasterized points */
596 static void nv30PointSize(GLcontext *ctx, GLfloat size)
597 {
598 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
599 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
600 OUT_RING_CACHEf(size);
601 }
602
603 /** Select a polygon rasterization mode */
604 static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
605 {
606 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
607
608 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
609 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
610 OUT_RING_CACHE(mode);
611 }
612 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
613 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
614 OUT_RING_CACHE(mode);
615 }
616 }
617
618 /** Set the scale and units used to calculate depth values */
619 static void nv30PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
620 {
621 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
622 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
623 OUT_RING_CACHEf(factor);
624
625 /* Looks like we always multiply units by 2.0... according to the dumps.*/
626 OUT_RING_CACHEf(units * 2.0);
627 }
628
629 /** Set the polygon stippling pattern */
630 static void nv30PolygonStipple(GLcontext *ctx, const GLubyte *mask )
631 {
632 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
633 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
634 OUT_RING_CACHEp(mask, 32);
635 }
636
637 /* Specifies the current buffer for reading */
638 void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
639 /** Set rasterization mode */
640 void (*RenderMode)(GLcontext *ctx, GLenum mode );
641
642 /* Translate GL coords to window coords, clamping w/h to the
643 * dimensions of the window.
644 */
645 static void nv30WindowCoords(nouveauContextPtr nmesa,
646 GLuint x, GLuint y, GLuint w, GLuint h,
647 GLuint *wX, GLuint *wY, GLuint *wW, GLuint *wH)
648 {
649 if ((x+w) > nmesa->drawW)
650 w = nmesa->drawW - x;
651 (*wX) = x + nmesa->drawX;
652 (*wW) = w;
653
654 if ((y+h) > nmesa->drawH)
655 h = nmesa->drawH - y;
656 (*wY) = (nmesa->drawH - y) - h + nmesa->drawY;
657 (*wH) = h;
658 }
659
660 /** Define the scissor box */
661 static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
662 {
663 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
664 GLuint wX, wY, wW, wH;
665
666 /* There's no scissor enable bit, so adjust the scissor to cover the
667 * maximum draw buffer bounds
668 */
669 if (!ctx->Scissor.Enabled) {
670 wX = nmesa->drawX;
671 wY = nmesa->drawY;
672 wW = nmesa->drawW;
673 wH = nmesa->drawH;
674 } else {
675 nv30WindowCoords(nmesa, x, y, w, h, &wX, &wY, &wW, &wH);
676 }
677
678 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
679 OUT_RING_CACHE ((wW << 16) | wX);
680 OUT_RING_CACHE ((wH << 16) | wY);
681 }
682
683 /** Select flat or smooth shading */
684 static void nv30ShadeModel(GLcontext *ctx, GLenum mode)
685 {
686 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
687
688 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
689 OUT_RING_CACHE(mode);
690 }
691
692 /** OpenGL 2.0 two-sided StencilFunc */
693 static void nv30StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
694 GLint ref, GLuint mask)
695 {
696 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
697
698 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
699 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3);
700 OUT_RING_CACHE(func);
701 OUT_RING_CACHE(ref);
702 OUT_RING_CACHE(mask);
703 }
704 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
705 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3);
706 OUT_RING_CACHE(func);
707 OUT_RING_CACHE(ref);
708 OUT_RING_CACHE(mask);
709 }
710 }
711
712 /** OpenGL 2.0 two-sided StencilMask */
713 static void nv30StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
714 {
715 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
716
717 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
718 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1);
719 OUT_RING_CACHE(mask);
720 }
721 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
722 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1);
723 OUT_RING_CACHE(mask);
724 }
725 }
726
727 /** OpenGL 2.0 two-sided StencilOp */
728 static void nv30StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
729 GLenum zfail, GLenum zpass)
730 {
731 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
732
733 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
734 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3);
735 OUT_RING_CACHE(fail);
736 OUT_RING_CACHE(zfail);
737 OUT_RING_CACHE(zpass);
738 }
739 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
740 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3);
741 OUT_RING_CACHE(fail);
742 OUT_RING_CACHE(zfail);
743 OUT_RING_CACHE(zpass);
744 }
745 }
746
747 /** Control the generation of texture coordinates */
748 void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
749 const GLfloat *params);
750 /** Set texture environment parameters */
751 void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
752 const GLfloat *param);
753 /** Set texture parameters */
754 void (*TexParameter)(GLcontext *ctx, GLenum target,
755 struct gl_texture_object *texObj,
756 GLenum pname, const GLfloat *params);
757
758 static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
759 {
760 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
761
762 if (!NOUVEAU_CARD_USING_SHADERS) {
763 BEGIN_RING_CACHE(NvSub3D,
764 NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
765 /*XXX: This SHOULD work.*/
766 OUT_RING_CACHEp(mat->m, 16);
767 }
768 }
769
770 static void nv30WindowMoved(nouveauContextPtr nmesa)
771 {
772 GLcontext *ctx = nmesa->glCtx;
773 GLfloat *v = nmesa->viewport.m;
774 GLuint wX, wY, wW, wH;
775
776 nv30WindowCoords(nmesa, ctx->Viewport.X, ctx->Viewport.Y,
777 ctx->Viewport.Width, ctx->Viewport.Height,
778 &wX, &wY, &wW, &wH);
779 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
780 OUT_RING_CACHE ((wW << 16) | wX);
781 OUT_RING_CACHE ((wH << 16) | wY);
782
783 /* something to do with clears, possibly doesn't belong here */
784 BEGIN_RING_CACHE(NvSub3D,
785 NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
786 OUT_RING_CACHE(((nmesa->drawX + nmesa->drawW) << 16) | nmesa->drawX);
787 OUT_RING_CACHE(((nmesa->drawY + nmesa->drawH) << 16) | nmesa->drawY);
788
789 /* viewport transform */
790 BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
791 OUT_RING_CACHEf (v[MAT_TX]);
792 OUT_RING_CACHEf (v[MAT_TY]);
793 OUT_RING_CACHEf (v[MAT_TZ]);
794 OUT_RING_CACHEf (0.0);
795 OUT_RING_CACHEf (v[MAT_SX]);
796 OUT_RING_CACHEf (v[MAT_SY]);
797 OUT_RING_CACHEf (v[MAT_SZ]);
798 OUT_RING_CACHEf (0.0);
799
800 ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
801 ctx->Scissor.Width, ctx->Scissor.Height);
802 }
803
804 static GLboolean nv30InitCard(nouveauContextPtr nmesa)
805 {
806 int i;
807 nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
808
809 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3);
810 OUT_RING(NvDmaFB);
811 OUT_RING(NvDmaTT);
812 OUT_RING(NvDmaFB);
813 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
814 OUT_RING(NvDmaFB);
815 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
816 OUT_RING(NvDmaFB);
817 OUT_RING(NvDmaFB);
818 BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/
819 OUT_RING(NvDmaFB);
820
821 for(i = 0x2c8; i <= 0x2fc; i += 4)
822 {
823 BEGIN_RING_SIZE(NvSub3D, i, 1);
824 OUT_RING(0x0);
825 }
826
827 BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
828 OUT_RING(1);
829
830 BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1);
831 OUT_RING(0x00100000);
832 BEGIN_RING_SIZE(NvSub3D, 0x1454, 1);
833 OUT_RING(0);
834 BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
835 OUT_RING(3);
836
837 /* NEW */
838 BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
839 OUT_RING(0);
840 BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
841 OUT_RING(0);
842 OUT_RING(0);
843 OUT_RING(0x3f800000);
844 BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16);
845 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
846 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
847 OUT_RING(0x0000ffff);
848 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
849 OUT_RING(0); OUT_RING(0); OUT_RING(0);
850 /*
851 BEGIN_RING_SIZE(NvSub3D, 0x100, 2);
852 OUT_RING(0);
853 OUT_RING(0);
854 */
855 BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
856 OUT_RING(0);
857 OUT_RING(1);
858 OUT_RING(2);
859
860 BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
861 OUT_RING(0x00001200);
862
863 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
864 OUT_RING (0);
865
866 return GL_TRUE;
867 }
868
869 static GLboolean nv40InitCard(nouveauContextPtr nmesa)
870 {
871 nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
872
873 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
874 OUT_RING(NvDmaFB);
875 OUT_RING(NvDmaFB);
876 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
877 OUT_RING(NvDmaFB);
878 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
879 OUT_RING(NvDmaFB);
880 OUT_RING(NvDmaFB);
881 BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
882 OUT_RING(1);
883
884 BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3);
885 OUT_RING(0x00000010);
886 OUT_RING(0x01000100);
887 OUT_RING(0xff800006);
888 BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1);
889 OUT_RING(0x06144321);
890 BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2);
891 OUT_RING(0xedcba987);
892 OUT_RING(0x00000021);
893 BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1);
894 OUT_RING(0x00171615);
895 BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1);
896 OUT_RING(0x001b1a19);
897
898 BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1);
899 OUT_RING(0x0020ffff);
900 BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1);
901 OUT_RING(0x00d30000);
902 BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1);
903 OUT_RING(0x00000001);
904
905 return GL_TRUE;
906 }
907
908 static GLboolean
909 nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
910 nouveau_renderbuffer_t **color, nouveau_renderbuffer_t *depth)
911 {
912 GLuint x, y, w, h;
913
914 w = color[0]->mesa.Width;
915 h = color[0]->mesa.Height;
916 x = nmesa->drawX;
917 y = nmesa->drawY;
918
919 if (num_color != 1)
920 return GL_FALSE;
921 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
922 OUT_RING (((w+x)<<16)|x);
923 OUT_RING (((h+y)<<16)|y);
924 if (color[0]->mesa._ActualFormat == GL_RGBA8)
925 OUT_RING (0x148);
926 else
927 OUT_RING (0x143);
928 if (nmesa->screen->card->type >= NV_40)
929 OUT_RING (color[0]->pitch);
930 else
931 OUT_RING (color[0]->pitch | (depth ? (depth->pitch << 16): 0));
932 OUT_RING (color[0]->offset);
933
934 if (depth) {
935 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
936 OUT_RING (depth->offset);
937 if (nmesa->screen->card->type >= NV_40) {
938 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
939 OUT_RING (depth->pitch);
940 }
941 }
942
943 return GL_TRUE;
944 }
945
946 void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
947 {
948 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
949
950 func->AlphaFunc = nv30AlphaFunc;
951 func->BlendColor = nv30BlendColor;
952 func->BlendEquationSeparate = nv30BlendEquationSeparate;
953 func->BlendFuncSeparate = nv30BlendFuncSeparate;
954 func->Clear = nv30Clear;
955 func->ClearColor = nv30ClearColor;
956 func->ClearDepth = nv30ClearDepth;
957 func->ClearStencil = nv30ClearStencil;
958 func->ClipPlane = nv30ClipPlane;
959 func->ColorMask = nv30ColorMask;
960 func->ColorMaterial = nv30ColorMaterial;
961 func->CullFace = nv30CullFace;
962 func->FrontFace = nv30FrontFace;
963 func->DepthFunc = nv30DepthFunc;
964 func->DepthMask = nv30DepthMask;
965 func->DepthRange = nv30DepthRange;
966 func->Enable = nv30Enable;
967 func->Fogfv = nv30Fogfv;
968 func->Hint = nv30Hint;
969 func->Lightfv = nv30Lightfv;
970 /* func->LightModelfv = nv30LightModelfv; */
971 func->LineStipple = nv30LineStipple;
972 func->LineWidth = nv30LineWidth;
973 func->LogicOpcode = nv30LogicOpcode;
974 func->PointParameterfv = nv30PointParameterfv;
975 func->PointSize = nv30PointSize;
976 func->PolygonMode = nv30PolygonMode;
977 func->PolygonOffset = nv30PolygonOffset;
978 func->PolygonStipple = nv30PolygonStipple;
979 #if 0
980 func->ReadBuffer = nv30ReadBuffer;
981 func->RenderMode = nv30RenderMode;
982 #endif
983 func->Scissor = nv30Scissor;
984 func->ShadeModel = nv30ShadeModel;
985 func->StencilFuncSeparate = nv30StencilFuncSeparate;
986 func->StencilMaskSeparate = nv30StencilMaskSeparate;
987 func->StencilOpSeparate = nv30StencilOpSeparate;
988 #if 0
989 func->TexGen = nv30TexGen;
990 func->TexParameter = nv30TexParameter;
991 #endif
992 func->TextureMatrix = nv30TextureMatrix;
993
994
995 if (nmesa->screen->card->type >= NV_40)
996 nmesa->hw_func.InitCard = nv40InitCard;
997 else
998 nmesa->hw_func.InitCard = nv30InitCard;
999 nmesa->hw_func.BindBuffers = nv30BindBuffers;
1000 nmesa->hw_func.WindowMoved = nv30WindowMoved;
1001 }
1002