Major check-in of changes for GL_EXT_framebuffer_object extension.
[mesa.git] / src / mesa / drivers / dri / mach64 / mach64_span.c
1 /* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3 * Copyright 2000 Gareth Hughes
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * José Fonseca <j_r_fonseca@yahoo.co.uk>
30 */
31
32 #include "mach64_context.h"
33 #include "mach64_ioctl.h"
34 #include "mach64_state.h"
35 #include "mach64_span.h"
36 #include "mach64_tex.h"
37
38 #include "swrast/swrast.h"
39
40 #define DBG 0
41
42 #define LOCAL_VARS \
43 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); \
44 mach64ScreenRec *mach64Screen = mmesa->mach64Screen; \
45 __DRIscreenPrivate *driScreen = mmesa->driScreen; \
46 __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
47 GLuint pitch = mmesa->drawPitch * mach64Screen->cpp; \
48 GLuint height = dPriv->h; \
49 char *buf = (char *)(driScreen->pFB + \
50 mmesa->drawOffset + \
51 (dPriv->x * mach64Screen->cpp) + \
52 (dPriv->y * pitch)); \
53 char *read_buf = (char *)(driScreen->pFB + \
54 mmesa->readOffset + \
55 (dPriv->x * mach64Screen->cpp) + \
56 (dPriv->y * pitch)); \
57 GLushort p; \
58 (void) read_buf; (void) buf; (void) p
59
60 #define LOCAL_DEPTH_VARS \
61 mach64ScreenRec *mach64Screen = mmesa->mach64Screen; \
62 __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
63 __DRIscreenPrivate *driScreen = mmesa->driScreen; \
64 GLuint pitch = mach64Screen->depthPitch * 2; \
65 GLuint height = dPriv->h; \
66 char *buf = (char *)(driScreen->pFB + \
67 mach64Screen->depthOffset + \
68 dPriv->x * 2 + \
69 dPriv->y * pitch)
70
71 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
72
73 #define CLIPPIXEL( _x, _y ) \
74 ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
75
76
77 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
78 if (( _y < miny) || (_y >= maxy)) { \
79 _n1 = 0, _x1 = x; \
80 } else { \
81 _n1 = _n; \
82 _x1 = _x; \
83 if (_x1 < minx) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
84 if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \
85 }
86
87 #define Y_FLIP( _y ) (height - _y - 1)
88
89
90 #define HW_LOCK() \
91 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); \
92 LOCK_HARDWARE( mmesa ); \
93 FINISH_DMA_LOCKED( mmesa ); \
94
95 #define HW_CLIPLOOP() \
96 do { \
97 int _nc = mmesa->numClipRects; \
98 \
99 while ( _nc-- ) { \
100 int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
101 int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
102 int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
103 int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
104
105 #define HW_ENDCLIPLOOP() \
106 } \
107 } while (0)
108
109 #define HW_UNLOCK() \
110 UNLOCK_HARDWARE( mmesa ) \
111
112
113
114 /* ================================================================
115 * Color buffer
116 */
117
118 /* 16 bit, RGB565 color spanline and pixel functions
119 */
120 #undef INIT_MONO_PIXEL
121 #define INIT_MONO_PIXEL(p, color) \
122 p = MACH64PACKCOLOR565( color[0], color[1], color[2] )
123
124 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
125 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
126 (((int)g & 0xfc) << 3) | \
127 (((int)b & 0xf8) >> 3))
128
129 #define WRITE_PIXEL( _x, _y, p ) \
130 *(GLushort *)(buf + _x*2 + _y*pitch) = p
131
132 #define READ_RGBA( rgba, _x, _y ) \
133 do { \
134 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
135 rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
136 rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
137 rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
138 rgba[3] = 0xff; \
139 } while (0)
140
141 #define TAG(x) mach64##x##_RGB565
142 #include "spantmp.h"
143
144
145
146 /* 32 bit, ARGB8888 color spanline and pixel functions
147 */
148 #undef INIT_MONO_PIXEL
149 #define INIT_MONO_PIXEL(p, color) \
150 p = MACH64PACKCOLOR8888( color[0], color[1], color[2], color[3] )
151
152 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
153 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
154 (g << 8) | \
155 (r << 16) | \
156 (a << 24) )
157
158 #define WRITE_PIXEL( _x, _y, p ) \
159 *(GLuint *)(buf + _x*4 + _y*pitch) = p
160
161 #define READ_RGBA( rgba, _x, _y ) \
162 do { \
163 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
164 rgba[0] = (p >> 16) & 0xff; \
165 rgba[1] = (p >> 8) & 0xff; \
166 rgba[2] = (p >> 0) & 0xff; \
167 rgba[3] = 0xff; /*(p >> 24) & 0xff;*/ \
168 } while (0)
169
170 #define TAG(x) mach64##x##_ARGB8888
171 #include "spantmp.h"
172
173
174
175 /* ================================================================
176 * Depth buffer
177 */
178
179 /* 16 bit depthbuffer functions.
180 */
181 #define WRITE_DEPTH( _x, _y, d ) \
182 *(GLushort *)(buf + _x*2 + _y*pitch) = d;
183
184 #define READ_DEPTH( d, _x, _y ) \
185 d = *(GLushort *)(buf + _x*2 + _y*pitch);
186
187 #define TAG(x) mach64##x##_16
188 #include "depthtmp.h"
189
190
191 /*
192 * This function is called to specify which buffer to read and write
193 * for software rasterization (swrast) fallbacks. This doesn't necessarily
194 * correspond to glDrawBuffer() or glReadBuffer() calls.
195 */
196 static void mach64DDSetBuffer( GLcontext *ctx,
197 GLframebuffer *colorBuffer,
198 GLuint bufferBit )
199 {
200 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
201
202 switch ( bufferBit ) {
203 case BUFFER_BIT_FRONT_LEFT:
204 if (MACH64_DEBUG & DEBUG_VERBOSE_MSG)
205 fprintf(stderr,"%s: BUFFER_BIT_FRONT_LEFT\n", __FUNCTION__);
206 mmesa->drawOffset = mmesa->readOffset = mmesa->mach64Screen->frontOffset;
207 mmesa->drawPitch = mmesa->readPitch = mmesa->mach64Screen->frontPitch;
208 break;
209 case BUFFER_BIT_BACK_LEFT:
210 if (MACH64_DEBUG & DEBUG_VERBOSE_MSG)
211 fprintf(stderr,"%s: BUFFER_BIT_BACK_LEFT\n", __FUNCTION__);
212 mmesa->drawOffset = mmesa->readOffset = mmesa->mach64Screen->backOffset;
213 mmesa->drawPitch = mmesa->readPitch = mmesa->mach64Screen->backPitch;
214 break;
215 default:
216 break;
217 }
218 }
219
220
221 void mach64DDInitSpanFuncs( GLcontext *ctx )
222 {
223 #if 0
224 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
225 #endif
226 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
227
228 swdd->SetBuffer = mach64DDSetBuffer;
229
230 #if 0
231 switch ( mmesa->mach64Screen->cpp ) {
232 case 2:
233 swdd->WriteRGBASpan = mach64WriteRGBASpan_RGB565;
234 swdd->WriteRGBSpan = mach64WriteRGBSpan_RGB565;
235 swdd->WriteMonoRGBASpan = mach64WriteMonoRGBASpan_RGB565;
236 swdd->WriteRGBAPixels = mach64WriteRGBAPixels_RGB565;
237 swdd->WriteMonoRGBAPixels = mach64WriteMonoRGBAPixels_RGB565;
238 swdd->ReadRGBASpan = mach64ReadRGBASpan_RGB565;
239 swdd->ReadRGBAPixels = mach64ReadRGBAPixels_RGB565;
240 break;
241
242 case 4:
243 swdd->WriteRGBASpan = mach64WriteRGBASpan_ARGB8888;
244 swdd->WriteRGBSpan = mach64WriteRGBSpan_ARGB8888;
245 swdd->WriteMonoRGBASpan = mach64WriteMonoRGBASpan_ARGB8888;
246 swdd->WriteRGBAPixels = mach64WriteRGBAPixels_ARGB8888;
247 swdd->WriteMonoRGBAPixels = mach64WriteMonoRGBAPixels_ARGB8888;
248 swdd->ReadRGBASpan = mach64ReadRGBASpan_ARGB8888;
249 swdd->ReadRGBAPixels = mach64ReadRGBAPixels_ARGB8888;
250
251 break;
252
253 default:
254 break;
255 }
256 #endif
257
258 /* Depth buffer is always 16 bit */
259 #if 0
260 swdd->ReadDepthSpan = mach64ReadDepthSpan_16;
261 swdd->WriteDepthSpan = mach64WriteDepthSpan_16;
262 swdd->ReadDepthPixels = mach64ReadDepthPixels_16;
263 swdd->WriteDepthPixels = mach64WriteDepthPixels_16;
264 #endif
265 /* No hardware stencil buffer */
266 swdd->ReadStencilSpan = NULL;
267 swdd->WriteStencilSpan = NULL;
268 swdd->ReadStencilPixels = NULL;
269 swdd->WriteStencilPixels = NULL;
270
271 swdd->WriteCI8Span = NULL;
272 swdd->WriteCI32Span = NULL;
273 swdd->WriteMonoCISpan = NULL;
274 swdd->WriteCI32Pixels = NULL;
275 swdd->WriteMonoCIPixels = NULL;
276 swdd->ReadCI32Span = NULL;
277 swdd->ReadCI32Pixels = NULL;
278 }
279
280
281 /**
282 * Plug in the Get/Put routines for the given driRenderbuffer.
283 */
284 void
285 mach64SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
286 {
287 if (drb->Base.InternalFormat == GL_RGBA) {
288 if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
289 drb->Base.GetRow = mach64ReadRGBASpan_RGB565;
290 drb->Base.GetValues = mach64ReadRGBAPixels_RGB565;
291 drb->Base.PutRow = mach64WriteRGBASpan_RGB565;
292 drb->Base.PutRowRGB = mach64WriteRGBSpan_RGB565;
293 drb->Base.PutMonoRow = mach64WriteMonoRGBASpan_RGB565;
294 drb->Base.PutValues = mach64WriteRGBAPixels_RGB565;
295 drb->Base.PutMonoValues = mach64WriteMonoRGBAPixels_RGB565;
296 }
297 else {
298 drb->Base.GetRow = mach64ReadRGBASpan_ARGB8888;
299 drb->Base.GetValues = mach64ReadRGBAPixels_ARGB8888;
300 drb->Base.PutRow = mach64WriteRGBASpan_ARGB8888;
301 drb->Base.PutRowRGB = mach64WriteRGBSpan_ARGB8888;
302 drb->Base.PutMonoRow = mach64WriteMonoRGBASpan_ARGB8888;
303 drb->Base.PutValues = mach64WriteRGBAPixels_ARGB8888;
304 drb->Base.PutMonoValues = mach64WriteMonoRGBAPixels_ARGB8888;
305 }
306 }
307 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
308 drb->Base.GetRow = mach64ReadDepthSpan_16;
309 drb->Base.GetValues = mach64ReadDepthPixels_16;
310 drb->Base.PutRow = mach64WriteDepthSpan_16;
311 drb->Base.PutMonoRow = mach64WriteMonoDepthSpan_16;
312 drb->Base.PutValues = mach64WriteDepthPixels_16;
313 drb->Base.PutMonoValues = NULL;
314 }
315 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
316 /* never */
317 drb->Base.GetRow = NULL;
318 drb->Base.GetValues = NULL;
319 drb->Base.PutRow = NULL;
320 drb->Base.PutMonoRow = NULL;
321 drb->Base.PutValues = NULL;
322 drb->Base.PutMonoValues = NULL;
323 }
324 else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
325 /* never */
326 drb->Base.GetRow = NULL;
327 drb->Base.GetValues = NULL;
328 drb->Base.PutRow = NULL;
329 drb->Base.PutMonoRow = NULL;
330 drb->Base.PutValues = NULL;
331 drb->Base.PutMonoValues = NULL;
332 }
333 }