make alloc-dma functions inline, rearrange some debug
[mesa.git] / src / mesa / drivers / dri / unichrome / via_span.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. 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 * 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:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the 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 * 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.
23 */
24
25 #include "glheader.h"
26 #include "macros.h"
27 #include "mtypes.h"
28 #include "colormac.h"
29 #include "via_context.h"
30 #include "via_span.h"
31 #include "via_ioctl.h"
32 #include "swrast/swrast.h"
33
34 #define DBG 0
35
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))
42
43 #define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
44 _y >= miny && _y < maxy)
45
46
47 #define CLIPSPAN(_x, _y, _n, _x1, _n1, _i) \
48 if (_y < miny || _y >= maxy) { \
49 _n1 = 0, _x1 = x; \
50 } \
51 else { \
52 _n1 = _n; \
53 _x1 = _x; \
54 if (_x1 < minx) _i += (minx -_x1), n1 -= (minx -_x1), _x1 = minx; \
55 if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \
56 }
57
58 #define Y_FLIP(_y) (height - _y - 1)
59
60 #define HW_LOCK()
61 #define HW_CLIPLOOP() \
62 do { \
63 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
64 int _nc = dPriv->numClipRects; \
65 while (_nc--) { \
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;
70
71
72 #define HW_ENDCLIPLOOP() \
73 } \
74 } while (0)
75
76 #define HW_UNLOCK()
77
78 /* 16 bit, 565 rgb color spanline and pixel functions
79 */
80 #undef LOCAL_VARS
81 #define LOCAL_VARS \
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; \
87 GLushort p = 0; \
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);
91
92 #define INIT_MONO_PIXEL(p, color) \
93 p = PACK_COLOR_565(color[0], color[1], color[2])
94
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))
99
100 #define WRITE_PIXEL(_x, _y, p) \
101 *(GLushort *)(buf + _x * 2 + _y * draw_pitch) = p
102
103 #define READ_RGBA(rgba, _x, _y) \
104 do { \
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; \
109 rgba[3] = 255; \
110 } while (0)
111
112 #define TAG(x) via##x##_565
113 #include "spantmp.h"
114
115 /* 32 bit, 8888 argb color spanline and pixel functions
116 */
117 #undef LOCAL_VARS
118 #undef LOCAL_DEPTH_VARS
119 #undef INIT_MONO_PIXEL
120 #undef DBG
121 #define DBG 0
122
123 #define LOCAL_VARS \
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; \
129 GLuint p = 0; \
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);
133
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
138
139 #define TAG(x) via##x##_8888
140 #define TAG2(x,y) via##x##_8888##y
141 #include "spantmp2.h"
142
143
144 /* 16 bit depthbuffer functions.
145 */
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))
152
153 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
154
155
156 #define WRITE_DEPTH(_x, _y, d) \
157 *(GLushort *)(buf + _x * 2 + _y * depth_pitch) = d;
158
159 #define READ_DEPTH(d, _x, _y) \
160 d = *(GLushort *)(buf + _x * 2 + _y * depth_pitch);
161
162 #define TAG(x) via##x##_16
163 #include "depthtmp.h"
164
165 /* 32 bit depthbuffer functions.
166 */
167 #define WRITE_DEPTH(_x, _y, d) \
168 *(GLuint *)(buf + _x * 4 + _y * depth_pitch) = d;
169
170 #define READ_DEPTH(d, _x, _y) \
171 d = *(GLuint *)(buf + _x * 4 + _y * depth_pitch);
172
173 #define TAG(x) via##x##_32
174 #include "depthtmp.h"
175
176
177
178 /* 24/8 bit interleaved depth/stencil functions
179 */
180 #define WRITE_DEPTH( _x, _y, d ) { \
181 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
182 tmp &= 0x000000ff; \
183 tmp |= ((d)<<8); \
184 *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
185 }
186
187 #define READ_DEPTH( d, _x, _y ) \
188 d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8;
189
190
191 #define TAG(x) via##x##_24_8
192 #include "depthtmp.h"
193
194 #define WRITE_STENCIL( _x, _y, d ) { \
195 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
196 tmp &= 0xffffff00; \
197 tmp |= (d); \
198 *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
199 }
200
201 #define READ_STENCIL( d, _x, _y ) \
202 d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff;
203
204 #define TAG(x) via##x##_24_8
205 #include "stenciltmp.h"
206
207
208
209 static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
210 GLuint bufferBit)
211 {
212 viaContextPtr vmesa = VIA_CONTEXT(ctx);
213
214 if (bufferBit == DD_FRONT_LEFT_BIT) {
215 vmesa->drawBuffer = vmesa->readBuffer = &vmesa->front;
216 }
217 else if (bufferBit == DD_BACK_LEFT_BIT) {
218 vmesa->drawBuffer = vmesa->readBuffer = &vmesa->back;
219 }
220 else {
221 ASSERT(0);
222 }
223 }
224
225 /* Move locking out to get reasonable span performance.
226 */
227 void viaSpanRenderStart( GLcontext *ctx )
228 {
229 viaContextPtr vmesa = VIA_CONTEXT(ctx);
230 VIA_FINISH_PRIM(vmesa);
231 LOCK_HARDWARE(vmesa);
232 viaFlushDmaLocked(vmesa, 0);
233 WAIT_IDLE(vmesa);
234 }
235
236 void viaSpanRenderFinish( GLcontext *ctx )
237 {
238 viaContextPtr vmesa = VIA_CONTEXT(ctx);
239 _swrast_flush( ctx );
240 UNLOCK_HARDWARE( vmesa );
241 }
242
243 void viaInitSpanFuncs(GLcontext *ctx)
244 {
245 viaContextPtr vmesa = VIA_CONTEXT(ctx);
246 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
247
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;
257 }
258 else if (vmesa->viaScreen->bitsPerPixel == 32) {
259 viaInitPointers_8888( swdd );
260 }
261 else {
262 assert(0);
263 }
264
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;
271 }
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;
277
278 swdd->WriteStencilSpan = viaWriteStencilSpan_24_8;
279 swdd->ReadStencilSpan = viaReadStencilSpan_24_8;
280 swdd->WriteStencilPixels = viaWriteStencilPixels_24_8;
281 swdd->ReadStencilPixels = viaReadStencilPixels_24_8;
282 }
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;
289 }
290
291 swdd->SpanRenderStart = viaSpanRenderStart;
292 swdd->SpanRenderFinish = viaSpanRenderFinish;
293
294
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;
302 }