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 static void savageBlendFunc_s4(GLcontext
*);
52 static void savageBlendFunc_s3d(GLcontext
*);
54 static __inline__ GLuint
savagePackColor(GLuint format
,
60 return SAVAGEPACKCOLOR8888(r
,g
,b
,a
);
62 return SAVAGEPACKCOLOR565(r
,g
,b
);
70 static void savageDDAlphaFunc_s4(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
72 savageBlendFunc_s4(ctx
);
74 static void savageDDAlphaFunc_s3d(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
76 savageBlendFunc_s3d(ctx
);
79 static void savageDDBlendEquationSeparate(GLcontext
*ctx
,
80 GLenum modeRGB
, GLenum modeA
)
82 assert( modeRGB
== modeA
);
84 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
87 FALLBACK( ctx
, SAVAGE_FALLBACK_LOGICOP
,
88 (ctx
->Color
.ColorLogicOpEnabled
&&
89 ctx
->Color
.LogicOp
!= GL_COPY
));
91 /* Can only do blend addition, not min, max, subtract, etc. */
92 FALLBACK( ctx
, SAVAGE_FALLBACK_BLEND_EQ
,
93 modeRGB
!= GL_FUNC_ADD
);
97 static void savageBlendFunc_s4(GLcontext
*ctx
)
99 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
100 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
101 u_int32_t drawCtrl0
= imesa
->regs
.s4
.drawCtrl0
.ui
;
102 u_int32_t drawCtrl1
= imesa
->regs
.s4
.drawCtrl1
.ui
;
104 /* set up draw control register (including blending, alpha
105 * test, and shading model)
108 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= 0;
113 if(ctx
->Color
.BlendEnabled
){
114 switch (ctx
->Color
.BlendDstRGB
)
117 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
121 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
122 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
126 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
127 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
130 case GL_ONE_MINUS_SRC_COLOR
:
131 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
132 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
136 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
137 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
140 case GL_ONE_MINUS_SRC_ALPHA
:
141 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
142 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
146 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
148 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
152 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
154 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
157 case GL_ONE_MINUS_DST_ALPHA
:
158 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
160 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
164 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
=DAM_1DstAlpha
;
165 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
170 switch (ctx
->Color
.BlendSrcRGB
)
173 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
177 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
181 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
182 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
185 case GL_ONE_MINUS_DST_COLOR
:
186 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
187 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
191 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
194 case GL_ONE_MINUS_SRC_ALPHA
:
195 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
199 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
201 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
205 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
206 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
210 case GL_ONE_MINUS_DST_ALPHA
:
211 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
213 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
217 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
=SAM_1DstAlpha
;
218 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
225 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
226 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
231 if(ctx
->Color
.AlphaEnabled
)
236 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
238 switch(ctx
->Color
.AlphaFunc
) {
239 case GL_NEVER
: a
= CF_Never
; break;
240 case GL_ALWAYS
: a
= CF_Always
; break;
241 case GL_LESS
: a
= CF_Less
; break;
242 case GL_LEQUAL
: a
= CF_LessEqual
; break;
243 case GL_EQUAL
: a
= CF_Equal
; break;
244 case GL_GREATER
: a
= CF_Greater
; break;
245 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
246 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
250 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_TRUE
;
251 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestCmpFunc
= a
;
252 imesa
->regs
.s4
.drawCtrl0
.ni
.alphaRefVal
= alphaRef
;
256 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_FALSE
;
259 /* Set/Reset Z-after-alpha*/
261 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
=
262 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
;
263 /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
264 ~drawLocalCtrl.ni.wrZafterAlphaTst;*/
266 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
267 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
268 if (drawCtrl0
!= imesa
->regs
.s4
.drawCtrl0
.ui
||
269 drawCtrl1
!= imesa
->regs
.s4
.drawCtrl1
.ui
)
270 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
272 static void savageBlendFunc_s3d(GLcontext
*ctx
)
274 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
275 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
276 u_int32_t zBufCtrl
= imesa
->regs
.s3d
.zBufCtrl
.ui
;
278 /* set up draw control register (including blending, alpha
279 * test, dithering, and shading model)
282 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= 0;
287 if(ctx
->Color
.BlendEnabled
){
288 switch (ctx
->Color
.BlendDstRGB
)
291 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
295 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
296 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
300 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
301 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
304 case GL_ONE_MINUS_SRC_COLOR
:
305 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
306 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
310 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
311 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
314 case GL_ONE_MINUS_SRC_ALPHA
:
315 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
316 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
320 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
322 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
326 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
328 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
331 case GL_ONE_MINUS_DST_ALPHA
:
332 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
334 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
338 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1DstAlpha
;
339 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
344 switch (ctx
->Color
.BlendSrcRGB
)
347 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
351 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
355 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
356 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
359 case GL_ONE_MINUS_DST_COLOR
:
360 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
361 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
365 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
368 case GL_ONE_MINUS_SRC_ALPHA
:
369 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
373 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
375 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
379 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
380 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
384 case GL_ONE_MINUS_DST_ALPHA
:
385 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
387 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
391 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstAlpha
;
392 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
399 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
400 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
405 if(ctx
->Color
.AlphaEnabled
)
410 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
412 switch(ctx
->Color
.AlphaFunc
) {
413 case GL_NEVER
: a
= CF_Never
; break;
414 case GL_ALWAYS
: a
= CF_Always
; break;
415 case GL_LESS
: a
= CF_Less
; break;
416 case GL_LEQUAL
: a
= CF_LessEqual
; break;
417 case GL_EQUAL
: a
= CF_Equal
; break;
418 case GL_GREATER
: a
= CF_Greater
; break;
419 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
420 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
424 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_TRUE
;
425 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= a
;
426 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaRefVal
= alphaRef
;
430 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_FALSE
;
433 /* Set/Reset Z-after-alpha*/
435 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
=
436 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
;
438 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
||
439 zBufCtrl
!= imesa
->regs
.s3d
.zBufCtrl
.ui
)
440 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
443 static void savageDDBlendFuncSeparate_s4( GLcontext
*ctx
, GLenum sfactorRGB
,
444 GLenum dfactorRGB
, GLenum sfactorA
,
447 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
448 savageBlendFunc_s4( ctx
);
450 static void savageDDBlendFuncSeparate_s3d( GLcontext
*ctx
, GLenum sfactorRGB
,
451 GLenum dfactorRGB
, GLenum sfactorA
,
454 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
455 savageBlendFunc_s3d( ctx
);
460 static void savageDDDepthFunc_s4(GLcontext
*ctx
, GLenum func
)
462 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
464 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
465 u_int32_t zBufCtrl
= imesa
->regs
.s4
.zBufCtrl
.ui
;
466 u_int32_t zWatermarks
= imesa
->regs
.s4
.zWatermarks
.ui
; /* FIXME: in DRM */
468 /* set up z-buffer control register (global)
469 * set up z-buffer offset register (global)
470 * set up z read/write watermarks register (global)
473 switch(func
) { /* reversed (see savageCalcViewport) */
474 case GL_NEVER
: zmode
= CF_Never
; break;
475 case GL_ALWAYS
: zmode
= CF_Always
; break;
476 case GL_LESS
: zmode
= CF_Greater
; break;
477 case GL_LEQUAL
: zmode
= CF_GreaterEqual
; break;
478 case GL_EQUAL
: zmode
= CF_Equal
; break;
479 case GL_GREATER
: zmode
= CF_Less
; break;
480 case GL_GEQUAL
: zmode
= CF_LessEqual
; break;
481 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
487 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
488 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
489 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
491 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 0;
494 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
496 else if (imesa
->glCtx
->Stencil
.Enabled
&& imesa
->hw_stencil
)
498 /* Need to keep Z on for Stencil. */
499 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
500 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
501 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
502 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
503 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 8;
508 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
== GL_FALSE
)
510 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
511 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
515 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
517 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
519 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
520 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
521 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 8;
524 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
525 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
526 if (zBufCtrl
!= imesa
->regs
.s4
.zBufCtrl
.ui
||
527 zWatermarks
!= imesa
->regs
.s4
.zWatermarks
.ui
)
528 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
530 static void savageDDDepthFunc_s3d(GLcontext
*ctx
, GLenum func
)
532 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
534 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
535 u_int32_t zBufCtrl
= imesa
->regs
.s3d
.zBufCtrl
.ui
;
536 u_int32_t zWatermarks
= imesa
->regs
.s3d
.zWatermarks
.ui
; /* FIXME: in DRM */
538 /* set up z-buffer control register (global)
539 * set up z-buffer offset register (global)
540 * set up z read/write watermarks register (global)
542 switch(func
) { /* reversed (see savageCalcViewport) */
543 case GL_NEVER
: zmode
= CF_Never
; break;
544 case GL_ALWAYS
: zmode
= CF_Always
; break;
545 case GL_LESS
: zmode
= CF_Greater
; break;
546 case GL_LEQUAL
: zmode
= CF_GreaterEqual
; break;
547 case GL_EQUAL
: zmode
= CF_Equal
; break;
548 case GL_GREATER
: zmode
= CF_Less
; break;
549 case GL_GEQUAL
: zmode
= CF_LessEqual
; break;
550 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
555 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
556 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
557 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
559 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
561 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 0;
566 if (imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
== GL_FALSE
) {
567 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
568 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
572 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
574 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
576 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_FALSE
;
577 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
578 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 8;
581 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
||
582 zBufCtrl
!= imesa
->regs
.s3d
.zBufCtrl
.ui
)
583 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
584 if (zWatermarks
!= imesa
->regs
.s3d
.zWatermarks
.ui
)
585 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
588 static void savageDDDepthMask_s4(GLcontext
*ctx
, GLboolean flag
)
590 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
591 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
595 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
599 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
601 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
603 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
604 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
606 static void savageDDDepthMask_s3d(GLcontext
*ctx
, GLboolean flag
)
608 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
609 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
613 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
617 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
619 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
621 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
622 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
628 /* =============================================================
633 static void savageDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
634 GLsizei w
, GLsizei h
)
636 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
638 /* Emit buffered commands with old scissor state. */
641 /* Mirror scissors in private context. */
642 imesa
->scissor
.enabled
= ctx
->Scissor
.Enabled
;
643 imesa
->scissor
.x
= x
;
644 imesa
->scissor
.y
= y
;
645 imesa
->scissor
.w
= w
;
646 imesa
->scissor
.h
= h
;
651 static void savageDDDrawBuffer(GLcontext
*ctx
, GLenum mode
)
653 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
654 u_int32_t destCtrl
= imesa
->regs
.s4
.destCtrl
.ui
;
657 * _DrawDestMask is easier to cope with than <mode>.
659 switch ( ctx
->Color
._DrawDestMask
[0] ) {
660 case DD_FRONT_LEFT_BIT
:
661 imesa
->IsDouble
= GL_FALSE
;
662 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->frontOffset
>>11;
664 imesa
->NotFirstFrame
= GL_FALSE
;
665 savageXMesaSetFrontClipRects( imesa
);
666 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
668 case DD_BACK_LEFT_BIT
:
669 imesa
->IsDouble
= GL_TRUE
;
670 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->backOffset
>>11;
671 imesa
->NotFirstFrame
= GL_FALSE
;
672 savageXMesaSetBackClipRects( imesa
);
673 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
676 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
680 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
683 _swrast_DrawBuffer(ctx
, mode
);
685 if (destCtrl
!= imesa
->regs
.s4
.destCtrl
.ui
)
686 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
689 static void savageDDReadBuffer(GLcontext
*ctx
, GLenum mode
)
691 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
695 static void savageDDSetColor(GLcontext
*ctx
,
696 GLubyte r
, GLubyte g
,
697 GLubyte b
, GLubyte a
)
699 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
700 imesa
->MonoColor
= savagePackColor( imesa
->savageScreen
->frontFormat
, r
, g
, b
, a
);
704 /* =============================================================
705 * Window position and viewport transformation
708 void savageCalcViewport( GLcontext
*ctx
)
710 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
711 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
712 GLfloat
*m
= imesa
->hw_viewport
;
714 m
[MAT_SX
] = v
[MAT_SX
];
715 m
[MAT_TX
] = v
[MAT_TX
] + imesa
->drawX
+ SUBPIXEL_X
;
716 m
[MAT_SY
] = - v
[MAT_SY
];
717 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ imesa
->drawY
+ SUBPIXEL_Y
;
718 /* Depth range is reversed (far: 0, near: 1) so that float depth
719 * compensates for loss of accuracy of far coordinates. */
720 if (imesa
->float_depth
&& imesa
->savageScreen
->zpp
== 2) {
721 /* The Savage 16-bit floating point depth format can't encode
722 * numbers < 2^-16. Make sure all depth values stay greater
724 m
[MAT_SZ
] = - v
[MAT_SZ
] * imesa
->depth_scale
* (65535.0/65536.0);
725 m
[MAT_TZ
] = 1.0 - v
[MAT_TZ
] * imesa
->depth_scale
* (65535.0/65536.0);
727 m
[MAT_SZ
] = - v
[MAT_SZ
] * imesa
->depth_scale
;
728 m
[MAT_TZ
] = 1.0 - v
[MAT_TZ
] * imesa
->depth_scale
;
731 imesa
->SetupNewInputs
= ~0;
734 static void savageViewport( GLcontext
*ctx
,
736 GLsizei width
, GLsizei height
)
738 /* update size of Mesa/software ancillary buffers */
739 _mesa_ResizeBuffersMESA();
740 savageCalcViewport( ctx
);
743 static void savageDepthRange( GLcontext
*ctx
,
744 GLclampd nearval
, GLclampd farval
)
746 savageCalcViewport( ctx
);
750 /* =============================================================
754 static void savageDDClearColor(GLcontext
*ctx
,
755 const GLfloat color
[4] )
757 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
759 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
760 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
761 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
762 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
764 imesa
->ClearColor
= savagePackColor( imesa
->savageScreen
->frontFormat
,
765 c
[0], c
[1], c
[2], c
[3] );
768 /* Fallback to swrast for select and feedback.
770 static void savageRenderMode( GLcontext
*ctx
, GLenum mode
)
772 FALLBACK( ctx
, SAVAGE_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
778 /* =============================================================
779 * Culling - the savage isn't quite as clean here as the rest of
780 * its interfaces, but it's not bad.
782 static void savageDDCullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
784 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
785 GLuint cullMode
=imesa
->LcsCullMode
;
786 switch (ctx
->Polygon
.CullFaceMode
)
789 switch (ctx
->Polygon
.FrontFace
)
801 switch (ctx
->Polygon
.FrontFace
)
812 imesa
->LcsCullMode
= cullMode
;
813 imesa
->new_state
|= SAVAGE_NEW_CULL
;
815 #endif /* end #if HW_CULL */
817 static void savageUpdateCull( GLcontext
*ctx
)
820 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
822 if (ctx
->Polygon
.CullFlag
&&
823 imesa
->raster_primitive
>= GL_TRIANGLES
&&
824 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
825 cullMode
= imesa
->LcsCullMode
;
828 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
829 if (imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
!= cullMode
) {
830 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= cullMode
;
831 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
834 if (imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
!= cullMode
) {
835 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= cullMode
;
836 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
839 #endif /* end #if HW_CULL */
844 /* =============================================================
848 /* Mesa calls this from the wrong place - it is called a very large
849 * number of redundant times.
851 * Colormask can be simulated by multipass or multitexture techniques.
853 static void savageDDColorMask_s4(GLcontext
*ctx
,
854 GLboolean r
, GLboolean g
,
855 GLboolean b
, GLboolean a
)
857 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
860 if (ctx
->Visual
.alphaBits
)
862 enable
= b
| g
| r
| a
;
871 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
875 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
877 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
878 /* TODO: need a software fallback */
880 static void savageDDColorMask_s3d(GLcontext
*ctx
,
881 GLboolean r
, GLboolean g
,
882 GLboolean b
, GLboolean a
)
884 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
887 if (ctx
->Visual
.alphaBits
)
889 enable
= b
| g
| r
| a
;
898 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
902 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
904 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
905 /* TODO: need a software fallback */
908 /* Seperate specular not fully implemented in hardware... Needs
909 * some interaction with material state? Just punt to software
911 * FK: Don't fall back for now. Let's see the failure cases and
912 * fix them the right way. I don't see how this could be a
913 * hardware limitation.
915 static void savageUpdateSpecular_s4(GLcontext
*ctx
) {
916 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
917 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
919 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
920 ctx
->Light
.Enabled
) {
921 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_TRUE
;
922 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
924 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_FALSE
;
925 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
928 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
929 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
931 static void savageUpdateSpecular_s3d(GLcontext
*ctx
) {
932 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
933 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
935 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
936 ctx
->Light
.Enabled
) {
937 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_TRUE
;
938 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
940 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_FALSE
;
941 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
944 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
945 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
948 static void savageDDLightModelfv_s4(GLcontext
*ctx
, GLenum pname
,
949 const GLfloat
*param
)
951 savageUpdateSpecular_s4 (ctx
);
953 static void savageDDLightModelfv_s3d(GLcontext
*ctx
, GLenum pname
,
954 const GLfloat
*param
)
956 savageUpdateSpecular_s3d (ctx
);
959 static void savageDDShadeModel_s4(GLcontext
*ctx
, GLuint mod
)
961 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
962 u_int32_t drawLocalCtrl
= imesa
->regs
.s4
.drawLocalCtrl
.ui
;
964 if (mod
== GL_SMOOTH
)
966 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_FALSE
;
970 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_TRUE
;
973 if (drawLocalCtrl
!= imesa
->regs
.s4
.drawLocalCtrl
.ui
)
974 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
976 static void savageDDShadeModel_s3d(GLcontext
*ctx
, GLuint mod
)
978 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
979 u_int32_t drawCtrl
= imesa
->regs
.s3d
.drawCtrl
.ui
;
981 if (mod
== GL_SMOOTH
)
983 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_FALSE
;
987 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_TRUE
;
990 if (drawCtrl
!= imesa
->regs
.s3d
.drawCtrl
.ui
)
991 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
995 /* =============================================================
997 * The fogCtrl register has the same position and the same layout
998 * on savage3d and savage4. No need for two separate functions.
1001 static void savageDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
1003 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1005 u_int32_t fogCtrl
= imesa
->regs
.s4
.fogCtrl
.ui
;
1007 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
1008 if (ctx
->Fog
.Enabled
)
1010 fogClr
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
1011 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
1012 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
1013 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= GL_TRUE
;
1015 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= GL_TRUE
;
1016 imesa
->regs
.s4
.fogCtrl
.ni
.fogClr
= fogClr
;
1022 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= 0;
1023 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= 0;
1026 if (fogCtrl
!= imesa
->regs
.s4
.fogCtrl
.ui
)
1027 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1031 static void savageDDStencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
1034 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1036 u_int32_t zBufCtrl
= imesa
->regs
.s4
.zBufCtrl
.ui
;
1037 u_int32_t stencilCtrl
= imesa
->regs
.s4
.stencilCtrl
.ui
;
1039 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= ctx
->Stencil
.Ref
[0];
1040 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= ctx
->Stencil
.ValueMask
[0];
1042 switch (ctx
->Stencil
.Function
[0])
1044 case GL_NEVER
: a
= CF_Never
; break;
1045 case GL_ALWAYS
: a
= CF_Always
; break;
1046 case GL_LESS
: a
= CF_Less
; break;
1047 case GL_LEQUAL
: a
= CF_LessEqual
; break;
1048 case GL_EQUAL
: a
= CF_Equal
; break;
1049 case GL_GREATER
: a
= CF_Greater
; break;
1050 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
1051 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
1056 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= a
;
1058 if (zBufCtrl
!= imesa
->regs
.s4
.zBufCtrl
.ui
||
1059 stencilCtrl
!= imesa
->regs
.s4
.stencilCtrl
.ui
)
1060 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1063 static void savageDDStencilMask(GLcontext
*ctx
, GLuint mask
)
1065 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1067 if (imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
!= ctx
->Stencil
.WriteMask
[0]) {
1068 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= ctx
->Stencil
.WriteMask
[0];
1069 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1073 static void savageDDStencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
1076 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1077 u_int32_t stencilCtrl
= imesa
->regs
.s4
.stencilCtrl
.ui
;
1079 switch (ctx
->Stencil
.FailFunc
[0])
1082 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1085 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Zero
;
1088 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Equal
;
1091 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_IncClamp
;
1094 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_DecClamp
;
1097 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Invert
;
1099 case GL_INCR_WRAP_EXT
:
1100 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Inc
;
1102 case GL_DECR_WRAP_EXT
:
1103 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Dec
;
1108 switch (ctx
->Stencil
.ZFailFunc
[0])
1111 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1114 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Zero
;
1117 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Equal
;
1120 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_IncClamp
;
1123 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_DecClamp
;
1126 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Invert
;
1128 case GL_INCR_WRAP_EXT
:
1129 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Inc
;
1131 case GL_DECR_WRAP_EXT
:
1132 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Dec
;
1136 switch (ctx
->Stencil
.ZPassFunc
[0])
1139 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1142 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Zero
;
1145 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Equal
;
1148 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_IncClamp
;
1151 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_DecClamp
;
1154 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Invert
;
1156 case GL_INCR_WRAP_EXT
:
1157 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Inc
;
1159 case GL_DECR_WRAP_EXT
:
1160 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Dec
;
1164 if (stencilCtrl
!= imesa
->regs
.s4
.stencilCtrl
.ui
)
1165 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1169 /* =============================================================
1172 static void savageDDEnable_s4(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1175 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1178 /* we should consider the disable case*/
1179 savageBlendFunc_s4(ctx
);
1182 /*add the savageBlendFunc 2001/11/25
1183 * if call no such function, then glDisable(GL_BLEND) will do noting,
1184 *our chip has no disable bit
1186 savageBlendFunc_s4(ctx
);
1187 case GL_COLOR_LOGIC_OP
:
1189 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1191 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1192 (ctx
->Color
.ColorLogicOpEnabled
&&
1193 ctx
->Color
.LogicOp
!= GL_COPY
));
1196 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
1198 case GL_SCISSOR_TEST
:
1199 savageDDScissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
1200 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
1202 case GL_STENCIL_TEST
:
1203 if (!imesa
->hw_stencil
)
1204 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1206 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= state
;
1207 if (ctx
->Stencil
.Enabled
&&
1208 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
!= GL_TRUE
)
1210 /* Stencil buffer requires Z enabled. */
1211 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
1212 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
1213 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
1215 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
| SAVAGE_UPLOAD_LOCAL
;
1219 savageDDFogfv(ctx
,0,0);
1225 savageDDCullFaceFrontFace(ctx
,0);
1229 imesa
->LcsCullMode
= BCM_None
;
1230 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1237 if ( ctx
->Color
.DitherFlag
)
1239 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_TRUE
;
1242 if (!ctx
->Color
.DitherFlag
)
1244 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_FALSE
;
1246 imesa
->dirty
|= SAVAGE_UPLOAD_GLOBAL
;
1250 savageUpdateSpecular_s4 (ctx
);
1254 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1257 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1263 static void savageDDEnable_s3d(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1266 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1269 /* we should consider the disable case*/
1270 savageBlendFunc_s3d(ctx
);
1273 /*add the savageBlendFunc 2001/11/25
1274 * if call no such function, then glDisable(GL_BLEND) will do noting,
1275 *our chip has no disable bit
1277 savageBlendFunc_s3d(ctx
);
1278 case GL_COLOR_LOGIC_OP
:
1280 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1282 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1283 (ctx
->Color
.ColorLogicOpEnabled
&&
1284 ctx
->Color
.LogicOp
!= GL_COPY
));
1287 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
1289 case GL_SCISSOR_TEST
:
1290 savageDDScissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
1291 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
1293 case GL_STENCIL_TEST
:
1294 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1297 savageDDFogfv(ctx
,0,0);
1303 savageDDCullFaceFrontFace(ctx
,0);
1307 imesa
->LcsCullMode
= BCM_None
;
1308 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1315 if ( ctx
->Color
.DitherFlag
)
1317 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_TRUE
;
1320 if (!ctx
->Color
.DitherFlag
)
1322 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_FALSE
;
1324 imesa
->dirty
|= SAVAGE_UPLOAD_LOCAL
;
1328 savageUpdateSpecular_s3d (ctx
);
1332 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1335 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1342 void savageDDUpdateHwState( GLcontext
*ctx
)
1344 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1346 if (imesa
->new_state
) {
1347 savageFlushVertices(imesa
);
1348 if (imesa
->new_state
& SAVAGE_NEW_TEXTURE
) {
1349 savageUpdateTextureState( ctx
);
1351 if ((imesa
->new_state
& SAVAGE_NEW_CULL
)) {
1352 savageUpdateCull(ctx
);
1354 imesa
->new_state
= 0;
1359 static void savageDDPrintDirty( const char *msg
, GLuint state
)
1361 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s\n",
1363 (unsigned int) state
,
1364 (state
& SAVAGE_UPLOAD_LOCAL
) ? "upload-local, " : "",
1365 (state
& SAVAGE_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1366 (state
& SAVAGE_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1367 (state
& SAVAGE_UPLOAD_FOGTBL
) ? "upload-fogtbl, " : "",
1368 (state
& SAVAGE_UPLOAD_GLOBAL
) ? "upload-global, " : "",
1369 (state
& SAVAGE_UPLOAD_TEXGLOBAL
) ? "upload-texglobal, " : ""
1375 * Check if global registers were changed
1377 static GLboolean
savageGlobalRegChanged (savageContextPtr imesa
,
1378 GLuint first
, GLuint last
) {
1380 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1381 if (((imesa
->oldRegs
.ui
[i
] ^ imesa
->regs
.ui
[i
]) &
1382 imesa
->globalRegMask
.ui
[i
]) != 0)
1387 static void savageEmitOldRegs (savageContextPtr imesa
,
1388 GLuint first
, GLuint last
, GLboolean global
) {
1389 GLuint n
= last
-first
+1;
1390 drm_savage_cmd_header_t
*cmd
= savageAllocCmdBuf(imesa
, n
*4);
1391 cmd
->state
.cmd
= SAVAGE_CMD_STATE
;
1392 cmd
->state
.global
= global
;
1393 cmd
->state
.count
= n
;
1394 cmd
->state
.start
= first
;
1395 memcpy(cmd
+1, &imesa
->oldRegs
.ui
[first
-SAVAGE_FIRST_REG
], n
*4);
1397 static void savageEmitContiguousRegs (savageContextPtr imesa
,
1398 GLuint first
, GLuint last
) {
1400 GLuint n
= last
-first
+1;
1401 drm_savage_cmd_header_t
*cmd
= savageAllocCmdBuf(imesa
, n
*4);
1402 cmd
->state
.cmd
= SAVAGE_CMD_STATE
;
1403 cmd
->state
.global
= savageGlobalRegChanged(imesa
, first
, last
);
1404 cmd
->state
.count
= n
;
1405 cmd
->state
.start
= first
;
1406 memcpy(cmd
+1, &imesa
->regs
.ui
[first
-SAVAGE_FIRST_REG
], n
*4);
1407 /* savageAllocCmdBuf may need to flush the cmd buffer and backup
1408 * the current hardware state. It should see the "old" (current)
1409 * state that has actually been emitted to the hardware. Therefore
1410 * this update is done *after* savageAllocCmdBuf. */
1411 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
)
1412 imesa
->oldRegs
.ui
[i
] = imesa
->regs
.ui
[i
];
1413 if (SAVAGE_DEBUG
& DEBUG_STATE
)
1414 fprintf (stderr
, "Emitting regs 0x%02x-0x%02x\n", first
, last
);
1416 static void savageEmitChangedRegs (savageContextPtr imesa
,
1417 GLuint first
, GLuint last
) {
1418 GLuint i
, firstChanged
;
1419 firstChanged
= SAVAGE_NR_REGS
;
1420 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1421 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1422 if (firstChanged
== SAVAGE_NR_REGS
)
1425 if (firstChanged
!= SAVAGE_NR_REGS
) {
1426 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1427 i
-1+SAVAGE_FIRST_REG
);
1428 firstChanged
= SAVAGE_NR_REGS
;
1432 if (firstChanged
!= SAVAGE_NR_REGS
)
1433 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1436 static void savageEmitChangedRegChunk (savageContextPtr imesa
,
1437 GLuint first
, GLuint last
) {
1439 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1440 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1441 savageEmitContiguousRegs (imesa
, first
, last
);
1446 static void savageUpdateRegister_s4(savageContextPtr imesa
)
1448 /* In case the texture image was changed without changing the
1449 * texture address as well, we need to force emitting the texture
1450 * address in order to flush texture cashes. */
1451 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX0
) &&
1452 imesa
->oldRegs
.s4
.texAddr
[0].ui
== imesa
->regs
.s4
.texAddr
[0].ui
)
1453 imesa
->oldRegs
.s4
.texAddr
[0].ui
= 0xffffffff;
1454 if ((imesa
->dirty
& SAVAGE_UPLOAD_TEX1
) &&
1455 imesa
->oldRegs
.s4
.texAddr
[1].ui
== imesa
->regs
.s4
.texAddr
[1].ui
)
1456 imesa
->oldRegs
.s4
.texAddr
[1].ui
= 0xffffffff;
1458 savageEmitChangedRegs (imesa
, 0x1e, 0x39);
1462 static void savageUpdateRegister_s3d(savageContextPtr imesa
)
1464 /* Some temporary hacks to workaround lockups. Not sure if they are
1465 * still needed. But they work for now. */
1466 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1467 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1469 /* the savage3d uses two contiguous ranges of BCI registers:
1470 * 0x18-0x1c and 0x20-0x38. Some texture registers need to be
1471 * emitted in one chunk or we get some funky rendering errors. */
1472 /* FIXME: watermark registers aren't programmed correctly ATM */
1473 savageEmitChangedRegs (imesa
, 0x18, 0x19);
1474 savageEmitChangedRegChunk (imesa
, 0x1a, 0x1c);
1475 savageEmitChangedRegs (imesa
, 0x20, 0x36);
1481 void savageEmitOldState( savageContextPtr imesa
)
1483 assert(imesa
->cmdBuf
.write
== imesa
->cmdBuf
.base
);
1484 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
1485 savageEmitOldRegs (imesa
, 0x1e, 0x39, GL_TRUE
);
1487 savageEmitOldRegs (imesa
, 0x18, 0x1c, GL_TRUE
);
1488 savageEmitOldRegs (imesa
, 0x20, 0x36, GL_FALSE
);
1493 /* Push the state into the sarea and/or texture memory.
1495 void savageEmitChangedState( savageContextPtr imesa
)
1497 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_API
)
1498 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa
->dirty
);
1502 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_MSG
)
1503 fprintf (stderr
, "... emitting state\n");
1504 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1505 savageUpdateRegister_s4(imesa
);
1507 savageUpdateRegister_s3d(imesa
);
1514 static void savageDDInitState_s4( savageContextPtr imesa
)
1517 imesa
->regs
.s4
.destCtrl
.ui
= 1<<7;
1520 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1521 imesa
->regs
.s4
.zBufCtrl
.ni
.wToZEn
= GL_TRUE
;
1522 if (imesa
->float_depth
) {
1523 imesa
->regs
.s4
.zBufCtrl
.ni
.zExpOffset
=
1524 imesa
->savageScreen
->zpp
== 2 ? 16 : 32;
1525 imesa
->regs
.s4
.zBufCtrl
.ni
.floatZEn
= GL_TRUE
;
1527 imesa
->regs
.s4
.zBufCtrl
.ni
.zExpOffset
= 0;
1528 imesa
->regs
.s4
.zBufCtrl
.ni
.floatZEn
= GL_FALSE
;
1530 imesa
->regs
.s4
.texBlendCtrl
[0].ui
= TBC_NoTexMap
;
1531 imesa
->regs
.s4
.texBlendCtrl
[1].ui
= TBC_NoTexMap1
;
1532 imesa
->regs
.s4
.drawCtrl0
.ui
= 0;
1534 imesa
->regs
.s4
.drawCtrl1
.ni
.xyOffsetEn
= 1;
1537 /* Set DestTexWatermarks_31,30 to 01 always.
1538 *Has no effect if dest. flush is disabled.
1541 imesa
->regs
.s4
.zWatermarks
.ui
= 0x12000C04;
1542 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x40200400;
1544 imesa
->regs
.s4
.zWatermarks
.ui
= 0x16001808;
1545 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x4f000000;
1547 imesa
->regs
.s4
.drawCtrl0
.ni
.dPerfAccelEn
= GL_TRUE
;
1549 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1550 * alpha blending working properly
1553 imesa
->regs
.s4
.texCtrl
[0].ni
.dBias
= 0x08;
1554 imesa
->regs
.s4
.texCtrl
[1].ni
.dBias
= 0x08;
1555 imesa
->regs
.s4
.texCtrl
[0].ni
.texXprEn
= GL_TRUE
;
1556 imesa
->regs
.s4
.texCtrl
[1].ni
.texXprEn
= GL_TRUE
;
1557 imesa
->regs
.s4
.texCtrl
[0].ni
.dMax
= 0x0f;
1558 imesa
->regs
.s4
.texCtrl
[1].ni
.dMax
= 0x0f;
1559 /* programm a valid tex address, in case texture state is emitted
1560 * in wrong order. */
1561 if (imesa
->lastTexHeap
== 2 && imesa
->savageScreen
->textureSize
[1]) {
1562 /* AGP textures available */
1563 imesa
->regs
.s4
.texAddr
[0].ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1564 imesa
->regs
.s4
.texAddr
[1].ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1566 /* no AGP textures available, use local */
1567 imesa
->regs
.s4
.texAddr
[0].ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1568 imesa
->regs
.s4
.texAddr
[1].ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1570 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1571 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
1572 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1573 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1574 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1576 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1577 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
= (
1578 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1579 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1580 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= BCM_None
;
1582 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= 0x00;
1584 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= GL_FALSE
;
1585 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= CF_Always
;
1586 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1587 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1588 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1589 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= 0xff;
1590 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= 0xff;
1592 imesa
->LcsCullMode
=BCM_None
;
1593 imesa
->regs
.s4
.texDescr
.ni
.palSize
= TPS_256
;
1595 /* clear the local registers in the global reg mask */
1596 imesa
->globalRegMask
.s4
.drawLocalCtrl
.ui
= 0;
1597 imesa
->globalRegMask
.s4
.texPalAddr
.ui
= 0;
1598 imesa
->globalRegMask
.s4
.texCtrl
[0].ui
= 0;
1599 imesa
->globalRegMask
.s4
.texCtrl
[1].ui
= 0;
1600 imesa
->globalRegMask
.s4
.texAddr
[0].ui
= 0;
1601 imesa
->globalRegMask
.s4
.texAddr
[1].ui
= 0;
1602 imesa
->globalRegMask
.s4
.texBlendCtrl
[0].ui
= 0;
1603 imesa
->globalRegMask
.s4
.texBlendCtrl
[1].ui
= 0;
1604 imesa
->globalRegMask
.s4
.texXprClr
.ui
= 0;
1605 imesa
->globalRegMask
.s4
.texDescr
.ui
= 0;
1607 static void savageDDInitState_s3d( savageContextPtr imesa
)
1610 imesa
->regs
.s3d
.destCtrl
.ui
= 1<<7;
1613 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1615 imesa
->regs
.s3d
.drawCtrl
.ni
.xyOffsetEn
= 1;
1618 /* Set DestTexWatermarks_31,30 to 01 always.
1619 *Has no effect if dest. flush is disabled.
1622 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x12000C04;
1623 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x40200400;
1625 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x16001808;
1626 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x4f000000;
1629 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1630 * alpha blending working properly
1633 imesa
->regs
.s3d
.texCtrl
.ni
.dBias
= 0x08;
1634 imesa
->regs
.s3d
.texCtrl
.ni
.texXprEn
= GL_TRUE
;
1635 /* programm a valid tex address, in case texture state is emitted
1636 * in wrong order. */
1637 if (imesa
->lastTexHeap
== 2 && imesa
->savageScreen
->textureSize
[1]) {
1638 /* AGP textures available */
1639 imesa
->regs
.s3d
.texAddr
.ui
= imesa
->savageScreen
->textureOffset
[1]|3;
1641 /* no AGP textures available, use local */
1642 imesa
->regs
.s3d
.texAddr
.ui
= imesa
->savageScreen
->textureOffset
[0]|2;
1645 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1646 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1647 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1649 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
1650 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1651 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1653 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
= (
1654 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1655 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1656 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= BCM_None
;
1658 imesa
->LcsCullMode
= BCM_None
;
1659 imesa
->regs
.s3d
.texDescr
.ni
.palSize
= TPS_256
;
1661 /* clear the local registers in the global reg mask */
1662 imesa
->globalRegMask
.s3d
.texPalAddr
.ui
= 0;
1663 imesa
->globalRegMask
.s3d
.texXprClr
.ui
= 0;
1664 imesa
->globalRegMask
.s3d
.texAddr
.ui
= 0;
1665 imesa
->globalRegMask
.s3d
.texDescr
.ui
= 0;
1666 imesa
->globalRegMask
.s3d
.texCtrl
.ui
= 0;
1668 imesa
->globalRegMask
.s3d
.fogCtrl
.ui
= 0;
1670 /* drawCtrl is local with some exceptions */
1671 imesa
->globalRegMask
.s3d
.drawCtrl
.ui
= 0;
1672 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.cullMode
= 0x3;
1673 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= 0x7;
1674 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestEn
= 0x1;
1675 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaRefVal
= 0xff;
1677 /* zBufCtrl is local with some exceptions */
1678 imesa
->globalRegMask
.s3d
.zBufCtrl
.ui
= 0;
1679 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zCmpFunc
= 0x7;
1680 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zBufEn
= 0x1;
1682 void savageDDInitState( savageContextPtr imesa
) {
1683 memset (imesa
->regs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1684 memset (imesa
->globalRegMask
.ui
, 0xff, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1685 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1686 savageDDInitState_s4 (imesa
);
1688 savageDDInitState_s3d (imesa
);
1690 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1691 /* zbufoffset and destctrl have the same position and layout on
1692 * savage4 and savage3d. */
1693 if (imesa
->glCtx
->Visual
.doubleBufferMode
) {
1694 imesa
->IsDouble
= GL_TRUE
;
1695 imesa
->toggle
= TARGET_BACK
;
1696 imesa
->regs
.s4
.destCtrl
.ni
.offset
=
1697 imesa
->savageScreen
->backOffset
>>11;
1699 imesa
->IsDouble
= GL_FALSE
;
1700 imesa
->toggle
= TARGET_FRONT
;
1701 imesa
->regs
.s4
.destCtrl
.ni
.offset
=
1702 imesa
->savageScreen
->frontOffset
>>11;
1704 if(imesa
->savageScreen
->cpp
== 2) {
1705 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 0;
1706 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1707 (imesa
->savageScreen
->width
+63)>>6;
1709 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 1;
1710 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1711 (imesa
->savageScreen
->width
+31)>>5;
1713 imesa
->drawMap
= imesa
->apertureBase
[imesa
->toggle
];
1714 imesa
->readMap
= imesa
->apertureBase
[imesa
->toggle
];
1715 imesa
->NotFirstFrame
= GL_FALSE
;
1717 imesa
->regs
.s4
.zBufOffset
.ni
.offset
=imesa
->savageScreen
->depthOffset
>>11;
1718 if(imesa
->savageScreen
->zpp
== 2) {
1719 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1720 (imesa
->savageScreen
->width
+63)>>6;
1721 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 0;
1723 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1724 (imesa
->savageScreen
->width
+31)>>5;
1725 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 1;
1728 memcpy (imesa
->oldRegs
.ui
, imesa
->regs
.ui
, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1730 /* Emit the initial state to the (empty) command buffer. */
1731 assert (imesa
->cmdBuf
.write
== imesa
->cmdBuf
.base
);
1732 savageEmitOldState(imesa
);
1733 imesa
->cmdBuf
.start
= imesa
->cmdBuf
.write
;
1737 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1738 NEW_TEXTURE_MATRIX|\
1739 NEW_USER_CLIP|NEW_CLIENT_STATE))
1741 static void savageDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1743 _swrast_InvalidateState( ctx
, new_state
);
1744 _swsetup_InvalidateState( ctx
, new_state
);
1745 _ac_InvalidateState( ctx
, new_state
);
1746 _tnl_InvalidateState( ctx
, new_state
);
1747 SAVAGE_CONTEXT(ctx
)->new_gl_state
|= new_state
;
1751 void savageDDInitStateFuncs(GLcontext
*ctx
)
1753 ctx
->Driver
.UpdateState
= savageDDInvalidateState
;
1754 ctx
->Driver
.BlendEquationSeparate
= savageDDBlendEquationSeparate
;
1755 ctx
->Driver
.Fogfv
= savageDDFogfv
;
1756 ctx
->Driver
.Scissor
= savageDDScissor
;
1758 ctx
->Driver
.CullFace
= savageDDCullFaceFrontFace
;
1759 ctx
->Driver
.FrontFace
= savageDDCullFaceFrontFace
;
1761 ctx
->Driver
.CullFace
= 0;
1762 ctx
->Driver
.FrontFace
= 0;
1763 #endif /* end #if HW_CULL */
1764 ctx
->Driver
.PolygonMode
=NULL
;
1765 ctx
->Driver
.PolygonStipple
= 0;
1766 ctx
->Driver
.LineStipple
= 0;
1767 ctx
->Driver
.LineWidth
= 0;
1768 ctx
->Driver
.LogicOpcode
= 0;
1769 ctx
->Driver
.DrawBuffer
= savageDDDrawBuffer
;
1770 ctx
->Driver
.ReadBuffer
= savageDDReadBuffer
;
1771 ctx
->Driver
.ClearColor
= savageDDClearColor
;
1773 ctx
->Driver
.DepthRange
= savageDepthRange
;
1774 ctx
->Driver
.Viewport
= savageViewport
;
1775 ctx
->Driver
.RenderMode
= savageRenderMode
;
1777 ctx
->Driver
.ClearIndex
= 0;
1778 ctx
->Driver
.IndexMask
= 0;
1780 if (SAVAGE_CONTEXT( ctx
)->savageScreen
->chipset
>= S3_SAVAGE4
) {
1781 ctx
->Driver
.Enable
= savageDDEnable_s4
;
1782 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s4
;
1783 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s4
;
1784 ctx
->Driver
.DepthMask
= savageDDDepthMask_s4
;
1785 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s4
;
1786 ctx
->Driver
.ColorMask
= savageDDColorMask_s4
;
1787 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s4
;
1788 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s4
;
1789 ctx
->Driver
.StencilFunc
= savageDDStencilFunc
;
1790 ctx
->Driver
.StencilMask
= savageDDStencilMask
;
1791 ctx
->Driver
.StencilOp
= savageDDStencilOp
;
1793 ctx
->Driver
.Enable
= savageDDEnable_s3d
;
1794 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s3d
;
1795 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s3d
;
1796 ctx
->Driver
.DepthMask
= savageDDDepthMask_s3d
;
1797 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s3d
;
1798 ctx
->Driver
.ColorMask
= savageDDColorMask_s3d
;
1799 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s3d
;
1800 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s3d
;
1801 ctx
->Driver
.StencilFunc
= 0;
1802 ctx
->Driver
.StencilMask
= 0;
1803 ctx
->Driver
.StencilOp
= 0;
1806 /* Swrast hooks for imaging extensions:
1808 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1809 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1810 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1811 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;