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 $ */
36 #include "mgacontext.h"
45 #include "swrast/swrast.h"
46 #include "array_cache/acache.h"
48 #include "tnl/t_context.h"
49 #include "tnl/t_pipeline.h"
50 #include "swrast_setup/swrast_setup.h"
54 static void updateSpecularLighting( GLcontext
*ctx
);
56 static const GLuint mgarop_NoBLK
[16] = {
57 DC_atype_rpl
| 0x00000000, DC_atype_rstr
| 0x00080000,
58 DC_atype_rstr
| 0x00040000, DC_atype_rpl
| 0x000c0000,
59 DC_atype_rstr
| 0x00020000, DC_atype_rstr
| 0x000a0000,
60 DC_atype_rstr
| 0x00060000, DC_atype_rstr
| 0x000e0000,
61 DC_atype_rstr
| 0x00010000, DC_atype_rstr
| 0x00090000,
62 DC_atype_rstr
| 0x00050000, DC_atype_rstr
| 0x000d0000,
63 DC_atype_rpl
| 0x00030000, DC_atype_rstr
| 0x000b0000,
64 DC_atype_rstr
| 0x00070000, DC_atype_rpl
| 0x000f0000
67 /* =============================================================
71 static void mgaDDAlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
73 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
77 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
103 a
= AC_atmode_noacmp
;
110 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
111 mmesa
->hw
.alpha_func
= a
| MGA_FIELD( AC_atref
, refByte
);
114 static void updateBlendLogicOp(GLcontext
*ctx
)
116 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
118 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
120 mmesa
->hw
.blend_func_enable
=
121 (ctx
->Color
.BlendEnabled
&& !ctx
->Color
._LogicOpEnabled
) ? ~0 : 0;
123 FALLBACK( ctx
, MGA_FALLBACK_BLEND
,
124 ctx
->Color
.BlendEnabled
&& !ctx
->Color
._LogicOpEnabled
&&
125 mmesa
->hw
.blend_func
== (AC_src_src_alpha_sat
| AC_dst_zero
) );
128 static void mgaDDBlendEquationSeparate(GLcontext
*ctx
,
129 GLenum modeRGB
, GLenum modeA
)
131 assert( modeRGB
== modeA
);
132 updateBlendLogicOp( ctx
);
135 static void mgaDDBlendFuncSeparate( GLcontext
*ctx
, GLenum sfactorRGB
,
136 GLenum dfactorRGB
, GLenum sfactorA
,
139 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
143 switch (ctx
->Color
.BlendSrcRGB
) {
145 src
= AC_src_zero
; break;
147 src
= AC_src_src_alpha
; break;
149 default: /* never happens */
150 src
= AC_src_one
; break;
152 src
= AC_src_dst_color
; break;
153 case GL_ONE_MINUS_DST_COLOR
:
154 src
= AC_src_om_dst_color
; break;
155 case GL_ONE_MINUS_SRC_ALPHA
:
156 src
= AC_src_om_src_alpha
; break;
158 src
= (ctx
->Visual
.alphaBits
> 0)
159 ? AC_src_dst_alpha
: AC_src_one
;
161 case GL_ONE_MINUS_DST_ALPHA
:
162 src
= (ctx
->Visual
.alphaBits
> 0)
163 ? AC_src_om_dst_alpha
: AC_src_zero
;
165 case GL_SRC_ALPHA_SATURATE
:
166 src
= (ctx
->Visual
.alphaBits
> 0)
167 ? AC_src_src_alpha_sat
: AC_src_zero
;
171 switch (ctx
->Color
.BlendDstRGB
) {
173 dst
= AC_dst_src_alpha
; break;
174 case GL_ONE_MINUS_SRC_ALPHA
:
175 dst
= AC_dst_om_src_alpha
; break;
176 default: /* never happens */
178 dst
= AC_dst_zero
; break;
180 dst
= AC_dst_one
; break;
182 dst
= AC_dst_src_color
; break;
183 case GL_ONE_MINUS_SRC_COLOR
:
184 dst
= AC_dst_om_src_color
; break;
186 dst
= (ctx
->Visual
.alphaBits
> 0)
187 ? AC_dst_dst_alpha
: AC_dst_one
;
189 case GL_ONE_MINUS_DST_ALPHA
:
190 dst
= (ctx
->Visual
.alphaBits
> 0)
191 ? AC_dst_om_dst_alpha
: AC_dst_zero
;
195 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
196 mmesa
->hw
.blend_func
= (src
| dst
);
198 FALLBACK( ctx
, MGA_FALLBACK_BLEND
,
199 ctx
->Color
.BlendEnabled
&& !ctx
->Color
._LogicOpEnabled
&&
200 mmesa
->hw
.blend_func
== (AC_src_src_alpha_sat
| AC_dst_zero
) );
203 /* =============================================================
207 static void mgaDDDepthFunc(GLcontext
*ctx
, GLenum func
)
209 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
214 /* can't do this in h/w, we'll use a s/w fallback */
215 FALLBACK (ctx
, MGA_FALLBACK_DEPTH
, ctx
->Depth
.Test
);
219 zmode
= DC_zmode_nozcmp
; break;
221 zmode
= DC_zmode_zlt
; break;
223 zmode
= DC_zmode_zlte
; break;
225 zmode
= DC_zmode_ze
; break;
227 zmode
= DC_zmode_zgt
; break;
229 zmode
= DC_zmode_zgte
; break;
231 zmode
= DC_zmode_zne
; break;
236 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
237 mmesa
->hw
.zmode
&= DC_zmode_MASK
;
238 mmesa
->hw
.zmode
|= zmode
;
241 static void mgaDDDepthMask(GLcontext
*ctx
, GLboolean flag
)
243 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
246 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
247 mmesa
->hw
.zmode
&= DC_atype_MASK
;
248 mmesa
->hw
.zmode
|= (flag
) ? DC_atype_zi
: DC_atype_i
;
252 static void mgaDDClearDepth(GLcontext
*ctx
, GLclampd d
)
254 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
256 /* Select the Z depth. The ~ is used because the _MASK values in the
257 * MGA driver are used to mask OFF the selected bits. In this case,
258 * we want to mask off everything except the MA_zwidth bits.
260 switch (mmesa
->setup
.maccess
& ~MA_zwidth_MASK
) {
261 case MA_zwidth_16
: mmesa
->ClearDepth
= d
* 0x0000ffff; break;
262 case MA_zwidth_24
: mmesa
->ClearDepth
= d
* 0xffffff00; break;
263 case MA_zwidth_32
: mmesa
->ClearDepth
= d
* 0xffffffff; break;
269 /* =============================================================
274 static void mgaDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
276 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
278 if (pname
== GL_FOG_COLOR
) {
279 GLuint color
= PACK_COLOR_888((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
),
280 (GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
),
281 (GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
));
283 MGA_STATECHANGE(mmesa
, MGA_UPLOAD_CONTEXT
);
284 mmesa
->setup
.fogcolor
= color
;
289 /* =============================================================
294 void mgaUpdateClipping(const GLcontext
*ctx
)
296 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
298 if (mmesa
->driDrawable
)
300 int x1
= mmesa
->driDrawable
->x
+ ctx
->Scissor
.X
;
301 int y1
= mmesa
->driDrawable
->y
+ mmesa
->driDrawable
->h
302 - (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
);
303 int x2
= x1
+ ctx
->Scissor
.Width
;
304 int y2
= y1
+ ctx
->Scissor
.Height
;
311 mmesa
->scissor_rect
.x1
= x1
;
312 mmesa
->scissor_rect
.y1
= y1
;
313 mmesa
->scissor_rect
.x2
= x2
;
314 mmesa
->scissor_rect
.y2
= y2
;
316 mmesa
->dirty
|= MGA_UPLOAD_CLIPRECTS
;
321 static void mgaDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
322 GLsizei w
, GLsizei h
)
324 if ( ctx
->Scissor
.Enabled
) {
325 FLUSH_BATCH( MGA_CONTEXT(ctx
) ); /* don't pipeline cliprect changes */
326 mgaUpdateClipping( ctx
);
331 /* =============================================================
336 #define _CULL_DISABLE 0
337 #define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
338 #define _CULL_POSITIVE (1<<11)
340 static void mgaDDCullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
342 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
344 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
345 if (ctx
->Polygon
.CullFlag
&&
346 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
348 mmesa
->hw
.cull
= _CULL_NEGATIVE
;
350 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
351 mmesa
->hw
.cull
^= (_CULL_POSITIVE
^ _CULL_NEGATIVE
);
353 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
354 mmesa
->hw
.cull
^= (_CULL_POSITIVE
^ _CULL_NEGATIVE
);
356 mmesa
->hw
.cull_dualtex
= mmesa
->hw
.cull
^
357 (_CULL_POSITIVE
^ _CULL_NEGATIVE
); /* warp bug? */
360 mmesa
->hw
.cull
= _CULL_DISABLE
;
361 mmesa
->hw
.cull_dualtex
= _CULL_DISABLE
;
366 /* =============================================================
370 static void mgaDDColorMask(GLcontext
*ctx
,
371 GLboolean r
, GLboolean g
,
372 GLboolean b
, GLboolean a
)
374 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
375 mgaScreenPrivate
*mgaScreen
= mmesa
->mgaScreen
;
378 GLuint mask
= mgaPackColor(mgaScreen
->cpp
,
379 ctx
->Color
.ColorMask
[RCOMP
],
380 ctx
->Color
.ColorMask
[GCOMP
],
381 ctx
->Color
.ColorMask
[BCOMP
],
382 ctx
->Color
.ColorMask
[ACOMP
]);
384 if (mgaScreen
->cpp
== 2)
385 mask
= mask
| (mask
<< 16);
387 if (mmesa
->setup
.plnwt
!= mask
) {
388 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
389 mmesa
->setup
.plnwt
= mask
;
394 /* =============================================================
398 static int mgaStipples
[16] = {
418 * The MGA supports a subset of possible 4x4 stipples natively, GL
419 * wants 32x32. Fortunately stipple is usually a repeating pattern.
421 * \param ctx GL rendering context to be affected
422 * \param mask Pointer to the 32x32 stipple mask
425 static void mgaDDPolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
427 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
428 const GLubyte
*m
= mask
;
431 int active
= (ctx
->Polygon
.StippleFlag
&&
432 mmesa
->raster_primitive
== GL_TRIANGLES
);
436 mmesa
->haveHwStipple
= 0;
439 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
440 mmesa
->setup
.dwgctl
&= ~(0xf<<20);
443 p
[0] = mask
[0] & 0xf; p
[0] |= p
[0] << 4;
444 p
[1] = mask
[4] & 0xf; p
[1] |= p
[1] << 4;
445 p
[2] = mask
[8] & 0xf; p
[2] |= p
[2] << 4;
446 p
[3] = mask
[12] & 0xf; p
[3] |= p
[3] << 4;
448 for (k
= 0 ; k
< 8 ; k
++)
449 for (j
= 0 ; j
< 4; j
++)
450 for (i
= 0 ; i
< 4 ; i
++)
455 stipple
= ( ((p
[0] & 0xf) << 0) |
456 ((p
[1] & 0xf) << 4) |
457 ((p
[2] & 0xf) << 8) |
458 ((p
[3] & 0xf) << 12) );
460 for (i
= 0 ; i
< 16 ; i
++)
461 if (mgaStipples
[i
] == stipple
) {
462 mmesa
->poly_stipple
= i
<<20;
463 mmesa
->haveHwStipple
= 1;
468 mmesa
->setup
.dwgctl
&= ~(0xf<<20);
469 mmesa
->setup
.dwgctl
|= mmesa
->poly_stipple
;
474 /* =============================================================
475 * Rendering attributes
477 * We really don't want to recalculate all this every time we bind a
478 * texture. These things shouldn't change all that often, so it makes
479 * sense to break them out of the core texture state update routines.
482 static void updateSpecularLighting( GLcontext
*ctx
)
484 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
487 specen
= NEED_SECONDARY_COLOR(ctx
) ? TMC_specen_enable
: 0;
489 if ( specen
!= mmesa
->hw
.specen
) {
490 mmesa
->hw
.specen
= specen
;
491 mmesa
->dirty
|= MGA_UPLOAD_TEX0
| MGA_UPLOAD_TEX1
;
496 /* =============================================================
501 static void mgaDDLightModelfv(GLcontext
*ctx
, GLenum pname
,
502 const GLfloat
*param
)
504 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
505 FLUSH_BATCH( MGA_CONTEXT(ctx
) );
506 updateSpecularLighting( ctx
);
511 /* =============================================================
517 mgaDDStencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
, GLint ref
,
520 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
524 stencil
= MGA_FIELD( S_sref
, ref
) | MGA_FIELD( S_smsk
, mask
);
528 stencilctl
= SC_smode_snever
;
531 stencilctl
= SC_smode_slt
;
534 stencilctl
= SC_smode_slte
;
537 stencilctl
= SC_smode_sgt
;
540 stencilctl
= SC_smode_sgte
;
543 stencilctl
= SC_smode_sne
;
546 stencilctl
= SC_smode_se
;
550 stencilctl
= SC_smode_salways
;
554 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
555 mmesa
->hw
.stencil
&= (S_sref_MASK
& S_smsk_MASK
);
556 mmesa
->hw
.stencil
|= stencil
;
557 mmesa
->hw
.stencilctl
&= SC_smode_MASK
;
558 mmesa
->hw
.stencilctl
|= stencilctl
;
562 mgaDDStencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
564 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
566 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
567 mmesa
->hw
.stencil
&= S_swtmsk_MASK
;
568 mmesa
->hw
.stencil
|= MGA_FIELD( S_swtmsk
, mask
);
572 mgaDDStencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
, GLenum zfail
,
575 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
579 switch (ctx
->Stencil
.FailFunc
[0])
582 stencilctl
|= SC_sfailop_keep
;
585 stencilctl
|= SC_sfailop_zero
;
588 stencilctl
|= SC_sfailop_replace
;
591 stencilctl
|= SC_sfailop_incrsat
;
594 stencilctl
|= SC_sfailop_decrsat
;
597 stencilctl
|= SC_sfailop_incr
;
600 stencilctl
|= SC_sfailop_decr
;
603 stencilctl
|= SC_sfailop_invert
;
609 switch (ctx
->Stencil
.ZFailFunc
[0])
612 stencilctl
|= SC_szfailop_keep
;
615 stencilctl
|= SC_szfailop_zero
;
618 stencilctl
|= SC_szfailop_replace
;
621 stencilctl
|= SC_szfailop_incrsat
;
624 stencilctl
|= SC_szfailop_decrsat
;
627 stencilctl
|= SC_szfailop_incr
;
630 stencilctl
|= SC_szfailop_decr
;
633 stencilctl
|= SC_szfailop_invert
;
639 switch (ctx
->Stencil
.ZPassFunc
[0])
642 stencilctl
|= SC_szpassop_keep
;
645 stencilctl
|= SC_szpassop_zero
;
648 stencilctl
|= SC_szpassop_replace
;
651 stencilctl
|= SC_szpassop_incrsat
;
654 stencilctl
|= SC_szpassop_decrsat
;
657 stencilctl
|= SC_szpassop_incr
;
660 stencilctl
|= SC_szpassop_decr
;
663 stencilctl
|= SC_szpassop_invert
;
669 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
670 mmesa
->hw
.stencilctl
&= (SC_sfailop_MASK
& SC_szfailop_MASK
672 mmesa
->hw
.stencilctl
|= stencilctl
;
676 /* =============================================================
677 * Window position and viewport transformation
680 void mgaCalcViewport( GLcontext
*ctx
)
682 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
683 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
684 GLfloat
*m
= mmesa
->hw_viewport
;
686 /* See also mga_translate_vertex.
688 m
[MAT_SX
] = v
[MAT_SX
];
689 m
[MAT_TX
] = v
[MAT_TX
] + mmesa
->drawX
+ SUBPIXEL_X
;
690 m
[MAT_SY
] = - v
[MAT_SY
];
691 m
[MAT_TY
] = - v
[MAT_TY
] + mmesa
->driDrawable
->h
+ mmesa
->drawY
+ SUBPIXEL_Y
;
692 m
[MAT_SZ
] = v
[MAT_SZ
] * mmesa
->depth_scale
;
693 m
[MAT_TZ
] = v
[MAT_TZ
] * mmesa
->depth_scale
;
695 mmesa
->SetupNewInputs
= ~0;
698 static void mgaViewport( GLcontext
*ctx
,
700 GLsizei width
, GLsizei height
)
702 /* update size of Mesa/software ancillary buffers */
703 _mesa_ResizeBuffersMESA();
704 mgaCalcViewport( ctx
);
707 static void mgaDepthRange( GLcontext
*ctx
,
708 GLclampd nearval
, GLclampd farval
)
710 mgaCalcViewport( ctx
);
714 /* =============================================================
718 static void mgaDDClearColor(GLcontext
*ctx
,
719 const GLfloat color
[4] )
721 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
723 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
724 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
725 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
726 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
728 mmesa
->ClearColor
= mgaPackColor( mmesa
->mgaScreen
->cpp
,
729 c
[0], c
[1], c
[2], c
[3]);
733 /* Fallback to swrast for select and feedback.
735 static void mgaRenderMode( GLcontext
*ctx
, GLenum mode
)
737 FALLBACK( ctx
, MGA_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
741 static void mgaDDLogicOp( GLcontext
*ctx
, GLenum opcode
)
743 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
745 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
746 mmesa
->hw
.rop
= mgarop_NoBLK
[ opcode
& 0x0f ];
750 static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa
)
752 __DRIdrawablePrivate
*driDrawable
= mmesa
->driDrawable
;
754 if (driDrawable
->numClipRects
== 0) {
755 static drm_clip_rect_t zeroareacliprect
= {0,0,0,0};
756 mmesa
->numClipRects
= 1;
757 mmesa
->pClipRects
= &zeroareacliprect
;
759 mmesa
->numClipRects
= driDrawable
->numClipRects
;
760 mmesa
->pClipRects
= driDrawable
->pClipRects
;
762 mmesa
->drawX
= driDrawable
->x
;
763 mmesa
->drawY
= driDrawable
->y
;
765 mmesa
->setup
.dstorg
= mmesa
->drawOffset
;
766 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_CLIPRECTS
;
770 static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa
)
772 __DRIdrawablePrivate
*driDrawable
= mmesa
->driDrawable
;
774 if (driDrawable
->numBackClipRects
== 0)
776 if (driDrawable
->numClipRects
== 0) {
777 static drm_clip_rect_t zeroareacliprect
= {0,0,0,0};
778 mmesa
->numClipRects
= 1;
779 mmesa
->pClipRects
= &zeroareacliprect
;
781 mmesa
->numClipRects
= driDrawable
->numClipRects
;
782 mmesa
->pClipRects
= driDrawable
->pClipRects
;
784 mmesa
->drawX
= driDrawable
->x
;
785 mmesa
->drawY
= driDrawable
->y
;
787 mmesa
->numClipRects
= driDrawable
->numBackClipRects
;
788 mmesa
->pClipRects
= driDrawable
->pBackClipRects
;
789 mmesa
->drawX
= driDrawable
->backX
;
790 mmesa
->drawY
= driDrawable
->backY
;
793 mmesa
->setup
.dstorg
= mmesa
->drawOffset
;
794 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_CLIPRECTS
;
798 void mgaUpdateRects( mgaContextPtr mmesa
, GLuint buffers
)
800 __DRIdrawablePrivate
*driDrawable
= mmesa
->driDrawable
;
801 drm_mga_sarea_t
*sarea
= mmesa
->sarea
;
804 DRI_VALIDATE_DRAWABLE_INFO(mmesa
->driScreen
, driDrawable
);
805 mmesa
->dirty_cliprects
= 0;
807 if (mmesa
->draw_buffer
== MGA_FRONT
)
808 mgaXMesaSetFrontClipRects( mmesa
);
810 mgaXMesaSetBackClipRects( mmesa
);
812 sarea
->req_drawable
= driDrawable
->draw
;
813 sarea
->req_draw_buffer
= mmesa
->draw_buffer
;
815 mgaUpdateClipping( mmesa
->glCtx
);
816 mgaCalcViewport( mmesa
->glCtx
);
818 mmesa
->dirty
|= MGA_UPLOAD_CLIPRECTS
;
822 static void mgaDDDrawBuffer(GLcontext
*ctx
, GLenum mode
)
824 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
826 FLUSH_BATCH( mmesa
);
829 * _DrawDestMask is easier to cope with than <mode>.
831 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
832 case BUFFER_BIT_FRONT_LEFT
:
833 mmesa
->setup
.dstorg
= mmesa
->mgaScreen
->frontOffset
;
834 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
835 mmesa
->draw_buffer
= MGA_FRONT
;
836 mgaXMesaSetFrontClipRects( mmesa
);
837 FALLBACK( ctx
, MGA_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
839 case BUFFER_BIT_BACK_LEFT
:
840 mmesa
->setup
.dstorg
= mmesa
->mgaScreen
->backOffset
;
841 mmesa
->draw_buffer
= MGA_BACK
;
842 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
843 mgaXMesaSetBackClipRects( mmesa
);
844 FALLBACK( ctx
, MGA_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
847 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
848 FALLBACK( ctx
, MGA_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
854 static void mgaDDReadBuffer(GLcontext
*ctx
, GLenum mode
)
856 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
860 /* =============================================================
861 * State enable/disable
865 static void mgaDDEnable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
867 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
871 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
872 if (!ctx
->Color
.DitherFlag
)
873 mmesa
->setup
.maccess
|= MA_nodither_enable
;
875 mmesa
->setup
.maccess
&= ~MA_nodither_enable
;
878 case GL_COLOR_SUM_EXT
:
879 FLUSH_BATCH( mmesa
);
880 updateSpecularLighting( ctx
);
883 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
884 mmesa
->hw
.alpha_func_enable
= (state
) ? ~0 : 0;
887 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
888 FALLBACK (ctx
, MGA_FALLBACK_DEPTH
,
889 ctx
->Depth
.Func
== GL_NEVER
&& ctx
->Depth
.Test
);
892 case GL_SCISSOR_TEST
:
893 FLUSH_BATCH( mmesa
);
894 mmesa
->scissor
= state
;
895 mgaUpdateClipping( ctx
);
899 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
900 if (ctx
->Fog
.Enabled
)
901 mmesa
->setup
.maccess
|= MA_fogen_enable
;
903 mmesa
->setup
.maccess
&= ~MA_fogen_enable
;
906 mgaDDCullFaceFrontFace( ctx
, 0 );
912 case GL_POLYGON_STIPPLE
:
913 if (mmesa
->haveHwStipple
&& mmesa
->raster_primitive
== GL_TRIANGLES
) {
914 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
915 mmesa
->setup
.dwgctl
&= ~(0xf<<20);
917 mmesa
->setup
.dwgctl
|= mmesa
->poly_stipple
;
922 case GL_COLOR_LOGIC_OP
:
923 updateBlendLogicOp( ctx
);
926 case GL_STENCIL_TEST
:
927 MGA_STATECHANGE( mmesa
, MGA_UPLOAD_CONTEXT
);
928 if (mmesa
->hw_stencil
) {
929 mmesa
->hw
.stencil_enable
= ( state
) ? ~0 : 0;
932 FALLBACK( ctx
, MGA_FALLBACK_STENCIL
, state
);
940 /* =============================================================
943 static void mgaDDPrintDirty( const char *msg
, GLuint state
)
945 fprintf(stderr
, "%s (0x%03x): %s%s%s%s%s%s%s\n",
947 (unsigned int) state
,
948 (state
& MGA_WAIT_AGE
) ? "wait-age " : "",
949 (state
& MGA_UPLOAD_TEX0IMAGE
) ? "upload-tex0-img " : "",
950 (state
& MGA_UPLOAD_TEX1IMAGE
) ? "upload-tex1-img " : "",
951 (state
& MGA_UPLOAD_CONTEXT
) ? "upload-ctx " : "",
952 (state
& MGA_UPLOAD_TEX0
) ? "upload-tex0 " : "",
953 (state
& MGA_UPLOAD_TEX1
) ? "upload-tex1 " : "",
954 (state
& MGA_UPLOAD_PIPE
) ? "upload-pipe " : ""
958 /* Push the state into the sarea and/or texture memory.
960 void mgaEmitHwStateLocked( mgaContextPtr mmesa
)
962 drm_mga_sarea_t
*sarea
= mmesa
->sarea
;
963 GLcontext
* ctx
= mmesa
->glCtx
;
965 if (MGA_DEBUG
& DEBUG_VERBOSE_MSG
)
966 mgaDDPrintDirty( __FUNCTION__
, mmesa
->dirty
);
968 if (mmesa
->dirty
& MGA_UPLOAD_CONTEXT
) {
969 mmesa
->setup
.wflag
= _CULL_DISABLE
;
970 if (mmesa
->raster_primitive
== GL_TRIANGLES
) {
971 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
== TEXTURE_2D_BIT
&&
972 ctx
->Texture
.Unit
[1]._ReallyEnabled
== TEXTURE_2D_BIT
)) {
973 mmesa
->setup
.wflag
= mmesa
->hw
.cull_dualtex
;
976 mmesa
->setup
.wflag
= mmesa
->hw
.cull
;
980 mmesa
->setup
.stencil
= mmesa
->hw
.stencil
981 & mmesa
->hw
.stencil_enable
;
982 mmesa
->setup
.stencilctl
= mmesa
->hw
.stencilctl
983 & mmesa
->hw
.stencil_enable
;
985 /* If depth testing is not enabled, then use the no Z-compare / no
986 * Z-write mode. Otherwise, use whatever is set in hw.zmode.
988 mmesa
->setup
.dwgctl
&= (DC_zmode_MASK
& DC_atype_MASK
);
989 mmesa
->setup
.dwgctl
|= (ctx
->Depth
.Test
)
990 ? mmesa
->hw
.zmode
: (DC_zmode_nozcmp
| DC_atype_i
);
992 mmesa
->setup
.dwgctl
&= DC_bop_MASK
;
993 mmesa
->setup
.dwgctl
|= (ctx
->Color
._LogicOpEnabled
)
994 ? mmesa
->hw
.rop
: mgarop_NoBLK
[ GL_COPY
& 0x0f ];
996 mmesa
->setup
.alphactrl
&= AC_src_MASK
& AC_dst_MASK
& AC_atmode_MASK
997 & AC_atref_MASK
& AC_alphasel_MASK
;
998 mmesa
->setup
.alphactrl
|=
999 (mmesa
->hw
.alpha_func
& mmesa
->hw
.alpha_func_enable
) |
1000 (mmesa
->hw
.blend_func
& mmesa
->hw
.blend_func_enable
) |
1001 ((AC_src_one
| AC_dst_zero
) & ~mmesa
->hw
.blend_func_enable
) |
1002 mmesa
->hw
.alpha_sel
;
1004 memcpy( &sarea
->context_state
, &mmesa
->setup
, sizeof(mmesa
->setup
));
1007 if ((mmesa
->dirty
& MGA_UPLOAD_TEX0
) && mmesa
->CurrentTexObj
[0]) {
1008 memcpy(&sarea
->tex_state
[0],
1009 &mmesa
->CurrentTexObj
[0]->setup
,
1010 sizeof(sarea
->tex_state
[0]));
1013 if ((mmesa
->dirty
& MGA_UPLOAD_TEX1
) && mmesa
->CurrentTexObj
[1]) {
1014 memcpy(&sarea
->tex_state
[1],
1015 &mmesa
->CurrentTexObj
[1]->setup
,
1016 sizeof(sarea
->tex_state
[1]));
1019 if (mmesa
->dirty
& (MGA_UPLOAD_TEX0
| MGA_UPLOAD_TEX1
)) {
1020 sarea
->tex_state
[0].texctl2
&= ~TMC_specen_enable
;
1021 sarea
->tex_state
[1].texctl2
&= ~TMC_specen_enable
;
1022 sarea
->tex_state
[0].texctl2
|= mmesa
->hw
.specen
;
1023 sarea
->tex_state
[1].texctl2
|= mmesa
->hw
.specen
;
1026 if (mmesa
->dirty
& MGA_UPLOAD_PIPE
) {
1027 /* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
1028 mmesa
->sarea
->warp_pipe
= mmesa
->vertex_format
;
1029 mmesa
->sarea
->vertsize
= mmesa
->vertex_size
;
1032 mmesa
->sarea
->dirty
|= mmesa
->dirty
;
1033 mmesa
->dirty
&= MGA_UPLOAD_CLIPRECTS
;
1036 /* =============================================================
1040 static void mgaDDValidateState( GLcontext
*ctx
)
1042 mgaContextPtr mmesa
= MGA_CONTEXT( ctx
);
1044 FLUSH_BATCH( mmesa
);
1046 if (mmesa
->NewGLState
& _NEW_TEXTURE
) {
1047 mgaUpdateTextureState(ctx
);
1050 if (!mmesa
->Fallback
) {
1051 if (mmesa
->NewGLState
& _MGA_NEW_RASTERSETUP
) {
1052 mgaChooseVertexState( ctx
);
1055 if (mmesa
->NewGLState
& _MGA_NEW_RENDERSTATE
) {
1056 mgaChooseRenderState( ctx
);
1060 mmesa
->NewGLState
= 0;
1064 static void mgaDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1066 _swrast_InvalidateState( ctx
, new_state
);
1067 _swsetup_InvalidateState( ctx
, new_state
);
1068 _ac_InvalidateState( ctx
, new_state
);
1069 _tnl_InvalidateState( ctx
, new_state
);
1070 MGA_CONTEXT(ctx
)->NewGLState
|= new_state
;
1074 static void mgaRunPipeline( GLcontext
*ctx
)
1076 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
1078 if (mmesa
->NewGLState
) {
1079 mgaDDValidateState( ctx
);
1083 mgaEmitHwStateLocked( mmesa
);
1086 _tnl_run_pipeline( ctx
);
1090 void mgaInitState( mgaContextPtr mmesa
)
1092 mgaScreenPrivate
*mgaScreen
= mmesa
->mgaScreen
;
1093 GLcontext
*ctx
= mmesa
->glCtx
;
1095 if (ctx
->Visual
.doubleBufferMode
) {
1096 /* use back buffer by default */
1097 mmesa
->draw_buffer
= MGA_BACK
;
1098 mmesa
->drawOffset
= mmesa
->mgaScreen
->backOffset
;
1099 mmesa
->readOffset
= mmesa
->mgaScreen
->backOffset
;
1100 mmesa
->setup
.dstorg
= mgaScreen
->backOffset
;
1102 /* use front buffer by default */
1103 mmesa
->draw_buffer
= MGA_FRONT
;
1104 mmesa
->drawOffset
= mmesa
->mgaScreen
->frontOffset
;
1105 mmesa
->readOffset
= mmesa
->mgaScreen
->frontOffset
;
1106 mmesa
->setup
.dstorg
= mgaScreen
->frontOffset
;
1109 mmesa
->setup
.maccess
= (MA_memreset_disable
|
1111 MA_tlutload_disable
|
1112 MA_nodither_disable
|
1114 if (driQueryOptioni (&mmesa
->optionCache
, "color_reduction") !=
1115 DRI_CONF_COLOR_REDUCTION_DITHER
)
1116 mmesa
->setup
.maccess
|= MA_nodither_enable
;
1118 switch (mmesa
->mgaScreen
->cpp
) {
1120 mmesa
->setup
.maccess
|= MA_pwidth_16
;
1123 mmesa
->setup
.maccess
|= MA_pwidth_32
;
1126 fprintf( stderr
, "Error: unknown cpp %d, exiting...\n",
1127 mmesa
->mgaScreen
->cpp
);
1131 switch (mmesa
->glCtx
->Visual
.depthBits
) {
1133 mmesa
->setup
.maccess
|= MA_zwidth_16
;
1136 mmesa
->setup
.maccess
|= MA_zwidth_24
;
1139 mmesa
->setup
.maccess
|= MA_zwidth_32
;
1143 mmesa
->hw
.blend_func
= AC_src_one
| AC_dst_zero
;
1144 mmesa
->hw
.blend_func_enable
= 0;
1145 mmesa
->hw
.alpha_func
= AC_atmode_noacmp
| MGA_FIELD( AC_atref
, 0x00 );
1146 mmesa
->hw
.alpha_func_enable
= 0;
1147 mmesa
->hw
.rop
= mgarop_NoBLK
[ GL_COPY
& 0x0f ];
1148 mmesa
->hw
.zmode
= DC_zmode_zlt
| DC_atype_zi
;
1149 mmesa
->hw
.stencil
= MGA_FIELD( S_sref
, 0x00) | MGA_FIELD( S_smsk
, 0xff ) |
1150 MGA_FIELD( S_swtmsk
, 0xff );
1151 mmesa
->hw
.stencilctl
= SC_smode_salways
| SC_sfailop_keep
1152 | SC_szfailop_keep
| SC_szpassop_keep
;
1153 mmesa
->hw
.stencil_enable
= 0;
1154 mmesa
->hw
.cull
= _CULL_DISABLE
;
1155 mmesa
->hw
.cull_dualtex
= _CULL_DISABLE
;
1156 mmesa
->hw
.specen
= 0;
1157 mmesa
->hw
.alpha_sel
= AC_alphasel_diffused
;
1159 mmesa
->setup
.dwgctl
= (DC_opcod_trap
|
1163 DC_sgnzero_disable
|
1164 DC_shftzero_enable
|
1165 MGA_FIELD( DC_bop
, 0xC ) |
1166 MGA_FIELD( DC_trans
, 0x0 ) |
1167 DC_bltmod_bmonolef
|
1168 DC_pattern_disable
|
1170 DC_clipdis_disable
);
1172 mmesa
->setup
.plnwt
= ~0;
1173 mmesa
->setup
.alphactrl
= (AC_amode_alpha_channel
|
1174 AC_astipple_disable
|
1177 mmesa
->setup
.fogcolor
= PACK_COLOR_888((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
),
1178 (GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
),
1179 (GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
));
1181 mmesa
->setup
.wflag
= 0;
1182 mmesa
->setup
.tdualstage0
= 0;
1183 mmesa
->setup
.tdualstage1
= 0;
1184 mmesa
->setup
.fcol
= 0;
1185 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
;
1187 mmesa
->envcolor
[0] = 0;
1188 mmesa
->envcolor
[1] = 0;
1192 void mgaDDInitStateFuncs( GLcontext
*ctx
)
1194 ctx
->Driver
.UpdateState
= mgaDDInvalidateState
;
1195 ctx
->Driver
.Enable
= mgaDDEnable
;
1196 ctx
->Driver
.LightModelfv
= mgaDDLightModelfv
;
1197 ctx
->Driver
.AlphaFunc
= mgaDDAlphaFunc
;
1198 ctx
->Driver
.BlendEquationSeparate
= mgaDDBlendEquationSeparate
;
1199 ctx
->Driver
.BlendFuncSeparate
= mgaDDBlendFuncSeparate
;
1200 ctx
->Driver
.DepthFunc
= mgaDDDepthFunc
;
1201 ctx
->Driver
.DepthMask
= mgaDDDepthMask
;
1202 ctx
->Driver
.Fogfv
= mgaDDFogfv
;
1203 ctx
->Driver
.Scissor
= mgaDDScissor
;
1204 ctx
->Driver
.CullFace
= mgaDDCullFaceFrontFace
;
1205 ctx
->Driver
.FrontFace
= mgaDDCullFaceFrontFace
;
1206 ctx
->Driver
.ColorMask
= mgaDDColorMask
;
1208 ctx
->Driver
.DrawBuffer
= mgaDDDrawBuffer
;
1209 ctx
->Driver
.ReadBuffer
= mgaDDReadBuffer
;
1210 ctx
->Driver
.ClearColor
= mgaDDClearColor
;
1211 ctx
->Driver
.ClearDepth
= mgaDDClearDepth
;
1212 ctx
->Driver
.LogicOpcode
= mgaDDLogicOp
;
1214 ctx
->Driver
.PolygonStipple
= mgaDDPolygonStipple
;
1216 ctx
->Driver
.StencilFuncSeparate
= mgaDDStencilFuncSeparate
;
1217 ctx
->Driver
.StencilMaskSeparate
= mgaDDStencilMaskSeparate
;
1218 ctx
->Driver
.StencilOpSeparate
= mgaDDStencilOpSeparate
;
1220 ctx
->Driver
.DepthRange
= mgaDepthRange
;
1221 ctx
->Driver
.Viewport
= mgaViewport
;
1222 ctx
->Driver
.RenderMode
= mgaRenderMode
;
1224 ctx
->Driver
.ClearIndex
= 0;
1225 ctx
->Driver
.IndexMask
= 0;
1227 /* Swrast hooks for imaging extensions:
1229 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1230 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1231 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1232 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1234 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= mgaRunPipeline
;