1 /**************************************************************************
2
3 Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice (including the
16 next paragraph) shall be included in all copies or substantial
17 portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
23 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/api_arrayelt.h"
38 #include "main/enums.h"
39 #include "main/light.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/fbobject.h"
43 #include "main/simple_list.h"
44 #include "main/state.h"
45
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_context.h"
53 #include "radeon_mipmap_tree.h"
54 #include "radeon_ioctl.h"
55 #include "radeon_state.h"
56 #include "radeon_tcl.h"
57 #include "radeon_tex.h"
58 #include "radeon_swtcl.h"
59
60 static void radeonUpdateSpecular( struct gl_context *ctx );
61
62 /* =============================================================
63 * Alpha blending
64 */
65
radeonAlphaFunc(struct gl_context * ctx,GLenum func,GLfloat ref)66 static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
67 {
68 r100ContextPtr rmesa = R100_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 RADEON_STATECHANGE( rmesa, ctx );
75
76 pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
77 pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
78
79 switch ( func ) {
80 case GL_NEVER:
81 pp_misc |= RADEON_ALPHA_TEST_FAIL;
82 break;
83 case GL_LESS:
84 pp_misc |= RADEON_ALPHA_TEST_LESS;
85 break;
86 case GL_EQUAL:
87 pp_misc |= RADEON_ALPHA_TEST_EQUAL;
88 break;
89 case GL_LEQUAL:
90 pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
91 break;
92 case GL_GREATER:
93 pp_misc |= RADEON_ALPHA_TEST_GREATER;
94 break;
95 case GL_NOTEQUAL:
96 pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
97 break;
98 case GL_GEQUAL:
99 pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
100 break;
101 case GL_ALWAYS:
102 pp_misc |= RADEON_ALPHA_TEST_PASS;
103 break;
104 }
105
106 rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
107 }
108
radeonBlendEquationSeparate(struct gl_context * ctx,GLenum modeRGB,GLenum modeA)109 static void radeonBlendEquationSeparate( struct gl_context *ctx,
110 GLenum modeRGB, GLenum modeA )
111 {
112 r100ContextPtr rmesa = R100_CONTEXT(ctx);
113 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
114 GLboolean fallback = GL_FALSE;
115
116 assert( modeRGB == modeA );
117
118 switch ( modeRGB ) {
119 case GL_FUNC_ADD:
120 case GL_LOGIC_OP:
121 b |= RADEON_COMB_FCN_ADD_CLAMP;
122 break;
123
124 case GL_FUNC_SUBTRACT:
125 b |= RADEON_COMB_FCN_SUB_CLAMP;
126 break;
127
128 default:
129 if (ctx->Color.BlendEnabled)
130 fallback = GL_TRUE;
131 else
132 b |= RADEON_COMB_FCN_ADD_CLAMP;
133 break;
134 }
135
136 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
137 if ( !fallback ) {
138 RADEON_STATECHANGE( rmesa, ctx );
139 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
140 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
141 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
142 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
143 } else {
144 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
145 }
146 }
147 }
148
radeonBlendFuncSeparate(struct gl_context * ctx,GLenum sfactorRGB,GLenum dfactorRGB,GLenum sfactorA,GLenum dfactorA)149 static void radeonBlendFuncSeparate( struct gl_context *ctx,
150 GLenum sfactorRGB, GLenum dfactorRGB,
151 GLenum sfactorA, GLenum dfactorA )
152 {
153 r100ContextPtr rmesa = R100_CONTEXT(ctx);
154 GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
155 ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
156 GLboolean fallback = GL_FALSE;
157
158 switch ( ctx->Color.Blend[0].SrcRGB ) {
159 case GL_ZERO:
160 b |= RADEON_SRC_BLEND_GL_ZERO;
161 break;
162 case GL_ONE:
163 b |= RADEON_SRC_BLEND_GL_ONE;
164 break;
165 case GL_DST_COLOR:
166 b |= RADEON_SRC_BLEND_GL_DST_COLOR;
167 break;
168 case GL_ONE_MINUS_DST_COLOR:
169 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
170 break;
171 case GL_SRC_COLOR:
172 b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
173 break;
174 case GL_ONE_MINUS_SRC_COLOR:
175 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
176 break;
177 case GL_SRC_ALPHA:
178 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
179 break;
180 case GL_ONE_MINUS_SRC_ALPHA:
181 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
182 break;
183 case GL_DST_ALPHA:
184 b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
185 break;
186 case GL_ONE_MINUS_DST_ALPHA:
187 b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
188 break;
189 case GL_SRC_ALPHA_SATURATE:
190 b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
191 break;
192 case GL_CONSTANT_COLOR:
193 case GL_ONE_MINUS_CONSTANT_COLOR:
194 case GL_CONSTANT_ALPHA:
195 case GL_ONE_MINUS_CONSTANT_ALPHA:
196 if (ctx->Color.BlendEnabled)
197 fallback = GL_TRUE;
198 else
199 b |= RADEON_SRC_BLEND_GL_ONE;
200 break;
201 default:
202 break;
203 }
204
205 switch ( ctx->Color.Blend[0].DstRGB ) {
206 case GL_ZERO:
207 b |= RADEON_DST_BLEND_GL_ZERO;
208 break;
209 case GL_ONE:
210 b |= RADEON_DST_BLEND_GL_ONE;
211 break;
212 case GL_SRC_COLOR:
213 b |= RADEON_DST_BLEND_GL_SRC_COLOR;
214 break;
215 case GL_ONE_MINUS_SRC_COLOR:
216 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
217 break;
218 case GL_SRC_ALPHA:
219 b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
220 break;
221 case GL_ONE_MINUS_SRC_ALPHA:
222 b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
223 break;
224 case GL_DST_COLOR:
225 b |= RADEON_DST_BLEND_GL_DST_COLOR;
226 break;
227 case GL_ONE_MINUS_DST_COLOR:
228 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
229 break;
230 case GL_DST_ALPHA:
231 b |= RADEON_DST_BLEND_GL_DST_ALPHA;
232 break;
233 case GL_ONE_MINUS_DST_ALPHA:
234 b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
235 break;
236 case GL_CONSTANT_COLOR:
237 case GL_ONE_MINUS_CONSTANT_COLOR:
238 case GL_CONSTANT_ALPHA:
239 case GL_ONE_MINUS_CONSTANT_ALPHA:
240 if (ctx->Color.BlendEnabled)
241 fallback = GL_TRUE;
242 else
243 b |= RADEON_DST_BLEND_GL_ZERO;
244 break;
245 default:
246 break;
247 }
248
249 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
250 if ( !fallback ) {
251 RADEON_STATECHANGE( rmesa, ctx );
252 rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
253 }
254 }
255
256
257 /* =============================================================
258 * Depth testing
259 */
260
radeonDepthFunc(struct gl_context * ctx,GLenum func)261 static void radeonDepthFunc( struct gl_context *ctx, GLenum func )
262 {
263 r100ContextPtr rmesa = R100_CONTEXT(ctx);
264
265 RADEON_STATECHANGE( rmesa, ctx );
266 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
267
268 switch ( ctx->Depth.Func ) {
269 case GL_NEVER:
270 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
271 break;
272 case GL_LESS:
273 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
274 break;
275 case GL_EQUAL:
276 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
277 break;
278 case GL_LEQUAL:
279 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
280 break;
281 case GL_GREATER:
282 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
283 break;
284 case GL_NOTEQUAL:
285 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
286 break;
287 case GL_GEQUAL:
288 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
289 break;
290 case GL_ALWAYS:
291 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
292 break;
293 }
294 }
295
296
radeonDepthMask(struct gl_context * ctx,GLboolean flag)297 static void radeonDepthMask( struct gl_context *ctx, GLboolean flag )
298 {
299 r100ContextPtr rmesa = R100_CONTEXT(ctx);
300 RADEON_STATECHANGE( rmesa, ctx );
301
302 if ( ctx->Depth.Mask ) {
303 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_WRITE_ENABLE;
304 } else {
305 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
306 }
307 }
308
309
310 /* =============================================================
311 * Fog
312 */
313
314
radeonFogfv(struct gl_context * ctx,GLenum pname,const GLfloat * param)315 static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
316 {
317 r100ContextPtr rmesa = R100_CONTEXT(ctx);
318 union { int i; float f; } c, d;
319 GLubyte col[4];
320
321 switch (pname) {
322 case GL_FOG_MODE:
323 if (!ctx->Fog.Enabled)
324 return;
325 RADEON_STATECHANGE(rmesa, tcl);
326 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
327 switch (ctx->Fog.Mode) {
328 case GL_LINEAR:
329 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
330 break;
331 case GL_EXP:
332 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
333 break;
334 case GL_EXP2:
335 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
336 break;
337 default:
338 return;
339 }
340 /* fallthrough */
341 case GL_FOG_DENSITY:
342 case GL_FOG_START:
343 case GL_FOG_END:
344 if (!ctx->Fog.Enabled)
345 return;
346 c.i = rmesa->hw.fog.cmd[FOG_C];
347 d.i = rmesa->hw.fog.cmd[FOG_D];
348 switch (ctx->Fog.Mode) {
349 case GL_EXP:
350 c.f = 0.0;
351 /* While this is the opposite sign from the DDK, it makes the fog test
352 * pass, and matches r200.
353 */
354 d.f = -ctx->Fog.Density;
355 break;
356 case GL_EXP2:
357 c.f = 0.0;
358 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
359 break;
360 case GL_LINEAR:
361 if (ctx->Fog.Start == ctx->Fog.End) {
362 c.f = 1.0F;
363 d.f = 1.0F;
364 } else {
365 c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
366 /* While this is the opposite sign from the DDK, it makes the fog
367 * test pass, and matches r200.
368 */
369 d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
370 }
371 break;
372 default:
373 break;
374 }
375 if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
376 RADEON_STATECHANGE( rmesa, fog );
377 rmesa->hw.fog.cmd[FOG_C] = c.i;
378 rmesa->hw.fog.cmd[FOG_D] = d.i;
379 }
380 break;
381 case GL_FOG_COLOR:
382 RADEON_STATECHANGE( rmesa, ctx );
383 _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color );
384 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
385 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
386 radeonPackColor( 4, col[0], col[1], col[2], 0 );
387 break;
388 case GL_FOG_COORD_SRC:
389 radeonUpdateSpecular( ctx );
390 break;
391 default:
392 return;
393 }
394 }
395
396 /* =============================================================
397 * Culling
398 */
399
radeonCullFace(struct gl_context * ctx,GLenum unused)400 static void radeonCullFace( struct gl_context *ctx, GLenum unused )
401 {
402 r100ContextPtr rmesa = R100_CONTEXT(ctx);
403 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
404 GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
405
406 s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
407 t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
408
409 if ( ctx->Polygon.CullFlag ) {
410 switch ( ctx->Polygon.CullFaceMode ) {
411 case GL_FRONT:
412 s &= ~RADEON_FFACE_SOLID;
413 t |= RADEON_CULL_FRONT;
414 break;
415 case GL_BACK:
416 s &= ~RADEON_BFACE_SOLID;
417 t |= RADEON_CULL_BACK;
418 break;
419 case GL_FRONT_AND_BACK:
420 s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
421 t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
422 break;
423 }
424 }
425
426 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
427 RADEON_STATECHANGE(rmesa, set );
428 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
429 }
430
431 if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
432 RADEON_STATECHANGE(rmesa, tcl );
433 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
434 }
435 }
436
radeonFrontFace(struct gl_context * ctx,GLenum mode)437 static void radeonFrontFace( struct gl_context *ctx, GLenum mode )
438 {
439 r100ContextPtr rmesa = R100_CONTEXT(ctx);
440 int cull_face = (mode == GL_CW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW;
441
442 RADEON_STATECHANGE( rmesa, set );
443 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
444
445 RADEON_STATECHANGE( rmesa, tcl );
446 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
447
448 /* Winding is inverted when rendering to FBO */
449 if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer))
450 cull_face = (mode == GL_CCW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW;
451 rmesa->hw.set.cmd[SET_SE_CNTL] |= cull_face;
452
453 if ( mode == GL_CCW )
454 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
455 }
456
457
458 /* =============================================================
459 * Line state
460 */
radeonLineWidth(struct gl_context * ctx,GLfloat widthf)461 static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf )
462 {
463 r100ContextPtr rmesa = R100_CONTEXT(ctx);
464
465 RADEON_STATECHANGE( rmesa, lin );
466 RADEON_STATECHANGE( rmesa, set );
467
468 /* Line width is stored in U6.4 format.
469 */
470 rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
471 if ( widthf > 1.0 ) {
472 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE;
473 } else {
474 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
475 }
476 }
477
radeonLineStipple(struct gl_context * ctx,GLint factor,GLushort pattern)478 static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
479 {
480 r100ContextPtr rmesa = R100_CONTEXT(ctx);
481
482 RADEON_STATECHANGE( rmesa, lin );
483 rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
484 ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
485 }
486
487
488 /* =============================================================
489 * Masks
490 */
radeonColorMask(struct gl_context * ctx,GLboolean r,GLboolean g,GLboolean b,GLboolean a)491 static void radeonColorMask( struct gl_context *ctx,
492 GLboolean r, GLboolean g,
493 GLboolean b, GLboolean a )
494 {
495 r100ContextPtr rmesa = R100_CONTEXT(ctx);
496 struct radeon_renderbuffer *rrb;
497 GLuint mask;
498
499 rrb = radeon_get_colorbuffer(&rmesa->radeon);
500 if (!rrb)
501 return;
502
503 mask = radeonPackColor( rrb->cpp,
504 ctx->Color.ColorMask[0][RCOMP],
505 ctx->Color.ColorMask[0][GCOMP],
506 ctx->Color.ColorMask[0][BCOMP],
507 ctx->Color.ColorMask[0][ACOMP] );
508
509 if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
510 RADEON_STATECHANGE( rmesa, msk );
511 rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
512 }
513 }
514
515
516 /* =============================================================
517 * Polygon state
518 */
519
radeonPolygonOffset(struct gl_context * ctx,GLfloat factor,GLfloat units)520 static void radeonPolygonOffset( struct gl_context *ctx,
521 GLfloat factor, GLfloat units )
522 {
523 r100ContextPtr rmesa = R100_CONTEXT(ctx);
524 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
525 float_ui32_type constant = { units * depthScale };
526 float_ui32_type factoru = { factor };
527
528 RADEON_STATECHANGE( rmesa, zbs );
529 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32;
530 rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
531 }
532
radeonPolygonMode(struct gl_context * ctx,GLenum face,GLenum mode)533 static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
534 {
535 r100ContextPtr rmesa = R100_CONTEXT(ctx);
536 GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
537
538 /* Can't generally do unfilled via tcl, but some good special
539 * cases work.
540 */
541 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
542 if (rmesa->radeon.TclFallback) {
543 radeonChooseRenderState( ctx );
544 radeonChooseVertexState( ctx );
545 }
546 }
547
548
549 /* =============================================================
550 * Rendering attributes
551 *
552 * We really don't want to recalculate all this every time we bind a
553 * texture. These things shouldn't change all that often, so it makes
554 * sense to break them out of the core texture state update routines.
555 */
556
557 /* Examine lighting and texture state to determine if separate specular
558 * should be enabled.
559 */
radeonUpdateSpecular(struct gl_context * ctx)560 static void radeonUpdateSpecular( struct gl_context *ctx )
561 {
562 r100ContextPtr rmesa = R100_CONTEXT(ctx);
563 uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
564 GLuint flag = 0;
565
566 RADEON_STATECHANGE( rmesa, tcl );
567
568 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
569 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
570 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
571 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
572 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
573
574 p &= ~RADEON_SPECULAR_ENABLE;
575
576 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
577
578
579 if (ctx->Light.Enabled &&
580 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
581 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
582 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
583 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
584 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
585 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
586 p |= RADEON_SPECULAR_ENABLE;
587 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
588 ~RADEON_DIFFUSE_SPECULAR_COMBINE;
589 }
590 else if (ctx->Light.Enabled) {
591 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
592 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
593 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
594 } else if (ctx->Fog.ColorSumEnabled ) {
595 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
596 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
597 p |= RADEON_SPECULAR_ENABLE;
598 } else {
599 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
600 }
601
602 if (ctx->Fog.Enabled) {
603 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
604 if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
605 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
606 /* Bizzare: have to leave lighting enabled to get fog. */
607 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
608 }
609 else {
610 /* cannot do tcl fog factor calculation with fog coord source
611 * (send precomputed factors). Cannot use precomputed fog
612 * factors together with tcl spec light (need tcl fallback) */
613 flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
614 RADEON_TCL_COMPUTE_SPECULAR) != 0;
615 }
616 }
617
618 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
619
620 if (_mesa_need_secondary_color(ctx)) {
621 assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
622 } else {
623 assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
624 }
625
626 if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
627 RADEON_STATECHANGE( rmesa, ctx );
628 rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
629 }
630
631 /* Update vertex/render formats
632 */
633 if (rmesa->radeon.TclFallback) {
634 radeonChooseRenderState( ctx );
635 radeonChooseVertexState( ctx );
636 }
637 }
638
639
640 /* =============================================================
641 * Materials
642 */
643
644
645 /* Update on colormaterial, material emmissive/ambient,
646 * lightmodel.globalambient
647 */
update_global_ambient(struct gl_context * ctx)648 static void update_global_ambient( struct gl_context *ctx )
649 {
650 r100ContextPtr rmesa = R100_CONTEXT(ctx);
651 float *fcmd = (float *)RADEON_DB_STATE( glt );
652
653 /* Need to do more if both emmissive & ambient are PREMULT:
654 * Hope this is not needed for MULT
655 */
656 if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
657 ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
658 (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
659 {
660 COPY_3V( &fcmd[GLT_RED],
661 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
662 ACC_SCALE_3V( &fcmd[GLT_RED],
663 ctx->Light.Model.Ambient,
664 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
665 }
666 else
667 {
668 COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
669 }
670
671 RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
672 }
673
674 /* Update on change to
675 * - light[p].colors
676 * - light[p].enabled
677 */
update_light_colors(struct gl_context * ctx,GLuint p)678 static void update_light_colors( struct gl_context *ctx, GLuint p )
679 {
680 struct gl_light *l = &ctx->Light.Light[p];
681
682 /* fprintf(stderr, "%s\n", __FUNCTION__); */
683
684 if (l->Enabled) {
685 r100ContextPtr rmesa = R100_CONTEXT(ctx);
686 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
687
688 COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
689 COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
690 COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
691
692 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
693 }
694 }
695
696 /* Also fallback for asym colormaterial mode in twoside lighting...
697 */
check_twoside_fallback(struct gl_context * ctx)698 static void check_twoside_fallback( struct gl_context *ctx )
699 {
700 GLboolean fallback = GL_FALSE;
701 GLint i;
702
703 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
704 if (ctx->Light.ColorMaterialEnabled &&
705 (ctx->Light._ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
706 ((ctx->Light._ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
707 fallback = GL_TRUE;
708 else {
709 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
710 if (memcmp( ctx->Light.Material.Attrib[i],
711 ctx->Light.Material.Attrib[i+1],
712 sizeof(GLfloat)*4) != 0) {
713 fallback = GL_TRUE;
714 break;
715 }
716 }
717 }
718
719 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
720 }
721
722
radeonColorMaterial(struct gl_context * ctx,GLenum face,GLenum mode)723 static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
724 {
725 r100ContextPtr rmesa = R100_CONTEXT(ctx);
726 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
727
728 light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
729 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
730 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
731 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
732
733 if (ctx->Light.ColorMaterialEnabled) {
734 GLuint mask = ctx->Light._ColorMaterialBitmask;
735
736 if (mask & MAT_BIT_FRONT_EMISSION) {
737 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
738 RADEON_EMISSIVE_SOURCE_SHIFT);
739 }
740 else {
741 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
742 RADEON_EMISSIVE_SOURCE_SHIFT);
743 }
744
745 if (mask & MAT_BIT_FRONT_AMBIENT) {
746 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
747 RADEON_AMBIENT_SOURCE_SHIFT);
748 }
749 else {
750 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
751 RADEON_AMBIENT_SOURCE_SHIFT);
752 }
753
754 if (mask & MAT_BIT_FRONT_DIFFUSE) {
755 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
756 RADEON_DIFFUSE_SOURCE_SHIFT);
757 }
758 else {
759 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
760 RADEON_DIFFUSE_SOURCE_SHIFT);
761 }
762
763 if (mask & MAT_BIT_FRONT_SPECULAR) {
764 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
765 RADEON_SPECULAR_SOURCE_SHIFT);
766 }
767 else {
768 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
769 RADEON_SPECULAR_SOURCE_SHIFT);
770 }
771 }
772 else {
773 /* Default to MULT:
774 */
775 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
776 (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
777 (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
778 (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
779 }
780
781 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
782 RADEON_STATECHANGE( rmesa, tcl );
783 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
784 }
785 }
786
radeonUpdateMaterial(struct gl_context * ctx)787 void radeonUpdateMaterial( struct gl_context *ctx )
788 {
789 r100ContextPtr rmesa = R100_CONTEXT(ctx);
790 GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
791 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
792 GLuint mask = ~0;
793
794 if (ctx->Light.ColorMaterialEnabled)
795 mask &= ~ctx->Light._ColorMaterialBitmask;
796
797 if (RADEON_DEBUG & RADEON_STATE)
798 fprintf(stderr, "%s\n", __FUNCTION__);
799
800
801 if (mask & MAT_BIT_FRONT_EMISSION) {
802 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
803 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
804 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
805 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
806 }
807 if (mask & MAT_BIT_FRONT_AMBIENT) {
808 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
809 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
810 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
811 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
812 }
813 if (mask & MAT_BIT_FRONT_DIFFUSE) {
814 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
815 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
816 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
817 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
818 }
819 if (mask & MAT_BIT_FRONT_SPECULAR) {
820 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
821 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
822 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
823 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
824 }
825 if (mask & MAT_BIT_FRONT_SHININESS) {
826 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
827 }
828
829 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
830
831 check_twoside_fallback( ctx );
832 /* update_global_ambient( ctx );*/
833 }
834
835 /* _NEW_LIGHT
836 * _NEW_MODELVIEW
837 * _MESA_NEW_NEED_EYE_COORDS
838 *
839 * Uses derived state from mesa:
840 * _VP_inf_norm
841 * _h_inf_norm
842 * _Position
843 * _NormSpotDirection
844 * _ModelViewInvScale
845 * _NeedEyeCoords
846 * _EyeZDir
847 *
848 * which are calculated in light.c and are correct for the current
849 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
850 * and _MESA_NEW_NEED_EYE_COORDS.
851 */
update_light(struct gl_context * ctx)852 static void update_light( struct gl_context *ctx )
853 {
854 r100ContextPtr rmesa = R100_CONTEXT(ctx);
855
856 /* Have to check these, or have an automatic shortcircuit mechanism
857 * to remove noop statechanges. (Or just do a better job on the
858 * front end).
859 */
860 {
861 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
862
863 if (ctx->_NeedEyeCoords)
864 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
865 else
866 tmp |= RADEON_LIGHT_IN_MODELSPACE;
867
868
869 /* Leave this test disabled: (unexplained q3 lockup) (even with
870 new packets)
871 */
872 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
873 {
874 RADEON_STATECHANGE( rmesa, tcl );
875 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
876 }
877 }
878
879 {
880 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
881 fcmd[EYE_X] = ctx->_EyeZDir[0];
882 fcmd[EYE_Y] = ctx->_EyeZDir[1];
883 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
884 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
885 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
886 }
887
888
889
890 if (ctx->Light.Enabled) {
891 GLint p;
892 for (p = 0 ; p < MAX_LIGHTS; p++) {
893 if (ctx->Light.Light[p].Enabled) {
894 struct gl_light *l = &ctx->Light.Light[p];
895 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
896
897 if (l->EyePosition[3] == 0.0) {
898 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
899 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
900 fcmd[LIT_POSITION_W] = 0;
901 fcmd[LIT_DIRECTION_W] = 0;
902 } else {
903 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
904 fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
905 fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
906 fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
907 fcmd[LIT_DIRECTION_W] = 0;
908 }
909
910 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
911 }
912 }
913 }
914 }
915
radeonLightfv(struct gl_context * ctx,GLenum light,GLenum pname,const GLfloat * params)916 static void radeonLightfv( struct gl_context *ctx, GLenum light,
917 GLenum pname, const GLfloat *params )
918 {
919 r100ContextPtr rmesa = R100_CONTEXT(ctx);
920 GLint p = light - GL_LIGHT0;
921 struct gl_light *l = &ctx->Light.Light[p];
922 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
923
924
925 switch (pname) {
926 case GL_AMBIENT:
927 case GL_DIFFUSE:
928 case GL_SPECULAR:
929 update_light_colors( ctx, p );
930 break;
931
932 case GL_SPOT_DIRECTION:
933 /* picked up in update_light */
934 break;
935
936 case GL_POSITION: {
937 /* positions picked up in update_light, but can do flag here */
938 GLuint flag;
939 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
940
941 /* FIXME: Set RANGE_ATTEN only when needed */
942 if (p&1)
943 flag = RADEON_LIGHT_1_IS_LOCAL;
944 else
945 flag = RADEON_LIGHT_0_IS_LOCAL;
946
947 RADEON_STATECHANGE(rmesa, tcl);
948 if (l->EyePosition[3] != 0.0F)
949 rmesa->hw.tcl.cmd[idx] |= flag;
950 else
951 rmesa->hw.tcl.cmd[idx] &= ~flag;
952 break;
953 }
954
955 case GL_SPOT_EXPONENT:
956 RADEON_STATECHANGE(rmesa, lit[p]);
957 fcmd[LIT_SPOT_EXPONENT] = params[0];
958 break;
959
960 case GL_SPOT_CUTOFF: {
961 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
962 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
963
964 RADEON_STATECHANGE(rmesa, lit[p]);
965 fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
966
967 RADEON_STATECHANGE(rmesa, tcl);
968 if (l->SpotCutoff != 180.0F)
969 rmesa->hw.tcl.cmd[idx] |= flag;
970 else
971 rmesa->hw.tcl.cmd[idx] &= ~flag;
972
973 break;
974 }
975
976 case GL_CONSTANT_ATTENUATION:
977 RADEON_STATECHANGE(rmesa, lit[p]);
978 fcmd[LIT_ATTEN_CONST] = params[0];
979 if ( params[0] == 0.0 )
980 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
981 else
982 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
983 break;
984 case GL_LINEAR_ATTENUATION:
985 RADEON_STATECHANGE(rmesa, lit[p]);
986 fcmd[LIT_ATTEN_LINEAR] = params[0];
987 break;
988 case GL_QUADRATIC_ATTENUATION:
989 RADEON_STATECHANGE(rmesa, lit[p]);
990 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
991 break;
992 default:
993 return;
994 }
995
996 /* Set RANGE_ATTEN only when needed */
997 switch (pname) {
998 case GL_POSITION:
999 case GL_CONSTANT_ATTENUATION:
1000 case GL_LINEAR_ATTENUATION:
1001 case GL_QUADRATIC_ATTENUATION:
1002 {
1003 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1004 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1005 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1006 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1007 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1008 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1009
1010 if ( l->EyePosition[3] == 0.0F ||
1011 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1012 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1013 /* Disable attenuation */
1014 icmd[idx] &= ~atten_flag;
1015 } else {
1016 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1017 /* Enable only constant portion of attenuation calculation */
1018 icmd[idx] |= ( atten_flag | atten_const_flag );
1019 } else {
1020 /* Enable full attenuation calculation */
1021 icmd[idx] &= ~atten_const_flag;
1022 icmd[idx] |= atten_flag;
1023 }
1024 }
1025
1026 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1027 break;
1028 }
1029 default:
1030 break;
1031 }
1032 }
1033
1034
1035
1036
radeonLightModelfv(struct gl_context * ctx,GLenum pname,const GLfloat * param)1037 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1038 const GLfloat *param )
1039 {
1040 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1041
1042 switch (pname) {
1043 case GL_LIGHT_MODEL_AMBIENT:
1044 update_global_ambient( ctx );
1045 break;
1046
1047 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1048 RADEON_STATECHANGE( rmesa, tcl );
1049 if (ctx->Light.Model.LocalViewer)
1050 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1051 else
1052 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1053 break;
1054
1055 case GL_LIGHT_MODEL_TWO_SIDE:
1056 RADEON_STATECHANGE( rmesa, tcl );
1057 if (ctx->Light.Model.TwoSide)
1058 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1059 else
1060 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1061
1062 check_twoside_fallback( ctx );
1063
1064 if (rmesa->radeon.TclFallback) {
1065 radeonChooseRenderState( ctx );
1066 radeonChooseVertexState( ctx );
1067 }
1068 break;
1069
1070 case GL_LIGHT_MODEL_COLOR_CONTROL:
1071 radeonUpdateSpecular(ctx);
1072 break;
1073
1074 default:
1075 break;
1076 }
1077 }
1078
radeonShadeModel(struct gl_context * ctx,GLenum mode)1079 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1080 {
1081 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1082 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1083
1084 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1085 RADEON_ALPHA_SHADE_MASK |
1086 RADEON_SPECULAR_SHADE_MASK |
1087 RADEON_FOG_SHADE_MASK);
1088
1089 switch ( mode ) {
1090 case GL_FLAT:
1091 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1092 RADEON_ALPHA_SHADE_FLAT |
1093 RADEON_SPECULAR_SHADE_FLAT |
1094 RADEON_FOG_SHADE_FLAT);
1095 break;
1096 case GL_SMOOTH:
1097 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1098 RADEON_ALPHA_SHADE_GOURAUD |
1099 RADEON_SPECULAR_SHADE_GOURAUD |
1100 RADEON_FOG_SHADE_GOURAUD);
1101 break;
1102 default:
1103 return;
1104 }
1105
1106 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1107 RADEON_STATECHANGE( rmesa, set );
1108 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1109 }
1110 }
1111
1112
1113 /* =============================================================
1114 * User clip planes
1115 */
1116
radeonClipPlane(struct gl_context * ctx,GLenum plane,const GLfloat * eq)1117 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1118 {
1119 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1120 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1121 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1122
1123 RADEON_STATECHANGE( rmesa, ucp[p] );
1124 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1125 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1126 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1127 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1128 }
1129
radeonUpdateClipPlanes(struct gl_context * ctx)1130 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1131 {
1132 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1133 GLuint p;
1134
1135 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1136 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1137 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1138
1139 RADEON_STATECHANGE( rmesa, ucp[p] );
1140 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1141 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1142 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1143 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1144 }
1145 }
1146 }
1147
1148
1149 /* =============================================================
1150 * Stencil
1151 */
1152
1153 static void
radeonStencilFuncSeparate(struct gl_context * ctx,GLenum face,GLenum func,GLint ref,GLuint mask)1154 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1155 GLint ref, GLuint mask )
1156 {
1157 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1158 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
1159 ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1160
1161 RADEON_STATECHANGE( rmesa, ctx );
1162 RADEON_STATECHANGE( rmesa, msk );
1163
1164 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1165 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1166 RADEON_STENCIL_VALUE_MASK);
1167
1168 switch ( ctx->Stencil.Function[0] ) {
1169 case GL_NEVER:
1170 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1171 break;
1172 case GL_LESS:
1173 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1174 break;
1175 case GL_EQUAL:
1176 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1177 break;
1178 case GL_LEQUAL:
1179 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1180 break;
1181 case GL_GREATER:
1182 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1183 break;
1184 case GL_NOTEQUAL:
1185 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1186 break;
1187 case GL_GEQUAL:
1188 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1189 break;
1190 case GL_ALWAYS:
1191 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1192 break;
1193 }
1194
1195 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1196 }
1197
1198 static void
radeonStencilMaskSeparate(struct gl_context * ctx,GLenum face,GLuint mask)1199 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1200 {
1201 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1202
1203 RADEON_STATECHANGE( rmesa, msk );
1204 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1205 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1206 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1207 }
1208
radeonStencilOpSeparate(struct gl_context * ctx,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)1209 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1210 GLenum zfail, GLenum zpass )
1211 {
1212 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1213
1214 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1215 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1216 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1217
1218 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1219 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1220 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1221 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1222 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1223 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1224
1225 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1226 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1227 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1228 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1229 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1230 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1231 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1232 }
1233 else {
1234 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1235 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1236 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1237 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1238 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1239 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1240 }
1241
1242 RADEON_STATECHANGE( rmesa, ctx );
1243 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1244 RADEON_STENCIL_ZFAIL_MASK |
1245 RADEON_STENCIL_ZPASS_MASK);
1246
1247 switch ( ctx->Stencil.FailFunc[0] ) {
1248 case GL_KEEP:
1249 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1250 break;
1251 case GL_ZERO:
1252 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1253 break;
1254 case GL_REPLACE:
1255 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1256 break;
1257 case GL_INCR:
1258 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1259 break;
1260 case GL_DECR:
1261 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1262 break;
1263 case GL_INCR_WRAP:
1264 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1265 break;
1266 case GL_DECR_WRAP:
1267 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1268 break;
1269 case GL_INVERT:
1270 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1271 break;
1272 }
1273
1274 switch ( ctx->Stencil.ZFailFunc[0] ) {
1275 case GL_KEEP:
1276 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1277 break;
1278 case GL_ZERO:
1279 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1280 break;
1281 case GL_REPLACE:
1282 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1283 break;
1284 case GL_INCR:
1285 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1286 break;
1287 case GL_DECR:
1288 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1289 break;
1290 case GL_INCR_WRAP:
1291 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1292 break;
1293 case GL_DECR_WRAP:
1294 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1295 break;
1296 case GL_INVERT:
1297 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1298 break;
1299 }
1300
1301 switch ( ctx->Stencil.ZPassFunc[0] ) {
1302 case GL_KEEP:
1303 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1304 break;
1305 case GL_ZERO:
1306 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1307 break;
1308 case GL_REPLACE:
1309 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1310 break;
1311 case GL_INCR:
1312 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1313 break;
1314 case GL_DECR:
1315 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1316 break;
1317 case GL_INCR_WRAP:
1318 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1319 break;
1320 case GL_DECR_WRAP:
1321 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1322 break;
1323 case GL_INVERT:
1324 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1325 break;
1326 }
1327 }
1328
1329
1330
1331 /* =============================================================
1332 * Window position and viewport transformation
1333 */
1334
1335 /*
1336 * To correctly position primitives:
1337 */
1338 #define SUBPIXEL_X 0.125
1339 #define SUBPIXEL_Y 0.125
1340
1341
1342 /**
1343 * Called when window size or position changes or viewport or depth range
1344 * state is changed. We update the hardware viewport state here.
1345 */
radeonUpdateWindow(struct gl_context * ctx)1346 void radeonUpdateWindow( struct gl_context *ctx )
1347 {
1348 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1349 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1350 GLfloat xoffset = 0.0;
1351 GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
1352 const GLfloat *v = ctx->Viewport._WindowMap.m;
1353 const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
1354 const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1355 GLfloat y_scale, y_bias;
1356
1357 if (render_to_fbo) {
1358 y_scale = 1.0;
1359 y_bias = 0;
1360 } else {
1361 y_scale = -1.0;
1362 y_bias = yoffset;
1363 }
1364
1365 float_ui32_type sx = { v[MAT_SX] };
1366 float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1367 float_ui32_type sy = { v[MAT_SY] * y_scale };
1368 float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1369 float_ui32_type sz = { v[MAT_SZ] * depthScale };
1370 float_ui32_type tz = { v[MAT_TZ] * depthScale };
1371
1372 RADEON_STATECHANGE( rmesa, vpt );
1373
1374 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1375 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1376 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1377 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1378 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1379 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1380 }
1381
1382
radeonViewport(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height)1383 static void radeonViewport( struct gl_context *ctx, GLint x, GLint y,
1384 GLsizei width, GLsizei height )
1385 {
1386 /* Don't pipeline viewport changes, conflict with window offset
1387 * setting below. Could apply deltas to rescue pipelined viewport
1388 * values, or keep the originals hanging around.
1389 */
1390 radeonUpdateWindow( ctx );
1391
1392 radeon_viewport(ctx, x, y, width, height);
1393 }
1394
radeonDepthRange(struct gl_context * ctx,GLclampd nearval,GLclampd farval)1395 static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval,
1396 GLclampd farval )
1397 {
1398 radeonUpdateWindow( ctx );
1399 }
1400
radeonUpdateViewportOffset(struct gl_context * ctx)1401 void radeonUpdateViewportOffset( struct gl_context *ctx )
1402 {
1403 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1404 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1405 GLfloat xoffset = 0.0;
1406 GLfloat yoffset = (GLfloat)dPriv->h;
1407 const GLfloat *v = ctx->Viewport._WindowMap.m;
1408
1409 float_ui32_type tx;
1410 float_ui32_type ty;
1411
1412 tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1413 ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1414
1415 if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1416 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1417 {
1418 /* Note: this should also modify whatever data the context reset
1419 * code uses...
1420 */
1421 RADEON_STATECHANGE( rmesa, vpt );
1422 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1423 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1424
1425 /* update polygon stipple x/y screen offset */
1426 {
1427 GLuint stx, sty;
1428 GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1429
1430 m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
1431 RADEON_STIPPLE_Y_OFFSET_MASK);
1432
1433 /* add magic offsets, then invert */
1434 stx = 31 - ((-1) & RADEON_STIPPLE_COORD_MASK);
1435 sty = 31 - ((dPriv->h - 1)
1436 & RADEON_STIPPLE_COORD_MASK);
1437
1438 m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
1439 (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
1440
1441 if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1442 RADEON_STATECHANGE( rmesa, msc );
1443 rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1444 }
1445 }
1446 }
1447
1448 radeonUpdateScissor( ctx );
1449 }
1450
1451
1452
1453 /* =============================================================
1454 * Miscellaneous
1455 */
1456
radeonRenderMode(struct gl_context * ctx,GLenum mode)1457 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1458 {
1459 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1460 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1461 }
1462
1463
1464 static GLuint radeon_rop_tab[] = {
1465 RADEON_ROP_CLEAR,
1466 RADEON_ROP_AND,
1467 RADEON_ROP_AND_REVERSE,
1468 RADEON_ROP_COPY,
1469 RADEON_ROP_AND_INVERTED,
1470 RADEON_ROP_NOOP,
1471 RADEON_ROP_XOR,
1472 RADEON_ROP_OR,
1473 RADEON_ROP_NOR,
1474 RADEON_ROP_EQUIV,
1475 RADEON_ROP_INVERT,
1476 RADEON_ROP_OR_REVERSE,
1477 RADEON_ROP_COPY_INVERTED,
1478 RADEON_ROP_OR_INVERTED,
1479 RADEON_ROP_NAND,
1480 RADEON_ROP_SET,
1481 };
1482
radeonLogicOpCode(struct gl_context * ctx,GLenum opcode)1483 static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
1484 {
1485 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1486 GLuint rop = (GLuint)opcode - GL_CLEAR;
1487
1488 ASSERT( rop < 16 );
1489
1490 RADEON_STATECHANGE( rmesa, msk );
1491 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
1492 }
1493
1494 /* =============================================================
1495 * State enable/disable
1496 */
1497
radeonEnable(struct gl_context * ctx,GLenum cap,GLboolean state)1498 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1499 {
1500 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1501 GLuint p, flag;
1502
1503 if ( RADEON_DEBUG & RADEON_STATE )
1504 fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1505 _mesa_lookup_enum_by_nr( cap ),
1506 state ? "GL_TRUE" : "GL_FALSE" );
1507
1508 switch ( cap ) {
1509 /* Fast track this one...
1510 */
1511 case GL_TEXTURE_1D:
1512 case GL_TEXTURE_2D:
1513 case GL_TEXTURE_3D:
1514 break;
1515
1516 case GL_ALPHA_TEST:
1517 RADEON_STATECHANGE( rmesa, ctx );
1518 if (state) {
1519 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1520 } else {
1521 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1522 }
1523 break;
1524
1525 case GL_BLEND:
1526 RADEON_STATECHANGE( rmesa, ctx );
1527 if (state) {
1528 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1529 } else {
1530 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1531 }
1532 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1533 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1534 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1535 } else {
1536 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1537 }
1538
1539 /* Catch a possible fallback:
1540 */
1541 if (state) {
1542 ctx->Driver.BlendEquationSeparate( ctx,
1543 ctx->Color.Blend[0].EquationRGB,
1544 ctx->Color.Blend[0].EquationA );
1545 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1546 ctx->Color.Blend[0].DstRGB,
1547 ctx->Color.Blend[0].SrcA,
1548 ctx->Color.Blend[0].DstA );
1549 }
1550 else {
1551 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1552 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1553 }
1554 break;
1555
1556 case GL_CLIP_PLANE0:
1557 case GL_CLIP_PLANE1:
1558 case GL_CLIP_PLANE2:
1559 case GL_CLIP_PLANE3:
1560 case GL_CLIP_PLANE4:
1561 case GL_CLIP_PLANE5:
1562 p = cap-GL_CLIP_PLANE0;
1563 RADEON_STATECHANGE( rmesa, tcl );
1564 if (state) {
1565 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1566 radeonClipPlane( ctx, cap, NULL );
1567 }
1568 else {
1569 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1570 }
1571 break;
1572
1573 case GL_COLOR_MATERIAL:
1574 radeonColorMaterial( ctx, 0, 0 );
1575 radeonUpdateMaterial( ctx );
1576 break;
1577
1578 case GL_CULL_FACE:
1579 radeonCullFace( ctx, 0 );
1580 break;
1581
1582 case GL_DEPTH_TEST:
1583 RADEON_STATECHANGE(rmesa, ctx );
1584 if ( state ) {
1585 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1586 } else {
1587 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1588 }
1589 break;
1590
1591 case GL_DITHER:
1592 RADEON_STATECHANGE(rmesa, ctx );
1593 if ( state ) {
1594 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1595 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1596 } else {
1597 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1598 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1599 }
1600 break;
1601
1602 case GL_FOG:
1603 RADEON_STATECHANGE(rmesa, ctx );
1604 if ( state ) {
1605 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1606 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1607 } else {
1608 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1609 RADEON_STATECHANGE(rmesa, tcl);
1610 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1611 }
1612 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1613 _mesa_allow_light_in_model( ctx, !state );
1614 break;
1615
1616 case GL_LIGHT0:
1617 case GL_LIGHT1:
1618 case GL_LIGHT2:
1619 case GL_LIGHT3:
1620 case GL_LIGHT4:
1621 case GL_LIGHT5:
1622 case GL_LIGHT6:
1623 case GL_LIGHT7:
1624 RADEON_STATECHANGE(rmesa, tcl);
1625 p = cap - GL_LIGHT0;
1626 if (p&1)
1627 flag = (RADEON_LIGHT_1_ENABLE |
1628 RADEON_LIGHT_1_ENABLE_AMBIENT |
1629 RADEON_LIGHT_1_ENABLE_SPECULAR);
1630 else
1631 flag = (RADEON_LIGHT_0_ENABLE |
1632 RADEON_LIGHT_0_ENABLE_AMBIENT |
1633 RADEON_LIGHT_0_ENABLE_SPECULAR);
1634
1635 if (state)
1636 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1637 else
1638 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1639
1640 /*
1641 */
1642 update_light_colors( ctx, p );
1643 break;
1644
1645 case GL_LIGHTING:
1646 RADEON_STATECHANGE(rmesa, tcl);
1647 radeonUpdateSpecular(ctx);
1648 check_twoside_fallback( ctx );
1649 break;
1650
1651 case GL_LINE_SMOOTH:
1652 RADEON_STATECHANGE( rmesa, ctx );
1653 if ( state ) {
1654 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1655 } else {
1656 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1657 }
1658 break;
1659
1660 case GL_LINE_STIPPLE:
1661 RADEON_STATECHANGE( rmesa, ctx );
1662 if ( state ) {
1663 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1664 } else {
1665 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1666 }
1667 break;
1668
1669 case GL_COLOR_LOGIC_OP:
1670 RADEON_STATECHANGE( rmesa, ctx );
1671 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1672 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1673 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1674 } else {
1675 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1676 }
1677 break;
1678
1679 case GL_NORMALIZE:
1680 RADEON_STATECHANGE( rmesa, tcl );
1681 if ( state ) {
1682 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1683 } else {
1684 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1685 }
1686 break;
1687
1688 case GL_POLYGON_OFFSET_POINT:
1689 RADEON_STATECHANGE( rmesa, set );
1690 if ( state ) {
1691 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1692 } else {
1693 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1694 }
1695 break;
1696
1697 case GL_POLYGON_OFFSET_LINE:
1698 RADEON_STATECHANGE( rmesa, set );
1699 if ( state ) {
1700 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1701 } else {
1702 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1703 }
1704 break;
1705
1706 case GL_POLYGON_OFFSET_FILL:
1707 RADEON_STATECHANGE( rmesa, set );
1708 if ( state ) {
1709 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1710 } else {
1711 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1712 }
1713 break;
1714
1715 case GL_POLYGON_SMOOTH:
1716 RADEON_STATECHANGE( rmesa, ctx );
1717 if ( state ) {
1718 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1719 } else {
1720 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1721 }
1722 break;
1723
1724 case GL_POLYGON_STIPPLE:
1725 RADEON_STATECHANGE(rmesa, ctx );
1726 if ( state ) {
1727 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1728 } else {
1729 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1730 }
1731 break;
1732
1733 case GL_RESCALE_NORMAL_EXT: {
1734 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1735 RADEON_STATECHANGE( rmesa, tcl );
1736 if ( tmp ) {
1737 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1738 } else {
1739 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1740 }
1741 break;
1742 }
1743
1744 case GL_SCISSOR_TEST:
1745 radeon_firevertices(&rmesa->radeon);
1746 rmesa->radeon.state.scissor.enabled = state;
1747 radeonUpdateScissor( ctx );
1748 break;
1749
1750 case GL_STENCIL_TEST:
1751 {
1752 GLboolean hw_stencil = GL_FALSE;
1753 if (ctx->DrawBuffer) {
1754 struct radeon_renderbuffer *rrbStencil
1755 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1756 hw_stencil = (rrbStencil && rrbStencil->bo);
1757 }
1758
1759 if (hw_stencil) {
1760 RADEON_STATECHANGE( rmesa, ctx );
1761 if ( state ) {
1762 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1763 } else {
1764 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1765 }
1766 } else {
1767 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1768 }
1769 }
1770 break;
1771
1772 case GL_TEXTURE_GEN_Q:
1773 case GL_TEXTURE_GEN_R:
1774 case GL_TEXTURE_GEN_S:
1775 case GL_TEXTURE_GEN_T:
1776 /* Picked up in radeonUpdateTextureState.
1777 */
1778 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1779 break;
1780
1781 case GL_COLOR_SUM_EXT:
1782 radeonUpdateSpecular ( ctx );
1783 break;
1784
1785 default:
1786 return;
1787 }
1788 }
1789
1790
radeonLightingSpaceChange(struct gl_context * ctx)1791 static void radeonLightingSpaceChange( struct gl_context *ctx )
1792 {
1793 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1794 GLboolean tmp;
1795 RADEON_STATECHANGE( rmesa, tcl );
1796
1797 if (RADEON_DEBUG & RADEON_STATE)
1798 fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1799 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1800
1801 if (ctx->_NeedEyeCoords)
1802 tmp = ctx->Transform.RescaleNormals;
1803 else
1804 tmp = !ctx->Transform.RescaleNormals;
1805
1806 if ( tmp ) {
1807 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1808 } else {
1809 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1810 }
1811
1812 if (RADEON_DEBUG & RADEON_STATE)
1813 fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
1814 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1815 }
1816
1817 /* =============================================================
1818 * Deferred state management - matrices, textures, other?
1819 */
1820
1821
radeonUploadTexMatrix(r100ContextPtr rmesa,int unit,GLboolean swapcols)1822 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1823 int unit, GLboolean swapcols )
1824 {
1825 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1826 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1827 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1828 texgen generates all 4 coords, at least tests with projtex indicated that.
1829 So: if we need the q coord in the end (solely determined by the texture
1830 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1831 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1832 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1833 will get submitted in the "wrong", i.e. 3rd, slot.
1834 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1835 size and using the texture matrix to swap the r and q coords around (ut2k3
1836 does exactly that), so we don't need the 3rd / 4th column swap - still need
1837 the 3rd / 4th row swap of course. This will potentially break for apps which
1838 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1839 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1840 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1841 incredibly hard to detect so we can't just fallback in such a case. Assume
1842 it never happens... - rs
1843 */
1844
1845 int idx = TEXMAT_0 + unit;
1846 float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1847 int i;
1848 struct gl_texture_unit tUnit = rmesa->radeon.glCtx->Texture.Unit[unit];
1849 GLfloat *src = rmesa->tmpmat[unit].m;
1850
1851 rmesa->TexMatColSwap &= ~(1 << unit);
1852 if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
1853 if (swapcols) {
1854 rmesa->TexMatColSwap |= 1 << unit;
1855 /* attention some elems are swapped 2 times! */
1856 *dest++ = src[0];
1857 *dest++ = src[4];
1858 *dest++ = src[12];
1859 *dest++ = src[8];
1860 *dest++ = src[1];
1861 *dest++ = src[5];
1862 *dest++ = src[13];
1863 *dest++ = src[9];
1864 *dest++ = src[2];
1865 *dest++ = src[6];
1866 *dest++ = src[15];
1867 *dest++ = src[11];
1868 /* those last 4 are probably never used */
1869 *dest++ = src[3];
1870 *dest++ = src[7];
1871 *dest++ = src[14];
1872 *dest++ = src[10];
1873 }
1874 else {
1875 for (i = 0; i < 2; i++) {
1876 *dest++ = src[i];
1877 *dest++ = src[i+4];
1878 *dest++ = src[i+8];
1879 *dest++ = src[i+12];
1880 }
1881 for (i = 3; i >= 2; i--) {
1882 *dest++ = src[i];
1883 *dest++ = src[i+4];
1884 *dest++ = src[i+8];
1885 *dest++ = src[i+12];
1886 }
1887 }
1888 }
1889 else {
1890 for (i = 0 ; i < 4 ; i++) {
1891 *dest++ = src[i];
1892 *dest++ = src[i+4];
1893 *dest++ = src[i+8];
1894 *dest++ = src[i+12];
1895 }
1896 }
1897
1898 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1899 }
1900
1901
upload_matrix(r100ContextPtr rmesa,GLfloat * src,int idx)1902 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1903 {
1904 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1905 int i;
1906
1907
1908 for (i = 0 ; i < 4 ; i++) {
1909 *dest++ = src[i];
1910 *dest++ = src[i+4];
1911 *dest++ = src[i+8];
1912 *dest++ = src[i+12];
1913 }
1914
1915 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1916 }
1917
upload_matrix_t(r100ContextPtr rmesa,GLfloat * src,int idx)1918 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1919 {
1920 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1921 memcpy(dest, src, 16*sizeof(float));
1922 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1923 }
1924
1925
update_texturematrix(struct gl_context * ctx)1926 static void update_texturematrix( struct gl_context *ctx )
1927 {
1928 r100ContextPtr rmesa = R100_CONTEXT( ctx );
1929 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
1930 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
1931 int unit;
1932 GLuint texMatEnabled = 0;
1933 rmesa->NeedTexMatrix = 0;
1934 rmesa->TexMatColSwap = 0;
1935
1936 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
1937 if (ctx->Texture.Unit[unit]._ReallyEnabled) {
1938 GLboolean needMatrix = GL_FALSE;
1939 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
1940 needMatrix = GL_TRUE;
1941 texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
1942 RADEON_TEXMAT_0_ENABLE) << unit;
1943
1944 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1945 /* Need to preconcatenate any active texgen
1946 * obj/eyeplane matrices:
1947 */
1948 _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
1949 ctx->TextureMatrixStack[unit].Top,
1950 &rmesa->TexGenMatrix[unit] );
1951 }
1952 else {
1953 _math_matrix_copy( &rmesa->tmpmat[unit],
1954 ctx->TextureMatrixStack[unit].Top );
1955 }
1956 }
1957 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1958 _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
1959 needMatrix = GL_TRUE;
1960 }
1961 if (needMatrix) {
1962 rmesa->NeedTexMatrix |= 1 << unit;
1963 radeonUploadTexMatrix( rmesa, unit,
1964 !ctx->Texture.Unit[unit].TexGenEnabled );
1965 }
1966 }
1967 }
1968
1969 tpc = (texMatEnabled | rmesa->TexGenEnabled);
1970
1971 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1972 vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
1973 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
1974 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
1975
1976 vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
1977 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
1978 ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
1979 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
1980 ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
1981 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
1982
1983 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
1984 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
1985
1986 RADEON_STATECHANGE(rmesa, tcl);
1987 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
1988 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
1989 }
1990 }
1991
r100ValidateBuffers(struct gl_context * ctx)1992 static GLboolean r100ValidateBuffers(struct gl_context *ctx)
1993 {
1994 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1995 struct radeon_renderbuffer *rrb;
1996 int i, ret;
1997
1998 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
1999
2000 rrb = radeon_get_colorbuffer(&rmesa->radeon);
2001 /* color buffer */
2002 if (rrb && rrb->bo) {
2003 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2004 0, RADEON_GEM_DOMAIN_VRAM);
2005 }
2006
2007 /* depth buffer */
2008 rrb = radeon_get_depthbuffer(&rmesa->radeon);
2009 /* color buffer */
2010 if (rrb && rrb->bo) {
2011 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2012 0, RADEON_GEM_DOMAIN_VRAM);
2013 }
2014
2015 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2016 radeonTexObj *t;
2017
2018 if (!ctx->Texture.Unit[i]._ReallyEnabled)
2019 continue;
2020
2021 t = rmesa->state.texture.unit[i].texobj;
2022
2023 if (!t)
2024 continue;
2025 if (t->image_override && t->bo)
2026 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2027 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2028 else if (t->mt->bo)
2029 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2030 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2031 }
2032
2033 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
2034 if (ret)
2035 return GL_FALSE;
2036 return GL_TRUE;
2037 }
2038
radeonValidateState(struct gl_context * ctx)2039 GLboolean radeonValidateState( struct gl_context *ctx )
2040 {
2041 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2042 GLuint new_state = rmesa->radeon.NewGLState;
2043
2044 if (new_state & _NEW_BUFFERS) {
2045 _mesa_update_framebuffer(ctx);
2046 /* this updates the DrawBuffer's Width/Height if it's a FBO */
2047 _mesa_update_draw_buffer_bounds(ctx);
2048 RADEON_STATECHANGE(rmesa, ctx);
2049 }
2050
2051 if (new_state & _NEW_TEXTURE) {
2052 radeonUpdateTextureState( ctx );
2053 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2054 }
2055
2056 /* we need to do a space check here */
2057 if (!r100ValidateBuffers(ctx))
2058 return GL_FALSE;
2059
2060 /* Need an event driven matrix update?
2061 */
2062 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2063 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
2064
2065 /* Need these for lighting (shouldn't upload otherwise)
2066 */
2067 if (new_state & (_NEW_MODELVIEW)) {
2068 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
2069 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
2070 }
2071
2072 /* Does this need to be triggered on eg. modelview for
2073 * texgen-derived objplane/eyeplane matrices?
2074 */
2075 if (new_state & _NEW_TEXTURE_MATRIX) {
2076 update_texturematrix( ctx );
2077 }
2078
2079 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2080 update_light( ctx );
2081 }
2082
2083 /* emit all active clip planes if projection matrix changes.
2084 */
2085 if (new_state & (_NEW_PROJECTION)) {
2086 if (ctx->Transform.ClipPlanesEnabled)
2087 radeonUpdateClipPlanes( ctx );
2088 }
2089
2090
2091 rmesa->radeon.NewGLState = 0;
2092
2093 return GL_TRUE;
2094 }
2095
2096
radeonInvalidateState(struct gl_context * ctx,GLuint new_state)2097 static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
2098 {
2099 _swrast_InvalidateState( ctx, new_state );
2100 _swsetup_InvalidateState( ctx, new_state );
2101 _vbo_InvalidateState( ctx, new_state );
2102 _tnl_InvalidateState( ctx, new_state );
2103 _ae_invalidate_state( ctx, new_state );
2104 R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2105 }
2106
2107
2108 /* A hack. Need a faster way to find this out.
2109 */
check_material(struct gl_context * ctx)2110 static GLboolean check_material( struct gl_context *ctx )
2111 {
2112 TNLcontext *tnl = TNL_CONTEXT(ctx);
2113 GLint i;
2114
2115 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2116 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2117 i++)
2118 if (tnl->vb.AttribPtr[i] &&
2119 tnl->vb.AttribPtr[i]->stride)
2120 return GL_TRUE;
2121
2122 return GL_FALSE;
2123 }
2124
2125
radeonWrapRunPipeline(struct gl_context * ctx)2126 static void radeonWrapRunPipeline( struct gl_context *ctx )
2127 {
2128 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2129 GLboolean has_material;
2130
2131 if (0)
2132 fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2133
2134 /* Validate state:
2135 */
2136 if (rmesa->radeon.NewGLState)
2137 if (!radeonValidateState( ctx ))
2138 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2139
2140 has_material = (ctx->Light.Enabled && check_material( ctx ));
2141
2142 if (has_material) {
2143 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2144 }
2145
2146 /* Run the pipeline.
2147 */
2148 _tnl_run_pipeline( ctx );
2149
2150 if (has_material) {
2151 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2152 }
2153 }
2154
radeonPolygonStipple(struct gl_context * ctx,const GLubyte * mask)2155 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2156 {
2157 r100ContextPtr r100 = R100_CONTEXT(ctx);
2158 GLint i;
2159
2160 radeon_firevertices(&r100->radeon);
2161
2162 RADEON_STATECHANGE(r100, stp);
2163
2164 /* Must flip pattern upside down.
2165 */
2166 for ( i = 31 ; i >= 0; i--) {
2167 r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2168 }
2169 }
2170
2171
2172 /* Initialize the driver's state functions.
2173 * Many of the ctx->Driver functions might have been initialized to
2174 * software defaults in the earlier _mesa_init_driver_functions() call.
2175 */
radeonInitStateFuncs(struct gl_context * ctx)2176 void radeonInitStateFuncs( struct gl_context *ctx )
2177 {
2178 ctx->Driver.UpdateState = radeonInvalidateState;
2179 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2180
2181 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2182 ctx->Driver.ReadBuffer = radeonReadBuffer;
2183 ctx->Driver.CopyPixels = _mesa_meta_CopyPixels;
2184 ctx->Driver.DrawPixels = _mesa_meta_DrawPixels;
2185 ctx->Driver.ReadPixels = radeonReadPixels;
2186
2187 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2188 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2189 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2190 ctx->Driver.ClipPlane = radeonClipPlane;
2191 ctx->Driver.ColorMask = radeonColorMask;
2192 ctx->Driver.CullFace = radeonCullFace;
2193 ctx->Driver.DepthFunc = radeonDepthFunc;
2194 ctx->Driver.DepthMask = radeonDepthMask;
2195 ctx->Driver.DepthRange = radeonDepthRange;
2196 ctx->Driver.Enable = radeonEnable;
2197 ctx->Driver.Fogfv = radeonFogfv;
2198 ctx->Driver.FrontFace = radeonFrontFace;
2199 ctx->Driver.Hint = NULL;
2200 ctx->Driver.LightModelfv = radeonLightModelfv;
2201 ctx->Driver.Lightfv = radeonLightfv;
2202 ctx->Driver.LineStipple = radeonLineStipple;
2203 ctx->Driver.LineWidth = radeonLineWidth;
2204 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2205 ctx->Driver.PolygonMode = radeonPolygonMode;
2206 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2207 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2208 ctx->Driver.RenderMode = radeonRenderMode;
2209 ctx->Driver.Scissor = radeonScissor;
2210 ctx->Driver.ShadeModel = radeonShadeModel;
2211 ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate;
2212 ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate;
2213 ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate;
2214 ctx->Driver.Viewport = radeonViewport;
2215
2216 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2217 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2218 }
2219