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>
29 #include "main/mtypes.h"
30 #include "main/colormac.h"
33 #include "main/state.h"
35 #include "mgacontext.h"
44 #include "swrast/swrast.h"
47 #include "tnl/t_context.h"
48 #include "tnl/t_pipeline.h"
49 #include "swrast_setup/swrast_setup.h"
52 #include "drirenderbuffer.h"
55 static void updateSpecularLighting( struct gl_context *ctx );
57 static const GLuint mgarop_NoBLK[16] = {
58 DC_atype_rpl | 0x00000000, DC_atype_rstr | 0x00080000,
59 DC_atype_rstr | 0x00040000, DC_atype_rpl | 0x000c0000,
60 DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000,
61 DC_atype_rstr | 0x00060000, DC_atype_rstr | 0x000e0000,
62 DC_atype_rstr | 0x00010000, DC_atype_rstr | 0x00090000,
63 DC_atype_rstr | 0x00050000, DC_atype_rstr | 0x000d0000,
64 DC_atype_rpl | 0x00030000, DC_atype_rstr | 0x000b0000,
65 DC_atype_rstr | 0x00070000, DC_atype_rpl | 0x000f0000
68 /* =============================================================
72 static void mgaDDAlphaFunc(struct gl_context *ctx, GLenum func, GLfloat ref)
74 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
78 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
104 a = AC_atmode_noacmp;
111 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
112 mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte );
115 static void updateBlendLogicOp(struct gl_context *ctx)
117 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
118 GLboolean logicOp = _mesa_rgba_logicop_enabled(ctx);
120 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
122 mmesa->hw.blend_func_enable =
123 (ctx->Color.BlendEnabled && !logicOp) ? ~0 : 0;
125 FALLBACK( ctx, MGA_FALLBACK_BLEND,
126 ctx->Color.BlendEnabled && !logicOp &&
127 mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );
130 static void mgaDDBlendEquationSeparate(struct gl_context *ctx,
131 GLenum modeRGB, GLenum modeA)
133 assert( modeRGB == modeA );
134 updateBlendLogicOp( ctx );
137 static void mgaDDBlendFuncSeparate( struct gl_context *ctx, GLenum sfactorRGB,
138 GLenum dfactorRGB, GLenum sfactorA,
141 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
145 switch (ctx->Color.Blend[0].SrcRGB) {
147 src = AC_src_zero; break;
149 src = AC_src_src_alpha; break;
151 default: /* never happens */
152 src = AC_src_one; break;
154 src = AC_src_dst_color; break;
155 case GL_ONE_MINUS_DST_COLOR:
156 src = AC_src_om_dst_color; break;
157 case GL_ONE_MINUS_SRC_ALPHA:
158 src = AC_src_om_src_alpha; break;
160 src = (ctx->Visual.alphaBits > 0)
161 ? AC_src_dst_alpha : AC_src_one;
163 case GL_ONE_MINUS_DST_ALPHA:
164 src = (ctx->Visual.alphaBits > 0)
165 ? AC_src_om_dst_alpha : AC_src_zero;
167 case GL_SRC_ALPHA_SATURATE:
168 src = (ctx->Visual.alphaBits > 0)
169 ? AC_src_src_alpha_sat : AC_src_zero;
173 switch (ctx->Color.Blend[0].DstRGB) {
175 dst = AC_dst_src_alpha; break;
176 case GL_ONE_MINUS_SRC_ALPHA:
177 dst = AC_dst_om_src_alpha; break;
178 default: /* never happens */
180 dst = AC_dst_zero; break;
182 dst = AC_dst_one; break;
184 dst = AC_dst_src_color; break;
185 case GL_ONE_MINUS_SRC_COLOR:
186 dst = AC_dst_om_src_color; break;
188 dst = (ctx->Visual.alphaBits > 0)
189 ? AC_dst_dst_alpha : AC_dst_one;
191 case GL_ONE_MINUS_DST_ALPHA:
192 dst = (ctx->Visual.alphaBits > 0)
193 ? AC_dst_om_dst_alpha : AC_dst_zero;
197 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
198 mmesa->hw.blend_func = (src | dst);
200 FALLBACK( ctx, MGA_FALLBACK_BLEND,
201 ctx->Color.BlendEnabled && !_mesa_rgba_logicop_enabled(ctx) &&
202 mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );
205 /* =============================================================
209 static void mgaDDDepthFunc(struct gl_context *ctx, GLenum func)
211 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
216 /* can't do this in h/w, we'll use a s/w fallback */
217 FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test);
221 zmode = DC_zmode_nozcmp; break;
223 zmode = DC_zmode_zlt; break;
225 zmode = DC_zmode_zlte; break;
227 zmode = DC_zmode_ze; break;
229 zmode = DC_zmode_zgt; break;
231 zmode = DC_zmode_zgte; break;
233 zmode = DC_zmode_zne; break;
238 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
239 mmesa->hw.zmode &= DC_zmode_MASK;
240 mmesa->hw.zmode |= zmode;
243 static void mgaDDDepthMask(struct gl_context *ctx, GLboolean flag)
245 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
248 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
249 mmesa->hw.zmode &= DC_atype_MASK;
250 mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i;
254 static void mgaDDClearDepth(struct gl_context *ctx, GLclampd d)
256 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
258 /* Select the Z depth. The ~ is used because the _MASK values in the
259 * MGA driver are used to mask OFF the selected bits. In this case,
260 * we want to mask off everything except the MA_zwidth bits.
262 switch (mmesa->setup.maccess & ~MA_zwidth_MASK) {
263 case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break;
264 case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break;
265 case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break;
271 /* =============================================================
276 static void mgaDDFogfv(struct gl_context *ctx, GLenum pname, const GLfloat *param)
278 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
280 if (pname == GL_FOG_COLOR) {
281 GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
282 (GLubyte)(ctx->Fog.Color[1]*255.0F),
283 (GLubyte)(ctx->Fog.Color[2]*255.0F));
285 MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT);
286 mmesa->setup.fogcolor = color;
291 /* =============================================================
296 void mgaUpdateClipping(const struct gl_context *ctx)
298 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
300 if (mmesa->driDrawable)
302 int x1 = mmesa->driDrawable->x + ctx->Scissor.X;
303 int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h
304 - (ctx->Scissor.Y + ctx->Scissor.Height);
305 int x2 = x1 + ctx->Scissor.Width;
306 int y2 = y1 + ctx->Scissor.Height;
313 mmesa->scissor_rect.x1 = x1;
314 mmesa->scissor_rect.y1 = y1;
315 mmesa->scissor_rect.x2 = x2;
316 mmesa->scissor_rect.y2 = y2;
318 mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
323 static void mgaDDScissor( struct gl_context *ctx, GLint x, GLint y,
324 GLsizei w, GLsizei h )
326 if ( ctx->Scissor.Enabled ) {
327 FLUSH_BATCH( MGA_CONTEXT(ctx) ); /* don't pipeline cliprect changes */
328 mgaUpdateClipping( ctx );
333 /* =============================================================
338 #define _CULL_DISABLE 0
339 #define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
340 #define _CULL_POSITIVE (1<<11)
342 static void mgaDDCullFaceFrontFace(struct gl_context *ctx, GLenum unused)
344 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
346 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
347 if (ctx->Polygon.CullFlag &&
348 ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
350 mmesa->hw.cull = _CULL_NEGATIVE;
352 if (ctx->Polygon.CullFaceMode == GL_FRONT)
353 mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
355 if (ctx->Polygon.FrontFace != GL_CCW)
356 mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
358 mmesa->hw.cull_dualtex = mmesa->hw.cull ^
359 (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */
362 mmesa->hw.cull = _CULL_DISABLE;
363 mmesa->hw.cull_dualtex = _CULL_DISABLE;
368 /* =============================================================
372 static void mgaDDColorMask(struct gl_context *ctx,
373 GLboolean r, GLboolean g,
374 GLboolean b, GLboolean a )
376 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
377 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
378 GLuint mask = mgaPackColor(mgaScreen->cpp,
379 ctx->Color.ColorMask[0][RCOMP],
380 ctx->Color.ColorMask[0][GCOMP],
381 ctx->Color.ColorMask[0][BCOMP],
382 ctx->Color.ColorMask[0][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( struct gl_context *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( struct gl_context *ctx )
484 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
487 specen = _mesa_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(struct gl_context *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(struct gl_context *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(struct gl_context *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(struct gl_context *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( struct gl_context *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( struct gl_context *ctx,
700 GLsizei width, GLsizei height )
702 mgaCalcViewport( ctx );
705 static void mgaDepthRange( struct gl_context *ctx,
706 GLclampd nearval, GLclampd farval )
708 mgaCalcViewport( ctx );
712 /* =============================================================
716 static void mgaDDClearColor(struct gl_context *ctx,
717 const GLfloat color[4] )
719 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
721 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
722 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
723 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
724 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
726 mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp,
727 c[0], c[1], c[2], c[3]);
731 /* Fallback to swrast for select and feedback.
733 static void mgaRenderMode( struct gl_context *ctx, GLenum mode )
735 FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
739 static void mgaDDLogicOp( struct gl_context *ctx, GLenum opcode )
741 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
743 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
744 mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ];
748 static void mga_set_cliprects(mgaContextPtr mmesa)
750 __DRIdrawable *driDrawable = mmesa->driDrawable;
752 if ((mmesa->draw_buffer != MGA_FRONT)
753 || (driDrawable->numBackClipRects == 0)) {
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->numClipRects = driDrawable->numBackClipRects;
766 mmesa->pClipRects = driDrawable->pBackClipRects;
767 mmesa->drawX = driDrawable->backX;
768 mmesa->drawY = driDrawable->backY;
771 mmesa->setup.dstorg = mmesa->drawOffset;
772 mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
776 void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
778 __DRIdrawable *const driDrawable = mmesa->driDrawable;
779 __DRIdrawable *const driReadable = mmesa->driReadable;
781 mmesa->dirty_cliprects = 0;
783 driUpdateFramebufferSize(mmesa->glCtx, driDrawable);
784 if (driDrawable != driReadable) {
785 driUpdateFramebufferSize(mmesa->glCtx, driReadable);
788 mga_set_cliprects(mmesa);
790 mgaUpdateClipping( mmesa->glCtx );
791 mgaCalcViewport( mmesa->glCtx );
795 static void mgaDDDrawBuffer(struct gl_context *ctx, GLenum mode )
797 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
799 FLUSH_BATCH( mmesa );
801 if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
802 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
803 FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
807 switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
808 case BUFFER_FRONT_LEFT:
809 mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
810 mmesa->draw_buffer = MGA_FRONT;
812 case BUFFER_BACK_LEFT:
813 mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
814 mmesa->draw_buffer = MGA_BACK;
817 FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
821 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
822 mga_set_cliprects(mmesa);
823 FALLBACK(ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE);
827 static void mgaDDReadBuffer(struct gl_context *ctx, GLenum mode )
829 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
833 /* =============================================================
834 * State enable/disable
838 static void mgaDDEnable(struct gl_context *ctx, GLenum cap, GLboolean state)
840 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
844 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
845 if (!ctx->Color.DitherFlag)
846 mmesa->setup.maccess |= MA_nodither_enable;
848 mmesa->setup.maccess &= ~MA_nodither_enable;
851 case GL_COLOR_SUM_EXT:
852 FLUSH_BATCH( mmesa );
853 updateSpecularLighting( ctx );
856 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
857 mmesa->hw.alpha_func_enable = (state) ? ~0 : 0;
860 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
861 FALLBACK (ctx, MGA_FALLBACK_DEPTH,
862 ctx->Depth.Func == GL_NEVER && ctx->Depth.Test);
865 case GL_SCISSOR_TEST:
866 FLUSH_BATCH( mmesa );
867 mmesa->scissor = state;
868 mgaUpdateClipping( ctx );
872 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
873 if (ctx->Fog.Enabled)
874 mmesa->setup.maccess |= MA_fogen_enable;
876 mmesa->setup.maccess &= ~MA_fogen_enable;
879 mgaDDCullFaceFrontFace( ctx, 0 );
885 case GL_POLYGON_STIPPLE:
886 if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) {
887 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
888 mmesa->setup.dwgctl &= ~(0xf<<20);
890 mmesa->setup.dwgctl |= mmesa->poly_stipple;
895 case GL_COLOR_LOGIC_OP:
896 updateBlendLogicOp( ctx );
899 case GL_STENCIL_TEST:
900 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
901 if (mmesa->hw_stencil) {
902 mmesa->hw.stencil_enable = ( state ) ? ~0 : 0;
905 FALLBACK( ctx, MGA_FALLBACK_STENCIL, state );
913 /* =============================================================
916 static void mgaDDPrintDirty( const char *msg, GLuint state )
918 fprintf(stderr, "%s (0x%03x): %s%s%s%s%s%s%s\n",
920 (unsigned int) state,
921 (state & MGA_WAIT_AGE) ? "wait-age " : "",
922 (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img " : "",
923 (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img " : "",
924 (state & MGA_UPLOAD_CONTEXT) ? "upload-ctx " : "",
925 (state & MGA_UPLOAD_TEX0) ? "upload-tex0 " : "",
926 (state & MGA_UPLOAD_TEX1) ? "upload-tex1 " : "",
927 (state & MGA_UPLOAD_PIPE) ? "upload-pipe " : ""
931 /* Push the state into the sarea and/or texture memory.
933 void mgaEmitHwStateLocked( mgaContextPtr mmesa )
935 drm_mga_sarea_t *sarea = mmesa->sarea;
936 struct gl_context * ctx = mmesa->glCtx;
938 if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
939 mgaDDPrintDirty( __FUNCTION__, mmesa->dirty );
941 if (mmesa->dirty & MGA_UPLOAD_CONTEXT) {
942 mmesa->setup.wflag = _CULL_DISABLE;
943 if (mmesa->raster_primitive == GL_TRIANGLES) {
944 if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
945 ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
946 mmesa->setup.wflag = mmesa->hw.cull_dualtex;
949 mmesa->setup.wflag = mmesa->hw.cull;
953 mmesa->setup.stencil = mmesa->hw.stencil
954 & mmesa->hw.stencil_enable;
955 mmesa->setup.stencilctl = mmesa->hw.stencilctl
956 & mmesa->hw.stencil_enable;
958 /* If depth testing is not enabled, then use the no Z-compare / no
959 * Z-write mode. Otherwise, use whatever is set in hw.zmode.
961 mmesa->setup.dwgctl &= (DC_zmode_MASK & DC_atype_MASK);
962 mmesa->setup.dwgctl |= (ctx->Depth.Test)
963 ? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i);
965 mmesa->setup.dwgctl &= DC_bop_MASK;
966 mmesa->setup.dwgctl |= _mesa_rgba_logicop_enabled(ctx)
967 ? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ];
969 mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_MASK
970 & AC_atref_MASK & AC_alphasel_MASK;
971 mmesa->setup.alphactrl |=
972 (mmesa->hw.alpha_func & mmesa->hw.alpha_func_enable) |
973 (mmesa->hw.blend_func & mmesa->hw.blend_func_enable) |
974 ((AC_src_one | AC_dst_zero) & ~mmesa->hw.blend_func_enable) |
977 memcpy( &sarea->context_state, &mmesa->setup, sizeof(mmesa->setup));
980 if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
981 memcpy(&sarea->tex_state[0],
982 &mmesa->CurrentTexObj[0]->setup,
983 sizeof(sarea->tex_state[0]));
986 if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
987 memcpy(&sarea->tex_state[1],
988 &mmesa->CurrentTexObj[1]->setup,
989 sizeof(sarea->tex_state[1]));
992 if (mmesa->dirty & (MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1)) {
993 sarea->tex_state[0].texctl2 &= ~TMC_specen_enable;
994 sarea->tex_state[1].texctl2 &= ~TMC_specen_enable;
995 sarea->tex_state[0].texctl2 |= mmesa->hw.specen;
996 sarea->tex_state[1].texctl2 |= mmesa->hw.specen;
999 if (mmesa->dirty & MGA_UPLOAD_PIPE) {
1000 /* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
1001 mmesa->sarea->warp_pipe = mmesa->vertex_format;
1002 mmesa->sarea->vertsize = mmesa->vertex_size;
1005 mmesa->sarea->dirty |= mmesa->dirty;
1006 mmesa->dirty &= MGA_UPLOAD_CLIPRECTS;
1009 /* =============================================================
1013 static void mgaDDValidateState( struct gl_context *ctx )
1015 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
1017 FLUSH_BATCH( mmesa );
1019 if (mmesa->NewGLState & _NEW_TEXTURE) {
1020 mgaUpdateTextureState(ctx);
1023 if (!mmesa->Fallback) {
1024 if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) {
1025 mgaChooseVertexState( ctx );
1028 if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) {
1029 mgaChooseRenderState( ctx );
1033 mmesa->NewGLState = 0;
1037 static void mgaDDInvalidateState( struct gl_context *ctx, GLuint new_state )
1039 _swrast_InvalidateState( ctx, new_state );
1040 _swsetup_InvalidateState( ctx, new_state );
1041 _vbo_InvalidateState( ctx, new_state );
1042 _tnl_InvalidateState( ctx, new_state );
1043 MGA_CONTEXT(ctx)->NewGLState |= new_state;
1047 static void mgaRunPipeline( struct gl_context *ctx )
1049 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
1051 if (mmesa->NewGLState) {
1052 mgaDDValidateState( ctx );
1056 mgaEmitHwStateLocked( mmesa );
1059 _tnl_run_pipeline( ctx );
1063 void mgaInitState( mgaContextPtr mmesa )
1065 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
1066 struct gl_context *ctx = mmesa->glCtx;
1068 if (ctx->Visual.doubleBufferMode) {
1069 /* use back buffer by default */
1070 mmesa->draw_buffer = MGA_BACK;
1071 mmesa->drawOffset = mmesa->mgaScreen->backOffset;
1072 mmesa->readOffset = mmesa->mgaScreen->backOffset;
1073 mmesa->setup.dstorg = mgaScreen->backOffset;
1075 /* use front buffer by default */
1076 mmesa->draw_buffer = MGA_FRONT;
1077 mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
1078 mmesa->readOffset = mmesa->mgaScreen->frontOffset;
1079 mmesa->setup.dstorg = mgaScreen->frontOffset;
1082 mmesa->setup.maccess = (MA_memreset_disable |
1084 MA_tlutload_disable |
1085 MA_nodither_disable |
1087 if (driQueryOptioni (&mmesa->optionCache, "color_reduction") !=
1088 DRI_CONF_COLOR_REDUCTION_DITHER)
1089 mmesa->setup.maccess |= MA_nodither_enable;
1091 switch (mmesa->mgaScreen->cpp) {
1093 mmesa->setup.maccess |= MA_pwidth_16;
1096 mmesa->setup.maccess |= MA_pwidth_32;
1099 fprintf( stderr, "Error: unknown cpp %d, exiting...\n",
1100 mmesa->mgaScreen->cpp );
1104 switch (mmesa->glCtx->Visual.depthBits) {
1106 mmesa->setup.maccess |= MA_zwidth_16;
1109 mmesa->setup.maccess |= MA_zwidth_24;
1112 mmesa->setup.maccess |= MA_zwidth_32;
1116 mmesa->hw.blend_func = AC_src_one | AC_dst_zero;
1117 mmesa->hw.blend_func_enable = 0;
1118 mmesa->hw.alpha_func = AC_atmode_noacmp | MGA_FIELD( AC_atref, 0x00 );
1119 mmesa->hw.alpha_func_enable = 0;
1120 mmesa->hw.rop = mgarop_NoBLK[ GL_COPY & 0x0f ];
1121 mmesa->hw.zmode = DC_zmode_zlt | DC_atype_zi;
1122 mmesa->hw.stencil = MGA_FIELD( S_sref, 0x00) | MGA_FIELD( S_smsk, 0xff ) |
1123 MGA_FIELD( S_swtmsk, 0xff );
1124 mmesa->hw.stencilctl = SC_smode_salways | SC_sfailop_keep
1125 | SC_szfailop_keep | SC_szpassop_keep;
1126 mmesa->hw.stencil_enable = 0;
1127 mmesa->hw.cull = _CULL_DISABLE;
1128 mmesa->hw.cull_dualtex = _CULL_DISABLE;
1129 mmesa->hw.specen = 0;
1130 mmesa->hw.alpha_sel = AC_alphasel_diffused;
1132 mmesa->setup.dwgctl = (DC_opcod_trap |
1136 DC_sgnzero_disable |
1137 DC_shftzero_enable |
1138 MGA_FIELD( DC_bop, 0xC ) |
1139 MGA_FIELD( DC_trans, 0x0 ) |
1140 DC_bltmod_bmonolef |
1141 DC_pattern_disable |
1143 DC_clipdis_disable);
1145 mmesa->setup.plnwt = ~0;
1146 mmesa->setup.alphactrl = (AC_amode_alpha_channel |
1147 AC_astipple_disable |
1150 mmesa->setup.fogcolor = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
1151 (GLubyte)(ctx->Fog.Color[1]*255.0F),
1152 (GLubyte)(ctx->Fog.Color[2]*255.0F));
1154 mmesa->setup.wflag = 0;
1155 mmesa->setup.tdualstage0 = 0;
1156 mmesa->setup.tdualstage1 = 0;
1157 mmesa->setup.fcol = 0;
1158 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
1160 mmesa->envcolor[0] = 0;
1161 mmesa->envcolor[1] = 0;
1165 void mgaDDInitStateFuncs( struct gl_context *ctx )
1167 ctx->Driver.UpdateState = mgaDDInvalidateState;
1168 ctx->Driver.Enable = mgaDDEnable;
1169 ctx->Driver.LightModelfv = mgaDDLightModelfv;
1170 ctx->Driver.AlphaFunc = mgaDDAlphaFunc;
1171 ctx->Driver.BlendEquationSeparate = mgaDDBlendEquationSeparate;
1172 ctx->Driver.BlendFuncSeparate = mgaDDBlendFuncSeparate;
1173 ctx->Driver.DepthFunc = mgaDDDepthFunc;
1174 ctx->Driver.DepthMask = mgaDDDepthMask;
1175 ctx->Driver.Fogfv = mgaDDFogfv;
1176 ctx->Driver.Scissor = mgaDDScissor;
1177 ctx->Driver.CullFace = mgaDDCullFaceFrontFace;
1178 ctx->Driver.FrontFace = mgaDDCullFaceFrontFace;
1179 ctx->Driver.ColorMask = mgaDDColorMask;
1181 ctx->Driver.DrawBuffer = mgaDDDrawBuffer;
1182 ctx->Driver.ReadBuffer = mgaDDReadBuffer;
1183 ctx->Driver.ClearColor = mgaDDClearColor;
1184 ctx->Driver.ClearDepth = mgaDDClearDepth;
1185 ctx->Driver.LogicOpcode = mgaDDLogicOp;
1187 ctx->Driver.PolygonStipple = mgaDDPolygonStipple;
1189 ctx->Driver.StencilFuncSeparate = mgaDDStencilFuncSeparate;
1190 ctx->Driver.StencilMaskSeparate = mgaDDStencilMaskSeparate;
1191 ctx->Driver.StencilOpSeparate = mgaDDStencilOpSeparate;
1193 ctx->Driver.DepthRange = mgaDepthRange;
1194 ctx->Driver.Viewport = mgaViewport;
1195 ctx->Driver.RenderMode = mgaRenderMode;
1197 TNL_CONTEXT(ctx)->Driver.RunPipeline = mgaRunPipeline;