Merge commit 'origin/gallium-0.1'
[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 __DRIdrawablePrivate *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[RCOMP],
706 ctx->Color.ColorMask[GCOMP],
707 ctx->Color.ColorMask[BCOMP],
708 ctx->Color.ColorMask[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
776 static void r128DDShadeModel( GLcontext *ctx, GLenum mode )
777 {
778 r128ContextPtr rmesa = R128_CONTEXT(ctx);
779 GLuint s = rmesa->setup.pm4_vc_fpu_setup;
780
781 s &= ~R128_FPU_COLOR_MASK;
782
783 switch ( mode ) {
784 case GL_FLAT:
785 s |= R128_FPU_COLOR_FLAT;
786 break;
787 case GL_SMOOTH:
788 s |= R128_FPU_COLOR_GOURAUD;
789 break;
790 default:
791 return;
792 }
793
794 updateSpecularLighting(ctx);
795
796 if ( rmesa->setup.pm4_vc_fpu_setup != s ) {
797 FLUSH_BATCH( rmesa );
798 rmesa->setup.pm4_vc_fpu_setup = s;
799
800 rmesa->new_state |= R128_NEW_CONTEXT;
801 rmesa->dirty |= R128_UPLOAD_SETUP;
802 }
803 }
804
805
806 /* =============================================================
807 * Window position
808 */
809
810 static void r128UpdateWindow( GLcontext *ctx )
811 {
812 r128ContextPtr rmesa = R128_CONTEXT(ctx);
813 int x = rmesa->driDrawable->x;
814 int y = rmesa->driDrawable->y;
815 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
816 driRenderbuffer *drb = (driRenderbuffer *) rb;
817
818 rmesa->setup.window_xy_offset = (((y & 0xFFF) << R128_WINDOW_Y_SHIFT) |
819 ((x & 0xFFF) << R128_WINDOW_X_SHIFT));
820
821 rmesa->setup.dst_pitch_offset_c = (((drb->flippedPitch/8) << 21) |
822 (drb->flippedOffset >> 5));
823
824
825 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW;
826 }
827
828
829 /* =============================================================
830 * Viewport
831 */
832
833 static void r128CalcViewport( GLcontext *ctx )
834 {
835 r128ContextPtr rmesa = R128_CONTEXT(ctx);
836 const GLfloat *v = ctx->Viewport._WindowMap.m;
837 GLfloat *m = rmesa->hw_viewport;
838
839 /* See also r128_translate_vertex.
840 */
841 m[MAT_SX] = v[MAT_SX];
842 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
843 m[MAT_SY] = - v[MAT_SY];
844 m[MAT_TY] = - v[MAT_TY] + rmesa->driDrawable->h + SUBPIXEL_Y;
845 m[MAT_SZ] = v[MAT_SZ] * rmesa->depth_scale;
846 m[MAT_TZ] = v[MAT_TZ] * rmesa->depth_scale;
847 }
848
849 static void r128Viewport( GLcontext *ctx,
850 GLint x, GLint y,
851 GLsizei width, GLsizei height )
852 {
853 r128CalcViewport( ctx );
854 }
855
856 static void r128DepthRange( GLcontext *ctx,
857 GLclampd nearval, GLclampd farval )
858 {
859 r128CalcViewport( ctx );
860 }
861
862
863 /* =============================================================
864 * Miscellaneous
865 */
866
867 static void r128DDClearColor( GLcontext *ctx,
868 const GLfloat color[4] )
869 {
870 r128ContextPtr rmesa = R128_CONTEXT(ctx);
871 GLubyte c[4];
872
873 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
874 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
875 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
876 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
877
878 rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp,
879 c[0], c[1], c[2], c[3] );
880 }
881
882 static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode )
883 {
884 r128ContextPtr rmesa = R128_CONTEXT(ctx);
885
886 if ( ctx->Color.ColorLogicOpEnabled ) {
887 FLUSH_BATCH( rmesa );
888
889 FALLBACK( rmesa, R128_FALLBACK_LOGICOP, opcode != GL_COPY );
890 }
891 }
892
893 static void r128DDDrawBuffer( GLcontext *ctx, GLenum mode )
894 {
895 r128ContextPtr rmesa = R128_CONTEXT(ctx);
896
897 FLUSH_BATCH( rmesa );
898
899 if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
900 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
901 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
902 return;
903 }
904 else {
905 switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
906 case BUFFER_FRONT_LEFT:
907 case BUFFER_BACK_LEFT:
908 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE );
909 break;
910 default:
911 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
912 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
913 break;
914 }
915 }
916
917 rmesa->new_state |= R128_NEW_WINDOW;
918 }
919
920 static void r128DDReadBuffer( GLcontext *ctx, GLenum mode )
921 {
922 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
923 }
924
925
926 /* =============================================================
927 * Polygon stipple
928 */
929
930 static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
931 {
932 r128ContextPtr rmesa = R128_CONTEXT(ctx);
933 GLuint stipple[32], i;
934 drm_r128_stipple_t stippleRec;
935
936 for (i = 0; i < 32; i++) {
937 stipple[31 - i] = ((mask[i*4+0] << 24) |
938 (mask[i*4+1] << 16) |
939 (mask[i*4+2] << 8) |
940 (mask[i*4+3]));
941 }
942
943 FLUSH_BATCH( rmesa );
944 LOCK_HARDWARE( rmesa );
945
946 stippleRec.mask = stipple;
947 drmCommandWrite( rmesa->driFd, DRM_R128_STIPPLE,
948 &stippleRec, sizeof(stippleRec) );
949
950 UNLOCK_HARDWARE( rmesa );
951
952 rmesa->new_state |= R128_NEW_CONTEXT;
953 rmesa->dirty |= R128_UPLOAD_CONTEXT;
954 }
955
956
957 /* =============================================================
958 * Render mode
959 */
960
961 static void r128DDRenderMode( GLcontext *ctx, GLenum mode )
962 {
963 r128ContextPtr rmesa = R128_CONTEXT(ctx);
964 FALLBACK( rmesa, R128_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
965 }
966
967
968
969 /* =============================================================
970 * State enable/disable
971 */
972
973 static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
974 {
975 r128ContextPtr rmesa = R128_CONTEXT(ctx);
976
977 if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
978 fprintf( stderr, "%s( %s = %s )\n",
979 __FUNCTION__, _mesa_lookup_enum_by_nr( cap ),
980 state ? "GL_TRUE" : "GL_FALSE" );
981 }
982
983 switch ( cap ) {
984 case GL_ALPHA_TEST:
985 FLUSH_BATCH( rmesa );
986 rmesa->new_state |= R128_NEW_ALPHA;
987 break;
988
989 case GL_BLEND:
990 FLUSH_BATCH( rmesa );
991 rmesa->new_state |= R128_NEW_ALPHA;
992
993 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
994 */
995 FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
996 (ctx->Color.ColorLogicOpEnabled &&
997 ctx->Color.LogicOp != GL_COPY));
998 break;
999
1000 case GL_CULL_FACE:
1001 FLUSH_BATCH( rmesa );
1002 rmesa->new_state |= R128_NEW_CULL;
1003 break;
1004
1005 case GL_DEPTH_TEST:
1006 FLUSH_BATCH( rmesa );
1007 rmesa->new_state |= R128_NEW_DEPTH;
1008 break;
1009
1010 case GL_DITHER:
1011 do {
1012 GLuint t = rmesa->setup.tex_cntl_c;
1013 FLUSH_BATCH( rmesa );
1014
1015 if ( ctx->Color.DitherFlag ) {
1016 t |= R128_DITHER_ENABLE;
1017 } else {
1018 t &= ~R128_DITHER_ENABLE;
1019 }
1020
1021 if ( rmesa->setup.tex_cntl_c != t ) {
1022 rmesa->setup.tex_cntl_c = t;
1023 rmesa->dirty |= R128_UPLOAD_CONTEXT;
1024 }
1025 } while (0);
1026 break;
1027
1028 case GL_FOG:
1029 FLUSH_BATCH( rmesa );
1030 rmesa->new_state |= R128_NEW_FOG;
1031 break;
1032
1033 case GL_COLOR_LOGIC_OP:
1034 FLUSH_BATCH( rmesa );
1035 FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
1036 state && ctx->Color.LogicOp != GL_COPY );
1037 break;
1038
1039 case GL_LIGHTING:
1040 case GL_COLOR_SUM_EXT:
1041 updateSpecularLighting(ctx);
1042 break;
1043
1044 case GL_SCISSOR_TEST:
1045 FLUSH_BATCH( rmesa );
1046 rmesa->scissor = state;
1047 rmesa->new_state |= R128_NEW_CLIP;
1048 break;
1049
1050 case GL_STENCIL_TEST:
1051 FLUSH_BATCH( rmesa );
1052 if ( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ) {
1053 if ( state ) {
1054 rmesa->setup.tex_cntl_c |= R128_STENCIL_ENABLE;
1055 /* Reset the fallback (if any) for bad stencil funcs */
1056 r128DDStencilOpSeparate( ctx, 0, ctx->Stencil.FailFunc[0],
1057 ctx->Stencil.ZFailFunc[0],
1058 ctx->Stencil.ZPassFunc[0] );
1059 } else {
1060 rmesa->setup.tex_cntl_c &= ~R128_STENCIL_ENABLE;
1061 FALLBACK( rmesa, R128_FALLBACK_STENCIL, GL_FALSE );
1062 }
1063 rmesa->dirty |= R128_UPLOAD_CONTEXT;
1064 } else {
1065 FALLBACK( rmesa, R128_FALLBACK_STENCIL, state );
1066 }
1067 break;
1068
1069 case GL_TEXTURE_1D:
1070 case GL_TEXTURE_2D:
1071 case GL_TEXTURE_3D:
1072 FLUSH_BATCH( rmesa );
1073 break;
1074
1075 case GL_POLYGON_STIPPLE:
1076 if ( rmesa->render_primitive == GL_TRIANGLES ) {
1077 FLUSH_BATCH( rmesa );
1078 rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
1079 if ( state ) {
1080 rmesa->setup.dp_gui_master_cntl_c |=
1081 R128_GMC_BRUSH_32x32_MONO_FG_LA;
1082 } else {
1083 rmesa->setup.dp_gui_master_cntl_c |=
1084 R128_GMC_BRUSH_SOLID_COLOR;
1085 }
1086 rmesa->new_state |= R128_NEW_CONTEXT;
1087 rmesa->dirty |= R128_UPLOAD_CONTEXT;
1088 }
1089 break;
1090
1091 default:
1092 return;
1093 }
1094 }
1095
1096
1097 /* =============================================================
1098 * State initialization, management
1099 */
1100
1101 static void r128DDPrintDirty( const char *msg, GLuint state )
1102 {
1103 fprintf( stderr,
1104 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
1105 msg,
1106 state,
1107 (state & R128_UPLOAD_CORE) ? "core, " : "",
1108 (state & R128_UPLOAD_CONTEXT) ? "context, " : "",
1109 (state & R128_UPLOAD_SETUP) ? "setup, " : "",
1110 (state & R128_UPLOAD_TEX0) ? "tex0, " : "",
1111 (state & R128_UPLOAD_TEX1) ? "tex1, " : "",
1112 (state & R128_UPLOAD_MASKS) ? "masks, " : "",
1113 (state & R128_UPLOAD_WINDOW) ? "window, " : "",
1114 (state & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
1115 (state & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
1116 }
1117
1118 /*
1119 * Load the current context's state into the hardware.
1120 *
1121 * NOTE: Be VERY careful about ensuring the context state is marked for
1122 * upload, the only place it shouldn't be uploaded is when the setup
1123 * state has changed in ReducedPrimitiveChange as this comes right after
1124 * a state update.
1125 *
1126 * Blits of any type should always upload the context and masks after
1127 * they are done.
1128 */
1129 void r128EmitHwStateLocked( r128ContextPtr rmesa )
1130 {
1131 drm_r128_sarea_t *sarea = rmesa->sarea;
1132 drm_r128_context_regs_t *regs = &(rmesa->setup);
1133 const r128TexObjPtr t0 = rmesa->CurrentTexObj[0];
1134 const r128TexObjPtr t1 = rmesa->CurrentTexObj[1];
1135
1136 if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) {
1137 r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty );
1138 }
1139
1140 if ( rmesa->dirty & (R128_UPLOAD_CONTEXT |
1141 R128_UPLOAD_SETUP |
1142 R128_UPLOAD_MASKS |
1143 R128_UPLOAD_WINDOW |
1144 R128_UPLOAD_CORE) ) {
1145 memcpy( &sarea->context_state, regs, sizeof(sarea->context_state) );
1146
1147 if( rmesa->dirty & R128_UPLOAD_CONTEXT )
1148 {
1149 /* One possible side-effect of uploading a new context is the
1150 * setting of the R128_GMC_AUX_CLIP_DIS bit, which causes all
1151 * auxilliary cliprects to be disabled. So the next command must
1152 * upload them again. */
1153 rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
1154 }
1155 }
1156
1157 if ( (rmesa->dirty & R128_UPLOAD_TEX0) && t0 ) {
1158 drm_r128_texture_regs_t *tex = &sarea->tex_state[0];
1159
1160 tex->tex_cntl = t0->setup.tex_cntl;
1161 tex->tex_combine_cntl = rmesa->tex_combine[0];
1162 tex->tex_size_pitch = t0->setup.tex_size_pitch;
1163 memcpy( &tex->tex_offset[0], &t0->setup.tex_offset[0],
1164 sizeof(tex->tex_offset ) );
1165 tex->tex_border_color = t0->setup.tex_border_color;
1166 }
1167
1168 if ( (rmesa->dirty & R128_UPLOAD_TEX1) && t1 ) {
1169 drm_r128_texture_regs_t *tex = &sarea->tex_state[1];
1170
1171 tex->tex_cntl = t1->setup.tex_cntl;
1172 tex->tex_combine_cntl = rmesa->tex_combine[1];
1173 tex->tex_size_pitch = t1->setup.tex_size_pitch;
1174 memcpy( &tex->tex_offset[0], &t1->setup.tex_offset[0],
1175 sizeof(tex->tex_offset ) );
1176 tex->tex_border_color = t1->setup.tex_border_color;
1177 }
1178
1179 sarea->vertsize = rmesa->vertex_size;
1180 sarea->vc_format = rmesa->vertex_format;
1181
1182 /* Turn off the texture cache flushing */
1183 rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
1184
1185 sarea->dirty |= rmesa->dirty;
1186 rmesa->dirty &= R128_UPLOAD_CLIPRECTS;
1187 }
1188
1189 static void r128DDPrintState( const char *msg, GLuint flags )
1190 {
1191 fprintf( stderr,
1192 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
1193 msg,
1194 flags,
1195 (flags & R128_NEW_CONTEXT) ? "context, " : "",
1196 (flags & R128_NEW_ALPHA) ? "alpha, " : "",
1197 (flags & R128_NEW_DEPTH) ? "depth, " : "",
1198 (flags & R128_NEW_FOG) ? "fog, " : "",
1199 (flags & R128_NEW_CLIP) ? "clip, " : "",
1200 (flags & R128_NEW_CULL) ? "cull, " : "",
1201 (flags & R128_NEW_MASKS) ? "masks, " : "",
1202 (flags & R128_NEW_WINDOW) ? "window, " : "" );
1203 }
1204
1205 void r128DDUpdateHWState( GLcontext *ctx )
1206 {
1207 r128ContextPtr rmesa = R128_CONTEXT(ctx);
1208 int new_state = rmesa->new_state;
1209
1210 if ( new_state || rmesa->NewGLState & _NEW_TEXTURE )
1211 {
1212 FLUSH_BATCH( rmesa );
1213
1214 rmesa->new_state = 0;
1215
1216 if ( R128_DEBUG & DEBUG_VERBOSE_MSG )
1217 r128DDPrintState( "r128UpdateHwState", new_state );
1218
1219 /* Update the various parts of the context's state.
1220 */
1221 if ( new_state & R128_NEW_ALPHA )
1222 r128UpdateAlphaMode( ctx );
1223
1224 if ( new_state & R128_NEW_DEPTH )
1225 r128UpdateZMode( ctx );
1226
1227 if ( new_state & R128_NEW_FOG )
1228 r128UpdateFogAttrib( ctx );
1229
1230 if ( new_state & R128_NEW_CLIP )
1231 r128UpdateClipping( ctx );
1232
1233 if ( new_state & R128_NEW_CULL )
1234 r128UpdateCull( ctx );
1235
1236 if ( new_state & R128_NEW_MASKS )
1237 r128UpdateMasks( ctx );
1238
1239 if ( new_state & R128_NEW_WINDOW )
1240 {
1241 r128UpdateWindow( ctx );
1242 r128CalcViewport( ctx );
1243 }
1244
1245 if ( rmesa->NewGLState & _NEW_TEXTURE ) {
1246 r128UpdateTextureState( ctx );
1247 }
1248 }
1249 }
1250
1251
1252 static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state )
1253 {
1254 _swrast_InvalidateState( ctx, new_state );
1255 _swsetup_InvalidateState( ctx, new_state );
1256 _vbo_InvalidateState( ctx, new_state );
1257 _tnl_InvalidateState( ctx, new_state );
1258 R128_CONTEXT(ctx)->NewGLState |= new_state;
1259 }
1260
1261
1262
1263 /* Initialize the context's hardware state.
1264 */
1265 void r128DDInitState( r128ContextPtr rmesa )
1266 {
1267 int dst_bpp, depth_bpp;
1268
1269 switch ( rmesa->r128Screen->cpp ) {
1270 case 2:
1271 dst_bpp = R128_GMC_DST_16BPP;
1272 break;
1273 case 4:
1274 dst_bpp = R128_GMC_DST_32BPP;
1275 break;
1276 default:
1277 fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
1278 exit( -1 );
1279 }
1280
1281 rmesa->ClearColor = 0x00000000;
1282
1283 switch ( rmesa->glCtx->Visual.depthBits ) {
1284 case 16:
1285 rmesa->ClearDepth = 0x0000ffff;
1286 depth_bpp = R128_Z_PIX_WIDTH_16;
1287 rmesa->depth_scale = 1.0 / (GLfloat)0xffff;
1288 break;
1289 case 24:
1290 rmesa->ClearDepth = 0x00ffffff;
1291 depth_bpp = R128_Z_PIX_WIDTH_24;
1292 rmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
1293 break;
1294 default:
1295 fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
1296 rmesa->glCtx->Visual.depthBits );
1297 exit( -1 );
1298 }
1299
1300 rmesa->Fallback = 0;
1301
1302 /* Hardware state:
1303 */
1304 rmesa->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL |
1305 R128_GMC_DST_CLIPPING |
1306 R128_GMC_BRUSH_SOLID_COLOR |
1307 dst_bpp |
1308 R128_GMC_SRC_DATATYPE_COLOR |
1309 R128_GMC_BYTE_MSB_TO_LSB |
1310 R128_GMC_CONVERSION_TEMP_6500 |
1311 R128_ROP3_S |
1312 R128_DP_SRC_SOURCE_MEMORY |
1313 R128_GMC_3D_FCN_EN |
1314 R128_GMC_CLR_CMP_CNTL_DIS |
1315 R128_GMC_AUX_CLIP_DIS |
1316 R128_GMC_WR_MSK_DIS);
1317
1318 rmesa->setup.sc_top_left_c = 0x00000000;
1319 rmesa->setup.sc_bottom_right_c = 0x1fff1fff;
1320
1321 rmesa->setup.z_offset_c = rmesa->r128Screen->depthOffset;
1322 rmesa->setup.z_pitch_c = ((rmesa->r128Screen->depthPitch >> 3) |
1323 R128_Z_TILE);
1324
1325 rmesa->setup.z_sten_cntl_c = (depth_bpp |
1326 R128_Z_TEST_LESS |
1327 R128_STENCIL_TEST_ALWAYS |
1328 R128_STENCIL_S_FAIL_KEEP |
1329 R128_STENCIL_ZPASS_KEEP |
1330 R128_STENCIL_ZFAIL_KEEP);
1331
1332 rmesa->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE |
1333 R128_SHADE_ENABLE |
1334 R128_DITHER_ENABLE |
1335 R128_ALPHA_IN_TEX_COMPLETE_A |
1336 R128_LIGHT_DIS |
1337 R128_ALPHA_LIGHT_DIS |
1338 R128_TEX_CACHE_FLUSH |
1339 (0x3f << R128_LOD_BIAS_SHIFT));
1340
1341 rmesa->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE |
1342 R128_MISC_SCALE_PIX_REPLICATE |
1343 R128_ALPHA_COMB_ADD_CLAMP |
1344 R128_FOG_VERTEX |
1345 (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1346 (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1347 R128_ALPHA_TEST_ALWAYS);
1348
1349 rmesa->setup.texture_clr_cmp_clr_c = 0x00000000;
1350 rmesa->setup.texture_clr_cmp_msk_c = 0xffffffff;
1351
1352 rmesa->setup.fog_color_c = 0x00000000;
1353
1354 rmesa->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW |
1355 R128_BACKFACE_SOLID |
1356 R128_FRONTFACE_SOLID |
1357 R128_FPU_COLOR_GOURAUD |
1358 R128_FPU_SUB_PIX_4BITS |
1359 R128_FPU_MODE_3D |
1360 R128_TRAP_BITS_DISABLE |
1361 R128_XFACTOR_2 |
1362 R128_YFACTOR_2 |
1363 R128_FLAT_SHADE_VERTEX_OGL |
1364 R128_FPU_ROUND_TRUNCATE |
1365 R128_WM_SEL_8DW);
1366
1367 rmesa->setup.setup_cntl = (R128_COLOR_GOURAUD |
1368 R128_PRIM_TYPE_TRI |
1369 R128_TEXTURE_ST_MULT_W |
1370 R128_STARTING_VERTEX_1 |
1371 R128_ENDING_VERTEX_3 |
1372 R128_SU_POLY_LINE_NOT_LAST |
1373 R128_SUB_PIX_4BITS);
1374
1375 rmesa->setup.tex_size_pitch_c = 0x00000000;
1376 rmesa->setup.constant_color_c = 0x00ffffff;
1377
1378 rmesa->setup.dp_write_mask = 0xffffffff;
1379 rmesa->setup.sten_ref_mask_c = 0xffff0000;
1380 rmesa->setup.plane_3d_mask_c = 0xffffffff;
1381
1382 rmesa->setup.window_xy_offset = 0x00000000;
1383
1384 rmesa->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE |
1385 R128_TEX_CACHE_SIZE_FULL |
1386 R128_DITHER_INIT_RESET |
1387 R128_SCALE_3D_TEXMAP_SHADE |
1388 R128_SCALE_PIX_REPLICATE |
1389 R128_ALPHA_COMB_ADD_CLAMP |
1390 R128_FOG_VERTEX |
1391 (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1392 (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1393 R128_ALPHA_TEST_ALWAYS |
1394 R128_COMPOSITE_SHADOW_CMP_EQUAL |
1395 R128_TEX_MAP_ALPHA_IN_TEXTURE |
1396 R128_TEX_CACHE_LINE_SIZE_4QW);
1397
1398 rmesa->new_state = R128_NEW_ALL;
1399 }
1400
1401 /* Initialize the driver's state functions.
1402 */
1403 void r128DDInitStateFuncs( GLcontext *ctx )
1404 {
1405 ctx->Driver.UpdateState = r128DDInvalidateState;
1406
1407 ctx->Driver.ClearIndex = NULL;
1408 ctx->Driver.ClearColor = r128DDClearColor;
1409 ctx->Driver.ClearStencil = r128DDClearStencil;
1410 ctx->Driver.DrawBuffer = r128DDDrawBuffer;
1411 ctx->Driver.ReadBuffer = r128DDReadBuffer;
1412
1413 ctx->Driver.IndexMask = NULL;
1414 ctx->Driver.ColorMask = r128DDColorMask;
1415 ctx->Driver.AlphaFunc = r128DDAlphaFunc;
1416 ctx->Driver.BlendEquationSeparate = r128DDBlendEquationSeparate;
1417 ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate;
1418 ctx->Driver.ClearDepth = r128DDClearDepth;
1419 ctx->Driver.CullFace = r128DDCullFace;
1420 ctx->Driver.FrontFace = r128DDFrontFace;
1421 ctx->Driver.DepthFunc = r128DDDepthFunc;
1422 ctx->Driver.DepthMask = r128DDDepthMask;
1423 ctx->Driver.Enable = r128DDEnable;
1424 ctx->Driver.Fogfv = r128DDFogfv;
1425 ctx->Driver.Hint = NULL;
1426 ctx->Driver.Lightfv = NULL;
1427 ctx->Driver.LightModelfv = r128DDLightModelfv;
1428 ctx->Driver.LogicOpcode = r128DDLogicOpCode;
1429 ctx->Driver.PolygonMode = NULL;
1430 ctx->Driver.PolygonStipple = r128DDPolygonStipple;
1431 ctx->Driver.RenderMode = r128DDRenderMode;
1432 ctx->Driver.Scissor = r128DDScissor;
1433 ctx->Driver.ShadeModel = r128DDShadeModel;
1434 ctx->Driver.StencilFuncSeparate = r128DDStencilFuncSeparate;
1435 ctx->Driver.StencilMaskSeparate = r128DDStencilMaskSeparate;
1436 ctx->Driver.StencilOpSeparate = r128DDStencilOpSeparate;
1437
1438 ctx->Driver.DepthRange = r128DepthRange;
1439 ctx->Driver.Viewport = r128Viewport;
1440 }