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 struct gl_light_uniforms *lu = &ctx->Light.LightSource[p];
684
685 /* fprintf(stderr, "%s\n", __func__); */
686
687 if (l->Enabled) {
688 r100ContextPtr rmesa = R100_CONTEXT(ctx);
689 float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
690
691 COPY_4V( &fcmd[LIT_AMBIENT_RED], lu->Ambient );
692 COPY_4V( &fcmd[LIT_DIFFUSE_RED], lu->Diffuse );
693 COPY_4V( &fcmd[LIT_SPECULAR_RED], lu->Specular );
694
695 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
696 }
697 }
698
699 /* Also fallback for asym colormaterial mode in twoside lighting...
700 */
check_twoside_fallback(struct gl_context * ctx)701 static void check_twoside_fallback( struct gl_context *ctx )
702 {
703 GLboolean fallback = GL_FALSE;
704 GLint i;
705
706 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
707 if (ctx->Light.ColorMaterialEnabled &&
708 (ctx->Light._ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
709 ((ctx->Light._ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
710 fallback = GL_TRUE;
711 else {
712 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
713 if (memcmp( ctx->Light.Material.Attrib[i],
714 ctx->Light.Material.Attrib[i+1],
715 sizeof(GLfloat)*4) != 0) {
716 fallback = GL_TRUE;
717 break;
718 }
719 }
720 }
721
722 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
723 }
724
725
radeonColorMaterial(struct gl_context * ctx,GLenum face,GLenum mode)726 static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
727 {
728 r100ContextPtr rmesa = R100_CONTEXT(ctx);
729 GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
730
731 light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
732 (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
733 (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
734 (3 << RADEON_SPECULAR_SOURCE_SHIFT));
735
736 if (ctx->Light.ColorMaterialEnabled) {
737 GLuint mask = ctx->Light._ColorMaterialBitmask;
738
739 if (mask & MAT_BIT_FRONT_EMISSION) {
740 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
741 RADEON_EMISSIVE_SOURCE_SHIFT);
742 }
743 else {
744 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
745 RADEON_EMISSIVE_SOURCE_SHIFT);
746 }
747
748 if (mask & MAT_BIT_FRONT_AMBIENT) {
749 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
750 RADEON_AMBIENT_SOURCE_SHIFT);
751 }
752 else {
753 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
754 RADEON_AMBIENT_SOURCE_SHIFT);
755 }
756
757 if (mask & MAT_BIT_FRONT_DIFFUSE) {
758 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
759 RADEON_DIFFUSE_SOURCE_SHIFT);
760 }
761 else {
762 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
763 RADEON_DIFFUSE_SOURCE_SHIFT);
764 }
765
766 if (mask & MAT_BIT_FRONT_SPECULAR) {
767 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
768 RADEON_SPECULAR_SOURCE_SHIFT);
769 }
770 else {
771 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
772 RADEON_SPECULAR_SOURCE_SHIFT);
773 }
774 }
775 else {
776 /* Default to MULT:
777 */
778 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
779 (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
780 (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
781 (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
782 }
783
784 if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
785 RADEON_STATECHANGE( rmesa, tcl );
786 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
787 }
788 }
789
radeonUpdateMaterial(struct gl_context * ctx)790 void radeonUpdateMaterial( struct gl_context *ctx )
791 {
792 r100ContextPtr rmesa = R100_CONTEXT(ctx);
793 GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
794 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
795 GLuint mask = ~0;
796
797 if (ctx->Light.ColorMaterialEnabled)
798 mask &= ~ctx->Light._ColorMaterialBitmask;
799
800 if (RADEON_DEBUG & RADEON_STATE)
801 fprintf(stderr, "%s\n", __func__);
802
803
804 if (mask & MAT_BIT_FRONT_EMISSION) {
805 fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
806 fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
807 fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2];
808 fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
809 }
810 if (mask & MAT_BIT_FRONT_AMBIENT) {
811 fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
812 fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
813 fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
814 fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
815 }
816 if (mask & MAT_BIT_FRONT_DIFFUSE) {
817 fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
818 fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
819 fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
820 fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
821 }
822 if (mask & MAT_BIT_FRONT_SPECULAR) {
823 fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
824 fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
825 fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
826 fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
827 }
828 if (mask & MAT_BIT_FRONT_SHININESS) {
829 fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
830 }
831
832 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
833
834 check_twoside_fallback( ctx );
835 /* update_global_ambient( ctx );*/
836 }
837
838 /* _NEW_LIGHT
839 * _NEW_MODELVIEW
840 * _MESA_NEW_NEED_EYE_COORDS
841 *
842 * Uses derived state from mesa:
843 * _VP_inf_norm
844 * _h_inf_norm
845 * _Position
846 * _NormSpotDirection
847 * _ModelViewInvScale
848 * _NeedEyeCoords
849 * _EyeZDir
850 *
851 * which are calculated in light.c and are correct for the current
852 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
853 * and _MESA_NEW_NEED_EYE_COORDS.
854 */
update_light(struct gl_context * ctx)855 static void update_light( struct gl_context *ctx )
856 {
857 r100ContextPtr rmesa = R100_CONTEXT(ctx);
858
859 /* Have to check these, or have an automatic shortcircuit mechanism
860 * to remove noop statechanges. (Or just do a better job on the
861 * front end).
862 */
863 {
864 GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
865
866 if (ctx->_NeedEyeCoords)
867 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
868 else
869 tmp |= RADEON_LIGHT_IN_MODELSPACE;
870
871
872 /* Leave this test disabled: (unexplained q3 lockup) (even with
873 new packets)
874 */
875 if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
876 {
877 RADEON_STATECHANGE( rmesa, tcl );
878 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
879 }
880 }
881
882 {
883 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
884 fcmd[EYE_X] = ctx->_EyeZDir[0];
885 fcmd[EYE_Y] = ctx->_EyeZDir[1];
886 fcmd[EYE_Z] = - ctx->_EyeZDir[2];
887 fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
888 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
889 }
890
891
892
893 if (ctx->Light.Enabled) {
894 GLbitfield mask = ctx->Light._EnabledLights;
895 while (mask) {
896 const int p = u_bit_scan(&mask);
897 struct gl_light *l = &ctx->Light.Light[p];
898 struct gl_light_uniforms *lu = &ctx->Light.LightSource[p];
899 GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
900
901 if (lu->EyePosition[3] == 0.0) {
902 COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
903 COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
904 fcmd[LIT_POSITION_W] = 0;
905 fcmd[LIT_DIRECTION_W] = 0;
906 } else {
907 COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
908 fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
909 fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
910 fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
911 fcmd[LIT_DIRECTION_W] = 0;
912 }
913
914 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
915 }
916 }
917 }
918
radeonLightfv(struct gl_context * ctx,GLenum light,GLenum pname,const GLfloat * params)919 static void radeonLightfv( struct gl_context *ctx, GLenum light,
920 GLenum pname, const GLfloat *params )
921 {
922 r100ContextPtr rmesa = R100_CONTEXT(ctx);
923 GLint p = light - GL_LIGHT0;
924 struct gl_light_uniforms *lu = &ctx->Light.LightSource[p];
925 GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
926
927
928 switch (pname) {
929 case GL_AMBIENT:
930 case GL_DIFFUSE:
931 case GL_SPECULAR:
932 update_light_colors( ctx, p );
933 break;
934
935 case GL_SPOT_DIRECTION:
936 /* picked up in update_light */
937 break;
938
939 case GL_POSITION: {
940 /* positions picked up in update_light, but can do flag here */
941 GLuint flag;
942 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
943
944 /* FIXME: Set RANGE_ATTEN only when needed */
945 if (p&1)
946 flag = RADEON_LIGHT_1_IS_LOCAL;
947 else
948 flag = RADEON_LIGHT_0_IS_LOCAL;
949
950 RADEON_STATECHANGE(rmesa, tcl);
951 if (lu->EyePosition[3] != 0.0F)
952 rmesa->hw.tcl.cmd[idx] |= flag;
953 else
954 rmesa->hw.tcl.cmd[idx] &= ~flag;
955 break;
956 }
957
958 case GL_SPOT_EXPONENT:
959 RADEON_STATECHANGE(rmesa, lit[p]);
960 fcmd[LIT_SPOT_EXPONENT] = params[0];
961 break;
962
963 case GL_SPOT_CUTOFF: {
964 GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
965 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
966
967 RADEON_STATECHANGE(rmesa, lit[p]);
968 fcmd[LIT_SPOT_CUTOFF] = lu->_CosCutoff;
969
970 RADEON_STATECHANGE(rmesa, tcl);
971 if (lu->SpotCutoff != 180.0F)
972 rmesa->hw.tcl.cmd[idx] |= flag;
973 else
974 rmesa->hw.tcl.cmd[idx] &= ~flag;
975
976 break;
977 }
978
979 case GL_CONSTANT_ATTENUATION:
980 RADEON_STATECHANGE(rmesa, lit[p]);
981 fcmd[LIT_ATTEN_CONST] = params[0];
982 if ( params[0] == 0.0 )
983 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
984 else
985 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
986 break;
987 case GL_LINEAR_ATTENUATION:
988 RADEON_STATECHANGE(rmesa, lit[p]);
989 fcmd[LIT_ATTEN_LINEAR] = params[0];
990 break;
991 case GL_QUADRATIC_ATTENUATION:
992 RADEON_STATECHANGE(rmesa, lit[p]);
993 fcmd[LIT_ATTEN_QUADRATIC] = params[0];
994 break;
995 default:
996 return;
997 }
998
999 /* Set RANGE_ATTEN only when needed */
1000 switch (pname) {
1001 case GL_POSITION:
1002 case GL_CONSTANT_ATTENUATION:
1003 case GL_LINEAR_ATTENUATION:
1004 case GL_QUADRATIC_ATTENUATION:
1005 {
1006 GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
1007 GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1008 GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
1009 : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
1010 GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
1011 : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
1012
1013 if ( lu->EyePosition[3] == 0.0F ||
1014 ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1015 fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1016 /* Disable attenuation */
1017 icmd[idx] &= ~atten_flag;
1018 } else {
1019 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1020 /* Enable only constant portion of attenuation calculation */
1021 icmd[idx] |= ( atten_flag | atten_const_flag );
1022 } else {
1023 /* Enable full attenuation calculation */
1024 icmd[idx] &= ~atten_const_flag;
1025 icmd[idx] |= atten_flag;
1026 }
1027 }
1028
1029 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1030 break;
1031 }
1032 default:
1033 break;
1034 }
1035 }
1036
1037
1038
1039
radeonLightModelfv(struct gl_context * ctx,GLenum pname,const GLfloat * param)1040 static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
1041 const GLfloat *param )
1042 {
1043 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1044
1045 switch (pname) {
1046 case GL_LIGHT_MODEL_AMBIENT:
1047 update_global_ambient( ctx );
1048 break;
1049
1050 case GL_LIGHT_MODEL_LOCAL_VIEWER:
1051 RADEON_STATECHANGE( rmesa, tcl );
1052 if (ctx->Light.Model.LocalViewer)
1053 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
1054 else
1055 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
1056 break;
1057
1058 case GL_LIGHT_MODEL_TWO_SIDE:
1059 RADEON_STATECHANGE( rmesa, tcl );
1060 if (ctx->Light.Model.TwoSide)
1061 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
1062 else
1063 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
1064
1065 check_twoside_fallback( ctx );
1066
1067 if (rmesa->radeon.TclFallback) {
1068 radeonChooseRenderState( ctx );
1069 radeonChooseVertexState( ctx );
1070 }
1071 break;
1072
1073 case GL_LIGHT_MODEL_COLOR_CONTROL:
1074 radeonUpdateSpecular(ctx);
1075 break;
1076
1077 default:
1078 break;
1079 }
1080 }
1081
radeonShadeModel(struct gl_context * ctx,GLenum mode)1082 static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
1083 {
1084 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1085 GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1086
1087 s &= ~(RADEON_DIFFUSE_SHADE_MASK |
1088 RADEON_ALPHA_SHADE_MASK |
1089 RADEON_SPECULAR_SHADE_MASK |
1090 RADEON_FOG_SHADE_MASK);
1091
1092 switch ( mode ) {
1093 case GL_FLAT:
1094 s |= (RADEON_DIFFUSE_SHADE_FLAT |
1095 RADEON_ALPHA_SHADE_FLAT |
1096 RADEON_SPECULAR_SHADE_FLAT |
1097 RADEON_FOG_SHADE_FLAT);
1098 break;
1099 case GL_SMOOTH:
1100 s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
1101 RADEON_ALPHA_SHADE_GOURAUD |
1102 RADEON_SPECULAR_SHADE_GOURAUD |
1103 RADEON_FOG_SHADE_GOURAUD);
1104 break;
1105 default:
1106 return;
1107 }
1108
1109 if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1110 RADEON_STATECHANGE( rmesa, set );
1111 rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1112 }
1113 }
1114
1115
1116 /* =============================================================
1117 * User clip planes
1118 */
1119
radeonClipPlane(struct gl_context * ctx,GLenum plane,const GLfloat * eq)1120 static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
1121 {
1122 GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1123 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1124 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1125
1126 RADEON_STATECHANGE( rmesa, ucp[p] );
1127 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1128 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1129 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1130 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1131 }
1132
radeonUpdateClipPlanes(struct gl_context * ctx)1133 static void radeonUpdateClipPlanes( struct gl_context *ctx )
1134 {
1135 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1136 GLbitfield mask = ctx->Transform.ClipPlanesEnabled;
1137
1138 while (mask) {
1139 const int p = u_bit_scan(&mask);
1140 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1141
1142 RADEON_STATECHANGE( rmesa, ucp[p] );
1143 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1144 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1145 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1146 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1147 }
1148 }
1149
1150
1151 /* =============================================================
1152 * Stencil
1153 */
1154
1155 static void
radeonStencilFuncSeparate(struct gl_context * ctx,GLenum face,GLenum func,GLint ref,GLuint mask)1156 radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
1157 GLint ref, GLuint mask )
1158 {
1159 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1160 GLuint refmask = ((_mesa_get_stencil_ref(ctx, 0) << RADEON_STENCIL_REF_SHIFT) |
1161 ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
1162
1163 RADEON_STATECHANGE( rmesa, ctx );
1164 RADEON_STATECHANGE( rmesa, msk );
1165
1166 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
1167 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
1168 RADEON_STENCIL_VALUE_MASK);
1169
1170 switch ( ctx->Stencil.Function[0] ) {
1171 case GL_NEVER:
1172 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
1173 break;
1174 case GL_LESS:
1175 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
1176 break;
1177 case GL_EQUAL:
1178 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
1179 break;
1180 case GL_LEQUAL:
1181 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
1182 break;
1183 case GL_GREATER:
1184 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
1185 break;
1186 case GL_NOTEQUAL:
1187 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
1188 break;
1189 case GL_GEQUAL:
1190 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
1191 break;
1192 case GL_ALWAYS:
1193 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
1194 break;
1195 }
1196
1197 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1198 }
1199
1200 static void
radeonStencilMaskSeparate(struct gl_context * ctx,GLenum face,GLuint mask)1201 radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
1202 {
1203 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1204
1205 RADEON_STATECHANGE( rmesa, msk );
1206 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
1207 rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1208 ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
1209 }
1210
radeonStencilOpSeparate(struct gl_context * ctx,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)1211 static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
1212 GLenum zfail, GLenum zpass )
1213 {
1214 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1215
1216 /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
1217 and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
1218 but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
1219
1220 GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
1221 GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
1222 GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1223 GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1224 GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1225 GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
1226
1227 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
1228 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
1229 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
1230 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
1231 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
1232 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
1233 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
1234 }
1235 else {
1236 tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
1237 tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
1238 tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
1239 tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
1240 tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
1241 tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
1242 }
1243
1244 RADEON_STATECHANGE( rmesa, ctx );
1245 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
1246 RADEON_STENCIL_ZFAIL_MASK |
1247 RADEON_STENCIL_ZPASS_MASK);
1248
1249 switch ( ctx->Stencil.FailFunc[0] ) {
1250 case GL_KEEP:
1251 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
1252 break;
1253 case GL_ZERO:
1254 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
1255 break;
1256 case GL_REPLACE:
1257 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
1258 break;
1259 case GL_INCR:
1260 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
1261 break;
1262 case GL_DECR:
1263 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
1264 break;
1265 case GL_INCR_WRAP:
1266 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
1267 break;
1268 case GL_DECR_WRAP:
1269 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
1270 break;
1271 case GL_INVERT:
1272 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
1273 break;
1274 }
1275
1276 switch ( ctx->Stencil.ZFailFunc[0] ) {
1277 case GL_KEEP:
1278 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
1279 break;
1280 case GL_ZERO:
1281 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
1282 break;
1283 case GL_REPLACE:
1284 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
1285 break;
1286 case GL_INCR:
1287 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
1288 break;
1289 case GL_DECR:
1290 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
1291 break;
1292 case GL_INCR_WRAP:
1293 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
1294 break;
1295 case GL_DECR_WRAP:
1296 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
1297 break;
1298 case GL_INVERT:
1299 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
1300 break;
1301 }
1302
1303 switch ( ctx->Stencil.ZPassFunc[0] ) {
1304 case GL_KEEP:
1305 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
1306 break;
1307 case GL_ZERO:
1308 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
1309 break;
1310 case GL_REPLACE:
1311 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
1312 break;
1313 case GL_INCR:
1314 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
1315 break;
1316 case GL_DECR:
1317 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
1318 break;
1319 case GL_INCR_WRAP:
1320 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
1321 break;
1322 case GL_DECR_WRAP:
1323 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
1324 break;
1325 case GL_INVERT:
1326 rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
1327 break;
1328 }
1329 }
1330
1331
1332
1333 /* =============================================================
1334 * Window position and viewport transformation
1335 */
1336
1337 /*
1338 * To correctly position primitives:
1339 */
1340 #define SUBPIXEL_X 0.125
1341 #define SUBPIXEL_Y 0.125
1342
1343
1344 /**
1345 * Called when window size or position changes or viewport or depth range
1346 * state is changed. We update the hardware viewport state here.
1347 */
radeonUpdateWindow(struct gl_context * ctx)1348 void radeonUpdateWindow( struct gl_context *ctx )
1349 {
1350 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1351 __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
1352 GLfloat xoffset = 0.0;
1353 GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
1354 const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
1355 float scale[3], translate[3];
1356 GLfloat y_scale, y_bias;
1357
1358 if (render_to_fbo) {
1359 y_scale = 1.0;
1360 y_bias = 0;
1361 } else {
1362 y_scale = -1.0;
1363 y_bias = yoffset;
1364 }
1365
1366 _mesa_get_viewport_xform(ctx, 0, scale, translate);
1367 float_ui32_type sx = { scale[0] };
1368 float_ui32_type sy = { scale[1] * y_scale };
1369 float_ui32_type sz = { scale[2] };
1370 float_ui32_type tx = { translate[0] + xoffset + SUBPIXEL_X };
1371 float_ui32_type ty = { (translate[1] * y_scale) + y_bias + SUBPIXEL_Y };
1372 float_ui32_type tz = { translate[2] };
1373
1374 RADEON_STATECHANGE( rmesa, vpt );
1375
1376 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
1377 rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1378 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
1379 rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1380 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
1381 rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1382 }
1383
1384
radeonViewport(struct gl_context * ctx)1385 static void radeonViewport(struct gl_context *ctx)
1386 {
1387 /* Don't pipeline viewport changes, conflict with window offset
1388 * setting below. Could apply deltas to rescue pipelined viewport
1389 * values, or keep the originals hanging around.
1390 */
1391 radeonUpdateWindow( ctx );
1392
1393 radeon_viewport(ctx);
1394 }
1395
radeonDepthRange(struct gl_context * ctx)1396 static void radeonDepthRange(struct gl_context *ctx)
1397 {
1398 radeonUpdateWindow( ctx );
1399 }
1400
1401 /* =============================================================
1402 * Miscellaneous
1403 */
1404
radeonRenderMode(struct gl_context * ctx,GLenum mode)1405 static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
1406 {
1407 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1408 FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1409 }
1410
radeonLogicOpCode(struct gl_context * ctx,enum gl_logicop_mode opcode)1411 static void radeonLogicOpCode(struct gl_context *ctx, enum gl_logicop_mode opcode)
1412 {
1413 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1414
1415 assert((unsigned) opcode <= 15);
1416
1417 RADEON_STATECHANGE( rmesa, msk );
1418 rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = opcode;
1419 }
1420
1421 /* =============================================================
1422 * State enable/disable
1423 */
1424
radeonEnable(struct gl_context * ctx,GLenum cap,GLboolean state)1425 static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
1426 {
1427 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1428 GLuint p, flag;
1429
1430 if ( RADEON_DEBUG & RADEON_STATE )
1431 fprintf( stderr, "%s( %s = %s )\n", __func__,
1432 _mesa_enum_to_string( cap ),
1433 state ? "GL_TRUE" : "GL_FALSE" );
1434
1435 switch ( cap ) {
1436 /* Fast track this one...
1437 */
1438 case GL_TEXTURE_1D:
1439 case GL_TEXTURE_2D:
1440 case GL_TEXTURE_3D:
1441 break;
1442
1443 case GL_ALPHA_TEST:
1444 RADEON_STATECHANGE( rmesa, ctx );
1445 if (state) {
1446 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
1447 } else {
1448 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
1449 }
1450 break;
1451
1452 case GL_BLEND:
1453 RADEON_STATECHANGE( rmesa, ctx );
1454 if (state) {
1455 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE;
1456 } else {
1457 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
1458 }
1459 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1460 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1461 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1462 } else {
1463 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1464 }
1465
1466 /* Catch a possible fallback:
1467 */
1468 if (state) {
1469 ctx->Driver.BlendEquationSeparate( ctx,
1470 ctx->Color.Blend[0].EquationRGB,
1471 ctx->Color.Blend[0].EquationA );
1472 ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
1473 ctx->Color.Blend[0].DstRGB,
1474 ctx->Color.Blend[0].SrcA,
1475 ctx->Color.Blend[0].DstA );
1476 }
1477 else {
1478 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
1479 FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
1480 }
1481 break;
1482
1483 case GL_CLIP_PLANE0:
1484 case GL_CLIP_PLANE1:
1485 case GL_CLIP_PLANE2:
1486 case GL_CLIP_PLANE3:
1487 case GL_CLIP_PLANE4:
1488 case GL_CLIP_PLANE5:
1489 p = cap-GL_CLIP_PLANE0;
1490 RADEON_STATECHANGE( rmesa, tcl );
1491 if (state) {
1492 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
1493 radeonClipPlane( ctx, cap, NULL );
1494 }
1495 else {
1496 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
1497 }
1498 break;
1499
1500 case GL_COLOR_MATERIAL:
1501 radeonColorMaterial( ctx, 0, 0 );
1502 radeonUpdateMaterial( ctx );
1503 break;
1504
1505 case GL_CULL_FACE:
1506 radeonCullFace( ctx, 0 );
1507 break;
1508
1509 case GL_DEPTH_TEST:
1510 RADEON_STATECHANGE(rmesa, ctx );
1511 if ( state ) {
1512 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE;
1513 } else {
1514 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
1515 }
1516 break;
1517
1518 case GL_DITHER:
1519 RADEON_STATECHANGE(rmesa, ctx );
1520 if ( state ) {
1521 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE;
1522 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1523 } else {
1524 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
1525 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable;
1526 }
1527 break;
1528
1529 case GL_FOG:
1530 RADEON_STATECHANGE(rmesa, ctx );
1531 if ( state ) {
1532 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
1533 radeonFogfv( ctx, GL_FOG_MODE, NULL );
1534 } else {
1535 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
1536 RADEON_STATECHANGE(rmesa, tcl);
1537 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
1538 }
1539 radeonUpdateSpecular( ctx ); /* for PK_SPEC */
1540 _mesa_allow_light_in_model( ctx, !state );
1541 break;
1542
1543 case GL_LIGHT0:
1544 case GL_LIGHT1:
1545 case GL_LIGHT2:
1546 case GL_LIGHT3:
1547 case GL_LIGHT4:
1548 case GL_LIGHT5:
1549 case GL_LIGHT6:
1550 case GL_LIGHT7:
1551 RADEON_STATECHANGE(rmesa, tcl);
1552 p = cap - GL_LIGHT0;
1553 if (p&1)
1554 flag = (RADEON_LIGHT_1_ENABLE |
1555 RADEON_LIGHT_1_ENABLE_AMBIENT |
1556 RADEON_LIGHT_1_ENABLE_SPECULAR);
1557 else
1558 flag = (RADEON_LIGHT_0_ENABLE |
1559 RADEON_LIGHT_0_ENABLE_AMBIENT |
1560 RADEON_LIGHT_0_ENABLE_SPECULAR);
1561
1562 if (state)
1563 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1564 else
1565 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1566
1567 /*
1568 */
1569 update_light_colors( ctx, p );
1570 break;
1571
1572 case GL_LIGHTING:
1573 RADEON_STATECHANGE(rmesa, tcl);
1574 radeonUpdateSpecular(ctx);
1575 check_twoside_fallback( ctx );
1576 break;
1577
1578 case GL_LINE_SMOOTH:
1579 RADEON_STATECHANGE( rmesa, ctx );
1580 if ( state ) {
1581 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE;
1582 } else {
1583 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
1584 }
1585 break;
1586
1587 case GL_LINE_STIPPLE:
1588 RADEON_STATECHANGE( rmesa, ctx );
1589 if ( state ) {
1590 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE;
1591 } else {
1592 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
1593 }
1594 break;
1595
1596 case GL_COLOR_LOGIC_OP:
1597 RADEON_STATECHANGE( rmesa, ctx );
1598 if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
1599 && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
1600 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
1601 } else {
1602 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
1603 }
1604 break;
1605
1606 case GL_NORMALIZE:
1607 RADEON_STATECHANGE( rmesa, tcl );
1608 if ( state ) {
1609 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS;
1610 } else {
1611 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
1612 }
1613 break;
1614
1615 case GL_POLYGON_OFFSET_POINT:
1616 RADEON_STATECHANGE( rmesa, set );
1617 if ( state ) {
1618 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
1619 } else {
1620 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
1621 }
1622 break;
1623
1624 case GL_POLYGON_OFFSET_LINE:
1625 RADEON_STATECHANGE( rmesa, set );
1626 if ( state ) {
1627 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
1628 } else {
1629 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
1630 }
1631 break;
1632
1633 case GL_POLYGON_OFFSET_FILL:
1634 RADEON_STATECHANGE( rmesa, set );
1635 if ( state ) {
1636 rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
1637 } else {
1638 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
1639 }
1640 break;
1641
1642 case GL_POLYGON_SMOOTH:
1643 RADEON_STATECHANGE( rmesa, ctx );
1644 if ( state ) {
1645 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY;
1646 } else {
1647 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
1648 }
1649 break;
1650
1651 case GL_POLYGON_STIPPLE:
1652 RADEON_STATECHANGE(rmesa, ctx );
1653 if ( state ) {
1654 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE;
1655 } else {
1656 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
1657 }
1658 break;
1659
1660 case GL_RESCALE_NORMAL_EXT: {
1661 GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
1662 RADEON_STATECHANGE( rmesa, tcl );
1663 if ( tmp ) {
1664 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1665 } else {
1666 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1667 }
1668 break;
1669 }
1670
1671 case GL_SCISSOR_TEST:
1672 radeon_firevertices(&rmesa->radeon);
1673 rmesa->radeon.state.scissor.enabled = state;
1674 radeonUpdateScissor( ctx );
1675 break;
1676
1677 case GL_STENCIL_TEST:
1678 {
1679 GLboolean hw_stencil = GL_FALSE;
1680 if (ctx->DrawBuffer) {
1681 struct radeon_renderbuffer *rrbStencil
1682 = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
1683 hw_stencil = (rrbStencil && rrbStencil->bo);
1684 }
1685
1686 if (hw_stencil) {
1687 RADEON_STATECHANGE( rmesa, ctx );
1688 if ( state ) {
1689 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
1690 } else {
1691 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
1692 }
1693 } else {
1694 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
1695 }
1696 }
1697 break;
1698
1699 case GL_TEXTURE_GEN_Q:
1700 case GL_TEXTURE_GEN_R:
1701 case GL_TEXTURE_GEN_S:
1702 case GL_TEXTURE_GEN_T:
1703 /* Picked up in radeonUpdateTextureState.
1704 */
1705 rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
1706 break;
1707
1708 case GL_COLOR_SUM_EXT:
1709 radeonUpdateSpecular ( ctx );
1710 break;
1711
1712 default:
1713 return;
1714 }
1715 }
1716
1717
radeonLightingSpaceChange(struct gl_context * ctx)1718 static void radeonLightingSpaceChange( struct gl_context *ctx )
1719 {
1720 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1721 GLboolean tmp;
1722 RADEON_STATECHANGE( rmesa, tcl );
1723
1724 if (RADEON_DEBUG & RADEON_STATE)
1725 fprintf(stderr, "%s %d BEFORE %x\n", __func__, ctx->_NeedEyeCoords,
1726 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1727
1728 if (ctx->_NeedEyeCoords)
1729 tmp = ctx->Transform.RescaleNormals;
1730 else
1731 tmp = !ctx->Transform.RescaleNormals;
1732
1733 if ( tmp ) {
1734 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS;
1735 } else {
1736 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
1737 }
1738
1739 if (RADEON_DEBUG & RADEON_STATE)
1740 fprintf(stderr, "%s %d AFTER %x\n", __func__, ctx->_NeedEyeCoords,
1741 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
1742 }
1743
1744 /* =============================================================
1745 * Deferred state management - matrices, textures, other?
1746 */
1747
1748
radeonUploadTexMatrix(r100ContextPtr rmesa,int unit,GLboolean swapcols)1749 void radeonUploadTexMatrix( r100ContextPtr rmesa,
1750 int unit, GLboolean swapcols )
1751 {
1752 /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
1753 vector looks like this probably: (s t r|q 0) (not sure if the last coord
1754 is hardwired to 0, could be 1 too). Interestingly, it actually looks like
1755 texgen generates all 4 coords, at least tests with projtex indicated that.
1756 So: if we need the q coord in the end (solely determined by the texture
1757 target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
1758 Additionally, if we don't have texgen but 4 tex coords submitted, we swap
1759 column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
1760 will get submitted in the "wrong", i.e. 3rd, slot.
1761 If an app submits 3 coords for 2d targets, we assume it is saving on vertex
1762 size and using the texture matrix to swap the r and q coords around (ut2k3
1763 does exactly that), so we don't need the 3rd / 4th column swap - still need
1764 the 3rd / 4th row swap of course. This will potentially break for apps which
1765 use TexCoord3x just for fun. Additionally, it will never work if an app uses
1766 an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
1767 the maximum needed 3. This seems impossible to do with hw tcl on r100, and
1768 incredibly hard to detect so we can't just fallback in such a case. Assume
1769 it never happens... - rs
1770 */
1771
1772 int idx = TEXMAT_0 + unit;
1773 float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
1774 int i;
1775 struct gl_texture_unit tUnit = rmesa->radeon.glCtx.Texture.Unit[unit];
1776 GLfloat *src = rmesa->tmpmat[unit].m;
1777
1778 rmesa->TexMatColSwap &= ~(1 << unit);
1779 if (!tUnit._Current ||
1780 (tUnit._Current->Target != GL_TEXTURE_3D &&
1781 tUnit._Current->Target != GL_TEXTURE_CUBE_MAP)) {
1782 if (swapcols) {
1783 rmesa->TexMatColSwap |= 1 << unit;
1784 /* attention some elems are swapped 2 times! */
1785 *dest++ = src[0];
1786 *dest++ = src[4];
1787 *dest++ = src[12];
1788 *dest++ = src[8];
1789 *dest++ = src[1];
1790 *dest++ = src[5];
1791 *dest++ = src[13];
1792 *dest++ = src[9];
1793 *dest++ = src[2];
1794 *dest++ = src[6];
1795 *dest++ = src[15];
1796 *dest++ = src[11];
1797 /* those last 4 are probably never used */
1798 *dest++ = src[3];
1799 *dest++ = src[7];
1800 *dest++ = src[14];
1801 *dest++ = src[10];
1802 }
1803 else {
1804 for (i = 0; i < 2; i++) {
1805 *dest++ = src[i];
1806 *dest++ = src[i+4];
1807 *dest++ = src[i+8];
1808 *dest++ = src[i+12];
1809 }
1810 for (i = 3; i >= 2; i--) {
1811 *dest++ = src[i];
1812 *dest++ = src[i+4];
1813 *dest++ = src[i+8];
1814 *dest++ = src[i+12];
1815 }
1816 }
1817 }
1818 else {
1819 for (i = 0 ; i < 4 ; i++) {
1820 *dest++ = src[i];
1821 *dest++ = src[i+4];
1822 *dest++ = src[i+8];
1823 *dest++ = src[i+12];
1824 }
1825 }
1826
1827 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1828 }
1829
1830
upload_matrix(r100ContextPtr rmesa,GLfloat * src,int idx)1831 static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
1832 {
1833 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1834 int i;
1835
1836
1837 for (i = 0 ; i < 4 ; i++) {
1838 *dest++ = src[i];
1839 *dest++ = src[i+4];
1840 *dest++ = src[i+8];
1841 *dest++ = src[i+12];
1842 }
1843
1844 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1845 }
1846
upload_matrix_t(r100ContextPtr rmesa,GLfloat * src,int idx)1847 static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
1848 {
1849 float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
1850 memcpy(dest, src, 16*sizeof(float));
1851 RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
1852 }
1853
1854
update_texturematrix(struct gl_context * ctx)1855 static void update_texturematrix( struct gl_context *ctx )
1856 {
1857 r100ContextPtr rmesa = R100_CONTEXT( ctx );
1858 GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
1859 GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
1860 int unit;
1861 GLuint texMatEnabled = 0;
1862 rmesa->NeedTexMatrix = 0;
1863 rmesa->TexMatColSwap = 0;
1864
1865 for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
1866 if (ctx->Texture.Unit[unit]._Current) {
1867 GLboolean needMatrix = GL_FALSE;
1868 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
1869 needMatrix = GL_TRUE;
1870 texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
1871 RADEON_TEXMAT_0_ENABLE) << unit;
1872
1873 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1874 /* Need to preconcatenate any active texgen
1875 * obj/eyeplane matrices:
1876 */
1877 _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
1878 ctx->TextureMatrixStack[unit].Top,
1879 &rmesa->TexGenMatrix[unit] );
1880 }
1881 else {
1882 _math_matrix_copy( &rmesa->tmpmat[unit],
1883 ctx->TextureMatrixStack[unit].Top );
1884 }
1885 }
1886 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
1887 _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
1888 needMatrix = GL_TRUE;
1889 }
1890 if (needMatrix) {
1891 rmesa->NeedTexMatrix |= 1 << unit;
1892 radeonUploadTexMatrix( rmesa, unit,
1893 !ctx->Texture.FixedFuncUnit[unit].TexGenEnabled );
1894 }
1895 }
1896 }
1897
1898 tpc = (texMatEnabled | rmesa->TexGenEnabled);
1899
1900 /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
1901 vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
1902 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
1903 (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
1904
1905 vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
1906 (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
1907 ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
1908 (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
1909 ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
1910 (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
1911
1912 if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
1913 vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
1914
1915 RADEON_STATECHANGE(rmesa, tcl);
1916 rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
1917 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
1918 }
1919 }
1920
r100ValidateBuffers(struct gl_context * ctx)1921 GLboolean r100ValidateBuffers(struct gl_context *ctx)
1922 {
1923 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1924 struct radeon_renderbuffer *rrb;
1925 int i, ret;
1926
1927 radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
1928
1929 rrb = radeon_get_colorbuffer(&rmesa->radeon);
1930 /* color buffer */
1931 if (rrb && rrb->bo) {
1932 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
1933 0, RADEON_GEM_DOMAIN_VRAM);
1934 }
1935
1936 /* depth buffer */
1937 rrb = radeon_get_depthbuffer(&rmesa->radeon);
1938 /* color buffer */
1939 if (rrb && rrb->bo) {
1940 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
1941 0, RADEON_GEM_DOMAIN_VRAM);
1942 }
1943
1944 for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; ++i) {
1945 radeonTexObj *t;
1946
1947 if (!ctx->Texture.Unit[i]._Current)
1948 continue;
1949
1950 t = rmesa->state.texture.unit[i].texobj;
1951
1952 if (!t)
1953 continue;
1954 if (t->image_override && t->bo)
1955 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
1956 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
1957 else if (t->mt->bo)
1958 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
1959 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
1960 }
1961
1962 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
1963 if (ret)
1964 return GL_FALSE;
1965 return GL_TRUE;
1966 }
1967
radeonValidateState(struct gl_context * ctx)1968 GLboolean radeonValidateState( struct gl_context *ctx )
1969 {
1970 r100ContextPtr rmesa = R100_CONTEXT(ctx);
1971 GLuint new_state = rmesa->radeon.NewGLState;
1972
1973 if (new_state & _NEW_BUFFERS) {
1974 _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
1975 /* this updates the DrawBuffer's Width/Height if it's a FBO */
1976 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
1977 RADEON_STATECHANGE(rmesa, ctx);
1978 }
1979
1980 if (new_state & _NEW_TEXTURE) {
1981 radeonUpdateTextureState( ctx );
1982 new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
1983 }
1984
1985 /* we need to do a space check here */
1986 if (!r100ValidateBuffers(ctx))
1987 return GL_FALSE;
1988
1989 /* Need an event driven matrix update?
1990 */
1991 if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
1992 upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
1993
1994 /* Need these for lighting (shouldn't upload otherwise)
1995 */
1996 if (new_state & (_NEW_MODELVIEW)) {
1997 upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
1998 upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
1999 }
2000
2001 /* Does this need to be triggered on eg. modelview for
2002 * texgen-derived objplane/eyeplane matrices?
2003 */
2004 if (new_state & _NEW_TEXTURE_MATRIX) {
2005 update_texturematrix( ctx );
2006 }
2007
2008 if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2009 update_light( ctx );
2010 }
2011
2012 /* emit all active clip planes if projection matrix changes.
2013 */
2014 if (new_state & (_NEW_PROJECTION)) {
2015 if (ctx->Transform.ClipPlanesEnabled)
2016 radeonUpdateClipPlanes( ctx );
2017 }
2018
2019
2020 rmesa->radeon.NewGLState = 0;
2021
2022 return GL_TRUE;
2023 }
2024
2025
radeonInvalidateState(struct gl_context * ctx)2026 static void radeonInvalidateState(struct gl_context *ctx)
2027 {
2028 GLuint new_state = ctx->NewState;
2029
2030 if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
2031 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
2032
2033 _swrast_InvalidateState( ctx, new_state );
2034 _swsetup_InvalidateState( ctx, new_state );
2035 _tnl_InvalidateState( ctx, new_state );
2036 R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2037 }
2038
2039
2040 /* A hack. Need a faster way to find this out.
2041 */
check_material(struct gl_context * ctx)2042 static GLboolean check_material( struct gl_context *ctx )
2043 {
2044 TNLcontext *tnl = TNL_CONTEXT(ctx);
2045 GLint i;
2046
2047 for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2048 i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2049 i++)
2050 if (tnl->vb.AttribPtr[i] &&
2051 tnl->vb.AttribPtr[i]->stride)
2052 return GL_TRUE;
2053
2054 return GL_FALSE;
2055 }
2056
2057
radeonWrapRunPipeline(struct gl_context * ctx)2058 static void radeonWrapRunPipeline( struct gl_context *ctx )
2059 {
2060 r100ContextPtr rmesa = R100_CONTEXT(ctx);
2061 GLboolean has_material;
2062
2063 if (0)
2064 fprintf(stderr, "%s, newstate: %x\n", __func__, rmesa->radeon.NewGLState);
2065
2066 /* Validate state:
2067 */
2068 if (rmesa->radeon.NewGLState)
2069 if (!radeonValidateState( ctx ))
2070 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2071
2072 has_material = (ctx->Light.Enabled && check_material( ctx ));
2073
2074 if (has_material) {
2075 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
2076 }
2077
2078 /* Run the pipeline.
2079 */
2080 _tnl_run_pipeline( ctx );
2081
2082 if (has_material) {
2083 TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
2084 }
2085 }
2086
radeonPolygonStipple(struct gl_context * ctx,const GLubyte * mask)2087 static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
2088 {
2089 r100ContextPtr r100 = R100_CONTEXT(ctx);
2090 GLint i;
2091
2092 radeon_firevertices(&r100->radeon);
2093
2094 RADEON_STATECHANGE(r100, stp);
2095
2096 /* Must flip pattern upside down.
2097 */
2098 for ( i = 31 ; i >= 0; i--) {
2099 r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
2100 }
2101 }
2102
2103
2104 /* Initialize the driver's state functions.
2105 * Many of the ctx->Driver functions might have been initialized to
2106 * software defaults in the earlier _mesa_init_driver_functions() call.
2107 */
radeonInitStateFuncs(struct gl_context * ctx)2108 void radeonInitStateFuncs( struct gl_context *ctx )
2109 {
2110 ctx->Driver.UpdateState = radeonInvalidateState;
2111 ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
2112
2113 ctx->Driver.DrawBuffer = radeonDrawBuffer;
2114 ctx->Driver.ReadBuffer = radeonReadBuffer;
2115 ctx->Driver.CopyPixels = _mesa_meta_CopyPixels;
2116 ctx->Driver.DrawPixels = _mesa_meta_DrawPixels;
2117 ctx->Driver.ReadPixels = radeonReadPixels;
2118
2119 ctx->Driver.AlphaFunc = radeonAlphaFunc;
2120 ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate;
2121 ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate;
2122 ctx->Driver.ClipPlane = radeonClipPlane;
2123 ctx->Driver.ColorMask = radeonColorMask;
2124 ctx->Driver.CullFace = radeonCullFace;
2125 ctx->Driver.DepthFunc = radeonDepthFunc;
2126 ctx->Driver.DepthMask = radeonDepthMask;
2127 ctx->Driver.DepthRange = radeonDepthRange;
2128 ctx->Driver.Enable = radeonEnable;
2129 ctx->Driver.Fogfv = radeonFogfv;
2130 ctx->Driver.FrontFace = radeonFrontFace;
2131 ctx->Driver.LightModelfv = radeonLightModelfv;
2132 ctx->Driver.Lightfv = radeonLightfv;
2133 ctx->Driver.LineStipple = radeonLineStipple;
2134 ctx->Driver.LineWidth = radeonLineWidth;
2135 ctx->Driver.LogicOpcode = radeonLogicOpCode;
2136 ctx->Driver.PolygonMode = radeonPolygonMode;
2137 ctx->Driver.PolygonOffset = radeonPolygonOffset;
2138 ctx->Driver.PolygonStipple = radeonPolygonStipple;
2139 ctx->Driver.RenderMode = radeonRenderMode;
2140 ctx->Driver.Scissor = radeonScissor;
2141 ctx->Driver.ShadeModel = radeonShadeModel;
2142 ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate;
2143 ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate;
2144 ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate;
2145 ctx->Driver.Viewport = radeonViewport;
2146
2147 TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
2148 TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
2149 }
2150