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