1 /**************************************************************************
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
27 /* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_clear.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
35 #include "sis_context.h"
36 #include "sis_state.h"
39 #include "swrast/swrast.h"
42 static GLbitfield
sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
43 GLint x
, GLint y
, GLint width
,
46 static void sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
,
47 GLint y
, GLint width
, GLint height
);
48 static void sis_clear_z_stencil_buffer( GLcontext
* ctx
,
49 GLbitfield mask
, GLint x
,
54 set_color_pattern( sisContextPtr smesa
, GLubyte red
, GLubyte green
,
55 GLubyte blue
, GLubyte alpha
)
57 /* XXX only RGB565 and ARGB8888 */
58 switch (GET_ColorFormat(smesa
))
60 case DST_FORMAT_ARGB_8888
:
61 smesa
->clearColorPattern
= (alpha
<< 24) +
62 (red
<< 16) + (green
<< 8) + (blue
);
64 case DST_FORMAT_RGB_565
:
65 smesa
->clearColorPattern
= ((red
>> 3) << 11) +
66 ((green
>> 2) << 5) + (blue
>> 3);
67 smesa
->clearColorPattern
|= smesa
->clearColorPattern
<< 16;
75 sisUpdateZStencilPattern( sisContextPtr smesa
, GLclampd z
, GLint stencil
)
82 zPattern
= 0xFFFFFFFF;
84 zPattern
= doFPtoFixedNoRound( z
, 32 );
86 switch (smesa
->zFormat
)
89 zPattern
= zPattern
>> 16;
90 zPattern
|= zPattern
<< 16;
92 case SiS_ZFORMAT_S8Z24
:
93 zPattern
= zPattern
>> 8;
94 zPattern
|= stencil
<< 24;
101 smesa
->clearZStencilPattern
= zPattern
;
105 sisDDClear( GLcontext
* ctx
, GLbitfield mask
, GLboolean all
,
106 GLint x
, GLint y
, GLint width
, GLint height
)
108 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
110 GLint x1
, y1
, width1
, height1
;
113 GLframebuffer
*buffer
= ctx
->DrawBuffer
;
117 width1
= buffer
->Width
;
118 height1
= buffer
->Height
;
121 y1
= Y_FLIP(y
+height
-1);
129 /* The 3d clear code is disabled because it appears to be slower, even
130 * in the case of being requested to clear Z and color buffers at the
133 if (mask
& (DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
| DD_STENCIL_BIT
))
135 /* only Clear either depth or stencil buffer */
136 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
140 if ( mask
& DD_FRONT_LEFT_BIT
|| mask
& DD_BACK_LEFT_BIT
) {
141 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
142 mask
&= ~(DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
);
145 if (mask
& (DD_DEPTH_BIT
| DD_STENCIL_BIT
)) {
146 if (smesa
->depthbuffer
!= NULL
)
147 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
148 mask
&= ~(DD_DEPTH_BIT
| DD_STENCIL_BIT
);
154 _swrast_Clear( ctx
, mask
, all
, x1
, y1
, width
, height
);
159 sisDDClearColor( GLcontext
* ctx
, const GLfloat color
[4] )
161 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
164 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
165 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
166 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
167 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
169 set_color_pattern( smesa
, c
[0], c
[1], c
[2], c
[3] );
173 sisDDClearDepth( GLcontext
* ctx
, GLclampd d
)
175 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
177 sisUpdateZStencilPattern( smesa
, d
, ctx
->Stencil
.Clear
);
181 sisDDClearStencil( GLcontext
* ctx
, GLint s
)
183 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
185 sisUpdateZStencilPattern( smesa
, ctx
->Depth
.Clear
, s
);
190 sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
191 GLint x
, GLint y
, GLint width
, GLint height
)
193 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
195 __GLSiSHardware
*current
= &smesa
->current
;
197 float left
, top
, right
, bottom
, zClearVal
;
198 GLboolean bClrColor
, bClrDepth
, bClrStencil
;
199 GLint dwPrimitiveSet
;
200 GLint dwEnable1
= 0, dwEnable2
= 0, dwDepthMask
= 0, dwSten1
= 0, dwSten2
= 0;
201 GLint dirtyflags
= GFLAG_ENABLESETTING
| GFLAG_ENABLESETTING2
|
202 GFLAG_CLIPPING
| GFLAG_DESTSETTING
;
205 XF86DRIClipRectPtr pExtents
;
207 bClrColor
= ((mask
& DD_BACK_LEFT_BIT
) != 0);
208 bClrDepth
= ((mask
& DD_DEPTH_BIT
) != 0) && (ctx
->Visual
.depthBits
!= 0);
209 bClrStencil
= ((mask
& DD_STENCIL_BIT
) != 0) && (ctx
->Visual
.stencilBits
!= 0);
211 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
212 sis_update_render_state( smesa
);
215 dwEnable2
|= MASK_ColorMaskWriteEnable
;
218 dwSten1
= STENCIL_FORMAT_8
| SiS_STENCIL_ALWAYS
|
219 (ctx
->Stencil
.Clear
<< 8) | 0xff;
220 dwSten2
= SiS_SFAIL_REPLACE
| SiS_SPASS_ZFAIL_REPLACE
|
221 SiS_SPASS_ZPASS_REPLACE
;
222 dwEnable1
= MASK_ZWriteEnable
| MASK_StencilTestEnable
;
223 dwEnable2
|= MASK_ZMaskWriteEnable
;
224 dwDepthMask
|= ctx
->Stencil
.WriteMask
[0] << 24;
225 } else if (bClrDepth
) {
226 dwEnable1
= MASK_ZWriteEnable
;
227 dwEnable2
|= MASK_ZMaskWriteEnable
;
231 zClearVal
= ctx
->Depth
.Clear
;
232 if (ctx
->Visual
.depthBits
!= 32)
233 dwDepthMask
|= 0x00ffffff;
235 dwDepthMask
= 0xffffffff;
240 MMIO(REG_3D_TEnable
, dwEnable1
);
241 MMIO(REG_3D_TEnable2
, dwEnable2
);
242 if (bClrDepth
|| bClrStencil
) {
243 MMIO(REG_3D_ZSet
, (current
->hwZ
& ~MASK_ZTestMode
) | SiS_Z_COMP_ALWAYS
);
244 dirtyflags
|= GFLAG_ZSETTING
;
247 MMIO(REG_3D_DstSet
, (current
->hwDstSet
& ~MASK_ROP2
) | LOP_COPY
);
249 MMIO(REG_3D_DstAlphaWriteMask
, 0L);
252 MMIO(REG_3D_StencilSet
, dwSten1
);
253 MMIO(REG_3D_StencilSet2
, dwSten2
);
254 dirtyflags
|= GFLAG_STENCILSETTING
;
257 if (mask
& DD_FRONT_LEFT_BIT
) {
258 pExtents
= smesa
->driDrawable
->pClipRects
;
259 count
= smesa
->driDrawable
->numClipRects
;
271 if (pExtents
!= NULL
) {
272 GLuint x1
, y1
, x2
, y2
;
274 x1
= pExtents
->x1
- smesa
->driDrawable
->x
;
275 y1
= pExtents
->y1
- smesa
->driDrawable
->y
;
276 x2
= pExtents
->x2
- smesa
->driDrawable
->x
- 1;
277 y2
= pExtents
->y2
- smesa
->driDrawable
->y
- 1;
279 left
= (left
> x1
) ? left
: x1
;
280 right
= (right
> x2
) ? x2
: right
;
281 top
= (top
> y1
) ? top
: y1
;
282 bottom
= (bottom
> y2
) ? y2
: bottom
;
284 if (left
> right
|| top
> bottom
)
290 MMIO(REG_3D_ClipTopBottom
, ((GLint
)top
<< 13) | (GLint
)bottom
);
291 MMIO(REG_3D_ClipLeftRight
, ((GLint
)left
<< 13) | (GLint
)right
);
293 /* the first triangle */
294 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBc
|
296 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
298 MMIO(REG_3D_TSZa
, *(GLint
*) &zClearVal
);
299 MMIO(REG_3D_TSXa
, *(GLint
*) &right
);
300 MMIO(REG_3D_TSYa
, *(GLint
*) &top
);
301 MMIO(REG_3D_TSARGBa
, smesa
->clearColorPattern
);
303 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
304 MMIO(REG_3D_TSXb
, *(GLint
*) &left
);
305 MMIO(REG_3D_TSYb
, *(GLint
*) &top
);
306 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
308 MMIO(REG_3D_TSZc
, *(GLint
*) &zClearVal
);
309 MMIO(REG_3D_TSXc
, *(GLint
*) &left
);
310 MMIO(REG_3D_TSYc
, *(GLint
*) &bottom
);
311 MMIO(REG_3D_TSARGBc
, smesa
->clearColorPattern
);
313 /* second triangle */
314 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBb
|
316 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
318 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
319 MMIO(REG_3D_TSXb
, *(GLint
*) &right
);
320 MMIO(REG_3D_TSYb
, *(GLint
*) &bottom
);
321 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
326 smesa
->GlobalFlag
|= dirtyflags
;
328 return (mask
& ~(DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
| DD_STENCIL_BIT
));
333 sis_bitblt_clear_cmd( sisContextPtr smesa
, ENGPACKET
* pkt
)
335 GLint
*lpdwDest
, *lpdwSrc
;
338 lpdwSrc
= (GLint
*) pkt
+ 1;
339 lpdwDest
= (GLint
*) (GET_IOBase (smesa
) + REG_SRC_ADDR
) + 1;
341 mWait3DCmdQueue (10);
343 *lpdwDest
++ = *lpdwSrc
++;
346 for (i
= 3; i
< 8; i
++) {
347 *lpdwDest
++ = *lpdwSrc
++;
350 MMIO(REG_CMD0
, *(GLint
*) & pkt
->stdwCmd
);
351 MMIO(REG_QueueLen
, -1);
355 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
356 GLint width
, GLint height
)
358 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
361 GLuint depth
= GET_DEPTH (smesa
);
362 XF86DRIClipRectPtr pExtents
= NULL
;
364 GLint x0
, y0
, width0
, height0
;
366 ENGPACKET stEngPacket
;
368 /* Clear back buffer */
369 if (mask
& DD_BACK_LEFT_BIT
) {
370 smesa
->cbClearPacket
.stdwDestPos
.wY
= y
;
371 smesa
->cbClearPacket
.stdwDestPos
.wX
= x
;
372 smesa
->cbClearPacket
.stdwDim
.wWidth
= (GLshort
) width
;
373 smesa
->cbClearPacket
.stdwDim
.wHeight
= (GLshort
) height
;
374 smesa
->cbClearPacket
.dwFgRopColor
= smesa
->clearColorPattern
;
376 sis_bitblt_clear_cmd( smesa
, &smesa
->cbClearPacket
);
379 if ((mask
& DD_FRONT_LEFT_BIT
) == 0)
382 /* Clear front buffer */
388 pExtents
= smesa
->driDrawable
->pClipRects
;
389 count
= smesa
->driDrawable
->numClipRects
;
391 memset( &stEngPacket
, 0, sizeof (ENGPACKET
) );
393 stEngPacket
.dwSrcPitch
= (depth
== 2) ? 0x80000000 : 0xc0000000;
394 stEngPacket
.dwDestBaseAddr
= smesa
->frontOffset
;
395 stEngPacket
.wDestPitch
= smesa
->frontPitch
;
396 /* TODO: set maximum value? */
397 stEngPacket
.wDestHeight
= smesa
->virtualY
;
398 stEngPacket
.stdwCmd
.cRop
= 0xf0;
399 stEngPacket
.dwFgRopColor
= smesa
->clearColorPattern
;
401 /* for SGRAM Block Write Enable */
402 if (smesa
->blockWrite
)
403 stEngPacket
.stdwCmd
.cCmd0
= CMD0_PAT_FG_COLOR
;
405 stEngPacket
.stdwCmd
.cCmd0
= 0;
406 stEngPacket
.stdwCmd
.cCmd1
= CMD1_DIR_X_INC
| CMD1_DIR_Y_INC
;
409 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
410 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
411 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
412 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
414 x
= (x0
> x2
) ? x0
: x2
;
415 y
= (y0
> y2
) ? y0
: y2
;
416 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
417 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
422 if (width
<= 0 || height
<= 0)
425 stEngPacket
.stdwDestPos
.wY
= y
;
426 stEngPacket
.stdwDestPos
.wX
= x
;
427 stEngPacket
.stdwDim
.wWidth
= (GLshort
)width
;
428 stEngPacket
.stdwDim
.wHeight
= (GLshort
)height
;
430 sis_bitblt_clear_cmd( smesa
, &stEngPacket
);
435 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
436 GLint x
, GLint y
, GLint width
, GLint height
)
438 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
440 /* TODO: check write mask */
442 if ( smesa
->depthbuffer
== NULL
)
445 /* TODO: consider alignment of width, height? */
446 smesa
->zClearPacket
.stdwDestPos
.wY
= y
;
447 smesa
->zClearPacket
.stdwDestPos
.wX
= x
;
448 smesa
->zClearPacket
.stdwDim
.wWidth
= (GLshort
) width
;
449 smesa
->zClearPacket
.stdwDim
.wHeight
= (GLshort
) height
;
450 smesa
->zClearPacket
.dwFgRopColor
= smesa
->clearZStencilPattern
;
452 sis_bitblt_clear_cmd( smesa
, &smesa
->zClearPacket
);