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 #define GET_SRC_PTR(_x, _y) (read_buf + _x * 2 + _y * pitch)
129 #define GET_DST_PTR(_x, _y) ( buf + _x * 2 + _y * pitch)
130 #define SPANTMP_PIXEL_FMT GL_RGB
131 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
133 #define TAG(x) r128##x##_RGB565
134 #define TAG2(x,y) r128##x##_RGB565##y
135 #include "spantmp2.h"
138 /* 32 bit, ARGB8888 color spanline and pixel functions
140 #define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * pitch)
141 #define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * pitch)
142 #define SPANTMP_PIXEL_FMT GL_BGRA
143 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
145 #define TAG(x) r128##x##_ARGB8888
146 #define TAG2(x,y) r128##x##_ARGB8888##y
147 #include "spantmp2.h"
150 /* ================================================================
154 /* 16-bit depth buffer functions
156 #define READ_DEPTH(d, _x, _y) \
157 d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch)
159 #define WRITE_DEPTH_SPAN() \
160 r128WriteDepthSpanLocked( rmesa, n, \
165 #define WRITE_DEPTH_PIXELS() \
167 GLint ox[MAX_WIDTH]; \
168 GLint oy[MAX_WIDTH]; \
169 for ( i = 0 ; i < n ; i++ ) { \
170 ox[i] = x[i] + dPriv->x; \
172 for ( i = 0 ; i < n ; i++ ) { \
173 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
175 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
178 #define READ_DEPTH_SPAN() \
180 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
181 r128scrn->spanOffset); \
184 r128ReadDepthSpanLocked( rmesa, n, \
187 r128WaitForIdleLocked( rmesa ); \
189 for ( i = 0 ; i < n ; i++ ) { \
194 #define READ_DEPTH_PIXELS() \
196 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
197 r128scrn->spanOffset); \
198 GLint i, remaining = n; \
200 while ( remaining > 0 ) { \
201 GLint ox[MAX_WIDTH]; \
202 GLint oy[MAX_WIDTH]; \
205 if ( remaining <= 128 ) { \
210 for ( i = 0 ; i < count ; i++ ) { \
211 ox[i] = x[i] + dPriv->x; \
213 for ( i = 0 ; i < count ; i++ ) { \
214 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
217 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
218 r128WaitForIdleLocked( rmesa ); \
220 for ( i = 0 ; i < count ; i++ ) { \
226 remaining -= count; \
230 #define TAG(x) r128##x##_16
231 #include "depthtmp.h"
234 /* 24-bit depth, 8-bit stencil buffer functions
236 #define WRITE_DEPTH_SPAN() \
237 r128WriteDepthSpanLocked( rmesa, n, \
242 #define WRITE_DEPTH_PIXELS() \
244 GLint ox[MAX_WIDTH]; \
245 GLint oy[MAX_WIDTH]; \
246 for ( i = 0 ; i < n ; i++ ) { \
247 ox[i] = x[i] + dPriv->x; \
249 for ( i = 0 ; i < n ; i++ ) { \
250 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
252 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
255 #define READ_DEPTH_SPAN() \
257 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
258 r128scrn->spanOffset); \
261 r128ReadDepthSpanLocked( rmesa, n, \
264 r128WaitForIdleLocked( rmesa ); \
266 for ( i = 0 ; i < n ; i++ ) { \
267 depth[i] = buf[i] & 0x00ffffff; \
271 #define READ_DEPTH_PIXELS() \
273 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
274 r128scrn->spanOffset); \
275 GLint i, remaining = n; \
277 while ( remaining > 0 ) { \
278 GLint ox[MAX_WIDTH]; \
279 GLint oy[MAX_WIDTH]; \
282 if ( remaining <= 128 ) { \
287 for ( i = 0 ; i < count ; i++ ) { \
288 ox[i] = x[i] + dPriv->x; \
290 for ( i = 0 ; i < count ; i++ ) { \
291 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
294 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
295 r128WaitForIdleLocked( rmesa ); \
297 for ( i = 0 ; i < count ; i++ ) { \
298 depth[i] = buf[i] & 0x00ffffff; \
303 remaining -= count; \
307 #define TAG(x) r128##x##_24_8
308 #include "depthtmp.h"
312 /* ================================================================
316 /* FIXME: Add support for hardware stencil buffers.
320 /* 32 bit depthbuffer functions */
321 #define WRITE_DEPTH(_x, _y, d) \
322 *(GLuint *)(buf + _x*4 + _y*pitch) = d
327 * This function is called to specify which buffer to read and write
328 * for software rasterization (swrast) fallbacks. This doesn't necessarily
329 * correspond to glDrawBuffer() or glReadBuffer() calls.
331 static void r128DDSetBuffer( GLcontext
*ctx
,
332 GLframebuffer
*colorBuffer
,
335 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
337 switch ( bufferBit
) {
338 case BUFFER_BIT_FRONT_LEFT
:
339 if ( rmesa
->sarea
->pfCurrentPage
== 1 ) {
340 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
341 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
343 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
344 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
347 case BUFFER_BIT_BACK_LEFT
:
348 if ( rmesa
->sarea
->pfCurrentPage
== 1 ) {
349 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
350 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
352 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
353 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
362 void r128DDInitSpanFuncs( GLcontext
*ctx
)
364 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
365 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
367 swdd
->SetBuffer
= r128DDSetBuffer
;
369 switch ( rmesa
->r128Screen
->cpp
) {
372 r128InitPointers_RGB565( swdd
);
378 r128InitPointers_ARGB8888( swdd
);
386 switch ( rmesa
->glCtx
->Visual
.depthBits
) {
389 swdd
->ReadDepthSpan
= r128ReadDepthSpan_16
;
390 swdd
->WriteDepthSpan
= r128WriteDepthSpan_16
;
391 swdd
->ReadDepthPixels
= r128ReadDepthPixels_16
;
392 swdd
->WriteDepthPixels
= r128WriteDepthPixels_16
;
398 swdd
->ReadDepthSpan
= r128ReadDepthSpan_24_8
;
399 swdd
->WriteDepthSpan
= r128WriteDepthSpan_24_8
;
400 swdd
->ReadDepthPixels
= r128ReadDepthPixels_24_8
;
401 swdd
->WriteDepthPixels
= r128WriteDepthPixels_24_8
;
409 swdd
->WriteCI8Span
= NULL
;
410 swdd
->WriteCI32Span
= NULL
;
411 swdd
->WriteMonoCISpan
= NULL
;
412 swdd
->WriteCI32Pixels
= NULL
;
413 swdd
->WriteMonoCIPixels
= NULL
;
414 swdd
->ReadCI32Span
= NULL
;
415 swdd
->ReadCI32Pixels
= NULL
;
420 * Plug in the Get/Put routines for the given driRenderbuffer.
423 r128SetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
425 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
426 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
427 r128InitPointers_RGB565(&drb
->Base
);
430 r128InitPointers_ARGB8888(&drb
->Base
);
433 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
) {
434 drb
->Base
.GetRow
= r128ReadDepthSpan_16
;
435 drb
->Base
.GetValues
= r128ReadDepthPixels_16
;
436 drb
->Base
.PutRow
= r128WriteDepthSpan_16
;
437 drb
->Base
.PutMonoRow
= r128WriteMonoDepthSpan_16
;
438 drb
->Base
.PutValues
= r128WriteDepthPixels_16
;
439 drb
->Base
.PutMonoValues
= NULL
;
441 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
442 drb
->Base
.GetRow
= r128ReadDepthSpan_24_8
;
443 drb
->Base
.GetValues
= r128ReadDepthPixels_24_8
;
444 drb
->Base
.PutRow
= r128WriteDepthSpan_24_8
;
445 drb
->Base
.PutMonoRow
= r128WriteMonoDepthSpan_24_8
;
446 drb
->Base
.PutValues
= r128WriteDepthPixels_24_8
;
447 drb
->Base
.PutMonoValues
= NULL
;
449 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
450 drb
->Base
.GetRow
= NULL
;
451 drb
->Base
.GetValues
= NULL
;
452 drb
->Base
.PutRow
= NULL
;
453 drb
->Base
.PutMonoRow
= NULL
;
454 drb
->Base
.PutValues
= NULL
;
455 drb
->Base
.PutMonoValues
= NULL
;