1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.11 2002/10/30 12:51:39 alanh Exp $ */
2 /**************************************************************************
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Kevin E. Martin <martin@valinux.com>
33 * Keith Whitwell <keith@tungstengraphics.com>
37 #include "r128_context.h"
38 #include "r128_state.h"
39 #include "r128_ioctl.h"
40 #include "r128_tris.h"
47 #include "swrast/swrast.h"
48 #include "array_cache/acache.h"
50 #include "swrast_setup/swrast_setup.h"
52 #include "tnl/t_pipeline.h"
55 /* =============================================================
59 static void r128UpdateAlphaMode( GLcontext
*ctx
)
61 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
62 GLuint a
= rmesa
->setup
.misc_3d_state_cntl_reg
;
63 GLuint t
= rmesa
->setup
.tex_cntl_c
;
65 if ( ctx
->Color
.AlphaEnabled
) {
68 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
70 a
&= ~(R128_ALPHA_TEST_MASK
| R128_REF_ALPHA_MASK
);
72 switch ( ctx
->Color
.AlphaFunc
) {
74 a
|= R128_ALPHA_TEST_NEVER
;
77 a
|= R128_ALPHA_TEST_LESS
;
80 a
|= R128_ALPHA_TEST_LESSEQUAL
;
83 a
|= R128_ALPHA_TEST_EQUAL
;
86 a
|= R128_ALPHA_TEST_GREATEREQUAL
;
89 a
|= R128_ALPHA_TEST_GREATER
;
92 a
|= R128_ALPHA_TEST_NEQUAL
;
95 a
|= R128_ALPHA_TEST_ALWAYS
;
99 a
|= ref
& R128_REF_ALPHA_MASK
;
100 t
|= R128_ALPHA_TEST_ENABLE
;
102 t
&= ~R128_ALPHA_TEST_ENABLE
;
105 FALLBACK( rmesa
, R128_FALLBACK_BLEND_FUNC
, GL_FALSE
);
107 if ( ctx
->Color
.BlendEnabled
) {
108 a
&= ~(R128_ALPHA_BLEND_SRC_MASK
| R128_ALPHA_BLEND_DST_MASK
);
110 switch ( ctx
->Color
.BlendSrcRGB
) {
112 a
|= R128_ALPHA_BLEND_SRC_ZERO
;
115 a
|= R128_ALPHA_BLEND_SRC_ONE
;
118 a
|= R128_ALPHA_BLEND_SRC_DESTCOLOR
;
120 case GL_ONE_MINUS_DST_COLOR
:
121 a
|= R128_ALPHA_BLEND_SRC_INVDESTCOLOR
;
124 a
|= R128_ALPHA_BLEND_SRC_SRCALPHA
;
126 case GL_ONE_MINUS_SRC_ALPHA
:
127 a
|= R128_ALPHA_BLEND_SRC_INVSRCALPHA
;
130 a
|= R128_ALPHA_BLEND_SRC_DESTALPHA
;
132 case GL_ONE_MINUS_DST_ALPHA
:
133 a
|= R128_ALPHA_BLEND_SRC_INVDESTALPHA
;
135 case GL_SRC_ALPHA_SATURATE
:
136 a
|= R128_ALPHA_BLEND_SRC_SRCALPHASAT
;
139 FALLBACK( rmesa
, R128_FALLBACK_BLEND_FUNC
, GL_TRUE
);
142 switch ( ctx
->Color
.BlendDstRGB
) {
144 a
|= R128_ALPHA_BLEND_DST_ZERO
;
147 a
|= R128_ALPHA_BLEND_DST_ONE
;
150 a
|= R128_ALPHA_BLEND_DST_SRCCOLOR
;
152 case GL_ONE_MINUS_SRC_COLOR
:
153 a
|= R128_ALPHA_BLEND_DST_INVSRCCOLOR
;
156 a
|= R128_ALPHA_BLEND_DST_SRCALPHA
;
158 case GL_ONE_MINUS_SRC_ALPHA
:
159 a
|= R128_ALPHA_BLEND_DST_INVSRCALPHA
;
162 a
|= R128_ALPHA_BLEND_DST_DESTALPHA
;
164 case GL_ONE_MINUS_DST_ALPHA
:
165 a
|= R128_ALPHA_BLEND_DST_INVDESTALPHA
;
168 FALLBACK( rmesa
, R128_FALLBACK_BLEND_FUNC
, GL_TRUE
);
171 t
|= R128_ALPHA_ENABLE
;
173 t
&= ~R128_ALPHA_ENABLE
;
176 if ( rmesa
->setup
.misc_3d_state_cntl_reg
!= a
) {
177 rmesa
->setup
.misc_3d_state_cntl_reg
= a
;
178 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_MASKS
;
180 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
181 rmesa
->setup
.tex_cntl_c
= t
;
182 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_MASKS
;
186 static void r128DDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
188 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
190 FLUSH_BATCH( rmesa
);
191 rmesa
->new_state
|= R128_NEW_ALPHA
;
194 static void r128DDBlendEquation( GLcontext
*ctx
, GLenum mode
)
196 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
198 FLUSH_BATCH( rmesa
);
200 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
203 FALLBACK( R128_CONTEXT(ctx
), R128_FALLBACK_LOGICOP
,
204 (ctx
->Color
.ColorLogicOpEnabled
&&
205 ctx
->Color
.LogicOp
!= GL_COPY
));
207 /* Can only do blend addition, not min, max, subtract, etc. */
208 FALLBACK( R128_CONTEXT(ctx
), R128_FALLBACK_BLEND_EQ
,
209 mode
!= GL_FUNC_ADD_EXT
);
211 rmesa
->new_state
|= R128_NEW_ALPHA
;
214 static void r128DDBlendFunc( GLcontext
*ctx
, GLenum sfactor
, GLenum dfactor
)
216 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
218 FLUSH_BATCH( rmesa
);
219 rmesa
->new_state
|= R128_NEW_ALPHA
;
222 static void r128DDBlendFuncSeparate( GLcontext
*ctx
,
223 GLenum sfactorRGB
, GLenum dfactorRGB
,
224 GLenum sfactorA
, GLenum dfactorA
)
226 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
228 FLUSH_BATCH( rmesa
);
229 rmesa
->new_state
|= R128_NEW_ALPHA
;
233 /* =============================================================
237 static void r128UpdateZMode( GLcontext
*ctx
)
239 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
240 GLuint z
= rmesa
->setup
.z_sten_cntl_c
;
241 GLuint t
= rmesa
->setup
.tex_cntl_c
;
243 if ( ctx
->Depth
.Test
) {
244 z
&= ~R128_Z_TEST_MASK
;
246 switch ( ctx
->Depth
.Func
) {
248 z
|= R128_Z_TEST_NEVER
;
251 z
|= R128_Z_TEST_ALWAYS
;
254 z
|= R128_Z_TEST_LESS
;
257 z
|= R128_Z_TEST_LESSEQUAL
;
260 z
|= R128_Z_TEST_EQUAL
;
263 z
|= R128_Z_TEST_GREATEREQUAL
;
266 z
|= R128_Z_TEST_GREATER
;
269 z
|= R128_Z_TEST_NEQUAL
;
278 if ( ctx
->Depth
.Mask
) {
279 t
|= R128_Z_WRITE_ENABLE
;
281 t
&= ~R128_Z_WRITE_ENABLE
;
284 if ( rmesa
->setup
.z_sten_cntl_c
!= z
) {
285 rmesa
->setup
.z_sten_cntl_c
= z
;
286 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
288 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
289 rmesa
->setup
.tex_cntl_c
= t
;
290 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
294 static void r128DDDepthFunc( GLcontext
*ctx
, GLenum func
)
296 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
298 FLUSH_BATCH( rmesa
);
299 rmesa
->new_state
|= R128_NEW_DEPTH
;
302 static void r128DDDepthMask( GLcontext
*ctx
, GLboolean flag
)
304 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
306 FLUSH_BATCH( rmesa
);
307 rmesa
->new_state
|= R128_NEW_DEPTH
;
310 static void r128DDClearDepth( GLcontext
*ctx
, GLclampd d
)
312 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
314 switch ( rmesa
->setup
.z_sten_cntl_c
& R128_Z_PIX_WIDTH_MASK
) {
315 case R128_Z_PIX_WIDTH_16
:
316 rmesa
->ClearDepth
= d
* 0x0000ffff;
318 case R128_Z_PIX_WIDTH_24
:
319 rmesa
->ClearDepth
= d
* 0x00ffffff;
321 case R128_Z_PIX_WIDTH_32
:
322 rmesa
->ClearDepth
= d
* 0xffffffff;
328 /* =============================================================
332 static void r128UpdateFogAttrib( GLcontext
*ctx
)
334 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
335 GLuint t
= rmesa
->setup
.tex_cntl_c
;
339 if ( ctx
->Fog
.Enabled
) {
340 t
|= R128_FOG_ENABLE
;
342 t
&= ~R128_FOG_ENABLE
;
345 c
[0] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] );
346 c
[1] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] );
347 c
[2] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
349 col
= r128PackColor( 4, c
[0], c
[1], c
[2], 0 );
351 if ( rmesa
->setup
.fog_color_c
!= col
) {
352 rmesa
->setup
.fog_color_c
= col
;
353 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
355 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
356 rmesa
->setup
.tex_cntl_c
= t
;
357 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
361 static void r128DDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
363 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
365 FLUSH_BATCH( rmesa
);
366 rmesa
->new_state
|= R128_NEW_FOG
;
370 /* =============================================================
374 static void r128UpdateClipping( GLcontext
*ctx
)
376 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
378 if ( rmesa
->driDrawable
) {
379 __DRIdrawablePrivate
*drawable
= rmesa
->driDrawable
;
382 int x2
= drawable
->w
- 1;
383 int y2
= drawable
->h
- 1;
385 if ( ctx
->Scissor
.Enabled
) {
386 if ( ctx
->Scissor
.X
> x1
) {
389 if ( drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
> y1
) {
390 y1
= drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
392 if ( ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
) {
393 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
395 if ( drawable
->h
- ctx
->Scissor
.Y
- 1 < y2
) {
396 y2
= drawable
->h
- ctx
->Scissor
.Y
- 1;
405 rmesa
->setup
.sc_top_left_c
= ((y1
<< 16) | x1
);
406 rmesa
->setup
.sc_bottom_right_c
= ((y2
<< 16) | x2
);
408 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
412 static void r128DDScissor( GLcontext
*ctx
,
413 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
415 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
417 FLUSH_BATCH( rmesa
);
418 rmesa
->new_state
|= R128_NEW_CLIP
;
422 /* =============================================================
426 static void r128UpdateCull( GLcontext
*ctx
)
428 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
429 GLuint f
= rmesa
->setup
.pm4_vc_fpu_setup
;
431 f
&= ~R128_FRONT_DIR_MASK
;
433 switch ( ctx
->Polygon
.FrontFace
) {
435 f
|= R128_FRONT_DIR_CW
;
438 f
|= R128_FRONT_DIR_CCW
;
442 f
|= R128_BACKFACE_SOLID
| R128_FRONTFACE_SOLID
;
444 if ( ctx
->Polygon
.CullFlag
) {
445 switch ( ctx
->Polygon
.CullFaceMode
) {
447 f
&= ~R128_FRONTFACE_SOLID
;
450 f
&= ~R128_BACKFACE_SOLID
;
452 case GL_FRONT_AND_BACK
:
453 f
&= ~(R128_BACKFACE_SOLID
|
454 R128_FRONTFACE_SOLID
);
459 if ( 1 || rmesa
->setup
.pm4_vc_fpu_setup
!= f
) {
460 rmesa
->setup
.pm4_vc_fpu_setup
= f
;
461 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_SETUP
;
465 static void r128DDCullFace( GLcontext
*ctx
, GLenum mode
)
467 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
469 FLUSH_BATCH( rmesa
);
470 rmesa
->new_state
|= R128_NEW_CULL
;
473 static void r128DDFrontFace( GLcontext
*ctx
, GLenum mode
)
475 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
477 FLUSH_BATCH( rmesa
);
478 rmesa
->new_state
|= R128_NEW_CULL
;
482 /* =============================================================
486 static void r128UpdateMasks( GLcontext
*ctx
)
488 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
490 GLuint mask
= r128PackColor( rmesa
->r128Screen
->cpp
,
491 ctx
->Color
.ColorMask
[RCOMP
],
492 ctx
->Color
.ColorMask
[GCOMP
],
493 ctx
->Color
.ColorMask
[BCOMP
],
494 ctx
->Color
.ColorMask
[ACOMP
] );
496 if ( rmesa
->setup
.plane_3d_mask_c
!= mask
) {
497 rmesa
->setup
.plane_3d_mask_c
= mask
;
498 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_MASKS
;
502 static void r128DDColorMask( GLcontext
*ctx
,
503 GLboolean r
, GLboolean g
,
504 GLboolean b
, GLboolean a
)
506 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
508 FLUSH_BATCH( rmesa
);
509 rmesa
->new_state
|= R128_NEW_MASKS
;
513 /* =============================================================
514 * Rendering attributes
516 * We really don't want to recalculate all this every time we bind a
517 * texture. These things shouldn't change all that often, so it makes
518 * sense to break them out of the core texture state update routines.
521 static void updateSpecularLighting( GLcontext
*ctx
)
523 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
524 GLuint t
= rmesa
->setup
.tex_cntl_c
;
526 if ( ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
527 ctx
->Light
.Enabled
) {
528 /* XXX separate specular color just doesn't seem to work as it should.
529 * For now, we fall back to s/w rendering whenever separate specular
533 if (ctx
->Light
.ShadeModel
== GL_FLAT
) {
534 /* R128 can't do flat-shaded separate specular */
535 t
&= ~R128_SPEC_LIGHT_ENABLE
;
536 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_TRUE
);
537 /*printf("%s fallback sep spec\n", __FUNCTION__);*/
540 t
|= R128_SPEC_LIGHT_ENABLE
;
541 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_FALSE
);
542 /*printf("%s enable sep spec\n", __FUNCTION__);*/
545 t
&= ~R128_SPEC_LIGHT_ENABLE
;
546 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_TRUE
);
547 /*printf("%s fallback sep spec\n", __FUNCTION__);*/
551 t
&= ~R128_SPEC_LIGHT_ENABLE
;
552 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_FALSE
);
553 /*printf("%s disable sep spec\n", __FUNCTION__);*/
556 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
557 rmesa
->setup
.tex_cntl_c
= t
;
558 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
559 rmesa
->dirty
|= R128_UPLOAD_SETUP
;
560 rmesa
->new_state
|= R128_NEW_CONTEXT
;
565 static void r128DDLightModelfv( GLcontext
*ctx
, GLenum pname
,
566 const GLfloat
*param
)
568 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
570 if ( pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
571 FLUSH_BATCH( rmesa
);
572 updateSpecularLighting(ctx
);
576 static void r128DDShadeModel( GLcontext
*ctx
, GLenum mode
)
578 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
579 GLuint s
= rmesa
->setup
.pm4_vc_fpu_setup
;
581 s
&= ~R128_FPU_COLOR_MASK
;
585 s
|= R128_FPU_COLOR_FLAT
;
588 s
|= R128_FPU_COLOR_GOURAUD
;
594 updateSpecularLighting(ctx
);
596 if ( rmesa
->setup
.pm4_vc_fpu_setup
!= s
) {
597 FLUSH_BATCH( rmesa
);
598 rmesa
->setup
.pm4_vc_fpu_setup
= s
;
600 rmesa
->new_state
|= R128_NEW_CONTEXT
;
601 rmesa
->dirty
|= R128_UPLOAD_SETUP
;
606 /* =============================================================
610 void r128UpdateWindow( GLcontext
*ctx
)
612 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
613 int x
= rmesa
->driDrawable
->x
;
614 int y
= rmesa
->driDrawable
->y
;
616 rmesa
->setup
.window_xy_offset
= ((y
<< R128_WINDOW_Y_SHIFT
) |
617 (x
<< R128_WINDOW_X_SHIFT
));
619 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_WINDOW
;
622 /* =============================================================
627 static void r128CalcViewport( GLcontext
*ctx
)
629 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
630 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
631 GLfloat
*m
= rmesa
->hw_viewport
;
633 /* See also r128_translate_vertex.
635 m
[MAT_SX
] = v
[MAT_SX
];
636 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
637 m
[MAT_SY
] = - v
[MAT_SY
];
638 m
[MAT_TY
] = - v
[MAT_TY
] + rmesa
->driDrawable
->h
+ SUBPIXEL_Y
;
639 m
[MAT_SZ
] = v
[MAT_SZ
] * rmesa
->depth_scale
;
640 m
[MAT_TZ
] = v
[MAT_TZ
] * rmesa
->depth_scale
;
643 static void r128Viewport( GLcontext
*ctx
,
645 GLsizei width
, GLsizei height
)
647 r128CalcViewport( ctx
);
650 static void r128DepthRange( GLcontext
*ctx
,
651 GLclampd nearval
, GLclampd farval
)
653 r128CalcViewport( ctx
);
657 /* =============================================================
661 static void r128DDClearColor( GLcontext
*ctx
,
662 const GLfloat color
[4] )
664 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
667 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
668 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
669 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
670 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
672 rmesa
->ClearColor
= r128PackColor( rmesa
->r128Screen
->cpp
,
673 c
[0], c
[1], c
[2], c
[3] );
676 static void r128DDLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
678 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
680 if ( ctx
->Color
.ColorLogicOpEnabled
) {
681 FLUSH_BATCH( rmesa
);
683 FALLBACK( rmesa
, R128_FALLBACK_LOGICOP
, opcode
!= GL_COPY
);
687 static void r128DDDrawBuffer( GLcontext
*ctx
, GLenum mode
)
689 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
691 FLUSH_BATCH( rmesa
);
694 * _DrawDestMask is easier to cope with than <mode>.
696 switch ( ctx
->Color
._DrawDestMask
) {
698 FALLBACK( rmesa
, R128_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
701 FALLBACK( rmesa
, R128_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
704 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
705 FALLBACK( rmesa
, R128_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
709 /* We want to update the s/w rast state too so that r200SetBuffer()
712 _swrast_DrawBuffer(ctx
, mode
);
714 rmesa
->setup
.dst_pitch_offset_c
= (((rmesa
->drawPitch
/8) << 21) |
715 (rmesa
->drawOffset
>> 5));
716 rmesa
->new_state
|= R128_NEW_WINDOW
;
719 static void r128DDReadBuffer( GLcontext
*ctx
, GLenum mode
)
721 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
725 /* =============================================================
729 static void r128DDPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
731 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
732 GLuint stipple
[32], i
;
733 drmR128Stipple stippleRec
;
735 for (i
= 0; i
< 32; i
++) {
736 stipple
[31 - i
] = ((mask
[i
*4+0] << 24) |
737 (mask
[i
*4+1] << 16) |
742 FLUSH_BATCH( rmesa
);
743 LOCK_HARDWARE( rmesa
);
745 stippleRec
.mask
= stipple
;
746 drmCommandWrite( rmesa
->driFd
, DRM_R128_STIPPLE
,
747 &stippleRec
, sizeof(drmR128Stipple
) );
749 UNLOCK_HARDWARE( rmesa
);
751 rmesa
->new_state
|= R128_NEW_CONTEXT
;
752 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
756 /* =============================================================
760 static void r128DDRenderMode( GLcontext
*ctx
, GLenum mode
)
762 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
763 FALLBACK( rmesa
, R128_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
768 /* =============================================================
769 * State enable/disable
772 static void r128DDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
774 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
776 if ( R128_DEBUG
& DEBUG_VERBOSE_API
) {
777 fprintf( stderr
, "%s( %s = %s )\n",
778 __FUNCTION__
, _mesa_lookup_enum_by_nr( cap
),
779 state
? "GL_TRUE" : "GL_FALSE" );
784 FLUSH_BATCH( rmesa
);
785 rmesa
->new_state
|= R128_NEW_ALPHA
;
789 FLUSH_BATCH( rmesa
);
790 rmesa
->new_state
|= R128_NEW_ALPHA
;
792 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
794 FALLBACK( rmesa
, R128_FALLBACK_LOGICOP
,
795 (ctx
->Color
.ColorLogicOpEnabled
&&
796 ctx
->Color
.LogicOp
!= GL_COPY
));
800 FLUSH_BATCH( rmesa
);
801 rmesa
->new_state
|= R128_NEW_CULL
;
805 FLUSH_BATCH( rmesa
);
806 rmesa
->new_state
|= R128_NEW_DEPTH
;
811 GLuint t
= rmesa
->setup
.tex_cntl_c
;
812 FLUSH_BATCH( rmesa
);
814 if ( ctx
->Color
.DitherFlag
) {
815 t
|= R128_DITHER_ENABLE
;
817 t
&= ~R128_DITHER_ENABLE
;
820 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
821 rmesa
->setup
.tex_cntl_c
= t
;
822 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
828 FLUSH_BATCH( rmesa
);
829 rmesa
->new_state
|= R128_NEW_FOG
;
832 case GL_COLOR_LOGIC_OP
:
833 FLUSH_BATCH( rmesa
);
834 FALLBACK( rmesa
, R128_FALLBACK_LOGICOP
,
835 state
&& ctx
->Color
.LogicOp
!= GL_COPY
);
839 updateSpecularLighting(ctx
);
842 case GL_SCISSOR_TEST
:
843 FLUSH_BATCH( rmesa
);
844 rmesa
->scissor
= state
;
845 rmesa
->new_state
|= R128_NEW_CLIP
;
848 case GL_STENCIL_TEST
:
849 FLUSH_BATCH( rmesa
);
850 FALLBACK( rmesa
, R128_FALLBACK_STENCIL
, state
);
856 FLUSH_BATCH( rmesa
);
859 case GL_POLYGON_STIPPLE
:
860 if ( rmesa
->render_primitive
== GL_TRIANGLES
) {
861 FLUSH_BATCH( rmesa
);
862 rmesa
->setup
.dp_gui_master_cntl_c
&= ~R128_GMC_BRUSH_NONE
;
864 rmesa
->setup
.dp_gui_master_cntl_c
|=
865 R128_GMC_BRUSH_32x32_MONO_FG_LA
;
867 rmesa
->setup
.dp_gui_master_cntl_c
|=
868 R128_GMC_BRUSH_SOLID_COLOR
;
870 rmesa
->new_state
|= R128_NEW_CONTEXT
;
871 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
881 /* =============================================================
882 * State initialization, management
885 static void r128DDPrintDirty( const char *msg
, GLuint state
)
888 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
891 (state
& R128_UPLOAD_CORE
) ? "core, " : "",
892 (state
& R128_UPLOAD_CONTEXT
) ? "context, " : "",
893 (state
& R128_UPLOAD_SETUP
) ? "setup, " : "",
894 (state
& R128_UPLOAD_TEX0
) ? "tex0, " : "",
895 (state
& R128_UPLOAD_TEX1
) ? "tex1, " : "",
896 (state
& R128_UPLOAD_MASKS
) ? "masks, " : "",
897 (state
& R128_UPLOAD_WINDOW
) ? "window, " : "",
898 (state
& R128_UPLOAD_CLIPRECTS
) ? "cliprects, " : "",
899 (state
& R128_REQUIRE_QUIESCENCE
) ? "quiescence, " : "" );
903 * Load the current context's state into the hardware.
905 * NOTE: Be VERY careful about ensuring the context state is marked for
906 * upload, the only place it shouldn't be uploaded is when the setup
907 * state has changed in ReducedPrimitiveChange as this comes right after
910 * Blits of any type should always upload the context and masks after
913 void r128EmitHwStateLocked( r128ContextPtr rmesa
)
915 R128SAREAPrivPtr sarea
= rmesa
->sarea
;
916 r128_context_regs_t
*regs
= &(rmesa
->setup
);
917 const r128TexObjPtr t0
= rmesa
->CurrentTexObj
[0];
918 const r128TexObjPtr t1
= rmesa
->CurrentTexObj
[1];
920 if ( R128_DEBUG
& DEBUG_VERBOSE_MSG
) {
921 r128DDPrintDirty( "r128EmitHwStateLocked", rmesa
->dirty
);
924 if ( rmesa
->dirty
& (R128_UPLOAD_CONTEXT
|
928 R128_UPLOAD_CORE
) ) {
929 memcpy( &sarea
->ContextState
, regs
, sizeof(sarea
->ContextState
) );
932 if ( (rmesa
->dirty
& R128_UPLOAD_TEX0
) && t0
) {
933 r128_texture_regs_t
*tex
= &sarea
->TexState
[0];
935 tex
->tex_cntl
= t0
->setup
.tex_cntl
;
936 tex
->tex_combine_cntl
= rmesa
->tex_combine
[0];
937 tex
->tex_size_pitch
= t0
->setup
.tex_size_pitch
;
938 memcpy( &tex
->tex_offset
[0], &t0
->setup
.tex_offset
[0],
939 sizeof(tex
->tex_offset
) );
940 tex
->tex_border_color
= t0
->setup
.tex_border_color
;
943 if ( (rmesa
->dirty
& R128_UPLOAD_TEX1
) && t1
) {
944 r128_texture_regs_t
*tex
= &sarea
->TexState
[1];
946 tex
->tex_cntl
= t1
->setup
.tex_cntl
;
947 tex
->tex_combine_cntl
= rmesa
->tex_combine
[1];
948 tex
->tex_size_pitch
= t1
->setup
.tex_size_pitch
;
949 memcpy( &tex
->tex_offset
[0], &t1
->setup
.tex_offset
[0],
950 sizeof(tex
->tex_offset
) );
951 tex
->tex_border_color
= t1
->setup
.tex_border_color
;
954 sarea
->vertsize
= rmesa
->vertex_size
;
955 sarea
->vc_format
= rmesa
->vertex_format
;
957 /* Turn off the texture cache flushing */
958 rmesa
->setup
.tex_cntl_c
&= ~R128_TEX_CACHE_FLUSH
;
960 sarea
->dirty
|= rmesa
->dirty
;
961 rmesa
->dirty
&= R128_UPLOAD_CLIPRECTS
;
964 static void r128DDPrintState( const char *msg
, GLuint flags
)
967 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
970 (flags
& R128_NEW_CONTEXT
) ? "context, " : "",
971 (flags
& R128_NEW_ALPHA
) ? "alpha, " : "",
972 (flags
& R128_NEW_DEPTH
) ? "depth, " : "",
973 (flags
& R128_NEW_FOG
) ? "fog, " : "",
974 (flags
& R128_NEW_CLIP
) ? "clip, " : "",
975 (flags
& R128_NEW_CULL
) ? "cull, " : "",
976 (flags
& R128_NEW_MASKS
) ? "masks, " : "",
977 (flags
& R128_NEW_WINDOW
) ? "window, " : "" );
980 void r128DDUpdateHWState( GLcontext
*ctx
)
982 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
983 int new_state
= rmesa
->new_state
;
985 if ( new_state
|| rmesa
->NewGLState
& _NEW_TEXTURE
)
987 FLUSH_BATCH( rmesa
);
989 rmesa
->new_state
= 0;
991 if ( R128_DEBUG
& DEBUG_VERBOSE_MSG
)
992 r128DDPrintState( "r128UpdateHwState", new_state
);
994 /* Update the various parts of the context's state.
996 if ( new_state
& R128_NEW_ALPHA
)
997 r128UpdateAlphaMode( ctx
);
999 if ( new_state
& R128_NEW_DEPTH
)
1000 r128UpdateZMode( ctx
);
1002 if ( new_state
& R128_NEW_FOG
)
1003 r128UpdateFogAttrib( ctx
);
1005 if ( new_state
& R128_NEW_CLIP
)
1006 r128UpdateClipping( ctx
);
1008 if ( new_state
& R128_NEW_CULL
)
1009 r128UpdateCull( ctx
);
1011 if ( new_state
& R128_NEW_MASKS
)
1012 r128UpdateMasks( ctx
);
1014 if ( new_state
& R128_NEW_WINDOW
)
1015 r128UpdateWindow( ctx
);
1017 if ( rmesa
->NewGLState
& _NEW_TEXTURE
) {
1018 r128UpdateTextureState( ctx
);
1024 static void r128DDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1026 _swrast_InvalidateState( ctx
, new_state
);
1027 _swsetup_InvalidateState( ctx
, new_state
);
1028 _ac_InvalidateState( ctx
, new_state
);
1029 _tnl_InvalidateState( ctx
, new_state
);
1030 R128_CONTEXT(ctx
)->NewGLState
|= new_state
;
1035 /* Initialize the context's hardware state.
1037 void r128DDInitState( r128ContextPtr rmesa
)
1039 int dst_bpp
, depth_bpp
;
1041 switch ( rmesa
->r128Screen
->cpp
) {
1043 dst_bpp
= R128_GMC_DST_16BPP
;
1046 dst_bpp
= R128_GMC_DST_32BPP
;
1049 fprintf( stderr
, "Error: Unsupported pixel depth... exiting\n" );
1053 rmesa
->ClearColor
= 0x00000000;
1055 switch ( rmesa
->glCtx
->Visual
.depthBits
) {
1057 rmesa
->ClearDepth
= 0x0000ffff;
1058 depth_bpp
= R128_Z_PIX_WIDTH_16
;
1059 rmesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
1062 rmesa
->ClearDepth
= 0x00ffffff;
1063 depth_bpp
= R128_Z_PIX_WIDTH_24
;
1064 rmesa
->depth_scale
= 1.0 / (GLfloat
)0xffffff;
1067 fprintf( stderr
, "Error: Unsupported depth %d... exiting\n",
1068 rmesa
->glCtx
->Visual
.depthBits
);
1072 rmesa
->Fallback
= 0;
1074 if ( rmesa
->glCtx
->Visual
.doubleBufferMode
&& rmesa
->sarea
->pfCurrentPage
== 0 ) {
1075 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
1076 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
1078 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
1079 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
1084 rmesa
->setup
.dst_pitch_offset_c
= (((rmesa
->drawPitch
/8) << 21) |
1085 (rmesa
->drawOffset
>> 5));
1087 rmesa
->setup
.dp_gui_master_cntl_c
= (R128_GMC_DST_PITCH_OFFSET_CNTL
|
1088 R128_GMC_DST_CLIPPING
|
1089 R128_GMC_BRUSH_SOLID_COLOR
|
1091 R128_GMC_SRC_DATATYPE_COLOR
|
1092 R128_GMC_BYTE_MSB_TO_LSB
|
1093 R128_GMC_CONVERSION_TEMP_6500
|
1095 R128_DP_SRC_SOURCE_MEMORY
|
1096 R128_GMC_3D_FCN_EN
|
1097 R128_GMC_CLR_CMP_CNTL_DIS
|
1098 R128_GMC_AUX_CLIP_DIS
|
1099 R128_GMC_WR_MSK_DIS
);
1101 rmesa
->setup
.sc_top_left_c
= 0x00000000;
1102 rmesa
->setup
.sc_bottom_right_c
= 0x1fff1fff;
1104 rmesa
->setup
.z_offset_c
= rmesa
->r128Screen
->depthOffset
;
1105 rmesa
->setup
.z_pitch_c
= ((rmesa
->r128Screen
->depthPitch
>> 3) |
1108 rmesa
->setup
.z_sten_cntl_c
= (depth_bpp
|
1110 R128_STENCIL_TEST_ALWAYS
|
1111 R128_STENCIL_S_FAIL_KEEP
|
1112 R128_STENCIL_ZPASS_KEEP
|
1113 R128_STENCIL_ZFAIL_KEEP
);
1115 rmesa
->setup
.tex_cntl_c
= (R128_Z_WRITE_ENABLE
|
1117 R128_DITHER_ENABLE
|
1118 R128_ALPHA_IN_TEX_COMPLETE_A
|
1120 R128_ALPHA_LIGHT_DIS
|
1121 R128_TEX_CACHE_FLUSH
|
1122 (0x3f << R128_LOD_BIAS_SHIFT
));
1124 rmesa
->setup
.misc_3d_state_cntl_reg
= (R128_MISC_SCALE_3D_TEXMAP_SHADE
|
1125 R128_MISC_SCALE_PIX_REPLICATE
|
1126 R128_ALPHA_COMB_ADD_CLAMP
|
1128 R128_ALPHA_BLEND_SRC_ONE
|
1129 R128_ALPHA_BLEND_DST_ZERO
|
1130 R128_ALPHA_TEST_ALWAYS
);
1132 rmesa
->setup
.texture_clr_cmp_clr_c
= 0x00000000;
1133 rmesa
->setup
.texture_clr_cmp_msk_c
= 0xffffffff;
1135 rmesa
->setup
.fog_color_c
= 0x00000000;
1137 rmesa
->setup
.pm4_vc_fpu_setup
= (R128_FRONT_DIR_CCW
|
1138 R128_BACKFACE_SOLID
|
1139 R128_FRONTFACE_SOLID
|
1140 R128_FPU_COLOR_GOURAUD
|
1141 R128_FPU_SUB_PIX_4BITS
|
1143 R128_TRAP_BITS_DISABLE
|
1146 R128_FLAT_SHADE_VERTEX_OGL
|
1147 R128_FPU_ROUND_TRUNCATE
|
1150 rmesa
->setup
.setup_cntl
= (R128_COLOR_GOURAUD
|
1151 R128_PRIM_TYPE_TRI
|
1152 R128_TEXTURE_ST_MULT_W
|
1153 R128_STARTING_VERTEX_1
|
1154 R128_ENDING_VERTEX_3
|
1155 R128_SU_POLY_LINE_NOT_LAST
|
1156 R128_SUB_PIX_4BITS
);
1158 rmesa
->setup
.tex_size_pitch_c
= 0x00000000;
1159 rmesa
->setup
.constant_color_c
= 0x00ffffff;
1161 rmesa
->setup
.dp_write_mask
= 0xffffffff;
1162 rmesa
->setup
.sten_ref_mask_c
= 0xffff0000;
1163 rmesa
->setup
.plane_3d_mask_c
= 0xffffffff;
1165 rmesa
->setup
.window_xy_offset
= 0x00000000;
1167 rmesa
->setup
.scale_3d_cntl
= (R128_SCALE_DITHER_TABLE
|
1168 R128_TEX_CACHE_SIZE_FULL
|
1169 R128_DITHER_INIT_RESET
|
1170 R128_SCALE_3D_TEXMAP_SHADE
|
1171 R128_SCALE_PIX_REPLICATE
|
1172 R128_ALPHA_COMB_ADD_CLAMP
|
1174 R128_ALPHA_BLEND_SRC_ONE
|
1175 R128_ALPHA_BLEND_DST_ZERO
|
1176 R128_ALPHA_TEST_ALWAYS
|
1177 R128_COMPOSITE_SHADOW_CMP_EQUAL
|
1178 R128_TEX_MAP_ALPHA_IN_TEXTURE
|
1179 R128_TEX_CACHE_LINE_SIZE_4QW
);
1181 rmesa
->new_state
= R128_NEW_ALL
;
1184 /* Initialize the driver's state functions.
1186 void r128DDInitStateFuncs( GLcontext
*ctx
)
1188 ctx
->Driver
.UpdateState
= r128DDInvalidateState
;
1190 ctx
->Driver
.ClearIndex
= NULL
;
1191 ctx
->Driver
.ClearColor
= r128DDClearColor
;
1192 ctx
->Driver
.DrawBuffer
= r128DDDrawBuffer
;
1193 ctx
->Driver
.ReadBuffer
= r128DDReadBuffer
;
1195 ctx
->Driver
.IndexMask
= NULL
;
1196 ctx
->Driver
.ColorMask
= r128DDColorMask
;
1197 ctx
->Driver
.AlphaFunc
= r128DDAlphaFunc
;
1198 ctx
->Driver
.BlendEquation
= r128DDBlendEquation
;
1199 ctx
->Driver
.BlendFunc
= r128DDBlendFunc
;
1200 ctx
->Driver
.BlendFuncSeparate
= r128DDBlendFuncSeparate
;
1201 ctx
->Driver
.ClearDepth
= r128DDClearDepth
;
1202 ctx
->Driver
.CullFace
= r128DDCullFace
;
1203 ctx
->Driver
.FrontFace
= r128DDFrontFace
;
1204 ctx
->Driver
.DepthFunc
= r128DDDepthFunc
;
1205 ctx
->Driver
.DepthMask
= r128DDDepthMask
;
1206 ctx
->Driver
.Enable
= r128DDEnable
;
1207 ctx
->Driver
.Fogfv
= r128DDFogfv
;
1208 ctx
->Driver
.Hint
= NULL
;
1209 ctx
->Driver
.Lightfv
= NULL
;
1210 ctx
->Driver
.LightModelfv
= r128DDLightModelfv
;
1211 ctx
->Driver
.LogicOpcode
= r128DDLogicOpCode
;
1212 ctx
->Driver
.PolygonMode
= NULL
;
1213 ctx
->Driver
.PolygonStipple
= r128DDPolygonStipple
;
1214 ctx
->Driver
.RenderMode
= r128DDRenderMode
;
1215 ctx
->Driver
.Scissor
= r128DDScissor
;
1216 ctx
->Driver
.ShadeModel
= r128DDShadeModel
;
1217 ctx
->Driver
.ClearStencil
= NULL
;
1218 ctx
->Driver
.StencilFunc
= NULL
;
1219 ctx
->Driver
.StencilMask
= NULL
;
1220 ctx
->Driver
.StencilOp
= NULL
;
1222 ctx
->Driver
.DepthRange
= r128DepthRange
;
1223 ctx
->Driver
.Viewport
= r128Viewport
;
1225 /* Pixel path fallbacks.
1227 ctx
->Driver
.Accum
= _swrast_Accum
;
1228 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1229 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1230 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1231 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1233 /* Swrast hooks for imaging extensions:
1235 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1236 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1237 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1238 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;