1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
33 #include "intel_screen.h"
35 #include "intel_span.h"
36 #include "intel_ioctl.h"
37 #include "swrast/swrast.h"
43 intelContextPtr intel = INTEL_CONTEXT(ctx); \
44 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
45 intelScreenPrivate *intelScreen = intel->intelScreen; \
46 GLuint pitch = intelScreen->backPitch * intelScreen->cpp; \
47 GLuint height = dPriv->h; \
48 char *buf = (char *)(intel->drawMap + \
49 dPriv->x * intelScreen->cpp + \
51 char *read_buf = (char *)(intel->readMap + \
52 dPriv->x * intelScreen->cpp + \
55 (void) read_buf; (void) buf; (void) p
57 #define LOCAL_DEPTH_VARS \
58 intelContextPtr intel = INTEL_CONTEXT(ctx); \
59 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
60 intelScreenPrivate *intelScreen = intel->intelScreen; \
61 GLuint pitch = intelScreen->backPitch * intelScreen->cpp; \
62 GLuint height = dPriv->h; \
63 char *buf = (char *)(intelScreen->depth.map + \
64 dPriv->x * intelScreen->cpp + \
67 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
69 #define INIT_MONO_PIXEL(p,color)\
70 p = INTEL_PACKCOLOR565(color[0],color[1],color[2])
72 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
73 _y >= miny && _y < maxy)
75 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
76 if ( _y < miny || _y >= maxy ) { \
81 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
82 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
85 #define Y_FLIP(_y) (height - _y - 1)
90 #define HW_CLIPLOOP() \
92 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
93 int _nc = dPriv->numClipRects; \
95 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
96 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
97 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
98 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
101 #define HW_ENDCLIPLOOP() \
107 /* 16 bit, 565 rgb color spanline and pixel functions
109 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
110 *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
111 (((int)g & 0xfc) << 3) | \
112 (((int)b & 0xf8) >> 3))
113 #define WRITE_PIXEL( _x, _y, p ) \
114 *(GLushort *)(buf + _x*2 + _y*pitch) = p
116 #define READ_RGBA( rgba, _x, _y ) \
118 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
119 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
120 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
121 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
125 #define TAG(x) intel##x##_565
131 /* 15 bit, 555 rgb color spanline and pixel functions
133 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
134 *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
135 ((g & 0xf8) << 3) | \
138 #define WRITE_PIXEL( _x, _y, p ) \
139 *(GLushort *)(buf + _x*2 + _y*pitch) = p
141 #define READ_RGBA( rgba, _x, _y ) \
143 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
144 rgba[0] = (p >> 7) & 0xf8; \
145 rgba[1] = (p >> 3) & 0xf8; \
146 rgba[2] = (p << 3) & 0xf8; \
150 #define TAG(x) intel##x##_555
153 /* 16 bit depthbuffer functions.
155 #define WRITE_DEPTH( _x, _y, d ) \
156 *(GLushort *)(buf + _x*2 + _y*pitch) = d;
158 #define READ_DEPTH( d, _x, _y ) \
159 d = *(GLushort *)(buf + _x*2 + _y*pitch);
162 #define TAG(x) intel##x##_16
163 #include "depthtmp.h"
168 intelContextPtr intel = INTEL_CONTEXT(ctx); \
169 __DRIdrawablePrivate *dPriv = intel->driDrawable; \
170 intelScreenPrivate *intelScreen = intel->intelScreen; \
171 GLuint pitch = intelScreen->backPitch * intelScreen->cpp; \
172 GLuint height = dPriv->h; \
173 char *buf = (char *)(intel->drawMap + \
174 dPriv->x * intelScreen->cpp + \
176 char *read_buf = (char *)(intel->readMap + \
177 dPriv->x * intelScreen->cpp + \
180 (void) read_buf; (void) buf; (void) p
182 #undef INIT_MONO_PIXEL
183 #define INIT_MONO_PIXEL(p,color)\
184 p = INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3])
186 /* 32 bit, 8888 argb color spanline and pixel functions
188 #define WRITE_RGBA(_x, _y, r, g, b, a) \
189 *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
194 #define WRITE_PIXEL(_x, _y, p) \
195 *(GLuint *)(buf + _x*4 + _y*pitch) = p
198 #define READ_RGBA(rgba, _x, _y) \
200 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
201 rgba[0] = (p >> 16) & 0xff; \
202 rgba[1] = (p >> 8) & 0xff; \
203 rgba[2] = (p >> 0) & 0xff; \
204 rgba[3] = (p >> 24) & 0xff; \
207 #define TAG(x) intel##x##_8888
211 /* 24/8 bit interleaved depth/stencil functions
213 #define WRITE_DEPTH( _x, _y, d ) { \
214 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
216 tmp |= (d) & 0xffffff; \
217 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
220 #define READ_DEPTH( d, _x, _y ) \
221 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff;
224 #define TAG(x) intel##x##_24_8
225 #include "depthtmp.h"
227 #define WRITE_STENCIL( _x, _y, d ) { \
228 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
231 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
234 #define READ_STENCIL( d, _x, _y ) \
235 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24;
237 #define TAG(x) intel##x##_24_8
238 #include "stenciltmp.h"
242 * This function is called to specify which buffer to read and write
243 * for software rasterization (swrast) fallbacks. This doesn't necessarily
244 * correspond to glDrawBuffer() or glReadBuffer() calls.
246 static void intelSetBuffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
249 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
250 if (bufferBit
== DD_FRONT_LEFT_BIT
) {
251 intel
->drawMap
= (char *)intel
->driScreen
->pFB
;
252 intel
->readMap
= (char *)intel
->driScreen
->pFB
;
253 } else if (bufferBit
== DD_BACK_LEFT_BIT
) {
254 intel
->drawMap
= intel
->intelScreen
->back
.map
;
255 intel
->readMap
= intel
->intelScreen
->back
.map
;
262 /* Move locking out to get reasonable span performance.
264 void intelSpanRenderStart( GLcontext
*ctx
)
266 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
268 intelFlush(&intel
->ctx
);
269 LOCK_HARDWARE(intel
);
270 intelWaitForIdle(intel
);
273 void intelSpanRenderFinish( GLcontext
*ctx
)
275 intelContextPtr intel
= INTEL_CONTEXT( ctx
);
276 _swrast_flush( ctx
);
277 UNLOCK_HARDWARE( intel
);
280 void intelInitSpanFuncs( GLcontext
*ctx
)
282 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
283 intelScreenPrivate
*intelScreen
= intel
->intelScreen
;
285 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
287 swdd
->SetBuffer
= intelSetBuffer
;
289 switch (intelScreen
->fbFormat
) {
291 swdd
->WriteRGBASpan
= intelWriteRGBASpan_555
;
292 swdd
->WriteRGBSpan
= intelWriteRGBSpan_555
;
293 swdd
->WriteMonoRGBASpan
= intelWriteMonoRGBASpan_555
;
294 swdd
->WriteRGBAPixels
= intelWriteRGBAPixels_555
;
295 swdd
->WriteMonoRGBAPixels
= intelWriteMonoRGBAPixels_555
;
296 swdd
->ReadRGBASpan
= intelReadRGBASpan_555
;
297 swdd
->ReadRGBAPixels
= intelReadRGBAPixels_555
;
299 swdd
->ReadDepthSpan
= intelReadDepthSpan_16
;
300 swdd
->WriteDepthSpan
= intelWriteDepthSpan_16
;
301 swdd
->ReadDepthPixels
= intelReadDepthPixels_16
;
302 swdd
->WriteDepthPixels
= intelWriteDepthPixels_16
;
306 swdd
->WriteRGBASpan
= intelWriteRGBASpan_565
;
307 swdd
->WriteRGBSpan
= intelWriteRGBSpan_565
;
308 swdd
->WriteMonoRGBASpan
= intelWriteMonoRGBASpan_565
;
309 swdd
->WriteRGBAPixels
= intelWriteRGBAPixels_565
;
310 swdd
->WriteMonoRGBAPixels
= intelWriteMonoRGBAPixels_565
;
311 swdd
->ReadRGBASpan
= intelReadRGBASpan_565
;
312 swdd
->ReadRGBAPixels
= intelReadRGBAPixels_565
;
314 swdd
->ReadDepthSpan
= intelReadDepthSpan_16
;
315 swdd
->WriteDepthSpan
= intelWriteDepthSpan_16
;
316 swdd
->ReadDepthPixels
= intelReadDepthPixels_16
;
317 swdd
->WriteDepthPixels
= intelWriteDepthPixels_16
;
321 swdd
->WriteRGBASpan
= intelWriteRGBASpan_8888
;
322 swdd
->WriteRGBSpan
= intelWriteRGBSpan_8888
;
323 swdd
->WriteMonoRGBASpan
= intelWriteMonoRGBASpan_8888
;
324 swdd
->WriteRGBAPixels
= intelWriteRGBAPixels_8888
;
325 swdd
->WriteMonoRGBAPixels
= intelWriteMonoRGBAPixels_8888
;
326 swdd
->ReadRGBASpan
= intelReadRGBASpan_8888
;
327 swdd
->ReadRGBAPixels
= intelReadRGBAPixels_8888
;
329 swdd
->ReadDepthSpan
= intelReadDepthSpan_24_8
;
330 swdd
->WriteDepthSpan
= intelWriteDepthSpan_24_8
;
331 swdd
->ReadDepthPixels
= intelReadDepthPixels_24_8
;
332 swdd
->WriteDepthPixels
= intelWriteDepthPixels_24_8
;
334 swdd
->WriteStencilSpan
= intelWriteStencilSpan_24_8
;
335 swdd
->ReadStencilSpan
= intelReadStencilSpan_24_8
;
336 swdd
->WriteStencilPixels
= intelWriteStencilPixels_24_8
;
337 swdd
->ReadStencilPixels
= intelReadStencilPixels_24_8
;
341 swdd
->SpanRenderStart
= intelSpanRenderStart
;
342 swdd
->SpanRenderFinish
= intelSpanRenderFinish
;