Chop out more dead code.
[mesa.git] / src / mesa / drivers / dri / sis / sis_clear.c
1 /**************************************************************************
2
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
5 All Rights Reserved.
6
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:
13
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
16 Software.
17
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.
25
26 **************************************************************************/
27 /* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_clear.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */
28
29 /*
30 * Authors:
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
33 */
34
35 #include "sis_context.h"
36 #include "sis_state.h"
37 #include "sis_lock.h"
38
39 #include "swrast/swrast.h"
40 #include "macros.h"
41
42 static GLbitfield sis_3D_Clear( GLcontext * ctx, GLbitfield mask,
43 GLint x, GLint y, GLint width,
44 GLint height );
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,
49 GLint y, GLint width,
50 GLint height );
51
52 static void
53 set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green,
54 GLubyte blue, GLubyte alpha )
55 {
56 /* XXX only RGB565 and ARGB8888 */
57 switch (smesa->colorFormat)
58 {
59 case DST_FORMAT_ARGB_8888:
60 smesa->clearColorPattern = (alpha << 24) +
61 (red << 16) + (green << 8) + (blue);
62 break;
63 case DST_FORMAT_RGB_565:
64 smesa->clearColorPattern = ((red >> 3) << 11) +
65 ((green >> 2) << 5) + (blue >> 3);
66 smesa->clearColorPattern |= smesa->clearColorPattern << 16;
67 break;
68 default:
69 sis_fatal_error("Bad dst color format\n");
70 }
71 }
72
73 void
74 sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil )
75 {
76 GLuint zPattern;
77
78 switch (smesa->zFormat)
79 {
80 case SiS_ZFORMAT_Z16:
81 zPattern = FLOAT_TO_USHORT(z);
82 zPattern |= zPattern << 16;
83 break;
84 case SiS_ZFORMAT_S8Z24:
85 zPattern = FLOAT_TO_UINT(z) >> 8;
86 zPattern |= stencil << 24;
87 break;
88 case SiS_ZFORMAT_Z32:
89 zPattern = FLOAT_TO_UINT(z);
90 break;
91 default:
92 sis_fatal_error("Bad Z format\n");
93 }
94 smesa->clearZStencilPattern = zPattern;
95 }
96
97 void
98 sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean all,
99 GLint x, GLint y, GLint width, GLint height )
100 {
101 sisContextPtr smesa = SIS_CONTEXT(ctx);
102
103 GLint x1, y1, width1, height1;
104
105 if (all) {
106 GLframebuffer *buffer = ctx->DrawBuffer;
107
108 x1 = 0;
109 y1 = 0;
110 width1 = buffer->Width;
111 height1 = buffer->Height;
112 } else {
113 x1 = x;
114 y1 = Y_FLIP(y+height-1);
115 width1 = width;
116 height1 = height;
117 }
118 /* XXX: Scissoring */
119
120 /* Mask out any non-existent buffers */
121 if (ctx->Visual.depthBits == 0 || !ctx->Depth.Mask)
122 mask &= ~DD_DEPTH_BIT;
123 if (ctx->Visual.stencilBits == 0)
124 mask &= ~DD_STENCIL_BIT;
125
126 LOCK_HARDWARE();
127
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.
131 */
132 /* XXX: Appears to be broken with stencil. */
133 if ((smesa->current.hwCapEnable2 & (MASK_AlphaMaskWriteEnable |
134 MASK_ColorMaskWriteEnable) &&
135 (mask & (DD_BACK_LEFT_BIT | DD_FRONT_LEFT_BIT)) != 0) ||
136 (ctx->Stencil.WriteMask[0] < 0xff && (mask & DD_STENCIL_BIT) != 0) )
137 {
138 mask = sis_3D_Clear( ctx, mask, x1, y1, width1, height1 );
139 }
140
141 if ( mask & DD_FRONT_LEFT_BIT || mask & DD_BACK_LEFT_BIT) {
142 sis_clear_color_buffer( ctx, mask, x1, y1, width1, height1 );
143 mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
144 }
145
146 if (mask & (DD_DEPTH_BIT | DD_STENCIL_BIT)) {
147 if (smesa->depthbuffer != NULL)
148 sis_clear_z_stencil_buffer( ctx, mask, x1, y1, width1, height1 );
149 mask &= ~(DD_DEPTH_BIT | DD_STENCIL_BIT);
150 }
151
152 UNLOCK_HARDWARE();
153
154 if (mask != 0)
155 _swrast_Clear( ctx, mask, all, x1, y1, width, height );
156 }
157
158
159 void
160 sisDDClearColor( GLcontext * ctx, const GLfloat color[4] )
161 {
162 sisContextPtr smesa = SIS_CONTEXT(ctx);
163 GLubyte c[4];
164
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]);
169
170 set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
171 }
172
173 void
174 sisDDClearDepth( GLcontext * ctx, GLclampd d )
175 {
176 sisContextPtr smesa = SIS_CONTEXT(ctx);
177
178 sisUpdateZStencilPattern( smesa, d, ctx->Stencil.Clear );
179 }
180
181 void
182 sisDDClearStencil( GLcontext * ctx, GLint s )
183 {
184 sisContextPtr smesa = SIS_CONTEXT(ctx);
185
186 sisUpdateZStencilPattern( smesa, ctx->Depth.Clear, s );
187 }
188
189 static GLbitfield
190 sis_3D_Clear( GLcontext * ctx, GLbitfield mask,
191 GLint x, GLint y, GLint width, GLint height )
192 {
193 sisContextPtr smesa = SIS_CONTEXT(ctx);
194
195 __GLSiSHardware *current = &smesa->current;
196
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;
204 int count;
205 drm_clip_rect_t *pExtents;
206
207 bClrColor = (mask & (DD_BACK_LEFT_BIT | DD_FRONT_LEFT_BIT)) != 0;
208 bClrDepth = (mask & DD_DEPTH_BIT) != 0;
209 bClrStencil = (mask & DD_STENCIL_BIT) != 0;
210
211 if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
212 sis_update_render_state( smesa );
213
214 if (bClrStencil) {
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;
226 }
227
228 if (bClrDepth) {
229 zClearVal = ctx->Depth.Clear;
230 if (ctx->Visual.depthBits != 32)
231 dwDepthMask |= 0x00ffffff;
232 else
233 dwDepthMask = 0xffffffff;
234 } else
235 zClearVal = 0.0;
236
237 mWait3DCmdQueue(9);
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;
243 }
244 if (bClrColor) {
245 MMIO(REG_3D_DstSet, (current->hwDstSet & ~MASK_ROP2) | LOP_COPY);
246 } else {
247 MMIO(REG_3D_DstAlphaWriteMask, 0L);
248 }
249 if (bClrStencil) {
250 MMIO(REG_3D_StencilSet, dwSten1);
251 MMIO(REG_3D_StencilSet2, dwSten2);
252 dirtyflags |= GFLAG_STENCILSETTING;
253 }
254
255 if (mask & DD_FRONT_LEFT_BIT) {
256 pExtents = smesa->driDrawable->pClipRects;
257 count = smesa->driDrawable->numClipRects;
258 } else {
259 pExtents = NULL;
260 count = 1;
261 }
262
263 while(count--) {
264 left = x;
265 right = x + width;
266 top = y;
267 bottom = y + height;
268
269 if (pExtents != NULL) {
270 GLuint x1, y1, x2, y2;
271
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;
276
277 left = (left > x1) ? left : x1;
278 right = (right > x2) ? x2 : right;
279 top = (top > y1) ? top : y1;
280 bottom = (bottom > y2) ? y2 : bottom;
281 pExtents++;
282 if (left > right || top > bottom)
283 continue;
284 }
285
286 mWait3DCmdQueue(20);
287
288 MMIO(REG_3D_ClipTopBottom, ((GLint)top << 13) | (GLint)bottom);
289 MMIO(REG_3D_ClipLeftRight, ((GLint)left << 13) | (GLint)right);
290
291 /* the first triangle */
292 dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBc |
293 SHADE_FLAT_VertexC;
294 MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
295
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);
300
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);
305
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);
310
311 /* second triangle */
312 dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBb |
313 SHADE_FLAT_VertexB;
314 MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet);
315
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);
320 }
321
322 mEndPrimitive();
323
324 /* If DD_FRONT_LEFT_BIT is set, we've only cleared the front buffer so far */
325 if ((mask & DD_FRONT_LEFT_BIT) != 0 && (mask & DD_BACK_LEFT_BIT) != 0)
326 sis_3D_Clear( ctx, DD_BACK_LEFT_BIT, x, y, width, height );
327
328 smesa->GlobalFlag |= dirtyflags;
329
330 return mask & ~(DD_DEPTH_BIT | DD_STENCIL_BIT | DD_BACK_LEFT_BIT |
331 DD_FRONT_LEFT_BIT);
332 }
333
334 static void
335 sis_bitblt_clear_cmd( sisContextPtr smesa, ENGPACKET * pkt )
336 {
337 GLint *lpdwDest, *lpdwSrc;
338 int i;
339
340 lpdwSrc = (GLint *) pkt + 1;
341 lpdwDest = (GLint *) (GET_IOBase (smesa) + REG_SRC_ADDR) + 1;
342
343 mWait3DCmdQueue (10);
344
345 *lpdwDest++ = *lpdwSrc++;
346 lpdwSrc++;
347 lpdwDest++;
348 for (i = 3; i < 8; i++) {
349 *lpdwDest++ = *lpdwSrc++;
350 }
351
352 MMIO(REG_CMD0, *(GLint *) & pkt->stdwCmd);
353 MMIO(REG_CommandQueue, -1);
354 }
355
356 static void
357 sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y,
358 GLint width, GLint height )
359 {
360 sisContextPtr smesa = SIS_CONTEXT(ctx);
361
362 int count;
363 GLuint depth = smesa->bytesPerPixel;
364 drm_clip_rect_t *pExtents = NULL;
365 GLint xx, yy;
366 GLint x0, y0, width0, height0;
367
368 ENGPACKET stEngPacket;
369
370 /* Clear back buffer */
371 if (mask & DD_BACK_LEFT_BIT) {
372 smesa->cbClearPacket.stdwDestPos.wY = y;
373 smesa->cbClearPacket.stdwDestPos.wX = x;
374 smesa->cbClearPacket.stdwDim.wWidth = (GLshort) width;
375 smesa->cbClearPacket.stdwDim.wHeight = (GLshort) height;
376 smesa->cbClearPacket.dwFgRopColor = smesa->clearColorPattern;
377
378 sis_bitblt_clear_cmd( smesa, &smesa->cbClearPacket );
379 }
380
381 if ((mask & DD_FRONT_LEFT_BIT) == 0)
382 return;
383
384 /* Clear front buffer */
385 x0 = x;
386 y0 = y;
387 width0 = width;
388 height0 = height;
389
390 pExtents = smesa->driDrawable->pClipRects;
391 count = smesa->driDrawable->numClipRects;
392
393 memset( &stEngPacket, 0, sizeof (ENGPACKET) );
394
395 stEngPacket.dwSrcPitch = (depth == 2) ? 0x80000000 : 0xc0000000;
396 stEngPacket.dwDestBaseAddr = smesa->frontOffset;
397 stEngPacket.wDestPitch = smesa->frontPitch;
398 /* TODO: set maximum value? */
399 stEngPacket.wDestHeight = smesa->virtualY;
400 stEngPacket.stdwCmd.cRop = 0xf0;
401 stEngPacket.dwFgRopColor = smesa->clearColorPattern;
402
403 /* for SGRAM Block Write Enable */
404 if (smesa->blockWrite)
405 stEngPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR;
406 else
407 stEngPacket.stdwCmd.cCmd0 = 0;
408 stEngPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC;
409
410 while (count--) {
411 GLint x2 = pExtents->x1 - smesa->driDrawable->x;
412 GLint y2 = pExtents->y1 - smesa->driDrawable->y;
413 GLint xx2 = pExtents->x2 - smesa->driDrawable->x;
414 GLint yy2 = pExtents->y2 - smesa->driDrawable->y;
415
416 x = (x0 > x2) ? x0 : x2;
417 y = (y0 > y2) ? y0 : y2;
418 xx = ((x0 + width0) > (xx2)) ? xx2 : x0 + width0;
419 yy = ((y0 + height0) > (yy2)) ? yy2 : y0 + height0;
420 width = xx - x;
421 height = yy - y;
422 pExtents++;
423
424 if (width <= 0 || height <= 0)
425 continue;
426
427 stEngPacket.stdwDestPos.wY = y;
428 stEngPacket.stdwDestPos.wX = x;
429 stEngPacket.stdwDim.wWidth = (GLshort)width;
430 stEngPacket.stdwDim.wHeight = (GLshort)height;
431
432 sis_bitblt_clear_cmd( smesa, &stEngPacket );
433 }
434 }
435
436 static void
437 sis_clear_z_stencil_buffer( GLcontext * ctx, GLbitfield mask,
438 GLint x, GLint y, GLint width, GLint height )
439 {
440 sisContextPtr smesa = SIS_CONTEXT(ctx);
441
442 /* TODO: consider alignment of width, height? */
443 smesa->zClearPacket.stdwDestPos.wY = y;
444 smesa->zClearPacket.stdwDestPos.wX = x;
445 smesa->zClearPacket.stdwDim.wWidth = (GLshort) width;
446 smesa->zClearPacket.stdwDim.wHeight = (GLshort) height;
447 smesa->zClearPacket.dwFgRopColor = smesa->clearZStencilPattern;
448
449 sis_bitblt_clear_cmd( smesa, &smesa->zClearPacket );
450 }
451