remove common macros used in the span functions of most drivers from the individual...
[mesa.git] / src / mesa / drivers / dri / r128 / r128_span.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.8 2002/10/30 12:51:39 alanh Exp $ */
2 /**************************************************************************
3
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
5 Cedar Park, Texas.
6 All Rights Reserved.
7
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:
14
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
17 Software.
18
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.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 * Kevin E. Martin <martin@valinux.com>
34 *
35 */
36
37 #include "r128_context.h"
38 #include "r128_ioctl.h"
39 #include "r128_state.h"
40 #include "r128_span.h"
41 #include "r128_tex.h"
42
43 #include "swrast/swrast.h"
44
45 #define DBG 0
46
47 #define HAVE_HW_DEPTH_SPANS 1
48 #define HAVE_HW_DEPTH_PIXELS 1
49
50 #define LOCAL_VARS \
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 + \
58 rmesa->drawOffset + \
59 (dPriv->x * r128scrn->cpp) + \
60 (dPriv->y * pitch)); \
61 char *read_buf = (char *)(sPriv->pFB + \
62 rmesa->readOffset + \
63 (dPriv->x * r128scrn->cpp) + \
64 (dPriv->y * pitch)); \
65 GLuint p; \
66 (void) read_buf; (void) buf; (void) p
67
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
75
76 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
77
78 #define Y_FLIP( _y ) (height - _y - 1)
79
80 #define HW_LOCK()
81
82 #define HW_UNLOCK()
83
84
85
86 /* ================================================================
87 * Color buffer
88 */
89
90 /* 16 bit, RGB565 color spanline and pixel functions
91 */
92 #define SPANTMP_PIXEL_FMT GL_RGB
93 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
94
95 #define TAG(x) r128##x##_RGB565
96 #define TAG2(x,y) r128##x##_RGB565##y
97 #include "spantmp2.h"
98
99
100 /* 32 bit, ARGB8888 color spanline and pixel functions
101 */
102 #define SPANTMP_PIXEL_FMT GL_BGRA
103 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
104
105 #define TAG(x) r128##x##_ARGB8888
106 #define TAG2(x,y) r128##x##_ARGB8888##y
107 #include "spantmp2.h"
108
109
110 /* ================================================================
111 * Depth buffer
112 */
113
114 /* 16-bit depth buffer functions
115 */
116
117 #define WRITE_DEPTH_SPAN() \
118 r128WriteDepthSpanLocked( rmesa, n, \
119 x + dPriv->x, \
120 y + dPriv->y, \
121 depth, mask );
122
123 #define WRITE_DEPTH_PIXELS() \
124 do { \
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; \
130 } \
131 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
132 } while (0)
133
134 #define READ_DEPTH_SPAN() \
135 do { \
136 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
137 r128scrn->spanOffset); \
138 GLint i; \
139 \
140 r128ReadDepthSpanLocked( rmesa, n, \
141 x + dPriv->x, \
142 y + dPriv->y ); \
143 r128WaitForIdleLocked( rmesa ); \
144 \
145 for ( i = 0 ; i < n ; i++ ) { \
146 depth[i] = buf[i]; \
147 } \
148 } while (0)
149
150 #define READ_DEPTH_PIXELS() \
151 do { \
152 GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \
153 r128scrn->spanOffset); \
154 GLint i, remaining = n; \
155 \
156 while ( remaining > 0 ) { \
157 GLint ox[128]; \
158 GLint oy[128]; \
159 GLint count; \
160 \
161 if ( remaining <= 128 ) { \
162 count = remaining; \
163 } else { \
164 count = 128; \
165 } \
166 for ( i = 0 ; i < count ; i++ ) { \
167 ox[i] = x[i] + dPriv->x; \
168 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
169 } \
170 \
171 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
172 r128WaitForIdleLocked( rmesa ); \
173 \
174 for ( i = 0 ; i < count ; i++ ) { \
175 depth[i] = buf[i]; \
176 } \
177 depth += count; \
178 x += count; \
179 y += count; \
180 remaining -= count; \
181 } \
182 } while (0)
183
184 #define TAG(x) r128##x##_16
185 #include "depthtmp.h"
186
187
188 /* 24-bit depth, 8-bit stencil buffer functions
189 */
190 #define WRITE_DEPTH_SPAN() \
191 r128WriteDepthSpanLocked( rmesa, n, \
192 x + dPriv->x, \
193 y + dPriv->y, \
194 depth, mask );
195
196 #define WRITE_DEPTH_PIXELS() \
197 do { \
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; \
203 } \
204 r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \
205 } while (0)
206
207 #define READ_DEPTH_SPAN() \
208 do { \
209 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
210 r128scrn->spanOffset); \
211 GLint i; \
212 \
213 r128ReadDepthSpanLocked( rmesa, n, \
214 x + dPriv->x, \
215 y + dPriv->y ); \
216 r128WaitForIdleLocked( rmesa ); \
217 \
218 for ( i = 0 ; i < n ; i++ ) { \
219 depth[i] = buf[i] & 0x00ffffff; \
220 } \
221 } while (0)
222
223 #define READ_DEPTH_PIXELS() \
224 do { \
225 GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \
226 r128scrn->spanOffset); \
227 GLint i, remaining = n; \
228 \
229 while ( remaining > 0 ) { \
230 GLint ox[128]; \
231 GLint oy[128]; \
232 GLint count; \
233 \
234 if ( remaining <= 128 ) { \
235 count = remaining; \
236 } else { \
237 count = 128; \
238 } \
239 for ( i = 0 ; i < count ; i++ ) { \
240 ox[i] = x[i] + dPriv->x; \
241 oy[i] = Y_FLIP( y[i] ) + dPriv->y; \
242 } \
243 \
244 r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \
245 r128WaitForIdleLocked( rmesa ); \
246 \
247 for ( i = 0 ; i < count ; i++ ) { \
248 depth[i] = buf[i] & 0x00ffffff; \
249 } \
250 depth += count; \
251 x += count; \
252 y += count; \
253 remaining -= count; \
254 } \
255 } while (0)
256
257 #define TAG(x) r128##x##_24_8
258 #include "depthtmp.h"
259
260
261
262 /* ================================================================
263 * Stencil buffer
264 */
265
266 /* FIXME: Add support for hardware stencil buffers.
267 */
268
269 /*
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.
273 */
274 static void r128DDSetBuffer( GLcontext *ctx,
275 GLframebuffer *colorBuffer,
276 GLuint bufferBit )
277 {
278 r128ContextPtr rmesa = R128_CONTEXT(ctx);
279
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;
285 } else {
286 rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset;
287 rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch;
288 }
289 break;
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;
294 } else {
295 rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset;
296 rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch;
297 }
298 break;
299 default:
300 break;
301 }
302 }
303
304 void r128SpanRenderStart( GLcontext *ctx )
305 {
306 r128ContextPtr rmesa = R128_CONTEXT(ctx);
307 FLUSH_BATCH(rmesa);
308 LOCK_HARDWARE(rmesa);
309 r128WaitForIdleLocked( rmesa );
310 }
311
312 void r128SpanRenderFinish( GLcontext *ctx )
313 {
314 r128ContextPtr rmesa = R128_CONTEXT(ctx);
315 _swrast_flush( ctx );
316 UNLOCK_HARDWARE( rmesa );
317 }
318
319 void r128DDInitSpanFuncs( GLcontext *ctx )
320 {
321 r128ContextPtr rmesa = R128_CONTEXT(ctx);
322 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
323
324 swdd->SetBuffer = r128DDSetBuffer;
325 swdd->SpanRenderStart = r128SpanRenderStart;
326 swdd->SpanRenderFinish = r128SpanRenderFinish;
327 }
328
329
330 /**
331 * Plug in the Get/Put routines for the given driRenderbuffer.
332 */
333 void
334 r128SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
335 {
336 if (drb->Base.InternalFormat == GL_RGBA) {
337 if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
338 r128InitPointers_RGB565(&drb->Base);
339 }
340 else {
341 r128InitPointers_ARGB8888(&drb->Base);
342 }
343 }
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;
351 }
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;
359 }
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;
367 }
368 }