1 /* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */
3 * Copyright 2000 Gareth Hughes
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
32 #include "mach64_context.h"
33 #include "mach64_state.h"
34 #include "mach64_ioctl.h"
35 #include "mach64_tris.h"
36 #include "mach64_vb.h"
37 #include "mach64_tex.h"
43 #include "swrast/swrast.h"
44 #include "array_cache/acache.h"
46 #include "swrast_setup/swrast_setup.h"
48 #include "tnl/t_pipeline.h"
51 /* =============================================================
55 static void mach64UpdateAlphaMode( GLcontext
*ctx
)
57 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
58 GLuint a
= mmesa
->setup
.alpha_tst_cntl
;
59 GLuint s
= mmesa
->setup
.scale_3d_cntl
;
60 GLuint m
= mmesa
->setup
.dp_write_mask
;
62 if ( ctx
->Color
.AlphaEnabled
) {
65 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
67 a
&= ~(MACH64_ALPHA_TEST_MASK
| MACH64_REF_ALPHA_MASK
);
69 switch ( ctx
->Color
.AlphaFunc
) {
71 a
|= MACH64_ALPHA_TEST_NEVER
;
74 a
|= MACH64_ALPHA_TEST_LESS
;
77 a
|= MACH64_ALPHA_TEST_LEQUAL
;
80 a
|= MACH64_ALPHA_TEST_EQUAL
;
83 a
|= MACH64_ALPHA_TEST_GEQUAL
;
86 a
|= MACH64_ALPHA_TEST_GREATER
;
89 a
|= MACH64_ALPHA_TEST_NOTEQUAL
;
92 a
|= MACH64_ALPHA_TEST_ALWAYS
;
96 a
|= (ref
<< MACH64_REF_ALPHA_SHIFT
);
97 a
|= MACH64_ALPHA_TEST_EN
;
99 a
&= ~MACH64_ALPHA_TEST_EN
;
102 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_FALSE
);
104 if ( ctx
->Color
.BlendEnabled
) {
105 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
106 MACH64_ALPHA_BLEND_DST_MASK
|
107 MACH64_ALPHA_BLEND_SAT
);
109 switch ( ctx
->Color
.BlendSrcRGB
) {
111 s
|= MACH64_ALPHA_BLEND_SRC_ZERO
;
114 s
|= MACH64_ALPHA_BLEND_SRC_ONE
;
117 s
|= MACH64_ALPHA_BLEND_SRC_DSTCOLOR
;
119 case GL_ONE_MINUS_DST_COLOR
:
120 s
|= MACH64_ALPHA_BLEND_SRC_INVDSTCOLOR
;
123 s
|= MACH64_ALPHA_BLEND_SRC_SRCALPHA
;
125 case GL_ONE_MINUS_SRC_ALPHA
:
126 s
|= MACH64_ALPHA_BLEND_SRC_INVSRCALPHA
;
129 s
|= MACH64_ALPHA_BLEND_SRC_DSTALPHA
;
131 case GL_ONE_MINUS_DST_ALPHA
:
132 s
|= MACH64_ALPHA_BLEND_SRC_INVDSTALPHA
;
134 case GL_SRC_ALPHA_SATURATE
:
135 s
|= (MACH64_ALPHA_BLEND_SRC_SRCALPHA
|
136 MACH64_ALPHA_BLEND_SAT
);
139 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_TRUE
);
142 switch ( ctx
->Color
.BlendDstRGB
) {
144 s
|= MACH64_ALPHA_BLEND_DST_ZERO
;
147 s
|= MACH64_ALPHA_BLEND_DST_ONE
;
150 s
|= MACH64_ALPHA_BLEND_DST_SRCCOLOR
;
152 case GL_ONE_MINUS_SRC_COLOR
:
153 s
|= MACH64_ALPHA_BLEND_DST_INVSRCCOLOR
;
156 s
|= MACH64_ALPHA_BLEND_DST_SRCALPHA
;
158 case GL_ONE_MINUS_SRC_ALPHA
:
159 s
|= MACH64_ALPHA_BLEND_DST_INVSRCALPHA
;
162 s
|= MACH64_ALPHA_BLEND_DST_DSTALPHA
;
164 case GL_ONE_MINUS_DST_ALPHA
:
165 s
|= MACH64_ALPHA_BLEND_DST_INVDSTALPHA
;
168 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_TRUE
);
171 m
= 0xffffffff; /* Can't color mask and blend at the same time */
172 s
&= ~MACH64_ALPHA_FOG_EN_FOG
; /* Can't fog and blend at the same time */
173 s
|= MACH64_ALPHA_FOG_EN_ALPHA
;
175 s
&= ~MACH64_ALPHA_FOG_EN_ALPHA
;
178 if ( mmesa
->setup
.alpha_tst_cntl
!= a
) {
179 mmesa
->setup
.alpha_tst_cntl
= a
;
180 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
182 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
183 mmesa
->setup
.scale_3d_cntl
= s
;
184 mmesa
->dirty
|= MACH64_UPLOAD_SCALE_3D_CNTL
;
186 if ( mmesa
->setup
.dp_write_mask
!= m
) {
187 mmesa
->setup
.dp_write_mask
= m
;
188 mmesa
->dirty
|= MACH64_UPLOAD_DP_WRITE_MASK
;
192 static void mach64DDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
194 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
196 FLUSH_BATCH( mmesa
);
197 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
200 static void mach64DDBlendEquationSeparate( GLcontext
*ctx
,
201 GLenum modeRGB
, GLenum modeA
)
203 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
205 assert( modeRGB
== modeA
);
206 FLUSH_BATCH( mmesa
);
208 /* BlendEquation affects ColorLogicOpEnabled
210 FALLBACK( MACH64_CONTEXT(ctx
), MACH64_FALLBACK_LOGICOP
,
211 (ctx
->Color
.ColorLogicOpEnabled
&&
212 ctx
->Color
.LogicOp
!= GL_COPY
));
214 /* Can only do blend addition, not min, max, subtract, etc. */
215 FALLBACK( MACH64_CONTEXT(ctx
), MACH64_FALLBACK_BLEND_EQ
,
216 modeRGB
!= GL_FUNC_ADD
);
218 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
221 static void mach64DDBlendFuncSeparate( GLcontext
*ctx
,
222 GLenum sfactorRGB
, GLenum dfactorRGB
,
223 GLenum sfactorA
, GLenum dfactorA
)
225 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
227 FLUSH_BATCH( mmesa
);
228 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
232 /* =============================================================
236 static void mach64UpdateZMode( GLcontext
*ctx
)
238 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
239 GLuint z
= mmesa
->setup
.z_cntl
;
241 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
242 fprintf( stderr
, "%s:\n", __FUNCTION__
);
245 if ( ctx
->Depth
.Test
) {
246 z
&= ~MACH64_Z_TEST_MASK
;
248 switch ( ctx
->Depth
.Func
) {
250 z
|= MACH64_Z_TEST_NEVER
;
253 z
|= MACH64_Z_TEST_ALWAYS
;
256 z
|= MACH64_Z_TEST_LESS
;
259 z
|= MACH64_Z_TEST_LEQUAL
;
262 z
|= MACH64_Z_TEST_EQUAL
;
265 z
|= MACH64_Z_TEST_GEQUAL
;
268 z
|= MACH64_Z_TEST_GREATER
;
271 z
|= MACH64_Z_TEST_NOTEQUAL
;
280 if ( ctx
->Depth
.Mask
) {
281 z
|= MACH64_Z_MASK_EN
;
283 z
&= ~MACH64_Z_MASK_EN
;
286 if ( mmesa
->setup
.z_cntl
!= z
) {
287 mmesa
->setup
.z_cntl
= z
;
288 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
292 static void mach64DDDepthFunc( GLcontext
*ctx
, GLenum func
)
294 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
296 FLUSH_BATCH( mmesa
);
297 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
300 static void mach64DDDepthMask( GLcontext
*ctx
, GLboolean flag
)
302 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
304 FLUSH_BATCH( mmesa
);
305 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
308 static void mach64DDClearDepth( GLcontext
*ctx
, GLclampd d
)
310 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
312 /* Always have a 16-bit depth buffer.
314 mmesa
->ClearDepth
= d
* 0xffff;
318 /* =============================================================
322 static void mach64UpdateFogAttrib( GLcontext
*ctx
)
324 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
326 CARD32 s
= mmesa
->setup
.scale_3d_cntl
;
330 /* Can't fog if blending is on */
331 if ( ctx
->Color
.BlendEnabled
)
334 if ( ctx
->Fog
.Enabled
) {
335 s
|= MACH64_ALPHA_FOG_EN_FOG
;
336 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
337 MACH64_ALPHA_BLEND_DST_MASK
|
338 MACH64_ALPHA_BLEND_SAT
);
339 /* From Utah-glx: "fog color is now dest and fog factor is alpha, so
340 * use GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA"
342 s
|= (MACH64_ALPHA_BLEND_SRC_SRCALPHA
|
343 MACH64_ALPHA_BLEND_DST_INVSRCALPHA
);
344 /* From Utah-glx: "can't use texture alpha when fogging" */
345 s
&= ~MACH64_TEX_MAP_AEN
;
347 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
348 MACH64_ALPHA_BLEND_DST_MASK
|
349 MACH64_ALPHA_BLEND_SAT
);
350 s
|= (MACH64_ALPHA_BLEND_SRC_ONE
|
351 MACH64_ALPHA_BLEND_DST_ZERO
);
352 s
&= ~MACH64_ALPHA_FOG_EN_FOG
;
355 c
[0] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] );
356 c
[1] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] );
357 c
[2] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
358 c
[3] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[3] );
360 col
= mach64PackColor( 4, c
[0], c
[1], c
[2], c
[3] );
362 if ( mmesa
->setup
.dp_fog_clr
!= col
) {
363 mmesa
->setup
.dp_fog_clr
= col
;
364 mmesa
->dirty
|= MACH64_UPLOAD_DP_FOG_CLR
;
366 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
367 mmesa
->setup
.scale_3d_cntl
= s
;
368 mmesa
->dirty
|= MACH64_UPLOAD_SCALE_3D_CNTL
;
373 static void mach64DDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
375 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
377 FLUSH_BATCH( mmesa
);
378 mmesa
->new_state
|= MACH64_NEW_FOG
;
382 /* =============================================================
386 static void mach64UpdateClipping( GLcontext
*ctx
)
388 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
389 mach64ScreenPtr mach64Screen
= mmesa
->mach64Screen
;
391 if ( mmesa
->driDrawable
) {
392 __DRIdrawablePrivate
*drawable
= mmesa
->driDrawable
;
395 int x2
= drawable
->w
- 1;
396 int y2
= drawable
->h
- 1;
398 if ( ctx
->Scissor
.Enabled
) {
399 if ( ctx
->Scissor
.X
> x1
) {
402 if ( drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
> y1
) {
403 y1
= drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
405 if ( ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
) {
406 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
408 if ( drawable
->h
- ctx
->Scissor
.Y
- 1 < y2
) {
409 y2
= drawable
->h
- ctx
->Scissor
.Y
- 1;
418 /* clamp to screen borders */
423 if (x2
> mach64Screen
->width
-1) x2
= mach64Screen
->width
-1;
424 if (y2
> mach64Screen
->height
-1) y2
= mach64Screen
->height
-1;
426 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
427 fprintf( stderr
, "%s: drawable %3d %3d %3d %3d\n",
433 fprintf( stderr
, "%s: scissor %3d %3d %3d %3d\n",
438 ctx
->Scissor
.Height
);
439 fprintf( stderr
, "%s: final %3d %3d %3d %3d\n",
440 __FUNCTION__
, x1
, y1
, x2
, y2
);
441 fprintf( stderr
, "\n" );
444 mmesa
->setup
.sc_top_bottom
= ((y1
<< 0) |
447 mmesa
->setup
.sc_left_right
= ((x1
<< 0) |
450 /* UPLOAD_MISC reduces the dirty state, we just need to
451 * emit the scissor to the SAREA. We need to dirty cliprects
452 * since the scissor and cliprects are intersected to update the
453 * single hardware scissor
455 mmesa
->dirty
|= MACH64_UPLOAD_MISC
| MACH64_UPLOAD_CLIPRECTS
;
459 static void mach64DDScissor( GLcontext
*ctx
,
460 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
462 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
464 FLUSH_BATCH( mmesa
);
465 mmesa
->new_state
|= MACH64_NEW_CLIP
;
469 /* =============================================================
473 static void mach64UpdateCull( GLcontext
*ctx
)
475 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
476 GLfloat backface_sign
= 1;
478 if ( ctx
->Polygon
.CullFlag
/*&& ctx->PB->primitive == GL_POLYGON*/ ) {
480 switch ( ctx
->Polygon
.CullFaceMode
) {
482 if ( ctx
->Polygon
.FrontFace
== GL_CCW
)
486 if ( ctx
->Polygon
.FrontFace
!= GL_CCW
)
490 case GL_FRONT_AND_BACK
:
498 mmesa
->backface_sign
= backface_sign
;
502 static void mach64DDCullFace( GLcontext
*ctx
, GLenum mode
)
504 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
506 FLUSH_BATCH( mmesa
);
507 mmesa
->new_state
|= MACH64_NEW_CULL
;
510 static void mach64DDFrontFace( GLcontext
*ctx
, GLenum mode
)
512 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
514 FLUSH_BATCH( mmesa
);
515 mmesa
->new_state
|= MACH64_NEW_CULL
;
519 /* =============================================================
523 static void mach64UpdateMasks( GLcontext
*ctx
)
525 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
526 GLuint mask
= 0xffffffff;
528 /* mach64 can't color mask with alpha blending enabled */
529 if ( !ctx
->Color
.BlendEnabled
) {
530 mask
= mach64PackColor( mmesa
->mach64Screen
->cpp
,
531 ctx
->Color
.ColorMask
[RCOMP
],
532 ctx
->Color
.ColorMask
[GCOMP
],
533 ctx
->Color
.ColorMask
[BCOMP
],
534 ctx
->Color
.ColorMask
[ACOMP
] );
537 if ( mmesa
->setup
.dp_write_mask
!= mask
) {
538 mmesa
->setup
.dp_write_mask
= mask
;
539 mmesa
->dirty
|= MACH64_UPLOAD_DP_WRITE_MASK
;
543 static void mach64DDColorMask( GLcontext
*ctx
,
544 GLboolean r
, GLboolean g
,
545 GLboolean b
, GLboolean a
)
547 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
549 FLUSH_BATCH( mmesa
);
550 mmesa
->new_state
|= MACH64_NEW_MASKS
;
554 /* =============================================================
555 * Rendering attributes
557 * We really don't want to recalculate all this every time we bind a
558 * texture. These things shouldn't change all that often, so it makes
559 * sense to break them out of the core texture state update routines.
562 static void mach64UpdateSpecularLighting( GLcontext
*ctx
)
564 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
565 GLuint a
= mmesa
->setup
.alpha_tst_cntl
;
567 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
568 fprintf( stderr
, "%s:\n", __FUNCTION__
);
571 if ( ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
572 ctx
->Light
.Enabled
) {
573 a
|= MACH64_SPECULAR_LIGHT_EN
;
575 a
&= ~MACH64_SPECULAR_LIGHT_EN
;
578 if ( mmesa
->setup
.alpha_tst_cntl
!= a
) {
579 mmesa
->setup
.alpha_tst_cntl
= a
;
580 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
581 mmesa
->new_state
|= MACH64_NEW_CONTEXT
;
585 static void mach64DDLightModelfv( GLcontext
*ctx
, GLenum pname
,
586 const GLfloat
*param
)
588 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
590 if ( pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
591 FLUSH_BATCH( mmesa
);
592 mach64UpdateSpecularLighting(ctx
);
596 static void mach64DDShadeModel( GLcontext
*ctx
, GLenum mode
)
598 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
599 GLuint s
= mmesa
->setup
.setup_cntl
;
601 s
&= ~MACH64_FLAT_SHADE_MASK
;
605 s
|= MACH64_FLAT_SHADE_VERTEX_3
;
608 s
|= MACH64_FLAT_SHADE_OFF
;
614 if ( mmesa
->setup
.setup_cntl
!= s
) {
615 FLUSH_BATCH( mmesa
);
616 mmesa
->setup
.setup_cntl
= s
;
618 mmesa
->dirty
|= MACH64_UPLOAD_SETUP_CNTL
;
623 /* =============================================================
628 void mach64CalcViewport( GLcontext
*ctx
)
630 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
631 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
632 GLfloat
*m
= mmesa
->hw_viewport
;
634 /* See also mach64_translate_vertex.
636 m
[MAT_SX
] = v
[MAT_SX
];
637 m
[MAT_TX
] = v
[MAT_TX
] + (GLfloat
)mmesa
->drawX
+ SUBPIXEL_X
;
638 m
[MAT_SY
] = - v
[MAT_SY
];
639 m
[MAT_TY
] = - v
[MAT_TY
] + mmesa
->driDrawable
->h
+ (GLfloat
)mmesa
->drawY
+ SUBPIXEL_Y
;
640 m
[MAT_SZ
] = v
[MAT_SZ
] * mmesa
->depth_scale
;
641 m
[MAT_TZ
] = v
[MAT_TZ
] * mmesa
->depth_scale
;
643 mmesa
->SetupNewInputs
= ~0;
646 static void mach64Viewport( GLcontext
*ctx
,
648 GLsizei width
, GLsizei height
)
650 /* update size of Mesa/software ancillary buffers */
651 _mesa_ResizeBuffersMESA();
652 mach64CalcViewport( ctx
);
655 static void mach64DepthRange( GLcontext
*ctx
,
656 GLclampd nearval
, GLclampd farval
)
658 mach64CalcViewport( ctx
);
662 /* =============================================================
666 static void mach64DDClearColor( GLcontext
*ctx
,
667 const GLfloat color
[4] )
669 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
672 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
673 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
674 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
675 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
677 mmesa
->ClearColor
= mach64PackColor( mmesa
->mach64Screen
->cpp
,
678 c
[0], c
[1], c
[2], c
[3] );
681 static void mach64DDLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
683 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
685 if ( ctx
->Color
.ColorLogicOpEnabled
) {
686 FLUSH_BATCH( mmesa
);
688 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
, opcode
!= GL_COPY
);
692 void mach64SetCliprects( GLcontext
*ctx
, GLenum mode
)
694 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
695 __DRIdrawablePrivate
*dPriv
= mmesa
->driDrawable
;
699 mmesa
->numClipRects
= dPriv
->numClipRects
;
700 mmesa
->pClipRects
= dPriv
->pClipRects
;
701 mmesa
->drawX
= dPriv
->x
;
702 mmesa
->drawY
= dPriv
->y
;
705 if ( dPriv
->numBackClipRects
== 0 ) {
706 mmesa
->numClipRects
= dPriv
->numClipRects
;
707 mmesa
->pClipRects
= dPriv
->pClipRects
;
708 mmesa
->drawX
= dPriv
->x
;
709 mmesa
->drawY
= dPriv
->y
;
711 mmesa
->numClipRects
= dPriv
->numBackClipRects
;
712 mmesa
->pClipRects
= dPriv
->pBackClipRects
;
713 mmesa
->drawX
= dPriv
->backX
;
714 mmesa
->drawY
= dPriv
->backY
;
721 mach64UpdateClipping( ctx
);
723 mmesa
->dirty
|= MACH64_UPLOAD_CLIPRECTS
;
726 static void mach64DDDrawBuffer( GLcontext
*ctx
, GLenum mode
)
728 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
730 FLUSH_BATCH( mmesa
);
733 * _DrawDestMask is easier to cope with than <mode>.
735 switch ( ctx
->Color
._DrawDestMask
[0] ) {
736 case DD_FRONT_LEFT_BIT
:
737 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
738 mach64SetCliprects( ctx
, GL_FRONT_LEFT
);
739 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
740 fprintf(stderr
,"%s: DD_FRONT_LEFT_BIT\n", __FUNCTION__
);
742 case DD_BACK_LEFT_BIT
:
743 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
744 mach64SetCliprects( ctx
, GL_BACK_LEFT
);
745 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
746 fprintf(stderr
,"%s: DD_BACK_LEFT_BIT\n", __FUNCTION__
);
749 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
750 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
751 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
752 fprintf(stderr
,"%s: fallback (mode=%d)\n", __FUNCTION__
, mode
);
756 /* We want to update the s/w rast state too so that mach64SetBuffer()
759 _swrast_DrawBuffer(ctx
, mode
);
761 mmesa
->setup
.dst_off_pitch
= (((mmesa
->drawPitch
/8) << 22) |
762 (mmesa
->drawOffset
>> 3));
764 mmesa
->dirty
|= MACH64_UPLOAD_DST_OFF_PITCH
;
767 static void mach64DDReadBuffer( GLcontext
*ctx
, GLenum mode
)
769 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
772 /* =============================================================
773 * State enable/disable
776 static void mach64DDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
778 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
780 if ( MACH64_DEBUG
& DEBUG_VERBOSE_API
) {
781 fprintf( stderr
, "%s( %s = %s )\n",
782 __FUNCTION__
, _mesa_lookup_enum_by_nr( cap
),
783 state
? "GL_TRUE" : "GL_FALSE" );
788 FLUSH_BATCH( mmesa
);
789 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
793 FLUSH_BATCH( mmesa
);
794 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
796 /* enable(GL_BLEND) affects ColorLogicOpEnabled.
798 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
,
799 (ctx
->Color
.ColorLogicOpEnabled
&&
800 ctx
->Color
.LogicOp
!= GL_COPY
));
804 FLUSH_BATCH( mmesa
);
805 mmesa
->new_state
|= MACH64_NEW_CULL
;
809 FLUSH_BATCH( mmesa
);
810 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
815 GLuint s
= mmesa
->setup
.scale_3d_cntl
;
816 FLUSH_BATCH( mmesa
);
818 if ( ctx
->Color
.DitherFlag
) {
819 /* Dithering causes problems w/ 24bpp depth */
820 if ( mmesa
->mach64Screen
->cpp
== 4 )
821 s
|= MACH64_ROUND_EN
;
823 s
|= MACH64_DITHER_EN
;
825 s
&= ~MACH64_DITHER_EN
;
826 s
&= ~MACH64_ROUND_EN
;
829 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
830 mmesa
->setup
.scale_3d_cntl
= s
;
831 mmesa
->dirty
|= ( MACH64_UPLOAD_SCALE_3D_CNTL
);
837 FLUSH_BATCH( mmesa
);
838 mmesa
->new_state
|= MACH64_NEW_FOG
;
841 case GL_INDEX_LOGIC_OP
:
842 case GL_COLOR_LOGIC_OP
:
843 FLUSH_BATCH( mmesa
);
844 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
,
845 state
&& ctx
->Color
.LogicOp
!= GL_COPY
);
849 mach64UpdateSpecularLighting(ctx
);
852 case GL_SCISSOR_TEST
:
853 FLUSH_BATCH( mmesa
);
854 mmesa
->scissor
= state
;
855 mmesa
->new_state
|= MACH64_NEW_CLIP
;
858 case GL_STENCIL_TEST
:
859 FLUSH_BATCH( mmesa
);
860 FALLBACK( mmesa
, MACH64_FALLBACK_STENCIL
, state
);
866 FLUSH_BATCH( mmesa
);
867 mmesa
->new_state
|= MACH64_NEW_TEXTURE
;
875 /* =============================================================
879 static void mach64DDRenderMode( GLcontext
*ctx
, GLenum mode
)
881 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
882 FALLBACK( mmesa
, MACH64_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
885 /* =============================================================
886 * State initialization, management
889 static void mach64DDPrintDirty( const char *msg
, GLuint state
)
892 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s\n",
895 (state
& MACH64_UPLOAD_DST_OFF_PITCH
) ? "dst_off_pitch, " : "",
896 (state
& MACH64_UPLOAD_Z_ALPHA_CNTL
) ? "z_alpha_cntl, " : "",
897 (state
& MACH64_UPLOAD_SCALE_3D_CNTL
) ? "scale_3d_cntl, " : "",
898 (state
& MACH64_UPLOAD_DP_FOG_CLR
) ? "dp_fog_clr, " : "",
899 (state
& MACH64_UPLOAD_DP_WRITE_MASK
) ? "dp_write_mask, " : "",
900 (state
& MACH64_UPLOAD_DP_PIX_WIDTH
) ? "dp_pix_width, " : "",
901 (state
& MACH64_UPLOAD_SETUP_CNTL
) ? "setup_cntl, " : "",
902 (state
& MACH64_UPLOAD_MISC
) ? "misc, " : "",
903 (state
& MACH64_UPLOAD_TEXTURE
) ? "texture, " : "",
904 (state
& MACH64_UPLOAD_TEX0IMAGE
) ? "tex0 image, " : "",
905 (state
& MACH64_UPLOAD_TEX1IMAGE
) ? "tex1 image, " : "",
906 (state
& MACH64_UPLOAD_CLIPRECTS
) ? "cliprects, " : "" );
910 * Load the current context's state into the hardware.
912 * NOTE: Be VERY careful about ensuring the context state is marked for
913 * upload, the only place it shouldn't be uploaded is when the setup
914 * state has changed in ReducedPrimitiveChange as this comes right after
917 * Blits of any type should always upload the context and masks after
920 void mach64EmitHwStateLocked( mach64ContextPtr mmesa
)
922 drm_mach64_sarea_t
*sarea
= mmesa
->sarea
;
923 drm_mach64_context_regs_t
*regs
= &(mmesa
->setup
);
924 mach64TexObjPtr t0
= mmesa
->CurrentTexObj
[0];
925 mach64TexObjPtr t1
= mmesa
->CurrentTexObj
[1];
927 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
928 mach64DDPrintDirty( __FUNCTION__
, mmesa
->dirty
);
931 if ( t0
&& t1
&& mmesa
->mach64Screen
->numTexHeaps
> 1 ) {
932 if (t0
->heap
!= t1
->heap
||
933 (mmesa
->dirty
& MACH64_UPLOAD_TEX0IMAGE
) ||
934 (mmesa
->dirty
& MACH64_UPLOAD_TEX1IMAGE
))
935 mach64UploadMultiTexImages( mmesa
, t0
, t1
);
937 if ( mmesa
->dirty
& MACH64_UPLOAD_TEX0IMAGE
) {
938 if ( t0
) mach64UploadTexImages( mmesa
, t0
);
940 if ( mmesa
->dirty
& MACH64_UPLOAD_TEX1IMAGE
) {
941 if ( t1
) mach64UploadTexImages( mmesa
, t1
);
945 if ( mmesa
->dirty
& (MACH64_UPLOAD_CONTEXT
| MACH64_UPLOAD_MISC
) ) {
946 memcpy( &sarea
->context_state
, regs
,
947 MACH64_NR_CONTEXT_REGS
* sizeof(GLuint
) );
950 if ( mmesa
->dirty
& MACH64_UPLOAD_TEXTURE
) {
951 mach64EmitTexStateLocked( mmesa
, t0
, t1
);
954 sarea
->vertsize
= mmesa
->vertex_size
;
956 /* Turn off the texture cache flushing.
958 mmesa
->setup
.tex_cntl
&= ~MACH64_TEX_CACHE_FLUSH
;
960 sarea
->dirty
|= mmesa
->dirty
;
962 mmesa
->dirty
&= MACH64_UPLOAD_CLIPRECTS
;
965 static void mach64DDPrintState( const char *msg
, GLuint flags
)
968 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
971 (flags
& MACH64_NEW_CONTEXT
) ? "context, " : "",
972 (flags
& MACH64_NEW_ALPHA
) ? "alpha, " : "",
973 (flags
& MACH64_NEW_DEPTH
) ? "depth, " : "",
974 (flags
& MACH64_NEW_FOG
) ? "fog, " : "",
975 (flags
& MACH64_NEW_CLIP
) ? "clip, " : "",
976 (flags
& MACH64_NEW_TEXTURE
) ? "texture, " : "",
977 (flags
& MACH64_NEW_CULL
) ? "cull, " : "",
978 (flags
& MACH64_NEW_MASKS
) ? "masks, " : "",
979 (flags
& MACH64_NEW_WINDOW
) ? "window, " : "" );
982 /* Update the hardware state */
983 void mach64DDUpdateHWState( GLcontext
*ctx
)
985 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
986 int new_state
= mmesa
->new_state
;
988 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
989 fprintf( stderr
, "%s:\n", __FUNCTION__
);
994 FLUSH_BATCH( mmesa
);
996 mmesa
->new_state
= 0;
998 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
999 mach64DDPrintState( __FUNCTION__
, new_state
);
1001 /* Update the various parts of the context's state.
1003 if ( new_state
& MACH64_NEW_ALPHA
)
1004 mach64UpdateAlphaMode( ctx
);
1006 if ( new_state
& MACH64_NEW_DEPTH
)
1007 mach64UpdateZMode( ctx
);
1009 if ( new_state
& MACH64_NEW_FOG
)
1010 mach64UpdateFogAttrib( ctx
);
1012 if ( new_state
& MACH64_NEW_CLIP
)
1013 mach64UpdateClipping( ctx
);
1015 if ( new_state
& MACH64_NEW_WINDOW
)
1016 mach64CalcViewport( ctx
);
1018 if ( new_state
& MACH64_NEW_CULL
)
1019 mach64UpdateCull( ctx
);
1021 if ( new_state
& MACH64_NEW_MASKS
)
1022 mach64UpdateMasks( ctx
);
1024 if ( new_state
& MACH64_NEW_TEXTURE
)
1025 mach64UpdateTextureState( ctx
);
1030 static void mach64DDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1032 _swrast_InvalidateState( ctx
, new_state
);
1033 _swsetup_InvalidateState( ctx
, new_state
);
1034 _ac_InvalidateState( ctx
, new_state
);
1035 _tnl_InvalidateState( ctx
, new_state
);
1036 MACH64_CONTEXT(ctx
)->NewGLState
|= new_state
;
1040 /* Initialize the context's hardware state */
1041 void mach64DDInitState( mach64ContextPtr mmesa
)
1045 switch ( mmesa
->mach64Screen
->cpp
) {
1047 format
= MACH64_DATATYPE_RGB565
;
1050 format
= MACH64_DATATYPE_ARGB8888
;
1053 fprintf( stderr
, "Error: Unsupported pixel depth... exiting\n" );
1057 /* Always have a 16-bit depth buffer
1058 * but Z coordinates are specified in 16.1 format to the setup engine.
1060 mmesa
->depth_scale
= 2.0;
1062 mmesa
->ClearColor
= 0x00000000;
1063 mmesa
->ClearDepth
= 0x0000ffff;
1065 mmesa
->Fallback
= 0;
1067 if ( mmesa
->glCtx
->Visual
.doubleBufferMode
) {
1068 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->backOffset
;
1069 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->backPitch
;
1071 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->frontOffset
;
1072 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->frontPitch
;
1077 mmesa
->setup
.dst_off_pitch
= (((mmesa
->drawPitch
/8) << 22) |
1078 (mmesa
->drawOffset
>> 3));
1080 mmesa
->setup
.z_off_pitch
= (((mmesa
->mach64Screen
->depthPitch
/8) << 22) |
1081 (mmesa
->mach64Screen
->depthOffset
>> 3));
1083 mmesa
->setup
.z_cntl
= (MACH64_Z_TEST_LESS
|
1086 mmesa
->setup
.alpha_tst_cntl
= (MACH64_ALPHA_TEST_ALWAYS
|
1087 MACH64_ALPHA_DST_SRCALPHA
|
1088 MACH64_ALPHA_TST_SRC_TEXEL
|
1089 (0 << MACH64_REF_ALPHA_SHIFT
));
1091 mmesa
->setup
.scale_3d_cntl
= (MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE
|
1092 /* MACH64_SCALE_DITHER_ERROR_DIFFUSE | */
1093 MACH64_SCALE_DITHER_2D_TABLE
|
1094 /* MACH64_DITHER_INIT_CURRENT | */
1095 MACH64_DITHER_INIT_RESET
|
1096 MACH64_SCALE_3D_FCN_SHADE
|
1097 MACH64_ALPHA_FOG_DIS
|
1098 MACH64_ALPHA_BLEND_SRC_ONE
|
1099 MACH64_ALPHA_BLEND_DST_ZERO
|
1100 MACH64_TEX_LIGHT_FCN_MODULATE
|
1101 MACH64_MIP_MAP_DISABLE
|
1102 MACH64_BILINEAR_TEX_EN
|
1103 MACH64_TEX_BLEND_FCN_LINEAR
);
1105 /* GL spec says dithering initially enabled, but dithering causes
1106 * problems w/ 24bpp depth
1108 if ( mmesa
->mach64Screen
->cpp
== 4 )
1109 mmesa
->setup
.scale_3d_cntl
|= MACH64_ROUND_EN
;
1111 mmesa
->setup
.scale_3d_cntl
|= MACH64_DITHER_EN
;
1113 mmesa
->setup
.sc_left_right
= 0x1fff0000;
1114 mmesa
->setup
.sc_top_bottom
= 0x3fff0000;
1116 mmesa
->setup
.dp_fog_clr
= 0x00ffffff;
1117 mmesa
->setup
.dp_write_mask
= 0xffffffff;
1119 mmesa
->setup
.dp_pix_width
= ((format
<< 0) |
1125 mmesa
->setup
.dp_mix
= (MACH64_BKGD_MIX_S
|
1127 mmesa
->setup
.dp_src
= (MACH64_BKGD_SRC_3D
|
1128 MACH64_FRGD_SRC_3D
|
1129 MACH64_MONO_SRC_ONE
);
1131 mmesa
->setup
.clr_cmp_cntl
= 0x00000000;
1132 mmesa
->setup
.gui_traj_cntl
= (MACH64_DST_X_LEFT_TO_RIGHT
|
1133 MACH64_DST_Y_TOP_TO_BOTTOM
);
1135 mmesa
->setup
.setup_cntl
= (MACH64_FLAT_SHADE_OFF
|
1136 MACH64_SOLID_MODE_OFF
|
1137 MACH64_LOG_MAX_INC_ADJ
);
1138 mmesa
->setup
.setup_cntl
= 0;
1140 mmesa
->setup
.tex_size_pitch
= 0x00000000;
1142 mmesa
->setup
.tex_cntl
= ((0 << MACH64_LOD_BIAS_SHIFT
) |
1143 (0 << MACH64_COMP_FACTOR_SHIFT
) |
1144 MACH64_COMP_COMBINE_MODULATE
|
1145 MACH64_COMP_BLEND_NEAREST
|
1146 MACH64_COMP_FILTER_NEAREST
|
1147 /* MACH64_TEXTURE_TILING | */
1148 #ifdef MACH64_PREMULT_TEXCOORDS
1149 MACH64_TEX_ST_DIRECT
|
1151 MACH64_TEX_SRC_LOCAL
|
1152 MACH64_TEX_UNCOMPRESSED
|
1153 MACH64_TEX_CACHE_FLUSH
|
1154 MACH64_TEX_CACHE_SIZE_4K
);
1156 mmesa
->setup
.secondary_tex_off
= 0x00000000;
1157 mmesa
->setup
.tex_offset
= 0x00000000;
1159 mmesa
->new_state
= MACH64_NEW_ALL
;
1162 /* Initialize the driver's state functions.
1164 void mach64DDInitStateFuncs( GLcontext
*ctx
)
1166 ctx
->Driver
.UpdateState
= mach64DDInvalidateState
;
1168 ctx
->Driver
.ClearIndex
= NULL
;
1169 ctx
->Driver
.ClearColor
= mach64DDClearColor
;
1170 ctx
->Driver
.DrawBuffer
= mach64DDDrawBuffer
;
1171 ctx
->Driver
.ReadBuffer
= mach64DDReadBuffer
;
1173 ctx
->Driver
.IndexMask
= NULL
;
1174 ctx
->Driver
.ColorMask
= mach64DDColorMask
;
1175 ctx
->Driver
.AlphaFunc
= mach64DDAlphaFunc
;
1176 ctx
->Driver
.BlendEquationSeparate
= mach64DDBlendEquationSeparate
;
1177 ctx
->Driver
.BlendFuncSeparate
= mach64DDBlendFuncSeparate
;
1178 ctx
->Driver
.ClearDepth
= mach64DDClearDepth
;
1179 ctx
->Driver
.CullFace
= mach64DDCullFace
;
1180 ctx
->Driver
.FrontFace
= mach64DDFrontFace
;
1181 ctx
->Driver
.DepthFunc
= mach64DDDepthFunc
;
1182 ctx
->Driver
.DepthMask
= mach64DDDepthMask
;
1183 ctx
->Driver
.Enable
= mach64DDEnable
;
1184 ctx
->Driver
.Fogfv
= mach64DDFogfv
;
1185 ctx
->Driver
.Hint
= NULL
;
1186 ctx
->Driver
.Lightfv
= NULL
;
1187 ctx
->Driver
.LightModelfv
= mach64DDLightModelfv
;
1188 ctx
->Driver
.LogicOpcode
= mach64DDLogicOpCode
;
1189 ctx
->Driver
.PolygonMode
= NULL
;
1190 ctx
->Driver
.PolygonStipple
= NULL
;
1191 ctx
->Driver
.RenderMode
= mach64DDRenderMode
;
1192 ctx
->Driver
.Scissor
= mach64DDScissor
;
1193 ctx
->Driver
.ShadeModel
= mach64DDShadeModel
;
1194 ctx
->Driver
.ClearStencil
= NULL
;
1195 ctx
->Driver
.StencilFunc
= NULL
;
1196 ctx
->Driver
.StencilMask
= NULL
;
1197 ctx
->Driver
.StencilOp
= NULL
;
1199 ctx
->Driver
.DepthRange
= mach64DepthRange
;
1200 ctx
->Driver
.Viewport
= mach64Viewport
;
1202 /* Pixel path fallbacks.
1204 ctx
->Driver
.Accum
= _swrast_Accum
;
1205 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1206 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1207 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1208 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1210 /* Swrast hooks for imaging extensions:
1212 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1213 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1214 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1215 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;