Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / i915 / intel_span.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "glheader.h"
29 #include "macros.h"
30 #include "mtypes.h"
31 #include "colormac.h"
32
33 #include "intel_screen.h"
34
35 #include "intel_span.h"
36 #include "intel_ioctl.h"
37 #include "swrast/swrast.h"
38
39
40 #define DBG 0
41
42 #define LOCAL_VARS \
43 intelContextPtr intel = INTEL_CONTEXT(ctx); \
44 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
45 intelScreenPrivate *intelScreen = intel->intelScreen; \
46 GLuint pitch = intelScreen->backPitch * intelScreen->cpp; \
47 GLuint height = dPriv->h; \
48 char *buf = (char *)(intel->drawMap + \
49 dPriv->x * intelScreen->cpp + \
50 dPriv->y * pitch); \
51 char *read_buf = (char *)(intel->readMap + \
52 dPriv->x * intelScreen->cpp + \
53 dPriv->y * pitch); \
54 GLushort p; \
55 (void) read_buf; (void) buf; (void) p
56
57 #define LOCAL_DEPTH_VARS \
58 intelContextPtr intel = INTEL_CONTEXT(ctx); \
59 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
60 intelScreenPrivate *intelScreen = intel->intelScreen; \
61 GLuint pitch = intelScreen->backPitch * intelScreen->cpp; \
62 GLuint height = dPriv->h; \
63 char *buf = (char *)(intelScreen->depth.map + \
64 dPriv->x * intelScreen->cpp + \
65 dPriv->y * pitch)
66
67 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
68
69 #define INIT_MONO_PIXEL(p,color)\
70 p = INTEL_PACKCOLOR565(color[0],color[1],color[2])
71
72 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
73 _y >= miny && _y < maxy)
74
75 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
76 if ( _y < miny || _y >= maxy ) { \
77 _n1 = 0, _x1 = x; \
78 } else { \
79 _n1 = _n; \
80 _x1 = _x; \
81 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
82 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
83 }
84
85 #define Y_FLIP(_y) (height - _y - 1)
86
87
88 #define HW_LOCK()
89
90 #define HW_CLIPLOOP() \
91 do { \
92 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
93 int _nc = dPriv->numClipRects; \
94 while (_nc--) { \
95 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
96 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
97 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
98 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
99
100
101 #define HW_ENDCLIPLOOP() \
102 } \
103 } while (0)
104
105 #define HW_UNLOCK()
106
107 /* 16 bit, 565 rgb color spanline and pixel functions
108 */
109 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
110 *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
111 (((int)g & 0xfc) << 3) | \
112 (((int)b & 0xf8) >> 3))
113 #define WRITE_PIXEL( _x, _y, p ) \
114 *(GLushort *)(buf + _x*2 + _y*pitch) = p
115
116 #define READ_RGBA( rgba, _x, _y ) \
117 do { \
118 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
119 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
120 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
121 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
122 rgba[3] = 255; \
123 } while(0)
124
125 #define TAG(x) intel##x##_565
126 #include "spantmp.h"
127
128
129
130
131 /* 15 bit, 555 rgb color spanline and pixel functions
132 */
133 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
134 *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
135 ((g & 0xf8) << 3) | \
136 ((b & 0xf8) >> 3))
137
138 #define WRITE_PIXEL( _x, _y, p ) \
139 *(GLushort *)(buf + _x*2 + _y*pitch) = p
140
141 #define READ_RGBA( rgba, _x, _y ) \
142 do { \
143 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
144 rgba[0] = (p >> 7) & 0xf8; \
145 rgba[1] = (p >> 3) & 0xf8; \
146 rgba[2] = (p << 3) & 0xf8; \
147 rgba[3] = 255; \
148 } while(0)
149
150 #define TAG(x) intel##x##_555
151 #include "spantmp.h"
152
153 /* 16 bit depthbuffer functions.
154 */
155 #define WRITE_DEPTH( _x, _y, d ) \
156 *(GLushort *)(buf + _x*2 + _y*pitch) = d;
157
158 #define READ_DEPTH( d, _x, _y ) \
159 d = *(GLushort *)(buf + _x*2 + _y*pitch);
160
161
162 #define TAG(x) intel##x##_16
163 #include "depthtmp.h"
164
165
166 #undef LOCAL_VARS
167 #define LOCAL_VARS \
168 intelContextPtr intel = INTEL_CONTEXT(ctx); \
169 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
170 intelScreenPrivate *intelScreen = intel->intelScreen; \
171 GLuint pitch = intelScreen->backPitch * intelScreen->cpp; \
172 GLuint height = dPriv->h; \
173 char *buf = (char *)(intel->drawMap + \
174 dPriv->x * intelScreen->cpp + \
175 dPriv->y * pitch); \
176 char *read_buf = (char *)(intel->readMap + \
177 dPriv->x * intelScreen->cpp + \
178 dPriv->y * pitch); \
179 GLuint p; \
180 (void) read_buf; (void) buf; (void) p
181
182 #undef INIT_MONO_PIXEL
183 #define INIT_MONO_PIXEL(p,color)\
184 p = INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3])
185
186 /* 32 bit, 8888 argb color spanline and pixel functions
187 */
188 #define WRITE_RGBA(_x, _y, r, g, b, a) \
189 *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
190 (g << 8) | \
191 (b << 0) | \
192 (a << 24) )
193
194 #define WRITE_PIXEL(_x, _y, p) \
195 *(GLuint *)(buf + _x*4 + _y*pitch) = p
196
197
198 #define READ_RGBA(rgba, _x, _y) \
199 do { \
200 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
201 rgba[0] = (p >> 16) & 0xff; \
202 rgba[1] = (p >> 8) & 0xff; \
203 rgba[2] = (p >> 0) & 0xff; \
204 rgba[3] = (p >> 24) & 0xff; \
205 } while (0)
206
207 #define TAG(x) intel##x##_8888
208 #include "spantmp.h"
209
210
211 /* 24/8 bit interleaved depth/stencil functions
212 */
213 #define WRITE_DEPTH( _x, _y, d ) { \
214 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
215 tmp &= 0xff000000; \
216 tmp |= (d) & 0xffffff; \
217 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
218 }
219
220 #define READ_DEPTH( d, _x, _y ) \
221 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff;
222
223
224 #define TAG(x) intel##x##_24_8
225 #include "depthtmp.h"
226
227 #define WRITE_STENCIL( _x, _y, d ) { \
228 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
229 tmp &= 0xffffff; \
230 tmp |= ((d)<<24); \
231 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
232 }
233
234 #define READ_STENCIL( d, _x, _y ) \
235 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24;
236
237 #define TAG(x) intel##x##_24_8
238 #include "stenciltmp.h"
239
240
241 /*
242 * This function is called to specify which buffer to read and write
243 * for software rasterization (swrast) fallbacks. This doesn't necessarily
244 * correspond to glDrawBuffer() or glReadBuffer() calls.
245 */
246 static void intelSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
247 GLuint bufferBit)
248 {
249 intelContextPtr intel = INTEL_CONTEXT(ctx);
250 if (bufferBit == DD_FRONT_LEFT_BIT) {
251 intel->drawMap = (char *)intel->driScreen->pFB;
252 intel->readMap = (char *)intel->driScreen->pFB;
253 } else if (bufferBit == DD_BACK_LEFT_BIT) {
254 intel->drawMap = intel->intelScreen->back.map;
255 intel->readMap = intel->intelScreen->back.map;
256 } else {
257 ASSERT(0);
258 }
259 }
260
261
262 /* Move locking out to get reasonable span performance.
263 */
264 void intelSpanRenderStart( GLcontext *ctx )
265 {
266 intelContextPtr intel = INTEL_CONTEXT(ctx);
267
268 intelFlush(&intel->ctx);
269 LOCK_HARDWARE(intel);
270 intelWaitForIdle(intel);
271 }
272
273 void intelSpanRenderFinish( GLcontext *ctx )
274 {
275 intelContextPtr intel = INTEL_CONTEXT( ctx );
276 _swrast_flush( ctx );
277 UNLOCK_HARDWARE( intel );
278 }
279
280 void intelInitSpanFuncs( GLcontext *ctx )
281 {
282 intelContextPtr intel = INTEL_CONTEXT(ctx);
283 intelScreenPrivate *intelScreen = intel->intelScreen;
284
285 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
286
287 swdd->SetBuffer = intelSetBuffer;
288
289 switch (intelScreen->fbFormat) {
290 case DV_PF_555:
291 swdd->WriteRGBASpan = intelWriteRGBASpan_555;
292 swdd->WriteRGBSpan = intelWriteRGBSpan_555;
293 swdd->WriteMonoRGBASpan = intelWriteMonoRGBASpan_555;
294 swdd->WriteRGBAPixels = intelWriteRGBAPixels_555;
295 swdd->WriteMonoRGBAPixels = intelWriteMonoRGBAPixels_555;
296 swdd->ReadRGBASpan = intelReadRGBASpan_555;
297 swdd->ReadRGBAPixels = intelReadRGBAPixels_555;
298
299 swdd->ReadDepthSpan = intelReadDepthSpan_16;
300 swdd->WriteDepthSpan = intelWriteDepthSpan_16;
301 swdd->ReadDepthPixels = intelReadDepthPixels_16;
302 swdd->WriteDepthPixels = intelWriteDepthPixels_16;
303 break;
304
305 case DV_PF_565:
306 swdd->WriteRGBASpan = intelWriteRGBASpan_565;
307 swdd->WriteRGBSpan = intelWriteRGBSpan_565;
308 swdd->WriteMonoRGBASpan = intelWriteMonoRGBASpan_565;
309 swdd->WriteRGBAPixels = intelWriteRGBAPixels_565;
310 swdd->WriteMonoRGBAPixels = intelWriteMonoRGBAPixels_565;
311 swdd->ReadRGBASpan = intelReadRGBASpan_565;
312 swdd->ReadRGBAPixels = intelReadRGBAPixels_565;
313
314 swdd->ReadDepthSpan = intelReadDepthSpan_16;
315 swdd->WriteDepthSpan = intelWriteDepthSpan_16;
316 swdd->ReadDepthPixels = intelReadDepthPixels_16;
317 swdd->WriteDepthPixels = intelWriteDepthPixels_16;
318 break;
319
320 case DV_PF_8888:
321 swdd->WriteRGBASpan = intelWriteRGBASpan_8888;
322 swdd->WriteRGBSpan = intelWriteRGBSpan_8888;
323 swdd->WriteMonoRGBASpan = intelWriteMonoRGBASpan_8888;
324 swdd->WriteRGBAPixels = intelWriteRGBAPixels_8888;
325 swdd->WriteMonoRGBAPixels = intelWriteMonoRGBAPixels_8888;
326 swdd->ReadRGBASpan = intelReadRGBASpan_8888;
327 swdd->ReadRGBAPixels = intelReadRGBAPixels_8888;
328
329 swdd->ReadDepthSpan = intelReadDepthSpan_24_8;
330 swdd->WriteDepthSpan = intelWriteDepthSpan_24_8;
331 swdd->ReadDepthPixels = intelReadDepthPixels_24_8;
332 swdd->WriteDepthPixels = intelWriteDepthPixels_24_8;
333
334 swdd->WriteStencilSpan = intelWriteStencilSpan_24_8;
335 swdd->ReadStencilSpan = intelReadStencilSpan_24_8;
336 swdd->WriteStencilPixels = intelWriteStencilPixels_24_8;
337 swdd->ReadStencilPixels = intelReadStencilPixels_24_8;
338 break;
339 }
340
341 swdd->SpanRenderStart = intelSpanRenderStart;
342 swdd->SpanRenderFinish = intelSpanRenderFinish;
343 }