2 * Copyright 2000-2001 VA Linux Systems, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keith@tungstengraphics.com>
27 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */
35 #include "mgacontext.h"
43 #include "mgabuffers.h"
45 #include "swrast/swrast.h"
46 #include "array_cache/acache.h"
48 #include "swrast_setup/swrast_setup.h"
52 /* Some outstanding problems with accelerating logic ops...
54 #if defined(ACCEL_ROP)
55 static GLuint mgarop_NoBLK
[16] = {
56 DC_atype_rpl
| 0x00000000, DC_atype_rstr
| 0x00080000,
57 DC_atype_rstr
| 0x00040000, DC_atype_rpl
| 0x000c0000,
58 DC_atype_rstr
| 0x00020000, DC_atype_rstr
| 0x000a0000,
59 DC_atype_rstr
| 0x00060000, DC_atype_rstr
| 0x000e0000,
60 DC_atype_rstr
| 0x00010000, DC_atype_rstr
| 0x00090000,
61 DC_atype_rstr
| 0x00050000, DC_atype_rstr
| 0x000d0000,
62 DC_atype_rpl
| 0x00030000, DC_atype_rstr
| 0x000b0000,
63 DC_atype_rstr
| 0x00070000, DC_atype_rpl
| 0x000f0000
68 static void mgaUpdateStencil(const GLcontext
*ctx
)
70 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
71 GLuint stencil
= 0, stencilctl
= 0;
73 if (ctx
->Stencil
.Enabled
)
75 stencil
= ctx
->Stencil
.Ref
[0] |
76 ( ctx
->Stencil
.ValueMask
[0] << 8 ) |
77 ( ctx
->Stencil
.WriteMask
[0] << 16 );
79 switch (ctx
->Stencil
.Function
[0])
82 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_snever
);
85 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_slt
);
88 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_slte
);
91 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_sgt
);
94 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_sgte
);
97 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_sne
);
100 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_se
);
103 MGA_SET_FIELD(stencilctl
, SC_smode_MASK
, SC_smode_salways
);
108 switch (ctx
->Stencil
.FailFunc
[0])
111 MGA_SET_FIELD(stencilctl
, SC_sfailop_MASK
, SC_sfailop_keep
);
114 MGA_SET_FIELD(stencilctl
, SC_sfailop_MASK
, SC_sfailop_zero
);
117 MGA_SET_FIELD(stencilctl
, SC_sfailop_MASK
, SC_sfailop_replace
);
120 MGA_SET_FIELD(stencilctl
, SC_sfailop_MASK
, SC_sfailop_incrsat
);
123 MGA_SET_FIELD(stencilctl
, SC_sfailop_MASK
, SC_sfailop_decrsat
);
126 MGA_SET_FIELD(stencilctl
, SC_sfailop_MASK
, SC_sfailop_invert
);
132 switch (ctx
->Stencil
.ZFailFunc
[0])
135 MGA_SET_FIELD(stencilctl
, SC_szfailop_MASK
, SC_szfailop_keep
);
138 MGA_SET_FIELD(stencilctl
, SC_szfailop_MASK
, SC_szfailop_zero
);
141 MGA_SET_FIELD(stencilctl
, SC_szfailop_MASK
, SC_szfailop_replace
);
144 MGA_SET_FIELD(stencilctl
, SC_szfailop_MASK
, SC_szfailop_incrsat
);
147 MGA_SET_FIELD(stencilctl
, SC_szfailop_MASK
, SC_szfailop_decrsat
);
150 MGA_SET_FIELD(stencilctl
, SC_szfailop_MASK
, SC_szfailop_invert
);
156 switch (ctx
->Stencil
.ZPassFunc
[0])
159 MGA_SET_FIELD(stencilctl
, SC_szpassop_MASK
, SC_szpassop_keep
);
162 MGA_SET_FIELD(stencilctl
, SC_szpassop_MASK
, SC_szpassop_zero
);
165 MGA_SET_FIELD(stencilctl
, SC_szpassop_MASK
, SC_szpassop_replace
);
168 MGA_SET_FIELD(stencilctl
, SC_szpassop_MASK
, SC_szpassop_incrsat
);
171 MGA_SET_FIELD(stencilctl
, SC_szpassop_MASK
, SC_szpassop_decrsat
);
174 MGA_SET_FIELD(stencilctl
, SC_szpassop_MASK
, SC_szpassop_invert
);
181 mmesa
->setup
.stencil
= stencil
;
182 mmesa
->setup
.stencilctl
= stencilctl
;
183 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
186 static void mgaDDStencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
189 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
190 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_STENCIL
;
193 static void mgaDDStencilMask(GLcontext
*ctx
, GLuint mask
)
195 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
196 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_STENCIL
;
199 static void mgaDDStencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
202 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
203 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_STENCIL
;
206 static void mgaDDClearDepth(GLcontext
*ctx
, GLclampd d
)
208 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
210 /* KW: should the ~ be there? */
211 switch (mmesa
->setup
.maccess
& ~MA_zwidth_MASK
) {
212 case MA_zwidth_16
: mmesa
->ClearDepth
= d
* 0x0000ffff; break;
213 case MA_zwidth_24
: mmesa
->ClearDepth
= d
* 0xffffff00; break;
214 case MA_zwidth_32
: mmesa
->ClearDepth
= d
* 0xffffffff; break;
219 static void mgaUpdateZMode(const GLcontext
*ctx
)
221 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
224 if (ctx
->Depth
.Test
) {
225 switch(ctx
->Depth
.Func
) {
227 /* can't do this in h/w, we'll use a s/w fallback */
228 zmode
= DC_zmode_nozcmp
;
231 zmode
= DC_zmode_nozcmp
; break;
233 zmode
= DC_zmode_zlt
; break;
235 zmode
= DC_zmode_zlte
; break;
237 zmode
= DC_zmode_ze
; break;
239 zmode
= DC_zmode_zgt
; break;
241 zmode
= DC_zmode_zgte
; break;
243 zmode
= DC_zmode_zne
; break;
249 zmode
|= DC_atype_zi
;
254 zmode
|= DC_zmode_nozcmp
;
255 zmode
|= DC_atype_i
; /* don't write to zbuffer */
258 #if defined(ACCEL_ROP)
259 mmesa
->setup
.dwgctl
&= DC_bop_MASK
;
260 if (ctx
->Color
.ColorLogicOpEnabled
)
261 zmode
|= mgarop_NoBLK
[(ctx
->Color
.LogicOp
)&0xf];
263 zmode
|= mgarop_NoBLK
[GL_COPY
& 0xf];
266 mmesa
->setup
.dwgctl
&= DC_zmode_MASK
& DC_atype_MASK
;
267 mmesa
->setup
.dwgctl
|= zmode
;
268 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
272 static void mgaDDAlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
274 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
275 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_ALPHA
;
279 static void mgaDDBlendEquation(GLcontext
*ctx
, GLenum mode
)
281 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
282 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_ALPHA
;
284 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
287 FALLBACK( ctx
, MGA_FALLBACK_LOGICOP
,
288 (ctx
->Color
.ColorLogicOpEnabled
&&
289 ctx
->Color
.LogicOp
!= GL_COPY
));
292 static void mgaDDBlendFunc(GLcontext
*ctx
, GLenum sfactor
, GLenum dfactor
)
294 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
295 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_ALPHA
;
298 static void mgaDDBlendFuncSeparate( GLcontext
*ctx
, GLenum sfactorRGB
,
299 GLenum dfactorRGB
, GLenum sfactorA
,
302 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
303 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_ALPHA
;
308 static void mgaDDLightModelfv(GLcontext
*ctx
, GLenum pname
,
309 const GLfloat
*param
)
311 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
312 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
313 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_TEXTURE
;
318 static void mgaDDShadeModel(GLcontext
*ctx
, GLenum mode
)
320 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
321 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_TEXTURE
;
325 static void mgaDDDepthFunc(GLcontext
*ctx
, GLenum func
)
327 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
328 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_DEPTH
;
331 static void mgaDDDepthMask(GLcontext
*ctx
, GLboolean flag
)
333 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
334 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_DEPTH
;
337 #if defined(ACCEL_ROP)
338 static void mgaDDLogicOp( GLcontext
*ctx
, GLenum opcode
)
340 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
341 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_DEPTH
;
344 static void mgaDDLogicOp( GLcontext
*ctx
, GLenum opcode
)
346 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
347 FALLBACK( ctx
, MGA_FALLBACK_LOGICOP
,
348 (ctx
->Color
.ColorLogicOpEnabled
&& opcode
!= GL_COPY
) );
354 static void mgaDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
356 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
358 if (pname
== GL_FOG_COLOR
) {
359 GLuint color
= MGAPACKCOLOR888((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
),
360 (GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
),
361 (GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
));
363 MGA_STATECHANGE(mmesa
, MGA_UPLOAD_CONTEXT
);
364 mmesa
->setup
.fogcolor
= color
;
371 /* =============================================================
376 static void mgaUpdateAlphaMode(GLcontext
*ctx
)
378 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
379 mgaScreenPrivate
*mgaScreen
= mmesa
->mgaScreen
;
382 /* determine source of alpha for blending and testing */
383 if ( !ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
384 a
|= AC_alphasel_diffused
;
387 /* G400: Regardless of texture env mode, we use the alpha from the
388 * texture unit (AC_alphasel_fromtex) since it will have already
389 * been modulated by the incoming fragment color, if needed.
390 * We don't want (AC_alphasel_modulate) since that'll effectively
391 * do the modulation twice.
393 if (MGA_IS_G400(mmesa
)) {
394 a
|= AC_alphasel_fromtex
;
398 switch (ctx
->Texture
.Unit
[0].EnvMode
) {
400 a
|= AC_alphasel_diffused
;
402 a
|= AC_alphasel_fromtex
;
406 a
|= AC_alphasel_modulated
;
415 /* alpha test control.
417 if (ctx
->Color
.AlphaEnabled
) {
418 GLubyte ref
= ctx
->Color
.AlphaRef
;
419 switch (ctx
->Color
.AlphaFunc
) {
443 a
|= AC_atmode_noacmp
;
448 a
|= MGA_FIELD(AC_atref
,ref
);
451 /* blending control */
452 if (ctx
->Color
.BlendEnabled
) {
453 switch (ctx
->Color
.BlendSrcRGB
) {
455 a
|= AC_src_zero
; break;
457 a
|= AC_src_src_alpha
; break;
459 a
|= AC_src_one
; break;
461 a
|= AC_src_dst_color
; break;
462 case GL_ONE_MINUS_DST_COLOR
:
463 a
|= AC_src_om_dst_color
; break;
464 case GL_ONE_MINUS_SRC_ALPHA
:
465 a
|= AC_src_om_src_alpha
; break;
467 if (mgaScreen
->cpp
== 4)
468 a
|= AC_src_dst_alpha
;
472 case GL_ONE_MINUS_DST_ALPHA
:
473 if (mgaScreen
->cpp
== 4)
474 a
|= AC_src_om_dst_alpha
;
478 case GL_SRC_ALPHA_SATURATE
:
479 if (ctx
->Visual
.alphaBits
> 0)
480 a
|= AC_src_src_alpha_sat
;
484 default: /* never happens */
488 switch (ctx
->Color
.BlendDstRGB
) {
490 a
|= AC_dst_src_alpha
; break;
491 case GL_ONE_MINUS_SRC_ALPHA
:
492 a
|= AC_dst_om_src_alpha
; break;
494 a
|= AC_dst_zero
; break;
496 a
|= AC_dst_one
; break;
498 a
|= AC_dst_src_color
; break;
499 case GL_ONE_MINUS_SRC_COLOR
:
500 a
|= AC_dst_om_src_color
; break;
502 if (mgaScreen
->cpp
== 4)
503 a
|= AC_dst_dst_alpha
;
507 case GL_ONE_MINUS_DST_ALPHA
:
508 if (mgaScreen
->cpp
== 4)
509 a
|= AC_dst_om_dst_alpha
;
513 default: /* never happens */
517 a
|= AC_src_one
|AC_dst_zero
;
520 mmesa
->setup
.alphactrl
= (AC_amode_alpha_channel
|
521 AC_astipple_disable
|
526 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
531 /* =============================================================
535 void mgaUpdateClipping(const GLcontext
*ctx
)
537 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
539 if (mmesa
->driDrawable
)
541 int x1
= mmesa
->driDrawable
->x
+ ctx
->Scissor
.X
;
542 int y1
= mmesa
->driDrawable
->y
+ mmesa
->driDrawable
->h
543 - (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
);
544 int x2
= x1
+ ctx
->Scissor
.Width
- 1;
545 int y2
= y1
+ ctx
->Scissor
.Height
- 1;
552 mmesa
->scissor_rect
.x1
= x1
;
553 mmesa
->scissor_rect
.y1
= y1
;
554 mmesa
->scissor_rect
.x2
= x2
;
555 mmesa
->scissor_rect
.y2
= y2
;
557 if (MGA_DEBUG
&DEBUG_VERBOSE_2D
)
558 fprintf(stderr
, "SET SCISSOR %d,%d-%d,%d\n",
559 mmesa
->scissor_rect
.x1
,
560 mmesa
->scissor_rect
.y1
,
561 mmesa
->scissor_rect
.x2
,
562 mmesa
->scissor_rect
.y2
);
564 mmesa
->dirty
|= MGA_UPLOAD_CLIPRECTS
;
569 static void mgaDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
570 GLsizei w
, GLsizei h
)
572 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
573 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_CLIP
;
577 static void mgaDDClearColor(GLcontext
*ctx
,
578 const GLfloat color
[4] )
580 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
582 mmesa
->ClearColor
= mgaPackColor( mmesa
->mgaScreen
->cpp
,
588 /* =============================================================
592 #define _CULL_DISABLE 0
593 #define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
594 #define _CULL_POSITIVE (1<<11)
597 void mgaUpdateCull( GLcontext
*ctx
)
599 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
600 GLuint mode
= _CULL_DISABLE
;
602 if (ctx
->Polygon
.CullFlag
&&
603 mmesa
->raster_primitive
== GL_TRIANGLES
&&
604 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
606 mode
= _CULL_NEGATIVE
;
607 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
608 mode
^= (_CULL_POSITIVE
^ _CULL_NEGATIVE
);
609 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
610 mode
^= (_CULL_POSITIVE
^ _CULL_NEGATIVE
);
611 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& TEXTURE_2D_BIT
) &&
612 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& TEXTURE_2D_BIT
))
613 mode
^= (_CULL_POSITIVE
^ _CULL_NEGATIVE
); /* warp bug? */
616 mmesa
->setup
.wflag
= mode
;
617 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
621 static void mgaDDCullFaceFrontFace(GLcontext
*ctx
, GLenum mode
)
623 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
624 MGA_CONTEXT(ctx
)->new_state
|= MGA_NEW_CULL
;
630 /* =============================================================
634 static void mgaDDColorMask(GLcontext
*ctx
,
635 GLboolean r
, GLboolean g
,
636 GLboolean b
, GLboolean a
)
638 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
639 mgaScreenPrivate
*mgaScreen
= mmesa
->mgaScreen
;
642 GLuint mask
= mgaPackColor(mgaScreen
->cpp
,
643 ctx
->Color
.ColorMask
[RCOMP
],
644 ctx
->Color
.ColorMask
[GCOMP
],
645 ctx
->Color
.ColorMask
[BCOMP
],
646 ctx
->Color
.ColorMask
[ACOMP
]);
648 if (mgaScreen
->cpp
== 2)
649 mask
= mask
| (mask
<< 16);
651 if (mmesa
->setup
.plnwt
!= mask
) {
652 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
653 mmesa
->setup
.plnwt
= mask
;
657 /* =============================================================
660 * The mga supports a subset of possible 4x4 stipples natively, GL
661 * wants 32x32. Fortunately stipple is usually a repeating pattern.
663 * Note: the fully opaque pattern (0xffff) has been disabled in order
664 * to work around a conformance issue.
666 static int mgaStipples
[16] = {
667 0xffff1, /* See above note */
685 static void mgaDDPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
687 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
688 const GLubyte
*m
= mask
;
691 int active
= (ctx
->Polygon
.StippleFlag
&&
692 mmesa
->raster_primitive
== GL_TRIANGLES
);
696 mmesa
->haveHwStipple
= 0;
699 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
700 mmesa
->setup
.dwgctl
&= ~(0xf<<20);
703 p
[0] = mask
[0] & 0xf; p
[0] |= p
[0] << 4;
704 p
[1] = mask
[4] & 0xf; p
[1] |= p
[1] << 4;
705 p
[2] = mask
[8] & 0xf; p
[2] |= p
[2] << 4;
706 p
[3] = mask
[12] & 0xf; p
[3] |= p
[3] << 4;
708 for (k
= 0 ; k
< 8 ; k
++)
709 for (j
= 0 ; j
< 4; j
++)
710 for (i
= 0 ; i
< 4 ; i
++)
715 stipple
= ( ((p
[0] & 0xf) << 0) |
716 ((p
[1] & 0xf) << 4) |
717 ((p
[2] & 0xf) << 8) |
718 ((p
[3] & 0xf) << 12) );
720 for (i
= 0 ; i
< 16 ; i
++)
721 if (mgaStipples
[i
] == stipple
) {
722 mmesa
->poly_stipple
= i
<<20;
723 mmesa
->haveHwStipple
= 1;
728 mmesa
->setup
.dwgctl
&= ~(0xf<<20);
729 mmesa
->setup
.dwgctl
|= mmesa
->poly_stipple
;
733 /* =============================================================
736 static void mgaDDPrintDirty( const char *msg
, GLuint state
)
738 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s%s\n",
740 (unsigned int) state
,
741 (state
& MGA_WAIT_AGE
) ? "wait-age, " : "",
742 (state
& MGA_UPLOAD_TEX0IMAGE
) ? "upload-tex0-img, " : "",
743 (state
& MGA_UPLOAD_TEX1IMAGE
) ? "upload-tex1-img, " : "",
744 (state
& MGA_UPLOAD_CONTEXT
) ? "upload-ctx, " : "",
745 (state
& MGA_UPLOAD_TEX0
) ? "upload-tex0, " : "",
746 (state
& MGA_UPLOAD_TEX1
) ? "upload-tex1, " : "",
747 (state
& MGA_UPLOAD_PIPE
) ? "upload-pipe, " : ""
751 /* Push the state into the sarea and/or texture memory.
753 void mgaEmitHwStateLocked( mgaContextPtr mmesa
)
755 MGASAREAPrivPtr sarea
= mmesa
->sarea
;
757 if (MGA_DEBUG
& DEBUG_VERBOSE_MSG
)
758 mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa
->dirty
);
760 if ((mmesa
->dirty
& MGA_UPLOAD_TEX0IMAGE
) && mmesa
->CurrentTexObj
[0])
761 mgaUploadTexImages(mmesa
, mmesa
->CurrentTexObj
[0]);
763 if ((mmesa
->dirty
& MGA_UPLOAD_TEX1IMAGE
) && mmesa
->CurrentTexObj
[1])
764 mgaUploadTexImages(mmesa
, mmesa
->CurrentTexObj
[1]);
766 if (mmesa
->dirty
& MGA_UPLOAD_CONTEXT
) {
767 memcpy( &sarea
->ContextState
, &mmesa
->setup
, sizeof(mmesa
->setup
));
770 if ((mmesa
->dirty
& MGA_UPLOAD_TEX0
) && mmesa
->CurrentTexObj
[0]) {
771 memcpy(&sarea
->TexState
[0],
772 &mmesa
->CurrentTexObj
[0]->setup
,
773 sizeof(sarea
->TexState
[0]));
776 if ((mmesa
->dirty
& MGA_UPLOAD_TEX1
) && mmesa
->CurrentTexObj
[1]) {
777 memcpy(&sarea
->TexState
[1],
778 &mmesa
->CurrentTexObj
[1]->setup
,
779 sizeof(sarea
->TexState
[1]));
782 if (sarea
->TexState
[0].texctl2
!=
783 sarea
->TexState
[1].texctl2
) {
784 memcpy(&sarea
->TexState
[1],
786 sizeof(sarea
->TexState
[0]));
787 mmesa
->dirty
|= MGA_UPLOAD_TEX1
|MGA_UPLOAD_TEX0
;
790 if (mmesa
->dirty
& MGA_UPLOAD_PIPE
) {
791 /* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
792 mmesa
->sarea
->WarpPipe
= mmesa
->vertex_format
;
793 mmesa
->sarea
->vertsize
= mmesa
->vertex_size
;
796 mmesa
->sarea
->dirty
|= mmesa
->dirty
;
798 mmesa
->dirty
&= (MGA_UPLOAD_CLIPRECTS
|MGA_WAIT_AGE
);
800 /* This is a bit of a hack but seems to be the best place to ensure
801 * that separate specular is disabled when not needed.
803 if (mmesa
->glCtx
->Texture
.Unit
[0]._ReallyEnabled
== 0 ||
804 !mmesa
->glCtx
->Light
.Enabled
||
805 mmesa
->glCtx
->Light
.Model
.ColorControl
== GL_SINGLE_COLOR
) {
806 sarea
->TexState
[0].texctl2
&= ~TMC_specen_enable
;
807 sarea
->TexState
[1].texctl2
&= ~TMC_specen_enable
;
811 /* Fallback to swrast for select and feedback.
813 static void mgaRenderMode( GLcontext
*ctx
, GLenum mode
)
815 FALLBACK( ctx
, MGA_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
819 /* =============================================================
822 void mgaCalcViewport( GLcontext
*ctx
)
824 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
825 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
826 GLfloat
*m
= mmesa
->hw_viewport
;
828 /* See also mga_translate_vertex.
830 m
[MAT_SX
] = v
[MAT_SX
];
831 m
[MAT_TX
] = v
[MAT_TX
] + mmesa
->drawX
+ SUBPIXEL_X
;
832 m
[MAT_SY
] = - v
[MAT_SY
];
833 m
[MAT_TY
] = - v
[MAT_TY
] + mmesa
->driDrawable
->h
+ mmesa
->drawY
+ SUBPIXEL_Y
;
834 m
[MAT_SZ
] = v
[MAT_SZ
] * mmesa
->depth_scale
;
835 m
[MAT_TZ
] = v
[MAT_TZ
] * mmesa
->depth_scale
;
837 mmesa
->SetupNewInputs
= ~0;
840 static void mgaViewport( GLcontext
*ctx
,
842 GLsizei width
, GLsizei height
)
844 mgaCalcViewport( ctx
);
847 static void mgaDepthRange( GLcontext
*ctx
,
848 GLclampd nearval
, GLclampd farval
)
850 mgaCalcViewport( ctx
);
853 /* =============================================================
856 static void mgaDDEnable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
858 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
862 FLUSH_BATCH( mmesa
);
863 mmesa
->new_state
|= MGA_NEW_ALPHA
;
866 FLUSH_BATCH( mmesa
);
867 mmesa
->new_state
|= MGA_NEW_ALPHA
;
869 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
871 FALLBACK( ctx
, MGA_FALLBACK_LOGICOP
,
872 (ctx
->Color
.ColorLogicOpEnabled
&&
873 ctx
->Color
.LogicOp
!= GL_COPY
));
876 FLUSH_BATCH( mmesa
);
877 mmesa
->new_state
|= MGA_NEW_DEPTH
;
878 FALLBACK (ctx
, MGA_FALLBACK_DEPTH
,
879 ctx
->Depth
.Func
== GL_NEVER
&& ctx
->Depth
.Test
);
881 case GL_SCISSOR_TEST
:
882 FLUSH_BATCH( mmesa
);
883 mmesa
->scissor
= state
;
884 mmesa
->new_state
|= MGA_NEW_CLIP
;
887 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
888 if (ctx
->Fog
.Enabled
)
889 mmesa
->setup
.maccess
|= MA_fogen_enable
;
891 mmesa
->setup
.maccess
&= ~MA_fogen_enable
;
894 FLUSH_BATCH( mmesa
);
895 mmesa
->new_state
|= MGA_NEW_CULL
;
900 FLUSH_BATCH( mmesa
);
901 mmesa
->new_state
|= (MGA_NEW_TEXTURE
|MGA_NEW_ALPHA
);
903 case GL_POLYGON_STIPPLE
:
904 if (mmesa
->haveHwStipple
&& mmesa
->raster_primitive
== GL_TRIANGLES
) {
906 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
907 mmesa
->setup
.dwgctl
&= ~(0xf<<20);
909 mmesa
->setup
.dwgctl
|= mmesa
->poly_stipple
;
912 case GL_COLOR_LOGIC_OP
:
913 FLUSH_BATCH( mmesa
);
914 #if !defined(ACCEL_ROP)
915 FALLBACK( ctx
, MGA_FALLBACK_LOGICOP
,
916 (state
&& ctx
->Color
.LogicOp
!= GL_COPY
));
918 mmesa
->new_state
|= MGA_NEW_DEPTH
;
921 case GL_STENCIL_TEST
:
922 FLUSH_BATCH( mmesa
);
923 if (mmesa
->hw_stencil
)
924 mmesa
->new_state
|= MGA_NEW_STENCIL
;
926 FALLBACK( ctx
, MGA_FALLBACK_STENCIL
, state
);
933 /* =============================================================
938 /* =============================================================
941 static void mgaDDPrintState( const char *msg
, GLuint state
)
943 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s\n",
946 (state
& MGA_NEW_DEPTH
) ? "depth, " : "",
947 (state
& MGA_NEW_ALPHA
) ? "alpha, " : "",
948 (state
& MGA_NEW_CLIP
) ? "clip, " : "",
949 (state
& MGA_NEW_CULL
) ? "cull, " : "",
950 (state
& MGA_NEW_TEXTURE
) ? "texture, " : "",
951 (state
& MGA_NEW_CONTEXT
) ? "context, " : "");
954 void mgaDDUpdateHwState( GLcontext
*ctx
)
956 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
957 int new_state
= mmesa
->new_state
;
961 FLUSH_BATCH( mmesa
);
963 mmesa
->new_state
= 0;
965 if (MESA_VERBOSE
&VERBOSE_DRIVER
)
966 mgaDDPrintState("UpdateHwState", new_state
);
968 if (new_state
& MGA_NEW_DEPTH
)
971 if (new_state
& MGA_NEW_ALPHA
)
972 mgaUpdateAlphaMode(ctx
);
974 if (new_state
& MGA_NEW_CLIP
)
975 mgaUpdateClipping(ctx
);
977 if (new_state
& MGA_NEW_STENCIL
)
978 mgaUpdateStencil(ctx
);
980 if (new_state
& (MGA_NEW_WARP
|MGA_NEW_CULL
))
983 if (new_state
& (MGA_NEW_WARP
|MGA_NEW_TEXTURE
))
984 mgaUpdateTextureState(ctx
);
989 static void mgaDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
991 _swrast_InvalidateState( ctx
, new_state
);
992 _swsetup_InvalidateState( ctx
, new_state
);
993 _ac_InvalidateState( ctx
, new_state
);
994 _tnl_InvalidateState( ctx
, new_state
);
995 MGA_CONTEXT(ctx
)->new_gl_state
|= new_state
;
1000 void mgaInitState( mgaContextPtr mmesa
)
1002 mgaScreenPrivate
*mgaScreen
= mmesa
->mgaScreen
;
1003 GLcontext
*ctx
= mmesa
->glCtx
;
1005 if (ctx
->Color
._DrawDestMask
== BACK_LEFT_BIT
) {
1006 mmesa
->draw_buffer
= MGA_BACK
;
1007 mmesa
->read_buffer
= MGA_BACK
;
1008 mmesa
->drawOffset
= mmesa
->mgaScreen
->backOffset
;
1009 mmesa
->readOffset
= mmesa
->mgaScreen
->backOffset
;
1010 mmesa
->setup
.dstorg
= mgaScreen
->backOffset
;
1012 mmesa
->draw_buffer
= MGA_FRONT
;
1013 mmesa
->read_buffer
= MGA_FRONT
;
1014 mmesa
->drawOffset
= mmesa
->mgaScreen
->frontOffset
;
1015 mmesa
->readOffset
= mmesa
->mgaScreen
->frontOffset
;
1016 mmesa
->setup
.dstorg
= mgaScreen
->frontOffset
;
1019 mmesa
->setup
.maccess
= (MA_memreset_disable
|
1021 MA_tlutload_disable
|
1022 MA_nodither_disable
|
1025 switch (mmesa
->mgaScreen
->cpp
) {
1027 mmesa
->setup
.maccess
|= MA_pwidth_16
;
1030 mmesa
->setup
.maccess
|= MA_pwidth_32
;
1033 fprintf( stderr
, "Error: unknown cpp %d, exiting...\n",
1034 mmesa
->mgaScreen
->cpp
);
1038 switch (mmesa
->glCtx
->Visual
.depthBits
) {
1040 mmesa
->setup
.maccess
|= MA_zwidth_16
;
1043 mmesa
->setup
.maccess
|= MA_zwidth_24
;
1046 mmesa
->setup
.maccess
|= MA_pwidth_32
;
1050 mmesa
->setup
.dwgctl
= (DC_opcod_trap
|
1056 DC_sgnzero_disable
|
1057 DC_shftzero_enable
|
1058 (0xC << DC_bop_SHIFT
) |
1059 (0x0 << DC_trans_SHIFT
) |
1060 DC_bltmod_bmonolef
|
1061 DC_pattern_disable
|
1063 DC_clipdis_disable
);
1066 mmesa
->setup
.plnwt
= ~0;
1067 mmesa
->setup
.alphactrl
= ( AC_src_one
|
1070 AC_astipple_disable
|
1073 AC_alphasel_fromtex
);
1075 mmesa
->setup
.fogcolor
=
1076 MGAPACKCOLOR888((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
),
1077 (GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
),
1078 (GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
));
1080 mmesa
->setup
.wflag
= 0;
1081 mmesa
->setup
.tdualstage0
= 0;
1082 mmesa
->setup
.tdualstage1
= 0;
1083 mmesa
->setup
.fcol
= 0;
1084 mmesa
->new_state
= ~0;
1088 void mgaDDInitStateFuncs( GLcontext
*ctx
)
1090 ctx
->Driver
.UpdateState
= mgaDDInvalidateState
;
1091 ctx
->Driver
.Enable
= mgaDDEnable
;
1092 ctx
->Driver
.LightModelfv
= mgaDDLightModelfv
;
1093 ctx
->Driver
.AlphaFunc
= mgaDDAlphaFunc
;
1094 ctx
->Driver
.BlendEquation
= mgaDDBlendEquation
;
1095 ctx
->Driver
.BlendFunc
= mgaDDBlendFunc
;
1096 ctx
->Driver
.BlendFuncSeparate
= mgaDDBlendFuncSeparate
;
1097 ctx
->Driver
.DepthFunc
= mgaDDDepthFunc
;
1098 ctx
->Driver
.DepthMask
= mgaDDDepthMask
;
1099 ctx
->Driver
.Fogfv
= mgaDDFogfv
;
1100 ctx
->Driver
.Scissor
= mgaDDScissor
;
1101 ctx
->Driver
.ShadeModel
= mgaDDShadeModel
;
1102 ctx
->Driver
.CullFace
= mgaDDCullFaceFrontFace
;
1103 ctx
->Driver
.FrontFace
= mgaDDCullFaceFrontFace
;
1104 ctx
->Driver
.ColorMask
= mgaDDColorMask
;
1106 ctx
->Driver
.DrawBuffer
= mgaDDSetDrawBuffer
;
1107 ctx
->Driver
.ReadBuffer
= mgaDDSetReadBuffer
;
1108 ctx
->Driver
.ClearColor
= mgaDDClearColor
;
1109 ctx
->Driver
.ClearDepth
= mgaDDClearDepth
;
1110 ctx
->Driver
.LogicOpcode
= mgaDDLogicOp
;
1112 ctx
->Driver
.PolygonStipple
= mgaDDPolygonStipple
;
1114 ctx
->Driver
.StencilFunc
= mgaDDStencilFunc
;
1115 ctx
->Driver
.StencilMask
= mgaDDStencilMask
;
1116 ctx
->Driver
.StencilOp
= mgaDDStencilOp
;
1118 ctx
->Driver
.DepthRange
= mgaDepthRange
;
1119 ctx
->Driver
.Viewport
= mgaViewport
;
1120 ctx
->Driver
.RenderMode
= mgaRenderMode
;
1122 ctx
->Driver
.ClearIndex
= 0;
1123 ctx
->Driver
.IndexMask
= 0;
1125 /* Swrast hooks for imaging extensions:
1127 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1128 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1129 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1130 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;