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 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
&= ~BUFFER_BIT_DEPTH
;
123 if (ctx
->Visual
.stencilBits
== 0)
124 mask
&= ~BUFFER_BIT_STENCIL
;
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
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0) ||
136 ((ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff &&
137 (mask
& BUFFER_BIT_STENCIL
) != 0) )
139 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
142 if ( mask
& BUFFER_BIT_FRONT_LEFT
|| mask
& BUFFER_BIT_BACK_LEFT
) {
143 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
144 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
147 if (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
)) {
148 if (smesa
->depth
.offset
!= 0)
149 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
150 mask
&= ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
);
156 _swrast_Clear( ctx
, mask
, all
, x1
, y1
, width
, height
);
161 sisDDClearColor( GLcontext
* ctx
, const GLfloat color
[4] )
163 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
166 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
167 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
168 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
169 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
171 set_color_pattern( smesa
, c
[0], c
[1], c
[2], c
[3] );
175 sisDDClearDepth( GLcontext
* ctx
, GLclampd d
)
177 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
179 sisUpdateZStencilPattern( smesa
, d
, ctx
->Stencil
.Clear
);
183 sisDDClearStencil( GLcontext
* ctx
, GLint s
)
185 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
187 sisUpdateZStencilPattern( smesa
, ctx
->Depth
.Clear
, s
);
191 sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
192 GLint x
, GLint y
, GLint width
, GLint height
)
194 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
196 __GLSiSHardware
*current
= &smesa
->current
;
198 float left
, top
, right
, bottom
, zClearVal
;
199 GLboolean bClrColor
, bClrDepth
, bClrStencil
;
200 GLint dwPrimitiveSet
;
201 GLint dwEnable1
= 0, dwEnable2
= MASK_ColorMaskWriteEnable
;
202 GLint dwDepthMask
= 0, dwSten1
= 0, dwSten2
= 0;
203 GLint dirtyflags
= GFLAG_ENABLESETTING
| GFLAG_ENABLESETTING2
|
204 GFLAG_CLIPPING
| GFLAG_DESTSETTING
;
206 drm_clip_rect_t
*pExtents
;
208 bClrColor
= (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0;
209 bClrDepth
= (mask
& BUFFER_BIT_DEPTH
) != 0;
210 bClrStencil
= (mask
& BUFFER_BIT_STENCIL
) != 0;
212 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
213 sis_update_render_state( smesa
);
216 dwSten1
= STENCIL_FORMAT_8
| SiS_STENCIL_ALWAYS
|
217 ((ctx
->Stencil
.Clear
& 0xff) << 8) | 0xff;
218 dwSten2
= SiS_SFAIL_REPLACE
| SiS_SPASS_ZFAIL_REPLACE
|
219 SiS_SPASS_ZPASS_REPLACE
;
220 dwEnable1
= MASK_ZWriteEnable
| MASK_StencilWriteEnable
|
221 MASK_StencilTestEnable
;
222 dwEnable2
|= MASK_ZMaskWriteEnable
;
223 dwDepthMask
|= (ctx
->Stencil
.WriteMask
[0] & 0xff) << 24;
224 } else if (bClrDepth
) {
225 dwEnable1
= MASK_ZWriteEnable
;
226 dwEnable2
|= MASK_ZMaskWriteEnable
;
230 zClearVal
= ctx
->Depth
.Clear
;
231 if (ctx
->Visual
.depthBits
!= 32)
232 dwDepthMask
|= 0x00ffffff;
234 dwDepthMask
= 0xffffffff;
239 MMIO(REG_3D_TEnable
, dwEnable1
);
240 MMIO(REG_3D_TEnable2
, dwEnable2
);
241 if (bClrDepth
|| bClrStencil
) {
242 MMIO(REG_3D_ZSet
, (current
->hwZ
& ~MASK_ZTestMode
) | SiS_Z_COMP_ALWAYS
);
243 dirtyflags
|= GFLAG_ZSETTING
;
246 MMIO(REG_3D_DstSet
, (current
->hwDstSet
& ~MASK_ROP2
) | LOP_COPY
);
248 MMIO(REG_3D_DstAlphaWriteMask
, 0L);
251 MMIO(REG_3D_StencilSet
, dwSten1
);
252 MMIO(REG_3D_StencilSet2
, dwSten2
);
253 dirtyflags
|= GFLAG_STENCILSETTING
;
256 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
257 pExtents
= smesa
->driDrawable
->pClipRects
;
258 count
= smesa
->driDrawable
->numClipRects
;
270 if (pExtents
!= NULL
) {
271 GLuint x1
, y1
, x2
, y2
;
273 x1
= pExtents
->x1
- smesa
->driDrawable
->x
;
274 y1
= pExtents
->y1
- smesa
->driDrawable
->y
;
275 x2
= pExtents
->x2
- smesa
->driDrawable
->x
- 1;
276 y2
= pExtents
->y2
- smesa
->driDrawable
->y
- 1;
278 left
= (left
> x1
) ? left
: x1
;
279 right
= (right
> x2
) ? x2
: right
;
280 top
= (top
> y1
) ? top
: y1
;
281 bottom
= (bottom
> y2
) ? y2
: bottom
;
283 if (left
> right
|| top
> bottom
)
289 MMIO(REG_3D_ClipTopBottom
, ((GLint
)top
<< 13) | (GLint
)bottom
);
290 MMIO(REG_3D_ClipLeftRight
, ((GLint
)left
<< 13) | (GLint
)right
);
292 /* the first triangle */
293 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBc
|
295 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
297 MMIO(REG_3D_TSZa
, *(GLint
*) &zClearVal
);
298 MMIO(REG_3D_TSXa
, *(GLint
*) &right
);
299 MMIO(REG_3D_TSYa
, *(GLint
*) &top
);
300 MMIO(REG_3D_TSARGBa
, smesa
->clearColorPattern
);
302 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
303 MMIO(REG_3D_TSXb
, *(GLint
*) &left
);
304 MMIO(REG_3D_TSYb
, *(GLint
*) &top
);
305 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
307 MMIO(REG_3D_TSZc
, *(GLint
*) &zClearVal
);
308 MMIO(REG_3D_TSXc
, *(GLint
*) &left
);
309 MMIO(REG_3D_TSYc
, *(GLint
*) &bottom
);
310 MMIO(REG_3D_TSARGBc
, smesa
->clearColorPattern
);
312 /* second triangle */
313 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBb
|
315 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
317 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
318 MMIO(REG_3D_TSXb
, *(GLint
*) &right
);
319 MMIO(REG_3D_TSYb
, *(GLint
*) &bottom
);
320 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
325 /* If BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */
326 if ((mask
& BUFFER_BIT_FRONT_LEFT
) != 0 && (mask
& BUFFER_BIT_BACK_LEFT
) != 0)
327 sis_3D_Clear( ctx
, BUFFER_BIT_BACK_LEFT
, x
, y
, width
, height
);
329 smesa
->GlobalFlag
|= dirtyflags
;
331 return mask
& ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
| BUFFER_BIT_BACK_LEFT
|
332 BUFFER_BIT_FRONT_LEFT
);
336 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
337 GLint width
, GLint height
)
339 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
342 GLuint depth
= smesa
->bytesPerPixel
;
343 drm_clip_rect_t
*pExtents
= NULL
;
345 GLint x0
, y0
, width0
, height0
;
347 /* Clear back buffer */
348 if (mask
& BUFFER_BIT_BACK_LEFT
) {
350 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
351 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
352 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
353 MMIO(REG_DST_ADDR
, smesa
->back
.offset
);
354 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->back
.pitch
);
355 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
356 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
357 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
358 MMIO(REG_CommandQueue
, -1);
361 if ((mask
& BUFFER_BIT_FRONT_LEFT
) == 0)
364 /* Clear front buffer */
370 pExtents
= smesa
->driDrawable
->pClipRects
;
371 count
= smesa
->driDrawable
->numClipRects
;
374 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
375 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
376 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
377 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
379 x
= (x0
> x2
) ? x0
: x2
;
380 y
= (y0
> y2
) ? y0
: y2
;
381 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
382 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
387 if (width
<= 0 || height
<= 0)
393 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
394 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
395 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
396 MMIO(REG_DST_ADDR
, smesa
->front
.offset
);
397 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->front
.pitch
);
398 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
399 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
400 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
401 MMIO(REG_CommandQueue
, -1);
406 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
407 GLint x
, GLint y
, GLint width
, GLint height
)
409 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
413 MMIO(REG_SRC_PITCH
, (smesa
->zFormat
== SiS_ZFORMAT_Z16
) ?
414 BLIT_DEPTH_16
: BLIT_DEPTH_32
);
415 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
416 MMIO(REG_DST_ADDR
, smesa
->depth
.offset
);
417 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->depth
.pitch
);
418 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
419 MMIO(REG_PATFG
, smesa
->clearZStencilPattern
);
420 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
421 MMIO(REG_CommandQueue
, -1);