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