r200: Drop the non-kernel-memory-manager and DRI1 code.
[mesa.git] / src / mesa / drivers / dri / r200 / r200_state.c
1 /**************************************************************************
2
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /*
32 * Authors:
33 * Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36 #include "main/glheader.h"
37 #include "main/imports.h"
38 #include "main/api_arrayelt.h"
39 #include "main/enums.h"
40 #include "main/colormac.h"
41 #include "main/light.h"
42 #include "main/framebuffer.h"
43
44 #include "swrast/swrast.h"
45 #include "vbo/vbo.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_pipeline.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "drivers/common/meta.h"
50
51 #include "radeon_common.h"
52 #include "radeon_mipmap_tree.h"
53 #include "r200_context.h"
54 #include "r200_ioctl.h"
55 #include "r200_state.h"
56 #include "r200_tcl.h"
57 #include "r200_tex.h"
58 #include "r200_swtcl.h"
59 #include "r200_vertprog.h"
60
61
62 /* =============================================================
63 * Alpha blending
64 */
65
66 static void r200AlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
67 {
68 r200ContextPtr rmesa = R200_CONTEXT(ctx);
69 int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
70 GLubyte refByte;
71
72 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
73
74 R200_STATECHANGE( rmesa, ctx );
75
76 pp_misc &= ~(R200_ALPHA_TEST_OP_MASK | R200_REF_ALPHA_MASK);
77 pp_misc |= (refByte & R200_REF_ALPHA_MASK);
78
79 switch ( func ) {
80 case GL_NEVER:
81 pp_misc |= R200_ALPHA_TEST_FAIL;
82 break;
83 case GL_LESS:
84 pp_misc |= R200_ALPHA_TEST_LESS;
85 break;
86 case GL_EQUAL:
87 pp_misc |= R200_ALPHA_TEST_EQUAL;
88 break;
89 case GL_LEQUAL:
90 pp_misc |= R200_ALPHA_TEST_LEQUAL;
91 break;
92 case GL_GREATER:
93 pp_misc |= R200_ALPHA_TEST_GREATER;
94 break;
95 case GL_NOTEQUAL:
96 pp_misc |= R200_ALPHA_TEST_NEQUAL;
97 break;
98 case GL_GEQUAL:
99 pp_misc |= R200_ALPHA_TEST_GEQUAL;
100 break;
101 case GL_ALWAYS:
102 pp_misc |= R200_ALPHA_TEST_PASS;
103 break;
104 }
105
106 rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
107 }
108
109 static void r200BlendColor( struct gl_context *ctx, const GLfloat cf[4] )
110 {
111 GLubyte color[4];
112 r200ContextPtr rmesa = R200_CONTEXT(ctx);
113 R200_STATECHANGE( rmesa, ctx );
114 CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
115 CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
116 CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
117 CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
118 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
119 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = radeonPackColor( 4, color[0], color[1], color[2], color[3] );
120 }
121
122 /**
123 * Calculate the hardware blend factor setting. This same function is used
124 * for source and destination of both alpha and RGB.
125 *
126 * \returns
127 * The hardware register value for the specified blend factor. This value
128 * will need to be shifted into the correct position for either source or
129 * destination factor.
130 *
131 * \todo
132 * Since the two cases where source and destination are handled differently
133 * are essentially error cases, they should never happen. Determine if these
134 * cases can be removed.
135 */
136 static int blend_factor( GLenum factor, GLboolean is_src )
137 {
138 int func;
139
140 switch ( factor ) {
141 case GL_ZERO:
142 func = R200_BLEND_GL_ZERO;
143 break;
144 case GL_ONE:
145 func = R200_BLEND_GL_ONE;
146 break;
147 case GL_DST_COLOR:
148 func = R200_BLEND_GL_DST_COLOR;
149 break;
150 case GL_ONE_MINUS_DST_COLOR:
151 func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
152 break;
153 case GL_SRC_COLOR:
154 func = R200_BLEND_GL_SRC_COLOR;
155 break;
156 case GL_ONE_MINUS_SRC_COLOR:
157 func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
158 break;
159 case GL_SRC_ALPHA:
160 func = R200_BLEND_GL_SRC_ALPHA;
161 break;
162 case GL_ONE_MINUS_SRC_ALPHA:
163 func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
164 break;
165 case GL_DST_ALPHA:
166 func = R200_BLEND_GL_DST_ALPHA;
167 break;
168 case GL_ONE_MINUS_DST_ALPHA:
169 func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
170 break;
171 case GL_SRC_ALPHA_SATURATE:
172 func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO;
173 break;
174 case GL_CONSTANT_COLOR:
175 func = R200_BLEND_GL_CONST_COLOR;
176 break;
177 case GL_ONE_MINUS_CONSTANT_COLOR:
178 func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
179 break;
180 case GL_CONSTANT_ALPHA:
181 func = R200_BLEND_GL_CONST_ALPHA;
182 break;
183 case GL_ONE_MINUS_CONSTANT_ALPHA:
184 func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
185 break;
186 default:
187 func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
188 }
189 return func;
190 }
191
192 /**
193 * Sets both the blend equation and the blend function.
194 * This is done in a single
195 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
196 * change the interpretation of the blend function.
197 * Also, make sure that blend function and blend equation are set to their default
198 * value if color blending is not enabled, since at least blend equations GL_MIN
199 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
200 * unknown reasons.
201 */
202 static void r200_set_blend_state( struct gl_context * ctx )
203 {
204 r200ContextPtr rmesa = R200_CONTEXT(ctx);
205 GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
206 ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE);
207
208 int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
209 (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
210 int eqn = R200_COMB_FCN_ADD_CLAMP;
211 int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
212 (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
213 int eqnA = R200_COMB_FCN_ADD_CLAMP;
214
215 R200_STATECHANGE( rmesa, ctx );
216
217 if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
218 if (ctx->Color.ColorLogicOpEnabled) {
219 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ROP_ENABLE;
220 rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
221 rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
222 return;
223 } else if (ctx->Color.BlendEnabled) {
224 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE;
225 }
226 else {
227 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
228 rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
229 rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
230 return;
231 }
232 }
233 else {
234 if (ctx->Color.ColorLogicOpEnabled) {
235 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ROP_ENABLE;
236 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
237 return;
238 } else if (ctx->Color.BlendEnabled) {
239 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ALPHA_BLEND_ENABLE;
240 }
241 else {
242 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
243 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
244 return;
245 }
246 }
247
248 func = (blend_factor( ctx->Color.Blend[0].SrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
249 (blend_factor( ctx->Color.Blend[0].DstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
250
251 switch(ctx->Color.Blend[0].EquationRGB) {
252 case GL_FUNC_ADD:
253 eqn = R200_COMB_FCN_ADD_CLAMP;
254 break;
255
256 case GL_FUNC_SUBTRACT:
257 eqn = R200_COMB_FCN_SUB_CLAMP;
258 break;
259
260 case GL_FUNC_REVERSE_SUBTRACT:
261 eqn = R200_COMB_FCN_RSUB_CLAMP;
262 break;
263
264 case GL_MIN:
265 eqn = R200_COMB_FCN_MIN;
266 func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
267 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
268 break;
269
270 case GL_MAX:
271 eqn = R200_COMB_FCN_MAX;
272 func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
273 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
274 break;
275
276 default:
277 fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
278 __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB );
279 return;
280 }
281
282 if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
283 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
284 return;
285 }
286
287 funcA = (blend_factor( ctx->Color.Blend[0].SrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
288 (blend_factor( ctx->Color.Blend[0].DstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
289
290 switch(ctx->Color.Blend[0].EquationA) {
291 case GL_FUNC_ADD:
292 eqnA = R200_COMB_FCN_ADD_CLAMP;
293 break;
294
295 case GL_FUNC_SUBTRACT:
296 eqnA = R200_COMB_FCN_SUB_CLAMP;
297 break;
298
299 case GL_FUNC_REVERSE_SUBTRACT:
300 eqnA = R200_COMB_FCN_RSUB_CLAMP;
301 break;
302
303 case GL_MIN:
304 eqnA = R200_COMB_FCN_MIN;
305 funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
306 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
307 break;
308
309 case GL_MAX:
310 eqnA = R200_COMB_FCN_MAX;
311 funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
312 (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
313 break;
314
315 default:
316 fprintf( stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
317 __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA );
318 return;
319 }
320
321 rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqnA | funcA;
322 rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
323
324 }
325
326 static void r200BlendEquationSeparate( struct gl_context *ctx,
327 GLenum modeRGB, GLenum modeA )
328 {
329 r200_set_blend_state( ctx );
330 }
331
332 static void r200BlendFuncSeparate( struct gl_context *ctx,
333 GLenum sfactorRGB, GLenum dfactorRGB,
334 GLenum sfactorA, GLenum dfactorA )
335 {
336 r200_set_blend_state( ctx );
337 }
338
339
340 /* =============================================================
341 * Depth testing
342 */
343
344 static void r200DepthFunc( struct gl_context *ctx, GLenum func )
345 {
346 r200ContextPtr rmesa = R200_CONTEXT(ctx);
347
348 R200_STATECHANGE( rmesa, ctx );
349 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_TEST_MASK;
350
351 switch ( ctx->Depth.Func ) {
352 case GL_NEVER:
353 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEVER;
354 break;
355 case GL_LESS:
356 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LESS;
357 break;
358 case GL_EQUAL:
359 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_EQUAL;
360 break;
361 case GL_LEQUAL:
362 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LEQUAL;
363 break;
364 case GL_GREATER:
365 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GREATER;
366 break;
367 case GL_NOTEQUAL:
368 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEQUAL;
369 break;
370 case GL_GEQUAL:
371 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GEQUAL;
372 break;
373 case GL_ALWAYS:
374 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_ALWAYS;
375 break;
376 }
377 }
378
379 static void r200ClearDepth( struct gl_context *ctx, GLclampd d )
380 {
381 r200ContextPtr rmesa = R200_CONTEXT(ctx);
382 GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
383 R200_DEPTH_FORMAT_MASK);
384
385 switch ( format ) {
386 case R200_DEPTH_FORMAT_16BIT_INT_Z:
387 rmesa->radeon.state.depth.clear = d * 0x0000ffff;
388 break;
389 case R200_DEPTH_FORMAT_24BIT_INT_Z:
390 rmesa->radeon.state.depth.clear = d * 0x00ffffff;
391 break;
392 }
393 }
394
395 static void r200DepthMask( struct gl_context *ctx, GLboolean flag )
396 {
397 r200ContextPtr rmesa = R200_CONTEXT(ctx);
398 R200_STATECHANGE( rmesa, ctx );
399
400 if ( ctx->Depth.Mask ) {
401 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_WRITE_ENABLE;
402 } else {
403 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_WRITE_ENABLE;
404 }
405 }
406
407
408 /* =============================================================
409 * Fog
410 */
411
412
413 static void r200Fogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
414 {
415 r200ContextPtr rmesa = R200_CONTEXT(ctx);
416 union { int i; float f; } c, d;
417 GLubyte col[4];
418 GLuint i;
419
420 c.i = rmesa->hw.fog.cmd[FOG_C];
421 d.i = rmesa->hw.fog.cmd[FOG_D];
422
423 switch (pname) {
424 case GL_FOG_MODE:
425 if (!ctx->Fog.Enabled)
426 return;
427 R200_STATECHANGE(rmesa, tcl);
428 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
429 switch (ctx->Fog.Mode) {
430 case GL_LINEAR:
431 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_LINEAR;
432 if (ctx->Fog.Start == ctx->Fog.End) {
433 c.f = 1.0F;
434 d.f = 1.0F;
435 }
436 else {
437 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
438 d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
439 }
440 break;
441 case GL_EXP:
442 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP;
443 c.f = 0.0;
444 d.f = -ctx->Fog.Density;
445 break;
446 case GL_EXP2:
447 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP2;
448 c.f = 0.0;
449 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
450 break;
451 default:
452 return;
453 }
454 break;
455 case GL_FOG_DENSITY:
456 switch (ctx->Fog.Mode) {
457 case GL_EXP:
458 c.f = 0.0;
459 d.f = -ctx->Fog.Density;
460 break;
461 case GL_EXP2:
462 c.f = 0.0;
463 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
464 break;
465 default:
466 break;
467 }
468 break;
469 case GL_FOG_START:
470 case GL_FOG_END:
471 if (ctx->Fog.Mode == GL_LINEAR) {
472 if (ctx->Fog.Start == ctx->Fog.End) {
473 c.f = 1.0F;
474 d.f = 1.0F;
475 } else {
476 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
477 d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
478 }
479 }
480 break;
481 case GL_FOG_COLOR:
482 R200_STATECHANGE( rmesa, ctx );
483 _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color );
484 i = radeonPackColor( 4, col[0], col[1], col[2], 0 );
485 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK;
486 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i;
487 break;
488 case GL_FOG_COORD_SRC: {
489 GLuint out_0 = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0];
490 GLuint fog = rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR];
491
492 fog &= ~R200_FOG_USE_MASK;
493 if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD || ctx->VertexProgram.Enabled) {
494 fog |= R200_FOG_USE_VTX_FOG;
495 out_0 |= R200_VTX_DISCRETE_FOG;
496 }
497 else {
498 fog |= R200_FOG_USE_SPEC_ALPHA;
499 out_0 &= ~R200_VTX_DISCRETE_FOG;
500 }
501
502 if ( fog != rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] ) {
503 R200_STATECHANGE( rmesa, ctx );
504 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = fog;
505 }
506
507 if (out_0 != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0]) {
508 R200_STATECHANGE( rmesa, vtx );
509 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = out_0;
510 }
511
512 break;
513 }
514 default:
515 return;
516 }
517
518 if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
519 R200_STATECHANGE( rmesa, fog );
520 rmesa->hw.fog.cmd[FOG_C] = c.i;
521 rmesa->hw.fog.cmd[FOG_D] = d.i;
522 }
523 }
524
525 /* =============================================================
526 * Culling
527 */
528
529 static void r200CullFace( struct gl_context *ctx, GLenum unused )
530 {
531 r200ContextPtr rmesa = R200_CONTEXT(ctx);
532 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
533 GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
534
535 s |= R200_FFACE_SOLID | R200_BFACE_SOLID;
536 t &= ~(R200_CULL_FRONT | R200_CULL_BACK);
537
538 if ( ctx->Polygon.CullFlag ) {
539 switch ( ctx->Polygon.CullFaceMode ) {
540 case GL_FRONT:
541 s &= ~R200_FFACE_SOLID;
542 t |= R200_CULL_FRONT;
543 break;
544 case GL_BACK:
545 s &= ~R200_BFACE_SOLID;
546 t |= R200_CULL_BACK;
547 break;
548 case GL_FRONT_AND_BACK:
549 s &= ~(R200_FFACE_SOLID | R200_BFACE_SOLID);
550 t |= (R200_CULL_FRONT | R200_CULL_BACK);
551 break;
552 }
553 }
554
555 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
556 R200_STATECHANGE(rmesa, set );
557 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
558 }
559
560 if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
561 R200_STATECHANGE(rmesa, tcl );
562 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
563 }
564 }
565
566 static void r200FrontFace( struct gl_context *ctx, GLenum mode )
567 {
568 r200ContextPtr rmesa = R200_CONTEXT(ctx);
569
570 R200_STATECHANGE( rmesa, set );
571 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_FFACE_CULL_DIR_MASK;
572
573 R200_STATECHANGE( rmesa, tcl );
574 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW;
575
576 /* Winding is inverted when rendering to FBO */
577 if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
578 mode = (mode == GL_CW) ? GL_CCW : GL_CW;
579
580 switch ( mode ) {
581 case GL_CW:
582 rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW;
583 break;
584 case GL_CCW:
585 rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CCW;
586 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_CULL_FRONT_IS_CCW;
587 break;
588 }
589 }
590
591 /* =============================================================
592 * Point state
593 */
594 static void r200PointSize( struct gl_context *ctx, GLfloat size )
595 {
596 r200ContextPtr rmesa = R200_CONTEXT(ctx);
597 GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
598
599 radeon_print(RADEON_STATE, RADEON_TRACE,
600 "%s(%p) size: %f, fixed point result: %d.%d (%d/16)\n",
601 __func__, ctx, size,
602 ((GLuint)(ctx->Point.Size * 16.0))/16,
603 (((GLuint)(ctx->Point.Size * 16.0))&15)*100/16,
604 ((GLuint)(ctx->Point.Size * 16.0))&15);
605
606 R200_STATECHANGE( rmesa, cst );
607 R200_STATECHANGE( rmesa, ptp );
608 rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff;
609 rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));
610 /* this is the size param of the point size calculation (point size reg value
611 is not used when calculation is active). */
612 fcmd[PTP_VPORT_SCALE_PTSIZE] = ctx->Point.Size;
613 }
614
615 static void r200PointParameter( struct gl_context *ctx, GLenum pname, const GLfloat *params)
616 {
617 r200ContextPtr rmesa = R200_CONTEXT(ctx);
618 GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
619
620 switch (pname) {
621 case GL_POINT_SIZE_MIN:
622 /* Can clamp both in tcl and setup - just set both (as does fglrx) */
623 R200_STATECHANGE( rmesa, lin );
624 R200_STATECHANGE( rmesa, ptp );
625 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= 0xffff;
626 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Point.MinSize * 16.0) << 16;
627 fcmd[PTP_CLAMP_MIN] = ctx->Point.MinSize;
628 break;
629 case GL_POINT_SIZE_MAX:
630 R200_STATECHANGE( rmesa, cst );
631 R200_STATECHANGE( rmesa, ptp );
632 rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= 0xffff;
633 rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= (GLuint)(ctx->Point.MaxSize * 16.0) << 16;
634 fcmd[PTP_CLAMP_MAX] = ctx->Point.MaxSize;
635 break;
636 case GL_POINT_DISTANCE_ATTENUATION:
637 R200_STATECHANGE( rmesa, vtx );
638 R200_STATECHANGE( rmesa, spr );
639 R200_STATECHANGE( rmesa, ptp );
640 GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
641 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &=
642 ~(R200_PS_MULT_MASK | R200_PS_LIN_ATT_ZERO | R200_PS_SE_SEL_STATE);
643 /* can't rely on ctx->Point._Attenuated here and test for NEW_POINT in
644 r200ValidateState looks like overkill */
645 if (ctx->Point.Params[0] != 1.0 ||
646 ctx->Point.Params[1] != 0.0 ||
647 ctx->Point.Params[2] != 0.0 ||
648 (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled)) {
649 /* all we care for vp would be the ps_se_sel_state setting */
650 fcmd[PTP_ATT_CONST_QUAD] = ctx->Point.Params[2];
651 fcmd[PTP_ATT_CONST_LIN] = ctx->Point.Params[1];
652 fcmd[PTP_ATT_CONST_CON] = ctx->Point.Params[0];
653 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_MULT_ATTENCONST;
654 if (ctx->Point.Params[1] == 0.0)
655 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_LIN_ATT_ZERO;
656 /* FIXME: setting this here doesn't look quite ok - we only want to do
657 that if we're actually drawing points probably */
658 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_PT_SIZE;
659 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= R200_VTX_POINT_SIZE;
660 }
661 else {
662 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
663 R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST;
664 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_PT_SIZE;
665 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~R200_VTX_POINT_SIZE;
666 }
667 break;
668 case GL_POINT_FADE_THRESHOLD_SIZE:
669 /* don't support multisampling, so doesn't matter. */
670 break;
671 /* can't do these but don't need them.
672 case GL_POINT_SPRITE_R_MODE_NV:
673 case GL_POINT_SPRITE_COORD_ORIGIN: */
674 default:
675 fprintf(stderr, "bad pname parameter in r200PointParameter\n");
676 return;
677 }
678 }
679
680 /* =============================================================
681 * Line state
682 */
683 static void r200LineWidth( struct gl_context *ctx, GLfloat widthf )
684 {
685 r200ContextPtr rmesa = R200_CONTEXT(ctx);
686
687 R200_STATECHANGE( rmesa, lin );
688 R200_STATECHANGE( rmesa, set );
689
690 /* Line width is stored in U6.4 format.
691 * Same min/max limits for AA, non-AA lines.
692 */
693 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff;
694 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)
695 (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0);
696
697 if ( widthf > 1.0 ) {
698 rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_WIDELINE_ENABLE;
699 } else {
700 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE;
701 }
702 }
703
704 static void r200LineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
705 {
706 r200ContextPtr rmesa = R200_CONTEXT(ctx);
707
708 R200_STATECHANGE( rmesa, lin );
709 rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
710 ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
711 }
712
713
714 /* =============================================================
715 * Masks
716 */
717 static void r200ColorMask( struct gl_context *ctx,
718 GLboolean r, GLboolean g,
719 GLboolean b, GLboolean a )
720 {
721 r200ContextPtr rmesa = R200_CONTEXT(ctx);
722 GLuint mask;
723 struct radeon_renderbuffer *rrb;
724 GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE;
725
726 rrb = radeon_get_colorbuffer(&rmesa->radeon);
727 if (!rrb)
728 return;
729 mask = radeonPackColor( rrb->cpp,
730 ctx->Color.ColorMask[0][RCOMP],
731 ctx->Color.ColorMask[0][GCOMP],
732 ctx->Color.ColorMask[0][BCOMP],
733 ctx->Color.ColorMask[0][ACOMP] );
734
735
736 if (!(r && g && b && a))
737 flag |= R200_PLANE_MASK_ENABLE;
738
739 if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) {
740 R200_STATECHANGE( rmesa, ctx );
741 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag;
742 }
743
744 if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
745 R200_STATECHANGE( rmesa, msk );
746 rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
747 }
748 }
749
750
751 /* =============================================================
752 * Polygon state
753 */
754
755 static void r200PolygonOffset( struct gl_context *ctx,
756 GLfloat factor, GLfloat units )
757 {
758 r200ContextPtr rmesa = R200_CONTEXT(ctx);
759 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
760 float_ui32_type constant = { units * depthScale };
761 float_ui32_type factoru = { factor };
762
763 /* factor *= 2; */
764 /* constant *= 2; */
765
766 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
767
768 R200_STATECHANGE( rmesa, zbs );
769 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32;
770 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
771 }
772
773 static void r200PolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
774 {
775 r200ContextPtr rmesa = R200_CONTEXT(ctx);
776 GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
777
778 /* Can't generally do unfilled via tcl, but some good special
779 * cases work.
780 */
781 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag);
782 if (rmesa->radeon.TclFallback) {
783 r200ChooseRenderState( ctx );
784 r200ChooseVertexState( ctx );
785 }
786 }
787
788
789 /* =============================================================
790 * Rendering attributes
791 *
792 * We really don't want to recalculate all this every time we bind a
793 * texture. These things shouldn't change all that often, so it makes
794 * sense to break them out of the core texture state update routines.
795 */
796
797 /* Examine lighting and texture state to determine if separate specular
798 * should be enabled.
799 */
800 static void r200UpdateSpecular( struct gl_context *ctx )
801 {
802 r200ContextPtr rmesa = R200_CONTEXT(ctx);
803 uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
804
805 R200_STATECHANGE( rmesa, tcl );
806 R200_STATECHANGE( rmesa, vtx );
807
808 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT);
809 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT);
810 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0;
811 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1;
812 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE;
813
814 p &= ~R200_SPECULAR_ENABLE;
815
816 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE;
817
818
819 if (ctx->Light.Enabled &&
820 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
821 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
822 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
823 (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
824 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
825 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
826 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
827 p |= R200_SPECULAR_ENABLE;
828 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &=
829 ~R200_DIFFUSE_SPECULAR_COMBINE;
830 }
831 else if (ctx->Light.Enabled) {
832 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
833 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
834 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
835 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
836 } else if (ctx->Fog.ColorSumEnabled ) {
837 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
838 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
839 (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
840 p |= R200_SPECULAR_ENABLE;
841 } else {
842 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
843 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
844 }
845
846 if (ctx->Fog.Enabled) {
847 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
848 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
849 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
850 }
851
852 if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
853 R200_STATECHANGE( rmesa, ctx );
854 rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
855 }
856
857 /* Update vertex/render formats
858 */
859 if (rmesa->radeon.TclFallback) {
860 r200ChooseRenderState( ctx );
861 r200ChooseVertexState( ctx );
862 }
863 }
864
865
866 /* =============================================================
867 * Materials
868 */
869
870
871 /* Update on colormaterial, material emmissive/ambient,
872 * lightmodel.globalambient
873 */
874 static void update_global_ambient( struct gl_context *ctx )
875 {
876 r200ContextPtr rmesa = R200_CONTEXT(ctx);
877 float *fcmd = (float *)R200_DB_STATE( glt );
878
879 /* Need to do more if both emmissive & ambient are PREMULT:
880 * I believe this is not nessary when using source_material. This condition thus
881 * will never happen currently, and the function has no dependencies on materials now
882 */
883 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] &
884 ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
885 (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0)
886 {
887 COPY_3V( &fcmd[GLT_RED],
888 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
889 ACC_SCALE_3V( &fcmd[GLT_RED],
890 ctx->Light.Model.Ambient,
891 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
892 }
893 else
894 {
895 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
896 }
897
898 R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
899 }
900
901 /* Update on change to
902 * - light[p].colors
903 * - light[p].enabled
904 */
905 static void update_light_colors( struct gl_context *ctx, GLuint p )
906 {
907 struct gl_light *l = &ctx->Light.Light[p];
908
909 /* fprintf(stderr, "%s\n", __FUNCTION__); */
910
911 if (l->Enabled) {
912 r200ContextPtr rmesa = R200_CONTEXT(ctx);
913 float *fcmd = (float *)R200_DB_STATE( lit[p] );
914
915 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
916 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
917 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
918
919 R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
920 }
921 }
922
923 static void r200ColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
924 {
925 r200ContextPtr rmesa = R200_CONTEXT(ctx);
926 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1];
927 light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
928 (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
929 (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
930 (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
931 (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
932 (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) |
933 (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
934 (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT));
935
936 if (ctx->Light.ColorMaterialEnabled) {
937 GLuint mask = ctx->Light.ColorMaterialBitmask;
938
939 if (mask & MAT_BIT_FRONT_EMISSION) {
940 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
941 R200_FRONT_EMISSIVE_SOURCE_SHIFT);
942 }
943 else
944 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
945 R200_FRONT_EMISSIVE_SOURCE_SHIFT);
946
947 if (mask & MAT_BIT_FRONT_AMBIENT) {
948 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
949 R200_FRONT_AMBIENT_SOURCE_SHIFT);
950 }
951 else
952 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
953 R200_FRONT_AMBIENT_SOURCE_SHIFT);
954
955 if (mask & MAT_BIT_FRONT_DIFFUSE) {
956 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
957 R200_FRONT_DIFFUSE_SOURCE_SHIFT);
958 }
959 else
960 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
961 R200_FRONT_DIFFUSE_SOURCE_SHIFT);
962
963 if (mask & MAT_BIT_FRONT_SPECULAR) {
964 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
965 R200_FRONT_SPECULAR_SOURCE_SHIFT);
966 }
967 else {
968 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
969 R200_FRONT_SPECULAR_SOURCE_SHIFT);
970 }
971
972 if (mask & MAT_BIT_BACK_EMISSION) {
973 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
974 R200_BACK_EMISSIVE_SOURCE_SHIFT);
975 }
976
977 else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
978 R200_BACK_EMISSIVE_SOURCE_SHIFT);
979
980 if (mask & MAT_BIT_BACK_AMBIENT) {
981 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
982 R200_BACK_AMBIENT_SOURCE_SHIFT);
983 }
984 else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
985 R200_BACK_AMBIENT_SOURCE_SHIFT);
986
987 if (mask & MAT_BIT_BACK_DIFFUSE) {
988 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
989 R200_BACK_DIFFUSE_SOURCE_SHIFT);
990 }
991 else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
992 R200_BACK_DIFFUSE_SOURCE_SHIFT);
993
994 if (mask & MAT_BIT_BACK_SPECULAR) {
995 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
996 R200_BACK_SPECULAR_SOURCE_SHIFT);
997 }
998 else {
999 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
1000 R200_BACK_SPECULAR_SOURCE_SHIFT);
1001 }
1002 }
1003 else {
1004 /* Default to SOURCE_MATERIAL:
1005 */
1006 light_model_ctl1 |=
1007 (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
1008 (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
1009 (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
1010 (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
1011 (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
1012 (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) |
1013 (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
1014 (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT);
1015 }
1016
1017 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) {
1018 R200_STATECHANGE( rmesa, tcl );
1019 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1;
1020 }
1021
1022
1023 }
1024
1025 void r200UpdateMaterial( struct gl_context *ctx )
1026 {
1027 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1028 GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
1029 GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] );
1030 GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] );
1031 GLuint mask = ~0;
1032
1033 /* Might be possible and faster to update everything unconditionally? */
1034 if (ctx->Light.ColorMaterialEnabled)
1035 mask &= ~ctx->Light.ColorMaterialBitmask;
1036
1037 if (R200_DEBUG & RADEON_STATE)
1038 fprintf(stderr, "%s\n", __FUNCTION__);
1039
1040 if (mask & MAT_BIT_FRONT_EMISSION) {
1041 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
1042 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
1043 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
1044 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
1045 }
1046 if (mask & MAT_BIT_FRONT_AMBIENT) {
1047 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
1048 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
1049 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
1050 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
1051 }
1052 if (mask & MAT_BIT_FRONT_DIFFUSE) {
1053 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
1054 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
1055 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
1056 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
1057 }
1058 if (mask & MAT_BIT_FRONT_SPECULAR) {
1059 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
1060 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
1061 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
1062 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
1063 }
1064 if (mask & MAT_BIT_FRONT_SHININESS) {
1065 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
1066 }
1067
1068 if (mask & MAT_BIT_BACK_EMISSION) {
1069 fcmd2[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_BACK_EMISSION][0];
1070 fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1];
1071 fcmd2[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_BACK_EMISSION][2];
1072 fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3];
1073 }
1074 if (mask & MAT_BIT_BACK_AMBIENT) {
1075 fcmd2[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_BACK_AMBIENT][0];
1076 fcmd2[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_BACK_AMBIENT][1];
1077 fcmd2[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_BACK_AMBIENT][2];
1078 fcmd2[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_BACK_AMBIENT][3];
1079 }
1080 if (mask & MAT_BIT_BACK_DIFFUSE) {
1081 fcmd2[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_BACK_DIFFUSE][0];
1082 fcmd2[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_BACK_DIFFUSE][1];
1083 fcmd2[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_BACK_DIFFUSE][2];
1084 fcmd2[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_BACK_DIFFUSE][3];
1085 }
1086 if (mask & MAT_BIT_BACK_SPECULAR) {
1087 fcmd2[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_BACK_SPECULAR][0];
1088 fcmd2[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_BACK_SPECULAR][1];
1089 fcmd2[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_BACK_SPECULAR][2];
1090 fcmd2[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_BACK_SPECULAR][3];
1091 }
1092 if (mask & MAT_BIT_BACK_SHININESS) {
1093 fcmd2[MTL_SHININESS] = mat[MAT_ATTRIB_BACK_SHININESS][0];
1094 }
1095
1096 R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] );
1097 R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] );
1098
1099 /* currently material changes cannot trigger a global ambient change, I believe this is correct
1100 update_global_ambient( ctx ); */
1101 }
1102
1103 /* _NEW_LIGHT
1104 * _NEW_MODELVIEW
1105 * _MESA_NEW_NEED_EYE_COORDS
1106 *
1107 * Uses derived state from mesa:
1108 * _VP_inf_norm
1109 * _h_inf_norm
1110 * _Position
1111 * _NormSpotDirection
1112 * _ModelViewInvScale
1113 * _NeedEyeCoords
1114 * _EyeZDir
1115 *
1116 * which are calculated in light.c and are correct for the current
1117 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
1118 * and _MESA_NEW_NEED_EYE_COORDS.
1119 */
1120 static void update_light( struct gl_context *ctx )
1121 {
1122 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1123
1124 /* Have to check these, or have an automatic shortcircuit mechanism
1125 * to remove noop statechanges. (Or just do a better job on the
1126 * front end).
1127 */
1128 {
1129 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0];
1130
1131 if (ctx->_NeedEyeCoords)
1132 tmp &= ~R200_LIGHT_IN_MODELSPACE;
1133 else
1134 tmp |= R200_LIGHT_IN_MODELSPACE;
1135
1136 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0])
1137 {
1138 R200_STATECHANGE( rmesa, tcl );
1139 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = tmp;
1140 }
1141 }
1142
1143 {
1144 GLfloat *fcmd = (GLfloat *)R200_DB_STATE( eye );
1145 fcmd[EYE_X] = ctx->_EyeZDir[0];
1146 fcmd[EYE_Y] = ctx->_EyeZDir[1];
1147 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
1148 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
1149 R200_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
1150 }
1151
1152
1153
1154 if (ctx->Light.Enabled) {
1155 GLint p;
1156 for (p = 0 ; p < MAX_LIGHTS; p++) {
1157 if (ctx->Light.Light[p].Enabled) {
1158 struct gl_light *l = &ctx->Light.Light[p];
1159 GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] );
1160
1161 if (l->EyePosition[3] == 0.0) {
1162 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
1163 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
1164 fcmd[LIT_POSITION_W] = 0;
1165 fcmd[LIT_DIRECTION_W] = 0;
1166 } else {
1167 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
1168 fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
1169 fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
1170 fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
1171 fcmd[LIT_DIRECTION_W] = 0;
1172 }
1173
1174 R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
1175 }
1176 }
1177 }
1178 }
1179
1180 static void r200Lightfv( struct gl_context *ctx, GLenum light,
1181 GLenum pname, const GLfloat *params )
1182 {
1183 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1184 GLint p = light - GL_LIGHT0;
1185 struct gl_light *l = &ctx->Light.Light[p];
1186 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
1187
1188
1189 switch (pname) {
1190 case GL_AMBIENT:
1191 case GL_DIFFUSE:
1192 case GL_SPECULAR:
1193 update_light_colors( ctx, p );
1194 break;
1195
1196 case GL_SPOT_DIRECTION:
1197 /* picked up in update_light */
1198 break;
1199
1200 case GL_POSITION: {
1201 /* positions picked up in update_light, but can do flag here */
1202 GLuint flag = (p&1)? R200_LIGHT_1_IS_LOCAL : R200_LIGHT_0_IS_LOCAL;
1203 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1204
1205 R200_STATECHANGE(rmesa, tcl);
1206 if (l->EyePosition[3] != 0.0F)
1207 rmesa->hw.tcl.cmd[idx] |= flag;
1208 else
1209 rmesa->hw.tcl.cmd[idx] &= ~flag;
1210 break;
1211 }
1212
1213 case GL_SPOT_EXPONENT:
1214 R200_STATECHANGE(rmesa, lit[p]);
1215 fcmd[LIT_SPOT_EXPONENT] = params[0];
1216 break;
1217
1218 case GL_SPOT_CUTOFF: {
1219 GLuint flag = (p&1) ? R200_LIGHT_1_IS_SPOT : R200_LIGHT_0_IS_SPOT;
1220 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1221
1222 R200_STATECHANGE(rmesa, lit[p]);
1223 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1224
1225 R200_STATECHANGE(rmesa, tcl);
1226 if (l->SpotCutoff != 180.0F)
1227 rmesa->hw.tcl.cmd[idx] |= flag;
1228 else
1229 rmesa->hw.tcl.cmd[idx] &= ~flag;
1230
1231 break;
1232 }
1233
1234 case GL_CONSTANT_ATTENUATION:
1235 R200_STATECHANGE(rmesa, lit[p]);
1236 fcmd[LIT_ATTEN_CONST] = params[0];
1237 if ( params[0] == 0.0 )
1238 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1239 else
1240 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1241 break;
1242 case GL_LINEAR_ATTENUATION:
1243 R200_STATECHANGE(rmesa, lit[p]);
1244 fcmd[LIT_ATTEN_LINEAR] = params[0];
1245 break;
1246 case GL_QUADRATIC_ATTENUATION:
1247 R200_STATECHANGE(rmesa, lit[p]);
1248 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1249 break;
1250 default:
1251 return;
1252 }
1253
1254 /* Set RANGE_ATTEN only when needed */
1255 switch (pname) {
1256 case GL_POSITION:
1257 case GL_CONSTANT_ATTENUATION:
1258 case GL_LINEAR_ATTENUATION:
1259 case GL_QUADRATIC_ATTENUATION: {
1260 GLuint *icmd = (GLuint *)R200_DB_STATE( tcl );
1261 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1262 GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1263 : R200_LIGHT_0_ENABLE_RANGE_ATTEN;
1264 GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1265 : R200_LIGHT_0_CONSTANT_RANGE_ATTEN;
1266
1267 if ( l->EyePosition[3] == 0.0F ||
1268 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1269 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1270 /* Disable attenuation */
1271 icmd[idx] &= ~atten_flag;
1272 } else {
1273 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1274 /* Enable only constant portion of attenuation calculation */
1275 icmd[idx] |= ( atten_flag | atten_const_flag );
1276 } else {
1277 /* Enable full attenuation calculation */
1278 icmd[idx] &= ~atten_const_flag;
1279 icmd[idx] |= atten_flag;
1280 }
1281 }
1282
1283 R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1284 break;
1285 }
1286 default:
1287 break;
1288 }
1289 }
1290
1291 static void r200UpdateLocalViewer ( struct gl_context *ctx )
1292 {
1293 /* It looks like for the texgen modes GL_SPHERE_MAP, GL_NORMAL_MAP and
1294 GL_REFLECTION_MAP we need R200_LOCAL_VIEWER set (fglrx does exactly that
1295 for these and only these modes). This means specular highlights may turn out
1296 wrong in some cases when lighting is enabled but GL_LIGHT_MODEL_LOCAL_VIEWER
1297 is not set, though it seems to happen rarely and the effect seems quite
1298 subtle. May need TCL fallback to fix it completely, though I'm not sure
1299 how you'd identify the cases where the specular highlights indeed will
1300 be wrong. Don't know if fglrx does something special in that case.
1301 */
1302 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1303 R200_STATECHANGE( rmesa, tcl );
1304 if (ctx->Light.Model.LocalViewer ||
1305 ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
1306 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LOCAL_VIEWER;
1307 else
1308 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LOCAL_VIEWER;
1309 }
1310
1311 static void r200LightModelfv( struct gl_context *ctx, GLenum pname,
1312 const GLfloat *param )
1313 {
1314 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1315
1316 switch (pname) {
1317 case GL_LIGHT_MODEL_AMBIENT:
1318 update_global_ambient( ctx );
1319 break;
1320
1321 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1322 r200UpdateLocalViewer( ctx );
1323 break;
1324
1325 case GL_LIGHT_MODEL_TWO_SIDE:
1326 R200_STATECHANGE( rmesa, tcl );
1327 if (ctx->Light.Model.TwoSide)
1328 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE;
1329 else
1330 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE);
1331 if (rmesa->radeon.TclFallback) {
1332 r200ChooseRenderState( ctx );
1333 r200ChooseVertexState( ctx );
1334 }
1335 break;
1336
1337 case GL_LIGHT_MODEL_COLOR_CONTROL:
1338 r200UpdateSpecular(ctx);
1339 break;
1340
1341 default:
1342 break;
1343 }
1344 }
1345
1346 static void r200ShadeModel( struct gl_context *ctx, GLenum mode )
1347 {
1348 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1349 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1350
1351 s &= ~(R200_DIFFUSE_SHADE_MASK |
1352 R200_ALPHA_SHADE_MASK |
1353 R200_SPECULAR_SHADE_MASK |
1354 R200_FOG_SHADE_MASK |
1355 R200_DISC_FOG_SHADE_MASK);
1356
1357 switch ( mode ) {
1358 case GL_FLAT:
1359 s |= (R200_DIFFUSE_SHADE_FLAT |
1360 R200_ALPHA_SHADE_FLAT |
1361 R200_SPECULAR_SHADE_FLAT |
1362 R200_FOG_SHADE_FLAT |
1363 R200_DISC_FOG_SHADE_FLAT);
1364 break;
1365 case GL_SMOOTH:
1366 s |= (R200_DIFFUSE_SHADE_GOURAUD |
1367 R200_ALPHA_SHADE_GOURAUD |
1368 R200_SPECULAR_SHADE_GOURAUD |
1369 R200_FOG_SHADE_GOURAUD |
1370 R200_DISC_FOG_SHADE_GOURAUD);
1371 break;
1372 default:
1373 return;
1374 }
1375
1376 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1377 R200_STATECHANGE( rmesa, set );
1378 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1379 }
1380 }
1381
1382
1383 /* =============================================================
1384 * User clip planes
1385 */
1386
1387 static void r200ClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1388 {
1389 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1390 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1391 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1392
1393 R200_STATECHANGE( rmesa, ucp[p] );
1394 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1395 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1396 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1397 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1398 }
1399
1400 static void r200UpdateClipPlanes( struct gl_context *ctx )
1401 {
1402 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1403 GLuint p;
1404
1405 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1406 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1407 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1408
1409 R200_STATECHANGE( rmesa, ucp[p] );
1410 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1411 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1412 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1413 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1414 }
1415 }
1416 }
1417
1418
1419 /* =============================================================
1420 * Stencil
1421 */
1422
1423 static void
1424 r200StencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1425 GLint ref, GLuint mask )
1426 {
1427 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1428 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R200_STENCIL_REF_SHIFT) |
1429 ((ctx->Stencil.ValueMask[0] & 0xff) << R200_STENCIL_MASK_SHIFT));
1430
1431 R200_STATECHANGE( rmesa, ctx );
1432 R200_STATECHANGE( rmesa, msk );
1433
1434 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_STENCIL_TEST_MASK;
1435 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(R200_STENCIL_REF_MASK|
1436 R200_STENCIL_VALUE_MASK);
1437
1438 switch ( ctx->Stencil.Function[0] ) {
1439 case GL_NEVER:
1440 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEVER;
1441 break;
1442 case GL_LESS:
1443 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LESS;
1444 break;
1445 case GL_EQUAL:
1446 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_EQUAL;
1447 break;
1448 case GL_LEQUAL:
1449 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LEQUAL;
1450 break;
1451 case GL_GREATER:
1452 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GREATER;
1453 break;
1454 case GL_NOTEQUAL:
1455 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEQUAL;
1456 break;
1457 case GL_GEQUAL:
1458 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GEQUAL;
1459 break;
1460 case GL_ALWAYS:
1461 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_ALWAYS;
1462 break;
1463 }
1464
1465 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1466 }
1467
1468 static void
1469 r200StencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1470 {
1471 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1472
1473 R200_STATECHANGE( rmesa, msk );
1474 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK;
1475 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1476 ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT);
1477 }
1478
1479 static void
1480 r200StencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1481 GLenum zfail, GLenum zpass )
1482 {
1483 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1484
1485 R200_STATECHANGE( rmesa, ctx );
1486 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(R200_STENCIL_FAIL_MASK |
1487 R200_STENCIL_ZFAIL_MASK |
1488 R200_STENCIL_ZPASS_MASK);
1489
1490 switch ( ctx->Stencil.FailFunc[0] ) {
1491 case GL_KEEP:
1492 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_KEEP;
1493 break;
1494 case GL_ZERO:
1495 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_ZERO;
1496 break;
1497 case GL_REPLACE:
1498 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_REPLACE;
1499 break;
1500 case GL_INCR:
1501 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC;
1502 break;
1503 case GL_DECR:
1504 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC;
1505 break;
1506 case GL_INCR_WRAP_EXT:
1507 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC_WRAP;
1508 break;
1509 case GL_DECR_WRAP_EXT:
1510 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC_WRAP;
1511 break;
1512 case GL_INVERT:
1513 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INVERT;
1514 break;
1515 }
1516
1517 switch ( ctx->Stencil.ZFailFunc[0] ) {
1518 case GL_KEEP:
1519 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_KEEP;
1520 break;
1521 case GL_ZERO:
1522 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_ZERO;
1523 break;
1524 case GL_REPLACE:
1525 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_REPLACE;
1526 break;
1527 case GL_INCR:
1528 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC;
1529 break;
1530 case GL_DECR:
1531 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC;
1532 break;
1533 case GL_INCR_WRAP_EXT:
1534 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC_WRAP;
1535 break;
1536 case GL_DECR_WRAP_EXT:
1537 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC_WRAP;
1538 break;
1539 case GL_INVERT:
1540 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INVERT;
1541 break;
1542 }
1543
1544 switch ( ctx->Stencil.ZPassFunc[0] ) {
1545 case GL_KEEP:
1546 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_KEEP;
1547 break;
1548 case GL_ZERO:
1549 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_ZERO;
1550 break;
1551 case GL_REPLACE:
1552 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_REPLACE;
1553 break;
1554 case GL_INCR:
1555 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC;
1556 break;
1557 case GL_DECR:
1558 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC;
1559 break;
1560 case GL_INCR_WRAP_EXT:
1561 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC_WRAP;
1562 break;
1563 case GL_DECR_WRAP_EXT:
1564 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC_WRAP;
1565 break;
1566 case GL_INVERT:
1567 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INVERT;
1568 break;
1569 }
1570 }
1571
1572 static void r200ClearStencil( struct gl_context *ctx, GLint s )
1573 {
1574 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1575
1576 rmesa->radeon.state.stencil.clear =
1577 ((GLuint) (ctx->Stencil.Clear & 0xff) |
1578 (0xff << R200_STENCIL_MASK_SHIFT) |
1579 ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT));
1580 }
1581
1582
1583 /* =============================================================
1584 * Window position and viewport transformation
1585 */
1586
1587 /**
1588 * Called when window size or position changes or viewport or depth range
1589 * state is changed. We update the hardware viewport state here.
1590 */
1591 void r200UpdateWindow( struct gl_context *ctx )
1592 {
1593 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1594 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1595 GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1596 GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1597 const GLfloat *v = ctx->Viewport._WindowMap.m;
1598 const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1599 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1600 GLfloat y_scale, y_bias;
1601
1602 if (render_to_fbo) {
1603 y_scale = 1.0;
1604 y_bias = 0;
1605 } else {
1606 y_scale = -1.0;
1607 y_bias = yoffset;
1608 }
1609
1610 float_ui32_type sx = { v[MAT_SX] };
1611 float_ui32_type tx = { v[MAT_TX] + xoffset };
1612 float_ui32_type sy = { v[MAT_SY] * y_scale };
1613 float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias };
1614 float_ui32_type sz = { v[MAT_SZ] * depthScale };
1615 float_ui32_type tz = { v[MAT_TZ] * depthScale };
1616
1617 R200_STATECHANGE( rmesa, vpt );
1618
1619 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1620 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1621 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1622 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1623 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1624 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1625 }
1626
1627 void r200_vtbl_update_scissor( struct gl_context *ctx )
1628 {
1629 r200ContextPtr r200 = R200_CONTEXT(ctx);
1630 unsigned x1, y1, x2, y2;
1631 struct radeon_renderbuffer *rrb;
1632
1633 R200_SET_STATE(r200, set, SET_RE_CNTL, R200_SCISSOR_ENABLE | r200->hw.set.cmd[SET_RE_CNTL]);
1634
1635 if (r200->radeon.state.scissor.enabled) {
1636 x1 = r200->radeon.state.scissor.rect.x1;
1637 y1 = r200->radeon.state.scissor.rect.y1;
1638 x2 = r200->radeon.state.scissor.rect.x2;
1639 y2 = r200->radeon.state.scissor.rect.y2;
1640 } else {
1641 rrb = radeon_get_colorbuffer(&r200->radeon);
1642 x1 = 0;
1643 y1 = 0;
1644 x2 = rrb->base.Width - 1;
1645 y2 = rrb->base.Height - 1;
1646 }
1647
1648 R200_SET_STATE(r200, sci, SCI_XY_1, x1 | (y1 << 16));
1649 R200_SET_STATE(r200, sci, SCI_XY_2, x2 | (y2 << 16));
1650 }
1651
1652
1653 static void r200Viewport( struct gl_context *ctx, GLint x, GLint y,
1654 GLsizei width, GLsizei height )
1655 {
1656 /* Don't pipeline viewport changes, conflict with window offset
1657 * setting below. Could apply deltas to rescue pipelined viewport
1658 * values, or keep the originals hanging around.
1659 */
1660 r200UpdateWindow( ctx );
1661
1662 radeon_viewport(ctx, x, y, width, height);
1663 }
1664
1665 static void r200DepthRange( struct gl_context *ctx, GLclampd nearval,
1666 GLclampd farval )
1667 {
1668 r200UpdateWindow( ctx );
1669 }
1670
1671 void r200UpdateViewportOffset( struct gl_context *ctx )
1672 {
1673 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1674 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1675 GLfloat xoffset = (GLfloat)dPriv->x;
1676 GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1677 const GLfloat *v = ctx->Viewport._WindowMap.m;
1678
1679 float_ui32_type tx;
1680 float_ui32_type ty;
1681
1682 tx.f = v[MAT_TX] + xoffset;
1683 ty.f = (- v[MAT_TY]) + yoffset;
1684
1685 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1686 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1687 {
1688 /* Note: this should also modify whatever data the context reset
1689 * code uses...
1690 */
1691 R200_STATECHANGE( rmesa, vpt );
1692 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1693 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1694
1695 /* update polygon stipple x/y screen offset */
1696 {
1697 GLuint stx, sty;
1698 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1699
1700 m &= ~(R200_STIPPLE_X_OFFSET_MASK |
1701 R200_STIPPLE_Y_OFFSET_MASK);
1702
1703 /* add magic offsets, then invert */
1704 stx = 31 - ((dPriv->x - 1) & R200_STIPPLE_COORD_MASK);
1705 sty = 31 - ((dPriv->y + dPriv->h - 1)
1706 & R200_STIPPLE_COORD_MASK);
1707
1708 m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) |
1709 (sty << R200_STIPPLE_Y_OFFSET_SHIFT));
1710
1711 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1712 R200_STATECHANGE( rmesa, msc );
1713 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1714 }
1715 }
1716 }
1717
1718 radeonUpdateScissor( ctx );
1719 }
1720
1721
1722
1723 /* =============================================================
1724 * Miscellaneous
1725 */
1726
1727 static void r200ClearColor( struct gl_context *ctx,
1728 const union gl_color_union c )
1729 {
1730 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1731 GLubyte color[4];
1732 struct radeon_renderbuffer *rrb;
1733
1734 rrb = radeon_get_colorbuffer(&rmesa->radeon);
1735 if (!rrb)
1736 return;
1737 _mesa_unclamped_float_rgba_to_ubyte(color, c.f);
1738 rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1739 color[0], color[1],
1740 color[2], color[3] );
1741 }
1742
1743
1744 static void r200RenderMode( struct gl_context *ctx, GLenum mode )
1745 {
1746 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1747 FALLBACK( rmesa, R200_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1748 }
1749
1750
1751 static GLuint r200_rop_tab[] = {
1752 R200_ROP_CLEAR,
1753 R200_ROP_AND,
1754 R200_ROP_AND_REVERSE,
1755 R200_ROP_COPY,
1756 R200_ROP_AND_INVERTED,
1757 R200_ROP_NOOP,
1758 R200_ROP_XOR,
1759 R200_ROP_OR,
1760 R200_ROP_NOR,
1761 R200_ROP_EQUIV,
1762 R200_ROP_INVERT,
1763 R200_ROP_OR_REVERSE,
1764 R200_ROP_COPY_INVERTED,
1765 R200_ROP_OR_INVERTED,
1766 R200_ROP_NAND,
1767 R200_ROP_SET,
1768 };
1769
1770 static void r200LogicOpCode( struct gl_context *ctx, GLenum opcode )
1771 {
1772 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1773 GLuint rop = (GLuint)opcode - GL_CLEAR;
1774
1775 ASSERT( rop < 16 );
1776
1777 R200_STATECHANGE( rmesa, msk );
1778 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop];
1779 }
1780
1781 /* =============================================================
1782 * State enable/disable
1783 */
1784
1785 static void r200Enable( struct gl_context *ctx, GLenum cap, GLboolean state )
1786 {
1787 r200ContextPtr rmesa = R200_CONTEXT(ctx);
1788 GLuint p, flag;
1789
1790 if ( R200_DEBUG & RADEON_STATE )
1791 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1792 _mesa_lookup_enum_by_nr( cap ),
1793 state ? "GL_TRUE" : "GL_FALSE" );
1794
1795 switch ( cap ) {
1796 /* Fast track this one...
1797 */
1798 case GL_TEXTURE_1D:
1799 case GL_TEXTURE_2D:
1800 case GL_TEXTURE_3D:
1801 break;
1802
1803 case GL_ALPHA_TEST:
1804 R200_STATECHANGE( rmesa, ctx );
1805 if (state) {
1806 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ALPHA_TEST_ENABLE;
1807 } else {
1808 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ALPHA_TEST_ENABLE;
1809 }
1810 break;
1811
1812 case GL_BLEND:
1813 case GL_COLOR_LOGIC_OP:
1814 r200_set_blend_state( ctx );
1815 break;
1816
1817 case GL_CLIP_PLANE0:
1818 case GL_CLIP_PLANE1:
1819 case GL_CLIP_PLANE2:
1820 case GL_CLIP_PLANE3:
1821 case GL_CLIP_PLANE4:
1822 case GL_CLIP_PLANE5:
1823 p = cap-GL_CLIP_PLANE0;
1824 R200_STATECHANGE( rmesa, tcl );
1825 if (state) {
1826 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0<<p);
1827 r200ClipPlane( ctx, cap, NULL );
1828 }
1829 else {
1830 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0<<p);
1831 }
1832 break;
1833
1834 case GL_COLOR_MATERIAL:
1835 r200ColorMaterial( ctx, 0, 0 );
1836 r200UpdateMaterial( ctx );
1837 break;
1838
1839 case GL_CULL_FACE:
1840 r200CullFace( ctx, 0 );
1841 break;
1842
1843 case GL_DEPTH_TEST:
1844 R200_STATECHANGE(rmesa, ctx );
1845 if ( state ) {
1846 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_Z_ENABLE;
1847 } else {
1848 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_Z_ENABLE;
1849 }
1850 break;
1851
1852 case GL_DITHER:
1853 R200_STATECHANGE(rmesa, ctx );
1854 if ( state ) {
1855 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE;
1856 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1857 } else {
1858 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE;
1859 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1860 }
1861 break;
1862
1863 case GL_FOG:
1864 R200_STATECHANGE(rmesa, ctx );
1865 if ( state ) {
1866 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_FOG_ENABLE;
1867 r200Fogfv( ctx, GL_FOG_MODE, NULL );
1868 } else {
1869 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_FOG_ENABLE;
1870 R200_STATECHANGE(rmesa, tcl);
1871 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
1872 }
1873 r200UpdateSpecular( ctx ); /* for PK_SPEC */
1874 if (rmesa->radeon.TclFallback)
1875 r200ChooseVertexState( ctx );
1876 _mesa_allow_light_in_model( ctx, !state );
1877 break;
1878
1879 case GL_LIGHT0:
1880 case GL_LIGHT1:
1881 case GL_LIGHT2:
1882 case GL_LIGHT3:
1883 case GL_LIGHT4:
1884 case GL_LIGHT5:
1885 case GL_LIGHT6:
1886 case GL_LIGHT7:
1887 R200_STATECHANGE(rmesa, tcl);
1888 p = cap - GL_LIGHT0;
1889 if (p&1)
1890 flag = (R200_LIGHT_1_ENABLE |
1891 R200_LIGHT_1_ENABLE_AMBIENT |
1892 R200_LIGHT_1_ENABLE_SPECULAR);
1893 else
1894 flag = (R200_LIGHT_0_ENABLE |
1895 R200_LIGHT_0_ENABLE_AMBIENT |
1896 R200_LIGHT_0_ENABLE_SPECULAR);
1897
1898 if (state)
1899 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1900 else
1901 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1902
1903 /*
1904 */
1905 update_light_colors( ctx, p );
1906 break;
1907
1908 case GL_LIGHTING:
1909 r200UpdateSpecular(ctx);
1910 /* for reflection map fixup - might set recheck_texgen for all units too */
1911 rmesa->radeon.NewGLState |= _NEW_TEXTURE;
1912 break;
1913
1914 case GL_LINE_SMOOTH:
1915 R200_STATECHANGE( rmesa, ctx );
1916 if ( state ) {
1917 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ANTI_ALIAS_LINE;
1918 } else {
1919 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_LINE;
1920 }
1921 break;
1922
1923 case GL_LINE_STIPPLE:
1924 R200_STATECHANGE( rmesa, set );
1925 if ( state ) {
1926 rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PATTERN_ENABLE;
1927 } else {
1928 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PATTERN_ENABLE;
1929 }
1930 break;
1931
1932 case GL_NORMALIZE:
1933 R200_STATECHANGE( rmesa, tcl );
1934 if ( state ) {
1935 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_NORMALIZE_NORMALS;
1936 } else {
1937 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_NORMALIZE_NORMALS;
1938 }
1939 break;
1940
1941 /* Pointsize registers on r200 only work for point sprites, and point smooth
1942 * doesn't work for point sprites (and isn't needed for 1.0 sized aa points).
1943 * In any case, setting pointmin == pointsizemax == 1.0 for aa points
1944 * is enough to satisfy conform.
1945 */
1946 case GL_POINT_SMOOTH:
1947 break;
1948
1949 /* These don't really do anything, as we don't use the 3vtx
1950 * primitives yet.
1951 */
1952 #if 0
1953 case GL_POLYGON_OFFSET_POINT:
1954 R200_STATECHANGE( rmesa, set );
1955 if ( state ) {
1956 rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_ZBIAS_ENABLE_POINT;
1957 } else {
1958 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_POINT;
1959 }
1960 break;
1961
1962 case GL_POLYGON_OFFSET_LINE:
1963 R200_STATECHANGE( rmesa, set );
1964 if ( state ) {
1965 rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_ZBIAS_ENABLE_LINE;
1966 } else {
1967 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_LINE;
1968 }
1969 break;
1970 #endif
1971
1972 case GL_POINT_SPRITE_ARB:
1973 R200_STATECHANGE( rmesa, spr );
1974 if ( state ) {
1975 int i;
1976 for (i = 0; i < 6; i++) {
1977 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
1978 ctx->Point.CoordReplace[i] << (R200_PS_GEN_TEX_0_SHIFT + i);
1979 }
1980 } else {
1981 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~R200_PS_GEN_TEX_MASK;
1982 }
1983 break;
1984
1985 case GL_POLYGON_OFFSET_FILL:
1986 R200_STATECHANGE( rmesa, set );
1987 if ( state ) {
1988 rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_ZBIAS_ENABLE_TRI;
1989 } else {
1990 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_TRI;
1991 }
1992 break;
1993
1994 case GL_POLYGON_SMOOTH:
1995 R200_STATECHANGE( rmesa, ctx );
1996 if ( state ) {
1997 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ANTI_ALIAS_POLY;
1998 } else {
1999 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_POLY;
2000 }
2001 break;
2002
2003 case GL_POLYGON_STIPPLE:
2004 R200_STATECHANGE(rmesa, set );
2005 if ( state ) {
2006 rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_STIPPLE_ENABLE;
2007 } else {
2008 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_STIPPLE_ENABLE;
2009 }
2010 break;
2011
2012 case GL_RESCALE_NORMAL_EXT: {
2013 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
2014 R200_STATECHANGE( rmesa, tcl );
2015 if ( tmp ) {
2016 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_RESCALE_NORMALS;
2017 } else {
2018 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2019 }
2020 break;
2021 }
2022
2023 case GL_SCISSOR_TEST:
2024 radeon_firevertices(&rmesa->radeon);
2025 rmesa->radeon.state.scissor.enabled = state;
2026 radeonUpdateScissor( ctx );
2027 break;
2028
2029 case GL_STENCIL_TEST:
2030 {
2031 GLboolean hw_stencil = GL_FALSE;
2032 if (ctx->DrawBuffer) {
2033 struct radeon_renderbuffer *rrbStencil
2034 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
2035 hw_stencil = (rrbStencil && rrbStencil->bo);
2036 }
2037
2038 if (hw_stencil) {
2039 R200_STATECHANGE( rmesa, ctx );
2040 if ( state ) {
2041 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_STENCIL_ENABLE;
2042 } else {
2043 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
2044 }
2045 } else {
2046 FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
2047 }
2048 }
2049 break;
2050
2051 case GL_TEXTURE_GEN_Q:
2052 case GL_TEXTURE_GEN_R:
2053 case GL_TEXTURE_GEN_S:
2054 case GL_TEXTURE_GEN_T:
2055 /* Picked up in r200UpdateTextureState.
2056 */
2057 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
2058 break;
2059
2060 case GL_COLOR_SUM_EXT:
2061 r200UpdateSpecular ( ctx );
2062 break;
2063
2064 case GL_VERTEX_PROGRAM_ARB:
2065 if (!state) {
2066 GLuint i;
2067 rmesa->curr_vp_hw = NULL;
2068 R200_STATECHANGE( rmesa, vap );
2069 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_PROG_VTX_SHADER_ENABLE;
2070 /* mark all tcl atoms (tcl vector state got overwritten) dirty
2071 not sure about tcl scalar state - we need at least grd
2072 with vert progs too.
2073 ucp looks like it doesn't get overwritten (may even work
2074 with vp for pos-invariant progs if we're lucky) */
2075 R200_STATECHANGE( rmesa, mtl[0] );
2076 R200_STATECHANGE( rmesa, mtl[1] );
2077 R200_STATECHANGE( rmesa, fog );
2078 R200_STATECHANGE( rmesa, glt );
2079 R200_STATECHANGE( rmesa, eye );
2080 for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) {
2081 R200_STATECHANGE( rmesa, mat[i] );
2082 }
2083 for (i = 0 ; i < 8; i++) {
2084 R200_STATECHANGE( rmesa, lit[i] );
2085 }
2086 R200_STATECHANGE( rmesa, tcl );
2087 for (i = 0; i <= ctx->Const.MaxClipPlanes; i++) {
2088 if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
2089 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0 << i);
2090 }
2091 /* else {
2092 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0 << i);
2093 }*/
2094 }
2095 /* ugly. Need to call everything which might change compsel. */
2096 r200UpdateSpecular( ctx );
2097 #if 0
2098 /* shouldn't be necessary, as it's picked up anyway in r200ValidateState (_NEW_PROGRAM),
2099 but without it doom3 locks up at always the same places. Why? */
2100 /* FIXME: This can (and should) be replaced by a call to the TCL_STATE_FLUSH reg before
2101 accessing VAP_SE_VAP_CNTL. Requires drm changes (done). Remove after some time... */
2102 r200UpdateTextureState( ctx );
2103 /* if we call r200UpdateTextureState we need the code below because we are calling it with
2104 non-current derived enabled values which may revert the state atoms for frag progs even when
2105 they already got disabled... ugh
2106 Should really figure out why we need to call r200UpdateTextureState in the first place */
2107 GLuint unit;
2108 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
2109 R200_STATECHANGE( rmesa, pix[unit] );
2110 R200_STATECHANGE( rmesa, tex[unit] );
2111 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2112 ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2113 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2114 /* need to guard this with drmSupportsFragmentShader? Should never get here if
2115 we don't announce ATI_fs, right? */
2116 rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2117 }
2118 R200_STATECHANGE( rmesa, cst );
2119 R200_STATECHANGE( rmesa, tf );
2120 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2121 #endif
2122 }
2123 else {
2124 /* picked up later */
2125 }
2126 /* call functions which change hw state based on ARB_vp enabled or not. */
2127 r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
2128 r200Fogfv( ctx, GL_FOG_COORD_SRC, NULL );
2129 break;
2130
2131 case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
2132 r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
2133 break;
2134
2135 case GL_FRAGMENT_SHADER_ATI:
2136 if ( !state ) {
2137 /* restore normal tex env colors and make sure tex env combine will get updated
2138 mark env atoms dirty (as their data was overwritten by afs even
2139 if they didn't change) and restore tex coord routing */
2140 GLuint unit;
2141 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
2142 R200_STATECHANGE( rmesa, pix[unit] );
2143 R200_STATECHANGE( rmesa, tex[unit] );
2144 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2145 ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2146 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2147 /* need to guard this with drmSupportsFragmentShader? Should never get here if
2148 we don't announce ATI_fs, right? */
2149 rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2150 }
2151 R200_STATECHANGE( rmesa, cst );
2152 R200_STATECHANGE( rmesa, tf );
2153 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2154 }
2155 else {
2156 /* need to mark this dirty as pix/tf atoms have overwritten the data
2157 even if the data in the atoms didn't change */
2158 R200_STATECHANGE( rmesa, atf );
2159 R200_STATECHANGE( rmesa, afs[1] );
2160 /* everything else picked up in r200UpdateTextureState hopefully */
2161 }
2162 break;
2163 default:
2164 return;
2165 }
2166 }
2167
2168
2169 void r200LightingSpaceChange( struct gl_context *ctx )
2170 {
2171 r200ContextPtr rmesa = R200_CONTEXT(ctx);
2172 GLboolean tmp;
2173
2174 if (R200_DEBUG & RADEON_STATE)
2175 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2176 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2177
2178 if (ctx->_NeedEyeCoords)
2179 tmp = ctx->Transform.RescaleNormals;
2180 else
2181 tmp = !ctx->Transform.RescaleNormals;
2182
2183 R200_STATECHANGE( rmesa, tcl );
2184 if ( tmp ) {
2185 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_RESCALE_NORMALS;
2186 } else {
2187 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2188 }
2189
2190 if (R200_DEBUG & RADEON_STATE)
2191 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2192 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2193 }
2194
2195 /* =============================================================
2196 * Deferred state management - matrices, textures, other?
2197 */
2198
2199
2200
2201
2202 static void upload_matrix( r200ContextPtr rmesa, GLfloat *src, int idx )
2203 {
2204 float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2205 int i;
2206
2207
2208 for (i = 0 ; i < 4 ; i++) {
2209 *dest++ = src[i];
2210 *dest++ = src[i+4];
2211 *dest++ = src[i+8];
2212 *dest++ = src[i+12];
2213 }
2214
2215 R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2216 }
2217
2218 static void upload_matrix_t( r200ContextPtr rmesa, const GLfloat *src, int idx )
2219 {
2220 float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2221 memcpy(dest, src, 16*sizeof(float));
2222 R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2223 }
2224
2225
2226 static void update_texturematrix( struct gl_context *ctx )
2227 {
2228 r200ContextPtr rmesa = R200_CONTEXT( ctx );
2229 GLuint tpc = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0];
2230 GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL];
2231 int unit;
2232
2233 if (R200_DEBUG & RADEON_STATE)
2234 fprintf(stderr, "%s before COMPSEL: %x\n", __FUNCTION__,
2235 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]);
2236
2237 rmesa->TexMatEnabled = 0;
2238 rmesa->TexMatCompSel = 0;
2239
2240 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2241 if (!ctx->Texture.Unit[unit]._ReallyEnabled)
2242 continue;
2243
2244 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2245 rmesa->TexMatEnabled |= (R200_TEXGEN_TEXMAT_0_ENABLE|
2246 R200_TEXMAT_0_ENABLE) << unit;
2247
2248 rmesa->TexMatCompSel |= R200_OUTPUT_TEX_0 << unit;
2249
2250 if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2251 /* Need to preconcatenate any active texgen
2252 * obj/eyeplane matrices:
2253 */
2254 _math_matrix_mul_matrix( &rmesa->tmpmat,
2255 ctx->TextureMatrixStack[unit].Top,
2256 &rmesa->TexGenMatrix[unit] );
2257 upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit );
2258 }
2259 else {
2260 upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
2261 R200_MTX_TEX0+unit );
2262 }
2263 }
2264 else if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2265 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
2266 R200_MTX_TEX0+unit );
2267 }
2268 }
2269
2270 tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
2271 if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) {
2272 R200_STATECHANGE(rmesa, tcg);
2273 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc;
2274 }
2275
2276 compsel &= ~R200_OUTPUT_TEX_MASK;
2277 compsel |= rmesa->TexMatCompSel | rmesa->TexGenCompSel;
2278 if (compsel != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]) {
2279 R200_STATECHANGE(rmesa, vtx);
2280 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = compsel;
2281 }
2282 }
2283
2284 static GLboolean r200ValidateBuffers(struct gl_context *ctx)
2285 {
2286 r200ContextPtr rmesa = R200_CONTEXT(ctx);
2287 struct radeon_renderbuffer *rrb;
2288 struct radeon_dma_bo *dma_bo;
2289 int i, ret;
2290
2291 if (RADEON_DEBUG & RADEON_IOCTL)
2292 fprintf(stderr, "%s\n", __FUNCTION__);
2293 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2294
2295 rrb = radeon_get_colorbuffer(&rmesa->radeon);
2296 /* color buffer */
2297 if (rrb && rrb->bo) {
2298 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2299 0, RADEON_GEM_DOMAIN_VRAM);
2300 }
2301
2302 /* depth buffer */
2303 rrb = radeon_get_depthbuffer(&rmesa->radeon);
2304 /* color buffer */
2305 if (rrb && rrb->bo) {
2306 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2307 0, RADEON_GEM_DOMAIN_VRAM);
2308 }
2309
2310 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2311 radeonTexObj *t;
2312
2313 if (!ctx->Texture.Unit[i]._ReallyEnabled)
2314 continue;
2315
2316 t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
2317 if (t->image_override && t->bo)
2318 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2319 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2320 else if (t->mt->bo)
2321 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2322 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2323 }
2324
2325 dma_bo = first_elem(&rmesa->radeon.dma.reserved);
2326 {
2327 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
2328 if (ret)
2329 return GL_FALSE;
2330 }
2331 return GL_TRUE;
2332 }
2333
2334 GLboolean r200ValidateState( struct gl_context *ctx )
2335 {
2336 r200ContextPtr rmesa = R200_CONTEXT(ctx);
2337 GLuint new_state = rmesa->radeon.NewGLState;
2338
2339 if (new_state & _NEW_BUFFERS) {
2340 _mesa_update_framebuffer(ctx);
2341 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2342 _mesa_update_draw_buffer_bounds(ctx);
2343
2344 R200_STATECHANGE(rmesa, ctx);
2345 }
2346
2347 if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) {
2348 r200UpdateTextureState( ctx );
2349 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2350 r200UpdateLocalViewer( ctx );
2351 }
2352
2353 /* we need to do a space check here */
2354 if (!r200ValidateBuffers(ctx))
2355 return GL_FALSE;
2356
2357 /* FIXME: don't really need most of these when vertex progs are enabled */
2358
2359 /* Need an event driven matrix update?
2360 */
2361 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2362 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, R200_MTX_MVP );
2363
2364 /* Need these for lighting (shouldn't upload otherwise)
2365 */
2366 if (new_state & (_NEW_MODELVIEW)) {
2367 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, R200_MTX_MV );
2368 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, R200_MTX_IMV );
2369 }
2370
2371 /* Does this need to be triggered on eg. modelview for
2372 * texgen-derived objplane/eyeplane matrices?
2373 */
2374 if (new_state & (_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) {
2375 update_texturematrix( ctx );
2376 }
2377
2378 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2379 update_light( ctx );
2380 }
2381
2382 /* emit all active clip planes if projection matrix changes.
2383 */
2384 if (new_state & (_NEW_PROJECTION)) {
2385 if (ctx->Transform.ClipPlanesEnabled)
2386 r200UpdateClipPlanes( ctx );
2387 }
2388
2389 if (new_state & (_NEW_PROGRAM|
2390 _NEW_PROGRAM_CONSTANTS |
2391 /* need to test for pretty much anything due to possible parameter bindings */
2392 _NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
2393 _NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
2394 _NEW_FOG|_NEW_POINT|_NEW_TRACK_MATRIX)) {
2395 if (ctx->VertexProgram._Enabled) {
2396 r200SetupVertexProg( ctx );
2397 }
2398 else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0);
2399 }
2400
2401 rmesa->radeon.NewGLState = 0;
2402 return GL_TRUE;
2403 }
2404
2405
2406 static void r200InvalidateState( struct gl_context *ctx, GLuint new_state )
2407 {
2408 _swrast_InvalidateState( ctx, new_state );
2409 _swsetup_InvalidateState( ctx, new_state );
2410 _vbo_InvalidateState( ctx, new_state );
2411 _tnl_InvalidateState( ctx, new_state );
2412 _ae_invalidate_state( ctx, new_state );
2413 R200_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2414 }
2415
2416 /* A hack. The r200 can actually cope just fine with materials
2417 * between begin/ends, so fix this.
2418 * Should map to inputs just like the generic vertex arrays for vertex progs.
2419 * In theory there could still be too many and we'd still need a fallback.
2420 */
2421 static GLboolean check_material( struct gl_context *ctx )
2422 {
2423 TNLcontext *tnl = TNL_CONTEXT(ctx);
2424 GLint i;
2425
2426 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2427 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2428 i++)
2429 if (tnl->vb.AttribPtr[i] &&
2430 tnl->vb.AttribPtr[i]->stride)
2431 return GL_TRUE;
2432
2433 return GL_FALSE;
2434 }
2435
2436 static void r200WrapRunPipeline( struct gl_context *ctx )
2437 {
2438 r200ContextPtr rmesa = R200_CONTEXT(ctx);
2439 GLboolean has_material;
2440
2441 if (0)
2442 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2443
2444 /* Validate state:
2445 */
2446 if (rmesa->radeon.NewGLState)
2447 if (!r200ValidateState( ctx ))
2448 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2449
2450 has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx );
2451
2452 if (has_material) {
2453 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE );
2454 }
2455
2456 /* Run the pipeline.
2457 */
2458 _tnl_run_pipeline( ctx );
2459
2460 if (has_material) {
2461 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_FALSE );
2462 }
2463 }
2464
2465
2466 static void r200PolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2467 {
2468 r200ContextPtr r200 = R200_CONTEXT(ctx);
2469 GLint i;
2470
2471 radeon_firevertices(&r200->radeon);
2472
2473 radeon_print(RADEON_STATE, RADEON_TRACE,
2474 "%s(%p) first 32 bits are %x.\n",
2475 __func__,
2476 ctx,
2477 *(uint32_t*)mask);
2478
2479 R200_STATECHANGE(r200, stp);
2480
2481 /* Must flip pattern upside down.
2482 */
2483 for ( i = 31 ; i >= 0; i--) {
2484 r200->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2485 }
2486 }
2487 /* Initialize the driver's state functions.
2488 */
2489 void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions )
2490 {
2491 functions->UpdateState = r200InvalidateState;
2492 functions->LightingSpaceChange = r200LightingSpaceChange;
2493
2494 functions->DrawBuffer = radeonDrawBuffer;
2495 functions->ReadBuffer = radeonReadBuffer;
2496
2497 functions->CopyPixels = _mesa_meta_CopyPixels;
2498 functions->DrawPixels = _mesa_meta_DrawPixels;
2499 functions->ReadPixels = radeonReadPixels;
2500
2501 functions->AlphaFunc = r200AlphaFunc;
2502 functions->BlendColor = r200BlendColor;
2503 functions->BlendEquationSeparate = r200BlendEquationSeparate;
2504 functions->BlendFuncSeparate = r200BlendFuncSeparate;
2505 functions->ClearColor = r200ClearColor;
2506 functions->ClearDepth = r200ClearDepth;
2507 functions->ClearStencil = r200ClearStencil;
2508 functions->ClipPlane = r200ClipPlane;
2509 functions->ColorMask = r200ColorMask;
2510 functions->CullFace = r200CullFace;
2511 functions->DepthFunc = r200DepthFunc;
2512 functions->DepthMask = r200DepthMask;
2513 functions->DepthRange = r200DepthRange;
2514 functions->Enable = r200Enable;
2515 functions->Fogfv = r200Fogfv;
2516 functions->FrontFace = r200FrontFace;
2517 functions->Hint = NULL;
2518 functions->LightModelfv = r200LightModelfv;
2519 functions->Lightfv = r200Lightfv;
2520 functions->LineStipple = r200LineStipple;
2521 functions->LineWidth = r200LineWidth;
2522 functions->LogicOpcode = r200LogicOpCode;
2523 functions->PolygonMode = r200PolygonMode;
2524 functions->PolygonOffset = r200PolygonOffset;
2525 functions->PolygonStipple = r200PolygonStipple;
2526 functions->PointParameterfv = r200PointParameter;
2527 functions->PointSize = r200PointSize;
2528 functions->RenderMode = r200RenderMode;
2529 functions->Scissor = radeonScissor;
2530 functions->ShadeModel = r200ShadeModel;
2531 functions->StencilFuncSeparate = r200StencilFuncSeparate;
2532 functions->StencilMaskSeparate = r200StencilMaskSeparate;
2533 functions->StencilOpSeparate = r200StencilOpSeparate;
2534 functions->Viewport = r200Viewport;
2535 }
2536
2537
2538 void r200InitTnlFuncs( struct gl_context *ctx )
2539 {
2540 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = r200UpdateMaterial;
2541 TNL_CONTEXT(ctx)->Driver.RunPipeline = r200WrapRunPipeline;
2542 }