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 && (mask
& BUFFER_BIT_STENCIL
) != 0) )
138 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
141 if ( mask
& BUFFER_BIT_FRONT_LEFT
|| mask
& BUFFER_BIT_BACK_LEFT
) {
142 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
143 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
146 if (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
)) {
147 if (smesa
->depth
.offset
!= 0)
148 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
149 mask
&= ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
);
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
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0;
208 bClrDepth
= (mask
& BUFFER_BIT_DEPTH
) != 0;
209 bClrStencil
= (mask
& BUFFER_BIT_STENCIL
) != 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
& BUFFER_BIT_FRONT_LEFT
) {
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 BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */
325 if ((mask
& BUFFER_BIT_FRONT_LEFT
) != 0 && (mask
& BUFFER_BIT_BACK_LEFT
) != 0)
326 sis_3D_Clear( ctx
, BUFFER_BIT_BACK_LEFT
, x
, y
, width
, height
);
328 smesa
->GlobalFlag
|= dirtyflags
;
330 return mask
& ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
| BUFFER_BIT_BACK_LEFT
|
331 BUFFER_BIT_FRONT_LEFT
);
335 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
336 GLint width
, GLint height
)
338 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
341 GLuint depth
= smesa
->bytesPerPixel
;
342 drm_clip_rect_t
*pExtents
= NULL
;
344 GLint x0
, y0
, width0
, height0
;
346 /* Clear back buffer */
347 if (mask
& BUFFER_BIT_BACK_LEFT
) {
349 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
350 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
351 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
352 MMIO(REG_DST_ADDR
, smesa
->back
.offset
);
353 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->back
.pitch
);
354 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
355 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
356 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
357 MMIO(REG_CommandQueue
, -1);
360 if ((mask
& BUFFER_BIT_FRONT_LEFT
) == 0)
363 /* Clear front buffer */
369 pExtents
= smesa
->driDrawable
->pClipRects
;
370 count
= smesa
->driDrawable
->numClipRects
;
373 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
374 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
375 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
376 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
378 x
= (x0
> x2
) ? x0
: x2
;
379 y
= (y0
> y2
) ? y0
: y2
;
380 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
381 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
386 if (width
<= 0 || height
<= 0)
392 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
393 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
394 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
395 MMIO(REG_DST_ADDR
, smesa
->front
.offset
);
396 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->front
.pitch
);
397 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
398 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
399 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
400 MMIO(REG_CommandQueue
, -1);
405 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
406 GLint x
, GLint y
, GLint width
, GLint height
)
408 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
412 MMIO(REG_SRC_PITCH
, (smesa
->zFormat
== SiS_ZFORMAT_Z16
) ?
413 BLIT_DEPTH_16
: BLIT_DEPTH_32
);
414 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
415 MMIO(REG_DST_ADDR
, smesa
->depth
.offset
);
416 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->depth
.pitch
);
417 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
418 MMIO(REG_PATFG
, smesa
->clearZStencilPattern
);
419 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
420 MMIO(REG_CommandQueue
, -1);