Merge branch 'master' of git+ssh://znh@git.freedesktop.org/git/mesa/mesa into 965...
[mesa.git] / src / mesa / drivers / dri / nouveau / nv10_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
32 #include "tnl/t_pipeline.h"
33
34 #include "mtypes.h"
35 #include "colormac.h"
36
37 static void nv10ViewportScale(nouveauContextPtr nmesa)
38 {
39 GLcontext *ctx = nmesa->glCtx;
40 GLuint w = ctx->Viewport.Width;
41 GLuint h = ctx->Viewport.Height;
42
43 GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5;
44 /* if (ctx->DrawBuffer) {
45 switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) {
46 case 16:
47 max_depth *= 32767.0;
48 break;
49 case 24:
50 max_depth *= 16777215.0;
51 break;
52 }
53 } else {*/
54 /* Default to 24 bits range */
55 max_depth *= 16777215.0;
56 /* }*/
57
58 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4);
59 OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0);
60 OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0);
61 OUT_RING_CACHEf (max_depth);
62 OUT_RING_CACHEf (0.0);
63 }
64
65 static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
66 {
67 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
68 GLubyte ubRef;
69 CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
70
71 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
72 OUT_RING_CACHE(func);
73 OUT_RING_CACHE(ubRef);
74 }
75
76 static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4])
77 {
78 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
79 GLubyte cf[4];
80
81 CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
82 CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
83 CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
84 CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
85
86 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
87 OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
88 }
89
90 static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
91 {
92 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
93
94 assert( modeRGB == modeA );
95
96 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
97 OUT_RING_CACHE(modeRGB);
98 }
99
100
101 static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
102 GLenum sfactorA, GLenum dfactorA)
103 {
104 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
105
106 assert( sfactorRGB == sfactorA );
107 assert( dfactorRGB == dfactorA );
108
109 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
110 OUT_RING_CACHE(sfactorRGB);
111 OUT_RING_CACHE(dfactorRGB);
112 }
113
114 static void nv10Clear(GLcontext *ctx, GLbitfield mask)
115 {
116 /* TODO */
117 }
118
119 static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4])
120 {
121 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
122 GLubyte c[4];
123 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
124 nmesa->clear_color_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
125 }
126
127 static void nv10ClearDepth(GLcontext *ctx, GLclampd d)
128 {
129 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
130
131 /* switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) {
132 case 16:
133 nmesa->clear_value = (uint32_t)(d*0x7FFF);
134 break;
135 case 24:*/
136 nmesa->clear_value = ((nmesa->clear_value&0x000000FF) |
137 (((uint32_t)(d*0xFFFFFF))<<8));
138 /* break;
139 }*/
140 }
141
142 static void nv10ClearStencil(GLcontext *ctx, GLint s)
143 {
144 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
145
146 /* if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) {*/
147 nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)|
148 (s&0x000000FF));
149 /* }*/
150 }
151
152 static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
153 {
154 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
155 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
156 OUT_RING_CACHEf(equation[0]);
157 OUT_RING_CACHEf(equation[1]);
158 OUT_RING_CACHEf(equation[2]);
159 OUT_RING_CACHEf(equation[3]);
160 }
161
162 static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
163 GLboolean bmask, GLboolean amask )
164 {
165 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
166 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
167 OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
168 }
169
170 static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
171 {
172 /* TODO I need love */
173 }
174
175 static void nv10CullFace(GLcontext *ctx, GLenum mode)
176 {
177 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
178 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1);
179 OUT_RING_CACHE(mode);
180 }
181
182 static void nv10FrontFace(GLcontext *ctx, GLenum mode)
183 {
184 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
185 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
186 OUT_RING_CACHE(mode);
187 }
188
189 static void nv10DepthFunc(GLcontext *ctx, GLenum func)
190 {
191 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
192 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
193 OUT_RING_CACHE(func);
194 }
195
196 static void nv10DepthMask(GLcontext *ctx, GLboolean flag)
197 {
198 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
199 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
200 OUT_RING_CACHE(flag);
201 }
202
203 static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
204 {
205 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
206
207 GLfloat depth_scale = 16777216.0;
208 if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) {
209 depth_scale = 32768.0;
210 }
211
212 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
213 OUT_RING_CACHEf(nearval * depth_scale);
214 OUT_RING_CACHEf(farval * depth_scale);
215
216 nv10ViewportScale(nmesa);
217 }
218
219 /** Specify the current buffer for writing */
220 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
221 /** Specify the buffers for writing for fragment programs*/
222 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
223
224 static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state)
225 {
226 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
227 switch(cap)
228 {
229 case GL_ALPHA_TEST:
230 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
231 OUT_RING_CACHE(state);
232 break;
233 // case GL_AUTO_NORMAL:
234 case GL_BLEND:
235 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
236 OUT_RING_CACHE(state);
237 break;
238 case GL_CLIP_PLANE0:
239 case GL_CLIP_PLANE1:
240 case GL_CLIP_PLANE2:
241 case GL_CLIP_PLANE3:
242 case GL_CLIP_PLANE4:
243 case GL_CLIP_PLANE5:
244 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
245 OUT_RING_CACHE(state);
246 break;
247 case GL_COLOR_LOGIC_OP:
248 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
249 OUT_RING_CACHE(state);
250 break;
251 // case GL_COLOR_MATERIAL:
252 // case GL_COLOR_SUM_EXT:
253 // case GL_COLOR_TABLE:
254 // case GL_CONVOLUTION_1D:
255 // case GL_CONVOLUTION_2D:
256 case GL_CULL_FACE:
257 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
258 OUT_RING_CACHE(state);
259 break;
260 case GL_DEPTH_TEST:
261 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
262 OUT_RING_CACHE(state);
263 break;
264 case GL_DITHER:
265 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
266 OUT_RING_CACHE(state);
267 break;
268 case GL_FOG:
269 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
270 OUT_RING_CACHE(state);
271 break;
272 // case GL_HISTOGRAM:
273 // case GL_INDEX_LOGIC_OP:
274 case GL_LIGHT0:
275 case GL_LIGHT1:
276 case GL_LIGHT2:
277 case GL_LIGHT3:
278 case GL_LIGHT4:
279 case GL_LIGHT5:
280 case GL_LIGHT6:
281 case GL_LIGHT7:
282 {
283 uint32_t mask=1<<(2*(cap-GL_LIGHT0));
284 nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
285 if (nmesa->lighting_enabled)
286 {
287 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
288 OUT_RING_CACHE(nmesa->enabled_lights);
289 }
290 break;
291 }
292 case GL_LIGHTING:
293 nmesa->lighting_enabled=state;
294 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
295 if (nmesa->lighting_enabled)
296 OUT_RING_CACHE(nmesa->enabled_lights);
297 else
298 OUT_RING_CACHE(0x0);
299 break;
300 case GL_LINE_SMOOTH:
301 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
302 OUT_RING_CACHE(state);
303 break;
304 // case GL_LINE_STIPPLE:
305 // case GL_MAP1_COLOR_4:
306 // case GL_MAP1_INDEX:
307 // case GL_MAP1_NORMAL:
308 // case GL_MAP1_TEXTURE_COORD_1:
309 // case GL_MAP1_TEXTURE_COORD_2:
310 // case GL_MAP1_TEXTURE_COORD_3:
311 // case GL_MAP1_TEXTURE_COORD_4:
312 // case GL_MAP1_VERTEX_3:
313 // case GL_MAP1_VERTEX_4:
314 // case GL_MAP2_COLOR_4:
315 // case GL_MAP2_INDEX:
316 // case GL_MAP2_NORMAL:
317 // case GL_MAP2_TEXTURE_COORD_1:
318 // case GL_MAP2_TEXTURE_COORD_2:
319 // case GL_MAP2_TEXTURE_COORD_3:
320 // case GL_MAP2_TEXTURE_COORD_4:
321 // case GL_MAP2_VERTEX_3:
322 // case GL_MAP2_VERTEX_4:
323 // case GL_MINMAX:
324 case GL_NORMALIZE:
325 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
326 OUT_RING_CACHE(state);
327 break;
328 // case GL_POINT_SMOOTH:
329 case GL_POLYGON_OFFSET_POINT:
330 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
331 OUT_RING_CACHE(state);
332 break;
333 case GL_POLYGON_OFFSET_LINE:
334 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
335 OUT_RING_CACHE(state);
336 break;
337 case GL_POLYGON_OFFSET_FILL:
338 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
339 OUT_RING_CACHE(state);
340 break;
341 case GL_POLYGON_SMOOTH:
342 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
343 OUT_RING_CACHE(state);
344 break;
345 // case GL_POLYGON_STIPPLE:
346 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
347 // case GL_POST_CONVOLUTION_COLOR_TABLE:
348 // case GL_RESCALE_NORMAL:
349 // case GL_SCISSOR_TEST:
350 // case GL_SEPARABLE_2D:
351 case GL_STENCIL_TEST:
352 // TODO BACK and FRONT ?
353 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1);
354 OUT_RING_CACHE(state);
355 break;
356 // case GL_TEXTURE_GEN_Q:
357 // case GL_TEXTURE_GEN_R:
358 // case GL_TEXTURE_GEN_S:
359 // case GL_TEXTURE_GEN_T:
360 // case GL_TEXTURE_1D:
361 // case GL_TEXTURE_2D:
362 // case GL_TEXTURE_3D:
363 }
364 }
365
366 static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
367 {
368 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
369 switch(pname)
370 {
371 case GL_FOG_MODE:
372 //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1);
373 //OUT_RING_CACHE (params);
374 break;
375 /* TODO: unsure about the rest.*/
376 default:
377 break;
378 }
379
380 }
381
382 static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode)
383 {
384 /* TODO I need love (fog and line_smooth hints) */
385 }
386
387 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
388
389 enum {
390 SPOTLIGHT_NO_UPDATE,
391 SPOTLIGHT_UPDATE_EXPONENT,
392 SPOTLIGHT_UPDATE_DIRECTION,
393 SPOTLIGHT_UPDATE_ALL
394 };
395
396 static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
397 {
398 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
399 GLint p = light - GL_LIGHT0;
400 struct gl_light *l = &ctx->Light.Light[p];
401 int spotlight_update = SPOTLIGHT_NO_UPDATE;
402
403 switch(pname)
404 {
405 case GL_AMBIENT:
406 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
407 OUT_RING_CACHEf(params[0]);
408 OUT_RING_CACHEf(params[1]);
409 OUT_RING_CACHEf(params[2]);
410 break;
411 case GL_DIFFUSE:
412 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
413 OUT_RING_CACHEf(params[0]);
414 OUT_RING_CACHEf(params[1]);
415 OUT_RING_CACHEf(params[2]);
416 break;
417 case GL_SPECULAR:
418 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
419 OUT_RING_CACHEf(params[0]);
420 OUT_RING_CACHEf(params[1]);
421 OUT_RING_CACHEf(params[2]);
422 break;
423 case GL_POSITION:
424 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
425 OUT_RING_CACHEf(params[0]);
426 OUT_RING_CACHEf(params[1]);
427 OUT_RING_CACHEf(params[2]);
428 break;
429 case GL_SPOT_DIRECTION:
430 spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
431 break;
432 case GL_SPOT_EXPONENT:
433 spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
434 break;
435 case GL_SPOT_CUTOFF:
436 spotlight_update = SPOTLIGHT_UPDATE_ALL;
437 break;
438 case GL_CONSTANT_ATTENUATION:
439 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
440 OUT_RING_CACHEf(*params);
441 break;
442 case GL_LINEAR_ATTENUATION:
443 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
444 OUT_RING_CACHEf(*params);
445 break;
446 case GL_QUADRATIC_ATTENUATION:
447 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
448 OUT_RING_CACHEf(*params);
449 break;
450 default:
451 break;
452 }
453
454 switch(spotlight_update) {
455 case SPOTLIGHT_UPDATE_DIRECTION:
456 {
457 GLfloat x,y,z;
458 GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
459 x = spot_light_coef_a * l->_NormDirection[0];
460 y = spot_light_coef_a * l->_NormDirection[1];
461 z = spot_light_coef_a * l->_NormDirection[2];
462 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
463 OUT_RING_CACHEf(x);
464 OUT_RING_CACHEf(y);
465 OUT_RING_CACHEf(z);
466 }
467 break;
468 case SPOTLIGHT_UPDATE_EXPONENT:
469 {
470 GLfloat cc,lc,qc;
471 cc = 1.0; /* FIXME: These need to be correctly computed */
472 lc = 0.0;
473 qc = 2.0;
474 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
475 OUT_RING_CACHEf(cc);
476 OUT_RING_CACHEf(lc);
477 OUT_RING_CACHEf(qc);
478 }
479 break;
480 case SPOTLIGHT_UPDATE_ALL:
481 {
482 GLfloat cc,lc,qc, x,y,z, c;
483 GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
484 cc = 1.0; /* FIXME: These need to be correctly computed */
485 lc = 0.0;
486 qc = 2.0;
487 x = spot_light_coef_a * l->_NormDirection[0];
488 y = spot_light_coef_a * l->_NormDirection[1];
489 z = spot_light_coef_a * l->_NormDirection[2];
490 c = spot_light_coef_a + 1.0;
491 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
492 OUT_RING_CACHEf(cc);
493 OUT_RING_CACHEf(lc);
494 OUT_RING_CACHEf(qc);
495 OUT_RING_CACHEf(x);
496 OUT_RING_CACHEf(y);
497 OUT_RING_CACHEf(z);
498 OUT_RING_CACHEf(c);
499 }
500 break;
501 default:
502 break;
503 }
504 }
505
506 /** Set the lighting model parameters */
507 static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
508
509
510 static void nv10LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
511 {
512 /* Not for NV10 */
513 }
514
515 static void nv10LineWidth(GLcontext *ctx, GLfloat width)
516 {
517 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
518 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
519 OUT_RING_CACHE(((int) (width * 8.0)) & -4);
520 }
521
522 static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode)
523 {
524 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
525 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
526 OUT_RING_CACHE(opcode);
527 }
528
529 static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
530 {
531 /*TODO: not sure what goes here. */
532 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
533
534 }
535
536 static void nv10PointSize(GLcontext *ctx, GLfloat size)
537 {
538 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
539 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
540 OUT_RING_CACHE(((int) (size * 8.0)) & -4);
541 }
542
543 static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
544 {
545 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
546
547 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
548 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
549 OUT_RING_CACHE(mode);
550 }
551 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
552 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
553 OUT_RING_CACHE(mode);
554 }
555 }
556
557 /** Set the scale and units used to calculate depth values */
558 static void nv10PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
559 {
560 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
561 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
562 OUT_RING_CACHEf(factor);
563 OUT_RING_CACHEf(units);
564 }
565
566 /** Set the polygon stippling pattern */
567 static void nv10PolygonStipple(GLcontext *ctx, const GLubyte *mask )
568 {
569 /* Not for NV10 */
570 }
571
572 /* Specifies the current buffer for reading */
573 void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
574 /** Set rasterization mode */
575 void (*RenderMode)(GLcontext *ctx, GLenum mode );
576
577 /** Define the scissor box */
578 static void nv10Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
579 {
580 }
581
582 /** Select flat or smooth shading */
583 static void nv10ShadeModel(GLcontext *ctx, GLenum mode)
584 {
585 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
586
587 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
588 OUT_RING_CACHE(mode);
589 }
590
591 /** OpenGL 2.0 two-sided StencilFunc */
592 static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
593 GLint ref, GLuint mask)
594 {
595 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
596
597 /* NV10 do not have separate FRONT and BACK stencils */
598 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3);
599 OUT_RING_CACHE(func);
600 OUT_RING_CACHE(ref);
601 OUT_RING_CACHE(mask);
602 }
603
604 /** OpenGL 2.0 two-sided StencilMask */
605 static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
606 {
607 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
608
609 /* NV10 do not have separate FRONT and BACK stencils */
610 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1);
611 OUT_RING_CACHE(mask);
612 }
613
614 /** OpenGL 2.0 two-sided StencilOp */
615 static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
616 GLenum zfail, GLenum zpass)
617 {
618 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
619
620 /* NV10 do not have separate FRONT and BACK stencils */
621 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 3);
622 OUT_RING_CACHE(fail);
623 OUT_RING_CACHE(zfail);
624 OUT_RING_CACHE(zpass);
625 }
626
627 /** Control the generation of texture coordinates */
628 void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
629 const GLfloat *params);
630 /** Set texture environment parameters */
631 void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
632 const GLfloat *param);
633 /** Set texture parameters */
634 void (*TexParameter)(GLcontext *ctx, GLenum target,
635 struct gl_texture_object *texObj,
636 GLenum pname, const GLfloat *params);
637
638 static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
639 {
640 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
641 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
642 /*XXX: This SHOULD work.*/
643 OUT_RING_CACHEp(mat->m, 16);
644 }
645
646 /* Update anything that depends on the window position/size */
647 static void nv10WindowMoved(nouveauContextPtr nmesa)
648 {
649 GLcontext *ctx = nmesa->glCtx;
650 GLfloat *v = nmesa->viewport.m;
651 GLuint w = ctx->Viewport.Width;
652 GLuint h = ctx->Viewport.Height;
653 GLuint x = ctx->Viewport.X + nmesa->drawX;
654 GLuint y = ctx->Viewport.Y + nmesa->drawY;
655 int i;
656
657 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
658 OUT_RING_CACHE((w << 16) | x);
659 OUT_RING_CACHE((h << 16) | y);
660
661 /* something to do with clears, possibly doesn't belong here */
662 BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1);
663 OUT_RING(0);
664
665 BEGIN_RING_CACHE(NvSub3D,
666 NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
667 OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800);
668 BEGIN_RING_CACHE(NvSub3D,
669 NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
670 OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800);
671 for (i=1; i<8; i++) {
672 BEGIN_RING_CACHE(NvSub3D,
673 NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
674 OUT_RING_CACHE(0);
675 BEGIN_RING_CACHE(NvSub3D,
676 NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
677 OUT_RING_CACHE(0);
678 }
679
680 nv10ViewportScale(nmesa);
681 }
682
683 /* Initialise any card-specific non-GL related state */
684 static GLboolean nv10InitCard(nouveauContextPtr nmesa)
685 {
686 nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
687
688 BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2);
689 OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */
690 OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */
691 BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2);
692 OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */
693 OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */
694
695 BEGIN_RING_SIZE(NvSub3D, 0x0290, 1);
696 OUT_RING(0x00100001);
697 BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1);
698 OUT_RING(0);
699
700 if (nmesa->screen->card->type >= NV_11) {
701 BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
702 OUT_RING(0);
703 OUT_RING(1);
704 OUT_RING(2);
705 }
706
707 return GL_TRUE;
708 }
709
710 /* Update buffer offset/pitch/format */
711 static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color,
712 nouveau_renderbuffer **color,
713 nouveau_renderbuffer *depth)
714 {
715 GLuint x, y, w, h;
716 GLuint pitch, format, depth_pitch;
717
718 w = color[0]->mesa.Width;
719 h = color[0]->mesa.Height;
720 x = nmesa->drawX;
721 y = nmesa->drawY;
722
723 if (num_color != 1)
724 return GL_FALSE;
725
726 BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6);
727 OUT_RING_CACHE((w << 16) | x);
728 OUT_RING_CACHE((h << 16) | y);
729 depth_pitch = (depth ? depth->pitch : color[0]->pitch);
730 pitch = (depth_pitch<<16) | color[0]->pitch;
731 format = 0x108;
732 if (color[0]->mesa._ActualFormat != GL_RGBA8) {
733 format = 0x103; /* R5G6B5 color buffer */
734 }
735 OUT_RING_CACHE(format);
736 OUT_RING_CACHE(pitch);
737 OUT_RING_CACHE(color[0]->offset);
738 OUT_RING_CACHE(depth ? depth->offset : color[0]->offset);
739
740 /* Always set to bottom left of buffer */
741 /*BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
742 OUT_RING_CACHEf (0.0);
743 OUT_RING_CACHEf ((GLfloat) h);
744 OUT_RING_CACHEf (0.0);
745 OUT_RING_CACHEf (0.0);*/
746
747 return GL_TRUE;
748 }
749
750 void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
751 {
752 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
753
754 func->AlphaFunc = nv10AlphaFunc;
755 func->BlendColor = nv10BlendColor;
756 func->BlendEquationSeparate = nv10BlendEquationSeparate;
757 func->BlendFuncSeparate = nv10BlendFuncSeparate;
758 func->Clear = nv10Clear;
759 func->ClearColor = nv10ClearColor;
760 func->ClearDepth = nv10ClearDepth;
761 func->ClearStencil = nv10ClearStencil;
762 func->ClipPlane = nv10ClipPlane;
763 func->ColorMask = nv10ColorMask;
764 func->ColorMaterial = nv10ColorMaterial;
765 func->CullFace = nv10CullFace;
766 func->FrontFace = nv10FrontFace;
767 func->DepthFunc = nv10DepthFunc;
768 func->DepthMask = nv10DepthMask;
769 func->DepthRange = nv10DepthRange;
770 func->Enable = nv10Enable;
771 func->Fogfv = nv10Fogfv;
772 func->Hint = nv10Hint;
773 func->Lightfv = nv10Lightfv;
774 /* func->LightModelfv = nv10LightModelfv; */
775 func->LineStipple = nv10LineStipple; /* Not for NV10 */
776 func->LineWidth = nv10LineWidth;
777 func->LogicOpcode = nv10LogicOpcode;
778 func->PointParameterfv = nv10PointParameterfv;
779 func->PointSize = nv10PointSize;
780 func->PolygonMode = nv10PolygonMode;
781 func->PolygonOffset = nv10PolygonOffset;
782 func->PolygonStipple = nv10PolygonStipple; /* Not for NV10 */
783 /* func->ReadBuffer = nv10ReadBuffer;*/
784 /* func->RenderMode = nv10RenderMode;*/
785 func->Scissor = nv10Scissor;
786 func->ShadeModel = nv10ShadeModel;
787 func->StencilFuncSeparate = nv10StencilFuncSeparate;
788 func->StencilMaskSeparate = nv10StencilMaskSeparate;
789 func->StencilOpSeparate = nv10StencilOpSeparate;
790 /* func->TexGen = nv10TexGen;*/
791 /* func->TexParameter = nv10TexParameter;*/
792 func->TextureMatrix = nv10TextureMatrix;
793
794 nmesa->hw_func.InitCard = nv10InitCard;
795 nmesa->hw_func.BindBuffers = nv10BindBuffers;
796 nmesa->hw_func.WindowMoved = nv10WindowMoved;
797 }