mesa: merge gallium-0.2 into gallium-master-merge
[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 /* 32-bit BGRX */
83 #define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \
84 DST[3] = 0xff; \
85 DST[2] = VALUE[RCOMP]; \
86 DST[1] = VALUE[GCOMP]; \
87 DST[0] = VALUE[BCOMP]
88 #define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \
89 DST[3] = 0xff; \
90 DST[2] = VALUE[RCOMP]; \
91 DST[1] = VALUE[GCOMP]; \
92 DST[0] = VALUE[BCOMP]
93 #define FETCH_PIXEL_X8R8G8B8(DST, SRC) \
94 DST[ACOMP] = 0xff; \
95 DST[RCOMP] = SRC[2]; \
96 DST[GCOMP] = SRC[1]; \
97 DST[BCOMP] = SRC[0]
98
99
100 /* 16-bit BGR */
101 #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
102 do { \
103 int d = DITHER_COMP(X, Y) >> 6; \
104 GLushort *p = (GLushort *)DST; \
105 *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
106 ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
107 ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
108 } while(0)
109 #define FETCH_PIXEL_R5G6B5(DST, SRC) \
110 do { \
111 GLushort p = *(GLushort *)SRC; \
112 DST[ACOMP] = 0xff; \
113 DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
114 DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
115 DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
116 } while(0)
117
118
119 /* 8-bit BGR */
120 #define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \
121 do { \
122 int d = DITHER_COMP(X, Y) >> 3; \
123 GLubyte *p = (GLubyte *)DST; \
124 *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xe0) >> 5) | \
125 ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xe0) >> 2) | \
126 ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xc0) >> 0) ); \
127 } while(0)
128 #define FETCH_PIXEL_R3G3B2(DST, SRC) \
129 do { \
130 GLubyte p = *(GLubyte *)SRC; \
131 DST[ACOMP] = 0xff; \
132 DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \
133 DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \
134 DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \
135 } while(0)
136
137
138 /*
139 * Generate code for back-buffer span functions.
140 */
141
142 /* 32-bit BGRA */
143 #define NAME(FUNC) FUNC##_A8R8G8B8
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) * 4;
149 #define INC_PIXEL_PTR(P) P += 4
150 #define STORE_PIXEL(DST, X, Y, VALUE) \
151 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
152 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
153 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
154 #define FETCH_PIXEL(DST, SRC) \
155 FETCH_PIXEL_A8R8G8B8(DST, SRC)
156
157 #include "swrast/s_spantemp.h"
158
159
160 /* 32-bit BGRX */
161 #define NAME(FUNC) FUNC##_X8R8G8B8
162 #define RB_TYPE GLubyte
163 #define SPAN_VARS \
164 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
165 #define INIT_PIXEL_PTR(P, X, Y) \
166 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
167 #define INC_PIXEL_PTR(P) P += 4
168 #define STORE_PIXEL(DST, X, Y, VALUE) \
169 STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
170 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
171 STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE)
172 #define FETCH_PIXEL(DST, SRC) \
173 FETCH_PIXEL_X8R8G8B8(DST, SRC)
174
175 #include "swrast/s_spantemp.h"
176
177
178 /* 16-bit BGR */
179 #define NAME(FUNC) FUNC##_R5G6B5
180 #define RB_TYPE GLubyte
181 #define SPAN_VARS \
182 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
183 #define INIT_PIXEL_PTR(P, X, Y) \
184 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
185 #define INC_PIXEL_PTR(P) P += 2
186 #define STORE_PIXEL(DST, X, Y, VALUE) \
187 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
188 #define FETCH_PIXEL(DST, SRC) \
189 FETCH_PIXEL_R5G6B5(DST, SRC)
190
191 #include "swrast/s_spantemp.h"
192
193
194 /* 8-bit BGR */
195 #define NAME(FUNC) FUNC##_R3G3B2
196 #define RB_TYPE GLubyte
197 #define SPAN_VARS \
198 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
199 #define INIT_PIXEL_PTR(P, X, Y) \
200 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1;
201 #define INC_PIXEL_PTR(P) P += 1
202 #define STORE_PIXEL(DST, X, Y, VALUE) \
203 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
204 #define FETCH_PIXEL(DST, SRC) \
205 FETCH_PIXEL_R3G3B2(DST, SRC)
206
207 #include "swrast/s_spantemp.h"
208
209
210 /* 8-bit color index */
211 #define NAME(FUNC) FUNC##_CI8
212 #define CI_MODE
213 #define RB_TYPE GLubyte
214 #define SPAN_VARS \
215 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
216 #define INIT_PIXEL_PTR(P, X, Y) \
217 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X);
218 #define INC_PIXEL_PTR(P) P += 1
219 #define STORE_PIXEL(DST, X, Y, VALUE) \
220 *DST = VALUE[0]
221 #define FETCH_PIXEL(DST, SRC) \
222 DST = SRC[0]
223
224 #include "swrast/s_spantemp.h"
225
226
227 /*
228 * Generate code for front-buffer span functions.
229 */
230
231 /* 32-bit BGRA */
232 #define NAME(FUNC) FUNC##_A8R8G8B8_front
233 #define RB_TYPE GLubyte
234 #define SPAN_VARS \
235 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
236 #define INIT_PIXEL_PTR(P, X, Y) \
237 GLubyte *P = (GLubyte *)row;
238 #define INC_PIXEL_PTR(P) P += 4
239 #define STORE_PIXEL(DST, X, Y, VALUE) \
240 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
241 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
242 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
243 #define FETCH_PIXEL(DST, SRC) \
244 FETCH_PIXEL_A8R8G8B8(DST, SRC)
245
246 #include "swrast_spantemp.h"
247
248
249 /* 32-bit BGRX */
250 #define NAME(FUNC) FUNC##_X8R8G8B8_front
251 #define RB_TYPE GLubyte
252 #define SPAN_VARS \
253 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
254 #define INIT_PIXEL_PTR(P, X, Y) \
255 GLubyte *P = (GLubyte *)row;
256 #define INC_PIXEL_PTR(P) P += 4
257 #define STORE_PIXEL(DST, X, Y, VALUE) \
258 STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
259 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
260 STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE)
261 #define FETCH_PIXEL(DST, SRC) \
262 FETCH_PIXEL_X8R8G8B8(DST, SRC)
263
264 #include "swrast_spantemp.h"
265
266
267 /* 16-bit BGR */
268 #define NAME(FUNC) FUNC##_R5G6B5_front
269 #define RB_TYPE GLubyte
270 #define SPAN_VARS \
271 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
272 #define INIT_PIXEL_PTR(P, X, Y) \
273 GLubyte *P = (GLubyte *)row;
274 #define INC_PIXEL_PTR(P) P += 2
275 #define STORE_PIXEL(DST, X, Y, VALUE) \
276 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
277 #define FETCH_PIXEL(DST, SRC) \
278 FETCH_PIXEL_R5G6B5(DST, SRC)
279
280 #include "swrast_spantemp.h"
281
282
283 /* 8-bit BGR */
284 #define NAME(FUNC) FUNC##_R3G3B2_front
285 #define RB_TYPE GLubyte
286 #define SPAN_VARS \
287 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
288 #define INIT_PIXEL_PTR(P, X, Y) \
289 GLubyte *P = (GLubyte *)row;
290 #define INC_PIXEL_PTR(P) P += 1
291 #define STORE_PIXEL(DST, X, Y, VALUE) \
292 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
293 #define FETCH_PIXEL(DST, SRC) \
294 FETCH_PIXEL_R3G3B2(DST, SRC)
295
296 #include "swrast_spantemp.h"
297
298
299 /* 8-bit color index */
300 #define NAME(FUNC) FUNC##_CI8_front
301 #define CI_MODE
302 #define RB_TYPE GLubyte
303 #define SPAN_VARS \
304 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
305 #define INIT_PIXEL_PTR(P, X, Y) \
306 GLubyte *P = (GLubyte *)row;
307 #define INC_PIXEL_PTR(P) P += 1
308 #define STORE_PIXEL(DST, X, Y, VALUE) \
309 *DST = VALUE[0]
310 #define FETCH_PIXEL(DST, SRC) \
311 DST = SRC[0]
312
313 #include "swrast_spantemp.h"
314
315
316 /*
317 * Back-buffers are malloced memory and always private.
318 *
319 * BACK_PIXMAP (not supported)
320 * BACK_XIMAGE
321 */
322 void
323 swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb,
324 GLuint pixel_format)
325 {
326 switch (pixel_format) {
327 case PF_A8R8G8B8:
328 xrb->Base.GetRow = get_row_A8R8G8B8;
329 xrb->Base.GetValues = get_values_A8R8G8B8;
330 xrb->Base.PutRow = put_row_A8R8G8B8;
331 xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8;
332 xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8;
333 xrb->Base.PutValues = put_values_A8R8G8B8;
334 xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8;
335 break;
336 case PF_X8R8G8B8:
337 xrb->Base.GetRow = get_row_X8R8G8B8;
338 xrb->Base.GetValues = get_values_X8R8G8B8;
339 xrb->Base.PutRow = put_row_X8R8G8B8;
340 xrb->Base.PutRowRGB = put_row_rgb_X8R8G8B8;
341 xrb->Base.PutMonoRow = put_mono_row_X8R8G8B8;
342 xrb->Base.PutValues = put_values_X8R8G8B8;
343 xrb->Base.PutMonoValues = put_mono_values_X8R8G8B8;
344 break;
345 case PF_R5G6B5:
346 xrb->Base.GetRow = get_row_R5G6B5;
347 xrb->Base.GetValues = get_values_R5G6B5;
348 xrb->Base.PutRow = put_row_R5G6B5;
349 xrb->Base.PutRowRGB = put_row_rgb_R5G6B5;
350 xrb->Base.PutMonoRow = put_mono_row_R5G6B5;
351 xrb->Base.PutValues = put_values_R5G6B5;
352 xrb->Base.PutMonoValues = put_mono_values_R5G6B5;
353 break;
354 case PF_R3G3B2:
355 xrb->Base.GetRow = get_row_R3G3B2;
356 xrb->Base.GetValues = get_values_R3G3B2;
357 xrb->Base.PutRow = put_row_R3G3B2;
358 xrb->Base.PutRowRGB = put_row_rgb_R3G3B2;
359 xrb->Base.PutMonoRow = put_mono_row_R3G3B2;
360 xrb->Base.PutValues = put_values_R3G3B2;
361 xrb->Base.PutMonoValues = put_mono_values_R3G3B2;
362 break;
363 case PF_CI8:
364 xrb->Base.GetRow = get_row_CI8;
365 xrb->Base.GetValues = get_values_CI8;
366 xrb->Base.PutRow = put_row_CI8;
367 xrb->Base.PutMonoRow = put_mono_row_CI8;
368 xrb->Base.PutValues = put_values_CI8;
369 xrb->Base.PutMonoValues = put_mono_values_CI8;
370 break;
371 default:
372 assert(0);
373 return;
374 }
375 }
376
377
378 /*
379 * Front-buffers are provided by the loader, the xorg loader uses pixmaps.
380 *
381 * WINDOW, An X window
382 * GLXWINDOW, GLX window
383 * PIXMAP, GLX pixmap
384 * PBUFFER GLX Pbuffer
385 */
386 void
387 swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb,
388 GLuint pixel_format)
389 {
390 switch (pixel_format) {
391 case PF_A8R8G8B8:
392 xrb->Base.GetRow = get_row_A8R8G8B8_front;
393 xrb->Base.GetValues = get_values_A8R8G8B8_front;
394 xrb->Base.PutRow = put_row_A8R8G8B8_front;
395 xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_front;
396 xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_front;
397 xrb->Base.PutValues = put_values_A8R8G8B8_front;
398 xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_front;
399 break;
400 case PF_X8R8G8B8:
401 xrb->Base.GetRow = get_row_X8R8G8B8_front;
402 xrb->Base.GetValues = get_values_X8R8G8B8_front;
403 xrb->Base.PutRow = put_row_X8R8G8B8_front;
404 xrb->Base.PutRowRGB = put_row_rgb_X8R8G8B8_front;
405 xrb->Base.PutMonoRow = put_mono_row_X8R8G8B8_front;
406 xrb->Base.PutValues = put_values_X8R8G8B8_front;
407 xrb->Base.PutMonoValues = put_mono_values_X8R8G8B8_front;
408 break;
409 case PF_R5G6B5:
410 xrb->Base.GetRow = get_row_R5G6B5_front;
411 xrb->Base.GetValues = get_values_R5G6B5_front;
412 xrb->Base.PutRow = put_row_R5G6B5_front;
413 xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_front;
414 xrb->Base.PutMonoRow = put_mono_row_R5G6B5_front;
415 xrb->Base.PutValues = put_values_R5G6B5_front;
416 xrb->Base.PutMonoValues = put_mono_values_R5G6B5_front;
417 break;
418 case PF_R3G3B2:
419 xrb->Base.GetRow = get_row_R3G3B2_front;
420 xrb->Base.GetValues = get_values_R3G3B2_front;
421 xrb->Base.PutRow = put_row_R3G3B2_front;
422 xrb->Base.PutRowRGB = put_row_rgb_R3G3B2_front;
423 xrb->Base.PutMonoRow = put_mono_row_R3G3B2_front;
424 xrb->Base.PutValues = put_values_R3G3B2_front;
425 xrb->Base.PutMonoValues = put_mono_values_R3G3B2_front;
426 break;
427 case PF_CI8:
428 xrb->Base.GetRow = get_row_CI8_front;
429 xrb->Base.GetValues = get_values_CI8_front;
430 xrb->Base.PutRow = put_row_CI8_front;
431 xrb->Base.PutMonoRow = put_mono_row_CI8_front;
432 xrb->Base.PutValues = put_values_CI8_front;
433 xrb->Base.PutMonoValues = put_mono_values_CI8_front;
434 break;
435 default:
436 assert(0);
437 return;
438 }
439 }