dri/swrast: add support for r3g3b2
[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 * Pixel macros shared across front/back buffer span functions.
36 */
37
38 /* 32-bit BGRA */
39 #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
40 DST[3] = VALUE[ACOMP]; \
41 DST[2] = VALUE[RCOMP]; \
42 DST[1] = VALUE[GCOMP]; \
43 DST[0] = VALUE[BCOMP]
44 #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
45 DST[3] = 0xff; \
46 DST[2] = VALUE[RCOMP]; \
47 DST[1] = VALUE[GCOMP]; \
48 DST[0] = VALUE[BCOMP]
49 #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
50 DST[ACOMP] = SRC[3]; \
51 DST[RCOMP] = SRC[2]; \
52 DST[GCOMP] = SRC[1]; \
53 DST[BCOMP] = SRC[0]
54
55
56 /* 16-bit BGR */
57 #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
58 do { \
59 GLushort *p = (GLushort *)DST; \
60 *p = ( (((VALUE[RCOMP]) & 0xf8) << 8) | \
61 (((VALUE[GCOMP]) & 0xfc) << 3) | \
62 (((VALUE[BCOMP]) & 0xf8) >> 3) ); \
63 } while(0)
64 #define FETCH_PIXEL_R5G6B5(DST, SRC) \
65 do { \
66 GLushort p = *(GLushort *)SRC; \
67 DST[ACOMP] = 0xff; \
68 DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
69 DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
70 DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
71 } while(0)
72
73
74 /* 8-bit BGR */
75 #define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \
76 do { \
77 GLubyte *p = (GLubyte *)DST; \
78 *p = ( (((VALUE[RCOMP]) & 0xe0) >> 5) | \
79 (((VALUE[GCOMP]) & 0xe0) >> 2) | \
80 (((VALUE[BCOMP]) & 0xc0) >> 0) ); \
81 } while(0)
82 #define FETCH_PIXEL_R3G3B2(DST, SRC) \
83 do { \
84 GLubyte p = *(GLubyte *)SRC; \
85 DST[ACOMP] = 0xff; \
86 DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \
87 DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \
88 DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \
89 } while(0)
90
91
92 /*
93 * Generate code for image span functions.
94 */
95
96 /* 32-bit BGRA */
97 #define NAME(FUNC) FUNC##_A8R8G8B8
98 #define RB_TYPE GLubyte
99 #define SPAN_VARS \
100 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
101 #define INIT_PIXEL_PTR(P, X, Y) \
102 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
103 #define INC_PIXEL_PTR(P) P += 4
104 #define STORE_PIXEL(DST, X, Y, VALUE) \
105 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
106 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
107 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
108 #define FETCH_PIXEL(DST, SRC) \
109 FETCH_PIXEL_A8R8G8B8(DST, SRC)
110
111 #include "swrast/s_spantemp.h"
112
113
114 /* 16-bit BGR */
115 #define NAME(FUNC) FUNC##_R5G6B5
116 #define RB_TYPE GLubyte
117 #define SPAN_VARS \
118 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
119 #define INIT_PIXEL_PTR(P, X, Y) \
120 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
121 #define INC_PIXEL_PTR(P) P += 2
122 #define STORE_PIXEL(DST, X, Y, VALUE) \
123 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
124 #define FETCH_PIXEL(DST, SRC) \
125 FETCH_PIXEL_R5G6B5(DST, SRC)
126
127 #include "swrast/s_spantemp.h"
128
129
130 /* 8-bit BGR */
131 #define NAME(FUNC) FUNC##_R3G3B2
132 #define RB_TYPE GLubyte
133 #define SPAN_VARS \
134 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
135 #define INIT_PIXEL_PTR(P, X, Y) \
136 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1;
137 #define INC_PIXEL_PTR(P) P += 1
138 #define STORE_PIXEL(DST, X, Y, VALUE) \
139 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
140 #define FETCH_PIXEL(DST, SRC) \
141 FETCH_PIXEL_R3G3B2(DST, SRC)
142
143 #include "swrast/s_spantemp.h"
144
145
146 /* 8-bit color index */
147 #define NAME(FUNC) FUNC##_CI8
148 #define CI_MODE
149 #define RB_TYPE GLubyte
150 #define SPAN_VARS \
151 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
152 #define INIT_PIXEL_PTR(P, X, Y) \
153 GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X);
154 #define INC_PIXEL_PTR(P) P += 1
155 #define STORE_PIXEL(DST, X, Y, VALUE) \
156 *DST = VALUE[0]
157 #define FETCH_PIXEL(DST, SRC) \
158 DST = SRC[0]
159
160 #include "swrast/s_spantemp.h"
161
162
163 /*
164 * Generate code for pixmap span functions.
165 */
166
167 /* 32-bit BGRA */
168 #define NAME(FUNC) FUNC##_A8R8G8B8_pixmap
169 #define RB_TYPE GLubyte
170 #define SPAN_VARS \
171 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
172 #define INIT_PIXEL_PTR(P, X, Y) \
173 GLubyte *P = (GLubyte *)row;
174 #define INC_PIXEL_PTR(P) P += 4
175 #define STORE_PIXEL(DST, X, Y, VALUE) \
176 STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
177 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
178 STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE)
179 #define FETCH_PIXEL(DST, SRC) \
180 FETCH_PIXEL_A8R8G8B8(DST, SRC)
181
182 #include "swrast_spantemp.h"
183
184
185 /* 16-bit BGR */
186 #define NAME(FUNC) FUNC##_R5G6B5_pixmap
187 #define RB_TYPE GLubyte
188 #define SPAN_VARS \
189 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
190 #define INIT_PIXEL_PTR(P, X, Y) \
191 GLubyte *P = (GLubyte *)row;
192 #define INC_PIXEL_PTR(P) P += 2
193 #define STORE_PIXEL(DST, X, Y, VALUE) \
194 STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
195 #define FETCH_PIXEL(DST, SRC) \
196 FETCH_PIXEL_R5G6B5(DST, SRC)
197
198 #include "swrast_spantemp.h"
199
200
201 /* 8-bit BGR */
202 #define NAME(FUNC) FUNC##_R3G3B2_pixmap
203 #define RB_TYPE GLubyte
204 #define SPAN_VARS \
205 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
206 #define INIT_PIXEL_PTR(P, X, Y) \
207 GLubyte *P = (GLubyte *)row;
208 #define INC_PIXEL_PTR(P) P += 1
209 #define STORE_PIXEL(DST, X, Y, VALUE) \
210 STORE_PIXEL_R3G3B2(DST, X, Y, VALUE)
211 #define FETCH_PIXEL(DST, SRC) \
212 FETCH_PIXEL_R3G3B2(DST, SRC)
213
214 #include "swrast_spantemp.h"
215
216
217 /* 8-bit color index */
218 #define NAME(FUNC) FUNC##_CI8_pixmap
219 #define CI_MODE
220 #define RB_TYPE GLubyte
221 #define SPAN_VARS \
222 struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
223 #define INIT_PIXEL_PTR(P, X, Y) \
224 GLubyte *P = (GLubyte *)row;
225 #define INC_PIXEL_PTR(P) P += 1
226 #define STORE_PIXEL(DST, X, Y, VALUE) \
227 *DST = VALUE[0]
228 #define FETCH_PIXEL(DST, SRC) \
229 DST = SRC[0]
230
231 #include "swrast_spantemp.h"
232
233
234 /*
235 * Images are malloced memory used for private back-buffers.
236 *
237 * BACK_PIXMAP (not supported)
238 * BACK_XIMAGE
239 */
240 void
241 swrast_set_span_funcs_ximage(struct swrast_renderbuffer *xrb,
242 GLuint pixel_format)
243 {
244 switch (pixel_format) {
245 case PF_A8R8G8B8:
246 xrb->Base.GetRow = get_row_A8R8G8B8;
247 xrb->Base.GetValues = get_values_A8R8G8B8;
248 xrb->Base.PutRow = put_row_A8R8G8B8;
249 xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8;
250 xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8;
251 xrb->Base.PutValues = put_values_A8R8G8B8;
252 xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8;
253 break;
254 case PF_R5G6B5:
255 xrb->Base.GetRow = get_row_R5G6B5;
256 xrb->Base.GetValues = get_values_R5G6B5;
257 xrb->Base.PutRow = put_row_R5G6B5;
258 xrb->Base.PutRowRGB = put_row_rgb_R5G6B5;
259 xrb->Base.PutMonoRow = put_mono_row_R5G6B5;
260 xrb->Base.PutValues = put_values_R5G6B5;
261 xrb->Base.PutMonoValues = put_mono_values_R5G6B5;
262 break;
263 case PF_R3G3B2:
264 xrb->Base.GetRow = get_row_R3G3B2;
265 xrb->Base.GetValues = get_values_R3G3B2;
266 xrb->Base.PutRow = put_row_R3G3B2;
267 xrb->Base.PutRowRGB = put_row_rgb_R3G3B2;
268 xrb->Base.PutMonoRow = put_mono_row_R3G3B2;
269 xrb->Base.PutValues = put_values_R3G3B2;
270 xrb->Base.PutMonoValues = put_mono_values_R3G3B2;
271 break;
272 case PF_CI8:
273 xrb->Base.GetRow = get_row_CI8;
274 xrb->Base.GetValues = get_values_CI8;
275 xrb->Base.PutRow = put_row_CI8;
276 xrb->Base.PutMonoRow = put_mono_row_CI8;
277 xrb->Base.PutValues = put_values_CI8;
278 xrb->Base.PutMonoValues = put_mono_values_CI8;
279 break;
280 default:
281 assert(0);
282 return;
283 }
284 }
285
286
287 /*
288 * Pixmaps are used for front-buffers.
289 *
290 * WINDOW, An X window
291 * GLXWINDOW, GLX window
292 * PIXMAP, GLX pixmap
293 * PBUFFER GLX Pbuffer
294 */
295 void
296 swrast_set_span_funcs_pixmap(struct swrast_renderbuffer *xrb,
297 GLuint pixel_format)
298 {
299 switch (pixel_format) {
300 case PF_A8R8G8B8:
301 xrb->Base.GetRow = get_row_A8R8G8B8_pixmap;
302 xrb->Base.GetValues = get_values_A8R8G8B8_pixmap;
303 xrb->Base.PutRow = put_row_A8R8G8B8_pixmap;
304 xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_pixmap;
305 xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_pixmap;
306 xrb->Base.PutValues = put_values_A8R8G8B8_pixmap;
307 xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_pixmap;
308 break;
309 case PF_R5G6B5:
310 xrb->Base.GetRow = get_row_R5G6B5_pixmap;
311 xrb->Base.GetValues = get_values_R5G6B5_pixmap;
312 xrb->Base.PutRow = put_row_R5G6B5_pixmap;
313 xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_pixmap;
314 xrb->Base.PutMonoRow = put_mono_row_R5G6B5_pixmap;
315 xrb->Base.PutValues = put_values_R5G6B5_pixmap;
316 xrb->Base.PutMonoValues = put_mono_values_R5G6B5_pixmap;
317 break;
318 case PF_R3G3B2:
319 xrb->Base.GetRow = get_row_R3G3B2_pixmap;
320 xrb->Base.GetValues = get_values_R3G3B2_pixmap;
321 xrb->Base.PutRow = put_row_R3G3B2_pixmap;
322 xrb->Base.PutRowRGB = put_row_rgb_R3G3B2_pixmap;
323 xrb->Base.PutMonoRow = put_mono_row_R3G3B2_pixmap;
324 xrb->Base.PutValues = put_values_R3G3B2_pixmap;
325 xrb->Base.PutMonoValues = put_mono_values_R3G3B2_pixmap;
326 break;
327 case PF_CI8:
328 xrb->Base.GetRow = get_row_CI8_pixmap;
329 xrb->Base.GetValues = get_values_CI8_pixmap;
330 xrb->Base.PutRow = put_row_CI8_pixmap;
331 xrb->Base.PutMonoRow = put_mono_row_CI8_pixmap;
332 xrb->Base.PutValues = put_values_CI8_pixmap;
333 xrb->Base.PutMonoValues = put_mono_values_CI8_pixmap;
334 break;
335 default:
336 assert(0);
337 return;
338 }
339 }