1 /**************************************************************************
3 Copyright 2001 VA Linux Systems Inc., Fremont, California.
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:
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
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 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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.
26 **************************************************************************/
28 /* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.c,v 1.4 2002/12/10 01:26:53 dawes Exp $ */
33 * Heavily based on the I810 driver, which was written by Keith Whitwell.
35 * \author Jeff Hartmann <jhartmann@2d3d.com>
36 * \author Keith Whitwell <keith@tungstengraphics.com>
44 #include "i830_screen.h"
47 #include "i830_span.h"
48 #include "i830_ioctl.h"
49 #include "swrast/swrast.h"
55 i830ContextPtr imesa = I830_CONTEXT(ctx); \
56 __DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \
57 i830ScreenPrivate *i830Screen = imesa->i830Screen; \
58 GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \
59 GLuint height = dPriv->h; \
60 char *buf = (char *)(imesa->drawMap + \
61 dPriv->x * i830Screen->cpp + \
63 char *read_buf = (char *)(imesa->readMap + \
64 dPriv->x * i830Screen->cpp + \
67 (void) read_buf; (void) buf; (void) p
69 #define LOCAL_DEPTH_VARS \
70 i830ContextPtr imesa = I830_CONTEXT(ctx); \
71 __DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \
72 i830ScreenPrivate *i830Screen = imesa->i830Screen; \
73 GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \
74 GLuint height = dPriv->h; \
75 char *buf = (char *)(i830Screen->depth.map + \
76 dPriv->x * i830Screen->cpp + \
79 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
81 #define INIT_MONO_PIXEL(p,color)\
82 p = PACK_COLOR_565(color[0],color[1],color[2])
84 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
85 _y >= miny && _y < maxy)
87 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
88 if ( _y < miny || _y >= maxy ) { \
93 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
94 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
97 #define Y_FLIP(_y) (height - _y - 1)
102 #define HW_CLIPLOOP() \
104 __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
105 int _nc = dPriv->numClipRects; \
107 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
108 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
109 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
110 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
113 #define HW_ENDCLIPLOOP() \
119 /* 16 bit, 565 rgb color spanline and pixel functions
121 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
122 *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
123 (((int)g & 0xfc) << 3) | \
124 (((int)b & 0xf8) >> 3))
125 #define WRITE_PIXEL( _x, _y, p ) \
126 *(GLushort *)(buf + _x*2 + _y*pitch) = p
128 #define READ_RGBA( rgba, _x, _y ) \
130 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
131 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
132 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
133 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
137 #define TAG(x) i830##x##_565
143 /* 15 bit, 555 rgb color spanline and pixel functions
145 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
146 *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
147 ((g & 0xf8) << 3) | \
150 #define WRITE_PIXEL( _x, _y, p ) \
151 *(GLushort *)(buf + _x*2 + _y*pitch) = p
153 #define READ_RGBA( rgba, _x, _y ) \
155 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
156 rgba[0] = (p >> 7) & 0xf8; \
157 rgba[1] = (p >> 3) & 0xf8; \
158 rgba[2] = (p << 3) & 0xf8; \
162 #define TAG(x) i830##x##_555
165 /* 16 bit depthbuffer functions.
167 #define WRITE_DEPTH( _x, _y, d ) \
168 *(GLushort *)(buf + _x*2 + _y*pitch) = d;
170 #define READ_DEPTH( d, _x, _y ) \
171 d = *(GLushort *)(buf + _x*2 + _y*pitch);
174 #define TAG(x) i830##x##_16
175 #include "depthtmp.h"
180 i830ContextPtr imesa = I830_CONTEXT(ctx); \
181 __DRIdrawablePrivate *dPriv = imesa->driDrawable; \
182 i830ScreenPrivate *i830Screen = imesa->i830Screen; \
183 GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \
184 GLuint height = dPriv->h; \
185 char *buf = (char *)(imesa->drawMap + \
186 dPriv->x * i830Screen->cpp + \
188 char *read_buf = (char *)(imesa->readMap + \
189 dPriv->x * i830Screen->cpp + \
191 GLuint p = I830_CONTEXT( ctx )->MonoColor; \
192 (void) read_buf; (void) buf; (void) p
194 #undef INIT_MONO_PIXEL
195 #define INIT_MONO_PIXEL(p,color)\
196 p = PACK_COLOR_888(color[0],color[1],color[2])
198 /* 32 bit, 8888 argb color spanline and pixel functions
200 #define WRITE_RGBA(_x, _y, r, g, b, a) \
201 *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
206 #define WRITE_PIXEL(_x, _y, p) \
207 *(GLuint *)(buf + _x*4 + _y*pitch) = p
210 #define READ_RGBA(rgba, _x, _y) \
212 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
213 rgba[0] = (p >> 16) & 0xff; \
214 rgba[1] = (p >> 8) & 0xff; \
215 rgba[2] = (p >> 0) & 0xff; \
216 rgba[3] = (p >> 24) & 0xff; \
219 #define TAG(x) i830##x##_8888
222 /* 24 bit depthbuffer functions.
224 #define WRITE_DEPTH( _x, _y, d ) \
225 *(GLuint *)(buf + _x*4 + _y*pitch) = 0xffffff & d;
227 #define READ_DEPTH( d, _x, _y ) \
228 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xffffff;
230 #define TAG(x) i830##x##_24
231 #include "depthtmp.h"
233 /* 24/8 bit interleaved depth/stencil functions
235 #define WRITE_DEPTH( _x, _y, d ) { \
236 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
238 tmp |= (d) & 0xffffff; \
239 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
242 #define READ_DEPTH( d, _x, _y ) \
243 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xffffff;
246 #define TAG(x) i830##x##_24_8
247 #include "depthtmp.h"
249 #define WRITE_STENCIL( _x, _y, d ) { \
250 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
253 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
256 #define READ_STENCIL( d, _x, _y ) \
257 d = *(GLuint *)(buf + _x*4 + _y*pitch) >> 24;
259 #define TAG(x) i830##x##_24_8
260 #include "stenciltmp.h"
263 * This function is called to specify which buffer to read and write
264 * for software rasterization (swrast) fallbacks. This doesn't necessarily
265 * correspond to glDrawBuffer() or glReadBuffer() calls.
267 static void i830SetBuffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
270 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
272 assert( (colorBuffer
== imesa
->driDrawable
->driverPrivate
)
273 || (colorBuffer
== imesa
->driReadable
->driverPrivate
) );
275 imesa
->mesa_drawable
= (colorBuffer
== imesa
->driDrawable
->driverPrivate
)
276 ? imesa
->driDrawable
: imesa
->driReadable
;
278 if (bufferBit
== DD_FRONT_LEFT_BIT
) {
279 imesa
->drawMap
= (char *)imesa
->driScreen
->pFB
;
280 imesa
->readMap
= (char *)imesa
->driScreen
->pFB
;
281 } else if (bufferBit
== DD_BACK_LEFT_BIT
) {
282 imesa
->drawMap
= imesa
->i830Screen
->back
.map
;
283 imesa
->readMap
= imesa
->i830Screen
->back
.map
;
291 /* Move locking out to get reasonable span performance.
293 void i830SpanRenderStart( GLcontext
*ctx
)
295 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
296 I830_FIREVERTICES(imesa
);
297 LOCK_HARDWARE(imesa
);
298 i830RegetLockQuiescent( imesa
);
301 void i830SpanRenderFinish( GLcontext
*ctx
)
303 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
304 _swrast_flush( ctx
);
305 UNLOCK_HARDWARE( imesa
);
308 void i830DDInitSpanFuncs( GLcontext
*ctx
)
310 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
311 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
313 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
315 swdd
->SetBuffer
= i830SetBuffer
;
317 switch (i830Screen
->fbFormat
) {
319 swdd
->WriteRGBASpan
= i830WriteRGBASpan_555
;
320 swdd
->WriteRGBSpan
= i830WriteRGBSpan_555
;
321 swdd
->WriteMonoRGBASpan
= i830WriteMonoRGBASpan_555
;
322 swdd
->WriteRGBAPixels
= i830WriteRGBAPixels_555
;
323 swdd
->WriteMonoRGBAPixels
= i830WriteMonoRGBAPixels_555
;
324 swdd
->ReadRGBASpan
= i830ReadRGBASpan_555
;
325 swdd
->ReadRGBAPixels
= i830ReadRGBAPixels_555
;
327 swdd
->ReadDepthSpan
= i830ReadDepthSpan_16
;
328 swdd
->WriteDepthSpan
= i830WriteDepthSpan_16
;
329 swdd
->ReadDepthPixels
= i830ReadDepthPixels_16
;
330 swdd
->WriteDepthPixels
= i830WriteDepthPixels_16
;
334 swdd
->WriteRGBASpan
= i830WriteRGBASpan_565
;
335 swdd
->WriteRGBSpan
= i830WriteRGBSpan_565
;
336 swdd
->WriteMonoRGBASpan
= i830WriteMonoRGBASpan_565
;
337 swdd
->WriteRGBAPixels
= i830WriteRGBAPixels_565
;
338 swdd
->WriteMonoRGBAPixels
= i830WriteMonoRGBAPixels_565
;
339 swdd
->ReadRGBASpan
= i830ReadRGBASpan_565
;
340 swdd
->ReadRGBAPixels
= i830ReadRGBAPixels_565
;
342 swdd
->ReadDepthSpan
= i830ReadDepthSpan_16
;
343 swdd
->WriteDepthSpan
= i830WriteDepthSpan_16
;
344 swdd
->ReadDepthPixels
= i830ReadDepthPixels_16
;
345 swdd
->WriteDepthPixels
= i830WriteDepthPixels_16
;
349 swdd
->WriteRGBASpan
= i830WriteRGBASpan_8888
;
350 swdd
->WriteRGBSpan
= i830WriteRGBSpan_8888
;
351 swdd
->WriteMonoRGBASpan
= i830WriteMonoRGBASpan_8888
;
352 swdd
->WriteRGBAPixels
= i830WriteRGBAPixels_8888
;
353 swdd
->WriteMonoRGBAPixels
= i830WriteMonoRGBAPixels_8888
;
354 swdd
->ReadRGBASpan
= i830ReadRGBASpan_8888
;
355 swdd
->ReadRGBAPixels
= i830ReadRGBAPixels_8888
;
357 if(imesa
->hw_stencil
) {
358 swdd
->ReadDepthSpan
= i830ReadDepthSpan_24_8
;
359 swdd
->WriteDepthSpan
= i830WriteDepthSpan_24_8
;
360 swdd
->ReadDepthPixels
= i830ReadDepthPixels_24_8
;
361 swdd
->WriteDepthPixels
= i830WriteDepthPixels_24_8
;
363 swdd
->WriteStencilSpan
= i830WriteStencilSpan_24_8
;
364 swdd
->ReadStencilSpan
= i830ReadStencilSpan_24_8
;
365 swdd
->WriteStencilPixels
= i830WriteStencilPixels_24_8
;
366 swdd
->ReadStencilPixels
= i830ReadStencilPixels_24_8
;
368 swdd
->ReadDepthSpan
= i830ReadDepthSpan_24
;
369 swdd
->WriteDepthSpan
= i830WriteDepthSpan_24
;
370 swdd
->ReadDepthPixels
= i830ReadDepthPixels_24
;
371 swdd
->WriteDepthPixels
= i830WriteDepthPixels_24
;
376 swdd
->SpanRenderStart
= i830SpanRenderStart
;
377 swdd
->SpanRenderFinish
= i830SpanRenderFinish
;