2 * Copyright 2000-2001 VA Linux Systems, Inc.
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:
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
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.
25 * Keith Whitwell <keith@tungstengraphics.com>
27 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.11 2002/10/30 12:51:36 alanh Exp $ */
31 #include "mgacontext.h"
34 #include "swrast/swrast.h"
39 mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
40 __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \
41 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
42 __DRIscreenPrivate *sPriv = mmesa->driScreen; \
43 GLuint pitch = mgaScreen->frontPitch; \
44 GLuint height = dPriv->h; \
45 char *read_buf = (char *)(sPriv->pFB + \
47 dPriv->x * mgaScreen->cpp + \
49 char *buf = (char *)(sPriv->pFB + \
51 dPriv->x * mgaScreen->cpp + \
54 (void) read_buf; (void) buf; (void) p
58 #define LOCAL_DEPTH_VARS \
59 mgaContextPtr mmesa = MGA_CONTEXT(ctx); \
60 __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \
61 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \
62 __DRIscreenPrivate *sPriv = mmesa->driScreen; \
63 GLuint pitch = mgaScreen->frontPitch; \
64 GLuint height = dPriv->h; \
65 char *buf = (char *)(sPriv->pFB + \
66 mgaScreen->depthOffset + \
67 dPriv->x * mgaScreen->cpp + \
70 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
74 /* FIXME could/should we use dPriv->numClipRects like the other drivers? */
75 #define HW_CLIPLOOP() \
77 int _nc = mmesa->numClipRects; \
79 int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
80 int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
81 int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
82 int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
84 #define HW_ENDCLIPLOOP() \
92 #define Y_FLIP(_y) (height - _y - 1)
94 /* 16 bit, RGB565 color spanline and pixel functions
96 #define SPANTMP_PIXEL_FMT GL_RGB
97 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
99 #define TAG(x) mga##x##_565
100 #define TAG2(x,y) mga##x##_565##y
101 #include "spantmp2.h"
103 /* 32 bit, ARGB8888 color spanline and pixel functions
105 #define SPANTMP_PIXEL_FMT GL_BGRA
106 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
108 #define TAG(x) mga##x##_8888
109 #define TAG2(x,y) mga##x##_8888##y
110 #include "spantmp2.h"
113 /* 16 bit depthbuffer functions.
115 #define WRITE_DEPTH( _x, _y, d ) \
116 *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
118 #define READ_DEPTH( d, _x, _y ) \
119 d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
121 #define TAG(x) mga##x##_16
122 #include "depthtmp.h"
127 /* 32 bit depthbuffer functions.
129 #define WRITE_DEPTH( _x, _y, d ) \
130 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = d;
132 #define READ_DEPTH( d, _x, _y ) \
133 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch);
135 #define TAG(x) mga##x##_32
136 #include "depthtmp.h"
140 /* 24/8 bit interleaved depth/stencil functions
142 #define WRITE_DEPTH( _x, _y, d ) { \
143 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
146 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
149 #define READ_DEPTH( d, _x, _y ) { \
150 d = (*(GLuint *)(buf + (_x)*4 + (_y)*pitch) & ~0xff) >> 8; \
153 #define TAG(x) mga##x##_24_8
154 #include "depthtmp.h"
156 #define WRITE_STENCIL( _x, _y, d ) { \
157 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
160 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
163 #define READ_STENCIL( d, _x, _y ) \
164 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
166 #define TAG(x) mga##x##_24_8
167 #include "stenciltmp.h"
172 * This function is called to specify which buffer to read and write
173 * for software rasterization (swrast) fallbacks. This doesn't necessarily
174 * correspond to glDrawBuffer() or glReadBuffer() calls.
176 static void mgaDDSetBuffer(GLcontext
*ctx
, GLframebuffer
*buffer
,
179 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
182 assert((bufferBit
== BUFFER_BIT_FRONT_LEFT
) || (bufferBit
== BUFFER_BIT_BACK_LEFT
));
184 offset
= (bufferBit
== BUFFER_BIT_FRONT_LEFT
)
185 ? mmesa
->mgaScreen
->frontOffset
186 : mmesa
->mgaScreen
->backOffset
;
188 mmesa
->drawOffset
= offset
;
189 mmesa
->readOffset
= offset
;
191 assert( (buffer
== mmesa
->driDrawable
->driverPrivate
)
192 || (buffer
== mmesa
->driReadable
->driverPrivate
) );
194 mmesa
->mesa_drawable
= (buffer
== mmesa
->driDrawable
->driverPrivate
)
195 ? mmesa
->driDrawable
: mmesa
->driReadable
;
198 void mgaSpanRenderStart( GLcontext
*ctx
)
200 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
201 FLUSH_BATCH( mmesa
);
202 LOCK_HARDWARE_QUIESCENT( mmesa
);
205 void mgaSpanRenderFinish( GLcontext
*ctx
)
207 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
208 _swrast_flush( ctx
);
209 UNLOCK_HARDWARE( mmesa
);
213 * Initialize the driver callbacks for the read / write span functions.
216 * To really support RGB888 and RGBA8888 visuals, we need separate read and
217 * write routines for 888 and 8888. We also need to determine whether or not
218 * the visual has destination alpha.
220 void mgaDDInitSpanFuncs( GLcontext
*ctx
)
222 mgaContextPtr mmesa
= MGA_CONTEXT(ctx
);
223 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
225 swdd
->SetBuffer
= mgaDDSetBuffer
;
227 switch (mmesa
->mgaScreen
->cpp
) {
230 mgaInitPointers_565( swdd
);
231 swdd
->ReadDepthSpan
= mgaReadDepthSpan_16
;
232 swdd
->WriteDepthSpan
= mgaWriteDepthSpan_16
;
233 swdd
->ReadDepthPixels
= mgaReadDepthPixels_16
;
234 swdd
->WriteDepthPixels
= mgaWriteDepthPixels_16
;
240 mgaInitPointers_8888( swdd
);
242 if (!mmesa
->hw_stencil
) {
243 swdd
->ReadDepthSpan
= mgaReadDepthSpan_32
;
244 swdd
->WriteDepthSpan
= mgaWriteDepthSpan_32
;
245 swdd
->ReadDepthPixels
= mgaReadDepthPixels_32
;
246 swdd
->WriteDepthPixels
= mgaWriteDepthPixels_32
;
248 swdd
->ReadDepthSpan
= mgaReadDepthSpan_24_8
;
249 swdd
->WriteDepthSpan
= mgaWriteDepthSpan_24_8
;
250 swdd
->ReadDepthPixels
= mgaReadDepthPixels_24_8
;
251 swdd
->WriteDepthPixels
= mgaWriteDepthPixels_24_8
;
253 swdd
->ReadStencilSpan
= mgaReadStencilSpan_24_8
;
254 swdd
->WriteStencilSpan
= mgaWriteStencilSpan_24_8
;
255 swdd
->ReadStencilPixels
= mgaReadStencilPixels_24_8
;
256 swdd
->WriteStencilPixels
= mgaWriteStencilPixels_24_8
;
261 swdd
->SpanRenderStart
= mgaSpanRenderStart
;
262 swdd
->SpanRenderFinish
= mgaSpanRenderFinish
;
267 * Plug in the Get/Put routines for the given driRenderbuffer.
270 mgaSetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
272 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
273 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
274 mgaInitPointers_565(&drb
->Base
);
277 mgaInitPointers_8888(&drb
->Base
);
280 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
) {
281 drb
->Base
.GetRow
= mgaReadDepthSpan_16
;
282 drb
->Base
.GetValues
= mgaReadDepthPixels_16
;
283 drb
->Base
.PutRow
= mgaWriteDepthSpan_16
;
284 drb
->Base
.PutMonoRow
= mgaWriteMonoDepthSpan_16
;
285 drb
->Base
.PutValues
= mgaWriteDepthPixels_16
;
286 drb
->Base
.PutMonoValues
= NULL
;
288 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
289 drb
->Base
.GetRow
= mgaReadDepthSpan_24_8
;
290 drb
->Base
.GetValues
= mgaReadDepthPixels_24_8
;
291 drb
->Base
.PutRow
= mgaWriteDepthSpan_24_8
;
292 drb
->Base
.PutMonoRow
= mgaWriteMonoDepthSpan_24_8
;
293 drb
->Base
.PutValues
= mgaWriteDepthPixels_24_8
;
294 drb
->Base
.PutMonoValues
= NULL
;
296 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT32
) {
297 drb
->Base
.GetRow
= mgaReadDepthSpan_32
;
298 drb
->Base
.GetValues
= mgaReadDepthPixels_32
;
299 drb
->Base
.PutRow
= mgaWriteDepthSpan_32
;
300 drb
->Base
.PutMonoRow
= mgaWriteMonoDepthSpan_32
;
301 drb
->Base
.PutValues
= mgaWriteDepthPixels_32
;
302 drb
->Base
.PutMonoValues
= NULL
;
304 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
305 drb
->Base
.GetRow
= mgaReadStencilSpan_24_8
;
306 drb
->Base
.GetValues
= mgaReadStencilPixels_24_8
;
307 drb
->Base
.PutRow
= mgaWriteStencilSpan_24_8
;
308 drb
->Base
.PutMonoRow
= mgaWriteMonoStencilSpan_24_8
;
309 drb
->Base
.PutValues
= mgaWriteStencilPixels_24_8
;
310 drb
->Base
.PutMonoValues
= NULL
;