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