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