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