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 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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
,
45 static void sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
,
46 GLint y
, GLint width
, GLint height
);
47 static void sis_clear_z_stencil_buffer( GLcontext
* ctx
,
48 GLbitfield mask
, GLint x
,
53 set_color_pattern( sisContextPtr smesa
, GLubyte red
, GLubyte green
,
54 GLubyte blue
, GLubyte alpha
)
56 /* XXX only RGB565 and ARGB8888 */
57 switch (smesa
->colorFormat
)
59 case DST_FORMAT_ARGB_8888
:
60 smesa
->clearColorPattern
= (alpha
<< 24) +
61 (red
<< 16) + (green
<< 8) + (blue
);
63 case DST_FORMAT_RGB_565
:
64 smesa
->clearColorPattern
= ((red
>> 3) << 11) +
65 ((green
>> 2) << 5) + (blue
>> 3);
66 smesa
->clearColorPattern
|= smesa
->clearColorPattern
<< 16;
69 sis_fatal_error("Bad dst color format\n");
74 sisUpdateZStencilPattern( sisContextPtr smesa
, GLclampd z
, GLint stencil
)
78 switch (smesa
->zFormat
)
81 zPattern
= FLOAT_TO_USHORT(z
);
82 zPattern
|= zPattern
<< 16;
84 case SiS_ZFORMAT_S8Z24
:
85 zPattern
= FLOAT_TO_UINT(z
) >> 8;
86 zPattern
|= stencil
<< 24;
89 zPattern
= FLOAT_TO_UINT(z
);
92 sis_fatal_error("Bad Z format\n");
94 smesa
->clearZStencilPattern
= zPattern
;
98 sisDDClear( GLcontext
* ctx
, GLbitfield mask
, GLboolean all
,
99 GLint x
, GLint y
, GLint width
, GLint height
)
101 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
103 GLint x1
, y1
, width1
, height1
;
106 GLframebuffer
*buffer
= ctx
->DrawBuffer
;
110 width1
= buffer
->Width
;
111 height1
= buffer
->Height
;
114 y1
= Y_FLIP(y
+height
-1);
118 /* XXX: Scissoring */
120 /* Mask out any non-existent buffers */
121 if (ctx
->Visual
.depthBits
== 0 || !ctx
->Depth
.Mask
)
122 mask
&= ~DD_DEPTH_BIT
;
123 if (ctx
->Visual
.stencilBits
== 0)
124 mask
&= ~DD_STENCIL_BIT
;
128 /* The 3d clear code is use for masked clears because apparently the SiS
129 * 300-series can't do write masks for 2d blits. 3d isn't used in general
130 * because it's slower, even in the case of clearing multiple buffers.
132 /* XXX: Appears to be broken with stencil. */
133 if ((smesa
->current
.hwCapEnable2
& (MASK_AlphaMaskWriteEnable
|
134 MASK_ColorMaskWriteEnable
) &&
135 (mask
& (DD_BACK_LEFT_BIT
| DD_FRONT_LEFT_BIT
)) != 0) ||
136 (ctx
->Stencil
.WriteMask
[0] < 0xff && (mask
& DD_STENCIL_BIT
) != 0) )
138 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
141 if ( mask
& DD_FRONT_LEFT_BIT
|| mask
& DD_BACK_LEFT_BIT
) {
142 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
143 mask
&= ~(DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
);
146 if (mask
& (DD_DEPTH_BIT
| DD_STENCIL_BIT
)) {
147 if (smesa
->depthbuffer
!= NULL
)
148 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
149 mask
&= ~(DD_DEPTH_BIT
| DD_STENCIL_BIT
);
155 _swrast_Clear( ctx
, mask
, all
, x1
, y1
, width
, height
);
160 sisDDClearColor( GLcontext
* ctx
, const GLfloat color
[4] )
162 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
165 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
166 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
167 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
168 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
170 set_color_pattern( smesa
, c
[0], c
[1], c
[2], c
[3] );
174 sisDDClearDepth( GLcontext
* ctx
, GLclampd d
)
176 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
178 sisUpdateZStencilPattern( smesa
, d
, ctx
->Stencil
.Clear
);
182 sisDDClearStencil( GLcontext
* ctx
, GLint s
)
184 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
186 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
= MASK_ColorMaskWriteEnable
;
201 GLint dwDepthMask
= 0, dwSten1
= 0, dwSten2
= 0;
202 GLint dirtyflags
= GFLAG_ENABLESETTING
| GFLAG_ENABLESETTING2
|
203 GFLAG_CLIPPING
| GFLAG_DESTSETTING
;
205 drm_clip_rect_t
*pExtents
;
207 bClrColor
= (mask
& (DD_BACK_LEFT_BIT
| DD_FRONT_LEFT_BIT
)) != 0;
208 bClrDepth
= (mask
& DD_DEPTH_BIT
) != 0;
209 bClrStencil
= (mask
& DD_STENCIL_BIT
) != 0;
211 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
212 sis_update_render_state( smesa
);
215 dwSten1
= STENCIL_FORMAT_8
| SiS_STENCIL_ALWAYS
|
216 (ctx
->Stencil
.Clear
<< 8) | 0xff;
217 dwSten2
= SiS_SFAIL_REPLACE
| SiS_SPASS_ZFAIL_REPLACE
|
218 SiS_SPASS_ZPASS_REPLACE
;
219 dwEnable1
= MASK_ZWriteEnable
| MASK_StencilWriteEnable
|
220 MASK_StencilTestEnable
;
221 dwEnable2
|= MASK_ZMaskWriteEnable
;
222 dwDepthMask
|= ctx
->Stencil
.WriteMask
[0] << 24;
223 } else if (bClrDepth
) {
224 dwEnable1
= MASK_ZWriteEnable
;
225 dwEnable2
|= MASK_ZMaskWriteEnable
;
229 zClearVal
= ctx
->Depth
.Clear
;
230 if (ctx
->Visual
.depthBits
!= 32)
231 dwDepthMask
|= 0x00ffffff;
233 dwDepthMask
= 0xffffffff;
238 MMIO(REG_3D_TEnable
, dwEnable1
);
239 MMIO(REG_3D_TEnable2
, dwEnable2
);
240 if (bClrDepth
|| bClrStencil
) {
241 MMIO(REG_3D_ZSet
, (current
->hwZ
& ~MASK_ZTestMode
) | SiS_Z_COMP_ALWAYS
);
242 dirtyflags
|= GFLAG_ZSETTING
;
245 MMIO(REG_3D_DstSet
, (current
->hwDstSet
& ~MASK_ROP2
) | LOP_COPY
);
247 MMIO(REG_3D_DstAlphaWriteMask
, 0L);
250 MMIO(REG_3D_StencilSet
, dwSten1
);
251 MMIO(REG_3D_StencilSet2
, dwSten2
);
252 dirtyflags
|= GFLAG_STENCILSETTING
;
255 if (mask
& DD_FRONT_LEFT_BIT
) {
256 pExtents
= smesa
->driDrawable
->pClipRects
;
257 count
= smesa
->driDrawable
->numClipRects
;
269 if (pExtents
!= NULL
) {
270 GLuint x1
, y1
, x2
, y2
;
272 x1
= pExtents
->x1
- smesa
->driDrawable
->x
;
273 y1
= pExtents
->y1
- smesa
->driDrawable
->y
;
274 x2
= pExtents
->x2
- smesa
->driDrawable
->x
- 1;
275 y2
= pExtents
->y2
- smesa
->driDrawable
->y
- 1;
277 left
= (left
> x1
) ? left
: x1
;
278 right
= (right
> x2
) ? x2
: right
;
279 top
= (top
> y1
) ? top
: y1
;
280 bottom
= (bottom
> y2
) ? y2
: bottom
;
282 if (left
> right
|| top
> bottom
)
288 MMIO(REG_3D_ClipTopBottom
, ((GLint
)top
<< 13) | (GLint
)bottom
);
289 MMIO(REG_3D_ClipLeftRight
, ((GLint
)left
<< 13) | (GLint
)right
);
291 /* the first triangle */
292 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBc
|
294 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
296 MMIO(REG_3D_TSZa
, *(GLint
*) &zClearVal
);
297 MMIO(REG_3D_TSXa
, *(GLint
*) &right
);
298 MMIO(REG_3D_TSYa
, *(GLint
*) &top
);
299 MMIO(REG_3D_TSARGBa
, smesa
->clearColorPattern
);
301 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
302 MMIO(REG_3D_TSXb
, *(GLint
*) &left
);
303 MMIO(REG_3D_TSYb
, *(GLint
*) &top
);
304 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
306 MMIO(REG_3D_TSZc
, *(GLint
*) &zClearVal
);
307 MMIO(REG_3D_TSXc
, *(GLint
*) &left
);
308 MMIO(REG_3D_TSYc
, *(GLint
*) &bottom
);
309 MMIO(REG_3D_TSARGBc
, smesa
->clearColorPattern
);
311 /* second triangle */
312 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBb
|
314 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
316 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
317 MMIO(REG_3D_TSXb
, *(GLint
*) &right
);
318 MMIO(REG_3D_TSYb
, *(GLint
*) &bottom
);
319 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
324 /* If DD_FRONT_LEFT_BIT is set, we've only cleared the front buffer so far */
325 if ((mask
& DD_FRONT_LEFT_BIT
) != 0 && (mask
& DD_BACK_LEFT_BIT
) != 0)
326 sis_3D_Clear( ctx
, DD_BACK_LEFT_BIT
, x
, y
, width
, height
);
328 smesa
->GlobalFlag
|= dirtyflags
;
330 return mask
& ~(DD_DEPTH_BIT
| DD_STENCIL_BIT
| DD_BACK_LEFT_BIT
|
335 sis_bitblt_clear_cmd( sisContextPtr smesa
, ENGPACKET
* pkt
)
337 GLint
*lpdwDest
, *lpdwSrc
;
340 lpdwSrc
= (GLint
*) pkt
+ 1;
341 lpdwDest
= (GLint
*) (GET_IOBase (smesa
) + REG_SRC_ADDR
) + 1;
343 mWait3DCmdQueue (10);
345 *lpdwDest
++ = *lpdwSrc
++;
348 for (i
= 3; i
< 8; i
++) {
349 *lpdwDest
++ = *lpdwSrc
++;
352 MMIO(REG_CMD0
, *(GLint
*) & pkt
->stdwCmd
);
353 MMIO(REG_CommandQueue
, -1);
357 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
358 GLint width
, GLint height
)
360 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
363 GLuint depth
= smesa
->bytesPerPixel
;
364 drm_clip_rect_t
*pExtents
= NULL
;
366 GLint x0
, y0
, width0
, height0
;
368 ENGPACKET stEngPacket
;
370 /* Clear back buffer */
371 if (mask
& DD_BACK_LEFT_BIT
) {
372 smesa
->cbClearPacket
.stdwDestPos
.wY
= y
;
373 smesa
->cbClearPacket
.stdwDestPos
.wX
= x
;
374 smesa
->cbClearPacket
.stdwDim
.wWidth
= (GLshort
) width
;
375 smesa
->cbClearPacket
.stdwDim
.wHeight
= (GLshort
) height
;
376 smesa
->cbClearPacket
.dwFgRopColor
= smesa
->clearColorPattern
;
378 sis_bitblt_clear_cmd( smesa
, &smesa
->cbClearPacket
);
381 if ((mask
& DD_FRONT_LEFT_BIT
) == 0)
384 /* Clear front buffer */
390 pExtents
= smesa
->driDrawable
->pClipRects
;
391 count
= smesa
->driDrawable
->numClipRects
;
393 memset( &stEngPacket
, 0, sizeof (ENGPACKET
) );
395 stEngPacket
.dwSrcPitch
= (depth
== 2) ? 0x80000000 : 0xc0000000;
396 stEngPacket
.dwDestBaseAddr
= smesa
->frontOffset
;
397 stEngPacket
.wDestPitch
= smesa
->frontPitch
;
398 /* TODO: set maximum value? */
399 stEngPacket
.wDestHeight
= smesa
->virtualY
;
400 stEngPacket
.stdwCmd
.cRop
= 0xf0;
401 stEngPacket
.dwFgRopColor
= smesa
->clearColorPattern
;
403 /* for SGRAM Block Write Enable */
404 if (smesa
->blockWrite
)
405 stEngPacket
.stdwCmd
.cCmd0
= CMD0_PAT_FG_COLOR
;
407 stEngPacket
.stdwCmd
.cCmd0
= 0;
408 stEngPacket
.stdwCmd
.cCmd1
= CMD1_DIR_X_INC
| CMD1_DIR_Y_INC
;
411 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
412 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
413 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
414 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
416 x
= (x0
> x2
) ? x0
: x2
;
417 y
= (y0
> y2
) ? y0
: y2
;
418 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
419 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
424 if (width
<= 0 || height
<= 0)
427 stEngPacket
.stdwDestPos
.wY
= y
;
428 stEngPacket
.stdwDestPos
.wX
= x
;
429 stEngPacket
.stdwDim
.wWidth
= (GLshort
)width
;
430 stEngPacket
.stdwDim
.wHeight
= (GLshort
)height
;
432 sis_bitblt_clear_cmd( smesa
, &stEngPacket
);
437 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
438 GLint x
, GLint y
, GLint width
, GLint height
)
440 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
442 /* TODO: consider alignment of width, height? */
443 smesa
->zClearPacket
.stdwDestPos
.wY
= y
;
444 smesa
->zClearPacket
.stdwDestPos
.wX
= x
;
445 smesa
->zClearPacket
.stdwDim
.wWidth
= (GLshort
) width
;
446 smesa
->zClearPacket
.stdwDim
.wHeight
= (GLshort
) height
;
447 smesa
->zClearPacket
.dwFgRopColor
= smesa
->clearZStencilPattern
;
449 sis_bitblt_clear_cmd( smesa
, &smesa
->zClearPacket
);