29b95f94d940639864ce4e086f1f53278c9a95de
[mesa.git] / src / mesa / drivers / dri / sis / sis6326_clear.c
1 /*
2 * Copyright 2005 Eric Anholt
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 * Eric Anholt <anholt@FreeBSD.org>
26 *
27 */
28
29 #include "sis_context.h"
30 #include "sis_state.h"
31 #include "sis_lock.h"
32 #include "sis_reg.h"
33
34 #include "swrast/swrast.h"
35 #include "macros.h"
36
37 static void sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x,
38 GLint y, GLint width, GLint height);
39 static void sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x,
40 GLint y, GLint width, GLint height);
41 static void sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x,
42 GLint y, GLint width, GLint height );
43
44 static void
45 set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green,
46 GLubyte blue, GLubyte alpha )
47 {
48 /* XXX only RGB565 and ARGB8888 */
49 switch (smesa->colorFormat)
50 {
51 case DST_FORMAT_ARGB_8888:
52 smesa->clearColorPattern = (alpha << 24) +
53 (red << 16) + (green << 8) + (blue);
54 break;
55 case DST_FORMAT_RGB_565:
56 smesa->clearColorPattern = ((red >> 3) << 11) +
57 ((green >> 2) << 5) + (blue >> 3);
58 smesa->clearColorPattern |= smesa->clearColorPattern << 16;
59 break;
60 default:
61 sis_fatal_error("Bad dst color format\n");
62 }
63 }
64
65 void
66 sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z)
67 {
68 smesa->clearZStencilPattern = FLOAT_TO_USHORT(z * 65535.0);
69 }
70
71 void
72 sis6326DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
73 GLint x, GLint y, GLint width, GLint height)
74 {
75 sisContextPtr smesa = SIS_CONTEXT(ctx);
76 GLint x1, y1, width1, height1;
77
78 if (all) {
79 GLframebuffer *buffer = ctx->DrawBuffer;
80
81 x1 = 0;
82 y1 = 0;
83 width1 = buffer->Width;
84 height1 = buffer->Height;
85 } else {
86 x1 = x;
87 y1 = Y_FLIP(y+height-1);
88 width1 = width;
89 height1 = height;
90 }
91 /* XXX: Scissoring */
92
93 fprintf(stderr, "Clear\n");
94
95 /* Mask out any non-existent buffers */
96 if (smesa->depth.offset == 0 || !ctx->Depth.Mask)
97 mask &= ~BUFFER_BIT_DEPTH;
98
99 LOCK_HARDWARE();
100
101 if (mask & BUFFER_BIT_FRONT_LEFT) {
102 sis_clear_front_buffer(ctx, mask, x1, y1, width1, height1);
103 mask &= ~BUFFER_BIT_FRONT_LEFT;
104 }
105
106 if (mask & BUFFER_BIT_BACK_LEFT) {
107 sis_clear_back_buffer(ctx, mask, x1, y1, width1, height1);
108 mask &= ~BUFFER_BIT_BACK_LEFT;
109 }
110
111 if (mask & BUFFER_BIT_DEPTH) {
112 sis_clear_z_buffer(ctx, mask, x1, y1, width1, height1);
113 mask &= ~BUFFER_BIT_DEPTH;
114 }
115
116 UNLOCK_HARDWARE();
117
118 if (mask != 0)
119 _swrast_Clear(ctx, mask, all, x1, y1, width, height);
120 }
121
122
123 void
124 sis6326DDClearColor(GLcontext *ctx, const GLfloat color[4])
125 {
126 sisContextPtr smesa = SIS_CONTEXT(ctx);
127 GLubyte c[4];
128
129 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
130 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
131 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
132 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
133
134 set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
135 }
136
137 void
138 sis6326DDClearDepth(GLcontext *ctx, GLclampd d)
139 {
140 sisContextPtr smesa = SIS_CONTEXT(ctx);
141
142 sis6326UpdateZPattern(smesa, d);
143 }
144
145 static void
146 sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
147 GLint width, GLint height)
148 {
149 sisContextPtr smesa = SIS_CONTEXT(ctx);
150
151 /* XXX: The order of writing these registers seems to matter, while
152 * it actually shouldn't.
153 */
154 mWait3DCmdQueue(6);
155 MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->back.pitch << 16);
156 MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
157 smesa->clearColorPattern);
158 MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
159 smesa->clearColorPattern);
160 MMIO(REG_6326_BitBlt_DstAddr, smesa->back.offset +
161 (y+height) * smesa->back.pitch +
162 (x+width) * smesa->bytesPerPixel);
163 MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
164 (width * smesa->bytesPerPixel));
165 MMIO_WMB();
166 MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
167 }
168
169 static void
170 sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
171 GLint width, GLint height)
172 {
173 sisContextPtr smesa = SIS_CONTEXT(ctx);
174 int count;
175 drm_clip_rect_t *pExtents = NULL;
176
177 pExtents = smesa->driDrawable->pClipRects;
178 count = smesa->driDrawable->numClipRects;
179
180 mWait3DCmdQueue(3);
181 MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->front.pitch << 16);
182 MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
183 smesa->clearColorPattern);
184 MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
185 smesa->clearColorPattern);
186
187 while (count--) {
188 GLint x1 = pExtents->x1 - smesa->driDrawable->x;
189 GLint y1 = pExtents->y1 - smesa->driDrawable->y;
190 GLint x2 = pExtents->x2 - smesa->driDrawable->x;
191 GLint y2 = pExtents->y2 - smesa->driDrawable->y;
192
193 if (x > x1)
194 x1 = x;
195 if (y > y1)
196 y1 = y;
197
198 if (x + width < x2)
199 x2 = x + width;
200 if (y + height < y2)
201 y2 = y + height;
202 width = x2 - x1;
203 height = y2 - y1;
204
205 pExtents++;
206
207 if (width <= 0 || height <= 0)
208 continue;
209
210 mWait3DCmdQueue(3);
211 MMIO(REG_6326_BitBlt_DstAddr, smesa->front.offset +
212 (y2-1) * smesa->front.pitch + x2 * smesa->bytesPerPixel);
213 MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
214 (width * smesa->bytesPerPixel));
215 MMIO_WMB();
216 MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
217 }
218 }
219
220 static void
221 sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x, GLint y,
222 GLint width, GLint height)
223 {
224 sisContextPtr smesa = SIS_CONTEXT(ctx);
225
226 mWait3DCmdQueue(6);
227 MMIO(REG_6326_BitBlt_DstAddr,
228 smesa->depth.offset + y * smesa->depth.pitch + x * 2);
229 MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->depth.pitch << 16);
230 MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | (width * 2));
231 MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
232 MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
233 MMIO_WMB();
234 MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG | BLT_XINC | BLT_YINC);
235 }
236