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 /* This can be done in BlendFunc*/
73 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
74 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
75 savageBlendFunc_s4(ctx
);
77 static void savageDDAlphaFunc_s3d(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
79 /* This can be done in BlendFunc*/
80 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
81 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
82 savageBlendFunc_s3d(ctx
);
85 static void savageDDBlendEquationSeparate(GLcontext
*ctx
,
86 GLenum modeRGB
, GLenum modeA
)
88 assert( modeRGB
== modeA
);
90 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
93 FALLBACK( ctx
, SAVAGE_FALLBACK_LOGICOP
,
94 (ctx
->Color
.ColorLogicOpEnabled
&&
95 ctx
->Color
.LogicOp
!= GL_COPY
));
97 /* Can only do blend addition, not min, max, subtract, etc. */
98 FALLBACK( ctx
, SAVAGE_FALLBACK_BLEND_EQ
,
99 modeRGB
!= GL_FUNC_ADD
);
103 static void savageBlendFunc_s4(GLcontext
*ctx
)
105 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
107 /* set up draw control register (including blending, alpha
108 * test, and shading model)
111 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= 0;
116 if(ctx
->Color
.BlendEnabled
){
117 switch (ctx
->Color
.BlendDstRGB
)
120 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
124 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
125 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
129 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
130 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
133 case GL_ONE_MINUS_SRC_COLOR
:
134 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
135 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
139 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
140 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
143 case GL_ONE_MINUS_SRC_ALPHA
:
144 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
145 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
149 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
151 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_One
;
155 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
157 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
160 case GL_ONE_MINUS_DST_ALPHA
:
161 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
163 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
167 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
=DAM_1DstAlpha
;
168 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
173 switch (ctx
->Color
.BlendSrcRGB
)
176 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
180 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
184 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
185 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
188 case GL_ONE_MINUS_DST_COLOR
:
189 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
190 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
194 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
197 case GL_ONE_MINUS_SRC_ALPHA
:
198 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
202 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
204 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
208 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
209 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
213 case GL_ONE_MINUS_DST_ALPHA
:
214 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
216 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
220 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
=SAM_1DstAlpha
;
221 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
228 imesa
->regs
.s4
.drawLocalCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
229 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
234 if(ctx
->Color
.AlphaEnabled
)
239 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
241 switch(ctx
->Color
.AlphaFunc
) {
242 case GL_NEVER
: a
= CF_Never
; break;
243 case GL_ALWAYS
: a
= CF_Always
; break;
244 case GL_LESS
: a
= CF_Less
; break;
245 case GL_LEQUAL
: a
= CF_LessEqual
; break;
246 case GL_EQUAL
: a
= CF_Equal
; break;
247 case GL_GREATER
: a
= CF_Greater
; break;
248 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
249 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
253 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_TRUE
;
254 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestCmpFunc
= a
;
255 imesa
->regs
.s4
.drawCtrl0
.ni
.alphaRefVal
= alphaRef
;
259 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
= GL_FALSE
;
262 /* Set/Reset Z-after-alpha*/
264 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
=
265 imesa
->regs
.s4
.drawCtrl1
.ni
.alphaTestEn
;
266 /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
267 ~drawLocalCtrl.ni.wrZafterAlphaTst;*/
269 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
271 static void savageBlendFunc_s3d(GLcontext
*ctx
)
273 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
275 /* set up draw control register (including blending, alpha
276 * test, dithering, and shading model)
279 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= 0;
284 if(ctx
->Color
.BlendEnabled
){
285 switch (ctx
->Color
.BlendDstRGB
)
288 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
292 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
293 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
297 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcClr
;
298 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
301 case GL_ONE_MINUS_SRC_COLOR
:
302 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcClr
;
303 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
307 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_SrcAlpha
;
308 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
311 case GL_ONE_MINUS_SRC_ALPHA
:
312 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1SrcAlpha
;
313 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
317 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
319 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_One
;
323 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_DstAlpha
;
325 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
328 case GL_ONE_MINUS_DST_ALPHA
:
329 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
331 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
335 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_1DstAlpha
;
336 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
341 switch (ctx
->Color
.BlendSrcRGB
)
344 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
348 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
352 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstClr
;
353 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
356 case GL_ONE_MINUS_DST_COLOR
:
357 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstClr
;
358 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
362 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_SrcAlpha
;
365 case GL_ONE_MINUS_SRC_ALPHA
:
366 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1SrcAlpha
;
370 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
372 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
376 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_DstAlpha
;
377 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
381 case GL_ONE_MINUS_DST_ALPHA
:
382 if (imesa
->glCtx
->Visual
.alphaBits
== 0)
384 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_Zero
;
388 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_1DstAlpha
;
389 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
396 imesa
->regs
.s3d
.drawCtrl
.ni
.dstAlphaMode
= DAM_Zero
;
397 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
402 if(ctx
->Color
.AlphaEnabled
)
407 CLAMPED_FLOAT_TO_UBYTE(alphaRef
,ctx
->Color
.AlphaRef
);
409 switch(ctx
->Color
.AlphaFunc
) {
410 case GL_NEVER
: a
= CF_Never
; break;
411 case GL_ALWAYS
: a
= CF_Always
; break;
412 case GL_LESS
: a
= CF_Less
; break;
413 case GL_LEQUAL
: a
= CF_LessEqual
; break;
414 case GL_EQUAL
: a
= CF_Equal
; break;
415 case GL_GREATER
: a
= CF_Greater
; break;
416 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
417 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
421 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_TRUE
;
422 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= a
;
423 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaRefVal
= alphaRef
;
427 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
= GL_FALSE
;
430 /* Set/Reset Z-after-alpha*/
432 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
=
433 imesa
->regs
.s3d
.drawCtrl
.ni
.alphaTestEn
;
435 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
438 static void savageDDBlendFuncSeparate_s4( GLcontext
*ctx
, GLenum sfactorRGB
,
439 GLenum dfactorRGB
, GLenum sfactorA
,
442 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
443 savageBlendFunc_s4( ctx
);
445 static void savageDDBlendFuncSeparate_s3d( GLcontext
*ctx
, GLenum sfactorRGB
,
446 GLenum dfactorRGB
, GLenum sfactorA
,
449 assert (dfactorRGB
== dfactorA
&& sfactorRGB
== sfactorA
);
450 savageBlendFunc_s3d( ctx
);
455 static void savageDDDepthFunc_s4(GLcontext
*ctx
, GLenum func
)
457 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
461 /* set up z-buffer control register (global)
462 * set up z-buffer offset register (global)
463 * set up z read/write watermarks register (global)
467 case GL_NEVER
: zmode
= CF_Never
; break;
468 case GL_ALWAYS
: zmode
= CF_Always
; break;
469 case GL_LESS
: zmode
= CF_Less
; break;
470 case GL_LEQUAL
: zmode
= CF_LessEqual
; break;
471 case GL_EQUAL
: zmode
= CF_Equal
; break;
472 case GL_GREATER
: zmode
= CF_Greater
; break;
473 case GL_GEQUAL
: zmode
= CF_GreaterEqual
; break;
474 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
480 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
481 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
482 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
484 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 0;
487 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
489 else if (imesa
->glCtx
->Stencil
.Enabled
&& imesa
->hw_stencil
)
491 /* Need to keep Z on for Stencil. */
492 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
493 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
494 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
495 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
496 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 8;
501 if (imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
== GL_FALSE
)
503 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
504 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
508 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
510 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
512 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
513 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
514 imesa
->regs
.s4
.zWatermarks
.ni
.wLow
= 8;
517 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
519 static void savageDDDepthFunc_s3d(GLcontext
*ctx
, GLenum func
)
521 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
525 /* set up z-buffer control register (global)
526 * set up z-buffer offset register (global)
527 * set up z read/write watermarks register (global)
530 case GL_NEVER
: zmode
= CF_Never
; break;
531 case GL_ALWAYS
: zmode
= CF_Always
; break;
532 case GL_LESS
: zmode
= CF_Less
; break;
533 case GL_LEQUAL
: zmode
= CF_LessEqual
; break;
534 case GL_EQUAL
: zmode
= CF_Equal
; break;
535 case GL_GREATER
: zmode
= CF_Greater
; break;
536 case GL_GEQUAL
: zmode
= CF_GreaterEqual
; break;
537 case GL_NOTEQUAL
: zmode
= CF_NotEqual
; break;
542 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
543 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= zmode
;
544 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= ctx
->Depth
.Mask
;
546 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
548 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 0;
553 if (imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
== GL_FALSE
) {
554 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
555 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
559 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
561 imesa
->regs
.s3d
.zBufCtrl
.ni
.zBufEn
= GL_FALSE
;
563 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_FALSE
;
564 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
565 imesa
->regs
.s3d
.zWatermarks
.ni
.wLow
= 8;
568 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
571 static void savageDDDepthMask_s4(GLcontext
*ctx
, GLboolean flag
)
573 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
575 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
578 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
582 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
584 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
586 static void savageDDDepthMask_s3d(GLcontext
*ctx
, GLboolean flag
)
588 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
590 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
593 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
597 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_FALSE
;
599 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
605 /* =============================================================
610 static void savageDDScissor( GLcontext
*ctx
, GLint x
, GLint y
,
611 GLsizei w
, GLsizei h
)
613 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
614 imesa
->scissor_rect
.x1
= MAX2(imesa
->drawX
+x
,imesa
->draw_rect
.x1
);
615 imesa
->scissor_rect
.y1
= MAX2(imesa
->drawY
+imesa
->driDrawable
->h
-(y
+h
),
616 imesa
->draw_rect
.y1
);
617 imesa
->scissor_rect
.x2
= MIN2(imesa
->drawX
+x
+w
,imesa
->draw_rect
.x2
);
618 imesa
->scissor_rect
.y2
= MIN2(imesa
->drawY
+imesa
->driDrawable
->h
- y
,
619 imesa
->draw_rect
.y2
);
622 imesa
->scissorChanged
=GL_TRUE
;
624 imesa
->dirty
|= SAVAGE_UPLOAD_CLIPRECTS
;
629 static void savageDDDrawBuffer(GLcontext
*ctx
, GLenum mode
)
631 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
634 * _DrawDestMask is easier to cope with than <mode>.
636 switch ( ctx
->Color
._DrawDestMask
[0] ) {
637 case DD_FRONT_LEFT_BIT
:
638 imesa
->IsDouble
= GL_FALSE
;
640 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_FRONT
];
641 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_FRONT
];
642 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->frontOffset
>>11;
643 imesa
->NotFirstFrame
= GL_FALSE
;
644 imesa
->dirty
|= SAVAGE_UPLOAD_BUFFERS
| SAVAGE_UPLOAD_CTX
;
645 savageXMesaSetFrontClipRects( imesa
);
646 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
648 case DD_BACK_LEFT_BIT
:
649 imesa
->IsDouble
= GL_TRUE
;
650 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
651 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
652 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->backOffset
>>11;
653 imesa
->NotFirstFrame
= GL_FALSE
;
654 imesa
->dirty
|= SAVAGE_UPLOAD_BUFFERS
| SAVAGE_UPLOAD_CTX
;
655 savageXMesaSetBackClipRects( imesa
);
656 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
659 FALLBACK( ctx
, SAVAGE_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
663 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
666 _swrast_DrawBuffer(ctx
, mode
);
669 static void savageDDReadBuffer(GLcontext
*ctx
, GLenum mode
)
671 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
675 static void savageDDSetColor(GLcontext
*ctx
,
676 GLubyte r
, GLubyte g
,
677 GLubyte b
, GLubyte a
)
679 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
680 imesa
->MonoColor
= savagePackColor( imesa
->savageScreen
->frontFormat
, r
, g
, b
, a
);
684 /* =============================================================
685 * Window position and viewport transformation
688 static void savageCalcViewport( GLcontext
*ctx
)
690 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
691 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
692 GLfloat
*m
= imesa
->hw_viewport
;
694 /* See also mga_translate_vertex.
696 m
[MAT_SX
] = v
[MAT_SX
];
697 m
[MAT_TX
] = v
[MAT_TX
] + imesa
->drawX
+ SUBPIXEL_X
;
698 m
[MAT_SY
] = - v
[MAT_SY
];
699 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ imesa
->drawY
+ SUBPIXEL_Y
;
700 m
[MAT_SZ
] = v
[MAT_SZ
] * imesa
->depth_scale
;
701 m
[MAT_TZ
] = v
[MAT_TZ
] * imesa
->depth_scale
;
703 imesa
->SetupNewInputs
= ~0;
706 static void savageViewport( GLcontext
*ctx
,
708 GLsizei width
, GLsizei height
)
710 /* update size of Mesa/software ancillary buffers */
711 _mesa_ResizeBuffersMESA();
712 savageCalcViewport( ctx
);
715 static void savageDepthRange( GLcontext
*ctx
,
716 GLclampd nearval
, GLclampd farval
)
718 savageCalcViewport( ctx
);
722 /* =============================================================
726 static void savageDDClearColor(GLcontext
*ctx
,
727 const GLfloat color
[4] )
729 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
731 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
732 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
733 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
734 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
736 imesa
->ClearColor
= savagePackColor( imesa
->savageScreen
->frontFormat
,
737 c
[0], c
[1], c
[2], c
[3] );
740 /* Fallback to swrast for select and feedback.
742 static void savageRenderMode( GLcontext
*ctx
, GLenum mode
)
744 FALLBACK( ctx
, SAVAGE_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
750 /* =============================================================
751 * Culling - the savage isn't quite as clean here as the rest of
752 * its interfaces, but it's not bad.
754 static void savageDDCullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
756 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
757 GLuint cullMode
=imesa
->LcsCullMode
;
758 switch (ctx
->Polygon
.CullFaceMode
)
761 switch (ctx
->Polygon
.FrontFace
)
773 switch (ctx
->Polygon
.FrontFace
)
784 imesa
->LcsCullMode
= cullMode
;
785 imesa
->new_state
|= SAVAGE_NEW_CULL
;
787 #endif /* end #if HW_CULL */
789 static void savageUpdateCull( GLcontext
*ctx
)
792 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
794 if (ctx
->Polygon
.CullFlag
&&
795 imesa
->raster_primitive
== GL_TRIANGLES
&&
796 ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
)
797 cullMode
= imesa
->LcsCullMode
;
800 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
) {
801 if (imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
!= cullMode
) {
802 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= cullMode
;
803 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
806 if (imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
!= cullMode
) {
807 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= cullMode
;
808 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
811 #endif /* end #if HW_CULL */
816 /* =============================================================
820 /* Mesa calls this from the wrong place - it is called a very large
821 * number of redundant times.
823 * Colormask can be simulated by multipass or multitexture techniques.
825 static void savageDDColorMask_s4(GLcontext
*ctx
,
826 GLboolean r
, GLboolean g
,
827 GLboolean b
, GLboolean a
)
829 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
832 if (ctx
->Visual
.alphaBits
)
834 enable
= b
| g
| r
| a
;
843 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
847 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
849 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
850 /* TODO: need a software fallback */
852 static void savageDDColorMask_s3d(GLcontext
*ctx
,
853 GLboolean r
, GLboolean g
,
854 GLboolean b
, GLboolean a
)
856 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
859 if (ctx
->Visual
.alphaBits
)
861 enable
= b
| g
| r
| a
;
870 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
874 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_FALSE
;
876 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
877 /* TODO: need a software fallback */
880 /* Seperate specular not fully implemented in hardware... Needs
881 * some interaction with material state? Just punt to software
883 * FK: Don't fall back for now. Let's see the failure cases and
884 * fix them the right way. I don't see how this could be a
885 * hardware limitation.
887 static void savageUpdateSpecular_s4(GLcontext
*ctx
) {
888 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
890 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
891 ctx
->Light
.Enabled
) {
892 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_TRUE
;
893 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
895 imesa
->regs
.s4
.drawLocalCtrl
.ni
.specShadeEn
= GL_FALSE
;
896 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
898 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
900 static void savageUpdateSpecular_s3d(GLcontext
*ctx
) {
901 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
903 if (ctx
->Light
.Model
.ColorControl
== GL_SEPARATE_SPECULAR_COLOR
&&
904 ctx
->Light
.Enabled
) {
905 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_TRUE
;
906 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
908 imesa
->regs
.s3d
.drawCtrl
.ni
.specShadeEn
= GL_FALSE
;
909 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
911 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
914 static void savageDDLightModelfv_s4(GLcontext
*ctx
, GLenum pname
,
915 const GLfloat
*param
)
917 savageUpdateSpecular_s4 (ctx
);
919 static void savageDDLightModelfv_s3d(GLcontext
*ctx
, GLenum pname
,
920 const GLfloat
*param
)
922 savageUpdateSpecular_s3d (ctx
);
925 static void savageDDShadeModel_s4(GLcontext
*ctx
, GLuint mod
)
927 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
929 if (mod
== GL_SMOOTH
)
931 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_FALSE
;
935 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flatShadeEn
= GL_TRUE
;
937 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
939 static void savageDDShadeModel_s3d(GLcontext
*ctx
, GLuint mod
)
941 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
943 if (mod
== GL_SMOOTH
)
945 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_FALSE
;
949 imesa
->regs
.s3d
.drawCtrl
.ni
.flatShadeEn
= GL_TRUE
;
951 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
955 /* =============================================================
957 * The fogCtrl register has the same position and the same layout
958 * on savage3d and savage4. No need for two separate functions.
961 static void savageDDFogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
963 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
966 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
967 if (ctx
->Fog
.Enabled
)
969 fogClr
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
970 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
971 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
972 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= GL_TRUE
;
974 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= GL_TRUE
;
975 imesa
->regs
.s4
.fogCtrl
.ni
.fogClr
= fogClr
;
981 imesa
->regs
.s4
.fogCtrl
.ni
.fogEn
= 0;
982 imesa
->regs
.s4
.fogCtrl
.ni
.fogMode
= 0;
984 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
988 static void savageStencilFunc(GLcontext
*);
990 static void savageDDStencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
993 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
996 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= ctx
->Stencil
.Ref
[0];
997 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= ctx
->Stencil
.ValueMask
[0];
999 switch (ctx
->Stencil
.Function
[0])
1001 case GL_NEVER
: a
= CF_Never
; break;
1002 case GL_ALWAYS
: a
= CF_Always
; break;
1003 case GL_LESS
: a
= CF_Less
; break;
1004 case GL_LEQUAL
: a
= CF_LessEqual
; break;
1005 case GL_EQUAL
: a
= CF_Equal
; break;
1006 case GL_GREATER
: a
= CF_Greater
; break;
1007 case GL_GEQUAL
: a
= CF_GreaterEqual
; break;
1008 case GL_NOTEQUAL
: a
= CF_NotEqual
; break;
1013 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= a
;
1015 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1018 static void savageDDStencilMask(GLcontext
*ctx
, GLuint mask
)
1020 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1022 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= ctx
->Stencil
.WriteMask
[0];
1024 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1027 static void savageDDStencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
1030 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1032 switch (ctx
->Stencil
.FailFunc
[0])
1035 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1038 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Zero
;
1041 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Equal
;
1044 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_IncClamp
;
1047 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_DecClamp
;
1050 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Invert
;
1052 case GL_INCR_WRAP_EXT
:
1053 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Inc
;
1055 case GL_DECR_WRAP_EXT
:
1056 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Dec
;
1061 switch (ctx
->Stencil
.ZFailFunc
[0])
1064 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1067 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Zero
;
1070 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Equal
;
1073 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_IncClamp
;
1076 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_DecClamp
;
1079 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Invert
;
1081 case GL_INCR_WRAP_EXT
:
1082 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Inc
;
1084 case GL_DECR_WRAP_EXT
:
1085 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Dec
;
1089 switch (ctx
->Stencil
.ZPassFunc
[0])
1092 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1095 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Zero
;
1098 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Equal
;
1101 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_IncClamp
;
1104 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_DecClamp
;
1107 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Invert
;
1109 case GL_INCR_WRAP_EXT
:
1110 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Inc
;
1112 case GL_DECR_WRAP_EXT
:
1113 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Dec
;
1117 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1121 /* =============================================================
1124 static void savageDDEnable_s4(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1127 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1130 /* we should consider the disable case*/
1131 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1132 savageBlendFunc_s4(ctx
);
1135 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1136 /*Can't find Enable bit in the 3D registers.*/
1137 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1139 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1140 (ctx
->Color
.ColorLogicOpEnabled
&&
1141 ctx
->Color
.LogicOp
!= GL_COPY
));
1142 /*add the savageBlendFunc 2001/11/25
1143 * if call no such function, then glDisable(GL_BLEND) will do noting,
1144 *our chip has no disable bit
1146 savageBlendFunc_s4(ctx
);
1149 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1150 savageDDDepthFunc_s4(ctx
,ctx
->Depth
.Func
);
1152 case GL_SCISSOR_TEST
:
1153 imesa
->scissor
= state
;
1154 imesa
->dirty
|= SAVAGE_UPLOAD_CLIPRECTS
;
1156 case GL_STENCIL_TEST
:
1157 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1158 if (!imesa
->hw_stencil
)
1159 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1161 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= state
;
1162 if (ctx
->Stencil
.Enabled
&&
1163 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
!= GL_TRUE
)
1165 /* Stencil buffer requires Z enabled. */
1166 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Always
;
1167 imesa
->regs
.s4
.zBufCtrl
.ni
.zBufEn
= GL_TRUE
;
1168 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_FALSE
;
1170 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1174 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1175 savageDDFogfv(ctx
,0,0);
1181 savageDDCullFaceFrontFace(ctx
,0);
1185 imesa
->LcsCullMode
= BCM_None
;
1186 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1191 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1194 if ( ctx
->Color
.DitherFlag
)
1196 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_TRUE
;
1199 if (!ctx
->Color
.DitherFlag
)
1201 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
=GL_FALSE
;
1206 savageUpdateSpecular_s4 (ctx
);
1210 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1213 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1219 static void savageDDEnable_s3d(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1222 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1225 /* we should consider the disable case*/
1226 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1227 savageBlendFunc_s3d(ctx
);
1230 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1231 /*Can't find Enable bit in the 3D registers.*/
1232 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1234 FALLBACK (ctx
, SAVAGE_FALLBACK_LOGICOP
,
1235 (ctx
->Color
.ColorLogicOpEnabled
&&
1236 ctx
->Color
.LogicOp
!= GL_COPY
));
1237 /*add the savageBlendFunc 2001/11/25
1238 * if call no such function, then glDisable(GL_BLEND) will do noting,
1239 *our chip has no disable bit
1241 savageBlendFunc_s3d(ctx
);
1244 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1245 savageDDDepthFunc_s3d(ctx
,ctx
->Depth
.Func
);
1247 case GL_SCISSOR_TEST
:
1248 imesa
->scissor
= state
;
1249 imesa
->dirty
|= SAVAGE_UPLOAD_CLIPRECTS
;
1251 case GL_STENCIL_TEST
:
1252 FALLBACK (ctx
, SAVAGE_FALLBACK_STENCIL
, state
);
1255 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1256 savageDDFogfv(ctx
,0,0);
1262 savageDDCullFaceFrontFace(ctx
,0);
1266 imesa
->LcsCullMode
= BCM_None
;
1267 imesa
->new_state
|= SAVAGE_NEW_CULL
;
1272 imesa
->dirty
|= SAVAGE_UPLOAD_CTX
;
1275 if ( ctx
->Color
.DitherFlag
)
1277 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_TRUE
;
1280 if (!ctx
->Color
.DitherFlag
)
1282 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
=GL_FALSE
;
1287 savageUpdateSpecular_s3d (ctx
);
1291 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1294 imesa
->new_state
|= SAVAGE_NEW_TEXTURE
;
1301 void savageDDUpdateHwState( GLcontext
*ctx
)
1303 savageContextPtr imesa
= SAVAGE_CONTEXT(ctx
);
1305 if (imesa
->new_state
) {
1308 if (imesa
->new_state
& SAVAGE_NEW_TEXTURE
) {
1309 savageUpdateTextureState( ctx
);
1311 if ((imesa
->new_state
& SAVAGE_NEW_CULL
)) {
1312 savageUpdateCull(ctx
);
1314 imesa
->new_state
= 0;
1319 void savageEmitDrawingRectangle( savageContextPtr imesa
)
1321 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1322 savageScreenPrivate
*savageScreen
= imesa
->savageScreen
;
1323 drm_clip_rect_t
*pbox
;
1327 int x0
= imesa
->drawX
;
1328 int y0
= imesa
->drawY
;
1329 int x1
= x0
+ dPriv
->w
;
1330 int y1
= y0
+ dPriv
->h
;
1332 pbox
= dPriv
->pClipRects
;
1333 nbox
= dPriv
->numClipRects
;
1337 /* Coordinate origin of the window - may be offscreen.
1339 /* imesa->BufferSetup[SAVAGE_DESTREG_DR4] = ((y0<<16) |
1340 (((unsigned)x0)&0xFFFF));*/
1346 if (x1
> savageScreen
->width
) x1
= savageScreen
->width
;
1347 if (y1
> savageScreen
->height
) y1
= savageScreen
->height
;
1352 imesa
->draw_rect
.x1
= MAX2(x0
,pbox
->x1
);
1353 imesa
->draw_rect
.y1
= MAX2(y0
,pbox
->y1
);
1354 imesa
->draw_rect
.x2
= MIN2(x1
,pbox
->x2
);
1355 imesa
->draw_rect
.y2
= MIN2(y1
,pbox
->y2
);
1359 imesa
->draw_rect
.x1
= x0
;
1360 imesa
->draw_rect
.y1
= y0
;
1361 imesa
->draw_rect
.x2
= x1
;
1362 imesa
->draw_rect
.y2
= y1
;
1365 imesa
->scissorChanged
= GL_TRUE
;
1367 /* imesa->regs.ni.changed.ni.fDrawCtrl0Changed=GL_TRUE;
1368 imesa->regs.ni.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/
1370 savageCalcViewport (imesa
->glCtx
);
1372 imesa
->dirty
|= SAVAGE_UPLOAD_BUFFERS
;
1376 static void savageDDPrintDirty( const char *msg
, GLuint state
)
1378 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s\n",
1380 (unsigned int) state
,
1381 (state
& SAVAGE_UPLOAD_TEX0IMAGE
) ? "upload-tex0, " : "",
1382 (state
& SAVAGE_UPLOAD_TEX1IMAGE
) ? "upload-tex1, " : "",
1383 (state
& SAVAGE_UPLOAD_CTX
) ? "upload-ctx, " : "",
1384 (state
& SAVAGE_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1385 (state
& SAVAGE_UPLOAD_CLIPRECTS
) ? "upload-cliprects, " : ""
1391 * Check if global registers were changed
1393 static GLboolean
savageGlobalRegChanged (savageContextPtr imesa
,
1394 GLuint first
, GLuint last
) {
1396 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1397 if (((imesa
->oldRegs
.ui
[i
] ^ imesa
->regs
.ui
[i
]) &
1398 imesa
->globalRegMask
.ui
[i
]) != 0)
1403 static void savageEmitContiguousRegs (savageContextPtr imesa
,
1404 GLuint first
, GLuint last
) {
1406 u_int32_t
*pBCIBase
;
1407 pBCIBase
= savageDMAAlloc (imesa
, last
- first
+ 2);
1408 WRITE_CMD (pBCIBase
, SET_REGISTER(first
, last
- first
+ 1), u_int32_t
);
1410 for (i
= first
- SAVAGE_FIRST_REG
; i
<= last
- SAVAGE_FIRST_REG
; ++i
) {
1411 WRITE_CMD (pBCIBase
, imesa
->regs
.ui
[i
], u_int32_t
);
1412 imesa
->oldRegs
.ui
[i
] = imesa
->regs
.ui
[i
];
1414 savageDMACommit (imesa
, pBCIBase
);
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 u_int32_t
*pBCIBase
;
1451 * Scissors updates drawctrl0 and drawctrl 1
1453 if (imesa
->scissorChanged
)
1457 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorXStart
= imesa
->scissor_rect
.x1
;
1458 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorYStart
= imesa
->scissor_rect
.y1
;
1459 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorXEnd
= imesa
->scissor_rect
.x2
-1;
1460 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorYEnd
= imesa
->scissor_rect
.y2
-1;
1464 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorXStart
= imesa
->draw_rect
.x1
;
1465 imesa
->regs
.s4
.drawCtrl0
.ni
.scissorYStart
= imesa
->draw_rect
.y1
;
1466 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorXEnd
= imesa
->draw_rect
.x2
-1;
1467 imesa
->regs
.s4
.drawCtrl1
.ni
.scissorYEnd
= imesa
->draw_rect
.y2
-1;
1471 /* the savage4 uses the contiguous range of BCI registers 0x1e-0x39
1472 * 0x1e-0x27 are local, no need to check them for global changes */
1473 if (imesa
->lostContext
|| savageGlobalRegChanged (imesa
, 0x28, 0x39)) {
1474 pBCIBase
= savageDMAAlloc (imesa
, 1);
1475 WRITE_CMD (pBCIBase
, WAIT_3D_IDLE
, u_int32_t
);
1476 savageDMACommit (imesa
, pBCIBase
);
1478 if (imesa
->lostContext
)
1479 savageEmitContiguousRegs (imesa
, 0x1e, 0x39);
1481 savageEmitChangedRegs (imesa
, 0x1e, 0x39);
1484 imesa
->lostContext
= GL_FALSE
;
1486 static void savageUpdateRegister_s3d(savageContextPtr imesa
)
1488 u_int32_t
*pBCIBase
;
1490 if (imesa
->scissorChanged
)
1494 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorXStart
=
1495 imesa
->scissor_rect
.x1
;
1496 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorYStart
=
1497 imesa
->scissor_rect
.y1
;
1498 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorXEnd
=
1499 imesa
->scissor_rect
.x2
-1;
1500 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorYEnd
=
1501 imesa
->scissor_rect
.y2
-1;
1505 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorXStart
=
1506 imesa
->draw_rect
.x1
;
1507 imesa
->regs
.s3d
.scissorsStart
.ni
.scissorYStart
=
1508 imesa
->draw_rect
.y1
;
1509 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorXEnd
=
1510 imesa
->draw_rect
.x2
-1;
1511 imesa
->regs
.s3d
.scissorsEnd
.ni
.scissorYEnd
=
1512 imesa
->draw_rect
.y2
-1;
1516 /* Some temporary hacks to workaround lockups. Not sure if they are
1517 * still needed. But they work for now. */
1518 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1519 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1521 /* the savage3d uses two contiguous ranges of BCI registers:
1522 * 0x18-0x1c and 0x20-0x38. The first range is local. */
1523 if (imesa
->lostContext
|| savageGlobalRegChanged (imesa
, 0x20, 0x38)) {
1524 pBCIBase
= savageDMAAlloc (imesa
, 1);
1525 WRITE_CMD (pBCIBase
, WAIT_3D_IDLE
, u_int32_t
);
1526 savageDMACommit (imesa
, pBCIBase
);
1528 /* FIXME: watermark registers aren't programmed correctly ATM */
1529 if (imesa
->lostContext
) {
1530 savageEmitContiguousRegs (imesa
, 0x18, 0x1c);
1531 savageEmitContiguousRegs (imesa
, 0x20, 0x36);
1533 /* On the Savage IX texture registers (at least some of them)
1534 * have to be emitted as one chunk. */
1535 savageEmitChangedRegs (imesa
, 0x18, 0x19);
1536 savageEmitChangedRegChunk (imesa
, 0x1a, 0x1c);
1537 savageEmitChangedRegs (imesa
, 0x20, 0x36);
1541 imesa
->lostContext
= GL_FALSE
;
1546 /* Push the state into the sarea and/or texture memory.
1548 void savageEmitHwStateLocked( savageContextPtr imesa
)
1550 if (SAVAGE_DEBUG
& DEBUG_VERBOSE_API
)
1551 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa
->dirty
);
1553 if (imesa
->dirty
& ~SAVAGE_UPLOAD_CLIPRECTS
)
1555 if (imesa
->dirty
& (SAVAGE_UPLOAD_CTX
| SAVAGE_UPLOAD_TEX0
| \
1556 SAVAGE_UPLOAD_TEX1
| SAVAGE_UPLOAD_BUFFERS
))
1559 /*SAVAGE_STATE_COPY(imesa);*/
1560 /* update state to hw*/
1561 if (imesa
->driDrawable
&&imesa
->driDrawable
->numClipRects
==0 )
1565 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1566 savageUpdateRegister_s4(imesa
);
1568 savageUpdateRegister_s3d(imesa
);
1571 imesa
->sarea
->dirty
|= (imesa
->dirty
&
1572 ~(SAVAGE_UPLOAD_TEX1
|SAVAGE_UPLOAD_TEX0
));
1573 imesa
->dirty
&= SAVAGE_UPLOAD_CLIPRECTS
;
1579 static void savageDDInitState_s4( savageContextPtr imesa
)
1582 imesa
->regs
.s4
.destCtrl
.ui
= 1<<7;
1585 imesa
->regs
.s4
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1586 imesa
->regs
.s4
.zBufCtrl
.ni
.wToZEn
= GL_TRUE
;
1587 /*imesa->regs.s4.ZBufCtrl.ni.floatZEn = GL_TRUE;*/
1588 imesa
->regs
.s4
.texBlendCtrl
[0].ui
= TBC_NoTexMap
;
1589 imesa
->regs
.s4
.texBlendCtrl
[1].ui
= TBC_NoTexMap1
;
1590 imesa
->regs
.s4
.drawCtrl0
.ui
= 0;
1592 imesa
->regs
.s4
.drawCtrl1
.ni
.xyOffsetEn
= 1;
1595 /* Set DestTexWatermarks_31,30 to 01 always.
1596 *Has no effect if dest. flush is disabled.
1599 imesa
->regs
.s4
.zWatermarks
.ui
= 0x12000C04;
1600 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x40200400;
1602 imesa
->regs
.s4
.zWatermarks
.ui
= 0x16001808;
1603 imesa
->regs
.s4
.destTexWatermarks
.ui
= 0x4f000000;
1605 imesa
->regs
.s4
.drawCtrl0
.ni
.dPerfAccelEn
= GL_TRUE
;
1607 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1608 * alpha blending working properly
1611 imesa
->regs
.s4
.texCtrl
[0].ni
.dBias
= 0x08;
1612 imesa
->regs
.s4
.texCtrl
[1].ni
.dBias
= 0x08;
1613 imesa
->regs
.s4
.texCtrl
[0].ni
.texXprEn
= GL_TRUE
;
1614 imesa
->regs
.s4
.texCtrl
[1].ni
.texXprEn
= GL_TRUE
;
1615 imesa
->regs
.s4
.texCtrl
[0].ni
.dMax
= 0x0f;
1616 imesa
->regs
.s4
.texCtrl
[1].ni
.dMax
= 0x0f;
1617 imesa
->regs
.s4
.drawLocalCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1618 imesa
->regs
.s4
.drawLocalCtrl
.ni
.srcAlphaMode
= SAM_One
;
1619 imesa
->regs
.s4
.drawLocalCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1620 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1621 imesa
->regs
.s4
.drawLocalCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1623 imesa
->regs
.s4
.drawLocalCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1624 imesa
->regs
.s4
.drawCtrl1
.ni
.ditherEn
= (
1625 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1626 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1627 imesa
->regs
.s4
.drawCtrl1
.ni
.cullMode
= BCM_None
;
1629 imesa
->regs
.s4
.zBufCtrl
.ni
.stencilRefVal
= 0x00;
1631 imesa
->regs
.s4
.stencilCtrl
.ni
.stencilEn
= GL_FALSE
;
1632 imesa
->regs
.s4
.stencilCtrl
.ni
.cmpFunc
= CF_Always
;
1633 imesa
->regs
.s4
.stencilCtrl
.ni
.failOp
= STC_FAIL_Keep
;
1634 imesa
->regs
.s4
.stencilCtrl
.ni
.passZfailOp
= STC_FAIL_Keep
;
1635 imesa
->regs
.s4
.stencilCtrl
.ni
.passZpassOp
= STC_FAIL_Keep
;
1636 imesa
->regs
.s4
.stencilCtrl
.ni
.writeMask
= 0xff;
1637 imesa
->regs
.s4
.stencilCtrl
.ni
.readMask
= 0xff;
1639 imesa
->LcsCullMode
=BCM_None
;
1640 imesa
->regs
.s4
.texDescr
.ni
.palSize
= TPS_256
;
1642 /* clear the local registers in the global reg mask */
1643 imesa
->globalRegMask
.s4
.drawLocalCtrl
.ui
= 0;
1644 imesa
->globalRegMask
.s4
.texPalAddr
.ui
= 0;
1645 imesa
->globalRegMask
.s4
.texCtrl
[0].ui
= 0;
1646 imesa
->globalRegMask
.s4
.texCtrl
[1].ui
= 0;
1647 imesa
->globalRegMask
.s4
.texAddr
[0].ui
= 0;
1648 imesa
->globalRegMask
.s4
.texAddr
[1].ui
= 0;
1649 imesa
->globalRegMask
.s4
.texBlendCtrl
[0].ui
= 0;
1650 imesa
->globalRegMask
.s4
.texBlendCtrl
[1].ui
= 0;
1651 imesa
->globalRegMask
.s4
.texXprClr
.ui
= 0;
1652 imesa
->globalRegMask
.s4
.texDescr
.ui
= 0;
1654 static void savageDDInitState_s3d( savageContextPtr imesa
)
1657 imesa
->regs
.s3d
.destCtrl
.ui
= 1<<7;
1660 imesa
->regs
.s3d
.zBufCtrl
.ni
.zCmpFunc
= CF_Less
;
1662 imesa
->regs
.s3d
.drawCtrl
.ni
.xyOffsetEn
= 1;
1665 /* Set DestTexWatermarks_31,30 to 01 always.
1666 *Has no effect if dest. flush is disabled.
1669 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x12000C04;
1670 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x40200400;
1672 imesa
->regs
.s3d
.zWatermarks
.ui
= 0x16001808;
1673 imesa
->regs
.s3d
.destTexWatermarks
.ui
= 0x4f000000;
1676 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1677 * alpha blending working properly
1680 imesa
->regs
.s3d
.texCtrl
.ni
.dBias
= 0x08;
1681 imesa
->regs
.s3d
.texCtrl
.ni
.texXprEn
= GL_TRUE
;
1683 imesa
->regs
.s3d
.zBufCtrl
.ni
.drawUpdateEn
= GL_TRUE
;
1684 imesa
->regs
.s3d
.zBufCtrl
.ni
.wrZafterAlphaTst
= GL_FALSE
;
1685 imesa
->regs
.s3d
.zBufCtrl
.ni
.zUpdateEn
= GL_TRUE
;
1687 imesa
->regs
.s3d
.drawCtrl
.ni
.srcAlphaMode
= SAM_One
;
1688 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdZbufWrites
= GL_TRUE
;
1689 imesa
->regs
.s3d
.drawCtrl
.ni
.flushPdDestWrites
= GL_TRUE
;
1691 imesa
->regs
.s3d
.drawCtrl
.ni
.ditherEn
= (
1692 driQueryOptioni(&imesa
->optionCache
, "color_reduction") ==
1693 DRI_CONF_COLOR_REDUCTION_DITHER
) ? GL_TRUE
: GL_FALSE
;
1694 imesa
->regs
.s3d
.drawCtrl
.ni
.cullMode
= BCM_None
;
1696 imesa
->LcsCullMode
= BCM_None
;
1697 imesa
->regs
.s3d
.texDescr
.ni
.palSize
= TPS_256
;
1699 /* clear the local registers in the global reg mask */
1700 imesa
->globalRegMask
.s3d
.texPalAddr
.ui
= 0;
1701 imesa
->globalRegMask
.s3d
.texXprClr
.ui
= 0;
1702 imesa
->globalRegMask
.s3d
.texAddr
.ui
= 0;
1703 imesa
->globalRegMask
.s3d
.texDescr
.ui
= 0;
1704 imesa
->globalRegMask
.s3d
.texCtrl
.ui
= 0;
1706 imesa
->globalRegMask
.s3d
.fogCtrl
.ui
= 0;
1708 /* drawCtrl is local with some exceptions */
1709 imesa
->globalRegMask
.s3d
.drawCtrl
.ui
= 0;
1710 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.cullMode
= 0x3;
1711 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestCmpFunc
= 0x7;
1712 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaTestEn
= 0x1;
1713 imesa
->globalRegMask
.s3d
.drawCtrl
.ni
.alphaRefVal
= 0xff;
1715 /* zBufCtrl is local with some exceptions */
1716 imesa
->globalRegMask
.s3d
.zBufCtrl
.ui
= 0;
1717 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zCmpFunc
= 0x7;
1718 imesa
->globalRegMask
.s3d
.zBufCtrl
.ni
.zBufEn
= 0x1;
1720 void savageDDInitState( savageContextPtr imesa
) {
1721 memset (imesa
->regs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1722 memset (imesa
->oldRegs
.ui
, 0, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1723 memset (imesa
->globalRegMask
.ui
, 0xff, SAVAGE_NR_REGS
*sizeof(u_int32_t
));
1724 if (imesa
->savageScreen
->chipset
>= S3_SAVAGE4
)
1725 savageDDInitState_s4 (imesa
);
1727 savageDDInitState_s3d (imesa
);
1729 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1730 /* zbufoffset and destctrl have the same position and layout on
1731 * savage4 and savage3d. */
1732 imesa
->regs
.s4
.destCtrl
.ni
.offset
= imesa
->savageScreen
->backOffset
>>11;
1733 if(imesa
->savageScreen
->cpp
== 2)
1735 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 0;
1736 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1737 (imesa
->savageScreen
->width
+63)>>6;
1741 imesa
->regs
.s4
.destCtrl
.ni
.dstPixFmt
= 1;
1742 imesa
->regs
.s4
.destCtrl
.ni
.dstWidthInTile
=
1743 (imesa
->savageScreen
->width
+31)>>5;
1746 imesa
->IsDouble
= GL_TRUE
;
1748 imesa
->NotFirstFrame
= GL_FALSE
;
1749 imesa
->regs
.s4
.zBufOffset
.ni
.offset
=imesa
->savageScreen
->depthOffset
>>11;
1750 if(imesa
->savageScreen
->zpp
== 2)
1752 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1753 (imesa
->savageScreen
->width
+63)>>6;
1754 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 0;
1758 imesa
->regs
.s4
.zBufOffset
.ni
.zBufWidthInTiles
=
1759 (imesa
->savageScreen
->width
+31)>>5;
1760 imesa
->regs
.s4
.zBufOffset
.ni
.zDepthSelect
= 1;
1763 if (imesa
->glCtx
->Color
._DrawDestMask
[0] == DD_BACK_LEFT_BIT
) {
1764 if(imesa
->IsFullScreen
)
1766 imesa
->toggle
= TARGET_BACK
;
1768 imesa
->drawMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1769 imesa
->readMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1773 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1774 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1779 if(imesa
->IsFullScreen
)
1781 imesa
->toggle
= TARGET_BACK
;
1783 imesa
->drawMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1784 imesa
->readMap
= (char *)imesa
->apertureBase
[imesa
->toggle
];
1788 imesa
->drawMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1789 imesa
->readMap
= (char *)imesa
->apertureBase
[TARGET_BACK
];
1795 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1796 NEW_TEXTURE_MATRIX|\
1797 NEW_USER_CLIP|NEW_CLIENT_STATE))
1799 void savageDDRenderStart(GLcontext
*ctx
)
1801 savageContextPtr imesa
= SAVAGE_CONTEXT( ctx
);
1802 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1803 drm_clip_rect_t
*pbox
;
1806 /* if the screen is overrided by other application. set the scissor.
1807 * In MulitPass, re-render the screen.
1809 pbox
= dPriv
->pClipRects
;
1810 nbox
= dPriv
->numClipRects
;
1813 imesa
->currentClip
= nbox
;
1814 /* set scissor to the first clip box*/
1815 savageDDScissor(ctx
,pbox
->x1
,pbox
->y1
,pbox
->x2
,pbox
->y2
);
1817 /*savageDDUpdateHwState(ctx);*/ /* update to hardware register*/
1819 else /* need not render at all*/
1821 /*ctx->VB->CopyStart = ctx->VB->Count;*/
1826 void savageDDRenderEnd(GLcontext
*ctx
)
1830 static void savageDDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
1832 _swrast_InvalidateState( ctx
, new_state
);
1833 _swsetup_InvalidateState( ctx
, new_state
);
1834 _ac_InvalidateState( ctx
, new_state
);
1835 _tnl_InvalidateState( ctx
, new_state
);
1836 SAVAGE_CONTEXT(ctx
)->new_gl_state
|= new_state
;
1840 void savageDDInitStateFuncs(GLcontext
*ctx
)
1842 ctx
->Driver
.UpdateState
= savageDDInvalidateState
;
1843 ctx
->Driver
.BlendEquationSeparate
= savageDDBlendEquationSeparate
;
1844 ctx
->Driver
.Fogfv
= savageDDFogfv
;
1845 ctx
->Driver
.Scissor
= savageDDScissor
;
1847 ctx
->Driver
.CullFace
= savageDDCullFaceFrontFace
;
1848 ctx
->Driver
.FrontFace
= savageDDCullFaceFrontFace
;
1850 ctx
->Driver
.CullFace
= 0;
1851 ctx
->Driver
.FrontFace
= 0;
1852 #endif /* end #if HW_CULL */
1853 ctx
->Driver
.PolygonMode
=NULL
;
1854 ctx
->Driver
.PolygonStipple
= 0;
1855 ctx
->Driver
.LineStipple
= 0;
1856 ctx
->Driver
.LineWidth
= 0;
1857 ctx
->Driver
.LogicOpcode
= 0;
1858 ctx
->Driver
.DrawBuffer
= savageDDDrawBuffer
;
1859 ctx
->Driver
.ReadBuffer
= savageDDReadBuffer
;
1860 ctx
->Driver
.ClearColor
= savageDDClearColor
;
1862 ctx
->Driver
.DepthRange
= savageDepthRange
;
1863 ctx
->Driver
.Viewport
= savageViewport
;
1864 ctx
->Driver
.RenderMode
= savageRenderMode
;
1866 ctx
->Driver
.ClearIndex
= 0;
1867 ctx
->Driver
.IndexMask
= 0;
1869 if (SAVAGE_CONTEXT( ctx
)->savageScreen
->chipset
>= S3_SAVAGE4
) {
1870 ctx
->Driver
.Enable
= savageDDEnable_s4
;
1871 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s4
;
1872 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s4
;
1873 ctx
->Driver
.DepthMask
= savageDDDepthMask_s4
;
1874 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s4
;
1875 ctx
->Driver
.ColorMask
= savageDDColorMask_s4
;
1876 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s4
;
1877 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s4
;
1878 ctx
->Driver
.StencilFunc
= savageDDStencilFunc
;
1879 ctx
->Driver
.StencilMask
= savageDDStencilMask
;
1880 ctx
->Driver
.StencilOp
= savageDDStencilOp
;
1882 ctx
->Driver
.Enable
= savageDDEnable_s3d
;
1883 ctx
->Driver
.AlphaFunc
= savageDDAlphaFunc_s3d
;
1884 ctx
->Driver
.DepthFunc
= savageDDDepthFunc_s3d
;
1885 ctx
->Driver
.DepthMask
= savageDDDepthMask_s3d
;
1886 ctx
->Driver
.BlendFuncSeparate
= savageDDBlendFuncSeparate_s3d
;
1887 ctx
->Driver
.ColorMask
= savageDDColorMask_s3d
;
1888 ctx
->Driver
.ShadeModel
= savageDDShadeModel_s3d
;
1889 ctx
->Driver
.LightModelfv
= savageDDLightModelfv_s3d
;
1890 ctx
->Driver
.StencilFunc
= 0;
1891 ctx
->Driver
.StencilMask
= 0;
1892 ctx
->Driver
.StencilOp
= 0;
1895 /* Swrast hooks for imaging extensions:
1897 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1898 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1899 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1900 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;