2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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 * VIA, S3 GRAPHICS, 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 OTHER
22 * DEALINGS IN THE SOFTWARE.
36 #include "savagecontext.h"
38 #include "savagestate.h"
39 #include "savagetex.h"
40 #include "savagetris.h"
41 #include "savageioctl.h"
42 #include "savage_bci.h"
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
47 #include "swrast_setup/swrast_setup.h"
51 /* Savage4, ProSavage[DDR], SuperSavage watermarks */
64 /* Savage3D/MX/IX watermarks */
77 static void savageBlendFunc_s4(GLcontext
*);
78 static void savageBlendFunc_s3d(GLcontext
*);
80 static __inline__ GLuint
savagePackColor(GLuint format
,
86 return SAVAGEPACKCOLOR8888(r
,g
,b
,a
);
88 return SAVAGEPACKCOLOR565(r
,g
,b
);
96 static void savageDDAlphaFunc_s4(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
98 savageBlendFunc_s4(ctx
);
100 static void savageDDAlphaFunc_s3d(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
102 savageBlendFunc_s3d(ctx
);
105 static void savageDDBlendEquationSeparate(GLcontext
*ctx
,
106 GLenum modeRGB
, GLenum modeA
)
108 assert( modeRGB
== modeA
);
110 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
113 FALLBACK( ctx
, SAVAGE_FALLBACK_LOGICOP
,
114 (ctx
->Color
.ColorLogicOpEnabled
&&
115 ctx
->Color
.LogicOp
!= GL_COPY
));
117 /* Can only do blend addition, not min, max, subtract, etc. */
118 FALLBACK( ctx
, SAVAGE_FALLBACK_BLEND_EQ
,
119 modeRGB
!= GL_FUNC_ADD
);
123 static void savageBlendFunc_s4(GLcontext
*ctx
)
125 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
126 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
127 u_int32_t drawCtrl0
= imesa
->regs
.s4
.drawCtrl0
.ui
;
128 u_int32_t drawCtrl1
= imesa
->regs
.s4
.drawCtrl1
.ui
;
130 /* set up draw control register (including blending, alpha
131 * test, and shading model)
134 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_FALSE
;
139 if(ctx
->Color
.BlendEnabled
){
140 switch (ctx
->Color
.BlendDstRGB
)
143 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
147 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
148 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
152 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
153 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
156 case GL_ONE_MINUS_SRC_COLOR
:
157 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
158 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
162 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
163 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
166 case GL_ONE_MINUS_SRC_ALPHA
:
167 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
168 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
172 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
174 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
178 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
180 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
183 case GL_ONE_MINUS_DST_ALPHA
:
184 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
186 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
190 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
=DAM_1DstAlpha
;
191 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
196 switch (ctx
->Color
.BlendSrcRGB
)
199 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
203 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
207 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
208 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
211 case GL_ONE_MINUS_DST_COLOR
:
212 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
213 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
217 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
220 case GL_ONE_MINUS_SRC_ALPHA
:
221 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
225 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
227 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
231 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
232 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
236 case GL_ONE_MINUS_DST_ALPHA
:
237 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
239 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
243 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
=SAM_1DstAlpha
;
244 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
251 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
252 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
257 if(ctx
->Color
.AlphaEnabled
)
262 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
264 switch(ctx
->Color
.AlphaFunc
) {
265 case GL_NEVER
: a
= CF_Never
; break;
266 case GL_ALWAYS
: a
= CF_Always
; break;
267 case GL_LESS
: a
= CF_Less
; break;
268 case GL_LEQUAL
: a
= CF_LessEqual
; break;
269 case GL_EQUAL
: a
= CF_Equal
; break;
270 case GL_GREATER
: a
= CF_Greater
; break;
271 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
272 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
276 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_TRUE
;
277 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestCmpFunc
= a
;
278 imesa
->regs
.s4
.drawCtrl0
.ni
.alphaRefVal
= alphaRef
;
282 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_FALSE
;
285 /* Set/Reset Z-after-alpha*/
287 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
=
288 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
;
289 /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
290 ~drawLocalCtrl.ni.wrZafterAlphaTst;*/
292 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
293 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
294 if (drawCtrl0
!= imesa
->regs
.s4
.drawCtrl0
.ui
||
295 drawCtrl1
!= imesa
->regs
.s4
.drawCtrl1
.ui
)
296 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
298 static void savageBlendFunc_s3d(GLcontext
*ctx
)
300 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
301 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
302 u_int32_t zBufCtrl
= imesa
->regs
.s3d
.zBufCtrl
.ui
;
304 /* set up draw control register (including blending, alpha
305 * test, dithering, and shading model)
308 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= 0;
313 if(ctx
->Color
.BlendEnabled
){
314 switch (ctx
->Color
.BlendDstRGB
)
317 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
321 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
322 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
326 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
327 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
330 case GL_ONE_MINUS_SRC_COLOR
:
331 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
332 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
336 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
337 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
340 case GL_ONE_MINUS_SRC_ALPHA
:
341 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
342 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
346 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
348 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
352 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
354 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
357 case GL_ONE_MINUS_DST_ALPHA
:
358 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
360 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
364 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1DstAlpha
;
365 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
370 switch (ctx
->Color
.BlendSrcRGB
)
373 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
377 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
381 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
382 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
385 case GL_ONE_MINUS_DST_COLOR
:
386 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
387 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
391 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
394 case GL_ONE_MINUS_SRC_ALPHA
:
395 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
399 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
401 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
405 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
406 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
410 case GL_ONE_MINUS_DST_ALPHA
:
411 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
413 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
417 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstAlpha
;
418 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
425 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
426 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
431 if(ctx
->Color
.AlphaEnabled
)
436 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
438 switch(ctx
->Color
.AlphaFunc
) {
439 case GL_NEVER
: a
= CF_Never
; break;
440 case GL_ALWAYS
: a
= CF_Always
; break;
441 case GL_LESS
: a
= CF_Less
; break;
442 case GL_LEQUAL
: a
= CF_LessEqual
; break;
443 case GL_EQUAL
: a
= CF_Equal
; break;
444 case GL_GREATER
: a
= CF_Greater
; break;
445 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
446 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
450 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_TRUE
;
451 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= a
;
452 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaRefVal
= alphaRef
;
456 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_FALSE
;
459 /* Set/Reset Z-after-alpha*/
461 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
=
462 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
;
464 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
||
465 zBufCtrl
!= imesa
->regs
.s3d
.zBufCtrl
.ui
)
466 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
469 static void savageDDBlendFuncSeparate_s4( GLcontext
*ctx
, GLenum sfactorRGB
,
470 GLenum dfactorRGB
, GLenum sfactorA
,
473 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
474 savageBlendFunc_s4( ctx
);
476 static void savageDDBlendFuncSeparate_s3d( GLcontext
*ctx
, GLenum sfactorRGB
,
477 GLenum dfactorRGB
, GLenum sfactorA
,
480 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
481 savageBlendFunc_s3d( ctx
);
486 static void savageDDDepthFunc_s4(GLcontext
*ctx
, GLenum func
)
488 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
490 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
491 u_int32_t zBufCtrl
= imesa
->regs
.s4
.zBufCtrl
.ui
;
492 u_int32_t zWatermarks
= imesa
->regs
.s4
.zWatermarks
.ui
; /* FIXME: in DRM */
494 /* set up z-buffer control register (global)
495 * set up z-buffer offset register (global)
496 * set up z read/write watermarks register (global)
499 switch(func
) { /* reversed (see savageCalcViewport) */
500 case GL_NEVER
: zmode
= CF_Never
; break;
501 case GL_ALWAYS
: zmode
= CF_Always
; break;
502 case GL_LESS
: zmode
= CF_Greater
; break;
503 case GL_LEQUAL
: zmode
= CF_GreaterEqual
; break;
504 case GL_EQUAL
: zmode
= CF_Equal
; break;
505 case GL_GREATER
: zmode
= CF_Less
; break;
506 case GL_GEQUAL
: zmode
= CF_LessEqual
; break;
507 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
513 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
514 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
515 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
516 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
518 else if (imesa
->glCtx
->Stencil
.Enabled
&& imesa
->hw_stencil
)
520 /* Need to keep Z on for Stencil. */
521 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
522 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
523 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
524 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
529 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
== GL_FALSE
)
531 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
532 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
536 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
538 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
540 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
541 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
544 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
545 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
546 if (zBufCtrl
!= imesa
->regs
.s4
.zBufCtrl
.ui
||
547 zWatermarks
!= imesa
->regs
.s4
.zWatermarks
.ui
)
548 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
550 static void savageDDDepthFunc_s3d(GLcontext
*ctx
, GLenum func
)
552 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
554 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
555 u_int32_t zBufCtrl
= imesa
->regs
.s3d
.zBufCtrl
.ui
;
556 u_int32_t zWatermarks
= imesa
->regs
.s3d
.zWatermarks
.ui
; /* FIXME: in DRM */
558 /* set up z-buffer control register (global)
559 * set up z-buffer offset register (global)
560 * set up z read/write watermarks register (global)
562 switch(func
) { /* reversed (see savageCalcViewport) */
563 case GL_NEVER
: zmode
= CF_Never
; break;
564 case GL_ALWAYS
: zmode
= CF_Always
; break;
565 case GL_LESS
: zmode
= CF_Greater
; break;
566 case GL_LEQUAL
: zmode
= CF_GreaterEqual
; break;
567 case GL_EQUAL
: zmode
= CF_Equal
; break;
568 case GL_GREATER
: zmode
= CF_Less
; break;
569 case GL_GEQUAL
: zmode
= CF_LessEqual
; break;
570 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
575 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
576 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
577 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
579 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
583 if (imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
== GL_FALSE
) {
584 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
585 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
589 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
591 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
593 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_FALSE
;
594 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
597 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
||
598 zBufCtrl
!= imesa
->regs
.s3d
.zBufCtrl
.ui
)
599 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
600 if (zWatermarks
!= imesa
->regs
.s3d
.zWatermarks
.ui
)
601 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
604 static void savageDDDepthMask_s4(GLcontext
*ctx
, GLboolean flag
)
606 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
608 static void savageDDDepthMask_s3d(GLcontext
*ctx
, GLboolean flag
)
610 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
616 /* =============================================================
621 static void savageDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
622 GLsizei w
, GLsizei h
)
624 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
626 /* Emit buffered commands with old scissor state. */
629 /* Mirror scissors in private context. */
630 imesa
->scissor
.enabled
= ctx
->Scissor
.Enabled
;
631 imesa
->scissor
.x
= x
;
632 imesa
->scissor
.y
= y
;
633 imesa
->scissor
.w
= w
;
634 imesa
->scissor
.h
= h
;
639 static void savageDDDrawBuffer(GLcontext
*ctx
, GLenum mode
)
641 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
642 u_int32_t destCtrl
= imesa
->regs
.s4
.destCtrl
.ui
;
645 * _DrawDestMask is easier to cope with than <mode>.
647 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
648 case BUFFER_BIT_FRONT_LEFT
:
649 imesa
->IsDouble
= GL_FALSE
;
650 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->frontOffset
>>11;
652 imesa
->NotFirstFrame
= GL_FALSE
;
653 savageXMesaSetFrontClipRects( imesa
);
654 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
656 case BUFFER_BIT_BACK_LEFT
:
657 imesa
->IsDouble
= GL_TRUE
;
658 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->backOffset
>>11;
659 imesa
->NotFirstFrame
= GL_FALSE
;
660 savageXMesaSetBackClipRects( imesa
);
661 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
664 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
668 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
671 _swrast_DrawBuffer(ctx
, mode
);
673 if (destCtrl
!= imesa
->regs
.s4
.destCtrl
.ui
)
674 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
677 static void savageDDReadBuffer(GLcontext
*ctx
, GLenum mode
)
679 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
683 static void savageDDSetColor(GLcontext
*ctx
,
684 GLubyte r
, GLubyte g
,
685 GLubyte b
, GLubyte a
)
687 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
688 imesa
->MonoColor
= savagePackColor( imesa
->savageScreen
->frontFormat
, r
, g
, b
, a
);
692 /* =============================================================
693 * Window position and viewport transformation
696 void savageCalcViewport( GLcontext
*ctx
)
698 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
699 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
700 GLfloat
*m
= imesa
->hw_viewport
;
702 m
[MAT_SX
] = v
[MAT_SX
];
703 m
[MAT_TX
] = v
[MAT_TX
] + imesa
->drawX
+ SUBPIXEL_X
;
704 m
[MAT_SY
] = - v
[MAT_SY
];
705 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ imesa
->drawY
+ SUBPIXEL_Y
;
706 /* Depth range is reversed (far: 0, near: 1) so that float depth
707 * compensates for loss of accuracy of far coordinates. */
708 if (imesa
->float_depth
&& imesa
->savageScreen
->zpp
== 2) {
709 /* The Savage 16-bit floating point depth format can't encode
710 * numbers < 2^-16. Make sure all depth values stay greater
712 m
[MAT_SZ
] = - v
[MAT_SZ
] * imesa
->depth_scale
* (65535.0/65536.0);
713 m
[MAT_TZ
] = 1.0 - v
[MAT_TZ
] * imesa
->depth_scale
* (65535.0/65536.0);
715 m
[MAT_SZ
] = - v
[MAT_SZ
] * imesa
->depth_scale
;
716 m
[MAT_TZ
] = 1.0 - v
[MAT_TZ
] * imesa
->depth_scale
;
719 imesa
->SetupNewInputs
= ~0;
722 static void savageViewport( GLcontext
*ctx
,
724 GLsizei width
, GLsizei height
)
726 /* update size of Mesa/software ancillary buffers */
727 _mesa_ResizeBuffersMESA();
728 savageCalcViewport( ctx
);
731 static void savageDepthRange( GLcontext
*ctx
,
732 GLclampd nearval
, GLclampd farval
)
734 savageCalcViewport( ctx
);
738 /* =============================================================
742 static void savageDDClearColor(GLcontext
*ctx
,
743 const GLfloat color
[4] )
745 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
747 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
748 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
749 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
750 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
752 imesa
->ClearColor
= savagePackColor( imesa
->savageScreen
->frontFormat
,
753 c
[0], c
[1], c
[2], c
[3] );
756 /* Fallback to swrast for select and feedback.
758 static void savageRenderMode( GLcontext
*ctx
, GLenum mode
)
760 FALLBACK( ctx
, SAVAGE_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
766 /* =============================================================
767 * Culling - the savage isn't quite as clean here as the rest of
768 * its interfaces, but it's not bad.
770 static void savageDDCullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
772 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
773 GLuint cullMode
=imesa
->LcsCullMode
;
774 switch (ctx
->Polygon
.CullFaceMode
)
777 switch (ctx
->Polygon
.FrontFace
)
789 switch (ctx
->Polygon
.FrontFace
)
800 imesa
->LcsCullMode
= cullMode
;
801 imesa
->new_state
|= SAVAGE_NEW_CULL
;
803 #endif /* end #if HW_CULL */
805 static void savageUpdateCull( GLcontext
*ctx
)
808 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
810 if (ctx
->Polygon
.CullFlag
&&
811 imesa
->raster_primitive
>= GL_TRIANGLES
&&
812 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
813 cullMode
= imesa
->LcsCullMode
;
816 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
817 if (imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
!= cullMode
) {
818 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= cullMode
;
819 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
822 if (imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
!= cullMode
) {
823 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= cullMode
;
824 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
827 #endif /* end #if HW_CULL */
832 /* =============================================================
836 /* Savage4 can disable draw updates when all channels are
837 * masked. Savage3D has a bit called drawUpdateEn, but it doesn't seem
838 * to have any effect. If only some channels are masked we need a
839 * software fallback on all chips.
841 static void savageDDColorMask_s4(GLcontext
*ctx
,
842 GLboolean r
, GLboolean g
,
843 GLboolean b
, GLboolean a
)
845 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
846 GLboolean passAny
, passAll
;
848 if (ctx
->Visual
.alphaBits
) {
849 passAny
= b
|| g
|| r
|| a
;
850 passAll
= r
&& g
&& b
&& a
;
852 passAny
= b
|| g
|| r
;
853 passAll
= r
&& g
&& b
;
857 if (!imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
) {
858 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
859 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
861 FALLBACK (ctx
, SAVAGE_FALLBACK_COLORMASK
, !passAll
);
862 } else if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
) {
863 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
864 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
867 static void savageDDColorMask_s3d(GLcontext
*ctx
,
868 GLboolean r
, GLboolean g
,
869 GLboolean b
, GLboolean a
)
871 if (ctx
->Visual
.alphaBits
)
872 FALLBACK (ctx
, SAVAGE_FALLBACK_COLORMASK
, !(r
&& g
&& b
&& a
));
874 FALLBACK (ctx
, SAVAGE_FALLBACK_COLORMASK
, !(r
&& g
&& b
));
877 /* Seperate specular not fully implemented in hardware... Needs
878 * some interaction with material state? Just punt to software
880 * FK: Don't fall back for now. Let's see the failure cases and
881 * fix them the right way. I don't see how this could be a
882 * hardware limitation.
884 static void savageUpdateSpecular_s4(GLcontext
*ctx
) {
885 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
886 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
888 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
889 ctx
->Light
.Enabled
) {
890 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_TRUE
;
891 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
893 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_FALSE
;
894 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
897 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
898 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
900 static void savageUpdateSpecular_s3d(GLcontext
*ctx
) {
901 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
902 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
904 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
905 ctx
->Light
.Enabled
) {
906 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_TRUE
;
907 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
909 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_FALSE
;
910 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
913 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
914 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
917 static void savageDDLightModelfv_s4(GLcontext
*ctx
, GLenum pname
,
918 const GLfloat
*param
)
920 savageUpdateSpecular_s4 (ctx
);
922 static void savageDDLightModelfv_s3d(GLcontext
*ctx
, GLenum pname
,
923 const GLfloat
*param
)
925 savageUpdateSpecular_s3d (ctx
);
928 static void savageDDShadeModel_s4(GLcontext
*ctx
, GLuint mod
)
930 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
931 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
933 if (mod
== GL_SMOOTH
)
935 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_FALSE
;
939 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_TRUE
;
942 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
943 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
945 static void savageDDShadeModel_s3d(GLcontext
*ctx
, GLuint mod
)
947 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
948 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
950 if (mod
== GL_SMOOTH
)
952 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_FALSE
;
956 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_TRUE
;
959 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
960 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
964 /* =============================================================
966 * The fogCtrl register has the same position and the same layout
967 * on savage3d and savage4. No need for two separate functions.
970 static void savageDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
972 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
974 u_int32_t fogCtrl
= imesa
->regs
.s4
.fogCtrl
.ui
;
976 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
977 if (ctx
->Fog
.Enabled
)
979 fogClr
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
980 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
981 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
982 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= GL_TRUE
;
984 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= GL_TRUE
;
985 imesa
->regs
.s4
.fogCtrl
.ni
.fogClr
= fogClr
;
991 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= 0;
992 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= 0;
995 if (fogCtrl
!= imesa
->regs
.s4
.fogCtrl
.ui
)
996 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1000 static void savageDDStencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
1003 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1005 u_int32_t zBufCtrl
= imesa
->regs
.s4
.zBufCtrl
.ui
;
1006 u_int32_t stencilCtrl
= imesa
->regs
.s4
.stencilCtrl
.ui
;
1008 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= ctx
->Stencil
.Ref
[0];
1009 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= ctx
->Stencil
.ValueMask
[0];
1011 switch (ctx
->Stencil
.Function
[0])
1013 case GL_NEVER
: a
= CF_Never
; break;
1014 case GL_ALWAYS
: a
= CF_Always
; break;
1015 case GL_LESS
: a
= CF_Less
; break;
1016 case GL_LEQUAL
: a
= CF_LessEqual
; break;
1017 case GL_EQUAL
: a
= CF_Equal
; break;
1018 case GL_GREATER
: a
= CF_Greater
; break;
1019 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
1020 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
1025 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= a
;
1027 if (zBufCtrl
!= imesa
->regs
.s4
.zBufCtrl
.ui
||
1028 stencilCtrl
!= imesa
->regs
.s4
.stencilCtrl
.ui
)
1029 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1032 static void savageDDStencilMask(GLcontext
*ctx
, GLuint mask
)
1034 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1036 if (imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
!= ctx
->Stencil
.WriteMask
[0]) {
1037 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= ctx
->Stencil
.WriteMask
[0];
1038 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1042 static void savageDDStencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
1045 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1046 u_int32_t stencilCtrl
= imesa
->regs
.s4
.stencilCtrl
.ui
;
1048 switch (ctx
->Stencil
.FailFunc
[0])
1051 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1054 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Zero
;
1057 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Equal
;
1060 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_IncClamp
;
1063 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_DecClamp
;
1066 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Invert
;
1068 case GL_INCR_WRAP_EXT
:
1069 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Inc
;
1071 case GL_DECR_WRAP_EXT
:
1072 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Dec
;
1077 switch (ctx
->Stencil
.ZFailFunc
[0])
1080 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1083 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Zero
;
1086 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Equal
;
1089 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_IncClamp
;
1092 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_DecClamp
;
1095 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Invert
;
1097 case GL_INCR_WRAP_EXT
:
1098 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Inc
;
1100 case GL_DECR_WRAP_EXT
:
1101 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Dec
;
1105 switch (ctx
->Stencil
.ZPassFunc
[0])
1108 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1111 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Zero
;
1114 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Equal
;
1117 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_IncClamp
;
1120 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_DecClamp
;
1123 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Invert
;
1125 case GL_INCR_WRAP_EXT
:
1126 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Inc
;
1128 case GL_DECR_WRAP_EXT
:
1129 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Dec
;
1133 if (stencilCtrl
!= imesa
->regs
.s4
.stencilCtrl
.ui
)
1134 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1138 /* =============================================================
1141 static void savageDDEnable_s4(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1144 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1147 /* we should consider the disable case*/
1148 savageBlendFunc_s4(ctx
);
1151 /*add the savageBlendFunc 2001/11/25
1152 * if call no such function, then glDisable(GL_BLEND) will do noting,
1153 *our chip has no disable bit
1155 savageBlendFunc_s4(ctx
);
1156 case GL_COLOR_LOGIC_OP
:
1158 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1160 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1161 (ctx
->Color
.ColorLogicOpEnabled
&&
1162 ctx
->Color
.LogicOp
!= GL_COPY
));
1165 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
1167 case GL_SCISSOR_TEST
:
1168 savageDDScissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
1169 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
1171 case GL_STENCIL_TEST
:
1172 if (!imesa
->hw_stencil
)
1173 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1175 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= state
;
1176 if (ctx
->Stencil
.Enabled
&&
1177 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
!= GL_TRUE
)
1179 /* Stencil buffer requires Z enabled. */
1180 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
1181 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
1182 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
1184 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
| SAVAGE_UPLOAD_LOCAL
;
1188 savageDDFogfv(ctx
,0,0);
1194 savageDDCullFaceFrontFace(ctx
,0);
1198 imesa
->LcsCullMode
= BCM_None
;
1199 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1206 if ( ctx
->Color
.DitherFlag
)
1208 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_TRUE
;
1211 if (!ctx
->Color
.DitherFlag
)
1213 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_FALSE
;
1215 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1219 savageUpdateSpecular_s4 (ctx
);
1223 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1226 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1232 static void savageDDEnable_s3d(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1235 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1238 /* we should consider the disable case*/
1239 savageBlendFunc_s3d(ctx
);
1242 /*add the savageBlendFunc 2001/11/25
1243 * if call no such function, then glDisable(GL_BLEND) will do noting,
1244 *our chip has no disable bit
1246 savageBlendFunc_s3d(ctx
);
1247 case GL_COLOR_LOGIC_OP
:
1249 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1251 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1252 (ctx
->Color
.ColorLogicOpEnabled
&&
1253 ctx
->Color
.LogicOp
!= GL_COPY
));
1256 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
1258 case GL_SCISSOR_TEST
:
1259 savageDDScissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
1260 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
1262 case GL_STENCIL_TEST
:
1263 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1266 savageDDFogfv(ctx
,0,0);
1272 savageDDCullFaceFrontFace(ctx
,0);
1276 imesa
->LcsCullMode
= BCM_None
;
1277 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1284 if ( ctx
->Color
.DitherFlag
)
1286 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_TRUE
;
1289 if (!ctx
->Color
.DitherFlag
)
1291 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_FALSE
;
1293 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
1297 savageUpdateSpecular_s3d (ctx
);
1301 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1304 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1311 void savageDDUpdateHwState( GLcontext
*ctx
)
1313 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1315 if (imesa
->new_state
) {
1316 savageFlushVertices(imesa
);
1317 if (imesa
->new_state
& SAVAGE_NEW_TEXTURE
) {
1318 savageUpdateTextureState( ctx
);
1320 if ((imesa
->new_state
& SAVAGE_NEW_CULL
)) {
1321 savageUpdateCull(ctx
);
1323 imesa
->new_state
= 0;
1328 static void savageDDPrintDirty( const char *msg
, GLuint state
)
1330 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s\n",
1332 (unsigned int) state
,
1333 (state
& SAVAGE_UPLOAD_LOCAL
) ? "upload-local, " : "",
1334 (state
& SAVAGE_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1335 (state
& SAVAGE_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1336 (state
& SAVAGE_UPLOAD_FOGTBL
) ? "upload-fogtbl, " : "",
1337 (state
& SAVAGE_UPLOAD_GLOBAL
) ? "upload-global, " : "",
1338 (state
& SAVAGE_UPLOAD_TEXGLOBAL
) ? "upload-texglobal, " : ""
1344 * Check if global registers were changed
1346 static GLboolean
savageGlobalRegChanged (savageContextPtr imesa
,
1347 GLuint first
, GLuint last
) {
1349 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1350 if (((imesa
->oldRegs
.ui
[i
] ^ imesa
->regs
.ui
[i
]) &
1351 imesa
->globalRegMask
.ui
[i
]) != 0)
1356 static void savageEmitOldRegs (savageContextPtr imesa
,
1357 GLuint first
, GLuint last
, GLboolean global
) {
1358 GLuint n
= last
-first
+1;
1359 drm_savage_cmd_header_t
*cmd
= savageAllocCmdBuf(imesa
, n
*4);
1360 cmd
->state
.cmd
= SAVAGE_CMD_STATE
;
1361 cmd
->state
.global
= global
;
1362 cmd
->state
.count
= n
;
1363 cmd
->state
.start
= first
;
1364 memcpy(cmd
+1, &imesa
->oldRegs
.ui
[first
-SAVAGE_FIRST_REG
], n
*4);
1366 static void savageEmitContiguousRegs (savageContextPtr imesa
,
1367 GLuint first
, GLuint last
) {
1369 GLuint n
= last
-first
+1;
1370 drm_savage_cmd_header_t
*cmd
= savageAllocCmdBuf(imesa
, n
*4);
1371 cmd
->state
.cmd
= SAVAGE_CMD_STATE
;
1372 cmd
->state
.global
= savageGlobalRegChanged(imesa
, first
, last
);
1373 cmd
->state
.count
= n
;
1374 cmd
->state
.start
= first
;
1375 memcpy(cmd
+1, &imesa
->regs
.ui
[first
-SAVAGE_FIRST_REG
], n
*4);
1376 /* savageAllocCmdBuf may need to flush the cmd buffer and backup
1377 * the current hardware state. It should see the "old" (current)
1378 * state that has actually been emitted to the hardware. Therefore
1379 * this update is done *after* savageAllocCmdBuf. */
1380 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
)
1381 imesa
->oldRegs
.ui
[i
] = imesa
->regs
.ui
[i
];
1382 if (SAVAGE_DEBUG
& DEBUG_STATE
)
1383 fprintf (stderr
, "Emitting regs 0x%02x-0x%02x\n", first
, last
);
1385 static void savageEmitChangedRegs (savageContextPtr imesa
,
1386 GLuint first
, GLuint last
) {
1387 GLuint i
, firstChanged
;
1388 firstChanged
= SAVAGE_NR_REGS
;
1389 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1390 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1391 if (firstChanged
== SAVAGE_NR_REGS
)
1394 if (firstChanged
!= SAVAGE_NR_REGS
) {
1395 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1396 i
-1+SAVAGE_FIRST_REG
);
1397 firstChanged
= SAVAGE_NR_REGS
;
1401 if (firstChanged
!= SAVAGE_NR_REGS
)
1402 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1405 static void savageEmitChangedRegChunk (savageContextPtr imesa
,
1406 GLuint first
, GLuint last
) {
1408 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1409 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1410 savageEmitContiguousRegs (imesa
, first
, last
);
1415 static void savageUpdateRegister_s4(savageContextPtr imesa
)
1417 /* In case the texture image was changed without changing the
1418 * texture address as well, we need to force emitting the texture
1419 * address in order to flush texture cashes. */
1420 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX0
) &&
1421 imesa
->oldRegs
.s4
.texAddr
[0].ui
== imesa
->regs
.s4
.texAddr
[0].ui
)
1422 imesa
->oldRegs
.s4
.texAddr
[0].ui
= 0xffffffff;
1423 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX1
) &&
1424 imesa
->oldRegs
.s4
.texAddr
[1].ui
== imesa
->regs
.s4
.texAddr
[1].ui
)
1425 imesa
->oldRegs
.s4
.texAddr
[1].ui
= 0xffffffff;
1427 /* Fix up watermarks */
1428 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
) {
1429 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteLow
= 0;
1430 imesa
->regs
.s4
.destTexWatermarks
.ni
.destFlush
= 1;
1432 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteLow
= S4_DWLO
;
1433 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
)
1434 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 0;
1436 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= S4_ZWLO
;
1438 savageEmitChangedRegs (imesa
, 0x1e, 0x39);
1442 static void savageUpdateRegister_s3d(savageContextPtr imesa
)
1444 /* In case the texture image was changed without changing the
1445 * texture address as well, we need to force emitting the texture
1446 * address in order to flush texture cashes. */
1447 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX0
) &&
1448 imesa
->oldRegs
.s3d
.texAddr
.ui
== imesa
->regs
.s3d
.texAddr
.ui
)
1449 imesa
->oldRegs
.s3d
.texAddr
.ui
= 0xffffffff;
1451 /* Fix up watermarks */
1452 if (imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
) {
1453 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteLow
= 0;
1454 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destFlush
= 1;
1456 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteLow
= S3D_DWLO
;
1457 if (imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
)
1458 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 0;
1460 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= S3D_ZWLO
;
1463 /* the savage3d uses two contiguous ranges of BCI registers:
1464 * 0x18-0x1c and 0x20-0x38. Some texture registers need to be
1465 * emitted in one chunk or we get some funky rendering errors. */
1466 savageEmitChangedRegs (imesa
, 0x18, 0x19);
1467 savageEmitChangedRegChunk (imesa
, 0x1a, 0x1c);
1468 savageEmitChangedRegs (imesa
, 0x20, 0x38);
1474 void savageEmitOldState( savageContextPtr imesa
)
1476 assert(imesa
->cmdBuf
.write
== imesa
->cmdBuf
.base
);
1477 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
1478 savageEmitOldRegs (imesa
, 0x1e, 0x39, GL_TRUE
);
1480 savageEmitOldRegs (imesa
, 0x18, 0x1c, GL_TRUE
);
1481 savageEmitOldRegs (imesa
, 0x20, 0x38, GL_FALSE
);
1486 /* Push the state into the sarea and/or texture memory.
1488 void savageEmitChangedState( savageContextPtr imesa
)
1490 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_API
)
1491 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa
->dirty
);
1495 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_MSG
)
1496 fprintf (stderr
, "... emitting state\n");
1497 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1498 savageUpdateRegister_s4(imesa
);
1500 savageUpdateRegister_s3d(imesa
);
1507 static void savageDDInitState_s4( savageContextPtr imesa
)
1510 imesa
->regs
.s4
.destCtrl
.ui
= 1<<7;
1513 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1514 imesa
->regs
.s4
.zBufCtrl
.ni
.wToZEn
= GL_TRUE
;
1515 if (imesa
->float_depth
) {
1516 imesa
->regs
.s4
.zBufCtrl
.ni
.zExpOffset
=
1517 imesa
->savageScreen
->zpp
== 2 ? 16 : 32;
1518 imesa
->regs
.s4
.zBufCtrl
.ni
.floatZEn
= GL_TRUE
;
1520 imesa
->regs
.s4
.zBufCtrl
.ni
.zExpOffset
= 0;
1521 imesa
->regs
.s4
.zBufCtrl
.ni
.floatZEn
= GL_FALSE
;
1523 imesa
->regs
.s4
.texBlendCtrl
[0].ui
= TBC_NoTexMap
;
1524 imesa
->regs
.s4
.texBlendCtrl
[1].ui
= TBC_NoTexMap1
;
1525 imesa
->regs
.s4
.drawCtrl0
.ui
= 0;
1527 imesa
->regs
.s4
.drawCtrl1
.ni
.xyOffsetEn
= 1;
1530 /* Set DestTexWatermarks_31,30 to 01 always.
1531 *Has no effect if dest. flush is disabled.
1534 imesa
->regs
.s4
.zWatermarks
.ui
= 0x12000C04;
1535 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x40200400;
1537 /*imesa->regs.s4.zWatermarks.ui = 0x16001808;*/
1538 imesa
->regs
.s4
.zWatermarks
.ni
.rLow
= S4_ZRLO
;
1539 imesa
->regs
.s4
.zWatermarks
.ni
.rHigh
= S4_ZRHI
;
1540 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= S4_ZWLO
;
1541 imesa
->regs
.s4
.zWatermarks
.ni
.wHigh
= S4_ZWHI
;
1542 /*imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;*/
1543 imesa
->regs
.s4
.destTexWatermarks
.ni
.destReadLow
= S4_DRLO
;
1544 imesa
->regs
.s4
.destTexWatermarks
.ni
.destReadHigh
= S4_DRHI
;
1545 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteLow
= S4_DWLO
;
1546 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteHigh
= S4_DWHI
;
1547 imesa
->regs
.s4
.destTexWatermarks
.ni
.texRead
= S4_TR
;
1548 imesa
->regs
.s4
.destTexWatermarks
.ni
.destFlush
= 1;
1550 imesa
->regs
.s4
.drawCtrl0
.ni
.dPerfAccelEn
= GL_TRUE
;
1552 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1553 * alpha blending working properly
1556 imesa
->regs
.s4
.texCtrl
[0].ni
.dBias
= 0x08;
1557 imesa
->regs
.s4
.texCtrl
[1].ni
.dBias
= 0x08;
1558 imesa
->regs
.s4
.texCtrl
[0].ni
.texXprEn
= GL_TRUE
;
1559 imesa
->regs
.s4
.texCtrl
[1].ni
.texXprEn
= GL_TRUE
;
1560 imesa
->regs
.s4
.texCtrl
[0].ni
.dMax
= 0x0f;
1561 imesa
->regs
.s4
.texCtrl
[1].ni
.dMax
= 0x0f;
1562 /* programm a valid tex address, in case texture state is emitted
1563 * in wrong order. */
1564 if (imesa
->lastTexHeap
== 2 && imesa
->savageScreen
->textureSize
[1]) {
1565 /* AGP textures available */
1566 imesa
->regs
.s4
.texAddr
[0].ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1567 imesa
->regs
.s4
.texAddr
[1].ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1569 /* no AGP textures available, use local */
1570 imesa
->regs
.s4
.texAddr
[0].ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1571 imesa
->regs
.s4
.texAddr
[1].ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1573 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1574 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
1575 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1576 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1577 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1579 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1580 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
= (
1581 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1582 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1583 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= BCM_None
;
1585 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= 0x00;
1587 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= GL_FALSE
;
1588 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= CF_Always
;
1589 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1590 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1591 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1592 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= 0xff;
1593 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= 0xff;
1595 imesa
->LcsCullMode
=BCM_None
;
1596 imesa
->regs
.s4
.texDescr
.ni
.palSize
= TPS_256
;
1598 /* clear the local registers in the global reg mask */
1599 imesa
->globalRegMask
.s4
.drawLocalCtrl
.ui
= 0;
1600 imesa
->globalRegMask
.s4
.texPalAddr
.ui
= 0;
1601 imesa
->globalRegMask
.s4
.texCtrl
[0].ui
= 0;
1602 imesa
->globalRegMask
.s4
.texCtrl
[1].ui
= 0;
1603 imesa
->globalRegMask
.s4
.texAddr
[0].ui
= 0;
1604 imesa
->globalRegMask
.s4
.texAddr
[1].ui
= 0;
1605 imesa
->globalRegMask
.s4
.texBlendCtrl
[0].ui
= 0;
1606 imesa
->globalRegMask
.s4
.texBlendCtrl
[1].ui
= 0;
1607 imesa
->globalRegMask
.s4
.texXprClr
.ui
= 0;
1608 imesa
->globalRegMask
.s4
.texDescr
.ui
= 0;
1610 static void savageDDInitState_s3d( savageContextPtr imesa
)
1613 imesa
->regs
.s3d
.destCtrl
.ui
= 1<<7;
1616 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1618 imesa
->regs
.s3d
.drawCtrl
.ni
.xyOffsetEn
= 1;
1621 /* Set DestTexWatermarks_31,30 to 01 always.
1622 *Has no effect if dest. flush is disabled.
1625 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x12000C04;
1626 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x40200400;
1628 /*imesa->regs.s3d.zWatermarks.ui = 0x16001808;*/
1629 imesa
->regs
.s3d
.zWatermarks
.ni
.rLow
= S3D_ZRLO
;
1630 imesa
->regs
.s3d
.zWatermarks
.ni
.rHigh
= S3D_ZRHI
;
1631 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= S3D_ZWLO
;
1632 imesa
->regs
.s3d
.zWatermarks
.ni
.wHigh
= S3D_ZWHI
;
1633 /*imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;*/
1634 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destReadLow
= S3D_DRLO
;
1635 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destReadHigh
= S3D_DRHI
;
1636 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteLow
= S3D_DWLO
;
1637 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteHigh
= S3D_DWHI
;
1638 imesa
->regs
.s3d
.destTexWatermarks
.ni
.texRead
= S3D_TR
;
1639 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destFlush
= 1;
1642 imesa
->regs
.s3d
.texCtrl
.ni
.dBias
= 0x08;
1643 imesa
->regs
.s3d
.texCtrl
.ni
.texXprEn
= GL_TRUE
;
1644 /* texXprEn is needed to get alphatest and alpha blending working
1645 * properly. However, this makes texels with color texXprClr
1646 * completely transparent in some texture environment modes. I
1647 * couldn't find a way to disable this. So choose an arbitrary and
1648 * improbable color. (0 is a bad choice, makes all black texels
1650 imesa
->regs
.s3d
.texXprClr
.ui
= 0x26ae26ae;
1651 /* programm a valid tex address, in case texture state is emitted
1652 * in wrong order. */
1653 if (imesa
->lastTexHeap
== 2 && imesa
->savageScreen
->textureSize
[1]) {
1654 /* AGP textures available */
1655 imesa
->regs
.s3d
.texAddr
.ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1657 /* no AGP textures available, use local */
1658 imesa
->regs
.s3d
.texAddr
.ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1661 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1662 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1663 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1665 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
1666 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1667 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1669 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
= (
1670 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1671 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1672 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= BCM_None
;
1674 imesa
->LcsCullMode
= BCM_None
;
1675 imesa
->regs
.s3d
.texDescr
.ni
.palSize
= TPS_256
;
1677 /* clear the local registers in the global reg mask */
1678 imesa
->globalRegMask
.s3d
.texPalAddr
.ui
= 0;
1679 imesa
->globalRegMask
.s3d
.texXprClr
.ui
= 0;
1680 imesa
->globalRegMask
.s3d
.texAddr
.ui
= 0;
1681 imesa
->globalRegMask
.s3d
.texDescr
.ui
= 0;
1682 imesa
->globalRegMask
.s3d
.texCtrl
.ui
= 0;
1684 imesa
->globalRegMask
.s3d
.fogCtrl
.ui
= 0;
1686 /* drawCtrl is local with some exceptions */
1687 imesa
->globalRegMask
.s3d
.drawCtrl
.ui
= 0;
1688 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.cullMode
= 0x3;
1689 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= 0x7;
1690 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestEn
= 0x1;
1691 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaRefVal
= 0xff;
1693 /* zBufCtrl is local with some exceptions */
1694 imesa
->globalRegMask
.s3d
.zBufCtrl
.ui
= 0;
1695 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zCmpFunc
= 0x7;
1696 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zBufEn
= 0x1;
1698 void savageDDInitState( savageContextPtr imesa
) {
1699 memset (imesa
->regs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1700 memset (imesa
->globalRegMask
.ui
, 0xff, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1701 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1702 savageDDInitState_s4 (imesa
);
1704 savageDDInitState_s3d (imesa
);
1706 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1707 /* zbufoffset and destctrl have the same position and layout on
1708 * savage4 and savage3d. */
1709 if (imesa
->glCtx
->Visual
.doubleBufferMode
) {
1710 imesa
->IsDouble
= GL_TRUE
;
1711 imesa
->toggle
= TARGET_BACK
;
1712 imesa
->regs
.s4
.destCtrl
.ni
.offset
=
1713 imesa
->savageScreen
->backOffset
>>11;
1715 imesa
->IsDouble
= GL_FALSE
;
1716 imesa
->toggle
= TARGET_FRONT
;
1717 imesa
->regs
.s4
.destCtrl
.ni
.offset
=
1718 imesa
->savageScreen
->frontOffset
>>11;
1720 if(imesa
->savageScreen
->cpp
== 2) {
1721 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 0;
1722 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1723 (imesa
->savageScreen
->width
+63)>>6;
1725 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 1;
1726 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1727 (imesa
->savageScreen
->width
+31)>>5;
1729 imesa
->drawMap
= imesa
->apertureBase
[imesa
->toggle
];
1730 imesa
->readMap
= imesa
->apertureBase
[imesa
->toggle
];
1731 imesa
->NotFirstFrame
= GL_FALSE
;
1733 imesa
->regs
.s4
.zBufOffset
.ni
.offset
=imesa
->savageScreen
->depthOffset
>>11;
1734 if(imesa
->savageScreen
->zpp
== 2) {
1735 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1736 (imesa
->savageScreen
->width
+63)>>6;
1737 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 0;
1739 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1740 (imesa
->savageScreen
->width
+31)>>5;
1741 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 1;
1744 memcpy (imesa
->oldRegs
.ui
, imesa
->regs
.ui
, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1746 /* Emit the initial state to the (empty) command buffer. */
1747 assert (imesa
->cmdBuf
.write
== imesa
->cmdBuf
.base
);
1748 savageEmitOldState(imesa
);
1749 imesa
->cmdBuf
.start
= imesa
->cmdBuf
.write
;
1753 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1754 NEW_TEXTURE_MATRIX|\
1755 NEW_USER_CLIP|NEW_CLIENT_STATE))
1757 static void savageDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1759 _swrast_InvalidateState( ctx
, new_state
);
1760 _swsetup_InvalidateState( ctx
, new_state
);
1761 _ac_InvalidateState( ctx
, new_state
);
1762 _tnl_InvalidateState( ctx
, new_state
);
1763 SAVAGE_CONTEXT(ctx
)->new_gl_state
|= new_state
;
1767 void savageDDInitStateFuncs(GLcontext
*ctx
)
1769 ctx
->Driver
.UpdateState
= savageDDInvalidateState
;
1770 ctx
->Driver
.BlendEquationSeparate
= savageDDBlendEquationSeparate
;
1771 ctx
->Driver
.Fogfv
= savageDDFogfv
;
1772 ctx
->Driver
.Scissor
= savageDDScissor
;
1774 ctx
->Driver
.CullFace
= savageDDCullFaceFrontFace
;
1775 ctx
->Driver
.FrontFace
= savageDDCullFaceFrontFace
;
1777 ctx
->Driver
.CullFace
= 0;
1778 ctx
->Driver
.FrontFace
= 0;
1779 #endif /* end #if HW_CULL */
1780 ctx
->Driver
.PolygonMode
=NULL
;
1781 ctx
->Driver
.PolygonStipple
= 0;
1782 ctx
->Driver
.LineStipple
= 0;
1783 ctx
->Driver
.LineWidth
= 0;
1784 ctx
->Driver
.LogicOpcode
= 0;
1785 ctx
->Driver
.DrawBuffer
= savageDDDrawBuffer
;
1786 ctx
->Driver
.ReadBuffer
= savageDDReadBuffer
;
1787 ctx
->Driver
.ClearColor
= savageDDClearColor
;
1789 ctx
->Driver
.DepthRange
= savageDepthRange
;
1790 ctx
->Driver
.Viewport
= savageViewport
;
1791 ctx
->Driver
.RenderMode
= savageRenderMode
;
1793 ctx
->Driver
.ClearIndex
= 0;
1794 ctx
->Driver
.IndexMask
= 0;
1796 if (SAVAGE_CONTEXT( ctx
)->savageScreen
->chipset
>= S3_SAVAGE4
) {
1797 ctx
->Driver
.Enable
= savageDDEnable_s4
;
1798 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s4
;
1799 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s4
;
1800 ctx
->Driver
.DepthMask
= savageDDDepthMask_s4
;
1801 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s4
;
1802 ctx
->Driver
.ColorMask
= savageDDColorMask_s4
;
1803 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s4
;
1804 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s4
;
1805 ctx
->Driver
.StencilFunc
= savageDDStencilFunc
;
1806 ctx
->Driver
.StencilMask
= savageDDStencilMask
;
1807 ctx
->Driver
.StencilOp
= savageDDStencilOp
;
1809 ctx
->Driver
.Enable
= savageDDEnable_s3d
;
1810 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s3d
;
1811 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s3d
;
1812 ctx
->Driver
.DepthMask
= savageDDDepthMask_s3d
;
1813 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s3d
;
1814 ctx
->Driver
.ColorMask
= savageDDColorMask_s3d
;
1815 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s3d
;
1816 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s3d
;
1817 ctx
->Driver
.StencilFunc
= 0;
1818 ctx
->Driver
.StencilMask
= 0;
1819 ctx
->Driver
.StencilOp
= 0;
1822 /* Swrast hooks for imaging extensions:
1824 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1825 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1826 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1827 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;