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.
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"
44 #include "array_cache/acache.h"
46 #include "swrast_setup/swrast_setup.h"
48 static void savageBlendFunc_s4(GLcontext
*);
49 static void savageBlendFunc_s3d(GLcontext
*);
51 static __inline__ GLuint
savagePackColor(GLuint format
,
57 return SAVAGEPACKCOLOR8888(r
,g
,b
,a
);
59 return SAVAGEPACKCOLOR565(r
,g
,b
);
67 static void savageDDAlphaFunc_s4(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
69 /* This can be done in BlendFunc*/
70 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
71 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
72 savageBlendFunc_s4(ctx
);
74 static void savageDDAlphaFunc_s3d(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
76 /* This can be done in BlendFunc*/
77 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
78 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
79 savageBlendFunc_s3d(ctx
);
82 static void savageDDBlendEquationSeparate(GLcontext
*ctx
,
83 GLenum modeRGB
, GLenum modeA
)
85 assert( modeRGB
== modeA
);
87 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
90 FALLBACK( ctx
, SAVAGE_FALLBACK_LOGICOP
,
91 (ctx
->Color
.ColorLogicOpEnabled
&&
92 ctx
->Color
.LogicOp
!= GL_COPY
));
94 /* Can only do blend addition, not min, max, subtract, etc. */
95 FALLBACK( ctx
, SAVAGE_FALLBACK_BLEND_EQ
,
96 modeRGB
!= GL_FUNC_ADD
);
100 static void savageBlendFunc_s4(GLcontext
*ctx
)
102 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
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
= LCS_A_NEVER
; break;
240 case GL_ALWAYS
: a
= LCS_A_ALWAYS
; break;
241 case GL_LESS
: a
= LCS_A_LESS
; break;
242 case GL_LEQUAL
: a
= LCS_A_LEQUAL
; break;
243 case GL_EQUAL
: a
= LCS_A_EQUAL
; break;
244 case GL_GREATER
: a
= LCS_A_GREATER
; break;
245 case GL_GEQUAL
: a
= LCS_A_GEQUAL
; break;
246 case GL_NOTEQUAL
: a
= LCS_A_NOTEQUAL
; break;
250 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_TRUE
;
251 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestCmpFunc
= a
& 0x0F;
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 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
268 static void savageBlendFunc_s3d(GLcontext
*ctx
)
270 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
272 /* set up draw control register (including blending, alpha
273 * test, dithering, and shading model)
276 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= 0;
281 if(ctx
->Color
.BlendEnabled
){
282 switch (ctx
->Color
.BlendDstRGB
)
285 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
289 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
290 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
294 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
295 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
298 case GL_ONE_MINUS_SRC_COLOR
:
299 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
300 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
304 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
305 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
308 case GL_ONE_MINUS_SRC_ALPHA
:
309 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
310 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
314 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
316 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
320 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
322 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
325 case GL_ONE_MINUS_DST_ALPHA
:
326 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
328 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
332 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1DstAlpha
;
333 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
338 switch (ctx
->Color
.BlendSrcRGB
)
341 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
345 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
349 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
350 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
353 case GL_ONE_MINUS_DST_COLOR
:
354 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
355 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
359 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
362 case GL_ONE_MINUS_SRC_ALPHA
:
363 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
367 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
369 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
373 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
374 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
378 case GL_ONE_MINUS_DST_ALPHA
:
379 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
381 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
385 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstAlpha
;
386 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
393 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
394 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
399 if(ctx
->Color
.AlphaEnabled
)
404 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
406 switch(ctx
->Color
.AlphaFunc
) {
407 case GL_NEVER
: a
= LCS_A_NEVER
; break;
408 case GL_ALWAYS
: a
= LCS_A_ALWAYS
; break;
409 case GL_LESS
: a
= LCS_A_LESS
; break;
410 case GL_LEQUAL
: a
= LCS_A_LEQUAL
; break;
411 case GL_EQUAL
: a
= LCS_A_EQUAL
; break;
412 case GL_GREATER
: a
= LCS_A_GREATER
; break;
413 case GL_GEQUAL
: a
= LCS_A_GEQUAL
; break;
414 case GL_NOTEQUAL
: a
= LCS_A_NOTEQUAL
; break;
418 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_TRUE
;
419 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= a
& 0x07;
420 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaRefVal
= alphaRef
;
424 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_FALSE
;
427 /* Set/Reset Z-after-alpha*/
429 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
=
430 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
;
432 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
435 static void savageDDBlendFuncSeparate_s4( GLcontext
*ctx
, GLenum sfactorRGB
,
436 GLenum dfactorRGB
, GLenum sfactorA
,
439 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
440 savageBlendFunc_s4( ctx
);
442 static void savageDDBlendFuncSeparate_s3d( GLcontext
*ctx
, GLenum sfactorRGB
,
443 GLenum dfactorRGB
, GLenum sfactorA
,
446 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
447 savageBlendFunc_s3d( ctx
);
452 static void savageDDDepthFunc_s4(GLcontext
*ctx
, GLenum func
)
454 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
458 /* set up z-buffer control register (global)
459 * set up z-buffer offset register (global)
460 * set up z read/write watermarks register (global)
464 case GL_NEVER
: zmode
= LCS_Z_NEVER
; break;
465 case GL_ALWAYS
: zmode
= LCS_Z_ALWAYS
; break;
466 case GL_LESS
: zmode
= LCS_Z_LESS
; break;
467 case GL_LEQUAL
: zmode
= LCS_Z_LEQUAL
; break;
468 case GL_EQUAL
: zmode
= LCS_Z_EQUAL
; break;
469 case GL_GREATER
: zmode
= LCS_Z_GREATER
; break;
470 case GL_GEQUAL
: zmode
= LCS_Z_GEQUAL
; break;
471 case GL_NOTEQUAL
: zmode
= LCS_Z_NOTEQUAL
; break;
477 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= zmode
& 0x0F;
478 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
479 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
481 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 0;
484 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
486 else if (imesa
->glCtx
->Stencil
.Enabled
&&
487 !imesa
->glCtx
->DrawBuffer
->UseSoftwareStencilBuffer
)
489 #define STENCIL (0x27)
491 /* by Jiayo, tempory disable HW stencil in 24 bpp */
493 if(imesa
->hw_stencil
)
495 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= LCS_Z_ALWAYS
& 0x0F;
496 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
497 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
498 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
499 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 8;
501 #endif /* end #if HW_STENCIL */
506 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
== GL_FALSE
)
508 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= LCS_Z_ALWAYS
& 0x0F;
509 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
513 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
515 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
517 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
518 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
519 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 8;
522 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
524 static void savageDDDepthFunc_s3d(GLcontext
*ctx
, GLenum func
)
526 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
530 /* set up z-buffer control register (global)
531 * set up z-buffer offset register (global)
532 * set up z read/write watermarks register (global)
535 case GL_NEVER
: zmode
= LCS_Z_NEVER
; break;
536 case GL_ALWAYS
: zmode
= LCS_Z_ALWAYS
; break;
537 case GL_LESS
: zmode
= LCS_Z_LESS
; break;
538 case GL_LEQUAL
: zmode
= LCS_Z_LEQUAL
; break;
539 case GL_EQUAL
: zmode
= LCS_Z_EQUAL
; break;
540 case GL_GREATER
: zmode
= LCS_Z_GREATER
; break;
541 case GL_GEQUAL
: zmode
= LCS_Z_GEQUAL
; break;
542 case GL_NOTEQUAL
: zmode
= LCS_Z_NOTEQUAL
; break;
547 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
548 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= zmode
& 0x0F;
549 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
551 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
553 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 0;
558 if (imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
== GL_FALSE
) {
559 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= LCS_Z_ALWAYS
& 0x0F;
560 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
564 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
566 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
568 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_FALSE
;
569 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
570 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 8;
573 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
576 static void savageDDDepthMask_s4(GLcontext
*ctx
, GLboolean flag
)
578 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
580 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
583 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
587 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
589 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
591 static void savageDDDepthMask_s3d(GLcontext
*ctx
, GLboolean flag
)
593 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
595 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
598 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
602 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
604 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
610 /* =============================================================
615 static void savageDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
616 GLsizei w
, GLsizei h
)
618 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
619 imesa
->scissor_rect
.x1
= MAX2(imesa
->drawX
+x
,imesa
->draw_rect
.x1
);
620 imesa
->scissor_rect
.y1
= MAX2(imesa
->drawY
+imesa
->driDrawable
->h
-(y
+h
),
621 imesa
->draw_rect
.y1
);
622 imesa
->scissor_rect
.x2
= MIN2(imesa
->drawX
+x
+w
,imesa
->draw_rect
.x2
);
623 imesa
->scissor_rect
.y2
= MIN2(imesa
->drawY
+imesa
->driDrawable
->h
- y
,
624 imesa
->draw_rect
.y2
);
627 imesa
->scissorChanged
=GL_TRUE
;
629 imesa
->dirty
|= SAVAGE_UPLOAD_CLIPRECTS
;
634 static void savageDDDrawBuffer(GLcontext
*ctx
, GLenum mode
)
636 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
639 * _DrawDestMask is easier to cope with than <mode>.
641 switch ( ctx
->Color
._DrawDestMask
) {
643 imesa
->IsDouble
= GL_FALSE
;
645 if(imesa
->IsFullScreen
)
647 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_FRONT
];
648 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_FRONT
];
652 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
653 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
655 imesa
->NotFirstFrame
= GL_FALSE
;
656 imesa
->dirty
|= SAVAGE_UPLOAD_BUFFERS
;
657 savageXMesaSetFrontClipRects( imesa
);
658 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
661 imesa
->IsDouble
= GL_TRUE
;
662 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
663 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
664 imesa
->NotFirstFrame
= GL_FALSE
;
665 imesa
->dirty
|= SAVAGE_UPLOAD_BUFFERS
;
666 savageXMesaSetBackClipRects( imesa
);
667 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
670 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
674 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
677 _swrast_DrawBuffer(ctx
, mode
);
680 static void savageDDReadBuffer(GLcontext
*ctx
, GLenum mode
)
682 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
686 static void savageDDSetColor(GLcontext
*ctx
,
687 GLubyte r
, GLubyte g
,
688 GLubyte b
, GLubyte a
)
690 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
691 imesa
->MonoColor
= savagePackColor( imesa
->savageScreen
->frontFormat
, r
, g
, b
, a
);
695 /* =============================================================
696 * Window position and viewport transformation
699 static void savageCalcViewport( GLcontext
*ctx
)
701 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
702 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
703 GLfloat
*m
= imesa
->hw_viewport
;
705 /* See also mga_translate_vertex.
707 m
[MAT_SX
] = v
[MAT_SX
];
708 m
[MAT_TX
] = v
[MAT_TX
] + imesa
->drawX
+ SUBPIXEL_X
;
709 m
[MAT_SY
] = - v
[MAT_SY
];
710 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ imesa
->drawY
+ SUBPIXEL_Y
;
711 m
[MAT_SZ
] = v
[MAT_SZ
] * imesa
->depth_scale
;
712 m
[MAT_TZ
] = v
[MAT_TZ
] * imesa
->depth_scale
;
714 imesa
->SetupNewInputs
= ~0;
717 static void savageViewport( GLcontext
*ctx
,
719 GLsizei width
, GLsizei height
)
721 savageCalcViewport( ctx
);
724 static void savageDepthRange( GLcontext
*ctx
,
725 GLclampd nearval
, GLclampd farval
)
727 savageCalcViewport( ctx
);
731 /* =============================================================
735 static void savageDDClearColor(GLcontext
*ctx
,
736 const GLfloat color
[4] )
738 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
740 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
741 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
742 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
743 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
745 imesa
->ClearColor
= savagePackColor( imesa
->savageScreen
->frontFormat
,
746 c
[0], c
[1], c
[2], c
[3] );
749 /* Fallback to swrast for select and feedback.
751 static void savageRenderMode( GLcontext
*ctx
, GLenum mode
)
753 FALLBACK( ctx
, SAVAGE_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
759 /* =============================================================
760 * Culling - the savage isn't quite as clean here as the rest of
761 * its interfaces, but it's not bad.
763 static void savageDDCullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
765 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
766 GLuint cullMode
=imesa
->LcsCullMode
;
767 switch (ctx
->Polygon
.CullFaceMode
)
770 switch (ctx
->Polygon
.FrontFace
)
782 switch (ctx
->Polygon
.FrontFace
)
793 imesa
->LcsCullMode
= cullMode
;
795 #endif /* end #if HW_CULL */
797 static void savageUpdateCull( GLcontext
*ctx
)
800 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
802 if (ctx
->Polygon
.CullFlag
&&
803 imesa
->raster_primitive
== GL_TRIANGLES
&&
804 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
805 cullMode
= imesa
->LcsCullMode
;
808 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
809 if (imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
!= cullMode
) {
810 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= cullMode
;
811 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
814 if (imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
!= cullMode
) {
815 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= cullMode
;
816 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
819 #endif /* end #if HW_CULL */
824 /* =============================================================
828 /* Mesa calls this from the wrong place - it is called a very large
829 * number of redundant times.
831 * Colormask can be simulated by multipass or multitexture techniques.
833 static void savageDDColorMask_s4(GLcontext
*ctx
,
834 GLboolean r
, GLboolean g
,
835 GLboolean b
, GLboolean a
)
837 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
840 if (ctx
->Visual
.alphaBits
)
842 enable
= b
| g
| r
| a
;
851 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
855 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
857 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
858 /* TODO: need a software fallback */
860 static void savageDDColorMask_s3d(GLcontext
*ctx
,
861 GLboolean r
, GLboolean g
,
862 GLboolean b
, GLboolean a
)
864 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
867 if (ctx
->Visual
.alphaBits
)
869 enable
= b
| g
| r
| a
;
878 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
882 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
884 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
885 /* TODO: need a software fallback */
888 /* Seperate specular not fully implemented in hardware... Needs
889 * some interaction with material state? Just punt to software
891 * FK: Don't fall back for now. Let's see the failure cases and
892 * fix them the right way. I don't see how this could be a
893 * hardware limitation.
895 static void savageUpdateSpecular_s4(GLcontext
*ctx
) {
896 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
898 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
899 ctx
->Light
.Enabled
) {
900 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_TRUE
;
901 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
903 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_FALSE
;
904 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
906 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
908 static void savageUpdateSpecular_s3d(GLcontext
*ctx
) {
909 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
911 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
912 ctx
->Light
.Enabled
) {
913 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_TRUE
;
914 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
916 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_FALSE
;
917 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
919 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
922 static void savageDDLightModelfv_s4(GLcontext
*ctx
, GLenum pname
,
923 const GLfloat
*param
)
925 savageUpdateSpecular_s4 (ctx
);
927 static void savageDDLightModelfv_s3d(GLcontext
*ctx
, GLenum pname
,
928 const GLfloat
*param
)
930 savageUpdateSpecular_s3d (ctx
);
933 static void savageDDShadeModel_s4(GLcontext
*ctx
, GLuint mod
)
935 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
937 if (mod
== GL_SMOOTH
)
939 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_FALSE
;
943 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_TRUE
;
945 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
947 static void savageDDShadeModel_s3d(GLcontext
*ctx
, GLuint mod
)
949 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
951 if (mod
== GL_SMOOTH
)
953 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_FALSE
;
957 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_TRUE
;
959 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
963 /* =============================================================
965 * The fogCtrl register has the same position and the same layout
966 * on savage3d and savage4. No need for two separate functions.
969 static void savageDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
971 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
974 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
975 if (ctx
->Fog
.Enabled
)
977 fogClr
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
978 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
979 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
980 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= GL_TRUE
;
982 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= GL_TRUE
;
983 imesa
->regs
.s4
.fogCtrl
.ni
.fogClr
= fogClr
;
989 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= 0;
990 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= 0;
992 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
997 static void savageStencilFunc(GLcontext
*);
999 static void savageDDStencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
1002 savageStencilFunc(ctx
);
1005 static void savageDDStencilMask(GLcontext
*ctx
, GLuint mask
)
1007 savageStencilFunc(ctx
);
1010 static void savageDDStencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
1013 savageStencilFunc(ctx
);
1016 static void savageStencilFunc(GLcontext
*ctx
)
1018 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1021 if (ctx
->Stencil
.Enabled
)
1023 imesa
->regs
.s4
.stencilCtrl
.ui
= 0x0;
1025 switch (ctx
->Stencil
.Function
[0])
1027 case GL_NEVER
: a
= LCS_S_NEVER
; break;
1028 case GL_ALWAYS
: a
= LCS_S_ALWAYS
; break;
1029 case GL_LESS
: a
= LCS_S_LESS
; break;
1030 case GL_LEQUAL
: a
= LCS_S_LEQUAL
; break;
1031 case GL_EQUAL
: a
= LCS_S_EQUAL
; break;
1032 case GL_GREATER
: a
= LCS_S_GREATER
; break;
1033 case GL_GEQUAL
: a
= LCS_S_GEQUAL
; break;
1034 case GL_NOTEQUAL
: a
= LCS_S_NOTEQUAL
; break;
1039 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= (GLuint
)a
& 0x0F;
1040 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= GL_TRUE
;
1041 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= ctx
->Stencil
.ValueMask
[0];
1042 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= ctx
->Stencil
.WriteMask
[0];
1044 switch (ctx
->Stencil
.FailFunc
[0])
1047 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1050 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Zero
;
1053 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Equal
;
1056 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_IncClamp
;
1059 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_DecClamp
;
1062 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Invert
;
1064 #if GL_EXT_stencil_wrap
1065 case GL_INCR_WRAP_EXT
:
1066 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Inc
;
1068 case GL_DECR_WRAP_EXT
:
1069 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Dec
;
1074 switch (ctx
->Stencil
.ZFailFunc
[0])
1077 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1080 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Zero
;
1083 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Equal
;
1086 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_IncClamp
;
1089 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_DecClamp
;
1092 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Invert
;
1094 #if GL_EXT_stencil_wrap
1095 case GL_INCR_WRAP_EXT
:
1096 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Inc
;
1098 case GL_DECR_WRAP_EXT
:
1099 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Dec
;
1104 switch (ctx
->Stencil
.ZPassFunc
[0])
1107 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1110 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Zero
;
1113 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Equal
;
1116 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_IncClamp
;
1119 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_DecClamp
;
1122 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Invert
;
1124 #if GL_EXT_stencil_wrap
1125 case GL_INCR_WRAP_EXT
:
1126 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Inc
;
1128 case GL_DECR_WRAP_EXT
:
1129 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Dec
;
1135 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= ctx
->Stencil
.Ref
[0];
1138 * force Z on, HW limitation
1141 if (imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
!= GL_TRUE
)
1143 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= LCS_Z_ALWAYS
& 0x0F;
1144 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
1145 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
1150 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= GL_FALSE
;
1152 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1154 #endif /* end #if HW_STENCIL */
1155 /* =============================================================
1158 static void savageDDEnable_s4(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1161 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1164 /* we should consider the disable case*/
1165 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1166 savageBlendFunc_s4(ctx
);
1169 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1170 /*Can't find Enable bit in the 3D registers.*/
1171 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1173 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1174 (ctx
->Color
.ColorLogicOpEnabled
&&
1175 ctx
->Color
.LogicOp
!= GL_COPY
));
1176 /*add the savageBlendFunc 2001/11/25
1177 * if call no such function, then glDisable(GL_BLEND) will do noting,
1178 *our chip has no disable bit
1180 savageBlendFunc_s4(ctx
);
1183 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1184 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
1186 case GL_SCISSOR_TEST
:
1187 imesa
->scissor
= state
;
1188 imesa
->dirty
|= SAVAGE_UPLOAD_CLIPRECTS
;
1190 case GL_STENCIL_TEST
:
1191 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1192 if (!imesa
->hw_stencil
)
1193 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1196 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
=
1197 state
? GL_TRUE
: GL_FALSE
;
1201 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1202 savageDDFogfv(ctx
,0,0);
1208 savageDDCullFaceFrontFace(ctx
,0);
1212 imesa
->LcsCullMode
= BCM_None
;
1217 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1220 if ( ctx
->Color
.DitherFlag
)
1222 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_TRUE
;
1225 if (!ctx
->Color
.DitherFlag
)
1227 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_FALSE
;
1232 savageUpdateSpecular_s4 (ctx
);
1236 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1239 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1245 static void savageDDEnable_s3d(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1248 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1251 /* we should consider the disable case*/
1252 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1253 savageBlendFunc_s3d(ctx
);
1256 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1257 /*Can't find Enable bit in the 3D registers.*/
1258 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1260 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1261 (ctx
->Color
.ColorLogicOpEnabled
&&
1262 ctx
->Color
.LogicOp
!= GL_COPY
));
1263 /*add the savageBlendFunc 2001/11/25
1264 * if call no such function, then glDisable(GL_BLEND) will do noting,
1265 *our chip has no disable bit
1267 savageBlendFunc_s3d(ctx
);
1270 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1271 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
1273 case GL_SCISSOR_TEST
:
1274 imesa
->scissor
= state
;
1275 imesa
->dirty
|= SAVAGE_UPLOAD_CLIPRECTS
;
1277 case GL_STENCIL_TEST
:
1278 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1281 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1282 savageDDFogfv(ctx
,0,0);
1288 savageDDCullFaceFrontFace(ctx
,0);
1292 imesa
->LcsCullMode
= BCM_None
;
1297 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1300 if ( ctx
->Color
.DitherFlag
)
1302 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_TRUE
;
1305 if (!ctx
->Color
.DitherFlag
)
1307 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_FALSE
;
1312 savageUpdateSpecular_s3d (ctx
);
1316 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1319 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1326 void savageDDUpdateHwState( GLcontext
*ctx
)
1328 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1330 if(imesa
->driDrawable
)
1332 LOCK_HARDWARE(imesa
);
1335 if (imesa
->new_state
& SAVAGE_NEW_TEXTURE
) {
1336 savageUpdateTextureState( ctx
);
1338 if((imesa
->dirty
!=0)|| (imesa
->new_state
!=0))
1340 savageEmitHwStateLocked(imesa
);
1341 imesa
->new_state
= 0;
1343 if(imesa
->driDrawable
)
1345 UNLOCK_HARDWARE(imesa
);
1350 void savageEmitDrawingRectangle( savageContextPtr imesa
)
1352 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1353 savageScreenPrivate
*savageScreen
= imesa
->savageScreen
;
1354 XF86DRIClipRectPtr pbox
;
1358 int x0
= imesa
->drawX
;
1359 int y0
= imesa
->drawY
;
1360 int x1
= x0
+ dPriv
->w
;
1361 int y1
= y0
+ dPriv
->h
;
1363 pbox
= dPriv
->pClipRects
;
1364 nbox
= dPriv
->numClipRects
;
1368 /* Coordinate origin of the window - may be offscreen.
1370 /* imesa->BufferSetup[SAVAGE_DESTREG_DR4] = ((y0<<16) |
1371 (((unsigned)x0)&0xFFFF));*/
1377 if (x1
> savageScreen
->width
) x1
= savageScreen
->width
;
1378 if (y1
> savageScreen
->height
) y1
= savageScreen
->height
;
1383 imesa
->draw_rect
.x1
= MAX2(x0
,pbox
->x1
);
1384 imesa
->draw_rect
.y1
= MAX2(y0
,pbox
->y1
);
1385 imesa
->draw_rect
.x2
= MIN2(x1
,pbox
->x2
);
1386 imesa
->draw_rect
.y2
= MIN2(y1
,pbox
->y2
);
1390 imesa
->draw_rect
.x1
= x0
;
1391 imesa
->draw_rect
.y1
= y0
;
1392 imesa
->draw_rect
.x2
= x1
;
1393 imesa
->draw_rect
.y2
= y1
;
1396 imesa
->scissorChanged
= GL_TRUE
;
1398 /* imesa->regs.ni.changed.ni.fDrawCtrl0Changed=GL_TRUE;
1399 imesa->regs.ni.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/
1402 imesa
->dirty
|= SAVAGE_UPLOAD_BUFFERS
;
1406 static void savageDDPrintDirty( const char *msg
, GLuint state
)
1408 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s\n",
1410 (unsigned int) state
,
1411 (state
& SAVAGE_UPLOAD_TEX0IMAGE
) ? "upload-tex0, " : "",
1412 (state
& SAVAGE_UPLOAD_TEX1IMAGE
) ? "upload-tex1, " : "",
1413 (state
& SAVAGE_UPLOAD_CTX
) ? "upload-ctx, " : "",
1414 (state
& SAVAGE_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1415 (state
& SAVAGE_UPLOAD_CLIPRECTS
) ? "upload-cliprects, " : ""
1421 * Check if global registers were changed
1423 static GLboolean
savageGlobalRegChanged (savageContextPtr imesa
,
1424 GLuint first
, GLuint last
) {
1426 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1427 if (((imesa
->oldRegs
.ui
[i
] ^ imesa
->regs
.ui
[i
]) &
1428 imesa
->globalRegMask
.ui
[i
]) != 0)
1433 static void savageEmitContiguousRegs (savageContextPtr imesa
,
1434 GLuint first
, GLuint last
) {
1437 pBCIBase
= savageDMAAlloc (imesa
, last
- first
+ 2);
1438 WRITE_CMD (pBCIBase
, SET_REGISTER(first
, last
- first
+ 1), uint32_t);
1440 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1441 WRITE_CMD (pBCIBase
, imesa
->regs
.ui
[i
], uint32_t);
1442 imesa
->oldRegs
.ui
[i
] = imesa
->regs
.ui
[i
];
1444 savageDMACommit (imesa
, pBCIBase
);
1446 static void savageEmitChangedRegs (savageContextPtr imesa
,
1447 GLuint first
, GLuint last
) {
1448 GLuint i
, firstChanged
;
1449 firstChanged
= SAVAGE_NR_REGS
;
1450 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1451 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1452 if (firstChanged
== SAVAGE_NR_REGS
)
1455 if (firstChanged
!= SAVAGE_NR_REGS
) {
1456 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1457 i
-1+SAVAGE_FIRST_REG
);
1458 firstChanged
= SAVAGE_NR_REGS
;
1462 if (firstChanged
!= SAVAGE_NR_REGS
)
1463 savageEmitContiguousRegs (imesa
, firstChanged
+SAVAGE_FIRST_REG
,
1466 static void savageEmitChangedRegChunk (savageContextPtr imesa
,
1467 GLuint first
, GLuint last
) {
1469 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1470 if (imesa
->oldRegs
.ui
[i
] != imesa
->regs
.ui
[i
]) {
1471 savageEmitContiguousRegs (imesa
, first
, last
);
1476 static void savageUpdateRegister_s4(savageContextPtr imesa
)
1481 * Scissors updates drawctrl0 and drawctrl 1
1483 if (imesa
->scissorChanged
)
1487 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorXStart
= imesa
->scissor_rect
.x1
;
1488 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorYStart
= imesa
->scissor_rect
.y1
;
1489 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorXEnd
= imesa
->scissor_rect
.x2
-1;
1490 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorYEnd
= imesa
->scissor_rect
.y2
-1;
1494 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorXStart
= imesa
->draw_rect
.x1
;
1495 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorYStart
= imesa
->draw_rect
.y1
;
1496 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorXEnd
= imesa
->draw_rect
.x2
-1;
1497 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorYEnd
= imesa
->draw_rect
.y2
-1;
1501 /* the savage4 uses the contiguous range of BCI registers 0x1e-0x39
1502 * 0x1e-0x27 are local, no need to check them for global changes */
1503 if (imesa
->lostContext
|| savageGlobalRegChanged (imesa
, 0x28, 0x39)) {
1504 pBCIBase
= savageDMAAlloc (imesa
, 1);
1505 WRITE_CMD (pBCIBase
, WAIT_3D_IDLE
, uint32_t);
1506 savageDMACommit (imesa
, pBCIBase
);
1508 if (imesa
->lostContext
)
1509 savageEmitContiguousRegs (imesa
, 0x1e, 0x39);
1511 savageEmitChangedRegs (imesa
, 0x1e, 0x39);
1514 imesa
->lostContext
= GL_FALSE
;
1516 static void savageUpdateRegister_s3d(savageContextPtr imesa
)
1520 if (imesa
->scissorChanged
)
1524 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorXStart
=
1525 imesa
->scissor_rect
.x1
;
1526 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorYStart
=
1527 imesa
->scissor_rect
.y1
;
1528 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorXEnd
=
1529 imesa
->scissor_rect
.x2
-1;
1530 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorYEnd
=
1531 imesa
->scissor_rect
.y2
-1;
1535 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorXStart
=
1536 imesa
->draw_rect
.x1
;
1537 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorYStart
=
1538 imesa
->draw_rect
.y1
;
1539 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorXEnd
=
1540 imesa
->draw_rect
.x2
-1;
1541 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorYEnd
=
1542 imesa
->draw_rect
.y2
-1;
1546 /* Some temporary hacks to workaround lockups. Not sure if they are
1547 * still needed. But they work for now. */
1548 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1549 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1551 /* the savage3d uses two contiguous ranges of BCI registers:
1552 * 0x18-0x1c and 0x20-0x38. The first range is local. */
1553 if (imesa
->lostContext
|| savageGlobalRegChanged (imesa
, 0x20, 0x38)) {
1554 pBCIBase
= savageDMAAlloc (imesa
, 1);
1555 WRITE_CMD (pBCIBase
, WAIT_3D_IDLE
, uint32_t);
1556 savageDMACommit (imesa
, pBCIBase
);
1558 /* FIXME: watermark registers aren't programmed correctly ATM */
1559 if (imesa
->lostContext
) {
1560 savageEmitContiguousRegs (imesa
, 0x18, 0x1c);
1561 savageEmitContiguousRegs (imesa
, 0x20, 0x36);
1563 /* On the Savage IX texture registers (at least some of them)
1564 * have to be emitted as one chunk. */
1565 savageEmitChangedRegs (imesa
, 0x18, 0x19);
1566 savageEmitChangedRegChunk (imesa
, 0x1a, 0x1c);
1567 savageEmitChangedRegs (imesa
, 0x20, 0x36);
1571 imesa
->lostContext
= GL_FALSE
;
1576 /* Push the state into the sarea and/or texture memory.
1578 void savageEmitHwStateLocked( savageContextPtr imesa
)
1580 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_API
)
1581 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa
->dirty
);
1583 if (imesa
->dirty
& ~SAVAGE_UPLOAD_CLIPRECTS
)
1585 if (imesa
->dirty
& (SAVAGE_UPLOAD_CTX
| SAVAGE_UPLOAD_TEX0
| \
1586 SAVAGE_UPLOAD_TEX1
| SAVAGE_UPLOAD_BUFFERS
))
1589 /*SAVAGE_STATE_COPY(imesa);*/
1590 /* update state to hw*/
1591 if (imesa
->driDrawable
&&imesa
->driDrawable
->numClipRects
==0 )
1595 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1596 savageUpdateRegister_s4(imesa
);
1598 savageUpdateRegister_s3d(imesa
);
1601 imesa
->sarea
->dirty
|= (imesa
->dirty
&
1602 ~(SAVAGE_UPLOAD_TEX1
|SAVAGE_UPLOAD_TEX0
));
1603 imesa
->dirty
&= SAVAGE_UPLOAD_CLIPRECTS
;
1609 static void savageDDInitState_s4( savageContextPtr imesa
)
1612 imesa
->regs
.s4
.destCtrl
.ui
= 1<<7;
1615 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= LCS_Z_LESS
;
1616 imesa
->regs
.s4
.zBufCtrl
.ni
.wToZEn
= GL_TRUE
;
1617 /*imesa->regs.s4.ZBufCtrl.ni.floatZEn = GL_TRUE;*/
1618 imesa
->regs
.s4
.texBlendCtrl
[0].ui
= TBC_NoTexMap
;
1619 imesa
->regs
.s4
.texBlendCtrl
[1].ui
= TBC_NoTexMap1
;
1620 imesa
->regs
.s4
.drawCtrl0
.ui
= 0;
1622 imesa
->regs
.s4
.drawCtrl1
.ni
.xyOffsetEn
= 1;
1625 /* Set DestTexWatermarks_31,30 to 01 always.
1626 *Has no effect if dest. flush is disabled.
1629 imesa
->regs
.s4
.zWatermarks
.ui
= 0x12000C04;
1630 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x40200400;
1632 imesa
->regs
.s4
.zWatermarks
.ui
= 0x16001808;
1633 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x4f000000;
1635 imesa
->regs
.s4
.drawCtrl0
.ni
.dPerfAccelEn
= GL_TRUE
;
1637 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1638 * alpha blending working properly
1641 imesa
->regs
.s4
.texCtrl
[0].ni
.dBias
= 0x08;
1642 imesa
->regs
.s4
.texCtrl
[1].ni
.dBias
= 0x08;
1643 imesa
->regs
.s4
.texCtrl
[0].ni
.texXprEn
= GL_TRUE
;
1644 imesa
->regs
.s4
.texCtrl
[1].ni
.texXprEn
= GL_TRUE
;
1645 imesa
->regs
.s4
.texCtrl
[0].ni
.dMax
= 0x0f;
1646 imesa
->regs
.s4
.texCtrl
[1].ni
.dMax
= 0x0f;
1647 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1648 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
1649 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1650 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1651 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1653 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1654 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_TRUE
;
1655 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= BCM_None
;
1657 imesa
->LcsCullMode
=BCM_None
;
1658 imesa
->regs
.s4
.texDescr
.ni
.palSize
= TPS_256
;
1660 /* clear the local registers in the global reg mask */
1661 imesa
->globalRegMask
.s4
.drawLocalCtrl
.ui
= 0;
1662 imesa
->globalRegMask
.s4
.texPalAddr
.ui
= 0;
1663 imesa
->globalRegMask
.s4
.texCtrl
[0].ui
= 0;
1664 imesa
->globalRegMask
.s4
.texCtrl
[1].ui
= 0;
1665 imesa
->globalRegMask
.s4
.texAddr
[0].ui
= 0;
1666 imesa
->globalRegMask
.s4
.texAddr
[1].ui
= 0;
1667 imesa
->globalRegMask
.s4
.texBlendCtrl
[0].ui
= 0;
1668 imesa
->globalRegMask
.s4
.texBlendCtrl
[1].ui
= 0;
1669 imesa
->globalRegMask
.s4
.texXprClr
.ui
= 0;
1670 imesa
->globalRegMask
.s4
.texDescr
.ui
= 0;
1672 static void savageDDInitState_s3d( savageContextPtr imesa
)
1675 imesa
->regs
.s3d
.destCtrl
.ui
= 1<<7;
1678 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= LCS_Z_LESS
& 0x07;
1680 imesa
->regs
.s3d
.drawCtrl
.ni
.xyOffsetEn
= 1;
1683 /* Set DestTexWatermarks_31,30 to 01 always.
1684 *Has no effect if dest. flush is disabled.
1687 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x12000C04;
1688 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x40200400;
1690 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x16001808;
1691 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x4f000000;
1694 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1695 * alpha blending working properly
1698 imesa
->regs
.s3d
.texCtrl
.ni
.dBias
= 0x08;
1699 imesa
->regs
.s3d
.texCtrl
.ni
.texXprEn
= GL_TRUE
;
1701 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1702 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1703 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1705 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
1706 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1707 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1709 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
= GL_TRUE
;
1710 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= BCM_None
;
1712 imesa
->LcsCullMode
= BCM_None
;
1713 imesa
->regs
.s3d
.texDescr
.ni
.palSize
= TPS_256
;
1715 /* clear the local registers in the global reg mask */
1716 imesa
->globalRegMask
.s3d
.texPalAddr
.ui
= 0;
1717 imesa
->globalRegMask
.s3d
.texXprClr
.ui
= 0;
1718 imesa
->globalRegMask
.s3d
.texAddr
.ui
= 0;
1719 imesa
->globalRegMask
.s3d
.texDescr
.ui
= 0;
1720 imesa
->globalRegMask
.s3d
.texCtrl
.ui
= 0;
1722 imesa
->globalRegMask
.s3d
.fogCtrl
.ui
= 0;
1724 /* drawCtrl is local with some exceptions */
1725 imesa
->globalRegMask
.s3d
.drawCtrl
.ui
= 0;
1726 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.cullMode
= 0x3;
1727 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= 0x7;
1728 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestEn
= 0x1;
1729 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaRefVal
= 0xff;
1731 /* zBufCtrl is local with some exceptions */
1732 imesa
->globalRegMask
.s3d
.zBufCtrl
.ui
= 0;
1733 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zCmpFunc
= 0x7;
1734 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zBufEn
= 0x1;
1736 void savageDDInitState( savageContextPtr imesa
) {
1737 memset (imesa
->regs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(uint32_t));
1738 memset (imesa
->oldRegs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(uint32_t));
1739 memset (imesa
->globalRegMask
.ui
, 0xff, SAVAGE_NR_REGS
*sizeof(uint32_t));
1740 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1741 savageDDInitState_s4 (imesa
);
1743 savageDDInitState_s3d (imesa
);
1745 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1746 /* zbufoffset and destctrl have the same position and layout on
1747 * savage4 and savage3d. */
1748 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->backOffset
>>11;
1749 if(imesa
->savageScreen
->cpp
== 2)
1751 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 0;
1752 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1753 (imesa
->savageScreen
->width
+63)>>6;
1757 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 1;
1758 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1759 (imesa
->savageScreen
->width
+31)>>5;
1762 imesa
->IsDouble
= GL_TRUE
;
1764 imesa
->NotFirstFrame
= GL_FALSE
;
1765 imesa
->regs
.s4
.zBufOffset
.ni
.offset
=imesa
->savageScreen
->depthOffset
>>11;
1766 if(imesa
->savageScreen
->zpp
== 2)
1768 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1769 (imesa
->savageScreen
->width
+63)>>6;
1770 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 0;
1774 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1775 (imesa
->savageScreen
->width
+31)>>5;
1776 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 1;
1779 if (imesa
->glCtx
->Color
._DrawDestMask
== BACK_LEFT_BIT
) {
1780 if(imesa
->IsFullScreen
)
1782 imesa
->toggle
= TARGET_BACK
;
1784 imesa
->drawMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1785 imesa
->readMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1789 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1790 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1795 if(imesa
->IsFullScreen
)
1797 imesa
->toggle
= TARGET_BACK
;
1799 imesa
->drawMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1800 imesa
->readMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1804 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1805 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1811 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1812 NEW_TEXTURE_MATRIX|\
1813 NEW_USER_CLIP|NEW_CLIENT_STATE))
1815 void savageDDRenderStart(GLcontext
*ctx
)
1817 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
1818 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1819 XF86DRIClipRectPtr pbox
;
1822 /* if the screen is overrided by other application. set the scissor.
1823 * In MulitPass, re-render the screen.
1825 pbox
= dPriv
->pClipRects
;
1826 nbox
= dPriv
->numClipRects
;
1829 imesa
->currentClip
= nbox
;
1830 /* set scissor to the first clip box*/
1831 savageDDScissor(ctx
,pbox
->x1
,pbox
->y1
,pbox
->x2
,pbox
->y2
);
1833 savageUpdateCull(ctx
);
1834 savageDDUpdateHwState(ctx
); /* update to hardware register*/
1836 else /* need not render at all*/
1838 /*ctx->VB->CopyStart = ctx->VB->Count;*/
1840 LOCK_HARDWARE(SAVAGE_CONTEXT(ctx
));
1844 void savageDDRenderEnd(GLcontext
*ctx
)
1846 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
1848 UNLOCK_HARDWARE(SAVAGE_CONTEXT(ctx
));
1849 if(!imesa
->IsDouble
)
1851 savageSwapBuffers(imesa
->driDrawable
);
1856 static void savageDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1858 _swrast_InvalidateState( ctx
, new_state
);
1859 _swsetup_InvalidateState( ctx
, new_state
);
1860 _ac_InvalidateState( ctx
, new_state
);
1861 _tnl_InvalidateState( ctx
, new_state
);
1862 SAVAGE_CONTEXT(ctx
)->new_gl_state
|= new_state
;
1866 void savageDDInitStateFuncs(GLcontext
*ctx
)
1868 ctx
->Driver
.UpdateState
= savageDDInvalidateState
;
1869 ctx
->Driver
.BlendEquationSeparate
= savageDDBlendEquationSeparate
;
1870 ctx
->Driver
.Fogfv
= savageDDFogfv
;
1871 ctx
->Driver
.Scissor
= savageDDScissor
;
1873 ctx
->Driver
.CullFace
= savageDDCullFaceFrontFace
;
1874 ctx
->Driver
.FrontFace
= savageDDCullFaceFrontFace
;
1876 ctx
->Driver
.CullFace
= 0;
1877 ctx
->Driver
.FrontFace
= 0;
1878 #endif /* end #if HW_CULL */
1879 ctx
->Driver
.PolygonMode
=NULL
;
1880 ctx
->Driver
.PolygonStipple
= 0;
1881 ctx
->Driver
.LineStipple
= 0;
1882 ctx
->Driver
.LineWidth
= 0;
1883 ctx
->Driver
.LogicOpcode
= 0;
1884 ctx
->Driver
.DrawBuffer
= savageDDDrawBuffer
;
1885 ctx
->Driver
.ReadBuffer
= savageDDReadBuffer
;
1886 ctx
->Driver
.ClearColor
= savageDDClearColor
;
1888 ctx
->Driver
.DepthRange
= savageDepthRange
;
1889 ctx
->Driver
.Viewport
= savageViewport
;
1890 ctx
->Driver
.RenderMode
= savageRenderMode
;
1892 ctx
->Driver
.ClearIndex
= 0;
1893 ctx
->Driver
.IndexMask
= 0;
1895 if (SAVAGE_CONTEXT( ctx
)->savageScreen
->chipset
>= S3_SAVAGE4
) {
1896 ctx
->Driver
.Enable
= savageDDEnable_s4
;
1897 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s4
;
1898 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s4
;
1899 ctx
->Driver
.DepthMask
= savageDDDepthMask_s4
;
1900 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s4
;
1901 ctx
->Driver
.ColorMask
= savageDDColorMask_s4
;
1902 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s4
;
1903 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s4
;
1905 ctx
->Driver
.StencilFunc
= savageDDStencilFunc
;
1906 ctx
->Driver
.StencilMask
= savageDDStencilMask
;
1907 ctx
->Driver
.StencilOp
= savageDDStencilOp
;
1909 ctx
->Driver
.StencilFunc
= 0;
1910 ctx
->Driver
.StencilMask
= 0;
1911 ctx
->Driver
.StencilOp
= 0;
1912 #endif /* end #if HW_STENCIL */
1914 ctx
->Driver
.Enable
= savageDDEnable_s3d
;
1915 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s3d
;
1916 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s3d
;
1917 ctx
->Driver
.DepthMask
= savageDDDepthMask_s3d
;
1918 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s3d
;
1919 ctx
->Driver
.ColorMask
= savageDDColorMask_s3d
;
1920 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s3d
;
1921 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s3d
;
1922 ctx
->Driver
.StencilFunc
= 0;
1923 ctx
->Driver
.StencilMask
= 0;
1924 ctx
->Driver
.StencilOp
= 0;
1927 /* Swrast hooks for imaging extensions:
1929 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1930 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1931 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1932 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;