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.
28 #include "main/mtypes.h"
29 #include "main/enums.h"
30 #include "main/macros.h"
35 #include "savagecontext.h"
37 #include "savagestate.h"
38 #include "savagetex.h"
39 #include "savagetris.h"
40 #include "savageioctl.h"
41 #include "savage_bci.h"
43 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
50 /* Savage4, ProSavage[DDR], SuperSavage watermarks */
63 /* Savage3D/MX/IX watermarks */
76 static void savageBlendFunc_s4(GLcontext
*);
77 static void savageBlendFunc_s3d(GLcontext
*);
79 static INLINE GLuint
savagePackColor(GLuint format
,
85 return SAVAGEPACKCOLOR8888(r
,g
,b
,a
);
87 return SAVAGEPACKCOLOR565(r
,g
,b
);
95 static void savageDDAlphaFunc_s4(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
97 savageBlendFunc_s4(ctx
);
99 static void savageDDAlphaFunc_s3d(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
101 savageBlendFunc_s3d(ctx
);
104 static void savageDDBlendEquationSeparate(GLcontext
*ctx
,
105 GLenum modeRGB
, GLenum modeA
)
107 assert( modeRGB
== modeA
);
109 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
112 FALLBACK( ctx
, SAVAGE_FALLBACK_LOGICOP
,
113 (ctx
->Color
.ColorLogicOpEnabled
&&
114 ctx
->Color
.LogicOp
!= GL_COPY
));
116 /* Can only do blend addition, not min, max, subtract, etc. */
117 FALLBACK( ctx
, SAVAGE_FALLBACK_BLEND_EQ
,
118 modeRGB
!= GL_FUNC_ADD
);
122 static void savageBlendFunc_s4(GLcontext
*ctx
)
124 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
125 uint32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
126 uint32_t drawCtrl0
= imesa
->regs
.s4
.drawCtrl0
.ui
;
127 uint32_t drawCtrl1
= imesa
->regs
.s4
.drawCtrl1
.ui
;
129 /* set up draw control register (including blending, alpha
130 * test, and shading model)
133 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_FALSE
;
138 if(ctx
->Color
.BlendEnabled
){
139 switch (ctx
->Color
.BlendDstRGB
)
142 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
146 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
147 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
151 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
152 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
155 case GL_ONE_MINUS_SRC_COLOR
:
156 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
157 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
161 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
162 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
165 case GL_ONE_MINUS_SRC_ALPHA
:
166 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
167 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
171 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
173 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
177 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
179 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
182 case GL_ONE_MINUS_DST_ALPHA
:
183 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
185 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
189 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
=DAM_1DstAlpha
;
190 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
195 switch (ctx
->Color
.BlendSrcRGB
)
198 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
202 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
206 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
207 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
210 case GL_ONE_MINUS_DST_COLOR
:
211 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
212 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
216 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
219 case GL_ONE_MINUS_SRC_ALPHA
:
220 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
224 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
226 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
230 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
231 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
235 case GL_ONE_MINUS_DST_ALPHA
:
236 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
238 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
242 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
=SAM_1DstAlpha
;
243 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
250 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
251 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
256 if(ctx
->Color
.AlphaEnabled
)
261 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
263 switch(ctx
->Color
.AlphaFunc
) {
264 case GL_NEVER
: a
= CF_Never
; break;
265 case GL_ALWAYS
: a
= CF_Always
; break;
266 case GL_LESS
: a
= CF_Less
; break;
267 case GL_LEQUAL
: a
= CF_LessEqual
; break;
268 case GL_EQUAL
: a
= CF_Equal
; break;
269 case GL_GREATER
: a
= CF_Greater
; break;
270 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
271 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
275 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_TRUE
;
276 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestCmpFunc
= a
;
277 imesa
->regs
.s4
.drawCtrl0
.ni
.alphaRefVal
= alphaRef
;
281 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_FALSE
;
284 /* Set/Reset Z-after-alpha*/
286 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
=
287 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
;
288 /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
289 ~drawLocalCtrl.ni.wrZafterAlphaTst;*/
291 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
292 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
293 if (drawCtrl0
!= imesa
->regs
.s4
.drawCtrl0
.ui
||
294 drawCtrl1
!= imesa
->regs
.s4
.drawCtrl1
.ui
)
295 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
297 static void savageBlendFunc_s3d(GLcontext
*ctx
)
299 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
300 uint32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
301 uint32_t zBufCtrl
= imesa
->regs
.s3d
.zBufCtrl
.ui
;
303 /* set up draw control register (including blending, alpha
304 * test, dithering, and shading model)
307 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= 0;
312 if(ctx
->Color
.BlendEnabled
){
313 switch (ctx
->Color
.BlendDstRGB
)
316 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
320 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
321 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
325 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
326 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
329 case GL_ONE_MINUS_SRC_COLOR
:
330 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
331 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
335 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
336 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
339 case GL_ONE_MINUS_SRC_ALPHA
:
340 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
341 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
345 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
347 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
351 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
353 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
356 case GL_ONE_MINUS_DST_ALPHA
:
357 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
359 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
363 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1DstAlpha
;
364 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
369 switch (ctx
->Color
.BlendSrcRGB
)
372 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
376 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
380 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
381 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
384 case GL_ONE_MINUS_DST_COLOR
:
385 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
386 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
390 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
393 case GL_ONE_MINUS_SRC_ALPHA
:
394 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
398 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
400 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
404 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
405 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
409 case GL_ONE_MINUS_DST_ALPHA
:
410 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
412 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
416 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstAlpha
;
417 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
424 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
425 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
430 if(ctx
->Color
.AlphaEnabled
)
435 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
437 switch(ctx
->Color
.AlphaFunc
) {
438 case GL_NEVER
: a
= CF_Never
; break;
439 case GL_ALWAYS
: a
= CF_Always
; break;
440 case GL_LESS
: a
= CF_Less
; break;
441 case GL_LEQUAL
: a
= CF_LessEqual
; break;
442 case GL_EQUAL
: a
= CF_Equal
; break;
443 case GL_GREATER
: a
= CF_Greater
; break;
444 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
445 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
449 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_TRUE
;
450 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= a
;
451 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaRefVal
= alphaRef
;
455 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_FALSE
;
458 /* Set/Reset Z-after-alpha*/
460 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
=
461 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
;
463 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
||
464 zBufCtrl
!= imesa
->regs
.s3d
.zBufCtrl
.ui
)
465 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
468 static void savageDDBlendFuncSeparate_s4( GLcontext
*ctx
, GLenum sfactorRGB
,
469 GLenum dfactorRGB
, GLenum sfactorA
,
472 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
473 savageBlendFunc_s4( ctx
);
475 static void savageDDBlendFuncSeparate_s3d( GLcontext
*ctx
, GLenum sfactorRGB
,
476 GLenum dfactorRGB
, GLenum sfactorA
,
479 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
480 savageBlendFunc_s3d( ctx
);
485 static void savageDDDepthFunc_s4(GLcontext
*ctx
, GLenum func
)
487 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
489 uint32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
490 uint32_t zBufCtrl
= imesa
->regs
.s4
.zBufCtrl
.ui
;
491 uint32_t zWatermarks
= imesa
->regs
.s4
.zWatermarks
.ui
; /* FIXME: in DRM */
493 /* set up z-buffer control register (global)
494 * set up z-buffer offset register (global)
495 * set up z read/write watermarks register (global)
498 switch(func
) { /* reversed (see savageCalcViewport) */
499 case GL_NEVER
: zmode
= CF_Never
; break;
500 case GL_ALWAYS
: zmode
= CF_Always
; break;
501 case GL_LESS
: zmode
= CF_Greater
; break;
502 case GL_LEQUAL
: zmode
= CF_GreaterEqual
; break;
503 case GL_EQUAL
: zmode
= CF_Equal
; break;
504 case GL_GREATER
: zmode
= CF_Less
; break;
505 case GL_GEQUAL
: zmode
= CF_LessEqual
; break;
506 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
512 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
513 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
514 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
515 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
517 else if (imesa
->glCtx
->Stencil
._Enabled
&& imesa
->hw_stencil
)
519 /* Need to keep Z on for Stencil. */
520 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
521 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
522 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
523 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
528 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
== GL_FALSE
)
530 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
531 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
535 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
537 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
539 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
540 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
543 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
544 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
545 if (zBufCtrl
!= imesa
->regs
.s4
.zBufCtrl
.ui
||
546 zWatermarks
!= imesa
->regs
.s4
.zWatermarks
.ui
)
547 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
549 static void savageDDDepthFunc_s3d(GLcontext
*ctx
, GLenum func
)
551 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
553 uint32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
554 uint32_t zBufCtrl
= imesa
->regs
.s3d
.zBufCtrl
.ui
;
555 uint32_t zWatermarks
= imesa
->regs
.s3d
.zWatermarks
.ui
; /* FIXME: in DRM */
557 /* set up z-buffer control register (global)
558 * set up z-buffer offset register (global)
559 * set up z read/write watermarks register (global)
561 switch(func
) { /* reversed (see savageCalcViewport) */
562 case GL_NEVER
: zmode
= CF_Never
; break;
563 case GL_ALWAYS
: zmode
= CF_Always
; break;
564 case GL_LESS
: zmode
= CF_Greater
; break;
565 case GL_LEQUAL
: zmode
= CF_GreaterEqual
; break;
566 case GL_EQUAL
: zmode
= CF_Equal
; break;
567 case GL_GREATER
: zmode
= CF_Less
; break;
568 case GL_GEQUAL
: zmode
= CF_LessEqual
; break;
569 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
574 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
575 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
576 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
578 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
582 if (imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
== GL_FALSE
) {
583 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
584 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
588 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
590 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
592 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_FALSE
;
593 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
596 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
||
597 zBufCtrl
!= imesa
->regs
.s3d
.zBufCtrl
.ui
)
598 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
599 if (zWatermarks
!= imesa
->regs
.s3d
.zWatermarks
.ui
)
600 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
603 static void savageDDDepthMask_s4(GLcontext
*ctx
, GLboolean flag
)
605 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
607 static void savageDDDepthMask_s3d(GLcontext
*ctx
, GLboolean flag
)
609 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
615 /* =============================================================
620 static void savageDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
621 GLsizei w
, GLsizei h
)
623 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
625 /* Emit buffered commands with old scissor state. */
628 /* Mirror scissors in private context. */
629 imesa
->scissor
.enabled
= ctx
->Scissor
.Enabled
;
630 imesa
->scissor
.x
= x
;
631 imesa
->scissor
.y
= y
;
632 imesa
->scissor
.w
= w
;
633 imesa
->scissor
.h
= h
;
638 static void savageDDDrawBuffer(GLcontext
*ctx
, GLenum mode
)
640 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
641 uint32_t destCtrl
= imesa
->regs
.s4
.destCtrl
.ui
;
643 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
!= 1) {
644 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
648 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
649 case BUFFER_FRONT_LEFT
:
650 imesa
->IsDouble
= GL_FALSE
;
651 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->frontOffset
>>11;
653 case BUFFER_BACK_LEFT
:
654 imesa
->IsDouble
= GL_TRUE
;
655 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->backOffset
>>11;
658 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
662 imesa
->NotFirstFrame
= GL_FALSE
;
663 savageXMesaSetClipRects(imesa
);
664 FALLBACK(ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
666 if (destCtrl
!= imesa
->regs
.s4
.destCtrl
.ui
)
667 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
670 static void savageDDReadBuffer(GLcontext
*ctx
, GLenum mode
)
672 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
676 static void savageDDSetColor(GLcontext
*ctx
,
677 GLubyte r
, GLubyte g
,
678 GLubyte b
, GLubyte a
)
680 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
681 imesa
->MonoColor
= savagePackColor( imesa
->savageScreen
->frontFormat
, r
, g
, b
, a
);
685 /* =============================================================
686 * Window position and viewport transformation
689 void savageCalcViewport( GLcontext
*ctx
)
691 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
692 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
693 GLfloat
*m
= imesa
->hw_viewport
;
695 m
[MAT_SX
] = v
[MAT_SX
];
696 m
[MAT_TX
] = v
[MAT_TX
] + imesa
->drawX
+ SUBPIXEL_X
;
697 m
[MAT_SY
] = - v
[MAT_SY
];
698 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ imesa
->drawY
+ SUBPIXEL_Y
;
699 /* Depth range is reversed (far: 0, near: 1) so that float depth
700 * compensates for loss of accuracy of far coordinates. */
701 if (imesa
->float_depth
&& imesa
->savageScreen
->zpp
== 2) {
702 /* The Savage 16-bit floating point depth format can't encode
703 * numbers < 2^-16. Make sure all depth values stay greater
705 m
[MAT_SZ
] = - v
[MAT_SZ
] * imesa
->depth_scale
* (65535.0/65536.0);
706 m
[MAT_TZ
] = 1.0 - v
[MAT_TZ
] * imesa
->depth_scale
* (65535.0/65536.0);
708 m
[MAT_SZ
] = - v
[MAT_SZ
] * imesa
->depth_scale
;
709 m
[MAT_TZ
] = 1.0 - v
[MAT_TZ
] * imesa
->depth_scale
;
712 imesa
->SetupNewInputs
= ~0;
715 static void savageViewport( GLcontext
*ctx
,
717 GLsizei width
, GLsizei height
)
719 savageCalcViewport( ctx
);
722 static void savageDepthRange( GLcontext
*ctx
,
723 GLclampd nearval
, GLclampd farval
)
725 savageCalcViewport( ctx
);
729 /* =============================================================
733 static void savageDDClearColor(GLcontext
*ctx
,
734 const GLfloat color
[4] )
736 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
738 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
739 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
740 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
741 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
743 imesa
->ClearColor
= savagePackColor( imesa
->savageScreen
->frontFormat
,
744 c
[0], c
[1], c
[2], c
[3] );
747 /* Fallback to swrast for select and feedback.
749 static void savageRenderMode( GLcontext
*ctx
, GLenum mode
)
751 FALLBACK( ctx
, SAVAGE_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
757 /* =============================================================
758 * Culling - the savage isn't quite as clean here as the rest of
759 * its interfaces, but it's not bad.
761 static void savageDDCullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
763 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
764 GLuint cullMode
=imesa
->LcsCullMode
;
765 switch (ctx
->Polygon
.CullFaceMode
)
768 switch (ctx
->Polygon
.FrontFace
)
780 switch (ctx
->Polygon
.FrontFace
)
791 imesa
->LcsCullMode
= cullMode
;
792 imesa
->new_state
|= SAVAGE_NEW_CULL
;
794 #endif /* end #if HW_CULL */
796 static void savageUpdateCull( GLcontext
*ctx
)
799 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
801 if (ctx
->Polygon
.CullFlag
&&
802 imesa
->raster_primitive
>= GL_TRIANGLES
&&
803 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
804 cullMode
= imesa
->LcsCullMode
;
807 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
808 if (imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
!= cullMode
) {
809 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= cullMode
;
810 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
813 if (imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
!= cullMode
) {
814 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= cullMode
;
815 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
818 #endif /* end #if HW_CULL */
823 /* =============================================================
827 /* Savage4 can disable draw updates when all channels are
828 * masked. Savage3D has a bit called drawUpdateEn, but it doesn't seem
829 * to have any effect. If only some channels are masked we need a
830 * software fallback on all chips.
832 static void savageDDColorMask_s4(GLcontext
*ctx
,
833 GLboolean r
, GLboolean g
,
834 GLboolean b
, GLboolean a
)
836 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
837 GLboolean passAny
, passAll
;
839 if (ctx
->Visual
.alphaBits
) {
840 passAny
= b
|| g
|| r
|| a
;
841 passAll
= r
&& g
&& b
&& a
;
843 passAny
= b
|| g
|| r
;
844 passAll
= r
&& g
&& b
;
848 if (!imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
) {
849 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
850 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
852 FALLBACK (ctx
, SAVAGE_FALLBACK_COLORMASK
, !passAll
);
853 } else if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
) {
854 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
855 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
858 static void savageDDColorMask_s3d(GLcontext
*ctx
,
859 GLboolean r
, GLboolean g
,
860 GLboolean b
, GLboolean a
)
862 if (ctx
->Visual
.alphaBits
)
863 FALLBACK (ctx
, SAVAGE_FALLBACK_COLORMASK
, !(r
&& g
&& b
&& a
));
865 FALLBACK (ctx
, SAVAGE_FALLBACK_COLORMASK
, !(r
&& g
&& b
));
868 static void savageUpdateSpecular_s4(GLcontext
*ctx
) {
869 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
870 uint32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
872 if (NEED_SECONDARY_COLOR(ctx
)) {
873 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_TRUE
;
875 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_FALSE
;
878 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
879 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
882 static void savageUpdateSpecular_s3d(GLcontext
*ctx
) {
883 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
884 uint32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
886 if (NEED_SECONDARY_COLOR(ctx
)) {
887 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_TRUE
;
889 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_FALSE
;
892 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
893 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
896 static void savageDDLightModelfv_s4(GLcontext
*ctx
, GLenum pname
,
897 const GLfloat
*param
)
899 savageUpdateSpecular_s4 (ctx
);
901 static void savageDDLightModelfv_s3d(GLcontext
*ctx
, GLenum pname
,
902 const GLfloat
*param
)
904 savageUpdateSpecular_s3d (ctx
);
907 static void savageDDShadeModel_s4(GLcontext
*ctx
, GLuint mod
)
909 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
910 uint32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
912 if (mod
== GL_SMOOTH
)
914 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_FALSE
;
918 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_TRUE
;
921 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
922 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
924 static void savageDDShadeModel_s3d(GLcontext
*ctx
, GLuint mod
)
926 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
927 uint32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
929 if (mod
== GL_SMOOTH
)
931 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_FALSE
;
935 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_TRUE
;
938 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
939 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
943 /* =============================================================
945 * The fogCtrl register has the same position and the same layout
946 * on savage3d and savage4. No need for two separate functions.
949 static void savageDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
951 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
953 uint32_t fogCtrl
= imesa
->regs
.s4
.fogCtrl
.ui
;
955 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
956 if (ctx
->Fog
.Enabled
)
958 fogClr
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
959 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
960 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
961 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= GL_TRUE
;
963 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= GL_TRUE
;
964 imesa
->regs
.s4
.fogCtrl
.ni
.fogClr
= fogClr
;
970 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= 0;
971 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= 0;
974 if (fogCtrl
!= imesa
->regs
.s4
.fogCtrl
.ui
)
975 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
980 savageDDStencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
,
981 GLint ref
, GLuint mask
)
983 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
985 const uint32_t zBufCtrl
= imesa
->regs
.s4
.zBufCtrl
.ui
;
986 const uint32_t stencilCtrl
= imesa
->regs
.s4
.stencilCtrl
.ui
;
988 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= ctx
->Stencil
.Ref
[0] & 0xff;
989 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= ctx
->Stencil
.ValueMask
[0] & 0xff;
991 switch (ctx
->Stencil
.Function
[0])
993 case GL_NEVER
: a
= CF_Never
; break;
994 case GL_ALWAYS
: a
= CF_Always
; break;
995 case GL_LESS
: a
= CF_Less
; break;
996 case GL_LEQUAL
: a
= CF_LessEqual
; break;
997 case GL_EQUAL
: a
= CF_Equal
; break;
998 case GL_GREATER
: a
= CF_Greater
; break;
999 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
1000 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
1005 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= a
;
1007 if (zBufCtrl
!= imesa
->regs
.s4
.zBufCtrl
.ui
||
1008 stencilCtrl
!= imesa
->regs
.s4
.stencilCtrl
.ui
)
1009 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1013 savageDDStencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
1015 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1017 if (imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
!= (ctx
->Stencil
.WriteMask
[0] & 0xff)) {
1018 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= (ctx
->Stencil
.WriteMask
[0] & 0xff);
1019 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1023 static unsigned get_stencil_op_value( GLenum op
)
1027 case GL_KEEP
: return STENCIL_Keep
;
1028 case GL_ZERO
: return STENCIL_Zero
;
1029 case GL_REPLACE
: return STENCIL_Equal
;
1030 case GL_INCR
: return STENCIL_IncClamp
;
1031 case GL_DECR
: return STENCIL_DecClamp
;
1032 case GL_INVERT
: return STENCIL_Invert
;
1033 case GL_INCR_WRAP
: return STENCIL_Inc
;
1034 case GL_DECR_WRAP
: return STENCIL_Dec
;
1037 /* Should *never* get here. */
1038 return STENCIL_Keep
;
1042 savageDDStencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
,
1043 GLenum zfail
, GLenum zpass
)
1045 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1046 const uint32_t stencilCtrl
= imesa
->regs
.s4
.stencilCtrl
.ui
;
1048 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= get_stencil_op_value( ctx
->Stencil
.FailFunc
[0] );
1049 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= get_stencil_op_value( ctx
->Stencil
.ZFailFunc
[0] );
1050 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= get_stencil_op_value( ctx
->Stencil
.ZPassFunc
[0] );
1052 if (stencilCtrl
!= imesa
->regs
.s4
.stencilCtrl
.ui
)
1053 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1057 /* =============================================================
1060 static void savageDDEnable_s4(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1063 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1066 /* we should consider the disable case*/
1067 savageBlendFunc_s4(ctx
);
1070 /*add the savageBlendFunc 2001/11/25
1071 * if call no such function, then glDisable(GL_BLEND) will do noting,
1072 *our chip has no disable bit
1074 savageBlendFunc_s4(ctx
);
1075 case GL_COLOR_LOGIC_OP
:
1077 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1079 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1080 (ctx
->Color
.ColorLogicOpEnabled
&&
1081 ctx
->Color
.LogicOp
!= GL_COPY
));
1084 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
1086 case GL_SCISSOR_TEST
:
1087 savageDDScissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
1088 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
1090 case GL_STENCIL_TEST
:
1091 if (!imesa
->hw_stencil
)
1092 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1094 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= state
;
1095 if (ctx
->Stencil
._Enabled
&&
1096 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
!= GL_TRUE
)
1098 /* Stencil buffer requires Z enabled. */
1099 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
1100 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
1101 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
1103 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
| SAVAGE_UPLOAD_LOCAL
;
1107 savageDDFogfv(ctx
,0,0);
1113 savageDDCullFaceFrontFace(ctx
,0);
1117 imesa
->LcsCullMode
= BCM_None
;
1118 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1125 if ( ctx
->Color
.DitherFlag
)
1127 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_TRUE
;
1130 if (!ctx
->Color
.DitherFlag
)
1132 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_FALSE
;
1134 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1138 savageUpdateSpecular_s4 (ctx
);
1142 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1145 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1151 static void savageDDEnable_s3d(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1154 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1157 /* we should consider the disable case*/
1158 savageBlendFunc_s3d(ctx
);
1161 /*add the savageBlendFunc 2001/11/25
1162 * if call no such function, then glDisable(GL_BLEND) will do noting,
1163 *our chip has no disable bit
1165 savageBlendFunc_s3d(ctx
);
1166 case GL_COLOR_LOGIC_OP
:
1168 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1170 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1171 (ctx
->Color
.ColorLogicOpEnabled
&&
1172 ctx
->Color
.LogicOp
!= GL_COPY
));
1175 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
1177 case GL_SCISSOR_TEST
:
1178 savageDDScissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
1179 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
1181 case GL_STENCIL_TEST
:
1182 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1185 savageDDFogfv(ctx
,0,0);
1191 savageDDCullFaceFrontFace(ctx
,0);
1195 imesa
->LcsCullMode
= BCM_None
;
1196 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1203 if ( ctx
->Color
.DitherFlag
)
1205 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_TRUE
;
1208 if (!ctx
->Color
.DitherFlag
)
1210 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_FALSE
;
1212 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
1216 savageUpdateSpecular_s3d (ctx
);
1220 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1223 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1230 void savageDDUpdateHwState( GLcontext
*ctx
)
1232 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1234 if (imesa
->new_state
) {
1235 savageFlushVertices(imesa
);
1236 if (imesa
->new_state
& SAVAGE_NEW_TEXTURE
) {
1237 savageUpdateTextureState( ctx
);
1239 if ((imesa
->new_state
& SAVAGE_NEW_CULL
)) {
1240 savageUpdateCull(ctx
);
1242 imesa
->new_state
= 0;
1247 static void savageDDPrintDirty( const char *msg
, GLuint state
)
1249 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s\n",
1251 (unsigned int) state
,
1252 (state
& SAVAGE_UPLOAD_LOCAL
) ? "upload-local, " : "",
1253 (state
& SAVAGE_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1254 (state
& SAVAGE_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1255 (state
& SAVAGE_UPLOAD_FOGTBL
) ? "upload-fogtbl, " : "",
1256 (state
& SAVAGE_UPLOAD_GLOBAL
) ? "upload-global, " : "",
1257 (state
& SAVAGE_UPLOAD_TEXGLOBAL
) ? "upload-texglobal, " : ""
1263 * Check if global registers were changed
1265 static GLboolean
savageGlobalRegChanged (savageContextPtr imesa
,
1266 GLuint first
, GLuint last
) {
1268 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1269 if (((imesa
->oldRegs
.ui
[i
] ^ imesa
->regs
.ui
[i
]) &
1270 imesa
->globalRegMask
.ui
[i
]) != 0)
1275 static void savageEmitOldRegs (savageContextPtr imesa
,
1276 GLuint first
, GLuint last
, GLboolean global
) {
1277 GLuint n
= last
-first
+1;
1278 drm_savage_cmd_header_t
*cmd
= savageAllocCmdBuf(imesa
, n
*4);
1279 cmd
->state
.cmd
= SAVAGE_CMD_STATE
;
1280 cmd
->state
.global
= global
;
1281 cmd
->state
.count
= n
;
1282 cmd
->state
.start
= first
;
1283 memcpy(cmd
+1, &imesa
->oldRegs
.ui
[first
-SAVAGE_FIRST_REG
], n
*4);
1285 static void savageEmitContiguousRegs (savageContextPtr imesa
,
1286 GLuint first
, GLuint last
) {
1288 GLuint n
= last
-first
+1;
1289 drm_savage_cmd_header_t
*cmd
= savageAllocCmdBuf(imesa
, n
*4);
1290 cmd
->state
.cmd
= SAVAGE_CMD_STATE
;
1291 cmd
->state
.global
= savageGlobalRegChanged(imesa
, first
, last
);
1292 cmd
->state
.count
= n
;
1293 cmd
->state
.start
= first
;
1294 memcpy(cmd
+1, &imesa
->regs
.ui
[first
-SAVAGE_FIRST_REG
], n
*4);
1295 /* savageAllocCmdBuf may need to flush the cmd buffer and backup
1296 * the current hardware state. It should see the "old" (current)
1297 * state that has actually been emitted to the hardware. Therefore
1298 * this update is done *after* savageAllocCmdBuf. */
1299 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
)
1300 imesa
->oldRegs
.ui
[i
] = imesa
->regs
.ui
[i
];
1301 if (SAVAGE_DEBUG
& DEBUG_STATE
)
1302 fprintf (stderr
, "Emitting regs 0x%02x-0x%02x\n", first
, last
);
1304 static void savageEmitChangedRegs (savageContextPtr imesa
,
1305 GLuint first
, GLuint last
) {
1306 GLuint i
, firstChanged
;
1307 firstChanged
= SAVAGE_NR_REGS
;
1308 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1309 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1310 if (firstChanged
== SAVAGE_NR_REGS
)
1313 if (firstChanged
!= SAVAGE_NR_REGS
) {
1314 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1315 i
-1+SAVAGE_FIRST_REG
);
1316 firstChanged
= SAVAGE_NR_REGS
;
1320 if (firstChanged
!= SAVAGE_NR_REGS
)
1321 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1324 static void savageEmitChangedRegChunk (savageContextPtr imesa
,
1325 GLuint first
, GLuint last
) {
1327 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1328 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1329 savageEmitContiguousRegs (imesa
, first
, last
);
1334 static void savageUpdateRegister_s4(savageContextPtr imesa
)
1336 /* In case the texture image was changed without changing the
1337 * texture address as well, we need to force emitting the texture
1338 * address in order to flush texture cashes. */
1339 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX0
) &&
1340 imesa
->oldRegs
.s4
.texAddr
[0].ui
== imesa
->regs
.s4
.texAddr
[0].ui
)
1341 imesa
->oldRegs
.s4
.texAddr
[0].ui
= 0xffffffff;
1342 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX1
) &&
1343 imesa
->oldRegs
.s4
.texAddr
[1].ui
== imesa
->regs
.s4
.texAddr
[1].ui
)
1344 imesa
->oldRegs
.s4
.texAddr
[1].ui
= 0xffffffff;
1346 /* Fix up watermarks */
1347 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
) {
1348 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteLow
= 0;
1349 imesa
->regs
.s4
.destTexWatermarks
.ni
.destFlush
= 1;
1351 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteLow
= S4_DWLO
;
1352 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
)
1353 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 0;
1355 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= S4_ZWLO
;
1357 savageEmitChangedRegs (imesa
, 0x1e, 0x39);
1361 static void savageUpdateRegister_s3d(savageContextPtr imesa
)
1363 /* In case the texture image was changed without changing the
1364 * texture address as well, we need to force emitting the texture
1365 * address in order to flush texture cashes. */
1366 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX0
) &&
1367 imesa
->oldRegs
.s3d
.texAddr
.ui
== imesa
->regs
.s3d
.texAddr
.ui
)
1368 imesa
->oldRegs
.s3d
.texAddr
.ui
= 0xffffffff;
1370 /* Fix up watermarks */
1371 if (imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
) {
1372 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteLow
= 0;
1373 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destFlush
= 1;
1375 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteLow
= S3D_DWLO
;
1376 if (imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
)
1377 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 0;
1379 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= S3D_ZWLO
;
1382 /* the savage3d uses two contiguous ranges of BCI registers:
1383 * 0x18-0x1c and 0x20-0x38. Some texture registers need to be
1384 * emitted in one chunk or we get some funky rendering errors. */
1385 savageEmitChangedRegs (imesa
, 0x18, 0x19);
1386 savageEmitChangedRegChunk (imesa
, 0x1a, 0x1c);
1387 savageEmitChangedRegs (imesa
, 0x20, 0x38);
1393 void savageEmitOldState( savageContextPtr imesa
)
1395 assert(imesa
->cmdBuf
.write
== imesa
->cmdBuf
.base
);
1396 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
1397 savageEmitOldRegs (imesa
, 0x1e, 0x39, GL_TRUE
);
1399 savageEmitOldRegs (imesa
, 0x18, 0x1c, GL_TRUE
);
1400 savageEmitOldRegs (imesa
, 0x20, 0x38, GL_FALSE
);
1405 /* Push the state into the sarea and/or texture memory.
1407 void savageEmitChangedState( savageContextPtr imesa
)
1409 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_API
)
1410 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa
->dirty
);
1414 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_MSG
)
1415 fprintf (stderr
, "... emitting state\n");
1416 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1417 savageUpdateRegister_s4(imesa
);
1419 savageUpdateRegister_s3d(imesa
);
1426 static void savageDDInitState_s4( savageContextPtr imesa
)
1429 imesa
->regs
.s4
.destCtrl
.ui
= 1<<7;
1432 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1433 imesa
->regs
.s4
.zBufCtrl
.ni
.wToZEn
= GL_TRUE
;
1434 if (imesa
->float_depth
) {
1435 imesa
->regs
.s4
.zBufCtrl
.ni
.zExpOffset
=
1436 imesa
->savageScreen
->zpp
== 2 ? 16 : 32;
1437 imesa
->regs
.s4
.zBufCtrl
.ni
.floatZEn
= GL_TRUE
;
1439 imesa
->regs
.s4
.zBufCtrl
.ni
.zExpOffset
= 0;
1440 imesa
->regs
.s4
.zBufCtrl
.ni
.floatZEn
= GL_FALSE
;
1442 imesa
->regs
.s4
.texBlendCtrl
[0].ui
= TBC_NoTexMap
;
1443 imesa
->regs
.s4
.texBlendCtrl
[1].ui
= TBC_NoTexMap1
;
1444 imesa
->regs
.s4
.drawCtrl0
.ui
= 0;
1446 imesa
->regs
.s4
.drawCtrl1
.ni
.xyOffsetEn
= 1;
1449 /* Set DestTexWatermarks_31,30 to 01 always.
1450 *Has no effect if dest. flush is disabled.
1453 imesa
->regs
.s4
.zWatermarks
.ui
= 0x12000C04;
1454 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x40200400;
1456 /*imesa->regs.s4.zWatermarks.ui = 0x16001808;*/
1457 imesa
->regs
.s4
.zWatermarks
.ni
.rLow
= S4_ZRLO
;
1458 imesa
->regs
.s4
.zWatermarks
.ni
.rHigh
= S4_ZRHI
;
1459 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= S4_ZWLO
;
1460 imesa
->regs
.s4
.zWatermarks
.ni
.wHigh
= S4_ZWHI
;
1461 /*imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;*/
1462 imesa
->regs
.s4
.destTexWatermarks
.ni
.destReadLow
= S4_DRLO
;
1463 imesa
->regs
.s4
.destTexWatermarks
.ni
.destReadHigh
= S4_DRHI
;
1464 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteLow
= S4_DWLO
;
1465 imesa
->regs
.s4
.destTexWatermarks
.ni
.destWriteHigh
= S4_DWHI
;
1466 imesa
->regs
.s4
.destTexWatermarks
.ni
.texRead
= S4_TR
;
1467 imesa
->regs
.s4
.destTexWatermarks
.ni
.destFlush
= 1;
1469 imesa
->regs
.s4
.drawCtrl0
.ni
.dPerfAccelEn
= GL_TRUE
;
1471 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1472 * alpha blending working properly
1475 imesa
->regs
.s4
.texCtrl
[0].ni
.dBias
= 0x08;
1476 imesa
->regs
.s4
.texCtrl
[1].ni
.dBias
= 0x08;
1477 imesa
->regs
.s4
.texCtrl
[0].ni
.texXprEn
= GL_TRUE
;
1478 imesa
->regs
.s4
.texCtrl
[1].ni
.texXprEn
= GL_TRUE
;
1479 imesa
->regs
.s4
.texCtrl
[0].ni
.dMax
= 0x0f;
1480 imesa
->regs
.s4
.texCtrl
[1].ni
.dMax
= 0x0f;
1481 /* programm a valid tex address, in case texture state is emitted
1482 * in wrong order. */
1483 if (imesa
->lastTexHeap
== 2 && imesa
->savageScreen
->textureSize
[1]) {
1484 /* AGP textures available */
1485 imesa
->regs
.s4
.texAddr
[0].ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1486 imesa
->regs
.s4
.texAddr
[1].ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1488 /* no AGP textures available, use local */
1489 imesa
->regs
.s4
.texAddr
[0].ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1490 imesa
->regs
.s4
.texAddr
[1].ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1492 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1493 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
1494 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1495 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1496 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1498 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1499 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
= (
1500 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1501 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1502 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= BCM_None
;
1504 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= 0x00;
1506 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= GL_FALSE
;
1507 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= CF_Always
;
1508 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STENCIL_Keep
;
1509 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STENCIL_Keep
;
1510 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STENCIL_Keep
;
1511 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= 0xff;
1512 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= 0xff;
1514 imesa
->LcsCullMode
=BCM_None
;
1515 imesa
->regs
.s4
.texDescr
.ni
.palSize
= TPS_256
;
1517 /* clear the local registers in the global reg mask */
1518 imesa
->globalRegMask
.s4
.drawLocalCtrl
.ui
= 0;
1519 imesa
->globalRegMask
.s4
.texPalAddr
.ui
= 0;
1520 imesa
->globalRegMask
.s4
.texCtrl
[0].ui
= 0;
1521 imesa
->globalRegMask
.s4
.texCtrl
[1].ui
= 0;
1522 imesa
->globalRegMask
.s4
.texAddr
[0].ui
= 0;
1523 imesa
->globalRegMask
.s4
.texAddr
[1].ui
= 0;
1524 imesa
->globalRegMask
.s4
.texBlendCtrl
[0].ui
= 0;
1525 imesa
->globalRegMask
.s4
.texBlendCtrl
[1].ui
= 0;
1526 imesa
->globalRegMask
.s4
.texXprClr
.ui
= 0;
1527 imesa
->globalRegMask
.s4
.texDescr
.ui
= 0;
1529 static void savageDDInitState_s3d( savageContextPtr imesa
)
1532 imesa
->regs
.s3d
.destCtrl
.ui
= 1<<7;
1535 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1537 imesa
->regs
.s3d
.drawCtrl
.ni
.xyOffsetEn
= 1;
1540 /* Set DestTexWatermarks_31,30 to 01 always.
1541 *Has no effect if dest. flush is disabled.
1544 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x12000C04;
1545 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x40200400;
1547 /*imesa->regs.s3d.zWatermarks.ui = 0x16001808;*/
1548 imesa
->regs
.s3d
.zWatermarks
.ni
.rLow
= S3D_ZRLO
;
1549 imesa
->regs
.s3d
.zWatermarks
.ni
.rHigh
= S3D_ZRHI
;
1550 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= S3D_ZWLO
;
1551 imesa
->regs
.s3d
.zWatermarks
.ni
.wHigh
= S3D_ZWHI
;
1552 /*imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;*/
1553 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destReadLow
= S3D_DRLO
;
1554 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destReadHigh
= S3D_DRHI
;
1555 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteLow
= S3D_DWLO
;
1556 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destWriteHigh
= S3D_DWHI
;
1557 imesa
->regs
.s3d
.destTexWatermarks
.ni
.texRead
= S3D_TR
;
1558 imesa
->regs
.s3d
.destTexWatermarks
.ni
.destFlush
= 1;
1561 imesa
->regs
.s3d
.texCtrl
.ni
.dBias
= 0x08;
1562 imesa
->regs
.s3d
.texCtrl
.ni
.texXprEn
= GL_TRUE
;
1563 /* texXprEn is needed to get alphatest and alpha blending working
1564 * properly. However, this makes texels with color texXprClr
1565 * completely transparent in some texture environment modes. I
1566 * couldn't find a way to disable this. So choose an arbitrary and
1567 * improbable color. (0 is a bad choice, makes all black texels
1569 imesa
->regs
.s3d
.texXprClr
.ui
= 0x26ae26ae;
1570 /* programm a valid tex address, in case texture state is emitted
1571 * in wrong order. */
1572 if (imesa
->lastTexHeap
== 2 && imesa
->savageScreen
->textureSize
[1]) {
1573 /* AGP textures available */
1574 imesa
->regs
.s3d
.texAddr
.ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1576 /* no AGP textures available, use local */
1577 imesa
->regs
.s3d
.texAddr
.ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1580 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1581 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1582 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1584 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
1585 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1586 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1588 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
= (
1589 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1590 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1591 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= BCM_None
;
1593 imesa
->LcsCullMode
= BCM_None
;
1594 imesa
->regs
.s3d
.texDescr
.ni
.palSize
= TPS_256
;
1596 /* clear the local registers in the global reg mask */
1597 imesa
->globalRegMask
.s3d
.texPalAddr
.ui
= 0;
1598 imesa
->globalRegMask
.s3d
.texXprClr
.ui
= 0;
1599 imesa
->globalRegMask
.s3d
.texAddr
.ui
= 0;
1600 imesa
->globalRegMask
.s3d
.texDescr
.ui
= 0;
1601 imesa
->globalRegMask
.s3d
.texCtrl
.ui
= 0;
1603 imesa
->globalRegMask
.s3d
.fogCtrl
.ui
= 0;
1605 /* drawCtrl is local with some exceptions */
1606 imesa
->globalRegMask
.s3d
.drawCtrl
.ui
= 0;
1607 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.cullMode
= 0x3;
1608 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= 0x7;
1609 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestEn
= 0x1;
1610 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaRefVal
= 0xff;
1612 /* zBufCtrl is local with some exceptions */
1613 imesa
->globalRegMask
.s3d
.zBufCtrl
.ui
= 0;
1614 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zCmpFunc
= 0x7;
1615 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zBufEn
= 0x1;
1617 void savageDDInitState( savageContextPtr imesa
) {
1618 memset (imesa
->regs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(uint32_t));
1619 memset (imesa
->globalRegMask
.ui
, 0xff, SAVAGE_NR_REGS
*sizeof(uint32_t));
1620 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1621 savageDDInitState_s4 (imesa
);
1623 savageDDInitState_s3d (imesa
);
1625 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1626 /* zbufoffset and destctrl have the same position and layout on
1627 * savage4 and savage3d. */
1628 if (imesa
->glCtx
->Visual
.doubleBufferMode
) {
1629 imesa
->IsDouble
= GL_TRUE
;
1630 imesa
->toggle
= TARGET_BACK
;
1631 imesa
->regs
.s4
.destCtrl
.ni
.offset
=
1632 imesa
->savageScreen
->backOffset
>>11;
1634 imesa
->IsDouble
= GL_FALSE
;
1635 imesa
->toggle
= TARGET_FRONT
;
1636 imesa
->regs
.s4
.destCtrl
.ni
.offset
=
1637 imesa
->savageScreen
->frontOffset
>>11;
1639 if(imesa
->savageScreen
->cpp
== 2) {
1640 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 0;
1641 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1642 (imesa
->savageScreen
->width
+63)>>6;
1644 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 1;
1645 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1646 (imesa
->savageScreen
->width
+31)>>5;
1648 imesa
->NotFirstFrame
= GL_FALSE
;
1650 imesa
->regs
.s4
.zBufOffset
.ni
.offset
=imesa
->savageScreen
->depthOffset
>>11;
1651 if(imesa
->savageScreen
->zpp
== 2) {
1652 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1653 (imesa
->savageScreen
->width
+63)>>6;
1654 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 0;
1656 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1657 (imesa
->savageScreen
->width
+31)>>5;
1658 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 1;
1661 memcpy (imesa
->oldRegs
.ui
, imesa
->regs
.ui
, SAVAGE_NR_REGS
*sizeof(uint32_t));
1663 /* Emit the initial state to the (empty) command buffer. */
1664 assert (imesa
->cmdBuf
.write
== imesa
->cmdBuf
.base
);
1665 savageEmitOldState(imesa
);
1666 imesa
->cmdBuf
.start
= imesa
->cmdBuf
.write
;
1670 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1671 NEW_TEXTURE_MATRIX|\
1672 NEW_USER_CLIP|NEW_CLIENT_STATE))
1674 static void savageDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1676 _swrast_InvalidateState( ctx
, new_state
);
1677 _swsetup_InvalidateState( ctx
, new_state
);
1678 _vbo_InvalidateState( ctx
, new_state
);
1679 _tnl_InvalidateState( ctx
, new_state
);
1680 SAVAGE_CONTEXT(ctx
)->new_gl_state
|= new_state
;
1684 void savageDDInitStateFuncs(GLcontext
*ctx
)
1686 ctx
->Driver
.UpdateState
= savageDDInvalidateState
;
1687 ctx
->Driver
.BlendEquationSeparate
= savageDDBlendEquationSeparate
;
1688 ctx
->Driver
.Fogfv
= savageDDFogfv
;
1689 ctx
->Driver
.Scissor
= savageDDScissor
;
1691 ctx
->Driver
.CullFace
= savageDDCullFaceFrontFace
;
1692 ctx
->Driver
.FrontFace
= savageDDCullFaceFrontFace
;
1694 ctx
->Driver
.CullFace
= 0;
1695 ctx
->Driver
.FrontFace
= 0;
1696 #endif /* end #if HW_CULL */
1697 ctx
->Driver
.DrawBuffer
= savageDDDrawBuffer
;
1698 ctx
->Driver
.ReadBuffer
= savageDDReadBuffer
;
1699 ctx
->Driver
.ClearColor
= savageDDClearColor
;
1701 ctx
->Driver
.DepthRange
= savageDepthRange
;
1702 ctx
->Driver
.Viewport
= savageViewport
;
1703 ctx
->Driver
.RenderMode
= savageRenderMode
;
1705 if (SAVAGE_CONTEXT( ctx
)->savageScreen
->chipset
>= S3_SAVAGE4
) {
1706 ctx
->Driver
.Enable
= savageDDEnable_s4
;
1707 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s4
;
1708 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s4
;
1709 ctx
->Driver
.DepthMask
= savageDDDepthMask_s4
;
1710 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s4
;
1711 ctx
->Driver
.ColorMask
= savageDDColorMask_s4
;
1712 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s4
;
1713 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s4
;
1714 ctx
->Driver
.StencilFuncSeparate
= savageDDStencilFuncSeparate
;
1715 ctx
->Driver
.StencilMaskSeparate
= savageDDStencilMaskSeparate
;
1716 ctx
->Driver
.StencilOpSeparate
= savageDDStencilOpSeparate
;
1718 ctx
->Driver
.Enable
= savageDDEnable_s3d
;
1719 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s3d
;
1720 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s3d
;
1721 ctx
->Driver
.DepthMask
= savageDDDepthMask_s3d
;
1722 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s3d
;
1723 ctx
->Driver
.ColorMask
= savageDDColorMask_s3d
;
1724 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s3d
;
1725 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s3d
;
1726 ctx
->Driver
.StencilFuncSeparate
= NULL
;
1727 ctx
->Driver
.StencilMaskSeparate
= NULL
;
1728 ctx
->Driver
.StencilOpSeparate
= NULL
;