1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.8 2002/10/30 12:51:39 alanh Exp $ */
2 /**************************************************************************
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 * Kevin E. Martin <martin@valinux.com>
37 #include "r128_context.h"
38 #include "r128_ioctl.h"
39 #include "r128_state.h"
40 #include "r128_span.h"
43 #include "swrast/swrast.h"
47 #define HAVE_HW_DEPTH_SPANS 1
48 #define HAVE_HW_DEPTH_PIXELS 1
51 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
52 r128ScreenPtr r128scrn = rmesa->r128Screen; \
53 __DRIscreenPrivate *sPriv = rmesa->driScreen; \
54 __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \
55 GLuint pitch = r128scrn->frontPitch * r128scrn->cpp; \
56 GLuint height = dPriv->h; \
57 char *buf = (char *)(sPriv->pFB + \
59 (dPriv->x * r128scrn->cpp) + \
60 (dPriv->y * pitch)); \
61 char *read_buf = (char *)(sPriv->pFB + \
63 (dPriv->x * r128scrn->cpp) + \
64 (dPriv->y * pitch)); \
66 (void) read_buf; (void) buf; (void) p
68 #define LOCAL_DEPTH_VARS \
69 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
70 r128ScreenPtr r128scrn = rmesa->r128Screen; \
71 __DRIscreenPrivate *sPriv = rmesa->driScreen; \
72 __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \
73 GLuint height = dPriv->h; \
74 (void) r128scrn; (void) sPriv; (void) height
76 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
79 #define CLIPPIXEL( _x, _y ) \
80 ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
83 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
84 if ( _y < miny || _y >= maxy ) { \
89 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
90 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
93 #define Y_FLIP( _y ) (height - _y - 1)
97 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
98 FLUSH_BATCH( rmesa ); \
99 LOCK_HARDWARE( rmesa ); \
100 r128WaitForIdleLocked( rmesa );
102 #define HW_CLIPLOOP() \
104 __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \
105 int _nc = dPriv->numClipRects; \
108 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
109 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
110 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
111 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
113 #define HW_ENDCLIPLOOP() \
117 #define HW_UNLOCK() \
118 UNLOCK_HARDWARE( rmesa )
122 /* ================================================================
126 /* 16 bit, RGB565 color spanline and pixel functions
128 #undef INIT_MONO_PIXEL
129 #define INIT_MONO_PIXEL(p, color) \
130 p = R128PACKCOLOR565( color[0], color[1], color[2] )
132 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
133 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
134 (((int)g & 0xfc) << 3) | \
135 (((int)b & 0xf8) >> 3))
137 #define WRITE_PIXEL( _x, _y, p ) \
138 *(GLushort *)(buf + _x*2 + _y*pitch) = p
140 #define READ_RGBA( rgba, _x, _y ) \
142 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
143 rgba[0] = (p >> 8) & 0xf8; \
144 rgba[1] = (p >> 3) & 0xfc; \
145 rgba[2] = (p << 3) & 0xf8; \
147 if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
148 if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
149 if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \
152 #define TAG(x) r128##x##_RGB565
155 #define READ_DEPTH(d, _x, _y) \
156 d = *(GLushort *)(buf + _x*2 + _y*pitch)
158 /* 32 bit, ARGB8888 color spanline and pixel functions
160 #undef INIT_MONO_PIXEL
161 #define INIT_MONO_PIXEL(p, color) \
162 p = R128PACKCOLOR8888( color[0], color[1], color[2], color[3] )
164 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
165 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
170 #define WRITE_PIXEL( _x, _y, p ) \
171 *(GLuint *)(buf + _x*4 + _y*pitch) = p
173 #define READ_RGBA( rgba, _x, _y ) \
175 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
176 rgba[0] = (p >> 16) & 0xff; \
177 rgba[1] = (p >> 8) & 0xff; \
178 rgba[2] = (p >> 0) & 0xff; \
179 rgba[3] = 0xff;/*(p >> 24) & 0xff;*/ \
182 #define TAG(x) r128##x##_ARGB8888
186 /* 24 bit, RGB888 color spanline and pixel functions */
187 #undef INIT_MONO_PIXEL
188 #define INIT_MONO_PIXEL(p, color) \
189 p = R128PACKCOLOR888( color[0], color[1], color[2] )
191 #define WRITE_RGBA(_x, _y, r, g, b, a) \
192 *(GLuint *)(buf + _x*3 + _y*pitch) = ((r << 16) | \
196 #define WRITE_PIXEL(_x, _y, p) \
197 *(GLuint *)(buf + _x*3 + _y*pitch) = p
199 #define READ_RGBA(rgba, _x, _y) \
201 GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \
202 rgba[0] = (p >> 16) & 0xff; \
203 rgba[1] = (p >> 8) & 0xff; \
204 rgba[2] = (p >> 0) & 0xff; \
208 /* ================================================================
212 /* 16-bit depth buffer functions
214 #define WRITE_DEPTH_SPAN() \
215 r128WriteDepthSpanLocked( rmesa, n, \
220 #define WRITE_DEPTH_PIXELS() \
222 GLint ox[MAX_WIDTH]; \
223 GLint oy[MAX_WIDTH]; \
224 for ( i = 0 ; i < n ; i++ ) { \
225 ox[i] = x[i] + dPriv->x; \
227 for ( i = 0 ; i < n ; i++ ) { \
228 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
230 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
233 #define READ_DEPTH_SPAN() \
235 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
236 r128scrn->spanOffset); \
239 r128ReadDepthSpanLocked( rmesa, n, \
242 r128WaitForIdleLocked( rmesa ); \
244 for ( i = 0 ; i < n ; i++ ) { \
249 #define READ_DEPTH_PIXELS() \
251 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
252 r128scrn->spanOffset); \
253 GLint i, remaining = n; \
255 while ( remaining > 0 ) { \
256 GLint ox[MAX_WIDTH]; \
257 GLint oy[MAX_WIDTH]; \
260 if ( remaining <= 128 ) { \
265 for ( i = 0 ; i < count ; i++ ) { \
266 ox[i] = x[i] + dPriv->x; \
268 for ( i = 0 ; i < count ; i++ ) { \
269 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
272 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
273 r128WaitForIdleLocked( rmesa ); \
275 for ( i = 0 ; i < count ; i++ ) { \
281 remaining -= count; \
285 #define TAG(x) r128##x##_16
286 #include "depthtmp.h"
289 /* 24-bit depth, 8-bit stencil buffer functions
291 #define WRITE_DEPTH_SPAN() \
292 r128WriteDepthSpanLocked( rmesa, n, \
297 #define WRITE_DEPTH_PIXELS() \
299 GLint ox[MAX_WIDTH]; \
300 GLint oy[MAX_WIDTH]; \
301 for ( i = 0 ; i < n ; i++ ) { \
302 ox[i] = x[i] + dPriv->x; \
304 for ( i = 0 ; i < n ; i++ ) { \
305 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
307 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
310 #define READ_DEPTH_SPAN() \
312 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
313 r128scrn->spanOffset); \
316 r128ReadDepthSpanLocked( rmesa, n, \
319 r128WaitForIdleLocked( rmesa ); \
321 for ( i = 0 ; i < n ; i++ ) { \
322 depth[i] = buf[i] & 0x00ffffff; \
326 #define READ_DEPTH_PIXELS() \
328 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
329 r128scrn->spanOffset); \
330 GLint i, remaining = n; \
332 while ( remaining > 0 ) { \
333 GLint ox[MAX_WIDTH]; \
334 GLint oy[MAX_WIDTH]; \
337 if ( remaining <= 128 ) { \
342 for ( i = 0 ; i < count ; i++ ) { \
343 ox[i] = x[i] + dPriv->x; \
345 for ( i = 0 ; i < count ; i++ ) { \
346 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
349 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
350 r128WaitForIdleLocked( rmesa ); \
352 for ( i = 0 ; i < count ; i++ ) { \
353 depth[i] = buf[i] & 0x00ffffff; \
358 remaining -= count; \
362 #define TAG(x) r128##x##_24_8
363 #include "depthtmp.h"
367 /* ================================================================
371 /* FIXME: Add support for hardware stencil buffers.
375 /* 32 bit depthbuffer functions */
376 #define WRITE_DEPTH(_x, _y, d) \
377 *(GLuint *)(buf + _x*4 + _y*pitch) = d
382 * This function is called to specify which buffer to read and write
383 * for software rasterization (swrast) fallbacks. This doesn't necessarily
384 * correspond to glDrawBuffer() or glReadBuffer() calls.
386 static void r128DDSetBuffer( GLcontext
*ctx
,
387 GLframebuffer
*colorBuffer
,
390 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
392 switch ( bufferBit
) {
394 if ( rmesa
->sarea
->pfCurrentPage
== 1 ) {
395 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
396 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
398 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
399 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
403 if ( rmesa
->sarea
->pfCurrentPage
== 1 ) {
404 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
405 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
407 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
408 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
417 void r128DDInitSpanFuncs( GLcontext
*ctx
)
419 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
420 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
422 swdd
->SetBuffer
= r128DDSetBuffer
;
424 switch ( rmesa
->r128Screen
->cpp
) {
426 swdd
->WriteRGBASpan
= r128WriteRGBASpan_RGB565
;
427 swdd
->WriteRGBSpan
= r128WriteRGBSpan_RGB565
;
428 swdd
->WriteMonoRGBASpan
= r128WriteMonoRGBASpan_RGB565
;
429 swdd
->WriteRGBAPixels
= r128WriteRGBAPixels_RGB565
;
430 swdd
->WriteMonoRGBAPixels
= r128WriteMonoRGBAPixels_RGB565
;
431 swdd
->ReadRGBASpan
= r128ReadRGBASpan_RGB565
;
432 swdd
->ReadRGBAPixels
= r128ReadRGBAPixels_RGB565
;
436 swdd
->WriteRGBASpan
= r128WriteRGBASpan_ARGB8888
;
437 swdd
->WriteRGBSpan
= r128WriteRGBSpan_ARGB8888
;
438 swdd
->WriteMonoRGBASpan
= r128WriteMonoRGBASpan_ARGB8888
;
439 swdd
->WriteRGBAPixels
= r128WriteRGBAPixels_ARGB8888
;
440 swdd
->WriteMonoRGBAPixels
= r128WriteMonoRGBAPixels_ARGB8888
;
441 swdd
->ReadRGBASpan
= r128ReadRGBASpan_ARGB8888
;
442 swdd
->ReadRGBAPixels
= r128ReadRGBAPixels_ARGB8888
;
449 switch ( rmesa
->glCtx
->Visual
.depthBits
) {
451 swdd
->ReadDepthSpan
= r128ReadDepthSpan_16
;
452 swdd
->WriteDepthSpan
= r128WriteDepthSpan_16
;
453 swdd
->ReadDepthPixels
= r128ReadDepthPixels_16
;
454 swdd
->WriteDepthPixels
= r128WriteDepthPixels_16
;
458 swdd
->ReadDepthSpan
= r128ReadDepthSpan_24_8
;
459 swdd
->WriteDepthSpan
= r128WriteDepthSpan_24_8
;
460 swdd
->ReadDepthPixels
= r128ReadDepthPixels_24_8
;
461 swdd
->WriteDepthPixels
= r128WriteDepthPixels_24_8
;
468 swdd
->WriteCI8Span
= NULL
;
469 swdd
->WriteCI32Span
= NULL
;
470 swdd
->WriteMonoCISpan
= NULL
;
471 swdd
->WriteCI32Pixels
= NULL
;
472 swdd
->WriteMonoCIPixels
= NULL
;
473 swdd
->ReadCI32Span
= NULL
;
474 swdd
->ReadCI32Pixels
= NULL
;