i965: Reduce repeated calculation of the attribute-offset-in-VUE.
[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 "main/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 CLAMPED_FLOAT_TO_USHORT(smesa->clearZStencilPattern, z * 65535.0);
69 }
70
71 void
72 sis6326DDClear(GLcontext *ctx, GLbitfield mask)
73 {
74 sisContextPtr smesa = SIS_CONTEXT(ctx);
75 GLint x1, y1, width1, height1;
76
77 /* get region after locking: */
78 x1 = ctx->DrawBuffer->_Xmin;
79 y1 = ctx->DrawBuffer->_Ymin;
80 width1 = ctx->DrawBuffer->_Xmax - x1;
81 height1 = ctx->DrawBuffer->_Ymax - y1;
82 y1 = Y_FLIP(y1 + height1 - 1);
83
84 /* XXX: Scissoring */
85
86 fprintf(stderr, "Clear\n");
87
88 /* Mask out any non-existent buffers */
89 if (smesa->depth.offset == 0 || !ctx->Depth.Mask)
90 mask &= ~BUFFER_BIT_DEPTH;
91
92 LOCK_HARDWARE();
93
94 if (mask & BUFFER_BIT_FRONT_LEFT) {
95 sis_clear_front_buffer(ctx, mask, x1, y1, width1, height1);
96 mask &= ~BUFFER_BIT_FRONT_LEFT;
97 }
98
99 if (mask & BUFFER_BIT_BACK_LEFT) {
100 sis_clear_back_buffer(ctx, mask, x1, y1, width1, height1);
101 mask &= ~BUFFER_BIT_BACK_LEFT;
102 }
103
104 if (mask & BUFFER_BIT_DEPTH) {
105 sis_clear_z_buffer(ctx, mask, x1, y1, width1, height1);
106 mask &= ~BUFFER_BIT_DEPTH;
107 }
108
109 UNLOCK_HARDWARE();
110
111 if (mask != 0)
112 _swrast_Clear(ctx, mask);
113 }
114
115
116 void
117 sis6326DDClearColor(GLcontext *ctx, const GLfloat color[4])
118 {
119 sisContextPtr smesa = SIS_CONTEXT(ctx);
120 GLubyte c[4];
121
122 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
123 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
124 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
125 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
126
127 set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
128 }
129
130 void
131 sis6326DDClearDepth(GLcontext *ctx, GLclampd d)
132 {
133 sisContextPtr smesa = SIS_CONTEXT(ctx);
134
135 sis6326UpdateZPattern(smesa, d);
136 }
137
138 static void
139 sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
140 GLint width, GLint height)
141 {
142 sisContextPtr smesa = SIS_CONTEXT(ctx);
143
144 /* XXX: The order of writing these registers seems to matter, while
145 * it actually shouldn't.
146 */
147 mWait3DCmdQueue(6);
148 MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->back.pitch << 16);
149 MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
150 smesa->clearColorPattern);
151 MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
152 smesa->clearColorPattern);
153 MMIO(REG_6326_BitBlt_DstAddr, smesa->back.offset +
154 (y+height) * smesa->back.pitch +
155 (x+width) * smesa->bytesPerPixel);
156 MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
157 (width * smesa->bytesPerPixel));
158 MMIO_WMB();
159 MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
160 }
161
162 static void
163 sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
164 GLint width, GLint height)
165 {
166 sisContextPtr smesa = SIS_CONTEXT(ctx);
167 int count;
168 drm_clip_rect_t *pExtents = NULL;
169
170 pExtents = smesa->driDrawable->pClipRects;
171 count = smesa->driDrawable->numClipRects;
172
173 mWait3DCmdQueue(3);
174 MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->front.pitch << 16);
175 MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
176 smesa->clearColorPattern);
177 MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
178 smesa->clearColorPattern);
179
180 while (count--) {
181 GLint x1 = pExtents->x1 - smesa->driDrawable->x;
182 GLint y1 = pExtents->y1 - smesa->driDrawable->y;
183 GLint x2 = pExtents->x2 - smesa->driDrawable->x;
184 GLint y2 = pExtents->y2 - smesa->driDrawable->y;
185
186 if (x > x1)
187 x1 = x;
188 if (y > y1)
189 y1 = y;
190
191 if (x + width < x2)
192 x2 = x + width;
193 if (y + height < y2)
194 y2 = y + height;
195 width = x2 - x1;
196 height = y2 - y1;
197
198 pExtents++;
199
200 if (width <= 0 || height <= 0)
201 continue;
202
203 mWait3DCmdQueue(3);
204 MMIO(REG_6326_BitBlt_DstAddr, smesa->front.offset +
205 (y2-1) * smesa->front.pitch + x2 * smesa->bytesPerPixel);
206 MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
207 (width * smesa->bytesPerPixel));
208 MMIO_WMB();
209 MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
210 }
211 }
212
213 static void
214 sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x, GLint y,
215 GLint width, GLint height)
216 {
217 sisContextPtr smesa = SIS_CONTEXT(ctx);
218
219 mWait3DCmdQueue(6);
220 MMIO(REG_6326_BitBlt_DstAddr,
221 smesa->depth.offset + y * smesa->depth.pitch + x * 2);
222 MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->depth.pitch << 16);
223 MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | (width * 2));
224 MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
225 MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
226 MMIO_WMB();
227 MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG | BLT_XINC | BLT_YINC);
228 }
229