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
, GLboolean allFoo
,
99 GLint xFoo
, GLint yFoo
, GLint widthFoo
, GLint heightFoo
)
101 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
103 GLint x1
, y1
, width1
, height1
;
105 /* get region after locking: */
106 x1
= ctx
->DrawBuffer
->_Xmin
;
107 y1
= ctx
->DrawBuffer
->_Ymin
;
108 width1
= ctx
->DrawBuffer
->_Xmax
- x1
;
109 height1
= ctx
->DrawBuffer
->_Ymax
- y1
;
110 y1
= Y_FLIP(y1
+ height1
- 1);
112 /* Mask out any non-existent buffers */
113 if (ctx
->Visual
.depthBits
== 0 || !ctx
->Depth
.Mask
)
114 mask
&= ~BUFFER_BIT_DEPTH
;
115 if (ctx
->Visual
.stencilBits
== 0)
116 mask
&= ~BUFFER_BIT_STENCIL
;
120 /* The 3d clear code is use for masked clears because apparently the SiS
121 * 300-series can't do write masks for 2d blits. 3d isn't used in general
122 * because it's slower, even in the case of clearing multiple buffers.
124 /* XXX: Appears to be broken with stencil. */
125 if ((smesa
->current
.hwCapEnable2
& (MASK_AlphaMaskWriteEnable
|
126 MASK_ColorMaskWriteEnable
) &&
127 (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0) ||
128 ((ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff &&
129 (mask
& BUFFER_BIT_STENCIL
) != 0) )
131 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
134 if ( mask
& BUFFER_BIT_FRONT_LEFT
|| mask
& BUFFER_BIT_BACK_LEFT
) {
135 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
136 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
139 if (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
)) {
140 if (smesa
->depth
.offset
!= 0)
141 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
142 mask
&= ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
);
148 _swrast_Clear( ctx
, mask
, 0, 0, 0, 0, 0);
153 sisDDClearColor( GLcontext
* ctx
, const GLfloat color
[4] )
155 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
158 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
159 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
160 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
161 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
163 set_color_pattern( smesa
, c
[0], c
[1], c
[2], c
[3] );
167 sisDDClearDepth( GLcontext
* ctx
, GLclampd d
)
169 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
171 sisUpdateZStencilPattern( smesa
, d
, ctx
->Stencil
.Clear
);
175 sisDDClearStencil( GLcontext
* ctx
, GLint s
)
177 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
179 sisUpdateZStencilPattern( smesa
, ctx
->Depth
.Clear
, s
);
183 sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
184 GLint x
, GLint y
, GLint width
, GLint height
)
186 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
188 __GLSiSHardware
*current
= &smesa
->current
;
190 float left
, top
, right
, bottom
, zClearVal
;
191 GLboolean bClrColor
, bClrDepth
, bClrStencil
;
192 GLint dwPrimitiveSet
;
193 GLint dwEnable1
= 0, dwEnable2
= MASK_ColorMaskWriteEnable
;
194 GLint dwDepthMask
= 0, dwSten1
= 0, dwSten2
= 0;
195 GLint dirtyflags
= GFLAG_ENABLESETTING
| GFLAG_ENABLESETTING2
|
196 GFLAG_CLIPPING
| GFLAG_DESTSETTING
;
198 drm_clip_rect_t
*pExtents
;
200 bClrColor
= (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0;
201 bClrDepth
= (mask
& BUFFER_BIT_DEPTH
) != 0;
202 bClrStencil
= (mask
& BUFFER_BIT_STENCIL
) != 0;
204 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
205 sis_update_render_state( smesa
);
208 dwSten1
= STENCIL_FORMAT_8
| SiS_STENCIL_ALWAYS
|
209 ((ctx
->Stencil
.Clear
& 0xff) << 8) | 0xff;
210 dwSten2
= SiS_SFAIL_REPLACE
| SiS_SPASS_ZFAIL_REPLACE
|
211 SiS_SPASS_ZPASS_REPLACE
;
212 dwEnable1
= MASK_ZWriteEnable
| MASK_StencilWriteEnable
|
213 MASK_StencilTestEnable
;
214 dwEnable2
|= MASK_ZMaskWriteEnable
;
215 dwDepthMask
|= (ctx
->Stencil
.WriteMask
[0] & 0xff) << 24;
216 } else if (bClrDepth
) {
217 dwEnable1
= MASK_ZWriteEnable
;
218 dwEnable2
|= MASK_ZMaskWriteEnable
;
222 zClearVal
= ctx
->Depth
.Clear
;
223 if (ctx
->Visual
.depthBits
!= 32)
224 dwDepthMask
|= 0x00ffffff;
226 dwDepthMask
= 0xffffffff;
231 MMIO(REG_3D_TEnable
, dwEnable1
);
232 MMIO(REG_3D_TEnable2
, dwEnable2
);
233 if (bClrDepth
|| bClrStencil
) {
234 MMIO(REG_3D_ZSet
, (current
->hwZ
& ~MASK_ZTestMode
) | SiS_Z_COMP_ALWAYS
);
235 dirtyflags
|= GFLAG_ZSETTING
;
238 MMIO(REG_3D_DstSet
, (current
->hwDstSet
& ~MASK_ROP2
) | LOP_COPY
);
240 MMIO(REG_3D_DstAlphaWriteMask
, 0L);
243 MMIO(REG_3D_StencilSet
, dwSten1
);
244 MMIO(REG_3D_StencilSet2
, dwSten2
);
245 dirtyflags
|= GFLAG_STENCILSETTING
;
248 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
249 pExtents
= smesa
->driDrawable
->pClipRects
;
250 count
= smesa
->driDrawable
->numClipRects
;
262 if (pExtents
!= NULL
) {
263 GLuint x1
, y1
, x2
, y2
;
265 x1
= pExtents
->x1
- smesa
->driDrawable
->x
;
266 y1
= pExtents
->y1
- smesa
->driDrawable
->y
;
267 x2
= pExtents
->x2
- smesa
->driDrawable
->x
- 1;
268 y2
= pExtents
->y2
- smesa
->driDrawable
->y
- 1;
270 left
= (left
> x1
) ? left
: x1
;
271 right
= (right
> x2
) ? x2
: right
;
272 top
= (top
> y1
) ? top
: y1
;
273 bottom
= (bottom
> y2
) ? y2
: bottom
;
275 if (left
> right
|| top
> bottom
)
281 MMIO(REG_3D_ClipTopBottom
, ((GLint
)top
<< 13) | (GLint
)bottom
);
282 MMIO(REG_3D_ClipLeftRight
, ((GLint
)left
<< 13) | (GLint
)right
);
284 /* the first triangle */
285 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBc
|
287 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
289 MMIO(REG_3D_TSZa
, *(GLint
*) &zClearVal
);
290 MMIO(REG_3D_TSXa
, *(GLint
*) &right
);
291 MMIO(REG_3D_TSYa
, *(GLint
*) &top
);
292 MMIO(REG_3D_TSARGBa
, smesa
->clearColorPattern
);
294 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
295 MMIO(REG_3D_TSXb
, *(GLint
*) &left
);
296 MMIO(REG_3D_TSYb
, *(GLint
*) &top
);
297 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
299 MMIO(REG_3D_TSZc
, *(GLint
*) &zClearVal
);
300 MMIO(REG_3D_TSXc
, *(GLint
*) &left
);
301 MMIO(REG_3D_TSYc
, *(GLint
*) &bottom
);
302 MMIO(REG_3D_TSARGBc
, smesa
->clearColorPattern
);
304 /* second triangle */
305 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBb
|
307 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
309 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
310 MMIO(REG_3D_TSXb
, *(GLint
*) &right
);
311 MMIO(REG_3D_TSYb
, *(GLint
*) &bottom
);
312 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
317 /* If BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */
318 if ((mask
& BUFFER_BIT_FRONT_LEFT
) != 0 && (mask
& BUFFER_BIT_BACK_LEFT
) != 0)
319 sis_3D_Clear( ctx
, BUFFER_BIT_BACK_LEFT
, x
, y
, width
, height
);
321 smesa
->GlobalFlag
|= dirtyflags
;
323 return mask
& ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
| BUFFER_BIT_BACK_LEFT
|
324 BUFFER_BIT_FRONT_LEFT
);
328 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
329 GLint width
, GLint height
)
331 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
334 GLuint depth
= smesa
->bytesPerPixel
;
335 drm_clip_rect_t
*pExtents
= NULL
;
337 GLint x0
, y0
, width0
, height0
;
339 /* Clear back buffer */
340 if (mask
& BUFFER_BIT_BACK_LEFT
) {
342 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
343 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
344 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
345 MMIO(REG_DST_ADDR
, smesa
->back
.offset
);
346 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->back
.pitch
);
347 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
348 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
349 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
350 MMIO(REG_CommandQueue
, -1);
353 if ((mask
& BUFFER_BIT_FRONT_LEFT
) == 0)
356 /* Clear front buffer */
362 pExtents
= smesa
->driDrawable
->pClipRects
;
363 count
= smesa
->driDrawable
->numClipRects
;
366 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
367 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
368 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
369 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
371 x
= (x0
> x2
) ? x0
: x2
;
372 y
= (y0
> y2
) ? y0
: y2
;
373 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
374 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
379 if (width
<= 0 || height
<= 0)
385 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
386 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
387 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
388 MMIO(REG_DST_ADDR
, smesa
->front
.offset
);
389 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->front
.pitch
);
390 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
391 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
392 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
393 MMIO(REG_CommandQueue
, -1);
398 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
399 GLint x
, GLint y
, GLint width
, GLint height
)
401 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
405 MMIO(REG_SRC_PITCH
, (smesa
->zFormat
== SiS_ZFORMAT_Z16
) ?
406 BLIT_DEPTH_16
: BLIT_DEPTH_32
);
407 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
408 MMIO(REG_DST_ADDR
, smesa
->depth
.offset
);
409 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->depth
.pitch
);
410 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
411 MMIO(REG_PATFG
, smesa
->clearZStencilPattern
);
412 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
413 MMIO(REG_CommandQueue
, -1);