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 **************************************************************************/
30 * Sung-Ching Lin <sclin@sis.com.tw>
31 * Eric Anholt <anholt@FreeBSD.org>
34 #include "sis_context.h"
35 #include "sis_state.h"
38 #include "swrast/swrast.h"
39 #include "main/macros.h"
41 static GLbitfield
sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
42 GLint x
, GLint y
, GLint width
,
44 static void sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
,
45 GLint y
, GLint width
, GLint height
);
46 static void sis_clear_z_stencil_buffer( GLcontext
* ctx
,
47 GLbitfield mask
, GLint x
,
52 set_color_pattern( sisContextPtr smesa
, GLubyte red
, GLubyte green
,
53 GLubyte blue
, GLubyte alpha
)
55 /* XXX only RGB565 and ARGB8888 */
56 switch (smesa
->colorFormat
)
58 case DST_FORMAT_ARGB_8888
:
59 smesa
->clearColorPattern
= (alpha
<< 24) +
60 (red
<< 16) + (green
<< 8) + (blue
);
62 case DST_FORMAT_RGB_565
:
63 smesa
->clearColorPattern
= ((red
>> 3) << 11) +
64 ((green
>> 2) << 5) + (blue
>> 3);
65 smesa
->clearColorPattern
|= smesa
->clearColorPattern
<< 16;
68 sis_fatal_error("Bad dst color format\n");
73 sisUpdateZStencilPattern( sisContextPtr smesa
, GLclampd z
, GLint stencil
)
77 switch (smesa
->zFormat
)
80 CLAMPED_FLOAT_TO_USHORT(zPattern
, z
);
81 zPattern
|= zPattern
<< 16;
83 case SiS_ZFORMAT_S8Z24
:
84 zPattern
= FLOAT_TO_UINT(z
) >> 8;
85 zPattern
|= stencil
<< 24;
88 zPattern
= FLOAT_TO_UINT(z
);
91 sis_fatal_error("Bad Z format\n");
93 smesa
->clearZStencilPattern
= zPattern
;
97 sisDDClear( GLcontext
* ctx
, GLbitfield mask
)
99 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
101 GLint x1
, y1
, width1
, height1
;
103 /* get region after locking: */
104 x1
= ctx
->DrawBuffer
->_Xmin
;
105 y1
= ctx
->DrawBuffer
->_Ymin
;
106 width1
= ctx
->DrawBuffer
->_Xmax
- x1
;
107 height1
= ctx
->DrawBuffer
->_Ymax
- y1
;
108 y1
= Y_FLIP(y1
+ height1
- 1);
110 /* Mask out any non-existent buffers */
111 if (ctx
->Visual
.depthBits
== 0 || !ctx
->Depth
.Mask
)
112 mask
&= ~BUFFER_BIT_DEPTH
;
113 if (ctx
->Visual
.stencilBits
== 0)
114 mask
&= ~BUFFER_BIT_STENCIL
;
118 /* The 3d clear code is use for masked clears because apparently the SiS
119 * 300-series can't do write masks for 2d blits. 3d isn't used in general
120 * because it's slower, even in the case of clearing multiple buffers.
122 /* XXX: Appears to be broken with stencil. */
123 if ((smesa
->current
.hwCapEnable2
& (MASK_AlphaMaskWriteEnable
|
124 MASK_ColorMaskWriteEnable
) &&
125 (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0) ||
126 ((ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff &&
127 (mask
& BUFFER_BIT_STENCIL
) != 0) )
129 mask
= sis_3D_Clear( ctx
, mask
, x1
, y1
, width1
, height1
);
132 if ( mask
& BUFFER_BIT_FRONT_LEFT
|| mask
& BUFFER_BIT_BACK_LEFT
) {
133 sis_clear_color_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
134 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
137 if (mask
& (BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
)) {
138 if (smesa
->depth
.offset
!= 0)
139 sis_clear_z_stencil_buffer( ctx
, mask
, x1
, y1
, width1
, height1
);
140 mask
&= ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
);
146 _swrast_Clear( ctx
, mask
);
151 sisDDClearColor( GLcontext
* ctx
, const GLfloat color
[4] )
153 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
156 CLAMPED_FLOAT_TO_UBYTE(c
[0], color
[0]);
157 CLAMPED_FLOAT_TO_UBYTE(c
[1], color
[1]);
158 CLAMPED_FLOAT_TO_UBYTE(c
[2], color
[2]);
159 CLAMPED_FLOAT_TO_UBYTE(c
[3], color
[3]);
161 set_color_pattern( smesa
, c
[0], c
[1], c
[2], c
[3] );
165 sisDDClearDepth( GLcontext
* ctx
, GLclampd d
)
167 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
169 sisUpdateZStencilPattern( smesa
, d
, ctx
->Stencil
.Clear
);
173 sisDDClearStencil( GLcontext
* ctx
, GLint s
)
175 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
177 sisUpdateZStencilPattern( smesa
, ctx
->Depth
.Clear
, s
);
181 sis_3D_Clear( GLcontext
* ctx
, GLbitfield mask
,
182 GLint x
, GLint y
, GLint width
, GLint height
)
184 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
186 __GLSiSHardware
*current
= &smesa
->current
;
188 float left
, top
, right
, bottom
, zClearVal
;
189 GLboolean bClrColor
, bClrDepth
, bClrStencil
;
190 GLint dwPrimitiveSet
;
191 GLint dwEnable1
= 0, dwEnable2
= MASK_ColorMaskWriteEnable
;
192 GLint dwDepthMask
= 0, dwSten1
= 0, dwSten2
= 0;
193 GLint dirtyflags
= GFLAG_ENABLESETTING
| GFLAG_ENABLESETTING2
|
194 GFLAG_CLIPPING
| GFLAG_DESTSETTING
;
196 drm_clip_rect_t
*pExtents
;
198 bClrColor
= (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_FRONT_LEFT
)) != 0;
199 bClrDepth
= (mask
& BUFFER_BIT_DEPTH
) != 0;
200 bClrStencil
= (mask
& BUFFER_BIT_STENCIL
) != 0;
202 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
203 sis_update_render_state( smesa
);
206 dwSten1
= STENCIL_FORMAT_8
| SiS_STENCIL_ALWAYS
|
207 ((ctx
->Stencil
.Clear
& 0xff) << 8) | 0xff;
208 dwSten2
= SiS_SFAIL_REPLACE
| SiS_SPASS_ZFAIL_REPLACE
|
209 SiS_SPASS_ZPASS_REPLACE
;
210 dwEnable1
= MASK_ZWriteEnable
| MASK_StencilWriteEnable
|
211 MASK_StencilTestEnable
;
212 dwEnable2
|= MASK_ZMaskWriteEnable
;
213 dwDepthMask
|= (ctx
->Stencil
.WriteMask
[0] & 0xff) << 24;
214 } else if (bClrDepth
) {
215 dwEnable1
= MASK_ZWriteEnable
;
216 dwEnable2
|= MASK_ZMaskWriteEnable
;
220 zClearVal
= ctx
->Depth
.Clear
;
221 if (ctx
->Visual
.depthBits
!= 32)
222 dwDepthMask
|= 0x00ffffff;
224 dwDepthMask
= 0xffffffff;
229 MMIO(REG_3D_TEnable
, dwEnable1
);
230 MMIO(REG_3D_TEnable2
, dwEnable2
);
231 if (bClrDepth
|| bClrStencil
) {
232 MMIO(REG_3D_ZSet
, (current
->hwZ
& ~MASK_ZTestMode
) | SiS_Z_COMP_ALWAYS
);
233 dirtyflags
|= GFLAG_ZSETTING
;
236 MMIO(REG_3D_DstSet
, (current
->hwDstSet
& ~MASK_ROP2
) | LOP_COPY
);
238 MMIO(REG_3D_DstAlphaWriteMask
, 0L);
241 MMIO(REG_3D_StencilSet
, dwSten1
);
242 MMIO(REG_3D_StencilSet2
, dwSten2
);
243 dirtyflags
|= GFLAG_STENCILSETTING
;
246 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
247 pExtents
= smesa
->driDrawable
->pClipRects
;
248 count
= smesa
->driDrawable
->numClipRects
;
260 if (pExtents
!= NULL
) {
261 GLuint x1
, y1
, x2
, y2
;
263 x1
= pExtents
->x1
- smesa
->driDrawable
->x
;
264 y1
= pExtents
->y1
- smesa
->driDrawable
->y
;
265 x2
= pExtents
->x2
- smesa
->driDrawable
->x
- 1;
266 y2
= pExtents
->y2
- smesa
->driDrawable
->y
- 1;
268 left
= (left
> x1
) ? left
: x1
;
269 right
= (right
> x2
) ? x2
: right
;
270 top
= (top
> y1
) ? top
: y1
;
271 bottom
= (bottom
> y2
) ? y2
: bottom
;
273 if (left
> right
|| top
> bottom
)
279 MMIO(REG_3D_ClipTopBottom
, ((GLint
)top
<< 13) | (GLint
)bottom
);
280 MMIO(REG_3D_ClipLeftRight
, ((GLint
)left
<< 13) | (GLint
)right
);
282 /* the first triangle */
283 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBc
|
285 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
287 MMIO(REG_3D_TSZa
, *(GLint
*) &zClearVal
);
288 MMIO(REG_3D_TSXa
, *(GLint
*) &right
);
289 MMIO(REG_3D_TSYa
, *(GLint
*) &top
);
290 MMIO(REG_3D_TSARGBa
, smesa
->clearColorPattern
);
292 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
293 MMIO(REG_3D_TSXb
, *(GLint
*) &left
);
294 MMIO(REG_3D_TSYb
, *(GLint
*) &top
);
295 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
297 MMIO(REG_3D_TSZc
, *(GLint
*) &zClearVal
);
298 MMIO(REG_3D_TSXc
, *(GLint
*) &left
);
299 MMIO(REG_3D_TSYc
, *(GLint
*) &bottom
);
300 MMIO(REG_3D_TSARGBc
, smesa
->clearColorPattern
);
302 /* second triangle */
303 dwPrimitiveSet
= OP_3D_TRIANGLE_DRAW
| OP_3D_FIRE_TSARGBb
|
305 MMIO(REG_3D_PrimitiveSet
, dwPrimitiveSet
);
307 MMIO(REG_3D_TSZb
, *(GLint
*) &zClearVal
);
308 MMIO(REG_3D_TSXb
, *(GLint
*) &right
);
309 MMIO(REG_3D_TSYb
, *(GLint
*) &bottom
);
310 MMIO(REG_3D_TSARGBb
, smesa
->clearColorPattern
);
315 /* If BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */
316 if ((mask
& BUFFER_BIT_FRONT_LEFT
) != 0 && (mask
& BUFFER_BIT_BACK_LEFT
) != 0)
317 sis_3D_Clear( ctx
, BUFFER_BIT_BACK_LEFT
, x
, y
, width
, height
);
319 smesa
->GlobalFlag
|= dirtyflags
;
321 return mask
& ~(BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
| BUFFER_BIT_BACK_LEFT
|
322 BUFFER_BIT_FRONT_LEFT
);
326 sis_clear_color_buffer( GLcontext
*ctx
, GLenum mask
, GLint x
, GLint y
,
327 GLint width
, GLint height
)
329 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
331 drm_clip_rect_t
*pExtents
= NULL
;
333 GLint x0
, y0
, width0
, height0
;
335 /* Clear back buffer */
336 if (mask
& BUFFER_BIT_BACK_LEFT
) {
338 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
339 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
340 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
341 MMIO(REG_DST_ADDR
, smesa
->back
.offset
);
342 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->back
.pitch
);
343 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
344 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
345 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
346 MMIO(REG_CommandQueue
, -1);
349 if ((mask
& BUFFER_BIT_FRONT_LEFT
) == 0)
352 /* Clear front buffer */
358 pExtents
= smesa
->driDrawable
->pClipRects
;
359 count
= smesa
->driDrawable
->numClipRects
;
362 GLint x2
= pExtents
->x1
- smesa
->driDrawable
->x
;
363 GLint y2
= pExtents
->y1
- smesa
->driDrawable
->y
;
364 GLint xx2
= pExtents
->x2
- smesa
->driDrawable
->x
;
365 GLint yy2
= pExtents
->y2
- smesa
->driDrawable
->y
;
367 x
= (x0
> x2
) ? x0
: x2
;
368 y
= (y0
> y2
) ? y0
: y2
;
369 xx
= ((x0
+ width0
) > (xx2
)) ? xx2
: x0
+ width0
;
370 yy
= ((y0
+ height0
) > (yy2
)) ? yy2
: y0
+ height0
;
375 if (width
<= 0 || height
<= 0)
379 MMIO(REG_SRC_PITCH
, (smesa
->bytesPerPixel
== 4) ?
380 BLIT_DEPTH_32
: BLIT_DEPTH_16
);
381 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
382 MMIO(REG_DST_ADDR
, smesa
->front
.offset
);
383 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->front
.pitch
);
384 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
385 MMIO(REG_PATFG
, smesa
->clearColorPattern
);
386 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
387 MMIO(REG_CommandQueue
, -1);
392 sis_clear_z_stencil_buffer( GLcontext
* ctx
, GLbitfield mask
,
393 GLint x
, GLint y
, GLint width
, GLint height
)
395 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
399 MMIO(REG_SRC_PITCH
, (smesa
->zFormat
== SiS_ZFORMAT_Z16
) ?
400 BLIT_DEPTH_16
: BLIT_DEPTH_32
);
401 MMIO(REG_DST_X_Y
, (x
<< 16) | y
);
402 MMIO(REG_DST_ADDR
, smesa
->depth
.offset
);
403 MMIO(REG_DST_PITCH_HEIGHT
, (smesa
->virtualY
<< 16) | smesa
->depth
.pitch
);
404 MMIO(REG_WIDTH_HEIGHT
, (height
<< 16) | width
);
405 MMIO(REG_PATFG
, smesa
->clearZStencilPattern
);
406 MMIO(REG_BLIT_CMD
, CMD_DIR_X_INC
| CMD_DIR_Y_INC
| CMD_ROP_PAT
);
407 MMIO(REG_CommandQueue
, -1);