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/context.h"
40 #include "main/enums.h"
41 #include "main/colormac.h"
42 #include "swrast/swrast.h"
45 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/t_pipeline.h"
50 /* =============================================================
54 static void mach64UpdateAlphaMode( GLcontext
*ctx
)
56 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
57 GLuint a
= mmesa
->setup
.alpha_tst_cntl
;
58 GLuint s
= mmesa
->setup
.scale_3d_cntl
;
59 GLuint m
= mmesa
->setup
.dp_write_mask
;
61 if ( ctx
->Color
.AlphaEnabled
) {
64 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
66 a
&= ~(MACH64_ALPHA_TEST_MASK
| MACH64_REF_ALPHA_MASK
);
68 switch ( ctx
->Color
.AlphaFunc
) {
70 a
|= MACH64_ALPHA_TEST_NEVER
;
73 a
|= MACH64_ALPHA_TEST_LESS
;
76 a
|= MACH64_ALPHA_TEST_LEQUAL
;
79 a
|= MACH64_ALPHA_TEST_EQUAL
;
82 a
|= MACH64_ALPHA_TEST_GEQUAL
;
85 a
|= MACH64_ALPHA_TEST_GREATER
;
88 a
|= MACH64_ALPHA_TEST_NOTEQUAL
;
91 a
|= MACH64_ALPHA_TEST_ALWAYS
;
95 a
|= (ref
<< MACH64_REF_ALPHA_SHIFT
);
96 a
|= MACH64_ALPHA_TEST_EN
;
98 a
&= ~MACH64_ALPHA_TEST_EN
;
101 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_FALSE
);
103 if ( ctx
->Color
.BlendEnabled
) {
104 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
105 MACH64_ALPHA_BLEND_DST_MASK
|
106 MACH64_ALPHA_BLEND_SAT
);
108 switch ( ctx
->Color
.BlendSrcRGB
) {
110 s
|= MACH64_ALPHA_BLEND_SRC_ZERO
;
113 s
|= MACH64_ALPHA_BLEND_SRC_ONE
;
116 s
|= MACH64_ALPHA_BLEND_SRC_DSTCOLOR
;
118 case GL_ONE_MINUS_DST_COLOR
:
119 s
|= MACH64_ALPHA_BLEND_SRC_INVDSTCOLOR
;
122 s
|= MACH64_ALPHA_BLEND_SRC_SRCALPHA
;
124 case GL_ONE_MINUS_SRC_ALPHA
:
125 s
|= MACH64_ALPHA_BLEND_SRC_INVSRCALPHA
;
128 s
|= MACH64_ALPHA_BLEND_SRC_DSTALPHA
;
130 case GL_ONE_MINUS_DST_ALPHA
:
131 s
|= MACH64_ALPHA_BLEND_SRC_INVDSTALPHA
;
133 case GL_SRC_ALPHA_SATURATE
:
134 s
|= (MACH64_ALPHA_BLEND_SRC_SRCALPHA
|
135 MACH64_ALPHA_BLEND_SAT
);
138 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_TRUE
);
141 switch ( ctx
->Color
.BlendDstRGB
) {
143 s
|= MACH64_ALPHA_BLEND_DST_ZERO
;
146 s
|= MACH64_ALPHA_BLEND_DST_ONE
;
149 s
|= MACH64_ALPHA_BLEND_DST_SRCCOLOR
;
151 case GL_ONE_MINUS_SRC_COLOR
:
152 s
|= MACH64_ALPHA_BLEND_DST_INVSRCCOLOR
;
155 s
|= MACH64_ALPHA_BLEND_DST_SRCALPHA
;
157 case GL_ONE_MINUS_SRC_ALPHA
:
158 s
|= MACH64_ALPHA_BLEND_DST_INVSRCALPHA
;
161 s
|= MACH64_ALPHA_BLEND_DST_DSTALPHA
;
163 case GL_ONE_MINUS_DST_ALPHA
:
164 s
|= MACH64_ALPHA_BLEND_DST_INVDSTALPHA
;
167 FALLBACK( mmesa
, MACH64_FALLBACK_BLEND_FUNC
, GL_TRUE
);
170 m
= 0xffffffff; /* Can't color mask and blend at the same time */
171 s
&= ~MACH64_ALPHA_FOG_EN_FOG
; /* Can't fog and blend at the same time */
172 s
|= MACH64_ALPHA_FOG_EN_ALPHA
;
174 s
&= ~MACH64_ALPHA_FOG_EN_ALPHA
;
177 if ( mmesa
->setup
.alpha_tst_cntl
!= a
) {
178 mmesa
->setup
.alpha_tst_cntl
= a
;
179 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
181 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
182 mmesa
->setup
.scale_3d_cntl
= s
;
183 mmesa
->dirty
|= MACH64_UPLOAD_SCALE_3D_CNTL
;
185 if ( mmesa
->setup
.dp_write_mask
!= m
) {
186 mmesa
->setup
.dp_write_mask
= m
;
187 mmesa
->dirty
|= MACH64_UPLOAD_DP_WRITE_MASK
;
191 static void mach64DDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
193 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
195 FLUSH_BATCH( mmesa
);
196 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
199 static void mach64DDBlendEquationSeparate( GLcontext
*ctx
,
200 GLenum modeRGB
, GLenum modeA
)
202 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
204 assert( modeRGB
== modeA
);
205 FLUSH_BATCH( mmesa
);
207 /* BlendEquation affects ColorLogicOpEnabled
209 FALLBACK( MACH64_CONTEXT(ctx
), MACH64_FALLBACK_LOGICOP
,
210 (ctx
->Color
.ColorLogicOpEnabled
&&
211 ctx
->Color
.LogicOp
!= GL_COPY
));
213 /* Can only do blend addition, not min, max, subtract, etc. */
214 FALLBACK( MACH64_CONTEXT(ctx
), MACH64_FALLBACK_BLEND_EQ
,
215 modeRGB
!= GL_FUNC_ADD
);
217 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
220 static void mach64DDBlendFuncSeparate( GLcontext
*ctx
,
221 GLenum sfactorRGB
, GLenum dfactorRGB
,
222 GLenum sfactorA
, GLenum dfactorA
)
224 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
226 FLUSH_BATCH( mmesa
);
227 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
231 /* =============================================================
235 static void mach64UpdateZMode( GLcontext
*ctx
)
237 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
238 GLuint z
= mmesa
->setup
.z_cntl
;
240 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
241 fprintf( stderr
, "%s:\n", __FUNCTION__
);
244 if ( ctx
->Depth
.Test
) {
245 z
&= ~MACH64_Z_TEST_MASK
;
247 switch ( ctx
->Depth
.Func
) {
249 z
|= MACH64_Z_TEST_NEVER
;
252 z
|= MACH64_Z_TEST_ALWAYS
;
255 z
|= MACH64_Z_TEST_LESS
;
258 z
|= MACH64_Z_TEST_LEQUAL
;
261 z
|= MACH64_Z_TEST_EQUAL
;
264 z
|= MACH64_Z_TEST_GEQUAL
;
267 z
|= MACH64_Z_TEST_GREATER
;
270 z
|= MACH64_Z_TEST_NOTEQUAL
;
279 if ( ctx
->Depth
.Mask
) {
280 z
|= MACH64_Z_MASK_EN
;
282 z
&= ~MACH64_Z_MASK_EN
;
285 if ( mmesa
->setup
.z_cntl
!= z
) {
286 mmesa
->setup
.z_cntl
= z
;
287 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
291 static void mach64DDDepthFunc( GLcontext
*ctx
, GLenum func
)
293 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
295 FLUSH_BATCH( mmesa
);
296 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
299 static void mach64DDDepthMask( GLcontext
*ctx
, GLboolean flag
)
301 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
303 FLUSH_BATCH( mmesa
);
304 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
307 static void mach64DDClearDepth( GLcontext
*ctx
, GLclampd d
)
309 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
311 /* Always have a 16-bit depth buffer.
313 mmesa
->ClearDepth
= d
* 0xffff;
317 /* =============================================================
321 static void mach64UpdateFogAttrib( GLcontext
*ctx
)
323 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
325 CARD32 s
= mmesa
->setup
.scale_3d_cntl
;
329 /* Can't fog if blending is on */
330 if ( ctx
->Color
.BlendEnabled
)
333 if ( ctx
->Fog
.Enabled
) {
334 s
|= MACH64_ALPHA_FOG_EN_FOG
;
335 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
336 MACH64_ALPHA_BLEND_DST_MASK
|
337 MACH64_ALPHA_BLEND_SAT
);
338 /* From Utah-glx: "fog color is now dest and fog factor is alpha, so
339 * use GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA"
341 s
|= (MACH64_ALPHA_BLEND_SRC_SRCALPHA
|
342 MACH64_ALPHA_BLEND_DST_INVSRCALPHA
);
343 /* From Utah-glx: "can't use texture alpha when fogging" */
344 s
&= ~MACH64_TEX_MAP_AEN
;
346 s
&= ~(MACH64_ALPHA_BLEND_SRC_MASK
|
347 MACH64_ALPHA_BLEND_DST_MASK
|
348 MACH64_ALPHA_BLEND_SAT
);
349 s
|= (MACH64_ALPHA_BLEND_SRC_ONE
|
350 MACH64_ALPHA_BLEND_DST_ZERO
);
351 s
&= ~MACH64_ALPHA_FOG_EN_FOG
;
354 c
[0] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] );
355 c
[1] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] );
356 c
[2] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
357 c
[3] = FLOAT_TO_UBYTE( ctx
->Fog
.Color
[3] );
359 col
= mach64PackColor( 4, c
[0], c
[1], c
[2], c
[3] );
361 if ( mmesa
->setup
.dp_fog_clr
!= col
) {
362 mmesa
->setup
.dp_fog_clr
= col
;
363 mmesa
->dirty
|= MACH64_UPLOAD_DP_FOG_CLR
;
365 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
366 mmesa
->setup
.scale_3d_cntl
= s
;
367 mmesa
->dirty
|= MACH64_UPLOAD_SCALE_3D_CNTL
;
372 static void mach64DDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
374 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
376 FLUSH_BATCH( mmesa
);
377 mmesa
->new_state
|= MACH64_NEW_FOG
;
381 /* =============================================================
385 static void mach64UpdateClipping( GLcontext
*ctx
)
387 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
388 mach64ScreenPtr mach64Screen
= mmesa
->mach64Screen
;
390 if ( mmesa
->driDrawable
) {
391 __DRIdrawablePrivate
*drawable
= mmesa
->driDrawable
;
394 int x2
= drawable
->w
- 1;
395 int y2
= drawable
->h
- 1;
397 if ( ctx
->Scissor
.Enabled
) {
398 if ( ctx
->Scissor
.X
> x1
) {
401 if ( drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
> y1
) {
402 y1
= drawable
->h
- ctx
->Scissor
.Y
- ctx
->Scissor
.Height
;
404 if ( ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
) {
405 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
407 if ( drawable
->h
- ctx
->Scissor
.Y
- 1 < y2
) {
408 y2
= drawable
->h
- ctx
->Scissor
.Y
- 1;
417 /* clamp to screen borders */
422 if (x2
> mach64Screen
->width
-1) x2
= mach64Screen
->width
-1;
423 if (y2
> mach64Screen
->height
-1) y2
= mach64Screen
->height
-1;
425 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
426 fprintf( stderr
, "%s: drawable %3d %3d %3d %3d\n",
432 fprintf( stderr
, "%s: scissor %3d %3d %3d %3d\n",
437 ctx
->Scissor
.Height
);
438 fprintf( stderr
, "%s: final %3d %3d %3d %3d\n",
439 __FUNCTION__
, x1
, y1
, x2
, y2
);
440 fprintf( stderr
, "\n" );
443 mmesa
->setup
.sc_top_bottom
= ((y1
<< 0) |
446 mmesa
->setup
.sc_left_right
= ((x1
<< 0) |
449 /* UPLOAD_MISC reduces the dirty state, we just need to
450 * emit the scissor to the SAREA. We need to dirty cliprects
451 * since the scissor and cliprects are intersected to update the
452 * single hardware scissor
454 mmesa
->dirty
|= MACH64_UPLOAD_MISC
| MACH64_UPLOAD_CLIPRECTS
;
458 static void mach64DDScissor( GLcontext
*ctx
,
459 GLint x
, GLint y
, GLsizei w
, GLsizei h
)
461 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
463 FLUSH_BATCH( mmesa
);
464 mmesa
->new_state
|= MACH64_NEW_CLIP
;
468 /* =============================================================
472 static void mach64UpdateCull( GLcontext
*ctx
)
474 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
475 GLfloat backface_sign
= 1;
477 if ( ctx
->Polygon
.CullFlag
/*&& ctx->PB->primitive == GL_POLYGON*/ ) {
479 switch ( ctx
->Polygon
.CullFaceMode
) {
481 if ( ctx
->Polygon
.FrontFace
== GL_CCW
)
485 if ( ctx
->Polygon
.FrontFace
!= GL_CCW
)
489 case GL_FRONT_AND_BACK
:
497 mmesa
->backface_sign
= backface_sign
;
501 static void mach64DDCullFace( GLcontext
*ctx
, GLenum mode
)
503 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
505 FLUSH_BATCH( mmesa
);
506 mmesa
->new_state
|= MACH64_NEW_CULL
;
509 static void mach64DDFrontFace( GLcontext
*ctx
, GLenum mode
)
511 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
513 FLUSH_BATCH( mmesa
);
514 mmesa
->new_state
|= MACH64_NEW_CULL
;
518 /* =============================================================
522 static void mach64UpdateMasks( GLcontext
*ctx
)
524 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
525 GLuint mask
= 0xffffffff;
527 /* mach64 can't color mask with alpha blending enabled */
528 if ( !ctx
->Color
.BlendEnabled
) {
529 mask
= mach64PackColor( mmesa
->mach64Screen
->cpp
,
530 ctx
->Color
.ColorMask
[RCOMP
],
531 ctx
->Color
.ColorMask
[GCOMP
],
532 ctx
->Color
.ColorMask
[BCOMP
],
533 ctx
->Color
.ColorMask
[ACOMP
] );
536 if ( mmesa
->setup
.dp_write_mask
!= mask
) {
537 mmesa
->setup
.dp_write_mask
= mask
;
538 mmesa
->dirty
|= MACH64_UPLOAD_DP_WRITE_MASK
;
542 static void mach64DDColorMask( GLcontext
*ctx
,
543 GLboolean r
, GLboolean g
,
544 GLboolean b
, GLboolean a
)
546 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
548 FLUSH_BATCH( mmesa
);
549 mmesa
->new_state
|= MACH64_NEW_MASKS
;
553 /* =============================================================
554 * Rendering attributes
556 * We really don't want to recalculate all this every time we bind a
557 * texture. These things shouldn't change all that often, so it makes
558 * sense to break them out of the core texture state update routines.
561 static void mach64UpdateSpecularLighting( GLcontext
*ctx
)
563 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
564 GLuint a
= mmesa
->setup
.alpha_tst_cntl
;
566 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
567 fprintf( stderr
, "%s:\n", __FUNCTION__
);
570 if ( ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
571 ctx
->Light
.Enabled
) {
572 a
|= MACH64_SPECULAR_LIGHT_EN
;
574 a
&= ~MACH64_SPECULAR_LIGHT_EN
;
577 if ( mmesa
->setup
.alpha_tst_cntl
!= a
) {
578 mmesa
->setup
.alpha_tst_cntl
= a
;
579 mmesa
->dirty
|= MACH64_UPLOAD_Z_ALPHA_CNTL
;
580 mmesa
->new_state
|= MACH64_NEW_CONTEXT
;
584 static void mach64DDLightModelfv( GLcontext
*ctx
, GLenum pname
,
585 const GLfloat
*param
)
587 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
589 if ( pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
590 FLUSH_BATCH( mmesa
);
591 mach64UpdateSpecularLighting(ctx
);
595 static void mach64DDShadeModel( GLcontext
*ctx
, GLenum mode
)
597 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
598 GLuint s
= mmesa
->setup
.setup_cntl
;
600 s
&= ~MACH64_FLAT_SHADE_MASK
;
604 s
|= MACH64_FLAT_SHADE_VERTEX_3
;
607 s
|= MACH64_FLAT_SHADE_OFF
;
613 if ( mmesa
->setup
.setup_cntl
!= s
) {
614 FLUSH_BATCH( mmesa
);
615 mmesa
->setup
.setup_cntl
= s
;
617 mmesa
->dirty
|= MACH64_UPLOAD_SETUP_CNTL
;
622 /* =============================================================
627 void mach64CalcViewport( GLcontext
*ctx
)
629 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
630 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
631 GLfloat
*m
= mmesa
->hw_viewport
;
633 /* See also mach64_translate_vertex.
635 m
[MAT_SX
] = v
[MAT_SX
];
636 m
[MAT_TX
] = v
[MAT_TX
] + (GLfloat
)mmesa
->drawX
+ SUBPIXEL_X
;
637 m
[MAT_SY
] = - v
[MAT_SY
];
638 m
[MAT_TY
] = - v
[MAT_TY
] + mmesa
->driDrawable
->h
+ (GLfloat
)mmesa
->drawY
+ SUBPIXEL_Y
;
639 m
[MAT_SZ
] = v
[MAT_SZ
] * mmesa
->depth_scale
;
640 m
[MAT_TZ
] = v
[MAT_TZ
] * mmesa
->depth_scale
;
642 mmesa
->SetupNewInputs
= ~0;
645 static void mach64Viewport( GLcontext
*ctx
,
647 GLsizei width
, GLsizei height
)
649 mach64CalcViewport( ctx
);
652 static void mach64DepthRange( GLcontext
*ctx
,
653 GLclampd nearval
, GLclampd farval
)
655 mach64CalcViewport( ctx
);
659 /* =============================================================
663 static void mach64DDClearColor( GLcontext
*ctx
,
664 const GLfloat color
[4] )
666 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
669 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
670 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
671 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
672 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
674 mmesa
->ClearColor
= mach64PackColor( mmesa
->mach64Screen
->cpp
,
675 c
[0], c
[1], c
[2], c
[3] );
678 static void mach64DDLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
680 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
682 if ( ctx
->Color
.ColorLogicOpEnabled
) {
683 FLUSH_BATCH( mmesa
);
685 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
, opcode
!= GL_COPY
);
689 void mach64SetCliprects( GLcontext
*ctx
, GLenum mode
)
691 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
692 __DRIdrawablePrivate
*dPriv
= mmesa
->driDrawable
;
696 mmesa
->numClipRects
= dPriv
->numClipRects
;
697 mmesa
->pClipRects
= dPriv
->pClipRects
;
698 mmesa
->drawX
= dPriv
->x
;
699 mmesa
->drawY
= dPriv
->y
;
702 if ( dPriv
->numBackClipRects
== 0 ) {
703 mmesa
->numClipRects
= dPriv
->numClipRects
;
704 mmesa
->pClipRects
= dPriv
->pClipRects
;
705 mmesa
->drawX
= dPriv
->x
;
706 mmesa
->drawY
= dPriv
->y
;
708 mmesa
->numClipRects
= dPriv
->numBackClipRects
;
709 mmesa
->pClipRects
= dPriv
->pBackClipRects
;
710 mmesa
->drawX
= dPriv
->backX
;
711 mmesa
->drawY
= dPriv
->backY
;
718 mach64UpdateClipping( ctx
);
720 mmesa
->dirty
|= MACH64_UPLOAD_CLIPRECTS
;
723 static void mach64DDDrawBuffer( GLcontext
*ctx
, GLenum mode
)
725 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
727 FLUSH_BATCH( mmesa
);
729 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
!= 1) {
730 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
731 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
735 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
736 case BUFFER_FRONT_LEFT
:
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: BUFFER_BIT_FRONT_LEFT\n", __FUNCTION__
);
742 case BUFFER_BACK_LEFT
:
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: BUFFER_BIT_BACK_LEFT\n", __FUNCTION__
);
749 FALLBACK( mmesa
, MACH64_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
750 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
751 fprintf(stderr
,"%s: fallback (mode=%d)\n", __FUNCTION__
, mode
);
755 mmesa
->setup
.dst_off_pitch
= (((mmesa
->drawPitch
/8) << 22) |
756 (mmesa
->drawOffset
>> 3));
758 mmesa
->dirty
|= MACH64_UPLOAD_DST_OFF_PITCH
;
761 static void mach64DDReadBuffer( GLcontext
*ctx
, GLenum mode
)
763 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
766 /* =============================================================
767 * State enable/disable
770 static void mach64DDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
772 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
774 if ( MACH64_DEBUG
& DEBUG_VERBOSE_API
) {
775 fprintf( stderr
, "%s( %s = %s )\n",
776 __FUNCTION__
, _mesa_lookup_enum_by_nr( cap
),
777 state
? "GL_TRUE" : "GL_FALSE" );
782 FLUSH_BATCH( mmesa
);
783 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
787 FLUSH_BATCH( mmesa
);
788 mmesa
->new_state
|= MACH64_NEW_ALPHA
;
790 /* enable(GL_BLEND) affects ColorLogicOpEnabled.
792 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
,
793 (ctx
->Color
.ColorLogicOpEnabled
&&
794 ctx
->Color
.LogicOp
!= GL_COPY
));
798 FLUSH_BATCH( mmesa
);
799 mmesa
->new_state
|= MACH64_NEW_CULL
;
803 FLUSH_BATCH( mmesa
);
804 mmesa
->new_state
|= MACH64_NEW_DEPTH
;
809 GLuint s
= mmesa
->setup
.scale_3d_cntl
;
810 FLUSH_BATCH( mmesa
);
812 if ( ctx
->Color
.DitherFlag
) {
813 /* Dithering causes problems w/ 24bpp depth */
814 if ( mmesa
->mach64Screen
->cpp
== 4 )
815 s
|= MACH64_ROUND_EN
;
817 s
|= MACH64_DITHER_EN
;
819 s
&= ~MACH64_DITHER_EN
;
820 s
&= ~MACH64_ROUND_EN
;
823 if ( mmesa
->setup
.scale_3d_cntl
!= s
) {
824 mmesa
->setup
.scale_3d_cntl
= s
;
825 mmesa
->dirty
|= ( MACH64_UPLOAD_SCALE_3D_CNTL
);
831 FLUSH_BATCH( mmesa
);
832 mmesa
->new_state
|= MACH64_NEW_FOG
;
835 case GL_INDEX_LOGIC_OP
:
836 case GL_COLOR_LOGIC_OP
:
837 FLUSH_BATCH( mmesa
);
838 FALLBACK( mmesa
, MACH64_FALLBACK_LOGICOP
,
839 state
&& ctx
->Color
.LogicOp
!= GL_COPY
);
843 mach64UpdateSpecularLighting(ctx
);
846 case GL_SCISSOR_TEST
:
847 FLUSH_BATCH( mmesa
);
848 mmesa
->scissor
= state
;
849 mmesa
->new_state
|= MACH64_NEW_CLIP
;
852 case GL_STENCIL_TEST
:
853 FLUSH_BATCH( mmesa
);
854 FALLBACK( mmesa
, MACH64_FALLBACK_STENCIL
, state
);
860 FLUSH_BATCH( mmesa
);
861 mmesa
->new_state
|= MACH64_NEW_TEXTURE
;
869 /* =============================================================
873 static void mach64DDRenderMode( GLcontext
*ctx
, GLenum mode
)
875 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
876 FALLBACK( mmesa
, MACH64_FALLBACK_RENDER_MODE
, (mode
!= GL_RENDER
) );
879 /* =============================================================
880 * State initialization, management
883 static void mach64DDPrintDirty( const char *msg
, GLuint state
)
886 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s\n",
889 (state
& MACH64_UPLOAD_DST_OFF_PITCH
) ? "dst_off_pitch, " : "",
890 (state
& MACH64_UPLOAD_Z_ALPHA_CNTL
) ? "z_alpha_cntl, " : "",
891 (state
& MACH64_UPLOAD_SCALE_3D_CNTL
) ? "scale_3d_cntl, " : "",
892 (state
& MACH64_UPLOAD_DP_FOG_CLR
) ? "dp_fog_clr, " : "",
893 (state
& MACH64_UPLOAD_DP_WRITE_MASK
) ? "dp_write_mask, " : "",
894 (state
& MACH64_UPLOAD_DP_PIX_WIDTH
) ? "dp_pix_width, " : "",
895 (state
& MACH64_UPLOAD_SETUP_CNTL
) ? "setup_cntl, " : "",
896 (state
& MACH64_UPLOAD_MISC
) ? "misc, " : "",
897 (state
& MACH64_UPLOAD_TEXTURE
) ? "texture, " : "",
898 (state
& MACH64_UPLOAD_TEX0IMAGE
) ? "tex0 image, " : "",
899 (state
& MACH64_UPLOAD_TEX1IMAGE
) ? "tex1 image, " : "",
900 (state
& MACH64_UPLOAD_CLIPRECTS
) ? "cliprects, " : "" );
904 * Load the current context's state into the hardware.
906 * NOTE: Be VERY careful about ensuring the context state is marked for
907 * upload, the only place it shouldn't be uploaded is when the setup
908 * state has changed in ReducedPrimitiveChange as this comes right after
911 * Blits of any type should always upload the context and masks after
914 void mach64EmitHwStateLocked( mach64ContextPtr mmesa
)
916 drm_mach64_sarea_t
*sarea
= mmesa
->sarea
;
917 drm_mach64_context_regs_t
*regs
= &(mmesa
->setup
);
918 mach64TexObjPtr t0
= mmesa
->CurrentTexObj
[0];
919 mach64TexObjPtr t1
= mmesa
->CurrentTexObj
[1];
921 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
922 mach64DDPrintDirty( __FUNCTION__
, mmesa
->dirty
);
925 if ( t0
&& t1
&& mmesa
->mach64Screen
->numTexHeaps
> 1 ) {
926 if (t0
->heap
!= t1
->heap
||
927 (mmesa
->dirty
& MACH64_UPLOAD_TEX0IMAGE
) ||
928 (mmesa
->dirty
& MACH64_UPLOAD_TEX1IMAGE
))
929 mach64UploadMultiTexImages( mmesa
, t0
, t1
);
931 if ( mmesa
->dirty
& MACH64_UPLOAD_TEX0IMAGE
) {
932 if ( t0
) mach64UploadTexImages( mmesa
, t0
);
934 if ( mmesa
->dirty
& MACH64_UPLOAD_TEX1IMAGE
) {
935 if ( t1
) mach64UploadTexImages( mmesa
, t1
);
939 if ( mmesa
->dirty
& (MACH64_UPLOAD_CONTEXT
| MACH64_UPLOAD_MISC
) ) {
940 memcpy( &sarea
->context_state
, regs
,
941 MACH64_NR_CONTEXT_REGS
* sizeof(GLuint
) );
944 if ( mmesa
->dirty
& MACH64_UPLOAD_TEXTURE
) {
945 mach64EmitTexStateLocked( mmesa
, t0
, t1
);
948 sarea
->vertsize
= mmesa
->vertex_size
;
950 /* Turn off the texture cache flushing.
952 mmesa
->setup
.tex_cntl
&= ~MACH64_TEX_CACHE_FLUSH
;
954 sarea
->dirty
|= mmesa
->dirty
;
956 mmesa
->dirty
&= MACH64_UPLOAD_CLIPRECTS
;
959 static void mach64DDPrintState( const char *msg
, GLuint flags
)
962 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
965 (flags
& MACH64_NEW_CONTEXT
) ? "context, " : "",
966 (flags
& MACH64_NEW_ALPHA
) ? "alpha, " : "",
967 (flags
& MACH64_NEW_DEPTH
) ? "depth, " : "",
968 (flags
& MACH64_NEW_FOG
) ? "fog, " : "",
969 (flags
& MACH64_NEW_CLIP
) ? "clip, " : "",
970 (flags
& MACH64_NEW_TEXTURE
) ? "texture, " : "",
971 (flags
& MACH64_NEW_CULL
) ? "cull, " : "",
972 (flags
& MACH64_NEW_MASKS
) ? "masks, " : "",
973 (flags
& MACH64_NEW_WINDOW
) ? "window, " : "" );
976 /* Update the hardware state */
977 void mach64DDUpdateHWState( GLcontext
*ctx
)
979 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
980 int new_state
= mmesa
->new_state
;
982 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
) {
983 fprintf( stderr
, "%s:\n", __FUNCTION__
);
988 FLUSH_BATCH( mmesa
);
990 mmesa
->new_state
= 0;
992 if ( MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
993 mach64DDPrintState( __FUNCTION__
, new_state
);
995 /* Update the various parts of the context's state.
997 if ( new_state
& MACH64_NEW_ALPHA
)
998 mach64UpdateAlphaMode( ctx
);
1000 if ( new_state
& MACH64_NEW_DEPTH
)
1001 mach64UpdateZMode( ctx
);
1003 if ( new_state
& MACH64_NEW_FOG
)
1004 mach64UpdateFogAttrib( ctx
);
1006 if ( new_state
& MACH64_NEW_CLIP
)
1007 mach64UpdateClipping( ctx
);
1009 if ( new_state
& MACH64_NEW_WINDOW
)
1010 mach64CalcViewport( ctx
);
1012 if ( new_state
& MACH64_NEW_CULL
)
1013 mach64UpdateCull( ctx
);
1015 if ( new_state
& MACH64_NEW_MASKS
)
1016 mach64UpdateMasks( ctx
);
1018 if ( new_state
& MACH64_NEW_TEXTURE
)
1019 mach64UpdateTextureState( ctx
);
1024 static void mach64DDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1026 _swrast_InvalidateState( ctx
, new_state
);
1027 _swsetup_InvalidateState( ctx
, new_state
);
1028 _vbo_InvalidateState( ctx
, new_state
);
1029 _tnl_InvalidateState( ctx
, new_state
);
1030 MACH64_CONTEXT(ctx
)->NewGLState
|= new_state
;
1034 /* Initialize the context's hardware state */
1035 void mach64DDInitState( mach64ContextPtr mmesa
)
1039 switch ( mmesa
->mach64Screen
->cpp
) {
1041 format
= MACH64_DATATYPE_RGB565
;
1044 format
= MACH64_DATATYPE_ARGB8888
;
1047 fprintf( stderr
, "Error: Unsupported pixel depth... exiting\n" );
1051 /* Always have a 16-bit depth buffer
1052 * but Z coordinates are specified in 16.1 format to the setup engine.
1054 mmesa
->depth_scale
= 2.0;
1056 mmesa
->ClearColor
= 0x00000000;
1057 mmesa
->ClearDepth
= 0x0000ffff;
1059 mmesa
->Fallback
= 0;
1061 if ( mmesa
->glCtx
->Visual
.doubleBufferMode
) {
1062 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->backOffset
;
1063 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->backPitch
;
1065 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->frontOffset
;
1066 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->frontPitch
;
1071 mmesa
->setup
.dst_off_pitch
= (((mmesa
->drawPitch
/8) << 22) |
1072 (mmesa
->drawOffset
>> 3));
1074 mmesa
->setup
.z_off_pitch
= (((mmesa
->mach64Screen
->depthPitch
/8) << 22) |
1075 (mmesa
->mach64Screen
->depthOffset
>> 3));
1077 mmesa
->setup
.z_cntl
= (MACH64_Z_TEST_LESS
|
1080 mmesa
->setup
.alpha_tst_cntl
= (MACH64_ALPHA_TEST_ALWAYS
|
1081 MACH64_ALPHA_DST_SRCALPHA
|
1082 MACH64_ALPHA_TST_SRC_TEXEL
|
1083 (0 << MACH64_REF_ALPHA_SHIFT
));
1085 mmesa
->setup
.scale_3d_cntl
= (MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE
|
1086 /* MACH64_SCALE_DITHER_ERROR_DIFFUSE | */
1087 MACH64_SCALE_DITHER_2D_TABLE
|
1088 /* MACH64_DITHER_INIT_CURRENT | */
1089 MACH64_DITHER_INIT_RESET
|
1090 MACH64_SCALE_3D_FCN_SHADE
|
1091 MACH64_ALPHA_FOG_DIS
|
1092 MACH64_ALPHA_BLEND_SRC_ONE
|
1093 MACH64_ALPHA_BLEND_DST_ZERO
|
1094 MACH64_TEX_LIGHT_FCN_MODULATE
|
1095 MACH64_MIP_MAP_DISABLE
|
1096 MACH64_BILINEAR_TEX_EN
|
1097 MACH64_TEX_BLEND_FCN_LINEAR
);
1099 /* GL spec says dithering initially enabled, but dithering causes
1100 * problems w/ 24bpp depth
1102 if ( mmesa
->mach64Screen
->cpp
== 4 )
1103 mmesa
->setup
.scale_3d_cntl
|= MACH64_ROUND_EN
;
1105 mmesa
->setup
.scale_3d_cntl
|= MACH64_DITHER_EN
;
1107 mmesa
->setup
.sc_left_right
= 0x1fff0000;
1108 mmesa
->setup
.sc_top_bottom
= 0x3fff0000;
1110 mmesa
->setup
.dp_fog_clr
= 0x00ffffff;
1111 mmesa
->setup
.dp_write_mask
= 0xffffffff;
1113 mmesa
->setup
.dp_pix_width
= ((format
<< 0) |
1119 mmesa
->setup
.dp_mix
= (MACH64_BKGD_MIX_S
|
1121 mmesa
->setup
.dp_src
= (MACH64_BKGD_SRC_3D
|
1122 MACH64_FRGD_SRC_3D
|
1123 MACH64_MONO_SRC_ONE
);
1125 mmesa
->setup
.clr_cmp_cntl
= 0x00000000;
1126 mmesa
->setup
.gui_traj_cntl
= (MACH64_DST_X_LEFT_TO_RIGHT
|
1127 MACH64_DST_Y_TOP_TO_BOTTOM
);
1129 mmesa
->setup
.setup_cntl
= (MACH64_FLAT_SHADE_OFF
|
1130 MACH64_SOLID_MODE_OFF
|
1131 MACH64_LOG_MAX_INC_ADJ
);
1132 mmesa
->setup
.setup_cntl
= 0;
1134 mmesa
->setup
.tex_size_pitch
= 0x00000000;
1136 mmesa
->setup
.tex_cntl
= ((0 << MACH64_LOD_BIAS_SHIFT
) |
1137 (0 << MACH64_COMP_FACTOR_SHIFT
) |
1138 MACH64_COMP_COMBINE_MODULATE
|
1139 MACH64_COMP_BLEND_NEAREST
|
1140 MACH64_COMP_FILTER_NEAREST
|
1141 /* MACH64_TEXTURE_TILING | */
1142 #ifdef MACH64_PREMULT_TEXCOORDS
1143 MACH64_TEX_ST_DIRECT
|
1145 MACH64_TEX_SRC_LOCAL
|
1146 MACH64_TEX_UNCOMPRESSED
|
1147 MACH64_TEX_CACHE_FLUSH
|
1148 MACH64_TEX_CACHE_SIZE_4K
);
1150 mmesa
->setup
.secondary_tex_off
= 0x00000000;
1151 mmesa
->setup
.tex_offset
= 0x00000000;
1153 mmesa
->new_state
= MACH64_NEW_ALL
;
1156 /* Initialize the driver's state functions.
1158 void mach64DDInitStateFuncs( GLcontext
*ctx
)
1160 ctx
->Driver
.UpdateState
= mach64DDInvalidateState
;
1162 ctx
->Driver
.ClearIndex
= NULL
;
1163 ctx
->Driver
.ClearColor
= mach64DDClearColor
;
1164 ctx
->Driver
.DrawBuffer
= mach64DDDrawBuffer
;
1165 ctx
->Driver
.ReadBuffer
= mach64DDReadBuffer
;
1167 ctx
->Driver
.IndexMask
= NULL
;
1168 ctx
->Driver
.ColorMask
= mach64DDColorMask
;
1169 ctx
->Driver
.AlphaFunc
= mach64DDAlphaFunc
;
1170 ctx
->Driver
.BlendEquationSeparate
= mach64DDBlendEquationSeparate
;
1171 ctx
->Driver
.BlendFuncSeparate
= mach64DDBlendFuncSeparate
;
1172 ctx
->Driver
.ClearDepth
= mach64DDClearDepth
;
1173 ctx
->Driver
.CullFace
= mach64DDCullFace
;
1174 ctx
->Driver
.FrontFace
= mach64DDFrontFace
;
1175 ctx
->Driver
.DepthFunc
= mach64DDDepthFunc
;
1176 ctx
->Driver
.DepthMask
= mach64DDDepthMask
;
1177 ctx
->Driver
.Enable
= mach64DDEnable
;
1178 ctx
->Driver
.Fogfv
= mach64DDFogfv
;
1179 ctx
->Driver
.Hint
= NULL
;
1180 ctx
->Driver
.Lightfv
= NULL
;
1181 ctx
->Driver
.LightModelfv
= mach64DDLightModelfv
;
1182 ctx
->Driver
.LogicOpcode
= mach64DDLogicOpCode
;
1183 ctx
->Driver
.PolygonMode
= NULL
;
1184 ctx
->Driver
.PolygonStipple
= NULL
;
1185 ctx
->Driver
.RenderMode
= mach64DDRenderMode
;
1186 ctx
->Driver
.Scissor
= mach64DDScissor
;
1187 ctx
->Driver
.ShadeModel
= mach64DDShadeModel
;
1189 ctx
->Driver
.DepthRange
= mach64DepthRange
;
1190 ctx
->Driver
.Viewport
= mach64Viewport
;