2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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 * VIA, S3 GRAPHICS, 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 OTHER
22 * DEALINGS IN THE SOFTWARE.
29 #include "via_context.h"
31 #include "via_ioctl.h"
32 #include "swrast/swrast.h"
36 #define LOCAL_DEPTH_VARS \
37 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
38 viaScreenPrivate *viaScreen = vmesa->viaScreen; \
39 GLuint depth_pitch = vmesa->depth.pitch; \
40 GLuint height = dPriv->h; \
41 char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8))
43 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
44 _y >= miny && _y < maxy)
47 #define CLIPSPAN(_x, _y, _n, _x1, _n1, _i) \
48 if (_y < miny || _y >= maxy) { \
54 if (_x1 < minx) _i += (minx -_x1), n1 -= (minx -_x1), _x1 = minx; \
55 if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \
58 #define Y_FLIP(_y) (height - _y - 1)
61 #define HW_CLIPLOOP() \
63 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
64 int _nc = dPriv->numClipRects; \
66 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
67 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
68 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
69 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
72 #define HW_ENDCLIPLOOP() \
78 /* 16 bit, 565 rgb color spanline and pixel functions
82 viaContextPtr vmesa = VIA_CONTEXT(ctx); \
83 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
84 GLuint draw_pitch = vmesa->drawBuffer->pitch; \
85 GLuint read_pitch = vmesa->readBuffer->pitch; \
86 GLuint height = dPriv->h; \
88 char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 2); \
89 char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 2); \
90 (void) (read_pitch && draw_pitch && buf && read_buf && p);
92 #define INIT_MONO_PIXEL(p, color) \
93 p = PACK_COLOR_565(color[0], color[1], color[2])
95 #define WRITE_RGBA(_x, _y, r, g, b, a) \
96 *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = ((((int)r & 0xf8) << 8) | \
97 (((int)g & 0xfc) << 3) | \
98 (((int)b & 0xf8) >> 3))
100 #define WRITE_PIXEL(_x, _y, p) \
101 *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = p
103 #define READ_RGBA(rgba, _x, _y) \
105 GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * read_pitch); \
106 rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
107 rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
108 rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
112 #define TAG(x) via##x##_565
115 /* 32 bit, 8888 argb color spanline and pixel functions
118 #undef LOCAL_DEPTH_VARS
119 #undef INIT_MONO_PIXEL
124 viaContextPtr vmesa = VIA_CONTEXT(ctx); \
125 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
126 GLuint draw_pitch = vmesa->drawBuffer->pitch; \
127 GLuint read_pitch = vmesa->readBuffer->pitch; \
128 GLuint height = dPriv->h; \
130 char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * 4); \
131 char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * 4); \
132 (void) (read_pitch && draw_pitch && buf && read_buf && p);
134 #define GET_SRC_PTR(_x, _y) (read_buf + _x * 4 + _y * read_pitch)
135 #define GET_DST_PTR(_x, _y) ( buf + _x * 4 + _y * draw_pitch)
136 #define SPANTMP_PIXEL_FMT GL_BGRA
137 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
139 #define TAG(x) via##x##_8888
140 #define TAG2(x,y) via##x##_8888##y
141 #include "spantmp2.h"
144 /* 16 bit depthbuffer functions.
146 #define LOCAL_DEPTH_VARS \
147 viaContextPtr vmesa = VIA_CONTEXT(ctx); \
148 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
149 GLuint depth_pitch = vmesa->depth.pitch; \
150 GLuint height = dPriv->h; \
151 char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8))
153 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
156 #define WRITE_DEPTH(_x, _y, d) \
157 *(GLushort *)(buf + _x * 2 + _y * depth_pitch) = d;
159 #define READ_DEPTH(d, _x, _y) \
160 d = *(GLushort *)(buf + _x * 2 + _y * depth_pitch);
162 #define TAG(x) via##x##_16
163 #include "depthtmp.h"
165 /* 32 bit depthbuffer functions.
167 #define WRITE_DEPTH(_x, _y, d) \
168 *(GLuint *)(buf + _x * 4 + _y * depth_pitch) = d;
170 #define READ_DEPTH(d, _x, _y) \
171 d = *(GLuint *)(buf + _x * 4 + _y * depth_pitch);
173 #define TAG(x) via##x##_32
174 #include "depthtmp.h"
178 /* 24/8 bit interleaved depth/stencil functions
180 #define WRITE_DEPTH( _x, _y, d ) { \
181 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
184 *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
187 #define READ_DEPTH( d, _x, _y ) \
188 d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8;
191 #define TAG(x) via##x##_24_8
192 #include "depthtmp.h"
194 #define WRITE_STENCIL( _x, _y, d ) { \
195 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
198 *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
201 #define READ_STENCIL( d, _x, _y ) \
202 d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff;
204 #define TAG(x) via##x##_24_8
205 #include "stenciltmp.h"
209 static void viaSetBuffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
212 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
214 if (bufferBit
== DD_FRONT_LEFT_BIT
) {
215 vmesa
->drawBuffer
= vmesa
->readBuffer
= &vmesa
->front
;
217 else if (bufferBit
== DD_BACK_LEFT_BIT
) {
218 vmesa
->drawBuffer
= vmesa
->readBuffer
= &vmesa
->back
;
225 /* Move locking out to get reasonable span performance.
227 void viaSpanRenderStart( GLcontext
*ctx
)
229 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
230 VIA_FINISH_PRIM(vmesa
);
231 LOCK_HARDWARE(vmesa
);
232 viaFlushDmaLocked(vmesa
, 0);
236 void viaSpanRenderFinish( GLcontext
*ctx
)
238 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
239 _swrast_flush( ctx
);
240 UNLOCK_HARDWARE( vmesa
);
243 void viaInitSpanFuncs(GLcontext
*ctx
)
245 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
246 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
248 swdd
->SetBuffer
= viaSetBuffer
;
249 if (vmesa
->viaScreen
->bitsPerPixel
== 16) {
250 swdd
->WriteRGBASpan
= viaWriteRGBASpan_565
;
251 swdd
->WriteRGBSpan
= viaWriteRGBSpan_565
;
252 swdd
->WriteMonoRGBASpan
= viaWriteMonoRGBASpan_565
;
253 swdd
->WriteRGBAPixels
= viaWriteRGBAPixels_565
;
254 swdd
->WriteMonoRGBAPixels
= viaWriteMonoRGBAPixels_565
;
255 swdd
->ReadRGBASpan
= viaReadRGBASpan_565
;
256 swdd
->ReadRGBAPixels
= viaReadRGBAPixels_565
;
258 else if (vmesa
->viaScreen
->bitsPerPixel
== 32) {
259 viaInitPointers_8888( swdd
);
265 if (vmesa
->glCtx
->Visual
.depthBits
== 16) {
266 swdd
->ReadDepthSpan
= viaReadDepthSpan_16
;
267 swdd
->WriteDepthSpan
= viaWriteDepthSpan_16
;
268 swdd
->WriteMonoDepthSpan
= viaWriteMonoDepthSpan_16
;
269 swdd
->ReadDepthPixels
= viaReadDepthPixels_16
;
270 swdd
->WriteDepthPixels
= viaWriteDepthPixels_16
;
272 else if (vmesa
->glCtx
->Visual
.depthBits
== 24) {
273 swdd
->ReadDepthSpan
= viaReadDepthSpan_24_8
;
274 swdd
->WriteDepthSpan
= viaWriteDepthSpan_24_8
;
275 swdd
->ReadDepthPixels
= viaReadDepthPixels_24_8
;
276 swdd
->WriteDepthPixels
= viaWriteDepthPixels_24_8
;
278 swdd
->WriteStencilSpan
= viaWriteStencilSpan_24_8
;
279 swdd
->ReadStencilSpan
= viaReadStencilSpan_24_8
;
280 swdd
->WriteStencilPixels
= viaWriteStencilPixels_24_8
;
281 swdd
->ReadStencilPixels
= viaReadStencilPixels_24_8
;
283 else if (vmesa
->glCtx
->Visual
.depthBits
== 32) {
284 swdd
->ReadDepthSpan
= viaReadDepthSpan_32
;
285 swdd
->WriteDepthSpan
= viaWriteDepthSpan_32
;
286 swdd
->WriteMonoDepthSpan
= viaWriteMonoDepthSpan_32
;
287 swdd
->ReadDepthPixels
= viaReadDepthPixels_32
;
288 swdd
->WriteDepthPixels
= viaWriteDepthPixels_32
;
291 swdd
->SpanRenderStart
= viaSpanRenderStart
;
292 swdd
->SpanRenderFinish
= viaSpanRenderFinish
;
295 swdd
->WriteCI8Span
= NULL
;
296 swdd
->WriteCI32Span
= NULL
;
297 swdd
->WriteMonoCISpan
= NULL
;
298 swdd
->WriteCI32Pixels
= NULL
;
299 swdd
->WriteMonoCIPixels
= NULL
;
300 swdd
->ReadCI32Span
= NULL
;
301 swdd
->ReadCI32Pixels
= NULL
;