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 CLAMPED_FLOAT_TO_USHORT(zPattern
, 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
)
100 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
102 GLint x1
, y1
, width1
, height1
;
104 /* get region after locking: */
105 x1
= ctx
->DrawBuffer
->_Xmin
;
106 y1
= ctx
->DrawBuffer
->_Ymin
;
107 width1
= ctx
->DrawBuffer
->_Xmax
- x1
;
108 height1
= ctx
->DrawBuffer
->_Ymax
- y1
;
109 y1
= Y_FLIP(y1
+ height1
- 1);
111 /* Mask out any non-existent buffers */
112 if (ctx
->Visual
.depthBits
== 0 || !ctx
->Depth
.Mask
)
113 mask
&= ~BUFFER_BIT_DEPTH
;
114 if (ctx
->Visual
.stencilBits
== 0)
115 mask
&= ~BUFFER_BIT_STENCIL
;
119 /* The 3d clear code is use for masked clears because apparently the SiS
120 * 300-series can't do write masks for 2d blits. 3d isn't used in general
121 * because it's slower, even in the case of clearing multiple buffers.
123 /* XXX: Appears to be broken with stencil. */
124 if ((smesa
->current
.hwCapEnable2
& (MASK_AlphaMaskWriteEnable
|
125 MASK_ColorMaskWriteEnable
) &&
126 (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0) ||
127 ((ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff &&
128 (mask
& BUFFER_BIT_STENCIL
) != 0) )
130 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
133 if ( mask
& BUFFER_BIT_FRONT_LEFT
|| mask
& BUFFER_BIT_BACK_LEFT
) {
134 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
135 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
138 if (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
)) {
139 if (smesa
->depth
.offset
!= 0)
140 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
141 mask
&= ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
);
147 _swrast_Clear( ctx
, mask
);
152 sisDDClearColor( GLcontext
* ctx
, const GLfloat color
[4] )
154 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
157 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
158 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
159 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
160 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
162 set_color_pattern( smesa
, c
[0], c
[1], c
[2], c
[3] );
166 sisDDClearDepth( GLcontext
* ctx
, GLclampd d
)
168 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
170 sisUpdateZStencilPattern( smesa
, d
, ctx
->Stencil
.Clear
);
174 sisDDClearStencil( GLcontext
* ctx
, GLint s
)
176 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
178 sisUpdateZStencilPattern( smesa
, ctx
->Depth
.Clear
, s
);
182 sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
183 GLint x
, GLint y
, GLint width
, GLint height
)
185 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
187 __GLSiSHardware
*current
= &smesa
->current
;
189 float left
, top
, right
, bottom
, zClearVal
;
190 GLboolean bClrColor
, bClrDepth
, bClrStencil
;
191 GLint dwPrimitiveSet
;
192 GLint dwEnable1
= 0, dwEnable2
= MASK_ColorMaskWriteEnable
;
193 GLint dwDepthMask
= 0, dwSten1
= 0, dwSten2
= 0;
194 GLint dirtyflags
= GFLAG_ENABLESETTING
| GFLAG_ENABLESETTING2
|
195 GFLAG_CLIPPING
| GFLAG_DESTSETTING
;
197 drm_clip_rect_t
*pExtents
;
199 bClrColor
= (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0;
200 bClrDepth
= (mask
& BUFFER_BIT_DEPTH
) != 0;
201 bClrStencil
= (mask
& BUFFER_BIT_STENCIL
) != 0;
203 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
204 sis_update_render_state( smesa
);
207 dwSten1
= STENCIL_FORMAT_8
| SiS_STENCIL_ALWAYS
|
208 ((ctx
->Stencil
.Clear
& 0xff) << 8) | 0xff;
209 dwSten2
= SiS_SFAIL_REPLACE
| SiS_SPASS_ZFAIL_REPLACE
|
210 SiS_SPASS_ZPASS_REPLACE
;
211 dwEnable1
= MASK_ZWriteEnable
| MASK_StencilWriteEnable
|
212 MASK_StencilTestEnable
;
213 dwEnable2
|= MASK_ZMaskWriteEnable
;
214 dwDepthMask
|= (ctx
->Stencil
.WriteMask
[0] & 0xff) << 24;
215 } else if (bClrDepth
) {
216 dwEnable1
= MASK_ZWriteEnable
;
217 dwEnable2
|= MASK_ZMaskWriteEnable
;
221 zClearVal
= ctx
->Depth
.Clear
;
222 if (ctx
->Visual
.depthBits
!= 32)
223 dwDepthMask
|= 0x00ffffff;
225 dwDepthMask
= 0xffffffff;
230 MMIO(REG_3D_TEnable
, dwEnable1
);
231 MMIO(REG_3D_TEnable2
, dwEnable2
);
232 if (bClrDepth
|| bClrStencil
) {
233 MMIO(REG_3D_ZSet
, (current
->hwZ
& ~MASK_ZTestMode
) | SiS_Z_COMP_ALWAYS
);
234 dirtyflags
|= GFLAG_ZSETTING
;
237 MMIO(REG_3D_DstSet
, (current
->hwDstSet
& ~MASK_ROP2
) | LOP_COPY
);
239 MMIO(REG_3D_DstAlphaWriteMask
, 0L);
242 MMIO(REG_3D_StencilSet
, dwSten1
);
243 MMIO(REG_3D_StencilSet2
, dwSten2
);
244 dirtyflags
|= GFLAG_STENCILSETTING
;
247 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
248 pExtents
= smesa
->driDrawable
->pClipRects
;
249 count
= smesa
->driDrawable
->numClipRects
;
261 if (pExtents
!= NULL
) {
262 GLuint x1
, y1
, x2
, y2
;
264 x1
= pExtents
->x1
- smesa
->driDrawable
->x
;
265 y1
= pExtents
->y1
- smesa
->driDrawable
->y
;
266 x2
= pExtents
->x2
- smesa
->driDrawable
->x
- 1;
267 y2
= pExtents
->y2
- smesa
->driDrawable
->y
- 1;
269 left
= (left
> x1
) ? left
: x1
;
270 right
= (right
> x2
) ? x2
: right
;
271 top
= (top
> y1
) ? top
: y1
;
272 bottom
= (bottom
> y2
) ? y2
: bottom
;
274 if (left
> right
|| top
> bottom
)
280 MMIO(REG_3D_ClipTopBottom
, ((GLint
)top
<< 13) | (GLint
)bottom
);
281 MMIO(REG_3D_ClipLeftRight
, ((GLint
)left
<< 13) | (GLint
)right
);
283 /* the first triangle */
284 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBc
|
286 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
288 MMIO(REG_3D_TSZa
, *(GLint
*) &zClearVal
);
289 MMIO(REG_3D_TSXa
, *(GLint
*) &right
);
290 MMIO(REG_3D_TSYa
, *(GLint
*) &top
);
291 MMIO(REG_3D_TSARGBa
, smesa
->clearColorPattern
);
293 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
294 MMIO(REG_3D_TSXb
, *(GLint
*) &left
);
295 MMIO(REG_3D_TSYb
, *(GLint
*) &top
);
296 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
298 MMIO(REG_3D_TSZc
, *(GLint
*) &zClearVal
);
299 MMIO(REG_3D_TSXc
, *(GLint
*) &left
);
300 MMIO(REG_3D_TSYc
, *(GLint
*) &bottom
);
301 MMIO(REG_3D_TSARGBc
, smesa
->clearColorPattern
);
303 /* second triangle */
304 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBb
|
306 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
308 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
309 MMIO(REG_3D_TSXb
, *(GLint
*) &right
);
310 MMIO(REG_3D_TSYb
, *(GLint
*) &bottom
);
311 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
316 /* If BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */
317 if ((mask
& BUFFER_BIT_FRONT_LEFT
) != 0 && (mask
& BUFFER_BIT_BACK_LEFT
) != 0)
318 sis_3D_Clear( ctx
, BUFFER_BIT_BACK_LEFT
, x
, y
, width
, height
);
320 smesa
->GlobalFlag
|= dirtyflags
;
322 return mask
& ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
| BUFFER_BIT_BACK_LEFT
|
323 BUFFER_BIT_FRONT_LEFT
);
327 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
328 GLint width
, GLint height
)
330 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
332 drm_clip_rect_t
*pExtents
= NULL
;
334 GLint x0
, y0
, width0
, height0
;
336 /* Clear back buffer */
337 if (mask
& BUFFER_BIT_BACK_LEFT
) {
339 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
340 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
341 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
342 MMIO(REG_DST_ADDR
, smesa
->back
.offset
);
343 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->back
.pitch
);
344 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
345 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
346 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
347 MMIO(REG_CommandQueue
, -1);
350 if ((mask
& BUFFER_BIT_FRONT_LEFT
) == 0)
353 /* Clear front buffer */
359 pExtents
= smesa
->driDrawable
->pClipRects
;
360 count
= smesa
->driDrawable
->numClipRects
;
363 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
364 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
365 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
366 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
368 x
= (x0
> x2
) ? x0
: x2
;
369 y
= (y0
> y2
) ? y0
: y2
;
370 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
371 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
376 if (width
<= 0 || height
<= 0)
380 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
381 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
382 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
383 MMIO(REG_DST_ADDR
, smesa
->front
.offset
);
384 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->front
.pitch
);
385 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
386 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
387 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
388 MMIO(REG_CommandQueue
, -1);
393 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
394 GLint x
, GLint y
, GLint width
, GLint height
)
396 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
400 MMIO(REG_SRC_PITCH
, (smesa
->zFormat
== SiS_ZFORMAT_Z16
) ?
401 BLIT_DEPTH_16
: BLIT_DEPTH_32
);
402 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
403 MMIO(REG_DST_ADDR
, smesa
->depth
.offset
);
404 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->depth
.pitch
);
405 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
406 MMIO(REG_PATFG
, smesa
->clearZStencilPattern
);
407 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
408 MMIO(REG_CommandQueue
, -1);