Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / r128 / r128_state.c
1 /**************************************************************************
2
3 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
4 Cedar Park, Texas.
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Gareth Hughes <gareth@valinux.com>
31 * Kevin E. Martin <martin@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 *
34 */
35
36 #include "r128_context.h"
37 #include "r128_state.h"
38 #include "r128_ioctl.h"
39 #include "r128_tris.h"
40 #include "r128_tex.h"
41
42 #include "main/context.h"
43 #include "main/enums.h"
44 #include "main/colormac.h"
45 #include "swrast/swrast.h"
46 #include "vbo/vbo.h"
47 #include "tnl/tnl.h"
48 #include "swrast_setup/swrast_setup.h"
49
50 #include "tnl/t_pipeline.h"
51
52 #include "drirenderbuffer.h"
53
54
55 /* =============================================================
56 * Alpha blending
57 */
58
59
60 /**
61 * Calculate the hardware blend factor setting. This same function is used
62 * for source and destination of both alpha and RGB.
63 *
64 * \returns
65 * The hardware register value for the specified blend factor. This value
66 * will need to be shifted into the correct position for either source or
67 * destination factor.
68 *
69 * \todo
70 * Since the two cases where source and destination are handled differently
71 * are essentially error cases, they should never happen. Determine if these
72 * cases can be removed.
73 */
74 static int blend_factor( r128ContextPtr rmesa, GLenum factor, GLboolean is_src )
75 {
76 int func;
77
78 switch ( factor ) {
79 case GL_ZERO:
80 func = R128_ALPHA_BLEND_ZERO;
81 break;
82 case GL_ONE:
83 func = R128_ALPHA_BLEND_ONE;
84 break;
85
86 case GL_SRC_COLOR:
87 func = R128_ALPHA_BLEND_SRCCOLOR;
88 break;
89 case GL_ONE_MINUS_SRC_COLOR:
90 func = R128_ALPHA_BLEND_INVSRCCOLOR;
91 break;
92 case GL_SRC_ALPHA:
93 func = R128_ALPHA_BLEND_SRCALPHA;
94 break;
95 case GL_ONE_MINUS_SRC_ALPHA:
96 func = R128_ALPHA_BLEND_INVSRCALPHA;
97 break;
98 case GL_SRC_ALPHA_SATURATE:
99 func = (is_src) ? R128_ALPHA_BLEND_SAT : R128_ALPHA_BLEND_ZERO;
100 break;
101
102 case GL_DST_COLOR:
103 func = R128_ALPHA_BLEND_DSTCOLOR;
104 break;
105 case GL_ONE_MINUS_DST_COLOR:
106 func = R128_ALPHA_BLEND_INVDSTCOLOR;
107 break;
108 case GL_DST_ALPHA:
109 func = R128_ALPHA_BLEND_DSTALPHA;
110 break;
111 case GL_ONE_MINUS_DST_ALPHA:
112 func = R128_ALPHA_BLEND_INVDSTALPHA;
113 break;
114
115 case GL_CONSTANT_COLOR:
116 case GL_ONE_MINUS_CONSTANT_COLOR:
117 case GL_CONSTANT_ALPHA:
118 case GL_ONE_MINUS_CONSTANT_ALPHA:
119 default:
120 FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_TRUE );
121 func = (is_src) ? R128_ALPHA_BLEND_ONE : R128_ALPHA_BLEND_ZERO;
122 break;
123 }
124
125 return func;
126 }
127
128
129 static void r128UpdateAlphaMode( GLcontext *ctx )
130 {
131 r128ContextPtr rmesa = R128_CONTEXT(ctx);
132 GLuint a = rmesa->setup.misc_3d_state_cntl_reg;
133 GLuint t = rmesa->setup.tex_cntl_c;
134
135 if ( ctx->Color.AlphaEnabled ) {
136 GLubyte ref;
137
138 CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
139
140 a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK);
141
142 switch ( ctx->Color.AlphaFunc ) {
143 case GL_NEVER:
144 a |= R128_ALPHA_TEST_NEVER;
145 break;
146 case GL_LESS:
147 a |= R128_ALPHA_TEST_LESS;
148 break;
149 case GL_LEQUAL:
150 a |= R128_ALPHA_TEST_LESSEQUAL;
151 break;
152 case GL_EQUAL:
153 a |= R128_ALPHA_TEST_EQUAL;
154 break;
155 case GL_GEQUAL:
156 a |= R128_ALPHA_TEST_GREATEREQUAL;
157 break;
158 case GL_GREATER:
159 a |= R128_ALPHA_TEST_GREATER;
160 break;
161 case GL_NOTEQUAL:
162 a |= R128_ALPHA_TEST_NEQUAL;
163 break;
164 case GL_ALWAYS:
165 a |= R128_ALPHA_TEST_ALWAYS;
166 break;
167 }
168
169 a |= ref & R128_REF_ALPHA_MASK;
170 t |= R128_ALPHA_TEST_ENABLE;
171 } else {
172 t &= ~R128_ALPHA_TEST_ENABLE;
173 }
174
175 FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_FALSE );
176
177 if ( ctx->Color.BlendEnabled ) {
178 a &= ~((R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_SRC_SHIFT) |
179 (R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_DST_SHIFT)
180 | R128_ALPHA_COMB_FCN_MASK);
181
182 a |= blend_factor( rmesa, ctx->Color.BlendSrcRGB, GL_TRUE )
183 << R128_ALPHA_BLEND_SRC_SHIFT;
184 a |= blend_factor( rmesa, ctx->Color.BlendDstRGB, GL_FALSE )
185 << R128_ALPHA_BLEND_DST_SHIFT;
186
187 switch (ctx->Color.BlendEquationRGB) {
188 case GL_FUNC_ADD:
189 a |= R128_ALPHA_COMB_ADD_CLAMP;
190 break;
191 case GL_FUNC_SUBTRACT:
192 a |= R128_ALPHA_COMB_SUB_SRC_DST_CLAMP;
193 break;
194 default:
195 FALLBACK( rmesa, R128_FALLBACK_BLEND_EQ, GL_TRUE );
196 }
197
198 t |= R128_ALPHA_ENABLE;
199 } else {
200 t &= ~R128_ALPHA_ENABLE;
201 }
202
203 if ( rmesa->setup.misc_3d_state_cntl_reg != a ) {
204 rmesa->setup.misc_3d_state_cntl_reg = a;
205 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
206 }
207 if ( rmesa->setup.tex_cntl_c != t ) {
208 rmesa->setup.tex_cntl_c = t;
209 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
210 }
211 }
212
213 static void r128DDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
214 {
215 r128ContextPtr rmesa = R128_CONTEXT(ctx);
216
217 FLUSH_BATCH( rmesa );
218 rmesa->new_state |= R128_NEW_ALPHA;
219 }
220
221 static void r128DDBlendEquationSeparate( GLcontext *ctx,
222 GLenum modeRGB, GLenum modeA )
223 {
224 r128ContextPtr rmesa = R128_CONTEXT(ctx);
225
226 assert( modeRGB == modeA );
227 FLUSH_BATCH( rmesa );
228
229 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
230 * manner.
231 */
232 FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_LOGICOP,
233 (ctx->Color.ColorLogicOpEnabled &&
234 ctx->Color.LogicOp != GL_COPY));
235
236 /* Can only do blend addition, not min, max, subtract, etc. */
237 FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_BLEND_EQ,
238 (modeRGB != GL_FUNC_ADD) && (modeRGB != GL_FUNC_SUBTRACT));
239
240 rmesa->new_state |= R128_NEW_ALPHA;
241 }
242
243 static void r128DDBlendFuncSeparate( GLcontext *ctx,
244 GLenum sfactorRGB, GLenum dfactorRGB,
245 GLenum sfactorA, GLenum dfactorA )
246 {
247 r128ContextPtr rmesa = R128_CONTEXT(ctx);
248
249 FLUSH_BATCH( rmesa );
250 rmesa->new_state |= R128_NEW_ALPHA;
251 }
252
253 /* =============================================================
254 * Stencil
255 */
256
257 static void
258 r128DDStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
259 GLint ref, GLuint mask )
260 {
261 r128ContextPtr rmesa = R128_CONTEXT(ctx);
262 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << 0) |
263 ((ctx->Stencil.ValueMask[0] & 0xff) << 16) |
264 ((ctx->Stencil.WriteMask[0] & 0xff) << 24));
265 GLuint z = rmesa->setup.z_sten_cntl_c;
266
267 z &= ~R128_STENCIL_TEST_MASK;
268 switch ( ctx->Stencil.Function[0] ) {
269 case GL_NEVER:
270 z |= R128_STENCIL_TEST_NEVER;
271 break;
272 case GL_LESS:
273 z |= R128_STENCIL_TEST_LESS;
274 break;
275 case GL_EQUAL:
276 z |= R128_STENCIL_TEST_EQUAL;
277 break;
278 case GL_LEQUAL:
279 z |= R128_STENCIL_TEST_LESSEQUAL;
280 break;
281 case GL_GREATER:
282 z |= R128_STENCIL_TEST_GREATER;
283 break;
284 case GL_NOTEQUAL:
285 z |= R128_STENCIL_TEST_NEQUAL;
286 break;
287 case GL_GEQUAL:
288 z |= R128_STENCIL_TEST_GREATEREQUAL;
289 break;
290 case GL_ALWAYS:
291 z |= R128_STENCIL_TEST_ALWAYS;
292 break;
293 }
294
295 if ( rmesa->setup.sten_ref_mask_c != refmask ) {
296 rmesa->setup.sten_ref_mask_c = refmask;
297 rmesa->dirty |= R128_UPLOAD_MASKS;
298 }
299 if ( rmesa->setup.z_sten_cntl_c != z ) {
300 rmesa->setup.z_sten_cntl_c = z;
301 rmesa->dirty |= R128_UPLOAD_CONTEXT;
302 }
303 }
304
305 static void
306 r128DDStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
307 {
308 r128ContextPtr rmesa = R128_CONTEXT(ctx);
309 GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << 0) |
310 ((ctx->Stencil.ValueMask[0] & 0xff) << 16) |
311 ((ctx->Stencil.WriteMask[0] & 0xff) << 24));
312
313 if ( rmesa->setup.sten_ref_mask_c != refmask ) {
314 rmesa->setup.sten_ref_mask_c = refmask;
315 rmesa->dirty |= R128_UPLOAD_MASKS;
316 }
317 }
318
319 static void r128DDStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
320 GLenum zfail, GLenum zpass )
321 {
322 r128ContextPtr rmesa = R128_CONTEXT(ctx);
323 GLuint z = rmesa->setup.z_sten_cntl_c;
324
325 if (!( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ))
326 return;
327
328 z &= ~(R128_STENCIL_S_FAIL_MASK | R128_STENCIL_ZPASS_MASK |
329 R128_STENCIL_ZFAIL_MASK);
330
331 switch ( ctx->Stencil.FailFunc[0] ) {
332 case GL_KEEP:
333 z |= R128_STENCIL_S_FAIL_KEEP;
334 break;
335 case GL_ZERO:
336 z |= R128_STENCIL_S_FAIL_ZERO;
337 break;
338 case GL_REPLACE:
339 z |= R128_STENCIL_S_FAIL_REPLACE;
340 break;
341 case GL_INCR:
342 z |= R128_STENCIL_S_FAIL_INC;
343 break;
344 case GL_DECR:
345 z |= R128_STENCIL_S_FAIL_DEC;
346 break;
347 case GL_INVERT:
348 z |= R128_STENCIL_S_FAIL_INV;
349 break;
350 case GL_INCR_WRAP:
351 z |= R128_STENCIL_S_FAIL_INC_WRAP;
352 break;
353 case GL_DECR_WRAP:
354 z |= R128_STENCIL_S_FAIL_DEC_WRAP;
355 break;
356 }
357
358 switch ( ctx->Stencil.ZFailFunc[0] ) {
359 case GL_KEEP:
360 z |= R128_STENCIL_ZFAIL_KEEP;
361 break;
362 case GL_ZERO:
363 z |= R128_STENCIL_ZFAIL_ZERO;
364 break;
365 case GL_REPLACE:
366 z |= R128_STENCIL_ZFAIL_REPLACE;
367 break;
368 case GL_INCR:
369 z |= R128_STENCIL_ZFAIL_INC;
370 break;
371 case GL_DECR:
372 z |= R128_STENCIL_ZFAIL_DEC;
373 break;
374 case GL_INVERT:
375 z |= R128_STENCIL_ZFAIL_INV;
376 break;
377 case GL_INCR_WRAP:
378 z |= R128_STENCIL_ZFAIL_INC_WRAP;
379 break;
380 case GL_DECR_WRAP:
381 z |= R128_STENCIL_ZFAIL_DEC_WRAP;
382 break;
383 }
384
385 switch ( ctx->Stencil.ZPassFunc[0] ) {
386 case GL_KEEP:
387 z |= R128_STENCIL_ZPASS_KEEP;
388 break;
389 case GL_ZERO:
390 z |= R128_STENCIL_ZPASS_ZERO;
391 break;
392 case GL_REPLACE:
393 z |= R128_STENCIL_ZPASS_REPLACE;
394 break;
395 case GL_INCR:
396 z |= R128_STENCIL_ZPASS_INC;
397 break;
398 case GL_DECR:
399 z |= R128_STENCIL_ZPASS_DEC;
400 break;
401 case GL_INVERT:
402 z |= R128_STENCIL_ZPASS_INV;
403 break;
404 case GL_INCR_WRAP:
405 z |= R128_STENCIL_ZPASS_INC_WRAP;
406 break;
407 case GL_DECR_WRAP:
408 z |= R128_STENCIL_ZPASS_DEC_WRAP;
409 break;
410 }
411
412 if ( rmesa->setup.z_sten_cntl_c != z ) {
413 rmesa->setup.z_sten_cntl_c = z;
414 rmesa->dirty |= R128_UPLOAD_CONTEXT;
415 }
416 }
417
418 static void r128DDClearStencil( GLcontext *ctx, GLint s )
419 {
420 r128ContextPtr rmesa = R128_CONTEXT(ctx);
421
422 if (ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24) {
423 rmesa->ClearDepth &= 0x00ffffff;
424 rmesa->ClearDepth |= ctx->Stencil.Clear << 24;
425 }
426 }
427
428 /* =============================================================
429 * Depth testing
430 */
431
432 static void r128UpdateZMode( GLcontext *ctx )
433 {
434 r128ContextPtr rmesa = R128_CONTEXT(ctx);
435 GLuint z = rmesa->setup.z_sten_cntl_c;
436 GLuint t = rmesa->setup.tex_cntl_c;
437
438 if ( ctx->Depth.Test ) {
439 z &= ~R128_Z_TEST_MASK;
440
441 switch ( ctx->Depth.Func ) {
442 case GL_NEVER:
443 z |= R128_Z_TEST_NEVER;
444 break;
445 case GL_ALWAYS:
446 z |= R128_Z_TEST_ALWAYS;
447 break;
448 case GL_LESS:
449 z |= R128_Z_TEST_LESS;
450 break;
451 case GL_LEQUAL:
452 z |= R128_Z_TEST_LESSEQUAL;
453 break;
454 case GL_EQUAL:
455 z |= R128_Z_TEST_EQUAL;
456 break;
457 case GL_GEQUAL:
458 z |= R128_Z_TEST_GREATEREQUAL;
459 break;
460 case GL_GREATER:
461 z |= R128_Z_TEST_GREATER;
462 break;
463 case GL_NOTEQUAL:
464 z |= R128_Z_TEST_NEQUAL;
465 break;
466 }
467
468 t |= R128_Z_ENABLE;
469 } else {
470 t &= ~R128_Z_ENABLE;
471 }
472
473 if ( ctx->Depth.Mask ) {
474 t |= R128_Z_WRITE_ENABLE;
475 } else {
476 t &= ~R128_Z_WRITE_ENABLE;
477 }
478
479 if ( rmesa->setup.z_sten_cntl_c != z ) {
480 rmesa->setup.z_sten_cntl_c = z;
481 rmesa->dirty |= R128_UPLOAD_CONTEXT;
482 }
483 if ( rmesa->setup.tex_cntl_c != t ) {
484 rmesa->setup.tex_cntl_c = t;
485 rmesa->dirty |= R128_UPLOAD_CONTEXT;
486 }
487 }
488
489 static void r128DDDepthFunc( GLcontext *ctx, GLenum func )
490 {
491 r128ContextPtr rmesa = R128_CONTEXT(ctx);
492
493 FLUSH_BATCH( rmesa );
494 rmesa->new_state |= R128_NEW_DEPTH;
495 }
496
497 static void r128DDDepthMask( GLcontext *ctx, GLboolean flag )
498 {
499 r128ContextPtr rmesa = R128_CONTEXT(ctx);
500
501 FLUSH_BATCH( rmesa );
502 rmesa->new_state |= R128_NEW_DEPTH;
503 }
504
505 static void r128DDClearDepth( GLcontext *ctx, GLclampd d )
506 {
507 r128ContextPtr rmesa = R128_CONTEXT(ctx);
508
509 switch ( rmesa->setup.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK ) {
510 case R128_Z_PIX_WIDTH_16:
511 rmesa->ClearDepth = d * 0x0000ffff;
512 break;
513 case R128_Z_PIX_WIDTH_24:
514 rmesa->ClearDepth = d * 0x00ffffff;
515 rmesa->ClearDepth |= ctx->Stencil.Clear << 24;
516 break;
517 case R128_Z_PIX_WIDTH_32:
518 rmesa->ClearDepth = d * 0xffffffff;
519 break;
520 }
521 }
522
523
524 /* =============================================================
525 * Fog
526 */
527
528 static void r128UpdateFogAttrib( GLcontext *ctx )
529 {
530 r128ContextPtr rmesa = R128_CONTEXT(ctx);
531 GLuint t = rmesa->setup.tex_cntl_c;
532 GLubyte c[4];
533 GLuint col;
534
535 if ( ctx->Fog.Enabled ) {
536 t |= R128_FOG_ENABLE;
537 } else {
538 t &= ~R128_FOG_ENABLE;
539 }
540
541 c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
542 c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
543 c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
544
545 col = r128PackColor( 4, c[0], c[1], c[2], 0 );
546
547 if ( rmesa->setup.fog_color_c != col ) {
548 rmesa->setup.fog_color_c = col;
549 rmesa->dirty |= R128_UPLOAD_CONTEXT;
550 }
551 if ( rmesa->setup.tex_cntl_c != t ) {
552 rmesa->setup.tex_cntl_c = t;
553 rmesa->dirty |= R128_UPLOAD_CONTEXT;
554 }
555 }
556
557 static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
558 {
559 r128ContextPtr rmesa = R128_CONTEXT(ctx);
560
561 FLUSH_BATCH( rmesa );
562 rmesa->new_state |= R128_NEW_FOG;
563 }
564
565
566 /* =============================================================
567 * Clipping
568 */
569
570 static void r128UpdateClipping( GLcontext *ctx )
571 {
572 r128ContextPtr rmesa = R128_CONTEXT(ctx);
573
574 if ( rmesa->driDrawable ) {
575 __DRIdrawable *drawable = rmesa->driDrawable;
576 int x1 = 0;
577 int y1 = 0;
578 int x2 = drawable->w - 1;
579 int y2 = drawable->h - 1;
580
581 if ( ctx->Scissor.Enabled ) {
582 if ( ctx->Scissor.X > x1 ) {
583 x1 = ctx->Scissor.X;
584 }
585 if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y1 ) {
586 y1 = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height;
587 }
588 if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < x2 ) {
589 x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
590 }
591 if ( drawable->h - ctx->Scissor.Y - 1 < y2 ) {
592 y2 = drawable->h - ctx->Scissor.Y - 1;
593 }
594 }
595
596 x1 += drawable->x;
597 y1 += drawable->y;
598 x2 += drawable->x;
599 y2 += drawable->y;
600
601 /* Clamp values to screen to avoid wrapping problems */
602 if ( x1 < 0 )
603 x1 = 0;
604 else if ( x1 >= rmesa->driScreen->fbWidth )
605 x1 = rmesa->driScreen->fbWidth - 1;
606 if ( y1 < 0 )
607 y1 = 0;
608 else if ( y1 >= rmesa->driScreen->fbHeight )
609 y1 = rmesa->driScreen->fbHeight - 1;
610 if ( x2 < 0 )
611 x2 = 0;
612 else if ( x2 >= rmesa->driScreen->fbWidth )
613 x2 = rmesa->driScreen->fbWidth - 1;
614 if ( y2 < 0 )
615 y2 = 0;
616 else if ( y2 >= rmesa->driScreen->fbHeight )
617 y2 = rmesa->driScreen->fbHeight - 1;
618
619 rmesa->setup.sc_top_left_c = (((y1 & 0x3FFF) << 16) | (x1 & 0x3FFF));
620 rmesa->setup.sc_bottom_right_c = (((y2 & 0x3FFF) << 16) | (x2 & 0x3FFF));
621
622 rmesa->dirty |= R128_UPLOAD_CONTEXT;
623 }
624 }
625
626 static void r128DDScissor( GLcontext *ctx,
627 GLint x, GLint y, GLsizei w, GLsizei h )
628 {
629 r128ContextPtr rmesa = R128_CONTEXT(ctx);
630
631 FLUSH_BATCH( rmesa );
632 rmesa->new_state |= R128_NEW_CLIP;
633 }
634
635
636 /* =============================================================
637 * Culling
638 */
639
640 static void r128UpdateCull( GLcontext *ctx )
641 {
642 r128ContextPtr rmesa = R128_CONTEXT(ctx);
643 GLuint f = rmesa->setup.pm4_vc_fpu_setup;
644
645 f &= ~R128_FRONT_DIR_MASK;
646
647 switch ( ctx->Polygon.FrontFace ) {
648 case GL_CW:
649 f |= R128_FRONT_DIR_CW;
650 break;
651 case GL_CCW:
652 f |= R128_FRONT_DIR_CCW;
653 break;
654 }
655
656 f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID;
657
658 if ( ctx->Polygon.CullFlag ) {
659 switch ( ctx->Polygon.CullFaceMode ) {
660 case GL_FRONT:
661 f &= ~R128_FRONTFACE_SOLID;
662 break;
663 case GL_BACK:
664 f &= ~R128_BACKFACE_SOLID;
665 break;
666 case GL_FRONT_AND_BACK:
667 f &= ~(R128_BACKFACE_SOLID |
668 R128_FRONTFACE_SOLID);
669 break;
670 }
671 }
672
673 if ( 1 || rmesa->setup.pm4_vc_fpu_setup != f ) {
674 rmesa->setup.pm4_vc_fpu_setup = f;
675 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP;
676 }
677 }
678
679 static void r128DDCullFace( GLcontext *ctx, GLenum mode )
680 {
681 r128ContextPtr rmesa = R128_CONTEXT(ctx);
682
683 FLUSH_BATCH( rmesa );
684 rmesa->new_state |= R128_NEW_CULL;
685 }
686
687 static void r128DDFrontFace( GLcontext *ctx, GLenum mode )
688 {
689 r128ContextPtr rmesa = R128_CONTEXT(ctx);
690
691 FLUSH_BATCH( rmesa );
692 rmesa->new_state |= R128_NEW_CULL;
693 }
694
695
696 /* =============================================================
697 * Masks
698 */
699
700 static void r128UpdateMasks( GLcontext *ctx )
701 {
702 r128ContextPtr rmesa = R128_CONTEXT(ctx);
703
704 GLuint mask = r128PackColor( rmesa->r128Screen->cpp,
705 ctx->Color.ColorMask[0][RCOMP],
706 ctx->Color.ColorMask[0][GCOMP],
707 ctx->Color.ColorMask[0][BCOMP],
708 ctx->Color.ColorMask[0][ACOMP] );
709
710 if ( rmesa->setup.plane_3d_mask_c != mask ) {
711 rmesa->setup.plane_3d_mask_c = mask;
712 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
713 }
714 }
715
716 static void r128DDColorMask( GLcontext *ctx,
717 GLboolean r, GLboolean g,
718 GLboolean b, GLboolean a )
719 {
720 r128ContextPtr rmesa = R128_CONTEXT(ctx);
721
722 FLUSH_BATCH( rmesa );
723 rmesa->new_state |= R128_NEW_MASKS;
724 }
725
726
727 /* =============================================================
728 * Rendering attributes
729 *
730 * We really don't want to recalculate all this every time we bind a
731 * texture. These things shouldn't change all that often, so it makes
732 * sense to break them out of the core texture state update routines.
733 */
734
735 static void updateSpecularLighting( GLcontext *ctx )
736 {
737 r128ContextPtr rmesa = R128_CONTEXT(ctx);
738 GLuint t = rmesa->setup.tex_cntl_c;
739
740 if ( NEED_SECONDARY_COLOR( ctx ) ) {
741 if (ctx->Light.ShadeModel == GL_FLAT) {
742 /* R128 can't do flat-shaded separate specular */
743 t &= ~R128_SPEC_LIGHT_ENABLE;
744 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_TRUE );
745 }
746 else {
747 t |= R128_SPEC_LIGHT_ENABLE;
748 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE );
749 }
750 }
751 else {
752 t &= ~R128_SPEC_LIGHT_ENABLE;
753 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE );
754 }
755
756 if ( rmesa->setup.tex_cntl_c != t ) {
757 rmesa->setup.tex_cntl_c = t;
758 rmesa->dirty |= R128_UPLOAD_CONTEXT;
759 rmesa->dirty |= R128_UPLOAD_SETUP;
760 rmesa->new_state |= R128_NEW_CONTEXT;
761 }
762 }
763
764
765 static void r128DDLightModelfv( GLcontext *ctx, GLenum pname,
766 const GLfloat *param )
767 {
768 r128ContextPtr rmesa = R128_CONTEXT(ctx);
769
770 if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
771 FLUSH_BATCH( rmesa );
772 updateSpecularLighting(ctx);
773 }
774
775 if ( pname == GL_LIGHT_MODEL_TWO_SIDE ) {
776 FLUSH_BATCH( rmesa );
777 r128ChooseRenderState( ctx );
778 }
779 }
780
781 static void r128DDShadeModel( GLcontext *ctx, GLenum mode )
782 {
783 r128ContextPtr rmesa = R128_CONTEXT(ctx);
784 GLuint s = rmesa->setup.pm4_vc_fpu_setup;
785
786 s &= ~R128_FPU_COLOR_MASK;
787
788 switch ( mode ) {
789 case GL_FLAT:
790 s |= R128_FPU_COLOR_FLAT;
791 break;
792 case GL_SMOOTH:
793 s |= R128_FPU_COLOR_GOURAUD;
794 break;
795 default:
796 return;
797 }
798
799 updateSpecularLighting(ctx);
800
801 if ( rmesa->setup.pm4_vc_fpu_setup != s ) {
802 FLUSH_BATCH( rmesa );
803 rmesa->setup.pm4_vc_fpu_setup = s;
804
805 rmesa->new_state |= R128_NEW_CONTEXT;
806 rmesa->dirty |= R128_UPLOAD_SETUP;
807 }
808 }
809
810
811 /* =============================================================
812 * Window position
813 */
814
815 static void r128UpdateWindow( GLcontext *ctx )
816 {
817 r128ContextPtr rmesa = R128_CONTEXT(ctx);
818 int x = rmesa->driDrawable->x;
819 int y = rmesa->driDrawable->y;
820 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
821 driRenderbuffer *drb = (driRenderbuffer *) rb;
822
823 rmesa->setup.window_xy_offset = (((y & 0xFFF) << R128_WINDOW_Y_SHIFT) |
824 ((x & 0xFFF) << R128_WINDOW_X_SHIFT));
825
826 rmesa->setup.dst_pitch_offset_c = (((drb->flippedPitch/8) << 21) |
827 (drb->flippedOffset >> 5));
828
829
830 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW;
831 }
832
833
834 /* =============================================================
835 * Viewport
836 */
837
838 static void r128CalcViewport( GLcontext *ctx )
839 {
840 r128ContextPtr rmesa = R128_CONTEXT(ctx);
841 const GLfloat *v = ctx->Viewport._WindowMap.m;
842 GLfloat *m = rmesa->hw_viewport;
843
844 /* See also r128_translate_vertex.
845 */
846 m[MAT_SX] = v[MAT_SX];
847 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
848 m[MAT_SY] = - v[MAT_SY];
849 m[MAT_TY] = - v[MAT_TY] + rmesa->driDrawable->h + SUBPIXEL_Y;
850 m[MAT_SZ] = v[MAT_SZ] * rmesa->depth_scale;
851 m[MAT_TZ] = v[MAT_TZ] * rmesa->depth_scale;
852 }
853
854 static void r128Viewport( GLcontext *ctx,
855 GLint x, GLint y,
856 GLsizei width, GLsizei height )
857 {
858 r128CalcViewport( ctx );
859 }
860
861 static void r128DepthRange( GLcontext *ctx,
862 GLclampd nearval, GLclampd farval )
863 {
864 r128CalcViewport( ctx );
865 }
866
867
868 /* =============================================================
869 * Miscellaneous
870 */
871
872 static void r128DDClearColor( GLcontext *ctx,
873 const GLfloat color[4] )
874 {
875 r128ContextPtr rmesa = R128_CONTEXT(ctx);
876 GLubyte c[4];
877
878 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
879 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
880 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
881 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
882
883 rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp,
884 c[0], c[1], c[2], c[3] );
885 }
886
887 static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode )
888 {
889 r128ContextPtr rmesa = R128_CONTEXT(ctx);
890
891 if ( ctx->Color.ColorLogicOpEnabled ) {
892 FLUSH_BATCH( rmesa );
893
894 FALLBACK( rmesa, R128_FALLBACK_LOGICOP, opcode != GL_COPY );
895 }
896 }
897
898 static void r128DDDrawBuffer( GLcontext *ctx, GLenum mode )
899 {
900 r128ContextPtr rmesa = R128_CONTEXT(ctx);
901
902 FLUSH_BATCH( rmesa );
903
904 if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
905 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
906 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
907 return;
908 }
909 else {
910 switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
911 case BUFFER_FRONT_LEFT:
912 case BUFFER_BACK_LEFT:
913 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE );
914 break;
915 default:
916 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
917 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
918 break;
919 }
920 }
921
922 rmesa->new_state |= R128_NEW_WINDOW;
923 }
924
925 static void r128DDReadBuffer( GLcontext *ctx, GLenum mode )
926 {
927 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
928 }
929
930
931 /* =============================================================
932 * Polygon stipple
933 */
934
935 static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
936 {
937 r128ContextPtr rmesa = R128_CONTEXT(ctx);
938 GLuint stipple[32], i;
939 drm_r128_stipple_t stippleRec;
940
941 for (i = 0; i < 32; i++) {
942 stipple[31 - i] = ((mask[i*4+0] << 24) |
943 (mask[i*4+1] << 16) |
944 (mask[i*4+2] << 8) |
945 (mask[i*4+3]));
946 }
947
948 FLUSH_BATCH( rmesa );
949 LOCK_HARDWARE( rmesa );
950
951 stippleRec.mask = stipple;
952 drmCommandWrite( rmesa->driFd, DRM_R128_STIPPLE,
953 &stippleRec, sizeof(stippleRec) );
954
955 UNLOCK_HARDWARE( rmesa );
956
957 rmesa->new_state |= R128_NEW_CONTEXT;
958 rmesa->dirty |= R128_UPLOAD_CONTEXT;
959 }
960
961
962 /* =============================================================
963 * Render mode
964 */
965
966 static void r128DDRenderMode( GLcontext *ctx, GLenum mode )
967 {
968 r128ContextPtr rmesa = R128_CONTEXT(ctx);
969 FALLBACK( rmesa, R128_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
970 }
971
972
973
974 /* =============================================================
975 * State enable/disable
976 */
977
978 static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
979 {
980 r128ContextPtr rmesa = R128_CONTEXT(ctx);
981
982 if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
983 fprintf( stderr, "%s( %s = %s )\n",
984 __FUNCTION__, _mesa_lookup_enum_by_nr( cap ),
985 state ? "GL_TRUE" : "GL_FALSE" );
986 }
987
988 switch ( cap ) {
989 case GL_ALPHA_TEST:
990 FLUSH_BATCH( rmesa );
991 rmesa->new_state |= R128_NEW_ALPHA;
992 break;
993
994 case GL_BLEND:
995 FLUSH_BATCH( rmesa );
996 rmesa->new_state |= R128_NEW_ALPHA;
997
998 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
999 */
1000 FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
1001 (ctx->Color.ColorLogicOpEnabled &&
1002 ctx->Color.LogicOp != GL_COPY));
1003 break;
1004
1005 case GL_CULL_FACE:
1006 FLUSH_BATCH( rmesa );
1007 rmesa->new_state |= R128_NEW_CULL;
1008 break;
1009
1010 case GL_DEPTH_TEST:
1011 FLUSH_BATCH( rmesa );
1012 rmesa->new_state |= R128_NEW_DEPTH;
1013 break;
1014
1015 case GL_DITHER:
1016 do {
1017 GLuint t = rmesa->setup.tex_cntl_c;
1018 FLUSH_BATCH( rmesa );
1019
1020 if ( ctx->Color.DitherFlag ) {
1021 t |= R128_DITHER_ENABLE;
1022 } else {
1023 t &= ~R128_DITHER_ENABLE;
1024 }
1025
1026 if ( rmesa->setup.tex_cntl_c != t ) {
1027 rmesa->setup.tex_cntl_c = t;
1028 rmesa->dirty |= R128_UPLOAD_CONTEXT;
1029 }
1030 } while (0);
1031 break;
1032
1033 case GL_FOG:
1034 FLUSH_BATCH( rmesa );
1035 rmesa->new_state |= R128_NEW_FOG;
1036 break;
1037
1038 case GL_COLOR_LOGIC_OP:
1039 FLUSH_BATCH( rmesa );
1040 FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
1041 state && ctx->Color.LogicOp != GL_COPY );
1042 break;
1043
1044 case GL_LIGHTING:
1045 case GL_COLOR_SUM_EXT:
1046 updateSpecularLighting(ctx);
1047 break;
1048
1049 case GL_SCISSOR_TEST:
1050 FLUSH_BATCH( rmesa );
1051 rmesa->scissor = state;
1052 rmesa->new_state |= R128_NEW_CLIP;
1053 break;
1054
1055 case GL_STENCIL_TEST:
1056 FLUSH_BATCH( rmesa );
1057 if ( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ) {
1058 if ( state ) {
1059 rmesa->setup.tex_cntl_c |= R128_STENCIL_ENABLE;
1060 /* Reset the fallback (if any) for bad stencil funcs */
1061 r128DDStencilOpSeparate( ctx, 0, ctx->Stencil.FailFunc[0],
1062 ctx->Stencil.ZFailFunc[0],
1063 ctx->Stencil.ZPassFunc[0] );
1064 } else {
1065 rmesa->setup.tex_cntl_c &= ~R128_STENCIL_ENABLE;
1066 FALLBACK( rmesa, R128_FALLBACK_STENCIL, GL_FALSE );
1067 }
1068 rmesa->dirty |= R128_UPLOAD_CONTEXT;
1069 } else {
1070 FALLBACK( rmesa, R128_FALLBACK_STENCIL, state );
1071 }
1072 break;
1073
1074 case GL_TEXTURE_1D:
1075 case GL_TEXTURE_2D:
1076 case GL_TEXTURE_3D:
1077 FLUSH_BATCH( rmesa );
1078 break;
1079
1080 case GL_POLYGON_STIPPLE:
1081 if ( rmesa->render_primitive == GL_TRIANGLES ) {
1082 FLUSH_BATCH( rmesa );
1083 rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
1084 if ( state ) {
1085 rmesa->setup.dp_gui_master_cntl_c |=
1086 R128_GMC_BRUSH_32x32_MONO_FG_LA;
1087 } else {
1088 rmesa->setup.dp_gui_master_cntl_c |=
1089 R128_GMC_BRUSH_SOLID_COLOR;
1090 }
1091 rmesa->new_state |= R128_NEW_CONTEXT;
1092 rmesa->dirty |= R128_UPLOAD_CONTEXT;
1093 }
1094 break;
1095
1096 default:
1097 return;
1098 }
1099 }
1100
1101
1102 /* =============================================================
1103 * State initialization, management
1104 */
1105
1106 static void r128DDPrintDirty( const char *msg, GLuint state )
1107 {
1108 fprintf( stderr,
1109 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
1110 msg,
1111 state,
1112 (state & R128_UPLOAD_CORE) ? "core, " : "",
1113 (state & R128_UPLOAD_CONTEXT) ? "context, " : "",
1114 (state & R128_UPLOAD_SETUP) ? "setup, " : "",
1115 (state & R128_UPLOAD_TEX0) ? "tex0, " : "",
1116 (state & R128_UPLOAD_TEX1) ? "tex1, " : "",
1117 (state & R128_UPLOAD_MASKS) ? "masks, " : "",
1118 (state & R128_UPLOAD_WINDOW) ? "window, " : "",
1119 (state & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
1120 (state & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
1121 }
1122
1123 /*
1124 * Load the current context's state into the hardware.
1125 *
1126 * NOTE: Be VERY careful about ensuring the context state is marked for
1127 * upload, the only place it shouldn't be uploaded is when the setup
1128 * state has changed in ReducedPrimitiveChange as this comes right after
1129 * a state update.
1130 *
1131 * Blits of any type should always upload the context and masks after
1132 * they are done.
1133 */
1134 void r128EmitHwStateLocked( r128ContextPtr rmesa )
1135 {
1136 drm_r128_sarea_t *sarea = rmesa->sarea;
1137 drm_r128_context_regs_t *regs = &(rmesa->setup);
1138 const r128TexObjPtr t0 = rmesa->CurrentTexObj[0];
1139 const r128TexObjPtr t1 = rmesa->CurrentTexObj[1];
1140
1141 if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) {
1142 r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty );
1143 }
1144
1145 if ( rmesa->dirty & (R128_UPLOAD_CONTEXT |
1146 R128_UPLOAD_SETUP |
1147 R128_UPLOAD_MASKS |
1148 R128_UPLOAD_WINDOW |
1149 R128_UPLOAD_CORE) ) {
1150 memcpy( &sarea->context_state, regs, sizeof(sarea->context_state) );
1151
1152 if( rmesa->dirty & R128_UPLOAD_CONTEXT )
1153 {
1154 /* One possible side-effect of uploading a new context is the
1155 * setting of the R128_GMC_AUX_CLIP_DIS bit, which causes all
1156 * auxilliary cliprects to be disabled. So the next command must
1157 * upload them again. */
1158 rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
1159 }
1160 }
1161
1162 if ( (rmesa->dirty & R128_UPLOAD_TEX0) && t0 ) {
1163 drm_r128_texture_regs_t *tex = &sarea->tex_state[0];
1164
1165 tex->tex_cntl = t0->setup.tex_cntl;
1166 tex->tex_combine_cntl = rmesa->tex_combine[0];
1167 tex->tex_size_pitch = t0->setup.tex_size_pitch;
1168 memcpy( &tex->tex_offset[0], &t0->setup.tex_offset[0],
1169 sizeof(tex->tex_offset ) );
1170 tex->tex_border_color = t0->setup.tex_border_color;
1171 }
1172
1173 if ( (rmesa->dirty & R128_UPLOAD_TEX1) && t1 ) {
1174 drm_r128_texture_regs_t *tex = &sarea->tex_state[1];
1175
1176 tex->tex_cntl = t1->setup.tex_cntl;
1177 tex->tex_combine_cntl = rmesa->tex_combine[1];
1178 tex->tex_size_pitch = t1->setup.tex_size_pitch;
1179 memcpy( &tex->tex_offset[0], &t1->setup.tex_offset[0],
1180 sizeof(tex->tex_offset ) );
1181 tex->tex_border_color = t1->setup.tex_border_color;
1182 }
1183
1184 sarea->vertsize = rmesa->vertex_size;
1185 sarea->vc_format = rmesa->vertex_format;
1186
1187 /* Turn off the texture cache flushing */
1188 rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
1189
1190 sarea->dirty |= rmesa->dirty;
1191 rmesa->dirty &= R128_UPLOAD_CLIPRECTS;
1192 }
1193
1194 static void r128DDPrintState( const char *msg, GLuint flags )
1195 {
1196 fprintf( stderr,
1197 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
1198 msg,
1199 flags,
1200 (flags & R128_NEW_CONTEXT) ? "context, " : "",
1201 (flags & R128_NEW_ALPHA) ? "alpha, " : "",
1202 (flags & R128_NEW_DEPTH) ? "depth, " : "",
1203 (flags & R128_NEW_FOG) ? "fog, " : "",
1204 (flags & R128_NEW_CLIP) ? "clip, " : "",
1205 (flags & R128_NEW_CULL) ? "cull, " : "",
1206 (flags & R128_NEW_MASKS) ? "masks, " : "",
1207 (flags & R128_NEW_WINDOW) ? "window, " : "" );
1208 }
1209
1210 void r128DDUpdateHWState( GLcontext *ctx )
1211 {
1212 r128ContextPtr rmesa = R128_CONTEXT(ctx);
1213 int new_state = rmesa->new_state;
1214
1215 if ( new_state || rmesa->NewGLState & _NEW_TEXTURE )
1216 {
1217 FLUSH_BATCH( rmesa );
1218
1219 rmesa->new_state = 0;
1220
1221 if ( R128_DEBUG & DEBUG_VERBOSE_MSG )
1222 r128DDPrintState( "r128UpdateHwState", new_state );
1223
1224 /* Update the various parts of the context's state.
1225 */
1226 if ( new_state & R128_NEW_ALPHA )
1227 r128UpdateAlphaMode( ctx );
1228
1229 if ( new_state & R128_NEW_DEPTH )
1230 r128UpdateZMode( ctx );
1231
1232 if ( new_state & R128_NEW_FOG )
1233 r128UpdateFogAttrib( ctx );
1234
1235 if ( new_state & R128_NEW_CLIP )
1236 r128UpdateClipping( ctx );
1237
1238 if ( new_state & R128_NEW_CULL )
1239 r128UpdateCull( ctx );
1240
1241 if ( new_state & R128_NEW_MASKS )
1242 r128UpdateMasks( ctx );
1243
1244 if ( new_state & R128_NEW_WINDOW )
1245 {
1246 r128UpdateWindow( ctx );
1247 r128CalcViewport( ctx );
1248 }
1249
1250 if ( rmesa->NewGLState & _NEW_TEXTURE ) {
1251 r128UpdateTextureState( ctx );
1252 }
1253 }
1254 }
1255
1256
1257 static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state )
1258 {
1259 _swrast_InvalidateState( ctx, new_state );
1260 _swsetup_InvalidateState( ctx, new_state );
1261 _vbo_InvalidateState( ctx, new_state );
1262 _tnl_InvalidateState( ctx, new_state );
1263 R128_CONTEXT(ctx)->NewGLState |= new_state;
1264 }
1265
1266
1267
1268 /* Initialize the context's hardware state.
1269 */
1270 void r128DDInitState( r128ContextPtr rmesa )
1271 {
1272 int dst_bpp, depth_bpp;
1273
1274 switch ( rmesa->r128Screen->cpp ) {
1275 case 2:
1276 dst_bpp = R128_GMC_DST_16BPP;
1277 break;
1278 case 4:
1279 dst_bpp = R128_GMC_DST_32BPP;
1280 break;
1281 default:
1282 fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
1283 exit( -1 );
1284 }
1285
1286 rmesa->ClearColor = 0x00000000;
1287
1288 switch ( rmesa->glCtx->Visual.depthBits ) {
1289 case 16:
1290 rmesa->ClearDepth = 0x0000ffff;
1291 depth_bpp = R128_Z_PIX_WIDTH_16;
1292 rmesa->depth_scale = 1.0 / (GLfloat)0xffff;
1293 break;
1294 case 24:
1295 rmesa->ClearDepth = 0x00ffffff;
1296 depth_bpp = R128_Z_PIX_WIDTH_24;
1297 rmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
1298 break;
1299 default:
1300 fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
1301 rmesa->glCtx->Visual.depthBits );
1302 exit( -1 );
1303 }
1304
1305 rmesa->Fallback = 0;
1306
1307 /* Hardware state:
1308 */
1309 rmesa->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL |
1310 R128_GMC_DST_CLIPPING |
1311 R128_GMC_BRUSH_SOLID_COLOR |
1312 dst_bpp |
1313 R128_GMC_SRC_DATATYPE_COLOR |
1314 R128_GMC_BYTE_MSB_TO_LSB |
1315 R128_GMC_CONVERSION_TEMP_6500 |
1316 R128_ROP3_S |
1317 R128_DP_SRC_SOURCE_MEMORY |
1318 R128_GMC_3D_FCN_EN |
1319 R128_GMC_CLR_CMP_CNTL_DIS |
1320 R128_GMC_AUX_CLIP_DIS |
1321 R128_GMC_WR_MSK_DIS);
1322
1323 rmesa->setup.sc_top_left_c = 0x00000000;
1324 rmesa->setup.sc_bottom_right_c = 0x1fff1fff;
1325
1326 rmesa->setup.z_offset_c = rmesa->r128Screen->depthOffset;
1327 rmesa->setup.z_pitch_c = ((rmesa->r128Screen->depthPitch >> 3) |
1328 R128_Z_TILE);
1329
1330 rmesa->setup.z_sten_cntl_c = (depth_bpp |
1331 R128_Z_TEST_LESS |
1332 R128_STENCIL_TEST_ALWAYS |
1333 R128_STENCIL_S_FAIL_KEEP |
1334 R128_STENCIL_ZPASS_KEEP |
1335 R128_STENCIL_ZFAIL_KEEP);
1336
1337 rmesa->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE |
1338 R128_SHADE_ENABLE |
1339 R128_DITHER_ENABLE |
1340 R128_ALPHA_IN_TEX_COMPLETE_A |
1341 R128_LIGHT_DIS |
1342 R128_ALPHA_LIGHT_DIS |
1343 R128_TEX_CACHE_FLUSH |
1344 (0x3f << R128_LOD_BIAS_SHIFT));
1345
1346 rmesa->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE |
1347 R128_MISC_SCALE_PIX_REPLICATE |
1348 R128_ALPHA_COMB_ADD_CLAMP |
1349 R128_FOG_VERTEX |
1350 (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1351 (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1352 R128_ALPHA_TEST_ALWAYS);
1353
1354 rmesa->setup.texture_clr_cmp_clr_c = 0x00000000;
1355 rmesa->setup.texture_clr_cmp_msk_c = 0xffffffff;
1356
1357 rmesa->setup.fog_color_c = 0x00000000;
1358
1359 rmesa->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW |
1360 R128_BACKFACE_SOLID |
1361 R128_FRONTFACE_SOLID |
1362 R128_FPU_COLOR_GOURAUD |
1363 R128_FPU_SUB_PIX_4BITS |
1364 R128_FPU_MODE_3D |
1365 R128_TRAP_BITS_DISABLE |
1366 R128_XFACTOR_2 |
1367 R128_YFACTOR_2 |
1368 R128_FLAT_SHADE_VERTEX_OGL |
1369 R128_FPU_ROUND_TRUNCATE |
1370 R128_WM_SEL_8DW);
1371
1372 rmesa->setup.setup_cntl = (R128_COLOR_GOURAUD |
1373 R128_PRIM_TYPE_TRI |
1374 R128_TEXTURE_ST_MULT_W |
1375 R128_STARTING_VERTEX_1 |
1376 R128_ENDING_VERTEX_3 |
1377 R128_SU_POLY_LINE_NOT_LAST |
1378 R128_SUB_PIX_4BITS);
1379
1380 rmesa->setup.tex_size_pitch_c = 0x00000000;
1381 rmesa->setup.constant_color_c = 0x00ffffff;
1382
1383 rmesa->setup.dp_write_mask = 0xffffffff;
1384 rmesa->setup.sten_ref_mask_c = 0xffff0000;
1385 rmesa->setup.plane_3d_mask_c = 0xffffffff;
1386
1387 rmesa->setup.window_xy_offset = 0x00000000;
1388
1389 rmesa->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE |
1390 R128_TEX_CACHE_SIZE_FULL |
1391 R128_DITHER_INIT_RESET |
1392 R128_SCALE_3D_TEXMAP_SHADE |
1393 R128_SCALE_PIX_REPLICATE |
1394 R128_ALPHA_COMB_ADD_CLAMP |
1395 R128_FOG_VERTEX |
1396 (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1397 (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1398 R128_ALPHA_TEST_ALWAYS |
1399 R128_COMPOSITE_SHADOW_CMP_EQUAL |
1400 R128_TEX_MAP_ALPHA_IN_TEXTURE |
1401 R128_TEX_CACHE_LINE_SIZE_4QW);
1402
1403 rmesa->new_state = R128_NEW_ALL;
1404 }
1405
1406 /* Initialize the driver's state functions.
1407 */
1408 void r128DDInitStateFuncs( GLcontext *ctx )
1409 {
1410 ctx->Driver.UpdateState = r128DDInvalidateState;
1411
1412 ctx->Driver.ClearIndex = NULL;
1413 ctx->Driver.ClearColor = r128DDClearColor;
1414 ctx->Driver.ClearStencil = r128DDClearStencil;
1415 ctx->Driver.DrawBuffer = r128DDDrawBuffer;
1416 ctx->Driver.ReadBuffer = r128DDReadBuffer;
1417
1418 ctx->Driver.IndexMask = NULL;
1419 ctx->Driver.ColorMask = r128DDColorMask;
1420 ctx->Driver.AlphaFunc = r128DDAlphaFunc;
1421 ctx->Driver.BlendEquationSeparate = r128DDBlendEquationSeparate;
1422 ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate;
1423 ctx->Driver.ClearDepth = r128DDClearDepth;
1424 ctx->Driver.CullFace = r128DDCullFace;
1425 ctx->Driver.FrontFace = r128DDFrontFace;
1426 ctx->Driver.DepthFunc = r128DDDepthFunc;
1427 ctx->Driver.DepthMask = r128DDDepthMask;
1428 ctx->Driver.Enable = r128DDEnable;
1429 ctx->Driver.Fogfv = r128DDFogfv;
1430 ctx->Driver.Hint = NULL;
1431 ctx->Driver.Lightfv = NULL;
1432 ctx->Driver.LightModelfv = r128DDLightModelfv;
1433 ctx->Driver.LogicOpcode = r128DDLogicOpCode;
1434 ctx->Driver.PolygonMode = NULL;
1435 ctx->Driver.PolygonStipple = r128DDPolygonStipple;
1436 ctx->Driver.RenderMode = r128DDRenderMode;
1437 ctx->Driver.Scissor = r128DDScissor;
1438 ctx->Driver.ShadeModel = r128DDShadeModel;
1439 ctx->Driver.StencilFuncSeparate = r128DDStencilFuncSeparate;
1440 ctx->Driver.StencilMaskSeparate = r128DDStencilMaskSeparate;
1441 ctx->Driver.StencilOpSeparate = r128DDStencilOpSeparate;
1442
1443 ctx->Driver.DepthRange = r128DepthRange;
1444 ctx->Driver.Viewport = r128Viewport;
1445 }