Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / swrast / swrast_span.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * Authors:
27 * George Sapountzis <gsap7@yahoo.gr>
28 */
29
30 #include "swrast_priv.h"
31
32 #define YFLIP(_xrb, Y) ((_xrb)->Base.Height - (Y) - 1)
33
34 /*
35 * Dithering support takes the "computation" extreme in the "computation vs.
36 * storage" trade-off. This approach is very simple to implement and any
37 * computational overhead should be acceptable. XMesa uses table lookups for
38 * around 8KB of storage overhead per visual.
39 */
40 #define DITHER 1
41
42 static const GLubyte kernel[16] = {
43 0*16, 8*16, 2*16, 10*16,
44 12*16, 4*16, 14*16, 6*16,
45 3*16, 11*16, 1*16, 9*16,
46 15*16, 7*16, 13*16, 5*16,
47 };
48
49 #if DITHER
50 #define DITHER_COMP(X, Y) kernel[((X) & 0x3) | (((Y) & 0x3) << 2)]
51
52 #define DITHER_CLAMP(X) (((X) < CHAN_MAX) ? (X) : CHAN_MAX)
53 #else
54 #define DITHER_COMP(X, Y) 0
55
56 #define DITHER_CLAMP(X) (X)
57 #endif
58
59
60 /*
61 * Pixel macros shared across front/back buffer span functions.
62 */
63
64 /* 32-bit BGRA */
65 #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
66 DST[3] = VALUE[ACOMP]; \
67 DST[2] = VALUE[RCOMP]; \
68 DST[1] = VALUE[GCOMP]; \
69 DST[0] = VALUE[BCOMP]
70 #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
71 DST[3] = 0xff; \
72 DST[2] = VALUE[RCOMP]; \
73 DST[1] = VALUE[GCOMP]; \
74 DST[0] = VALUE[BCOMP]
75 #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
76 DST[ACOMP] = SRC[3]; \
77 DST[RCOMP] = SRC[2]; \
78 DST[GCOMP] = SRC[1]; \
79 DST[BCOMP] = SRC[0]
80
81
82 /* 16-bit BGR */
83 #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
84 do { \
85 int d = DITHER_COMP(X, Y) >> 6; \
86 GLushort *p = (GLushort *)DST; \
87 *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
88 ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
89 ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
90 } while(0)
91 #define FETCH_PIXEL_R5G6B5(DST, SRC) \
92 do { \
93 GLushort p = *(GLushort *)SRC; \
94 DST[ACOMP] = 0xff; \
95 DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
96 DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
97 DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
98 } while(0)
99
100
101 /* 8-bit BGR */
102 #define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \
103 do { \
104 int d = DITHER_COMP(X, Y) >> 3; \
105 GLubyte *p = (GLubyte *)DST; \
106 *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xe0) >> 5) | \
107 ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xe0) >> 2) | \
108 ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xc0) >> 0) ); \
109 } while(0)
110 #define FETCH_PIXEL_R3G3B2(DST, SRC) \
111 do { \
112 GLubyte p = *(GLubyte *)SRC; \
113 DST[ACOMP] = 0xff; \
114 DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \
115 DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \
116 DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \
117 } while(0)
118
119
120 /*
121 * Generate code for back-buffer span functions.
122 */
123
124 /* 32-bit BGRA */
125 #define NAME(FUNC) FUNC##_A8R8G8B8
126 #define RB_TYPE GLubyte
127 #define SPAN_VARS \
128 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
129 #define INIT_PIXEL_PTR(P, X, Y) \
130 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
131 #define INC_PIXEL_PTR(P) P += 4
132 #define STORE_PIXEL(DST, X, Y, VALUE) \
133 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
134 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
135 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
136 #define FETCH_PIXEL(DST, SRC) \
137 FETCH_PIXEL_A8R8G8B8(DST, SRC)
138
139 #include "swrast/s_spantemp.h"
140
141
142 /* 16-bit BGR */
143 #define NAME(FUNC) FUNC##_R5G6B5
144 #define RB_TYPE GLubyte
145 #define SPAN_VARS \
146 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
147 #define INIT_PIXEL_PTR(P, X, Y) \
148 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
149 #define INC_PIXEL_PTR(P) P += 2
150 #define STORE_PIXEL(DST, X, Y, VALUE) \
151 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
152 #define FETCH_PIXEL(DST, SRC) \
153 FETCH_PIXEL_R5G6B5(DST, SRC)
154
155 #include "swrast/s_spantemp.h"
156
157
158 /* 8-bit BGR */
159 #define NAME(FUNC) FUNC##_R3G3B2
160 #define RB_TYPE GLubyte
161 #define SPAN_VARS \
162 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
163 #define INIT_PIXEL_PTR(P, X, Y) \
164 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1;
165 #define INC_PIXEL_PTR(P) P += 1
166 #define STORE_PIXEL(DST, X, Y, VALUE) \
167 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
168 #define FETCH_PIXEL(DST, SRC) \
169 FETCH_PIXEL_R3G3B2(DST, SRC)
170
171 #include "swrast/s_spantemp.h"
172
173
174 /* 8-bit color index */
175 #define NAME(FUNC) FUNC##_CI8
176 #define CI_MODE
177 #define RB_TYPE GLubyte
178 #define SPAN_VARS \
179 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
180 #define INIT_PIXEL_PTR(P, X, Y) \
181 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X);
182 #define INC_PIXEL_PTR(P) P += 1
183 #define STORE_PIXEL(DST, X, Y, VALUE) \
184 *DST = VALUE[0]
185 #define FETCH_PIXEL(DST, SRC) \
186 DST = SRC[0]
187
188 #include "swrast/s_spantemp.h"
189
190
191 /*
192 * Generate code for front-buffer span functions.
193 */
194
195 /* 32-bit BGRA */
196 #define NAME(FUNC) FUNC##_A8R8G8B8_front
197 #define RB_TYPE GLubyte
198 #define SPAN_VARS \
199 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
200 #define INIT_PIXEL_PTR(P, X, Y) \
201 GLubyte *P = (GLubyte *)row;
202 #define INC_PIXEL_PTR(P) P += 4
203 #define STORE_PIXEL(DST, X, Y, VALUE) \
204 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
205 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
206 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
207 #define FETCH_PIXEL(DST, SRC) \
208 FETCH_PIXEL_A8R8G8B8(DST, SRC)
209
210 #include "swrast_spantemp.h"
211
212
213 /* 16-bit BGR */
214 #define NAME(FUNC) FUNC##_R5G6B5_front
215 #define RB_TYPE GLubyte
216 #define SPAN_VARS \
217 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
218 #define INIT_PIXEL_PTR(P, X, Y) \
219 GLubyte *P = (GLubyte *)row;
220 #define INC_PIXEL_PTR(P) P += 2
221 #define STORE_PIXEL(DST, X, Y, VALUE) \
222 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
223 #define FETCH_PIXEL(DST, SRC) \
224 FETCH_PIXEL_R5G6B5(DST, SRC)
225
226 #include "swrast_spantemp.h"
227
228
229 /* 8-bit BGR */
230 #define NAME(FUNC) FUNC##_R3G3B2_front
231 #define RB_TYPE GLubyte
232 #define SPAN_VARS \
233 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
234 #define INIT_PIXEL_PTR(P, X, Y) \
235 GLubyte *P = (GLubyte *)row;
236 #define INC_PIXEL_PTR(P) P += 1
237 #define STORE_PIXEL(DST, X, Y, VALUE) \
238 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
239 #define FETCH_PIXEL(DST, SRC) \
240 FETCH_PIXEL_R3G3B2(DST, SRC)
241
242 #include "swrast_spantemp.h"
243
244
245 /* 8-bit color index */
246 #define NAME(FUNC) FUNC##_CI8_front
247 #define CI_MODE
248 #define RB_TYPE GLubyte
249 #define SPAN_VARS \
250 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
251 #define INIT_PIXEL_PTR(P, X, Y) \
252 GLubyte *P = (GLubyte *)row;
253 #define INC_PIXEL_PTR(P) P += 1
254 #define STORE_PIXEL(DST, X, Y, VALUE) \
255 *DST = VALUE[0]
256 #define FETCH_PIXEL(DST, SRC) \
257 DST = SRC[0]
258
259 #include "swrast_spantemp.h"
260
261
262 /*
263 * Back-buffers are malloced memory and always private.
264 *
265 * BACK_PIXMAP (not supported)
266 * BACK_XIMAGE
267 */
268 void
269 swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb,
270 GLuint pixel_format)
271 {
272 switch (pixel_format) {
273 case PF_A8R8G8B8:
274 xrb->Base.GetRow = get_row_A8R8G8B8;
275 xrb->Base.GetValues = get_values_A8R8G8B8;
276 xrb->Base.PutRow = put_row_A8R8G8B8;
277 xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8;
278 xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8;
279 xrb->Base.PutValues = put_values_A8R8G8B8;
280 xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8;
281 break;
282 case PF_R5G6B5:
283 xrb->Base.GetRow = get_row_R5G6B5;
284 xrb->Base.GetValues = get_values_R5G6B5;
285 xrb->Base.PutRow = put_row_R5G6B5;
286 xrb->Base.PutRowRGB = put_row_rgb_R5G6B5;
287 xrb->Base.PutMonoRow = put_mono_row_R5G6B5;
288 xrb->Base.PutValues = put_values_R5G6B5;
289 xrb->Base.PutMonoValues = put_mono_values_R5G6B5;
290 break;
291 case PF_R3G3B2:
292 xrb->Base.GetRow = get_row_R3G3B2;
293 xrb->Base.GetValues = get_values_R3G3B2;
294 xrb->Base.PutRow = put_row_R3G3B2;
295 xrb->Base.PutRowRGB = put_row_rgb_R3G3B2;
296 xrb->Base.PutMonoRow = put_mono_row_R3G3B2;
297 xrb->Base.PutValues = put_values_R3G3B2;
298 xrb->Base.PutMonoValues = put_mono_values_R3G3B2;
299 break;
300 case PF_CI8:
301 xrb->Base.GetRow = get_row_CI8;
302 xrb->Base.GetValues = get_values_CI8;
303 xrb->Base.PutRow = put_row_CI8;
304 xrb->Base.PutMonoRow = put_mono_row_CI8;
305 xrb->Base.PutValues = put_values_CI8;
306 xrb->Base.PutMonoValues = put_mono_values_CI8;
307 break;
308 default:
309 assert(0);
310 return;
311 }
312 }
313
314
315 /*
316 * Front-buffers are provided by the loader, the xorg loader uses pixmaps.
317 *
318 * WINDOW, An X window
319 * GLXWINDOW, GLX window
320 * PIXMAP, GLX pixmap
321 * PBUFFER GLX Pbuffer
322 */
323 void
324 swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb,
325 GLuint pixel_format)
326 {
327 switch (pixel_format) {
328 case PF_A8R8G8B8:
329 xrb->Base.GetRow = get_row_A8R8G8B8_front;
330 xrb->Base.GetValues = get_values_A8R8G8B8_front;
331 xrb->Base.PutRow = put_row_A8R8G8B8_front;
332 xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_front;
333 xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_front;
334 xrb->Base.PutValues = put_values_A8R8G8B8_front;
335 xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_front;
336 break;
337 case PF_R5G6B5:
338 xrb->Base.GetRow = get_row_R5G6B5_front;
339 xrb->Base.GetValues = get_values_R5G6B5_front;
340 xrb->Base.PutRow = put_row_R5G6B5_front;
341 xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_front;
342 xrb->Base.PutMonoRow = put_mono_row_R5G6B5_front;
343 xrb->Base.PutValues = put_values_R5G6B5_front;
344 xrb->Base.PutMonoValues = put_mono_values_R5G6B5_front;
345 break;
346 case PF_R3G3B2:
347 xrb->Base.GetRow = get_row_R3G3B2_front;
348 xrb->Base.GetValues = get_values_R3G3B2_front;
349 xrb->Base.PutRow = put_row_R3G3B2_front;
350 xrb->Base.PutRowRGB = put_row_rgb_R3G3B2_front;
351 xrb->Base.PutMonoRow = put_mono_row_R3G3B2_front;
352 xrb->Base.PutValues = put_values_R3G3B2_front;
353 xrb->Base.PutMonoValues = put_mono_values_R3G3B2_front;
354 break;
355 case PF_CI8:
356 xrb->Base.GetRow = get_row_CI8_front;
357 xrb->Base.GetValues = get_values_CI8_front;
358 xrb->Base.PutRow = put_row_CI8_front;
359 xrb->Base.PutMonoRow = put_mono_row_CI8_front;
360 xrb->Base.PutValues = put_values_CI8_front;
361 xrb->Base.PutMonoValues = put_mono_values_CI8_front;
362 break;
363 default:
364 assert(0);
365 return;
366 }
367 }