1 /* -*- 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"
39 #include "main/enums.h"
40 #include "main/colormac.h"
41 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
47 /* =============================================================
51 static void mach64UpdateAlphaMode( GLcontext
*ctx
)
53 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
54 GLuint a
= mmesa
->setup
.alpha_tst_cntl
;
55 GLuint s
= mmesa
->setup
.scale_3d_cntl
;
56 GLuint m
= mmesa
->setup
.dp_write_mask
;
58 if ( ctx
->Color
.AlphaEnabled
) {
61 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
63 a
&= ~(MACH64_ALPHA_TEST_MASK
| MACH64_REF_ALPHA_MASK
);
65 switch ( ctx
->Color
.AlphaFunc
) {
67 a
|= MACH64_ALPHA_TEST_NEVER
;
70 a
|= MACH64_ALPHA_TEST_LESS
;
73 a
|= MACH64_ALPHA_TEST_LEQUAL
;
76 a
|= MACH64_ALPHA_TEST_EQUAL
;
79 a
|= MACH64_ALPHA_TEST_GEQUAL
;
82 a
|= MACH64_ALPHA_TEST_GREATER
;
85 a
|= MACH64_ALPHA_TEST_NOTEQUAL
;
88 a
|= MACH64_ALPHA_TEST_ALWAYS
;
92 a
|= (ref
<< MACH64_REF_ALPHA_SHIFT
);
93 a
|= MACH64_ALPHA_TEST_EN
;
95 a
&= ~MACH64_ALPHA_TEST_EN
;
98 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_FALSE
);
100 if ( ctx
->Color
.BlendEnabled
) {
101 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
102 MACH64_ALPHA_BLEND_DST_MASK
|
103 MACH64_ALPHA_BLEND_SAT
);
105 switch ( ctx
->Color
.BlendSrcRGB
) {
107 s
|= MACH64_ALPHA_BLEND_SRC_ZERO
;
110 s
|= MACH64_ALPHA_BLEND_SRC_ONE
;
113 s
|= MACH64_ALPHA_BLEND_SRC_DSTCOLOR
;
115 case GL_ONE_MINUS_DST_COLOR
:
116 s
|= MACH64_ALPHA_BLEND_SRC_INVDSTCOLOR
;
119 s
|= MACH64_ALPHA_BLEND_SRC_SRCALPHA
;
121 case GL_ONE_MINUS_SRC_ALPHA
:
122 s
|= MACH64_ALPHA_BLEND_SRC_INVSRCALPHA
;
125 s
|= MACH64_ALPHA_BLEND_SRC_DSTALPHA
;
127 case GL_ONE_MINUS_DST_ALPHA
:
128 s
|= MACH64_ALPHA_BLEND_SRC_INVDSTALPHA
;
130 case GL_SRC_ALPHA_SATURATE
:
131 s
|= (MACH64_ALPHA_BLEND_SRC_SRCALPHA
|
132 MACH64_ALPHA_BLEND_SAT
);
135 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_TRUE
);
138 switch ( ctx
->Color
.BlendDstRGB
) {
140 s
|= MACH64_ALPHA_BLEND_DST_ZERO
;
143 s
|= MACH64_ALPHA_BLEND_DST_ONE
;
146 s
|= MACH64_ALPHA_BLEND_DST_SRCCOLOR
;
148 case GL_ONE_MINUS_SRC_COLOR
:
149 s
|= MACH64_ALPHA_BLEND_DST_INVSRCCOLOR
;
152 s
|= MACH64_ALPHA_BLEND_DST_SRCALPHA
;
154 case GL_ONE_MINUS_SRC_ALPHA
:
155 s
|= MACH64_ALPHA_BLEND_DST_INVSRCALPHA
;
158 s
|= MACH64_ALPHA_BLEND_DST_DSTALPHA
;
160 case GL_ONE_MINUS_DST_ALPHA
:
161 s
|= MACH64_ALPHA_BLEND_DST_INVDSTALPHA
;
164 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_TRUE
);
167 m
= 0xffffffff; /* Can't color mask and blend at the same time */
168 s
&= ~MACH64_ALPHA_FOG_EN_FOG
; /* Can't fog and blend at the same time */
169 s
|= MACH64_ALPHA_FOG_EN_ALPHA
;
171 s
&= ~MACH64_ALPHA_FOG_EN_ALPHA
;
174 if ( mmesa
->setup
.alpha_tst_cntl
!= a
) {
175 mmesa
->setup
.alpha_tst_cntl
= a
;
176 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
178 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
179 mmesa
->setup
.scale_3d_cntl
= s
;
180 mmesa
->dirty
|= MACH64_UPLOAD_SCALE_3D_CNTL
;
182 if ( mmesa
->setup
.dp_write_mask
!= m
) {
183 mmesa
->setup
.dp_write_mask
= m
;
184 mmesa
->dirty
|= MACH64_UPLOAD_DP_WRITE_MASK
;
188 static void mach64DDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
190 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
192 FLUSH_BATCH( mmesa
);
193 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
196 static void mach64DDBlendEquationSeparate( GLcontext
*ctx
,
197 GLenum modeRGB
, GLenum modeA
)
199 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
201 assert( modeRGB
== modeA
);
202 FLUSH_BATCH( mmesa
);
204 /* BlendEquation affects ColorLogicOpEnabled
206 FALLBACK( MACH64_CONTEXT(ctx
), MACH64_FALLBACK_LOGICOP
,
207 (ctx
->Color
.ColorLogicOpEnabled
&&
208 ctx
->Color
.LogicOp
!= GL_COPY
));
210 /* Can only do blend addition, not min, max, subtract, etc. */
211 FALLBACK( MACH64_CONTEXT(ctx
), MACH64_FALLBACK_BLEND_EQ
,
212 modeRGB
!= GL_FUNC_ADD
);
214 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
217 static void mach64DDBlendFuncSeparate( GLcontext
*ctx
,
218 GLenum sfactorRGB
, GLenum dfactorRGB
,
219 GLenum sfactorA
, GLenum dfactorA
)
221 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
223 FLUSH_BATCH( mmesa
);
224 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
228 /* =============================================================
232 static void mach64UpdateZMode( GLcontext
*ctx
)
234 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
235 GLuint z
= mmesa
->setup
.z_cntl
;
237 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
238 fprintf( stderr
, "%s:\n", __FUNCTION__
);
241 if ( ctx
->Depth
.Test
) {
242 z
&= ~MACH64_Z_TEST_MASK
;
244 switch ( ctx
->Depth
.Func
) {
246 z
|= MACH64_Z_TEST_NEVER
;
249 z
|= MACH64_Z_TEST_ALWAYS
;
252 z
|= MACH64_Z_TEST_LESS
;
255 z
|= MACH64_Z_TEST_LEQUAL
;
258 z
|= MACH64_Z_TEST_EQUAL
;
261 z
|= MACH64_Z_TEST_GEQUAL
;
264 z
|= MACH64_Z_TEST_GREATER
;
267 z
|= MACH64_Z_TEST_NOTEQUAL
;
276 if ( ctx
->Depth
.Mask
) {
277 z
|= MACH64_Z_MASK_EN
;
279 z
&= ~MACH64_Z_MASK_EN
;
282 if ( mmesa
->setup
.z_cntl
!= z
) {
283 mmesa
->setup
.z_cntl
= z
;
284 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
288 static void mach64DDDepthFunc( GLcontext
*ctx
, GLenum func
)
290 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
292 FLUSH_BATCH( mmesa
);
293 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
296 static void mach64DDDepthMask( GLcontext
*ctx
, GLboolean flag
)
298 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
300 FLUSH_BATCH( mmesa
);
301 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
304 static void mach64DDClearDepth( GLcontext
*ctx
, GLclampd d
)
306 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
308 /* Always have a 16-bit depth buffer.
310 mmesa
->ClearDepth
= d
* 0xffff;
314 /* =============================================================
318 static void mach64UpdateFogAttrib( GLcontext
*ctx
)
320 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
322 CARD32 s
= mmesa
->setup
.scale_3d_cntl
;
326 /* Can't fog if blending is on */
327 if ( ctx
->Color
.BlendEnabled
)
330 if ( ctx
->Fog
.Enabled
) {
331 s
|= MACH64_ALPHA_FOG_EN_FOG
;
332 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
333 MACH64_ALPHA_BLEND_DST_MASK
|
334 MACH64_ALPHA_BLEND_SAT
);
335 /* From Utah-glx: "fog color is now dest and fog factor is alpha, so
336 * use GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA"
338 s
|= (MACH64_ALPHA_BLEND_SRC_SRCALPHA
|
339 MACH64_ALPHA_BLEND_DST_INVSRCALPHA
);
340 /* From Utah-glx: "can't use texture alpha when fogging" */
341 s
&= ~MACH64_TEX_MAP_AEN
;
343 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
344 MACH64_ALPHA_BLEND_DST_MASK
|
345 MACH64_ALPHA_BLEND_SAT
);
346 s
|= (MACH64_ALPHA_BLEND_SRC_ONE
|
347 MACH64_ALPHA_BLEND_DST_ZERO
);
348 s
&= ~MACH64_ALPHA_FOG_EN_FOG
;
351 c
[0] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] );
352 c
[1] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] );
353 c
[2] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
354 c
[3] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[3] );
356 col
= mach64PackColor( 4, c
[0], c
[1], c
[2], c
[3] );
358 if ( mmesa
->setup
.dp_fog_clr
!= col
) {
359 mmesa
->setup
.dp_fog_clr
= col
;
360 mmesa
->dirty
|= MACH64_UPLOAD_DP_FOG_CLR
;
362 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
363 mmesa
->setup
.scale_3d_cntl
= s
;
364 mmesa
->dirty
|= MACH64_UPLOAD_SCALE_3D_CNTL
;
369 static void mach64DDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
371 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
373 FLUSH_BATCH( mmesa
);
374 mmesa
->new_state
|= MACH64_NEW_FOG
;
378 /* =============================================================
382 static void mach64UpdateClipping( GLcontext
*ctx
)
384 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
385 mach64ScreenPtr mach64Screen
= mmesa
->mach64Screen
;
387 if ( mmesa
->driDrawable
) {
388 __DRIdrawable
*drawable
= mmesa
->driDrawable
;
391 int x2
= drawable
->w
- 1;
392 int y2
= drawable
->h
- 1;
394 if ( ctx
->Scissor
.Enabled
) {
395 if ( ctx
->Scissor
.X
> x1
) {
398 if ( drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
> y1
) {
399 y1
= drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
401 if ( ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
) {
402 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
404 if ( drawable
->h
- ctx
->Scissor
.Y
- 1 < y2
) {
405 y2
= drawable
->h
- ctx
->Scissor
.Y
- 1;
414 /* clamp to screen borders */
419 if (x2
> mach64Screen
->width
-1) x2
= mach64Screen
->width
-1;
420 if (y2
> mach64Screen
->height
-1) y2
= mach64Screen
->height
-1;
422 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
423 fprintf( stderr
, "%s: drawable %3d %3d %3d %3d\n",
429 fprintf( stderr
, "%s: scissor %3d %3d %3d %3d\n",
434 ctx
->Scissor
.Height
);
435 fprintf( stderr
, "%s: final %3d %3d %3d %3d\n",
436 __FUNCTION__
, x1
, y1
, x2
, y2
);
437 fprintf( stderr
, "\n" );
440 mmesa
->setup
.sc_top_bottom
= ((y1
<< 0) |
443 mmesa
->setup
.sc_left_right
= ((x1
<< 0) |
446 /* UPLOAD_MISC reduces the dirty state, we just need to
447 * emit the scissor to the SAREA. We need to dirty cliprects
448 * since the scissor and cliprects are intersected to update the
449 * single hardware scissor
451 mmesa
->dirty
|= MACH64_UPLOAD_MISC
| MACH64_UPLOAD_CLIPRECTS
;
455 static void mach64DDScissor( GLcontext
*ctx
,
456 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
458 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
460 FLUSH_BATCH( mmesa
);
461 mmesa
->new_state
|= MACH64_NEW_CLIP
;
465 /* =============================================================
469 static void mach64UpdateCull( GLcontext
*ctx
)
471 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
472 GLfloat backface_sign
= 1;
474 if ( ctx
->Polygon
.CullFlag
/*&& ctx->PB->primitive == GL_POLYGON*/ ) {
476 switch ( ctx
->Polygon
.CullFaceMode
) {
478 if ( ctx
->Polygon
.FrontFace
== GL_CCW
)
482 if ( ctx
->Polygon
.FrontFace
!= GL_CCW
)
486 case GL_FRONT_AND_BACK
:
494 mmesa
->backface_sign
= backface_sign
;
498 static void mach64DDCullFace( GLcontext
*ctx
, GLenum mode
)
500 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
502 FLUSH_BATCH( mmesa
);
503 mmesa
->new_state
|= MACH64_NEW_CULL
;
506 static void mach64DDFrontFace( GLcontext
*ctx
, GLenum mode
)
508 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
510 FLUSH_BATCH( mmesa
);
511 mmesa
->new_state
|= MACH64_NEW_CULL
;
515 /* =============================================================
519 static void mach64UpdateMasks( GLcontext
*ctx
)
521 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
522 GLuint mask
= 0xffffffff;
524 /* mach64 can't color mask with alpha blending enabled */
525 if ( !ctx
->Color
.BlendEnabled
) {
526 mask
= mach64PackColor( mmesa
->mach64Screen
->cpp
,
527 ctx
->Color
.ColorMask
[0][RCOMP
],
528 ctx
->Color
.ColorMask
[0][GCOMP
],
529 ctx
->Color
.ColorMask
[0][BCOMP
],
530 ctx
->Color
.ColorMask
[0][ACOMP
] );
533 if ( mmesa
->setup
.dp_write_mask
!= mask
) {
534 mmesa
->setup
.dp_write_mask
= mask
;
535 mmesa
->dirty
|= MACH64_UPLOAD_DP_WRITE_MASK
;
539 static void mach64DDColorMask( GLcontext
*ctx
,
540 GLboolean r
, GLboolean g
,
541 GLboolean b
, GLboolean a
)
543 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
545 FLUSH_BATCH( mmesa
);
546 mmesa
->new_state
|= MACH64_NEW_MASKS
;
550 /* =============================================================
551 * Rendering attributes
553 * We really don't want to recalculate all this every time we bind a
554 * texture. These things shouldn't change all that often, so it makes
555 * sense to break them out of the core texture state update routines.
558 static void mach64UpdateSpecularLighting( GLcontext
*ctx
)
560 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
561 GLuint a
= mmesa
->setup
.alpha_tst_cntl
;
563 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
564 fprintf( stderr
, "%s:\n", __FUNCTION__
);
567 if ( ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
568 ctx
->Light
.Enabled
) {
569 a
|= MACH64_SPECULAR_LIGHT_EN
;
571 a
&= ~MACH64_SPECULAR_LIGHT_EN
;
574 if ( mmesa
->setup
.alpha_tst_cntl
!= a
) {
575 mmesa
->setup
.alpha_tst_cntl
= a
;
576 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
577 mmesa
->new_state
|= MACH64_NEW_CONTEXT
;
581 static void mach64DDLightModelfv( GLcontext
*ctx
, GLenum pname
,
582 const GLfloat
*param
)
584 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
586 if ( pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
587 FLUSH_BATCH( mmesa
);
588 mach64UpdateSpecularLighting(ctx
);
592 static void mach64DDShadeModel( GLcontext
*ctx
, GLenum mode
)
594 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
595 GLuint s
= mmesa
->setup
.setup_cntl
;
597 s
&= ~MACH64_FLAT_SHADE_MASK
;
601 s
|= MACH64_FLAT_SHADE_VERTEX_3
;
604 s
|= MACH64_FLAT_SHADE_OFF
;
610 if ( mmesa
->setup
.setup_cntl
!= s
) {
611 FLUSH_BATCH( mmesa
);
612 mmesa
->setup
.setup_cntl
= s
;
614 mmesa
->dirty
|= MACH64_UPLOAD_SETUP_CNTL
;
619 /* =============================================================
624 void mach64CalcViewport( GLcontext
*ctx
)
626 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
627 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
628 GLfloat
*m
= mmesa
->hw_viewport
;
630 /* See also mach64_translate_vertex.
632 m
[MAT_SX
] = v
[MAT_SX
];
633 m
[MAT_TX
] = v
[MAT_TX
] + (GLfloat
)mmesa
->drawX
+ SUBPIXEL_X
;
634 m
[MAT_SY
] = - v
[MAT_SY
];
635 m
[MAT_TY
] = - v
[MAT_TY
] + mmesa
->driDrawable
->h
+ (GLfloat
)mmesa
->drawY
+ SUBPIXEL_Y
;
636 m
[MAT_SZ
] = v
[MAT_SZ
] * mmesa
->depth_scale
;
637 m
[MAT_TZ
] = v
[MAT_TZ
] * mmesa
->depth_scale
;
639 mmesa
->SetupNewInputs
= ~0;
642 static void mach64Viewport( GLcontext
*ctx
,
644 GLsizei width
, GLsizei height
)
646 mach64CalcViewport( ctx
);
649 static void mach64DepthRange( GLcontext
*ctx
,
650 GLclampd nearval
, GLclampd farval
)
652 mach64CalcViewport( ctx
);
656 /* =============================================================
660 static void mach64DDClearColor( GLcontext
*ctx
,
661 const GLfloat color
[4] )
663 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
666 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
667 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
668 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
669 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
671 mmesa
->ClearColor
= mach64PackColor( mmesa
->mach64Screen
->cpp
,
672 c
[0], c
[1], c
[2], c
[3] );
675 static void mach64DDLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
677 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
679 if ( ctx
->Color
.ColorLogicOpEnabled
) {
680 FLUSH_BATCH( mmesa
);
682 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
, opcode
!= GL_COPY
);
686 void mach64SetCliprects( GLcontext
*ctx
, GLenum mode
)
688 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
689 __DRIdrawable
*dPriv
= mmesa
->driDrawable
;
693 mmesa
->numClipRects
= dPriv
->numClipRects
;
694 mmesa
->pClipRects
= dPriv
->pClipRects
;
695 mmesa
->drawX
= dPriv
->x
;
696 mmesa
->drawY
= dPriv
->y
;
699 if ( dPriv
->numBackClipRects
== 0 ) {
700 mmesa
->numClipRects
= dPriv
->numClipRects
;
701 mmesa
->pClipRects
= dPriv
->pClipRects
;
702 mmesa
->drawX
= dPriv
->x
;
703 mmesa
->drawY
= dPriv
->y
;
705 mmesa
->numClipRects
= dPriv
->numBackClipRects
;
706 mmesa
->pClipRects
= dPriv
->pBackClipRects
;
707 mmesa
->drawX
= dPriv
->backX
;
708 mmesa
->drawY
= dPriv
->backY
;
715 mach64UpdateClipping( ctx
);
717 mmesa
->dirty
|= MACH64_UPLOAD_CLIPRECTS
;
720 static void mach64DDDrawBuffer( GLcontext
*ctx
, GLenum mode
)
722 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
724 FLUSH_BATCH( mmesa
);
726 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
!= 1) {
727 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
728 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
732 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
733 case BUFFER_FRONT_LEFT
:
734 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
735 mach64SetCliprects( ctx
, GL_FRONT_LEFT
);
736 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
737 fprintf(stderr
,"%s: BUFFER_BIT_FRONT_LEFT\n", __FUNCTION__
);
739 case BUFFER_BACK_LEFT
:
740 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
741 mach64SetCliprects( ctx
, GL_BACK_LEFT
);
742 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
743 fprintf(stderr
,"%s: BUFFER_BIT_BACK_LEFT\n", __FUNCTION__
);
746 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
747 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
748 fprintf(stderr
,"%s: fallback (mode=%d)\n", __FUNCTION__
, mode
);
752 mmesa
->setup
.dst_off_pitch
= (((mmesa
->drawPitch
/8) << 22) |
753 (mmesa
->drawOffset
>> 3));
755 mmesa
->dirty
|= MACH64_UPLOAD_DST_OFF_PITCH
;
758 static void mach64DDReadBuffer( GLcontext
*ctx
, GLenum mode
)
760 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
763 /* =============================================================
764 * State enable/disable
767 static void mach64DDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
769 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
771 if ( MACH64_DEBUG
& DEBUG_VERBOSE_API
) {
772 fprintf( stderr
, "%s( %s = %s )\n",
773 __FUNCTION__
, _mesa_lookup_enum_by_nr( cap
),
774 state
? "GL_TRUE" : "GL_FALSE" );
779 FLUSH_BATCH( mmesa
);
780 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
784 FLUSH_BATCH( mmesa
);
785 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
787 /* enable(GL_BLEND) affects ColorLogicOpEnabled.
789 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
,
790 (ctx
->Color
.ColorLogicOpEnabled
&&
791 ctx
->Color
.LogicOp
!= GL_COPY
));
795 FLUSH_BATCH( mmesa
);
796 mmesa
->new_state
|= MACH64_NEW_CULL
;
800 FLUSH_BATCH( mmesa
);
801 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
806 GLuint s
= mmesa
->setup
.scale_3d_cntl
;
807 FLUSH_BATCH( mmesa
);
809 if ( ctx
->Color
.DitherFlag
) {
810 /* Dithering causes problems w/ 24bpp depth */
811 if ( mmesa
->mach64Screen
->cpp
== 4 )
812 s
|= MACH64_ROUND_EN
;
814 s
|= MACH64_DITHER_EN
;
816 s
&= ~MACH64_DITHER_EN
;
817 s
&= ~MACH64_ROUND_EN
;
820 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
821 mmesa
->setup
.scale_3d_cntl
= s
;
822 mmesa
->dirty
|= ( MACH64_UPLOAD_SCALE_3D_CNTL
);
828 FLUSH_BATCH( mmesa
);
829 mmesa
->new_state
|= MACH64_NEW_FOG
;
832 case GL_INDEX_LOGIC_OP
:
833 case GL_COLOR_LOGIC_OP
:
834 FLUSH_BATCH( mmesa
);
835 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
,
836 state
&& ctx
->Color
.LogicOp
!= GL_COPY
);
840 mach64UpdateSpecularLighting(ctx
);
843 case GL_SCISSOR_TEST
:
844 FLUSH_BATCH( mmesa
);
845 mmesa
->scissor
= state
;
846 mmesa
->new_state
|= MACH64_NEW_CLIP
;
849 case GL_STENCIL_TEST
:
850 FLUSH_BATCH( mmesa
);
851 FALLBACK( mmesa
, MACH64_FALLBACK_STENCIL
, state
);
857 FLUSH_BATCH( mmesa
);
858 mmesa
->new_state
|= MACH64_NEW_TEXTURE
;
866 /* =============================================================
870 static void mach64DDRenderMode( GLcontext
*ctx
, GLenum mode
)
872 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
873 FALLBACK( mmesa
, MACH64_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
876 /* =============================================================
877 * State initialization, management
880 static void mach64DDPrintDirty( const char *msg
, GLuint state
)
883 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s\n",
886 (state
& MACH64_UPLOAD_DST_OFF_PITCH
) ? "dst_off_pitch, " : "",
887 (state
& MACH64_UPLOAD_Z_ALPHA_CNTL
) ? "z_alpha_cntl, " : "",
888 (state
& MACH64_UPLOAD_SCALE_3D_CNTL
) ? "scale_3d_cntl, " : "",
889 (state
& MACH64_UPLOAD_DP_FOG_CLR
) ? "dp_fog_clr, " : "",
890 (state
& MACH64_UPLOAD_DP_WRITE_MASK
) ? "dp_write_mask, " : "",
891 (state
& MACH64_UPLOAD_DP_PIX_WIDTH
) ? "dp_pix_width, " : "",
892 (state
& MACH64_UPLOAD_SETUP_CNTL
) ? "setup_cntl, " : "",
893 (state
& MACH64_UPLOAD_MISC
) ? "misc, " : "",
894 (state
& MACH64_UPLOAD_TEXTURE
) ? "texture, " : "",
895 (state
& MACH64_UPLOAD_TEX0IMAGE
) ? "tex0 image, " : "",
896 (state
& MACH64_UPLOAD_TEX1IMAGE
) ? "tex1 image, " : "",
897 (state
& MACH64_UPLOAD_CLIPRECTS
) ? "cliprects, " : "" );
901 * Load the current context's state into the hardware.
903 * NOTE: Be VERY careful about ensuring the context state is marked for
904 * upload, the only place it shouldn't be uploaded is when the setup
905 * state has changed in ReducedPrimitiveChange as this comes right after
908 * Blits of any type should always upload the context and masks after
911 void mach64EmitHwStateLocked( mach64ContextPtr mmesa
)
913 drm_mach64_sarea_t
*sarea
= mmesa
->sarea
;
914 drm_mach64_context_regs_t
*regs
= &(mmesa
->setup
);
915 mach64TexObjPtr t0
= mmesa
->CurrentTexObj
[0];
916 mach64TexObjPtr t1
= mmesa
->CurrentTexObj
[1];
918 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
919 mach64DDPrintDirty( __FUNCTION__
, mmesa
->dirty
);
922 if ( t0
&& t1
&& mmesa
->mach64Screen
->numTexHeaps
> 1 ) {
923 if (t0
->heap
!= t1
->heap
||
924 (mmesa
->dirty
& MACH64_UPLOAD_TEX0IMAGE
) ||
925 (mmesa
->dirty
& MACH64_UPLOAD_TEX1IMAGE
))
926 mach64UploadMultiTexImages( mmesa
, t0
, t1
);
928 if ( mmesa
->dirty
& MACH64_UPLOAD_TEX0IMAGE
) {
929 if ( t0
) mach64UploadTexImages( mmesa
, t0
);
931 if ( mmesa
->dirty
& MACH64_UPLOAD_TEX1IMAGE
) {
932 if ( t1
) mach64UploadTexImages( mmesa
, t1
);
936 if ( mmesa
->dirty
& (MACH64_UPLOAD_CONTEXT
| MACH64_UPLOAD_MISC
) ) {
937 memcpy( &sarea
->context_state
, regs
,
938 MACH64_NR_CONTEXT_REGS
* sizeof(GLuint
) );
941 if ( mmesa
->dirty
& MACH64_UPLOAD_TEXTURE
) {
942 mach64EmitTexStateLocked( mmesa
, t0
, t1
);
945 sarea
->vertsize
= mmesa
->vertex_size
;
947 /* Turn off the texture cache flushing.
949 mmesa
->setup
.tex_cntl
&= ~MACH64_TEX_CACHE_FLUSH
;
951 sarea
->dirty
|= mmesa
->dirty
;
953 mmesa
->dirty
&= MACH64_UPLOAD_CLIPRECTS
;
956 static void mach64DDPrintState( const char *msg
, GLuint flags
)
959 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
962 (flags
& MACH64_NEW_CONTEXT
) ? "context, " : "",
963 (flags
& MACH64_NEW_ALPHA
) ? "alpha, " : "",
964 (flags
& MACH64_NEW_DEPTH
) ? "depth, " : "",
965 (flags
& MACH64_NEW_FOG
) ? "fog, " : "",
966 (flags
& MACH64_NEW_CLIP
) ? "clip, " : "",
967 (flags
& MACH64_NEW_TEXTURE
) ? "texture, " : "",
968 (flags
& MACH64_NEW_CULL
) ? "cull, " : "",
969 (flags
& MACH64_NEW_MASKS
) ? "masks, " : "",
970 (flags
& MACH64_NEW_WINDOW
) ? "window, " : "" );
973 /* Update the hardware state */
974 void mach64DDUpdateHWState( GLcontext
*ctx
)
976 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
977 int new_state
= mmesa
->new_state
;
979 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
980 fprintf( stderr
, "%s:\n", __FUNCTION__
);
985 FLUSH_BATCH( mmesa
);
987 mmesa
->new_state
= 0;
989 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
990 mach64DDPrintState( __FUNCTION__
, new_state
);
992 /* Update the various parts of the context's state.
994 if ( new_state
& MACH64_NEW_ALPHA
)
995 mach64UpdateAlphaMode( ctx
);
997 if ( new_state
& MACH64_NEW_DEPTH
)
998 mach64UpdateZMode( ctx
);
1000 if ( new_state
& MACH64_NEW_FOG
)
1001 mach64UpdateFogAttrib( ctx
);
1003 if ( new_state
& MACH64_NEW_CLIP
)
1004 mach64UpdateClipping( ctx
);
1006 if ( new_state
& MACH64_NEW_WINDOW
)
1007 mach64CalcViewport( ctx
);
1009 if ( new_state
& MACH64_NEW_CULL
)
1010 mach64UpdateCull( ctx
);
1012 if ( new_state
& MACH64_NEW_MASKS
)
1013 mach64UpdateMasks( ctx
);
1015 if ( new_state
& MACH64_NEW_TEXTURE
)
1016 mach64UpdateTextureState( ctx
);
1021 static void mach64DDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1023 _swrast_InvalidateState( ctx
, new_state
);
1024 _swsetup_InvalidateState( ctx
, new_state
);
1025 _vbo_InvalidateState( ctx
, new_state
);
1026 _tnl_InvalidateState( ctx
, new_state
);
1027 MACH64_CONTEXT(ctx
)->NewGLState
|= new_state
;
1031 /* Initialize the context's hardware state */
1032 void mach64DDInitState( mach64ContextPtr mmesa
)
1036 switch ( mmesa
->mach64Screen
->cpp
) {
1038 format
= MACH64_DATATYPE_RGB565
;
1041 format
= MACH64_DATATYPE_ARGB8888
;
1044 fprintf( stderr
, "Error: Unsupported pixel depth... exiting\n" );
1048 /* Always have a 16-bit depth buffer
1049 * but Z coordinates are specified in 16.1 format to the setup engine.
1051 mmesa
->depth_scale
= 2.0;
1053 mmesa
->ClearColor
= 0x00000000;
1054 mmesa
->ClearDepth
= 0x0000ffff;
1056 mmesa
->Fallback
= 0;
1058 if ( mmesa
->glCtx
->Visual
.doubleBufferMode
) {
1059 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->backOffset
;
1060 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->backPitch
;
1062 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->frontOffset
;
1063 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->frontPitch
;
1068 mmesa
->setup
.dst_off_pitch
= (((mmesa
->drawPitch
/8) << 22) |
1069 (mmesa
->drawOffset
>> 3));
1071 mmesa
->setup
.z_off_pitch
= (((mmesa
->mach64Screen
->depthPitch
/8) << 22) |
1072 (mmesa
->mach64Screen
->depthOffset
>> 3));
1074 mmesa
->setup
.z_cntl
= (MACH64_Z_TEST_LESS
|
1077 mmesa
->setup
.alpha_tst_cntl
= (MACH64_ALPHA_TEST_ALWAYS
|
1078 MACH64_ALPHA_DST_SRCALPHA
|
1079 MACH64_ALPHA_TST_SRC_TEXEL
|
1080 (0 << MACH64_REF_ALPHA_SHIFT
));
1082 mmesa
->setup
.scale_3d_cntl
= (MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE
|
1083 /* MACH64_SCALE_DITHER_ERROR_DIFFUSE | */
1084 MACH64_SCALE_DITHER_2D_TABLE
|
1085 /* MACH64_DITHER_INIT_CURRENT | */
1086 MACH64_DITHER_INIT_RESET
|
1087 MACH64_SCALE_3D_FCN_SHADE
|
1088 MACH64_ALPHA_FOG_DIS
|
1089 MACH64_ALPHA_BLEND_SRC_ONE
|
1090 MACH64_ALPHA_BLEND_DST_ZERO
|
1091 MACH64_TEX_LIGHT_FCN_MODULATE
|
1092 MACH64_MIP_MAP_DISABLE
|
1093 MACH64_BILINEAR_TEX_EN
|
1094 MACH64_TEX_BLEND_FCN_LINEAR
);
1096 /* GL spec says dithering initially enabled, but dithering causes
1097 * problems w/ 24bpp depth
1099 if ( mmesa
->mach64Screen
->cpp
== 4 )
1100 mmesa
->setup
.scale_3d_cntl
|= MACH64_ROUND_EN
;
1102 mmesa
->setup
.scale_3d_cntl
|= MACH64_DITHER_EN
;
1104 mmesa
->setup
.sc_left_right
= 0x1fff0000;
1105 mmesa
->setup
.sc_top_bottom
= 0x3fff0000;
1107 mmesa
->setup
.dp_fog_clr
= 0x00ffffff;
1108 mmesa
->setup
.dp_write_mask
= 0xffffffff;
1110 mmesa
->setup
.dp_pix_width
= ((format
<< 0) |
1116 mmesa
->setup
.dp_mix
= (MACH64_BKGD_MIX_S
|
1118 mmesa
->setup
.dp_src
= (MACH64_BKGD_SRC_3D
|
1119 MACH64_FRGD_SRC_3D
|
1120 MACH64_MONO_SRC_ONE
);
1122 mmesa
->setup
.clr_cmp_cntl
= 0x00000000;
1123 mmesa
->setup
.gui_traj_cntl
= (MACH64_DST_X_LEFT_TO_RIGHT
|
1124 MACH64_DST_Y_TOP_TO_BOTTOM
);
1126 mmesa
->setup
.setup_cntl
= (MACH64_FLAT_SHADE_OFF
|
1127 MACH64_SOLID_MODE_OFF
|
1128 MACH64_LOG_MAX_INC_ADJ
);
1129 mmesa
->setup
.setup_cntl
= 0;
1131 mmesa
->setup
.tex_size_pitch
= 0x00000000;
1133 mmesa
->setup
.tex_cntl
= ((0 << MACH64_LOD_BIAS_SHIFT
) |
1134 (0 << MACH64_COMP_FACTOR_SHIFT
) |
1135 MACH64_COMP_COMBINE_MODULATE
|
1136 MACH64_COMP_BLEND_NEAREST
|
1137 MACH64_COMP_FILTER_NEAREST
|
1138 /* MACH64_TEXTURE_TILING | */
1139 #ifdef MACH64_PREMULT_TEXCOORDS
1140 MACH64_TEX_ST_DIRECT
|
1142 MACH64_TEX_SRC_LOCAL
|
1143 MACH64_TEX_UNCOMPRESSED
|
1144 MACH64_TEX_CACHE_FLUSH
|
1145 MACH64_TEX_CACHE_SIZE_4K
);
1147 mmesa
->setup
.secondary_tex_off
= 0x00000000;
1148 mmesa
->setup
.tex_offset
= 0x00000000;
1150 mmesa
->new_state
= MACH64_NEW_ALL
;
1153 /* Initialize the driver's state functions.
1155 void mach64DDInitStateFuncs( GLcontext
*ctx
)
1157 ctx
->Driver
.UpdateState
= mach64DDInvalidateState
;
1159 ctx
->Driver
.ClearColor
= mach64DDClearColor
;
1160 ctx
->Driver
.DrawBuffer
= mach64DDDrawBuffer
;
1161 ctx
->Driver
.ReadBuffer
= mach64DDReadBuffer
;
1163 ctx
->Driver
.ColorMask
= mach64DDColorMask
;
1164 ctx
->Driver
.AlphaFunc
= mach64DDAlphaFunc
;
1165 ctx
->Driver
.BlendEquationSeparate
= mach64DDBlendEquationSeparate
;
1166 ctx
->Driver
.BlendFuncSeparate
= mach64DDBlendFuncSeparate
;
1167 ctx
->Driver
.ClearDepth
= mach64DDClearDepth
;
1168 ctx
->Driver
.CullFace
= mach64DDCullFace
;
1169 ctx
->Driver
.FrontFace
= mach64DDFrontFace
;
1170 ctx
->Driver
.DepthFunc
= mach64DDDepthFunc
;
1171 ctx
->Driver
.DepthMask
= mach64DDDepthMask
;
1172 ctx
->Driver
.Enable
= mach64DDEnable
;
1173 ctx
->Driver
.Fogfv
= mach64DDFogfv
;
1174 ctx
->Driver
.Hint
= NULL
;
1175 ctx
->Driver
.Lightfv
= NULL
;
1176 ctx
->Driver
.LightModelfv
= mach64DDLightModelfv
;
1177 ctx
->Driver
.LogicOpcode
= mach64DDLogicOpCode
;
1178 ctx
->Driver
.PolygonMode
= NULL
;
1179 ctx
->Driver
.PolygonStipple
= NULL
;
1180 ctx
->Driver
.RenderMode
= mach64DDRenderMode
;
1181 ctx
->Driver
.Scissor
= mach64DDScissor
;
1182 ctx
->Driver
.ShadeModel
= mach64DDShadeModel
;
1184 ctx
->Driver
.DepthRange
= mach64DepthRange
;
1185 ctx
->Driver
.Viewport
= mach64Viewport
;