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
78 #define Y_FLIP( _y ) (height - _y - 1)
86 /* ================================================================
90 /* 16 bit, RGB565 color spanline and pixel functions
92 #define SPANTMP_PIXEL_FMT GL_RGB
93 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
95 #define TAG(x) r128##x##_RGB565
96 #define TAG2(x,y) r128##x##_RGB565##y
100 /* 32 bit, ARGB8888 color spanline and pixel functions
102 #define SPANTMP_PIXEL_FMT GL_BGRA
103 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
105 #define TAG(x) r128##x##_ARGB8888
106 #define TAG2(x,y) r128##x##_ARGB8888##y
107 #include "spantmp2.h"
110 /* ================================================================
114 /* 16-bit depth buffer functions
117 #define WRITE_DEPTH_SPAN() \
118 r128WriteDepthSpanLocked( rmesa, n, \
123 #define WRITE_DEPTH_PIXELS() \
125 GLint ox[MAX_WIDTH]; \
126 GLint oy[MAX_WIDTH]; \
127 for ( i = 0 ; i < n ; i++ ) { \
128 ox[i] = x[i] + dPriv->x; \
129 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
131 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
134 #define READ_DEPTH_SPAN() \
136 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
137 r128scrn->spanOffset); \
140 r128ReadDepthSpanLocked( rmesa, n, \
143 r128WaitForIdleLocked( rmesa ); \
145 for ( i = 0 ; i < n ; i++ ) { \
150 #define READ_DEPTH_PIXELS() \
152 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
153 r128scrn->spanOffset); \
154 GLint i, remaining = n; \
156 while ( remaining > 0 ) { \
161 if ( remaining <= 128 ) { \
166 for ( i = 0 ; i < count ; i++ ) { \
167 ox[i] = x[i] + dPriv->x; \
168 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
171 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
172 r128WaitForIdleLocked( rmesa ); \
174 for ( i = 0 ; i < count ; i++ ) { \
180 remaining -= count; \
184 #define TAG(x) r128##x##_16
185 #include "depthtmp.h"
188 /* 24-bit depth, 8-bit stencil buffer functions
190 #define WRITE_DEPTH_SPAN() \
191 r128WriteDepthSpanLocked( rmesa, n, \
196 #define WRITE_DEPTH_PIXELS() \
198 GLint ox[MAX_WIDTH]; \
199 GLint oy[MAX_WIDTH]; \
200 for ( i = 0 ; i < n ; i++ ) { \
201 ox[i] = x[i] + dPriv->x; \
202 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
204 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
207 #define READ_DEPTH_SPAN() \
209 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
210 r128scrn->spanOffset); \
213 r128ReadDepthSpanLocked( rmesa, n, \
216 r128WaitForIdleLocked( rmesa ); \
218 for ( i = 0 ; i < n ; i++ ) { \
219 depth[i] = buf[i] & 0x00ffffff; \
223 #define READ_DEPTH_PIXELS() \
225 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
226 r128scrn->spanOffset); \
227 GLint i, remaining = n; \
229 while ( remaining > 0 ) { \
234 if ( remaining <= 128 ) { \
239 for ( i = 0 ; i < count ; i++ ) { \
240 ox[i] = x[i] + dPriv->x; \
241 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
244 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
245 r128WaitForIdleLocked( rmesa ); \
247 for ( i = 0 ; i < count ; i++ ) { \
248 depth[i] = buf[i] & 0x00ffffff; \
253 remaining -= count; \
257 #define TAG(x) r128##x##_24_8
258 #include "depthtmp.h"
262 /* ================================================================
266 /* FIXME: Add support for hardware stencil buffers.
270 * This function is called to specify which buffer to read and write
271 * for software rasterization (swrast) fallbacks. This doesn't necessarily
272 * correspond to glDrawBuffer() or glReadBuffer() calls.
274 static void r128DDSetBuffer( GLcontext
*ctx
,
275 GLframebuffer
*colorBuffer
,
278 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
280 switch ( bufferBit
) {
281 case BUFFER_BIT_FRONT_LEFT
:
282 if ( rmesa
->sarea
->pfCurrentPage
== 1 ) {
283 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
284 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
286 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
287 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
290 case BUFFER_BIT_BACK_LEFT
:
291 if ( rmesa
->sarea
->pfCurrentPage
== 1 ) {
292 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->frontOffset
;
293 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->frontPitch
;
295 rmesa
->drawOffset
= rmesa
->readOffset
= rmesa
->r128Screen
->backOffset
;
296 rmesa
->drawPitch
= rmesa
->readPitch
= rmesa
->r128Screen
->backPitch
;
304 void r128SpanRenderStart( GLcontext
*ctx
)
306 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
308 LOCK_HARDWARE(rmesa
);
309 r128WaitForIdleLocked( rmesa
);
312 void r128SpanRenderFinish( GLcontext
*ctx
)
314 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
315 _swrast_flush( ctx
);
316 UNLOCK_HARDWARE( rmesa
);
319 void r128DDInitSpanFuncs( GLcontext
*ctx
)
321 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
322 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
324 swdd
->SetBuffer
= r128DDSetBuffer
;
325 swdd
->SpanRenderStart
= r128SpanRenderStart
;
326 swdd
->SpanRenderFinish
= r128SpanRenderFinish
;
331 * Plug in the Get/Put routines for the given driRenderbuffer.
334 r128SetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
336 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
337 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
338 r128InitPointers_RGB565(&drb
->Base
);
341 r128InitPointers_ARGB8888(&drb
->Base
);
344 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
) {
345 drb
->Base
.GetRow
= r128ReadDepthSpan_16
;
346 drb
->Base
.GetValues
= r128ReadDepthPixels_16
;
347 drb
->Base
.PutRow
= r128WriteDepthSpan_16
;
348 drb
->Base
.PutMonoRow
= r128WriteMonoDepthSpan_16
;
349 drb
->Base
.PutValues
= r128WriteDepthPixels_16
;
350 drb
->Base
.PutMonoValues
= NULL
;
352 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
353 drb
->Base
.GetRow
= r128ReadDepthSpan_24_8
;
354 drb
->Base
.GetValues
= r128ReadDepthPixels_24_8
;
355 drb
->Base
.PutRow
= r128WriteDepthSpan_24_8
;
356 drb
->Base
.PutMonoRow
= r128WriteMonoDepthSpan_24_8
;
357 drb
->Base
.PutValues
= r128WriteDepthPixels_24_8
;
358 drb
->Base
.PutMonoValues
= NULL
;
360 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
361 drb
->Base
.GetRow
= NULL
;
362 drb
->Base
.GetValues
= NULL
;
363 drb
->Base
.PutRow
= NULL
;
364 drb
->Base
.PutMonoRow
= NULL
;
365 drb
->Base
.PutValues
= NULL
;
366 drb
->Base
.PutMonoValues
= NULL
;