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"
46 #include "swrast/swrast.h"
47 #include "array_cache/acache.h"
49 #include "swrast_setup/swrast_setup.h"
51 #include "tnl/t_pipeline.h"
54 /* =============================================================
60 * Calculate the hardware blend factor setting. This same function is used
61 * for source and destination of both alpha and RGB.
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
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.
73 static int blend_factor( r128ContextPtr rmesa
, GLenum factor
, GLboolean is_src
)
79 func
= R128_ALPHA_BLEND_ZERO
;
82 func
= R128_ALPHA_BLEND_ONE
;
86 func
= R128_ALPHA_BLEND_SRCCOLOR
;
88 case GL_ONE_MINUS_SRC_COLOR
:
89 func
= R128_ALPHA_BLEND_INVSRCCOLOR
;
92 func
= R128_ALPHA_BLEND_SRCALPHA
;
94 case GL_ONE_MINUS_SRC_ALPHA
:
95 func
= R128_ALPHA_BLEND_INVSRCALPHA
;
97 case GL_SRC_ALPHA_SATURATE
:
98 func
= (is_src
) ? R128_ALPHA_BLEND_SAT
: R128_ALPHA_BLEND_ZERO
;
102 func
= R128_ALPHA_BLEND_DSTCOLOR
;
104 case GL_ONE_MINUS_DST_COLOR
:
105 func
= R128_ALPHA_BLEND_INVDSTCOLOR
;
108 func
= R128_ALPHA_BLEND_DSTALPHA
;
110 case GL_ONE_MINUS_DST_ALPHA
:
111 func
= R128_ALPHA_BLEND_INVDSTALPHA
;
114 case GL_CONSTANT_COLOR
:
115 case GL_ONE_MINUS_CONSTANT_COLOR
:
116 case GL_CONSTANT_ALPHA
:
117 case GL_ONE_MINUS_CONSTANT_ALPHA
:
119 FALLBACK( rmesa
, R128_FALLBACK_BLEND_FUNC
, GL_TRUE
);
120 func
= (is_src
) ? R128_ALPHA_BLEND_ONE
: R128_ALPHA_BLEND_ZERO
;
128 static void r128UpdateAlphaMode( GLcontext
*ctx
)
130 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
131 GLuint a
= rmesa
->setup
.misc_3d_state_cntl_reg
;
132 GLuint t
= rmesa
->setup
.tex_cntl_c
;
134 if ( ctx
->Color
.AlphaEnabled
) {
137 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
139 a
&= ~(R128_ALPHA_TEST_MASK
| R128_REF_ALPHA_MASK
);
141 switch ( ctx
->Color
.AlphaFunc
) {
143 a
|= R128_ALPHA_TEST_NEVER
;
146 a
|= R128_ALPHA_TEST_LESS
;
149 a
|= R128_ALPHA_TEST_LESSEQUAL
;
152 a
|= R128_ALPHA_TEST_EQUAL
;
155 a
|= R128_ALPHA_TEST_GREATEREQUAL
;
158 a
|= R128_ALPHA_TEST_GREATER
;
161 a
|= R128_ALPHA_TEST_NEQUAL
;
164 a
|= R128_ALPHA_TEST_ALWAYS
;
168 a
|= ref
& R128_REF_ALPHA_MASK
;
169 t
|= R128_ALPHA_TEST_ENABLE
;
171 t
&= ~R128_ALPHA_TEST_ENABLE
;
174 FALLBACK( rmesa
, R128_FALLBACK_BLEND_FUNC
, GL_FALSE
);
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
);
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
;
186 switch (ctx
->Color
.BlendEquationRGB
) {
188 a
|= R128_ALPHA_COMB_ADD_CLAMP
;
190 case GL_FUNC_SUBTRACT
:
191 a
|= R128_ALPHA_COMB_SUB_SRC_DST_CLAMP
;
194 FALLBACK( rmesa
, R128_FALLBACK_BLEND_EQ
, GL_TRUE
);
197 t
|= R128_ALPHA_ENABLE
;
199 t
&= ~R128_ALPHA_ENABLE
;
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
;
206 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
207 rmesa
->setup
.tex_cntl_c
= t
;
208 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_MASKS
;
212 static void r128DDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
214 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
216 FLUSH_BATCH( rmesa
);
217 rmesa
->new_state
|= R128_NEW_ALPHA
;
220 static void r128DDBlendEquationSeparate( GLcontext
*ctx
,
221 GLenum modeRGB
, GLenum modeA
)
223 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
225 assert( modeRGB
== modeA
);
226 FLUSH_BATCH( rmesa
);
228 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
231 FALLBACK( R128_CONTEXT(ctx
), R128_FALLBACK_LOGICOP
,
232 (ctx
->Color
.ColorLogicOpEnabled
&&
233 ctx
->Color
.LogicOp
!= GL_COPY
));
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
));
239 rmesa
->new_state
|= R128_NEW_ALPHA
;
242 static void r128DDBlendFuncSeparate( GLcontext
*ctx
,
243 GLenum sfactorRGB
, GLenum dfactorRGB
,
244 GLenum sfactorA
, GLenum dfactorA
)
246 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
248 FLUSH_BATCH( rmesa
);
249 rmesa
->new_state
|= R128_NEW_ALPHA
;
253 /* =============================================================
257 static void r128UpdateZMode( GLcontext
*ctx
)
259 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
260 GLuint z
= rmesa
->setup
.z_sten_cntl_c
;
261 GLuint t
= rmesa
->setup
.tex_cntl_c
;
263 if ( ctx
->Depth
.Test
) {
264 z
&= ~R128_Z_TEST_MASK
;
266 switch ( ctx
->Depth
.Func
) {
268 z
|= R128_Z_TEST_NEVER
;
271 z
|= R128_Z_TEST_ALWAYS
;
274 z
|= R128_Z_TEST_LESS
;
277 z
|= R128_Z_TEST_LESSEQUAL
;
280 z
|= R128_Z_TEST_EQUAL
;
283 z
|= R128_Z_TEST_GREATEREQUAL
;
286 z
|= R128_Z_TEST_GREATER
;
289 z
|= R128_Z_TEST_NEQUAL
;
298 if ( ctx
->Depth
.Mask
) {
299 t
|= R128_Z_WRITE_ENABLE
;
301 t
&= ~R128_Z_WRITE_ENABLE
;
304 if ( rmesa
->setup
.z_sten_cntl_c
!= z
) {
305 rmesa
->setup
.z_sten_cntl_c
= z
;
306 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
308 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
309 rmesa
->setup
.tex_cntl_c
= t
;
310 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
314 static void r128DDDepthFunc( GLcontext
*ctx
, GLenum func
)
316 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
318 FLUSH_BATCH( rmesa
);
319 rmesa
->new_state
|= R128_NEW_DEPTH
;
322 static void r128DDDepthMask( GLcontext
*ctx
, GLboolean flag
)
324 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
326 FLUSH_BATCH( rmesa
);
327 rmesa
->new_state
|= R128_NEW_DEPTH
;
330 static void r128DDClearDepth( GLcontext
*ctx
, GLclampd d
)
332 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
334 switch ( rmesa
->setup
.z_sten_cntl_c
& R128_Z_PIX_WIDTH_MASK
) {
335 case R128_Z_PIX_WIDTH_16
:
336 rmesa
->ClearDepth
= d
* 0x0000ffff;
338 case R128_Z_PIX_WIDTH_24
:
339 rmesa
->ClearDepth
= d
* 0x00ffffff;
341 case R128_Z_PIX_WIDTH_32
:
342 rmesa
->ClearDepth
= d
* 0xffffffff;
348 /* =============================================================
352 static void r128UpdateFogAttrib( GLcontext
*ctx
)
354 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
355 GLuint t
= rmesa
->setup
.tex_cntl_c
;
359 if ( ctx
->Fog
.Enabled
) {
360 t
|= R128_FOG_ENABLE
;
362 t
&= ~R128_FOG_ENABLE
;
365 c
[0] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] );
366 c
[1] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] );
367 c
[2] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
369 col
= r128PackColor( 4, c
[0], c
[1], c
[2], 0 );
371 if ( rmesa
->setup
.fog_color_c
!= col
) {
372 rmesa
->setup
.fog_color_c
= col
;
373 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
375 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
376 rmesa
->setup
.tex_cntl_c
= t
;
377 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
381 static void r128DDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
383 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
385 FLUSH_BATCH( rmesa
);
386 rmesa
->new_state
|= R128_NEW_FOG
;
390 /* =============================================================
394 static void r128UpdateClipping( GLcontext
*ctx
)
396 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
398 if ( rmesa
->driDrawable
) {
399 __DRIdrawablePrivate
*drawable
= rmesa
->driDrawable
;
402 int x2
= drawable
->w
- 1;
403 int y2
= drawable
->h
- 1;
405 if ( ctx
->Scissor
.Enabled
) {
406 if ( ctx
->Scissor
.X
> x1
) {
409 if ( drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
> y1
) {
410 y1
= drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
412 if ( ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
) {
413 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
415 if ( drawable
->h
- ctx
->Scissor
.Y
- 1 < y2
) {
416 y2
= drawable
->h
- ctx
->Scissor
.Y
- 1;
425 rmesa
->setup
.sc_top_left_c
= ((y1
<< 16) | x1
);
426 rmesa
->setup
.sc_bottom_right_c
= ((y2
<< 16) | x2
);
428 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
432 static void r128DDScissor( GLcontext
*ctx
,
433 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
435 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
437 FLUSH_BATCH( rmesa
);
438 rmesa
->new_state
|= R128_NEW_CLIP
;
442 /* =============================================================
446 static void r128UpdateCull( GLcontext
*ctx
)
448 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
449 GLuint f
= rmesa
->setup
.pm4_vc_fpu_setup
;
451 f
&= ~R128_FRONT_DIR_MASK
;
453 switch ( ctx
->Polygon
.FrontFace
) {
455 f
|= R128_FRONT_DIR_CW
;
458 f
|= R128_FRONT_DIR_CCW
;
462 f
|= R128_BACKFACE_SOLID
| R128_FRONTFACE_SOLID
;
464 if ( ctx
->Polygon
.CullFlag
) {
465 switch ( ctx
->Polygon
.CullFaceMode
) {
467 f
&= ~R128_FRONTFACE_SOLID
;
470 f
&= ~R128_BACKFACE_SOLID
;
472 case GL_FRONT_AND_BACK
:
473 f
&= ~(R128_BACKFACE_SOLID
|
474 R128_FRONTFACE_SOLID
);
479 if ( 1 || rmesa
->setup
.pm4_vc_fpu_setup
!= f
) {
480 rmesa
->setup
.pm4_vc_fpu_setup
= f
;
481 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_SETUP
;
485 static void r128DDCullFace( GLcontext
*ctx
, GLenum mode
)
487 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
489 FLUSH_BATCH( rmesa
);
490 rmesa
->new_state
|= R128_NEW_CULL
;
493 static void r128DDFrontFace( GLcontext
*ctx
, GLenum mode
)
495 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
497 FLUSH_BATCH( rmesa
);
498 rmesa
->new_state
|= R128_NEW_CULL
;
502 /* =============================================================
506 static void r128UpdateMasks( GLcontext
*ctx
)
508 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
510 GLuint mask
= r128PackColor( rmesa
->r128Screen
->cpp
,
511 ctx
->Color
.ColorMask
[RCOMP
],
512 ctx
->Color
.ColorMask
[GCOMP
],
513 ctx
->Color
.ColorMask
[BCOMP
],
514 ctx
->Color
.ColorMask
[ACOMP
] );
516 if ( rmesa
->setup
.plane_3d_mask_c
!= mask
) {
517 rmesa
->setup
.plane_3d_mask_c
= mask
;
518 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_MASKS
;
522 static void r128DDColorMask( GLcontext
*ctx
,
523 GLboolean r
, GLboolean g
,
524 GLboolean b
, GLboolean a
)
526 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
528 FLUSH_BATCH( rmesa
);
529 rmesa
->new_state
|= R128_NEW_MASKS
;
533 /* =============================================================
534 * Rendering attributes
536 * We really don't want to recalculate all this every time we bind a
537 * texture. These things shouldn't change all that often, so it makes
538 * sense to break them out of the core texture state update routines.
541 static void updateSpecularLighting( GLcontext
*ctx
)
543 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
544 GLuint t
= rmesa
->setup
.tex_cntl_c
;
546 if ( ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
547 ctx
->Light
.Enabled
) {
548 /* XXX separate specular color just doesn't seem to work as it should.
549 * For now, we fall back to s/w rendering whenever separate specular
553 if (ctx
->Light
.ShadeModel
== GL_FLAT
) {
554 /* R128 can't do flat-shaded separate specular */
555 t
&= ~R128_SPEC_LIGHT_ENABLE
;
556 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_TRUE
);
557 /*printf("%s fallback sep spec\n", __FUNCTION__);*/
560 t
|= R128_SPEC_LIGHT_ENABLE
;
561 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_FALSE
);
562 /*printf("%s enable sep spec\n", __FUNCTION__);*/
565 t
&= ~R128_SPEC_LIGHT_ENABLE
;
566 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_TRUE
);
567 /*printf("%s fallback sep spec\n", __FUNCTION__);*/
571 t
&= ~R128_SPEC_LIGHT_ENABLE
;
572 FALLBACK( rmesa
, R128_FALLBACK_SEP_SPECULAR
, GL_FALSE
);
573 /*printf("%s disable sep spec\n", __FUNCTION__);*/
576 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
577 rmesa
->setup
.tex_cntl_c
= t
;
578 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
579 rmesa
->dirty
|= R128_UPLOAD_SETUP
;
580 rmesa
->new_state
|= R128_NEW_CONTEXT
;
585 static void r128DDLightModelfv( GLcontext
*ctx
, GLenum pname
,
586 const GLfloat
*param
)
588 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
590 if ( pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
591 FLUSH_BATCH( rmesa
);
592 updateSpecularLighting(ctx
);
596 static void r128DDShadeModel( GLcontext
*ctx
, GLenum mode
)
598 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
599 GLuint s
= rmesa
->setup
.pm4_vc_fpu_setup
;
601 s
&= ~R128_FPU_COLOR_MASK
;
605 s
|= R128_FPU_COLOR_FLAT
;
608 s
|= R128_FPU_COLOR_GOURAUD
;
614 updateSpecularLighting(ctx
);
616 if ( rmesa
->setup
.pm4_vc_fpu_setup
!= s
) {
617 FLUSH_BATCH( rmesa
);
618 rmesa
->setup
.pm4_vc_fpu_setup
= s
;
620 rmesa
->new_state
|= R128_NEW_CONTEXT
;
621 rmesa
->dirty
|= R128_UPLOAD_SETUP
;
626 /* =============================================================
630 void r128UpdateWindow( GLcontext
*ctx
)
632 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
633 int x
= rmesa
->driDrawable
->x
;
634 int y
= rmesa
->driDrawable
->y
;
636 rmesa
->setup
.window_xy_offset
= ((y
<< R128_WINDOW_Y_SHIFT
) |
637 (x
<< R128_WINDOW_X_SHIFT
));
639 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
| R128_UPLOAD_WINDOW
;
642 /* =============================================================
647 static void r128CalcViewport( GLcontext
*ctx
)
649 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
650 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
651 GLfloat
*m
= rmesa
->hw_viewport
;
653 /* See also r128_translate_vertex.
655 m
[MAT_SX
] = v
[MAT_SX
];
656 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
657 m
[MAT_SY
] = - v
[MAT_SY
];
658 m
[MAT_TY
] = - v
[MAT_TY
] + rmesa
->driDrawable
->h
+ SUBPIXEL_Y
;
659 m
[MAT_SZ
] = v
[MAT_SZ
] * rmesa
->depth_scale
;
660 m
[MAT_TZ
] = v
[MAT_TZ
] * rmesa
->depth_scale
;
663 static void r128Viewport( GLcontext
*ctx
,
665 GLsizei width
, GLsizei height
)
667 r128CalcViewport( ctx
);
670 static void r128DepthRange( GLcontext
*ctx
,
671 GLclampd nearval
, GLclampd farval
)
673 r128CalcViewport( ctx
);
677 /* =============================================================
681 static void r128DDClearColor( GLcontext
*ctx
,
682 const GLfloat color
[4] )
684 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
687 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
688 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
689 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
690 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
692 rmesa
->ClearColor
= r128PackColor( rmesa
->r128Screen
->cpp
,
693 c
[0], c
[1], c
[2], c
[3] );
696 static void r128DDLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
698 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
700 if ( ctx
->Color
.ColorLogicOpEnabled
) {
701 FLUSH_BATCH( rmesa
);
703 FALLBACK( rmesa
, R128_FALLBACK_LOGICOP
, opcode
!= GL_COPY
);
707 static void r128DDDrawBuffer( GLcontext
*ctx
, GLenum mode
)
709 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
711 FLUSH_BATCH( rmesa
);
714 * _DrawDestMask is easier to cope with than <mode>.
716 switch ( ctx
->Color
._DrawDestMask
[0] ) {
717 case DD_FRONT_LEFT_BIT
:
718 FALLBACK( rmesa
, R128_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
720 case DD_BACK_LEFT_BIT
:
721 FALLBACK( rmesa
, R128_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
724 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
725 FALLBACK( rmesa
, R128_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
729 /* We want to update the s/w rast state too so that r128DDSetBuffer()
732 _swrast_DrawBuffer(ctx
, mode
);
734 rmesa
->setup
.dst_pitch_offset_c
= (((rmesa
->drawPitch
/8) << 21) |
735 (rmesa
->drawOffset
>> 5));
736 rmesa
->new_state
|= R128_NEW_WINDOW
;
739 static void r128DDReadBuffer( GLcontext
*ctx
, GLenum mode
)
741 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
745 /* =============================================================
749 static void r128DDPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
751 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
752 GLuint stipple
[32], i
;
753 drm_r128_stipple_t stippleRec
;
755 for (i
= 0; i
< 32; i
++) {
756 stipple
[31 - i
] = ((mask
[i
*4+0] << 24) |
757 (mask
[i
*4+1] << 16) |
762 FLUSH_BATCH( rmesa
);
763 LOCK_HARDWARE( rmesa
);
765 stippleRec
.mask
= stipple
;
766 drmCommandWrite( rmesa
->driFd
, DRM_R128_STIPPLE
,
767 &stippleRec
, sizeof(stippleRec
) );
769 UNLOCK_HARDWARE( rmesa
);
771 rmesa
->new_state
|= R128_NEW_CONTEXT
;
772 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
776 /* =============================================================
780 static void r128DDRenderMode( GLcontext
*ctx
, GLenum mode
)
782 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
783 FALLBACK( rmesa
, R128_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
788 /* =============================================================
789 * State enable/disable
792 static void r128DDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
794 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
796 if ( R128_DEBUG
& DEBUG_VERBOSE_API
) {
797 fprintf( stderr
, "%s( %s = %s )\n",
798 __FUNCTION__
, _mesa_lookup_enum_by_nr( cap
),
799 state
? "GL_TRUE" : "GL_FALSE" );
804 FLUSH_BATCH( rmesa
);
805 rmesa
->new_state
|= R128_NEW_ALPHA
;
809 FLUSH_BATCH( rmesa
);
810 rmesa
->new_state
|= R128_NEW_ALPHA
;
812 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
814 FALLBACK( rmesa
, R128_FALLBACK_LOGICOP
,
815 (ctx
->Color
.ColorLogicOpEnabled
&&
816 ctx
->Color
.LogicOp
!= GL_COPY
));
820 FLUSH_BATCH( rmesa
);
821 rmesa
->new_state
|= R128_NEW_CULL
;
825 FLUSH_BATCH( rmesa
);
826 rmesa
->new_state
|= R128_NEW_DEPTH
;
831 GLuint t
= rmesa
->setup
.tex_cntl_c
;
832 FLUSH_BATCH( rmesa
);
834 if ( ctx
->Color
.DitherFlag
) {
835 t
|= R128_DITHER_ENABLE
;
837 t
&= ~R128_DITHER_ENABLE
;
840 if ( rmesa
->setup
.tex_cntl_c
!= t
) {
841 rmesa
->setup
.tex_cntl_c
= t
;
842 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
848 FLUSH_BATCH( rmesa
);
849 rmesa
->new_state
|= R128_NEW_FOG
;
852 case GL_COLOR_LOGIC_OP
:
853 FLUSH_BATCH( rmesa
);
854 FALLBACK( rmesa
, R128_FALLBACK_LOGICOP
,
855 state
&& ctx
->Color
.LogicOp
!= GL_COPY
);
859 updateSpecularLighting(ctx
);
862 case GL_SCISSOR_TEST
:
863 FLUSH_BATCH( rmesa
);
864 rmesa
->scissor
= state
;
865 rmesa
->new_state
|= R128_NEW_CLIP
;
868 case GL_STENCIL_TEST
:
869 FLUSH_BATCH( rmesa
);
870 FALLBACK( rmesa
, R128_FALLBACK_STENCIL
, state
);
876 FLUSH_BATCH( rmesa
);
879 case GL_POLYGON_STIPPLE
:
880 if ( rmesa
->render_primitive
== GL_TRIANGLES
) {
881 FLUSH_BATCH( rmesa
);
882 rmesa
->setup
.dp_gui_master_cntl_c
&= ~R128_GMC_BRUSH_NONE
;
884 rmesa
->setup
.dp_gui_master_cntl_c
|=
885 R128_GMC_BRUSH_32x32_MONO_FG_LA
;
887 rmesa
->setup
.dp_gui_master_cntl_c
|=
888 R128_GMC_BRUSH_SOLID_COLOR
;
890 rmesa
->new_state
|= R128_NEW_CONTEXT
;
891 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
901 /* =============================================================
902 * State initialization, management
905 static void r128DDPrintDirty( const char *msg
, GLuint state
)
908 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
911 (state
& R128_UPLOAD_CORE
) ? "core, " : "",
912 (state
& R128_UPLOAD_CONTEXT
) ? "context, " : "",
913 (state
& R128_UPLOAD_SETUP
) ? "setup, " : "",
914 (state
& R128_UPLOAD_TEX0
) ? "tex0, " : "",
915 (state
& R128_UPLOAD_TEX1
) ? "tex1, " : "",
916 (state
& R128_UPLOAD_MASKS
) ? "masks, " : "",
917 (state
& R128_UPLOAD_WINDOW
) ? "window, " : "",
918 (state
& R128_UPLOAD_CLIPRECTS
) ? "cliprects, " : "",
919 (state
& R128_REQUIRE_QUIESCENCE
) ? "quiescence, " : "" );
923 * Load the current context's state into the hardware.
925 * NOTE: Be VERY careful about ensuring the context state is marked for
926 * upload, the only place it shouldn't be uploaded is when the setup
927 * state has changed in ReducedPrimitiveChange as this comes right after
930 * Blits of any type should always upload the context and masks after
933 void r128EmitHwStateLocked( r128ContextPtr rmesa
)
935 drm_r128_sarea_t
*sarea
= rmesa
->sarea
;
936 drm_r128_context_regs_t
*regs
= &(rmesa
->setup
);
937 const r128TexObjPtr t0
= rmesa
->CurrentTexObj
[0];
938 const r128TexObjPtr t1
= rmesa
->CurrentTexObj
[1];
940 if ( R128_DEBUG
& DEBUG_VERBOSE_MSG
) {
941 r128DDPrintDirty( "r128EmitHwStateLocked", rmesa
->dirty
);
944 if ( rmesa
->dirty
& (R128_UPLOAD_CONTEXT
|
948 R128_UPLOAD_CORE
) ) {
949 memcpy( &sarea
->context_state
, regs
, sizeof(sarea
->context_state
) );
952 if ( (rmesa
->dirty
& R128_UPLOAD_TEX0
) && t0
) {
953 drm_r128_texture_regs_t
*tex
= &sarea
->tex_state
[0];
955 tex
->tex_cntl
= t0
->setup
.tex_cntl
;
956 tex
->tex_combine_cntl
= rmesa
->tex_combine
[0];
957 tex
->tex_size_pitch
= t0
->setup
.tex_size_pitch
;
958 memcpy( &tex
->tex_offset
[0], &t0
->setup
.tex_offset
[0],
959 sizeof(tex
->tex_offset
) );
960 tex
->tex_border_color
= t0
->setup
.tex_border_color
;
963 if ( (rmesa
->dirty
& R128_UPLOAD_TEX1
) && t1
) {
964 drm_r128_texture_regs_t
*tex
= &sarea
->tex_state
[1];
966 tex
->tex_cntl
= t1
->setup
.tex_cntl
;
967 tex
->tex_combine_cntl
= rmesa
->tex_combine
[1];
968 tex
->tex_size_pitch
= t1
->setup
.tex_size_pitch
;
969 memcpy( &tex
->tex_offset
[0], &t1
->setup
.tex_offset
[0],
970 sizeof(tex
->tex_offset
) );
971 tex
->tex_border_color
= t1
->setup
.tex_border_color
;
974 sarea
->vertsize
= rmesa
->vertex_size
;
975 sarea
->vc_format
= rmesa
->vertex_format
;
977 /* Turn off the texture cache flushing */
978 rmesa
->setup
.tex_cntl_c
&= ~R128_TEX_CACHE_FLUSH
;
980 sarea
->dirty
|= rmesa
->dirty
;
981 rmesa
->dirty
&= R128_UPLOAD_CLIPRECTS
;
984 static void r128DDPrintState( const char *msg
, GLuint flags
)
987 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
990 (flags
& R128_NEW_CONTEXT
) ? "context, " : "",
991 (flags
& R128_NEW_ALPHA
) ? "alpha, " : "",
992 (flags
& R128_NEW_DEPTH
) ? "depth, " : "",
993 (flags
& R128_NEW_FOG
) ? "fog, " : "",
994 (flags
& R128_NEW_CLIP
) ? "clip, " : "",
995 (flags
& R128_NEW_CULL
) ? "cull, " : "",
996 (flags
& R128_NEW_MASKS
) ? "masks, " : "",
997 (flags
& R128_NEW_WINDOW
) ? "window, " : "" );
1000 void r128DDUpdateHWState( GLcontext
*ctx
)
1002 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
1003 int new_state
= rmesa
->new_state
;
1005 if ( new_state
|| rmesa
->NewGLState
& _NEW_TEXTURE
)
1007 FLUSH_BATCH( rmesa
);
1009 rmesa
->new_state
= 0;
1011 if ( R128_DEBUG
& DEBUG_VERBOSE_MSG
)
1012 r128DDPrintState( "r128UpdateHwState", new_state
);
1014 /* Update the various parts of the context's state.
1016 if ( new_state
& R128_NEW_ALPHA
)
1017 r128UpdateAlphaMode( ctx
);
1019 if ( new_state
& R128_NEW_DEPTH
)
1020 r128UpdateZMode( ctx
);
1022 if ( new_state
& R128_NEW_FOG
)
1023 r128UpdateFogAttrib( ctx
);
1025 if ( new_state
& R128_NEW_CLIP
)
1026 r128UpdateClipping( ctx
);
1028 if ( new_state
& R128_NEW_CULL
)
1029 r128UpdateCull( ctx
);
1031 if ( new_state
& R128_NEW_MASKS
)
1032 r128UpdateMasks( ctx
);
1034 if ( new_state
& R128_NEW_WINDOW
)
1035 r128UpdateWindow( ctx
);
1037 if ( rmesa
->NewGLState
& _NEW_TEXTURE
) {
1038 r128UpdateTextureState( ctx
);
1044 static void r128DDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1046 _swrast_InvalidateState( ctx
, new_state
);
1047 _swsetup_InvalidateState( ctx
, new_state
);
1048 _ac_InvalidateState( ctx
, new_state
);
1049 _tnl_InvalidateState( ctx
, new_state
);
1050 R128_CONTEXT(ctx
)->NewGLState
|= new_state
;
1055 /* Initialize the context's hardware state.
1057 void r128DDInitState( r128ContextPtr rmesa
)
1059 int dst_bpp
, depth_bpp
;
1061 switch ( rmesa
->r128Screen
->cpp
) {
1063 dst_bpp
= R128_GMC_DST_16BPP
;
1066 dst_bpp
= R128_GMC_DST_32BPP
;
1069 fprintf( stderr
, "Error: Unsupported pixel depth... exiting\n" );
1073 rmesa
->ClearColor
= 0x00000000;
1075 switch ( rmesa
->glCtx
->Visual
.depthBits
) {
1077 rmesa
->ClearDepth
= 0x0000ffff;
1078 depth_bpp
= R128_Z_PIX_WIDTH_16
;
1079 rmesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
1082 rmesa
->ClearDepth
= 0x00ffffff;
1083 depth_bpp
= R128_Z_PIX_WIDTH_24
;
1084 rmesa
->depth_scale
= 1.0 / (GLfloat
)0xffffff;
1087 fprintf( stderr
, "Error: Unsupported depth %d... exiting\n",
1088 rmesa
->glCtx
->Visual
.depthBits
);
1092 rmesa
->Fallback
= 0;
1094 if ( rmesa
->glCtx
->Visual
.doubleBufferMode
&& rmesa
->sarea
->pfCurrentPage
== 0 ) {
1095 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
1096 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
1098 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
1099 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
1104 rmesa
->setup
.dst_pitch_offset_c
= (((rmesa
->drawPitch
/8) << 21) |
1105 (rmesa
->drawOffset
>> 5));
1107 rmesa
->setup
.dp_gui_master_cntl_c
= (R128_GMC_DST_PITCH_OFFSET_CNTL
|
1108 R128_GMC_DST_CLIPPING
|
1109 R128_GMC_BRUSH_SOLID_COLOR
|
1111 R128_GMC_SRC_DATATYPE_COLOR
|
1112 R128_GMC_BYTE_MSB_TO_LSB
|
1113 R128_GMC_CONVERSION_TEMP_6500
|
1115 R128_DP_SRC_SOURCE_MEMORY
|
1116 R128_GMC_3D_FCN_EN
|
1117 R128_GMC_CLR_CMP_CNTL_DIS
|
1118 R128_GMC_AUX_CLIP_DIS
|
1119 R128_GMC_WR_MSK_DIS
);
1121 rmesa
->setup
.sc_top_left_c
= 0x00000000;
1122 rmesa
->setup
.sc_bottom_right_c
= 0x1fff1fff;
1124 rmesa
->setup
.z_offset_c
= rmesa
->r128Screen
->depthOffset
;
1125 rmesa
->setup
.z_pitch_c
= ((rmesa
->r128Screen
->depthPitch
>> 3) |
1128 rmesa
->setup
.z_sten_cntl_c
= (depth_bpp
|
1130 R128_STENCIL_TEST_ALWAYS
|
1131 R128_STENCIL_S_FAIL_KEEP
|
1132 R128_STENCIL_ZPASS_KEEP
|
1133 R128_STENCIL_ZFAIL_KEEP
);
1135 rmesa
->setup
.tex_cntl_c
= (R128_Z_WRITE_ENABLE
|
1137 R128_DITHER_ENABLE
|
1138 R128_ALPHA_IN_TEX_COMPLETE_A
|
1140 R128_ALPHA_LIGHT_DIS
|
1141 R128_TEX_CACHE_FLUSH
|
1142 (0x3f << R128_LOD_BIAS_SHIFT
));
1144 rmesa
->setup
.misc_3d_state_cntl_reg
= (R128_MISC_SCALE_3D_TEXMAP_SHADE
|
1145 R128_MISC_SCALE_PIX_REPLICATE
|
1146 R128_ALPHA_COMB_ADD_CLAMP
|
1148 (R128_ALPHA_BLEND_ONE
<< R128_ALPHA_BLEND_SRC_SHIFT
) |
1149 (R128_ALPHA_BLEND_ZERO
<< R128_ALPHA_BLEND_DST_SHIFT
) |
1150 R128_ALPHA_TEST_ALWAYS
);
1152 rmesa
->setup
.texture_clr_cmp_clr_c
= 0x00000000;
1153 rmesa
->setup
.texture_clr_cmp_msk_c
= 0xffffffff;
1155 rmesa
->setup
.fog_color_c
= 0x00000000;
1157 rmesa
->setup
.pm4_vc_fpu_setup
= (R128_FRONT_DIR_CCW
|
1158 R128_BACKFACE_SOLID
|
1159 R128_FRONTFACE_SOLID
|
1160 R128_FPU_COLOR_GOURAUD
|
1161 R128_FPU_SUB_PIX_4BITS
|
1163 R128_TRAP_BITS_DISABLE
|
1166 R128_FLAT_SHADE_VERTEX_OGL
|
1167 R128_FPU_ROUND_TRUNCATE
|
1170 rmesa
->setup
.setup_cntl
= (R128_COLOR_GOURAUD
|
1171 R128_PRIM_TYPE_TRI
|
1172 R128_TEXTURE_ST_MULT_W
|
1173 R128_STARTING_VERTEX_1
|
1174 R128_ENDING_VERTEX_3
|
1175 R128_SU_POLY_LINE_NOT_LAST
|
1176 R128_SUB_PIX_4BITS
);
1178 rmesa
->setup
.tex_size_pitch_c
= 0x00000000;
1179 rmesa
->setup
.constant_color_c
= 0x00ffffff;
1181 rmesa
->setup
.dp_write_mask
= 0xffffffff;
1182 rmesa
->setup
.sten_ref_mask_c
= 0xffff0000;
1183 rmesa
->setup
.plane_3d_mask_c
= 0xffffffff;
1185 rmesa
->setup
.window_xy_offset
= 0x00000000;
1187 rmesa
->setup
.scale_3d_cntl
= (R128_SCALE_DITHER_TABLE
|
1188 R128_TEX_CACHE_SIZE_FULL
|
1189 R128_DITHER_INIT_RESET
|
1190 R128_SCALE_3D_TEXMAP_SHADE
|
1191 R128_SCALE_PIX_REPLICATE
|
1192 R128_ALPHA_COMB_ADD_CLAMP
|
1194 (R128_ALPHA_BLEND_ONE
<< R128_ALPHA_BLEND_SRC_SHIFT
) |
1195 (R128_ALPHA_BLEND_ZERO
<< R128_ALPHA_BLEND_DST_SHIFT
) |
1196 R128_ALPHA_TEST_ALWAYS
|
1197 R128_COMPOSITE_SHADOW_CMP_EQUAL
|
1198 R128_TEX_MAP_ALPHA_IN_TEXTURE
|
1199 R128_TEX_CACHE_LINE_SIZE_4QW
);
1201 rmesa
->new_state
= R128_NEW_ALL
;
1204 /* Initialize the driver's state functions.
1206 void r128DDInitStateFuncs( GLcontext
*ctx
)
1208 ctx
->Driver
.UpdateState
= r128DDInvalidateState
;
1210 ctx
->Driver
.ClearIndex
= NULL
;
1211 ctx
->Driver
.ClearColor
= r128DDClearColor
;
1212 ctx
->Driver
.DrawBuffer
= r128DDDrawBuffer
;
1213 ctx
->Driver
.ReadBuffer
= r128DDReadBuffer
;
1215 ctx
->Driver
.IndexMask
= NULL
;
1216 ctx
->Driver
.ColorMask
= r128DDColorMask
;
1217 ctx
->Driver
.AlphaFunc
= r128DDAlphaFunc
;
1218 ctx
->Driver
.BlendEquationSeparate
= r128DDBlendEquationSeparate
;
1219 ctx
->Driver
.BlendFuncSeparate
= r128DDBlendFuncSeparate
;
1220 ctx
->Driver
.ClearDepth
= r128DDClearDepth
;
1221 ctx
->Driver
.CullFace
= r128DDCullFace
;
1222 ctx
->Driver
.FrontFace
= r128DDFrontFace
;
1223 ctx
->Driver
.DepthFunc
= r128DDDepthFunc
;
1224 ctx
->Driver
.DepthMask
= r128DDDepthMask
;
1225 ctx
->Driver
.Enable
= r128DDEnable
;
1226 ctx
->Driver
.Fogfv
= r128DDFogfv
;
1227 ctx
->Driver
.Hint
= NULL
;
1228 ctx
->Driver
.Lightfv
= NULL
;
1229 ctx
->Driver
.LightModelfv
= r128DDLightModelfv
;
1230 ctx
->Driver
.LogicOpcode
= r128DDLogicOpCode
;
1231 ctx
->Driver
.PolygonMode
= NULL
;
1232 ctx
->Driver
.PolygonStipple
= r128DDPolygonStipple
;
1233 ctx
->Driver
.RenderMode
= r128DDRenderMode
;
1234 ctx
->Driver
.Scissor
= r128DDScissor
;
1235 ctx
->Driver
.ShadeModel
= r128DDShadeModel
;
1236 ctx
->Driver
.ClearStencil
= NULL
;
1237 ctx
->Driver
.StencilFunc
= NULL
;
1238 ctx
->Driver
.StencilMask
= NULL
;
1239 ctx
->Driver
.StencilOp
= NULL
;
1241 ctx
->Driver
.DepthRange
= r128DepthRange
;
1242 ctx
->Driver
.Viewport
= r128Viewport
;
1244 /* Pixel path fallbacks.
1246 ctx
->Driver
.Accum
= _swrast_Accum
;
1247 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1248 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1249 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1250 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1252 /* Swrast hooks for imaging extensions:
1254 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1255 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1256 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1257 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;