nouveau: nv20: texture matrix
[mesa.git] / src / mesa / drivers / dri / nouveau / nv20_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 nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
38 {
39 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
40 GLubyte ubRef;
41 CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
42
43 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
44 OUT_RING_CACHE(func);
45 OUT_RING_CACHE(ubRef);
46 }
47
48 static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4])
49 {
50 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
51 GLubyte cf[4];
52
53 CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
54 CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
55 CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
56 CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
57
58 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
59 OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
60 }
61
62 static void nv20BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
63 {
64 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
65 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
66 OUT_RING_CACHE((modeA<<16) | modeRGB);
67 }
68
69
70 static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
71 GLenum sfactorA, GLenum dfactorA)
72 {
73 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
74 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
75 OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
76 OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
77 }
78
79 static void nv20Clear(GLcontext *ctx, GLbitfield mask)
80 {
81 /* TODO */
82 }
83
84 static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4])
85 {
86 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
87 GLubyte c[4];
88 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
89 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
90 OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
91 }
92
93 static void nv20ClearDepth(GLcontext *ctx, GLclampd d)
94 {
95 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
96 nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
97 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
98 OUT_RING_CACHE(nmesa->clear_value);
99 }
100
101 /* we're don't support indexed buffers
102 void (*ClearIndex)(GLcontext *ctx, GLuint index)
103 */
104
105 static void nv20ClearStencil(GLcontext *ctx, GLint s)
106 {
107 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
108 nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
109 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
110 OUT_RING_CACHE(nmesa->clear_value);
111 }
112
113 static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
114 {
115 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
116 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
117 OUT_RING_CACHEf(equation[0]);
118 OUT_RING_CACHEf(equation[1]);
119 OUT_RING_CACHEf(equation[2]);
120 OUT_RING_CACHEf(equation[3]);
121 }
122
123 static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
124 GLboolean bmask, GLboolean amask )
125 {
126 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
127 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
128 OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
129 }
130
131 static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
132 {
133 // TODO I need love
134 }
135
136 static void nv20CullFace(GLcontext *ctx, GLenum mode)
137 {
138 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
139 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1);
140 OUT_RING_CACHE(mode);
141 }
142
143 static void nv20FrontFace(GLcontext *ctx, GLenum mode)
144 {
145 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
146 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
147 OUT_RING_CACHE(mode);
148 }
149
150 static void nv20DepthFunc(GLcontext *ctx, GLenum func)
151 {
152 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
153 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
154 OUT_RING_CACHE(func);
155 }
156
157 static void nv20DepthMask(GLcontext *ctx, GLboolean flag)
158 {
159 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
160 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
161 OUT_RING_CACHE(flag);
162 }
163
164 static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
165 {
166 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
167 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
168 OUT_RING_CACHEf(nearval);
169 OUT_RING_CACHEf(farval);
170 }
171
172 /** Specify the current buffer for writing */
173 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
174 /** Specify the buffers for writing for fragment programs*/
175 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
176
177 static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state)
178 {
179 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
180 switch(cap)
181 {
182 case GL_ALPHA_TEST:
183 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
184 OUT_RING_CACHE(state);
185 break;
186 // case GL_AUTO_NORMAL:
187 case GL_BLEND:
188 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
189 OUT_RING_CACHE(state);
190 break;
191 case GL_CLIP_PLANE0:
192 case GL_CLIP_PLANE1:
193 case GL_CLIP_PLANE2:
194 case GL_CLIP_PLANE3:
195 case GL_CLIP_PLANE4:
196 case GL_CLIP_PLANE5:
197 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
198 OUT_RING_CACHE(state);
199 break;
200 case GL_COLOR_LOGIC_OP:
201 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
202 OUT_RING_CACHE(state);
203 break;
204 // case GL_COLOR_MATERIAL:
205 // case GL_COLOR_SUM_EXT:
206 // case GL_COLOR_TABLE:
207 // case GL_CONVOLUTION_1D:
208 // case GL_CONVOLUTION_2D:
209 case GL_CULL_FACE:
210 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
211 OUT_RING_CACHE(state);
212 break;
213 case GL_DEPTH_TEST:
214 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
215 OUT_RING_CACHE(state);
216 break;
217 case GL_DITHER:
218 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
219 OUT_RING_CACHE(state);
220 break;
221 case GL_FOG:
222 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
223 OUT_RING_CACHE(state);
224 break;
225 // case GL_HISTOGRAM:
226 // case GL_INDEX_LOGIC_OP:
227 case GL_LIGHT0:
228 case GL_LIGHT1:
229 case GL_LIGHT2:
230 case GL_LIGHT3:
231 case GL_LIGHT4:
232 case GL_LIGHT5:
233 case GL_LIGHT6:
234 case GL_LIGHT7:
235 {
236 uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
237 nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
238 if (nmesa->lighting_enabled)
239 {
240 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
241 OUT_RING_CACHE(nmesa->enabled_lights);
242 }
243 break;
244 }
245 case GL_LIGHTING:
246 nmesa->lighting_enabled=state;
247 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
248 if (nmesa->lighting_enabled)
249 OUT_RING_CACHE(nmesa->enabled_lights);
250 else
251 OUT_RING_CACHE(0x0);
252 break;
253 case GL_LINE_SMOOTH:
254 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
255 OUT_RING_CACHE(state);
256 break;
257 // case GL_LINE_STIPPLE:
258 // case GL_MAP1_COLOR_4:
259 // case GL_MAP1_INDEX:
260 // case GL_MAP1_NORMAL:
261 // case GL_MAP1_TEXTURE_COORD_1:
262 // case GL_MAP1_TEXTURE_COORD_2:
263 // case GL_MAP1_TEXTURE_COORD_3:
264 // case GL_MAP1_TEXTURE_COORD_4:
265 // case GL_MAP1_VERTEX_3:
266 // case GL_MAP1_VERTEX_4:
267 // case GL_MAP2_COLOR_4:
268 // case GL_MAP2_INDEX:
269 // case GL_MAP2_NORMAL:
270 // case GL_MAP2_TEXTURE_COORD_1:
271 // case GL_MAP2_TEXTURE_COORD_2:
272 // case GL_MAP2_TEXTURE_COORD_3:
273 // case GL_MAP2_TEXTURE_COORD_4:
274 // case GL_MAP2_VERTEX_3:
275 // case GL_MAP2_VERTEX_4:
276 // case GL_MINMAX:
277 case GL_NORMALIZE:
278 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
279 OUT_RING_CACHE(state);
280 break;
281 // case GL_POINT_SMOOTH:
282 case GL_POLYGON_OFFSET_POINT:
283 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
284 OUT_RING_CACHE(state);
285 break;
286 case GL_POLYGON_OFFSET_LINE:
287 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
288 OUT_RING_CACHE(state);
289 break;
290 case GL_POLYGON_OFFSET_FILL:
291 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
292 OUT_RING_CACHE(state);
293 break;
294 case GL_POLYGON_SMOOTH:
295 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
296 OUT_RING_CACHE(state);
297 break;
298 case GL_POLYGON_STIPPLE:
299 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
300 OUT_RING_CACHE(state);
301 break;
302 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
303 // case GL_POST_CONVOLUTION_COLOR_TABLE:
304 // case GL_RESCALE_NORMAL:
305 case GL_SCISSOR_TEST:
306 /* No enable bit, nv20Scissor will adjust to max range */
307 ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
308 ctx->Scissor.Width, ctx->Scissor.Height);
309 break;
310 // case GL_SEPARABLE_2D:
311 case GL_STENCIL_TEST:
312 // TODO BACK and FRONT ?
313 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1);
314 OUT_RING_CACHE(state);
315 break;
316 // case GL_TEXTURE_GEN_Q:
317 // case GL_TEXTURE_GEN_R:
318 // case GL_TEXTURE_GEN_S:
319 // case GL_TEXTURE_GEN_T:
320 // case GL_TEXTURE_1D:
321 // case GL_TEXTURE_2D:
322 // case GL_TEXTURE_3D:
323 }
324 }
325
326 static void nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
327 {
328 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
329 switch(pname)
330 {
331 case GL_FOG_MODE:
332 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1);
333 //OUT_RING_CACHE (params);
334 break;
335 /* TODO: unsure about the rest.*/
336 default:
337 break;
338 }
339
340 }
341
342 static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode)
343 {
344 // TODO I need love (fog and line_smooth hints)
345 }
346
347 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
348
349 enum {
350 SPOTLIGHT_NO_UPDATE,
351 SPOTLIGHT_UPDATE_EXPONENT,
352 SPOTLIGHT_UPDATE_DIRECTION,
353 SPOTLIGHT_UPDATE_ALL
354 };
355
356 static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
357 {
358 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
359 GLint p = light - GL_LIGHT0;
360 struct gl_light *l = &ctx->Light.Light[p];
361 int spotlight_update = SPOTLIGHT_NO_UPDATE;
362
363 /* not sure where the fourth param value goes...*/
364 switch(pname)
365 {
366 case GL_AMBIENT:
367 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
368 OUT_RING_CACHEf(params[0]);
369 OUT_RING_CACHEf(params[1]);
370 OUT_RING_CACHEf(params[2]);
371 break;
372 case GL_DIFFUSE:
373 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
374 OUT_RING_CACHEf(params[0]);
375 OUT_RING_CACHEf(params[1]);
376 OUT_RING_CACHEf(params[2]);
377 break;
378 case GL_SPECULAR:
379 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
380 OUT_RING_CACHEf(params[0]);
381 OUT_RING_CACHEf(params[1]);
382 OUT_RING_CACHEf(params[2]);
383 break;
384 case GL_POSITION:
385 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
386 OUT_RING_CACHEf(params[0]);
387 OUT_RING_CACHEf(params[1]);
388 OUT_RING_CACHEf(params[2]);
389 break;
390 case GL_SPOT_DIRECTION:
391 spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
392 break;
393 case GL_SPOT_EXPONENT:
394 spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
395 break;
396 case GL_SPOT_CUTOFF:
397 spotlight_update = SPOTLIGHT_UPDATE_ALL;
398 break;
399 case GL_CONSTANT_ATTENUATION:
400 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
401 OUT_RING_CACHEf(*params);
402 break;
403 case GL_LINEAR_ATTENUATION:
404 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
405 OUT_RING_CACHEf(*params);
406 break;
407 case GL_QUADRATIC_ATTENUATION:
408 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
409 OUT_RING_CACHEf(*params);
410 break;
411 default:
412 break;
413 }
414
415 switch(spotlight_update) {
416 case SPOTLIGHT_UPDATE_DIRECTION:
417 {
418 GLfloat x,y,z;
419 GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
420 x = spot_light_coef_a * l->_NormDirection[0];
421 y = spot_light_coef_a * l->_NormDirection[1];
422 z = spot_light_coef_a * l->_NormDirection[2];
423 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
424 OUT_RING_CACHEf(x);
425 OUT_RING_CACHEf(y);
426 OUT_RING_CACHEf(z);
427 }
428 break;
429 case SPOTLIGHT_UPDATE_EXPONENT:
430 {
431 GLfloat cc,lc,qc;
432 cc = 1.0; /* FIXME: These need to be correctly computed */
433 lc = 0.0;
434 qc = 2.0;
435 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
436 OUT_RING_CACHEf(cc);
437 OUT_RING_CACHEf(lc);
438 OUT_RING_CACHEf(qc);
439 }
440 break;
441 case SPOTLIGHT_UPDATE_ALL:
442 {
443 GLfloat cc,lc,qc, x,y,z, c;
444 GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
445 cc = 1.0; /* FIXME: These need to be correctly computed */
446 lc = 0.0;
447 qc = 2.0;
448 x = spot_light_coef_a * l->_NormDirection[0];
449 y = spot_light_coef_a * l->_NormDirection[1];
450 z = spot_light_coef_a * l->_NormDirection[2];
451 c = spot_light_coef_a + 1.0;
452 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
453 OUT_RING_CACHEf(cc);
454 OUT_RING_CACHEf(lc);
455 OUT_RING_CACHEf(qc);
456 OUT_RING_CACHEf(x);
457 OUT_RING_CACHEf(y);
458 OUT_RING_CACHEf(z);
459 OUT_RING_CACHEf(c);
460 }
461 break;
462 default:
463 break;
464 }
465 }
466
467 /** Set the lighting model parameters */
468 static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
469
470
471 static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
472 {
473 /* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
474 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
475 OUT_RING_CACHE((pattern << 16) | factor);*/
476 }
477
478 static void nv20LineWidth(GLcontext *ctx, GLfloat width)
479 {
480 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
481 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
482 OUT_RING_CACHEf(width);
483 }
484
485 static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode)
486 {
487 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
488 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
489 OUT_RING_CACHE(opcode);
490 }
491
492 static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
493 {
494 /*TODO: not sure what goes here. */
495 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
496
497 }
498
499 /** Specify the diameter of rasterized points */
500 static void nv20PointSize(GLcontext *ctx, GLfloat size)
501 {
502 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
503 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
504 OUT_RING_CACHEf(size);
505 }
506
507 /** Select a polygon rasterization mode */
508 static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
509 {
510 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
511
512 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
513 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
514 OUT_RING_CACHE(mode);
515 }
516 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
517 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
518 OUT_RING_CACHE(mode);
519 }
520 }
521
522 /** Set the scale and units used to calculate depth values */
523 static void nv20PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
524 {
525 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
526 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
527 OUT_RING_CACHEf(factor);
528 OUT_RING_CACHEf(units);
529 }
530
531 /** Set the polygon stippling pattern */
532 static void nv20PolygonStipple(GLcontext *ctx, const GLubyte *mask )
533 {
534 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
535 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
536 OUT_RING_CACHEp(mask, 32);
537 }
538
539 /* Specifies the current buffer for reading */
540 void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
541 /** Set rasterization mode */
542 void (*RenderMode)(GLcontext *ctx, GLenum mode );
543
544 /** Define the scissor box */
545 static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
546 {
547 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
548
549 /* There's no scissor enable bit, so adjust the scissor to cover the
550 * maximum draw buffer bounds
551 */
552 if (!ctx->Scissor.Enabled) {
553 x = y = 0;
554 w = h = 4095;
555 } else {
556 x += nmesa->drawX;
557 y += nmesa->drawY;
558 }
559
560 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 2);
561 OUT_RING_CACHE(((x+w-1) << 16) | x);
562 OUT_RING_CACHE(((y+h-1) << 16) | y);
563 }
564
565 /** Select flat or smooth shading */
566 static void nv20ShadeModel(GLcontext *ctx, GLenum mode)
567 {
568 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
569
570 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
571 OUT_RING_CACHE(mode);
572 }
573
574 /** OpenGL 2.0 two-sided StencilFunc */
575 static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
576 GLint ref, GLuint mask)
577 {
578 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
579
580 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3);
581 OUT_RING_CACHE(func);
582 OUT_RING_CACHE(ref);
583 OUT_RING_CACHE(mask);
584 }
585
586 /** OpenGL 2.0 two-sided StencilMask */
587 static void nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
588 {
589 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
590
591 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1);
592 OUT_RING_CACHE(mask);
593 }
594
595 /** OpenGL 2.0 two-sided StencilOp */
596 static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
597 GLenum zfail, GLenum zpass)
598 {
599 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
600
601 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1);
602 OUT_RING_CACHE(fail);
603 OUT_RING_CACHE(zfail);
604 OUT_RING_CACHE(zpass);
605 }
606
607 /** Control the generation of texture coordinates */
608 void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
609 const GLfloat *params);
610 /** Set texture environment parameters */
611 void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
612 const GLfloat *param);
613 /** Set texture parameters */
614 void (*TexParameter)(GLcontext *ctx, GLenum target,
615 struct gl_texture_object *texObj,
616 GLenum pname, const GLfloat *params);
617
618 static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
619 {
620 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
621 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
622 /*XXX: This SHOULD work.*/
623 OUT_RING_CACHEp(mat->m, 16);
624 }
625
626 /* Update anything that depends on the window position/size */
627 static void nv20WindowMoved(nouveauContextPtr nmesa)
628 {
629 GLcontext *ctx = nmesa->glCtx;
630 GLfloat *v = nmesa->viewport.m;
631 GLuint w = ctx->Viewport.Width;
632 GLuint h = ctx->Viewport.Height;
633 GLuint x = ctx->Viewport.X + nmesa->drawX;
634 GLuint y = ctx->Viewport.Y + nmesa->drawY;
635 int i;
636
637 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
638 OUT_RING_CACHE((w << 16) | x);
639 OUT_RING_CACHE((h << 16) | y);
640
641 BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1);
642 OUT_RING(0);
643
644 BEGIN_RING_CACHE(NvSub3D,
645 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
646 OUT_RING_CACHE((4095 << 16) | 0);
647 OUT_RING_CACHE((4095 << 16) | 0);
648 for (i=1; i<8; i++) {
649 BEGIN_RING_CACHE(NvSub3D,
650 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
651 OUT_RING_CACHE(0);
652 BEGIN_RING_CACHE(NvSub3D,
653 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
654 OUT_RING_CACHE(0);
655 }
656
657 ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
658 ctx->Scissor.Width, ctx->Scissor.Height);
659
660 /* TODO: recalc viewport scale coefs */
661 }
662
663 /* Initialise any card-specific non-GL related state */
664 static GLboolean nv20InitCard(nouveauContextPtr nmesa)
665 {
666 nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
667
668 BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
669 OUT_RING(NvDmaFB); /* 184 dma_object1 */
670 OUT_RING(NvDmaFB); /* 188 dma_object2 */
671 BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3, 2);
672 OUT_RING(NvDmaFB); /* 194 dma_object3 */
673 OUT_RING(NvDmaFB); /* 198 dma_object4 */
674 BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
675 OUT_RING(NvDmaFB); /* 1a8 dma_object8 */
676
677 BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
678 OUT_RINGf(0.0);
679 OUT_RINGf(0.0);
680 OUT_RINGf(1.0);
681
682 BEGIN_RING_SIZE(NvSub3D, 0x1e6c, 1);
683 OUT_RING(0x0db6);
684 BEGIN_RING_SIZE(NvSub3D, 0x0290, 1);
685 OUT_RING(0x00100001);
686 BEGIN_RING_SIZE(NvSub3D, 0x09fc, 1);
687 OUT_RING(0);
688 BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
689 OUT_RING(1);
690 BEGIN_RING_SIZE(NvSub3D, 0x09f8, 1);
691 OUT_RING(4);
692
693 BEGIN_RING_SIZE(NvSub3D, 0x17ec, 3);
694 OUT_RINGf(0.0);
695 OUT_RINGf(1.0);
696 OUT_RINGf(0.0);
697
698 BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
699 OUT_RING(3);
700
701 /* FIXME: More dma objects to setup ? */
702
703 BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
704 OUT_RING(0);
705
706 BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
707 OUT_RING(0);
708 OUT_RING(1);
709 OUT_RING(2);
710
711 return GL_TRUE;
712 }
713
714 /* Update buffer offset/pitch/format */
715 static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color,
716 nouveau_renderbuffer **color,
717 nouveau_renderbuffer *depth)
718 {
719 GLuint x, y, w, h;
720 GLuint pitch, format, depth_pitch;
721
722 w = color[0]->mesa.Width;
723 h = color[0]->mesa.Height;
724 x = nmesa->drawX;
725 y = nmesa->drawY;
726
727 if (num_color != 1)
728 return GL_FALSE;
729
730 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6);
731 OUT_RING_CACHE((w << 16) | x);
732 OUT_RING_CACHE((h << 16) | y);
733 depth_pitch = (depth ? depth->pitch : color[0]->pitch);
734 pitch = (depth_pitch<<16) | color[0]->pitch;
735 format = 0x128;
736 if (color[0]->mesa._ActualFormat != GL_RGBA8) {
737 format = 0x123; /* R5G6B5 color buffer */
738 }
739 OUT_RING_CACHE(format);
740 OUT_RING_CACHE(pitch);
741 OUT_RING_CACHE(color[0]->offset);
742 OUT_RING_CACHE(depth ? depth->offset : color[0]->offset);
743
744 if (depth) {
745 BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 2);
746 /* TODO: use a different buffer */
747 OUT_RING(depth->pitch);
748 OUT_RING(depth->offset);
749 }
750
751 /* Always set to bottom left of buffer */
752 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
753 OUT_RING_CACHEf (0.0);
754 OUT_RING_CACHEf ((GLfloat) h);
755 OUT_RING_CACHEf (0.0);
756 OUT_RING_CACHEf (0.0);
757
758 return GL_TRUE;
759 }
760
761 void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
762 {
763 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
764
765 func->AlphaFunc = nv20AlphaFunc;
766 func->BlendColor = nv20BlendColor;
767 func->BlendEquationSeparate = nv20BlendEquationSeparate;
768 func->BlendFuncSeparate = nv20BlendFuncSeparate;
769 func->Clear = nv20Clear;
770 func->ClearColor = nv20ClearColor;
771 func->ClearDepth = nv20ClearDepth;
772 func->ClearStencil = nv20ClearStencil;
773 func->ClipPlane = nv20ClipPlane;
774 func->ColorMask = nv20ColorMask;
775 func->ColorMaterial = nv20ColorMaterial;
776 func->CullFace = nv20CullFace;
777 func->FrontFace = nv20FrontFace;
778 func->DepthFunc = nv20DepthFunc;
779 func->DepthMask = nv20DepthMask;
780 func->DepthRange = nv20DepthRange;
781 func->Enable = nv20Enable;
782 func->Fogfv = nv20Fogfv;
783 func->Hint = nv20Hint;
784 func->Lightfv = nv20Lightfv;
785 /* func->LightModelfv = nv20LightModelfv; */
786 func->LineStipple = nv20LineStipple;
787 func->LineWidth = nv20LineWidth;
788 func->LogicOpcode = nv20LogicOpcode;
789 func->PointParameterfv = nv20PointParameterfv;
790 func->PointSize = nv20PointSize;
791 func->PolygonMode = nv20PolygonMode;
792 func->PolygonOffset = nv20PolygonOffset;
793 func->PolygonStipple = nv20PolygonStipple;
794 /* func->ReadBuffer = nv20ReadBuffer;*/
795 /* func->RenderMode = nv20RenderMode;*/
796 func->Scissor = nv20Scissor;
797 func->ShadeModel = nv20ShadeModel;
798 func->StencilFuncSeparate = nv20StencilFuncSeparate;
799 func->StencilMaskSeparate = nv20StencilMaskSeparate;
800 func->StencilOpSeparate = nv20StencilOpSeparate;
801 /* func->TexGen = nv20TexGen;*/
802 /* func->TexParameter = nv20TexParameter;*/
803 func->TextureMatrix = nv20TextureMatrix;
804
805 nmesa->hw_func.InitCard = nv20InitCard;
806 nmesa->hw_func.BindBuffers = nv20BindBuffers;
807 nmesa->hw_func.WindowMoved = nv20WindowMoved;
808 }
809