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