fcb977187587e26ec61c046db0c80ed1b63fb97e
[mesa.git] / src / mesa / drivers / dri / unichrome / via_span.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
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
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "glheader.h"
26 #include "macros.h"
27 #include "mtypes.h"
28 #include "colormac.h"
29 #include "via_context.h"
30 #include "via_span.h"
31 #include "via_ioctl.h"
32 #include "swrast/swrast.h"
33
34 #define DBG 0
35 #define LOCAL_VARS \
36 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
37 viaScreenPrivate *viaScreen = vmesa->viaScreen; \
38 GLuint pitch = vmesa->drawPitch; \
39 GLuint height = dPriv->h; \
40 GLushort p; \
41 char *buf = (char *)(vmesa->drawMap + \
42 dPriv->x * viaScreen->bytesPerPixel + \
43 dPriv->y * pitch); \
44 char *read_buf = (char *)(vmesa->readMap + \
45 dPriv->x * viaScreen->bytesPerPixel + \
46 dPriv->y * pitch); \
47 (void)read_buf; (void)buf; (void)p
48
49 #define LOCAL_DEPTH_VARS \
50 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
51 viaScreenPrivate *viaScreen = vmesa->viaScreen; \
52 GLuint pitch = viaScreen->backPitch; \
53 GLuint height = dPriv->h; \
54 char *buf = (char *)(vmesa->depth.map + \
55 dPriv->x * 2 + \
56 dPriv->y * pitch)
57
58 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
59 _y >= miny && _y < maxy)
60
61
62 #define CLIPSPAN(_x, _y, _n, _x1, _n1, _i) \
63 if (_y < miny || _y >= maxy) { \
64 _n1 = 0, _x1 = x; \
65 } \
66 else { \
67 _n1 = _n; \
68 _x1 = _x; \
69 if (_x1 < minx) _i += (minx -_x1), n1 -= (minx -_x1), _x1 = minx; \
70 if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \
71 }
72
73 #define Y_FLIP(_y) (height - _y - 1)
74
75 #define HW_LOCK() \
76 viaContextPtr vmesa = VIA_CONTEXT(ctx); \
77 LOCK_HARDWARE_QUIESCENT(vmesa);
78
79 /*=* [DBG] csmash saam : bitmap option menu can't be drawn in saam *=*/
80 /*#define HW_CLIPLOOP() \
81 do { \
82 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
83 int _nc = dPriv->numClipRects; \
84 while (_nc--) { \
85 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
86 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
87 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
88 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;*/
89 #define HW_CLIPLOOP() \
90 do { \
91 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
92 int _nc = dPriv->numClipRects; \
93 GLuint scrn = vmesa->saam & S_MASK; \
94 if(scrn == S1) _nc = 1; \
95 while (_nc--) { \
96 int minx; \
97 int miny; \
98 int maxx; \
99 int maxy; \
100 if (!vmesa->saam) { \
101 minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
102 miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
103 maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
104 maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; \
105 } \
106 else { \
107 minx = -10000; \
108 miny = -10000; \
109 maxx = 10000; \
110 maxy = 10000; \
111 }
112
113 /*else if (scrn == S0) { \
114 minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
115 miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
116 maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
117 maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; \
118 } \
119 else if (scrn == S1) { \
120 drm_clip_rect_t *b = vmesa->sarea->boxes; \
121 minx = b->x1; \
122 miny = b->y1; \
123 maxx = b->x2; \
124 maxy = b->y2; \
125 } \
126 else { \
127 drm_clip_rect_t *b = vmesa->sarea->boxes + vmesa->numClipRects;\
128 minx = b->x1; \
129 miny = b->y1; \
130 maxx = b->x2; \
131 maxy = b->y2; \
132 }*/
133
134 #define HW_ENDCLIPLOOP() \
135 } \
136 } while (0)
137
138 #define HW_UNLOCK() \
139 UNLOCK_HARDWARE(vmesa);
140
141
142 /* 16 bit, 565 rgb color spanline and pixel functions
143 */
144 /*=* [DBG] csmash : fix options worng position *=*/
145 /*#define LOCAL_VARS \
146 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
147 GLuint pitch = vmesa->drawPitch; \
148 GLuint height = dPriv->h; \
149 GLushort p; \
150 char *buf = (char *)(vmesa->drawMap + \
151 dPriv->x * 2 + \
152 dPriv->y * pitch); \
153 char *read_buf = (char *)(vmesa->readMap + \
154 dPriv->x * 2 + \
155 dPriv->y * pitch); \
156 (void)read_buf; (void)buf; (void)p*/
157
158 #undef LOCAL_VARS
159 #define LOCAL_VARS \
160 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
161 GLuint pitch = vmesa->drawPitch; \
162 GLuint height = dPriv->h; \
163 GLushort p; \
164 char *buf, *read_buf; \
165 p = 0; \
166 if (vmesa->glCtx->Color._DrawDestMask == __GL_BACK_BUFFER_MASK) { \
167 buf = (char *)(vmesa->drawMap); \
168 read_buf = (char *)(vmesa->readMap); \
169 } \
170 else { \
171 buf = (char *)(vmesa->drawMap + \
172 dPriv->x * 2 + \
173 dPriv->y * pitch); \
174 read_buf = (char *)(vmesa->readMap + \
175 dPriv->x * 2 + \
176 dPriv->y * pitch); \
177 }
178
179 #define INIT_MONO_PIXEL(p, color) \
180 p = PACK_COLOR_565(color[0], color[1], color[2])
181
182 #define WRITE_RGBA(_x, _y, r, g, b, a) \
183 *(GLushort *)(buf + _x * 2 + _y * pitch) = ((((int)r & 0xf8) << 8) | \
184 (((int)g & 0xfc) << 3) | \
185 (((int)b & 0xf8) >> 3))
186
187 #define WRITE_PIXEL(_x, _y, p) \
188 *(GLushort *)(buf + _x * 2 + _y * pitch) = p
189
190 #define READ_RGBA(rgba, _x, _y) \
191 do { \
192 GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * pitch); \
193 rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
194 rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
195 rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
196 rgba[3] = 255; \
197 } while (0)
198
199 #define TAG(x) via##x##_565
200 #include "spantmp.h"
201
202 /* 32 bit, 8888 argb color spanline and pixel functions
203 */
204 #undef LOCAL_VARS
205 #undef LOCAL_DEPTH_VARS
206
207 /*=* [DBG] csmash : fix options worng position *=*/
208 /*#define LOCAL_VARS \
209 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
210 GLuint pitch = vmesa->drawPitch; \
211 GLuint height = dPriv->h; \
212 GLuint p; \
213 char *buf = (char *)(vmesa->drawMap + \
214 dPriv->x * 4 + \
215 dPriv->y * pitch); \
216 char *read_buf = (char *)(vmesa->readMap + \
217 dPriv->x * 4 + \
218 dPriv->y * pitch); \
219 (void)read_buf; (void)buf; (void)p*/
220 #define LOCAL_VARS \
221 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
222 GLuint pitch = vmesa->drawPitch; \
223 GLuint height = dPriv->h; \
224 GLuint p; \
225 char *buf, *read_buf; \
226 p = 0; \
227 if (vmesa->glCtx->Color._DrawDestMask == __GL_BACK_BUFFER_MASK) { \
228 buf = (char *)(vmesa->drawMap); \
229 read_buf = (char *)(vmesa->readMap); \
230 } \
231 else { \
232 buf = (char *)(vmesa->drawMap + \
233 dPriv->x * 4 + \
234 dPriv->y * pitch); \
235 read_buf = (char *)(vmesa->readMap + \
236 dPriv->x * 4 + \
237 dPriv->y * pitch); \
238 }
239
240
241 #undef INIT_MONO_PIXEL
242 #define INIT_MONO_PIXEL(p, color) \
243 p = PACK_COLOR_8888(color[3], color[0], color[1], color[2])
244
245 #define WRITE_RGBA(_x, _y, r, g, b, a) \
246 *(GLuint *)(buf + _x * 4 + _y * pitch) = ((r << 16) | \
247 (g << 8) | \
248 (b << 0) | \
249 (a << 24));
250
251
252 #define WRITE_PIXEL(_x, _y, p) \
253 *(GLuint *)(buf + _x * 4 + _y * pitch) = p
254
255 #define READ_RGBA(rgba, _x, _y) \
256 do { \
257 GLuint p = *(GLuint *)(read_buf + _x * 4 + _y * pitch); \
258 rgba[0] = (p >> 16) & 0xff; \
259 rgba[1] = (p >> 8) & 0xff; \
260 rgba[2] = (p >> 0) & 0xff; \
261 rgba[3] = 255; \
262 } while (0)
263
264 #define TAG(x) via##x##_8888
265 #include "spantmp.h"
266 /*#include "via_spantmp.h"*/
267
268 /* 16 bit depthbuffer functions.
269 */
270 /*=* John Sheng [2003.6.16] fix exy press 'i' dirty screen *=*/
271 /*#define LOCAL_DEPTH_VARS \
272 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
273 GLuint pitch = vmesa->depth.pitch; \
274 GLuint height = dPriv->h; \
275 char *buf = (char *)(vmesa->depth.map + \
276 dPriv->x * 2 + \
277 dPriv->y * pitch) */
278 #define LOCAL_DEPTH_VARS \
279 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
280 /*viaScreenPrivate *viaScreen = vmesa->viaScreen;*/ \
281 GLuint pitch = vmesa->depth.pitch; \
282 GLuint height = dPriv->h; \
283 char *buf = (char *)(vmesa->depth.map)
284
285
286 #define WRITE_DEPTH(_x, _y, d) \
287 *(GLushort *)(buf + _x * 2 + _y * pitch) = d;
288
289 #define READ_DEPTH(d, _x, _y) \
290 d = *(GLushort *)(buf + _x * 2 + _y * pitch);
291
292 #define TAG(x) via##x##_16
293 #include "depthtmp.h"
294
295 /* 32 bit depthbuffer functions.
296 */
297 #define WRITE_DEPTH(_x, _y, d) \
298 *(GLuint *)(buf + _x * 4 + _y * pitch) = d;
299
300 #define READ_DEPTH(d, _x, _y) \
301 d = *(GLuint *)(buf + _x * 4 + _y * pitch);
302
303 #define TAG(x) via##x##_32
304 #include "depthtmp.h"
305
306 /* 24/8 bit depthbuffer functions.
307 */
308 /*
309 #define WRITE_DEPTH(_x, _y, d) { \
310 GLuint tmp = *(GLuint *)(buf + _x * 4 + y * pitch); \
311 tmp &= 0xff; \
312 tmp |= (d) & 0xffffff00; \
313 *(GLuint *)(buf + _x * 4 + _y * pitch) = tmp; \
314
315 #define READ_DEPTH(d, _x, _y) \
316 d = (*(GLuint *)(buf + _x * 4 + _y * pitch) & ~0xff) >> 8;
317
318 #define TAG(x) via##x##_24_8
319 #include "depthtmp.h"
320 */
321
322
323 static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
324 GLuint bufferBit)
325 {
326 viaContextPtr vmesa = VIA_CONTEXT(ctx);
327 #ifdef DEBUG
328 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
329 #endif
330 if (bufferBit == DD_FRONT_LEFT_BIT) {
331 vmesa->drawMap = (char *)vmesa->driScreen->pFB;
332 vmesa->readMap = (char *)vmesa->driScreen->pFB;
333 vmesa->drawPitch = vmesa->front.pitch;
334 vmesa->readPitch = vmesa->front.pitch;
335 }
336 else if (bufferBit == DD_BACK_LEFT_BIT) {
337 vmesa->drawMap = vmesa->back.map;
338 vmesa->readMap = vmesa->back.map;
339 vmesa->drawPitch = vmesa->back.pitch;
340 vmesa->readPitch = vmesa->back.pitch;
341 }
342 else {
343 ASSERT(0);
344 }
345 #ifdef DEBUG
346 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
347 #endif
348 }
349
350
351 void viaInitSpanFuncs(GLcontext *ctx)
352 {
353 viaContextPtr vmesa = VIA_CONTEXT(ctx);
354 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
355
356 swdd->SetBuffer = viaSetBuffer;
357 #ifdef DEBUG
358 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
359 #endif
360 if (vmesa->viaScreen->bitsPerPixel == 0x10) {
361 swdd->WriteRGBASpan = viaWriteRGBASpan_565;
362 swdd->WriteRGBSpan = viaWriteRGBSpan_565;
363 swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_565;
364 swdd->WriteRGBAPixels = viaWriteRGBAPixels_565;
365 swdd->WriteMonoRGBAPixels = viaWriteMonoRGBAPixels_565;
366 swdd->ReadRGBASpan = viaReadRGBASpan_565;
367 swdd->ReadRGBAPixels = viaReadRGBAPixels_565;
368 }
369 else if (vmesa->viaScreen->bitsPerPixel == 0x20) {
370 swdd->WriteRGBASpan = viaWriteRGBASpan_8888;
371 swdd->WriteRGBSpan = viaWriteRGBSpan_8888;
372 swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_8888;
373 swdd->WriteRGBAPixels = viaWriteRGBAPixels_8888;
374 swdd->WriteMonoRGBAPixels = viaWriteMonoRGBAPixels_8888;
375 swdd->ReadRGBASpan = viaReadRGBASpan_8888;
376 swdd->ReadRGBAPixels = viaReadRGBAPixels_8888;
377 }
378 else
379 ASSERT(0);
380
381 if (vmesa->glCtx->Visual.depthBits == 0x10) {
382 swdd->ReadDepthSpan = viaReadDepthSpan_16;
383 swdd->WriteDepthSpan = viaWriteDepthSpan_16;
384 swdd->ReadDepthPixels = viaReadDepthPixels_16;
385 swdd->WriteDepthPixels = viaWriteDepthPixels_16;
386 }
387 else if (vmesa->glCtx->Visual.depthBits == 0x20) {
388 swdd->ReadDepthSpan = viaReadDepthSpan_32;
389 swdd->WriteDepthSpan = viaWriteDepthSpan_32;
390 swdd->ReadDepthPixels = viaReadDepthPixels_32;
391 swdd->WriteDepthPixels = viaWriteDepthPixels_32;
392 }
393
394 swdd->WriteCI8Span = NULL;
395 swdd->WriteCI32Span = NULL;
396 swdd->WriteMonoCISpan = NULL;
397 swdd->WriteCI32Pixels = NULL;
398 swdd->WriteMonoCIPixels = NULL;
399 swdd->ReadCI32Span = NULL;
400 swdd->ReadCI32Pixels = NULL;
401 #ifdef DEBUG
402 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
403 #endif
404 }