Major check-in of changes for GL_EXT_framebuffer_object extension.
[mesa.git] / src / mesa / drivers / dri / mga / mgaspan.c
1 /*
2 * Copyright 2000-2001 VA Linux Systems, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keith@tungstengraphics.com>
26 */
27 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.11 2002/10/30 12:51:36 alanh Exp $ */
28
29 #include "mtypes.h"
30 #include "mgadd.h"
31 #include "mgacontext.h"
32 #include "mgaspan.h"
33 #include "mgaioctl.h"
34 #include "swrast/swrast.h"
35
36 #define DBG 0
37
38 #define LOCAL_VARS \
39 __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \
40 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
41 __DRIscreenPrivate *sPriv = mmesa->driScreen; \
42 GLuint pitch = mgaScreen->frontPitch; \
43 GLuint height = dPriv->h; \
44 char *read_buf = (char *)(sPriv->pFB + \
45 mmesa->readOffset + \
46 dPriv->x * mgaScreen->cpp + \
47 dPriv->y * pitch); \
48 char *buf = (char *)(sPriv->pFB + \
49 mmesa->drawOffset + \
50 dPriv->x * mgaScreen->cpp + \
51 dPriv->y * pitch); \
52 GLuint p; \
53 (void) read_buf; (void) buf; (void) p
54
55
56
57 #define LOCAL_DEPTH_VARS \
58 __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \
59 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
60 __DRIscreenPrivate *sPriv = mmesa->driScreen; \
61 GLuint pitch = mgaScreen->frontPitch; \
62 GLuint height = dPriv->h; \
63 char *buf = (char *)(sPriv->pFB + \
64 mgaScreen->depthOffset + \
65 dPriv->x * mgaScreen->cpp + \
66 dPriv->y * pitch)
67
68 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
69
70 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
71 _y >= miny && _y < maxy)
72
73 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
74 if ( _y < miny || _y >= maxy ) { \
75 _n1 = 0, _x1 = x; \
76 } else { \
77 _n1 = _n; \
78 _x1 = _x; \
79 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
80 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
81 }
82
83
84 #define HW_LOCK() \
85 mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
86 FLUSH_BATCH(mmesa); \
87 LOCK_HARDWARE_QUIESCENT(mmesa);
88
89
90 #define HW_CLIPLOOP() \
91 do { \
92 int _nc = mmesa->numClipRects; \
93 while (_nc--) { \
94 int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
95 int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
96 int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
97 int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
98
99 #define HW_ENDCLIPLOOP() \
100 } \
101 } while (0)
102
103 #define HW_UNLOCK() \
104 UNLOCK_HARDWARE(mmesa);
105
106
107
108
109
110
111 #define Y_FLIP(_y) (height - _y - 1)
112
113 /* 16 bit, RGB565 color spanline and pixel functions
114 */
115
116 #define GET_SRC_PTR(_x, _y) (read_buf + _x * 2 + _y * pitch)
117 #define GET_DST_PTR(_x, _y) ( buf + _x * 2 + _y * pitch)
118 #define SPANTMP_PIXEL_FMT GL_RGB
119 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
120
121 #define TAG(x) mga##x##_565
122 #define TAG2(x,y) mga##x##_565##y
123 #include "spantmp2.h"
124
125 /* 32 bit, ARGB8888 color spanline and pixel functions
126 */
127
128 #define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * pitch)
129 #define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * pitch)
130 #define SPANTMP_PIXEL_FMT GL_BGRA
131 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
132
133 #define TAG(x) mga##x##_8888
134 #define TAG2(x,y) mga##x##_8888##y
135 #include "spantmp2.h"
136
137
138 /* 16 bit depthbuffer functions.
139 */
140 #define WRITE_DEPTH( _x, _y, d ) \
141 *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
142
143 #define READ_DEPTH( d, _x, _y ) \
144 d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
145
146 #define TAG(x) mga##x##_16
147 #include "depthtmp.h"
148
149
150
151
152 /* 32 bit depthbuffer functions.
153 */
154 #define WRITE_DEPTH( _x, _y, d ) \
155 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = d;
156
157 #define READ_DEPTH( d, _x, _y ) \
158 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch);
159
160 #define TAG(x) mga##x##_32
161 #include "depthtmp.h"
162
163
164
165 /* 24/8 bit interleaved depth/stencil functions
166 */
167 #define WRITE_DEPTH( _x, _y, d ) { \
168 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
169 tmp &= 0xff; \
170 tmp |= (d) << 8; \
171 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
172 }
173
174 #define READ_DEPTH( d, _x, _y ) { \
175 d = (*(GLuint *)(buf + (_x)*4 + (_y)*pitch) & ~0xff) >> 8; \
176 }
177
178 #define TAG(x) mga##x##_24_8
179 #include "depthtmp.h"
180
181 #define WRITE_STENCIL( _x, _y, d ) { \
182 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
183 tmp &= 0xffffff00; \
184 tmp |= d & 0xff; \
185 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
186 }
187
188 #define READ_STENCIL( d, _x, _y ) \
189 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
190
191 #define TAG(x) mga##x##_24_8
192 #include "stenciltmp.h"
193
194
195
196 /*
197 * This function is called to specify which buffer to read and write
198 * for software rasterization (swrast) fallbacks. This doesn't necessarily
199 * correspond to glDrawBuffer() or glReadBuffer() calls.
200 */
201 static void mgaDDSetBuffer(GLcontext *ctx, GLframebuffer *buffer,
202 GLuint bufferBit)
203 {
204 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
205 unsigned int offset;
206
207 assert((bufferBit == BUFFER_BIT_FRONT_LEFT) || (bufferBit == BUFFER_BIT_BACK_LEFT));
208
209 offset = (bufferBit == BUFFER_BIT_FRONT_LEFT)
210 ? mmesa->mgaScreen->frontOffset
211 : mmesa->mgaScreen->backOffset;
212
213 mmesa->drawOffset = offset;
214 mmesa->readOffset = offset;
215
216 assert( (buffer == mmesa->driDrawable->driverPrivate)
217 || (buffer == mmesa->driReadable->driverPrivate) );
218
219 mmesa->mesa_drawable = (buffer == mmesa->driDrawable->driverPrivate)
220 ? mmesa->driDrawable : mmesa->driReadable;
221 }
222
223 /**
224 * Initialize the driver callbacks for the read / write span functions.
225 *
226 * \bug
227 * To really support RGB888 and RGBA8888 visuals, we need separate read and
228 * write routines for 888 and 8888. We also need to determine whether or not
229 * the visual has destination alpha.
230 */
231 void mgaDDInitSpanFuncs( GLcontext *ctx )
232 {
233 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
234 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
235
236 swdd->SetBuffer = mgaDDSetBuffer;
237
238 switch (mmesa->mgaScreen->cpp) {
239 case 2:
240 #if 0
241 mgaInitPointers_565( swdd );
242 swdd->ReadDepthSpan = mgaReadDepthSpan_16;
243 swdd->WriteDepthSpan = mgaWriteDepthSpan_16;
244 swdd->ReadDepthPixels = mgaReadDepthPixels_16;
245 swdd->WriteDepthPixels = mgaWriteDepthPixels_16;
246 #endif
247 break;
248
249 case 4:
250 #if 0
251 mgaInitPointers_8888( swdd );
252
253 if (!mmesa->hw_stencil) {
254 swdd->ReadDepthSpan = mgaReadDepthSpan_32;
255 swdd->WriteDepthSpan = mgaWriteDepthSpan_32;
256 swdd->ReadDepthPixels = mgaReadDepthPixels_32;
257 swdd->WriteDepthPixels = mgaWriteDepthPixels_32;
258 } else {
259 swdd->ReadDepthSpan = mgaReadDepthSpan_24_8;
260 swdd->WriteDepthSpan = mgaWriteDepthSpan_24_8;
261 swdd->ReadDepthPixels = mgaReadDepthPixels_24_8;
262 swdd->WriteDepthPixels = mgaWriteDepthPixels_24_8;
263
264 swdd->ReadStencilSpan = mgaReadStencilSpan_24_8;
265 swdd->WriteStencilSpan = mgaWriteStencilSpan_24_8;
266 swdd->ReadStencilPixels = mgaReadStencilPixels_24_8;
267 swdd->WriteStencilPixels = mgaWriteStencilPixels_24_8;
268 }
269 #endif
270 break;
271 }
272 }
273
274
275
276 /**
277 * Plug in the Get/Put routines for the given driRenderbuffer.
278 */
279 void
280 mgaSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
281 {
282 if (drb->Base.InternalFormat == GL_RGBA) {
283 if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
284 mgaInitPointers_565(&drb->Base);
285 }
286 else {
287 mgaInitPointers_8888(&drb->Base);
288 }
289 }
290 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
291 drb->Base.GetRow = mgaReadDepthSpan_16;
292 drb->Base.GetValues = mgaReadDepthPixels_16;
293 drb->Base.PutRow = mgaWriteDepthSpan_16;
294 drb->Base.PutMonoRow = mgaWriteMonoDepthSpan_16;
295 drb->Base.PutValues = mgaWriteDepthPixels_16;
296 drb->Base.PutMonoValues = NULL;
297 }
298 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
299 drb->Base.GetRow = mgaReadDepthSpan_24_8;
300 drb->Base.GetValues = mgaReadDepthPixels_24_8;
301 drb->Base.PutRow = mgaWriteDepthSpan_24_8;
302 drb->Base.PutMonoRow = mgaWriteMonoDepthSpan_24_8;
303 drb->Base.PutValues = mgaWriteDepthPixels_24_8;
304 drb->Base.PutMonoValues = NULL;
305 }
306 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT32) {
307 drb->Base.GetRow = mgaReadDepthSpan_32;
308 drb->Base.GetValues = mgaReadDepthPixels_32;
309 drb->Base.PutRow = mgaWriteDepthSpan_32;
310 drb->Base.PutMonoRow = mgaWriteMonoDepthSpan_32;
311 drb->Base.PutValues = mgaWriteDepthPixels_32;
312 drb->Base.PutMonoValues = NULL;
313 }
314 else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
315 drb->Base.GetRow = mgaReadStencilSpan_24_8;
316 drb->Base.GetValues = mgaReadStencilPixels_24_8;
317 drb->Base.PutRow = mgaWriteStencilSpan_24_8;
318 drb->Base.PutMonoRow = mgaWriteMonoStencilSpan_24_8;
319 drb->Base.PutValues = mgaWriteStencilPixels_24_8;
320 drb->Base.PutMonoValues = NULL;
321 }
322 }