Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / common / spantmp2.h
1 /*
2  * Copyright 2000-2001 VA Linux Systems, Inc.
3  * (C) Copyright IBM Corporation 2004
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * on the rights to use, copy, modify, merge, publish, distribute, sub
10  * license, and/or sell copies of the Software, and to permit persons to whom
11  * the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20  * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23  * USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /**
27  * \file spantmp2.h
28  *
29  * Template file of span read / write functions.
30  *
31  * \author Keith Whitwell <keithw@tungstengraphics.com>
32  * \author Gareth Hughes <gareth@nvidia.com>
33  * \author Ian Romanick <idr@us.ibm.com>
34  */
35
36 #include "main/colormac.h"
37 #include "spantmp_common.h"
38
39 #ifndef DBG
40 #define DBG 0
41 #endif
42
43 #ifndef HW_READ_CLIPLOOP
44 #define HW_READ_CLIPLOOP()      HW_CLIPLOOP()
45 #endif
46
47 #ifndef HW_WRITE_CLIPLOOP
48 #define HW_WRITE_CLIPLOOP()     HW_CLIPLOOP()
49 #endif
50
51 #if (SPANTMP_PIXEL_FMT == GL_RGB)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5)
52
53 /**
54  ** GL_RGB, GL_UNSIGNED_SHORT_5_6_5
55  **/
56
57 #ifndef GET_VALUE
58 #ifndef GET_PTR
59 #define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
60 #endif
61
62 #define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
63 #define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
64 #endif /* GET_VALUE */
65
66 #define INIT_MONO_PIXEL(p, color) \
67   p = PACK_COLOR_565( color[0], color[1], color[2] )
68
69 #define WRITE_RGBA( _x, _y, r, g, b, a )                                \
70    PUT_VALUE(_x, _y, ((((int)r & 0xf8) << 8) |                          \
71                       (((int)g & 0xfc) << 3) |                          \
72                       (((int)b & 0xf8) >> 3)))                          \
73
74 #define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
75
76 #define READ_RGBA( rgba, _x, _y )                                       \
77    do {                                                                 \
78       GLushort p = GET_VALUE(_x, _y);                                   \
79       rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;                         \
80       rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;                         \
81       rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                         \
82       rgba[3] = 0xff;                                                   \
83    } while (0)
84
85 #elif (SPANTMP_PIXEL_FMT == GL_RGB)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5_REV)
86
87 /**
88  ** GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV
89  **/
90
91 #ifndef GET_VALUE
92 #ifndef GET_PTR
93 #define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
94 #endif
95
96 #define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
97 #define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
98 #endif /* GET_VALUE */
99
100 #define INIT_MONO_PIXEL(p, color) \
101   p = PACK_COLOR_565_REV( color[0], color[1], color[2] )
102
103 #define WRITE_RGBA( _x, _y, r, g, b, a )                                \
104    PUT_VALUE(_x, _y, PACK_COLOR_565_REV( r, g, b ))
105
106 #define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
107
108 #define READ_RGBA( rgba, _x, _y )                                       \
109    do {                                                                 \
110       GLushort p = GET_VALUE(_x, _y);                                   \
111       p = p << 8 | p >> 8;                                              \
112       rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;                         \
113       rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;                         \
114       rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                         \
115       rgba[3] = 0xff;                                                   \
116    } while (0)
117
118 #elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4)
119
120 /**
121  ** GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4
122  **/
123
124 #ifndef GET_VALUE
125 #ifndef GET_PTR
126 #define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
127 #endif
128
129 #define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
130 #define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
131 #endif /* GET_VALUE */
132
133 #define INIT_MONO_PIXEL(p, color) \
134    p = PACK_COLOR_4444_REV(color[3], color[0], color[1], color[2])
135
136 #define WRITE_RGBA( _x, _y, r, g, b, a )                                \
137    PUT_VALUE(_x, _y, PACK_COLOR_4444_REV(a, r, g, b))                   \
138
139 #define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
140
141 #define READ_RGBA( rgba, _x, _y )                                       \
142    do {                                                                 \
143       GLushort p = GET_VALUE(_x, _y);                                   \
144       rgba[0] = ((p >> 0) & 0xf) * 0x11;                                \
145       rgba[1] = ((p >> 12) & 0xf) * 0x11;                               \
146       rgba[2] = ((p >> 4) & 0xf) * 0x11;                                \
147       rgba[3] = ((p >> 8) & 0xf) * 0x11;                                \
148    } while (0)
149
150
151 #elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4_REV)
152
153 /**
154  ** GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV
155  **/
156
157 #ifndef GET_VALUE
158 #ifndef GET_PTR
159 #define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
160 #endif
161
162 #define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
163 #define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
164 #endif /* GET_VALUE */
165
166 #define INIT_MONO_PIXEL(p, color) \
167    p = PACK_COLOR_4444(color[3], color[0], color[1], color[2])
168
169 #define WRITE_RGBA( _x, _y, r, g, b, a )                                \
170    PUT_VALUE(_x, _y, PACK_COLOR_4444(a, r, g, b))                       \
171
172 #define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
173
174 #define READ_RGBA( rgba, _x, _y )                                       \
175    do {                                                                 \
176       GLushort p = GET_VALUE(_x, _y);                                   \
177       rgba[0] = ((p >> 8) & 0xf) * 0x11;                                \
178       rgba[1] = ((p >> 4) & 0xf) * 0x11;                                \
179       rgba[2] = ((p >> 0) & 0xf) * 0x11;                                \
180       rgba[3] = ((p >> 12) & 0xf) * 0x11;                               \
181    } while (0)
182
183
184 #elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_1_5_5_5_REV)
185
186 /**
187  ** GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV
188  **/
189
190 #ifndef GET_VALUE
191 #ifndef GET_PTR
192 #define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
193 #endif
194
195 #define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
196 #define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
197 #endif /* GET_VALUE */
198
199 #define INIT_MONO_PIXEL(p, color) \
200    p = PACK_COLOR_1555(color[3], color[0], color[1], color[2])
201
202 #define WRITE_RGBA( _x, _y, r, g, b, a )                                \
203    PUT_VALUE(_x, _y, PACK_COLOR_1555(a, r, g, b))                       \
204
205 #define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
206
207 #define READ_RGBA( rgba, _x, _y )                                       \
208    do {                                                                 \
209       GLushort p = GET_VALUE(_x, _y);                                   \
210       rgba[0] = ((p >> 7) & 0xf8) * 255 / 0xf8;                         \
211       rgba[1] = ((p >> 2) & 0xf8) * 255 / 0xf8;                         \
212       rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                         \
213       rgba[3] = ((p >> 15) & 0x1) * 0xff;                               \
214    } while (0)
215
216 #elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_1_5_5_5)
217
218 /**
219  ** GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5
220  **/
221
222 #ifndef GET_VALUE
223 #ifndef GET_PTR
224 #define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
225 #endif
226
227 #define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
228 #define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
229 #endif /* GET_VALUE */
230
231 #define INIT_MONO_PIXEL(p, color) \
232    p = PACK_COLOR_1555_REV(color[3], color[0], color[1], color[2])
233
234 #define WRITE_RGBA( _x, _y, r, g, b, a )                                \
235    PUT_VALUE(_x, _y, PACK_COLOR_1555_REV(a, r, g, b))                   \
236
237 #define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
238
239 #define READ_RGBA( rgba, _x, _y )                                       \
240    do {                                                                 \
241       GLushort p = GET_VALUE(_x, _y);                                   \
242       p = p << 8 | p >> 8;                                              \
243       rgba[0] = ((p >> 7) & 0xf8) * 255 / 0xf8;                         \
244       rgba[1] = ((p >> 2) & 0xf8) * 255 / 0xf8;                         \
245       rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                         \
246       rgba[3] = ((p >> 15) & 0x1) * 0xff;                               \
247    } while (0)
248
249 #elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
250
251 /**
252  ** GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV
253  **/
254
255 #ifndef GET_VALUE
256 #ifndef GET_PTR
257 #define GET_PTR(_x, _y) (     buf + (_x) * 4 + (_y) * pitch)
258 #endif
259
260 #define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y))
261 #define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v)
262 #endif /* GET_VALUE */
263
264 # define INIT_MONO_PIXEL(p, color)                       \
265      p = PACK_COLOR_8888(color[3], color[0], color[1], color[2]) 
266
267 # define WRITE_RGBA(_x, _y, r, g, b, a)                                 \
268    PUT_VALUE(_x, _y, ((r << 16) |                                       \
269                       (g << 8) |                                        \
270                       (b << 0) |                                        \
271                       (a << 24)))
272
273 #define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
274
275 # if defined( USE_X86_ASM )
276 #  define READ_RGBA(rgba, _x, _y)                                       \
277     do {                                                                \
278        GLuint p = GET_VALUE(_x, _y);                                    \
279        __asm__ __volatile__( "bswap     %0; rorl $8, %0"                \
280                                 : "=r" (p) : "0" (p) );                 \
281        ((GLuint *)rgba)[0] = p;                                         \
282     } while (0)
283 # elif defined( MESA_BIG_ENDIAN )
284     /* On PowerPC with GCC 3.4.2 the shift madness below becomes a single
285      * rotlwi instruction.  It also produces good code on SPARC.
286      */
287 #  define READ_RGBA( rgba, _x, _y )                                     \
288      do {                                                               \
289         GLuint p = GET_VALUE(_x, _y);                                   \
290         GLuint t = p;                                                   \
291         *((uint32_t *) rgba) = (t >> 24) | (p << 8);                    \
292      } while (0)
293 # else
294 #  define READ_RGBA( rgba, _x, _y )                                     \
295      do {                                                               \
296         GLuint p = GET_VALUE(_x, _y);                                   \
297         rgba[0] = (p >> 16) & 0xff;                                     \
298         rgba[1] = (p >>  8) & 0xff;                                     \
299         rgba[2] = (p >>  0) & 0xff;                                     \
300         rgba[3] = (p >> 24) & 0xff;                                     \
301      } while (0)
302 # endif
303
304 #elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8)
305
306 /**
307  ** GL_BGRA, GL_UNSIGNED_INT_8_8_8_8
308  **/
309
310 #ifndef GET_VALUE
311 #ifndef GET_PTR
312 #define GET_PTR(_x, _y) (     buf + (_x) * 4 + (_y) * pitch)
313 #endif
314
315 #define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y))
316 #define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v)
317 #endif /* GET_VALUE */
318
319 # define INIT_MONO_PIXEL(p, color)                       \
320      p = PACK_COLOR_8888(color[2], color[1], color[0], color[3]) 
321
322 # define WRITE_RGBA(_x, _y, r, g, b, a)                                 \
323    PUT_VALUE(_x, _y, ((r << 8) |                                        \
324                       (g << 16) |                                       \
325                       (b << 24) |                                       \
326                       (a << 0)))
327
328 #define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
329
330 # if defined( USE_X86_ASM )
331 #  define READ_RGBA(rgba, _x, _y)                                       \
332     do {                                                                \
333        GLuint p = GET_VALUE(_x, _y);                                    \
334        __asm__ __volatile__( "rorl $8, %0"                              \
335                                 : "=r" (p) : "0" (p) );                 \
336        ((GLuint *)rgba)[0] = p;                                         \
337     } while (0)
338 # elif defined( MESA_BIG_ENDIAN )
339     /* On PowerPC with GCC 3.4.2 the shift madness below becomes a single
340      * rotlwi instruction.  It also produces good code on SPARC.
341      */
342 #  define READ_RGBA( rgba, _x, _y )                                     \
343      do {                                                               \
344         GLuint p = CPU_TO_LE32(GET_VALUE(_x, _y));                      \
345         GLuint t = p;                                                   \
346         *((uint32_t *) rgba) = (t >> 24) | (p << 8);                    \
347      } while (0)
348 # else
349 #  define READ_RGBA( rgba, _x, _y )                                     \
350      do {                                                               \
351         GLuint p = GET_VALUE(_x, _y);                                   \
352         rgba[0] = (p >>  8) & 0xff;                                     \
353         rgba[1] = (p >> 16) & 0xff;                                     \
354         rgba[2] = (p >> 24) & 0xff;                                     \
355         rgba[3] = (p >>  0) & 0xff;                                     \
356      } while (0)
357 # endif
358
359 #elif (SPANTMP_PIXEL_FMT == GL_BGR) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
360
361 /**
362  ** GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV
363  **
364  ** This is really for MESA_FORMAT_XRGB8888.  The spantmp code needs to be
365  ** kicked to the curb, and we need to just code-gen this.
366  **/
367
368 #ifndef GET_VALUE
369 #ifndef GET_PTR
370 #define GET_PTR(_x, _y) (     buf + (_x) * 4 + (_y) * pitch)
371 #endif
372
373 #define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y))
374 #define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v)
375 #endif /* GET_VALUE */
376
377 # define INIT_MONO_PIXEL(p, color)                       \
378      p = PACK_COLOR_8888(0xff, color[0], color[1], color[2])
379
380 # define WRITE_RGBA(_x, _y, r, g, b, a)                                 \
381    PUT_VALUE(_x, _y, ((r << 16) |                                       \
382                       (g << 8) |                                        \
383                       (b << 0) |                                        \
384                       (0xff << 24)))
385
386 #define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
387
388 # if defined( USE_X86_ASM )
389 #  define READ_RGBA(rgba, _x, _y)                                       \
390     do {                                                                \
391        GLuint p = GET_VALUE(_x, _y);                                    \
392        __asm__ __volatile__( "bswap     %0; rorl $8, %0"                \
393                                 : "=r" (p) : "0" (p) );                 \
394        ((GLuint *)rgba)[0] = p | 0xff000000;                            \
395     } while (0)
396 # elif defined( MESA_BIG_ENDIAN )
397     /* On PowerPC with GCC 3.4.2 the shift madness below becomes a single
398      * rotlwi instruction.  It also produces good code on SPARC.
399      */
400 #  define READ_RGBA( rgba, _x, _y )                                     \
401      do {                                                               \
402         GLuint p = GET_VALUE(_x, _y);                                   \
403         *((uint32_t *) rgba) = (p << 8) | 0xff;                         \
404      } while (0)
405 # else
406 #  define READ_RGBA( rgba, _x, _y )                                     \
407      do {                                                               \
408         GLuint p = GET_VALUE(_x, _y);                                   \
409         rgba[0] = (p >> 16) & 0xff;                                     \
410         rgba[1] = (p >>  8) & 0xff;                                     \
411         rgba[2] = (p >>  0) & 0xff;                                     \
412         rgba[3] = 0xff;                                                 \
413      } while (0)
414 # endif
415
416 #elif (SPANTMP_PIXEL_FMT == GL_ALPHA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_BYTE)
417
418 /**
419  ** GL_ALPHA, GL_UNSIGNED_BYTE
420  **/
421
422 #ifndef GET_VALUE
423 #ifndef GET_PTR
424 #define GET_PTR(_x, _y) (     buf + (_x) + (_y) * pitch)
425 #endif
426
427 #define GET_VALUE(_x, _y) *(volatile GLubyte *)(GET_PTR(_x, _y))
428 #define PUT_VALUE(_x, _y, _v) *(volatile GLubyte *)(GET_PTR(_x, _y)) = (_v)
429 #endif /* GET_VALUE */
430
431 # define INIT_MONO_PIXEL(p, color)                       \
432      p = color[3]
433
434 # define WRITE_RGBA(_x, _y, r, g, b, a)                                 \
435    PUT_VALUE(_x, _y, a | (r & 0 /* quiet warnings */))
436
437 #define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
438
439 #define READ_RGBA( rgba, _x, _y )                                       \
440      do {                                                               \
441         GLubyte p = GET_VALUE(_x, _y);                                  \
442         rgba[0] = 0;                                                    \
443         rgba[1] = 0;                                                    \
444         rgba[2] = 0;                                                    \
445         rgba[3] = p;                                                    \
446      } while (0)
447
448 #else
449 #error SPANTMP_PIXEL_FMT must be set to a valid value!
450 #endif
451
452
453
454 /**
455  ** Assembly routines.
456  **/
457
458 #if defined( USE_MMX_ASM ) || defined( USE_SSE_ASM )
459 #include "x86/read_rgba_span_x86.h"
460 #include "x86/common_x86_asm.h"
461 #endif
462
463 static void TAG(WriteRGBASpan)( struct gl_context *ctx,
464                                 struct gl_renderbuffer *rb,
465                                 GLuint n, GLint x, GLint y,
466                                 const void *values, const GLubyte mask[] )
467 {
468    HW_WRITE_LOCK()
469       {
470          const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
471          GLint x1;
472          GLint n1;
473          LOCAL_VARS;
474
475          y = Y_FLIP(y);
476
477          HW_WRITE_CLIPLOOP()
478             {
479                GLint i = 0;
480                CLIPSPAN(x,y,n,x1,n1,i);
481
482                if (DBG) fprintf(stderr, "WriteRGBASpan %d..%d (x1 %d)\n",
483                                 (int)i, (int)n1, (int)x1);
484
485                if (mask)
486                {
487                   for (;n1>0;i++,x1++,n1--)
488                      if (mask[i])
489                         WRITE_RGBA( x1, y,
490                                     rgba[i][0], rgba[i][1],
491                                     rgba[i][2], rgba[i][3] );
492                }
493                else
494                {
495                   for (;n1>0;i++,x1++,n1--)
496                      WRITE_RGBA( x1, y,
497                                  rgba[i][0], rgba[i][1],
498                                  rgba[i][2], rgba[i][3] );
499                }
500             }
501          HW_ENDCLIPLOOP();
502       }
503    HW_WRITE_UNLOCK();
504 }
505
506 static void TAG(WriteRGBSpan)( struct gl_context *ctx,
507                                struct gl_renderbuffer *rb,
508                                GLuint n, GLint x, GLint y,
509                                const void *values, const GLubyte mask[] )
510 {
511    HW_WRITE_LOCK()
512       {
513          const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
514          GLint x1;
515          GLint n1;
516          LOCAL_VARS;
517
518          y = Y_FLIP(y);
519
520          HW_WRITE_CLIPLOOP()
521             {
522                GLint i = 0;
523                CLIPSPAN(x,y,n,x1,n1,i);
524
525                if (DBG) fprintf(stderr, "WriteRGBSpan %d..%d (x1 %d)\n",
526                                 (int)i, (int)n1, (int)x1);
527
528                if (mask)
529                {
530                   for (;n1>0;i++,x1++,n1--)
531                      if (mask[i])
532                         WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 );
533                }
534                else
535                {
536                   for (;n1>0;i++,x1++,n1--)
537                      WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 );
538                }
539             }
540          HW_ENDCLIPLOOP();
541       }
542    HW_WRITE_UNLOCK();
543 }
544
545 static void TAG(WriteRGBAPixels)( struct gl_context *ctx,
546                                   struct gl_renderbuffer *rb,
547                                   GLuint n, const GLint x[], const GLint y[],
548                                   const void *values, const GLubyte mask[] )
549 {
550    HW_WRITE_LOCK()
551       {
552          const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
553          GLint i;
554          LOCAL_VARS;
555
556          if (DBG) fprintf(stderr, "WriteRGBAPixels\n");
557
558          HW_WRITE_CLIPLOOP()
559             {
560                if (mask)
561                {
562                   for (i=0;i<n;i++)
563                   {
564                      if (mask[i]) {
565                         const int fy = Y_FLIP(y[i]);
566                         if (CLIPPIXEL(x[i],fy))
567                            WRITE_RGBA( x[i], fy,
568                                        rgba[i][0], rgba[i][1],
569                                        rgba[i][2], rgba[i][3] );
570                      }
571                   }
572                }
573                else
574                {
575                   for (i=0;i<n;i++)
576                   {
577                      const int fy = Y_FLIP(y[i]);
578                      if (CLIPPIXEL(x[i],fy))
579                         WRITE_RGBA( x[i], fy,
580                                     rgba[i][0], rgba[i][1],
581                                     rgba[i][2], rgba[i][3] );
582                   }
583                }
584             }
585          HW_ENDCLIPLOOP();
586       }
587    HW_WRITE_UNLOCK();
588 }
589
590
591 static void TAG(WriteMonoRGBASpan)( struct gl_context *ctx,     
592                                     struct gl_renderbuffer *rb,
593                                     GLuint n, GLint x, GLint y, 
594                                     const void *value, const GLubyte mask[] )
595 {
596    HW_WRITE_LOCK()
597       {
598          const GLubyte *color = (const GLubyte *) value;
599          GLint x1;
600          GLint n1;
601          LOCAL_VARS;
602          INIT_MONO_PIXEL(p, color);
603
604          y = Y_FLIP( y );
605
606          if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n");
607
608          HW_WRITE_CLIPLOOP()
609             {
610                GLint i = 0;
611                CLIPSPAN(x,y,n,x1,n1,i);
612                if (mask)
613                {
614                   for (;n1>0;i++,x1++,n1--)
615                      if (mask[i])
616                         WRITE_PIXEL( x1, y, p );
617                }
618                else
619                {
620                   for (;n1>0;i++,x1++,n1--)
621                      WRITE_PIXEL( x1, y, p );
622                }
623             }
624          HW_ENDCLIPLOOP();
625       }
626    HW_WRITE_UNLOCK();
627 }
628
629
630 static void TAG(WriteMonoRGBAPixels)( struct gl_context *ctx,
631                                       struct gl_renderbuffer *rb,
632                                       GLuint n,
633                                       const GLint x[], const GLint y[],
634                                       const void *value,
635                                       const GLubyte mask[] ) 
636 {
637    HW_WRITE_LOCK()
638       {
639          const GLubyte *color = (const GLubyte *) value;
640          GLint i;
641          LOCAL_VARS;
642          INIT_MONO_PIXEL(p, color);
643
644          if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n");
645
646          HW_WRITE_CLIPLOOP()
647             {
648                if (mask)
649                {
650                   for (i=0;i<n;i++)
651                      if (mask[i]) {
652                         int fy = Y_FLIP(y[i]);
653                         if (CLIPPIXEL( x[i], fy ))
654                            WRITE_PIXEL( x[i], fy, p );
655                      }
656                }
657                else
658                {
659                   for (i=0;i<n;i++) {
660                      int fy = Y_FLIP(y[i]);
661                      if (CLIPPIXEL( x[i], fy ))
662                         WRITE_PIXEL( x[i], fy, p );
663                   }
664                }
665             }
666          HW_ENDCLIPLOOP();
667       }
668    HW_WRITE_UNLOCK();
669 }
670
671
672 static void TAG(ReadRGBASpan)( struct gl_context *ctx,
673                                struct gl_renderbuffer *rb,
674                                GLuint n, GLint x, GLint y, void *values)
675 {
676    HW_READ_LOCK()
677       {
678          GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
679          GLint x1,n1;
680          LOCAL_VARS;
681
682          y = Y_FLIP(y);
683
684          if (DBG) fprintf(stderr, "ReadRGBASpan\n");
685
686          HW_READ_CLIPLOOP()
687             {
688                GLint i = 0;
689                CLIPSPAN(x,y,n,x1,n1,i);
690                for (;n1>0;i++,x1++,n1--)
691                   READ_RGBA( rgba[i], x1, y );
692             }
693          HW_ENDCLIPLOOP();
694       }
695    HW_READ_UNLOCK();
696 }
697
698
699 #if defined(GET_PTR) && \
700    defined(USE_MMX_ASM) && \
701    (((SPANTMP_PIXEL_FMT == GL_BGRA) && \
702         (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)) || \
703     ((SPANTMP_PIXEL_FMT == GL_RGB) && \
704         (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5)))
705 static void TAG2(ReadRGBASpan,_MMX)( struct gl_context *ctx,
706                                      struct gl_renderbuffer *rb,
707                                      GLuint n, GLint x, GLint y, void *values)
708 {
709 #ifndef USE_INNER_EMMS
710    /* The EMMS instruction is directly in-lined here because using GCC's
711     * built-in _mm_empty function was found to utterly destroy performance.
712     */
713    __asm__ __volatile__( "emms" );
714 #endif
715
716    HW_READ_LOCK()
717      {
718         GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
719         GLint x1,n1;
720         LOCAL_VARS;
721
722         y = Y_FLIP(y);
723
724         if (DBG) fprintf(stderr, "ReadRGBASpan\n");
725
726         HW_READ_CLIPLOOP()
727           {
728              GLint i = 0;
729              CLIPSPAN(x,y,n,x1,n1,i);
730
731                {
732                   const void * src = GET_PTR( x1, y );
733 #if (SPANTMP_PIXEL_FMT == GL_RGB) && \
734                   (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5)
735                   _generic_read_RGBA_span_RGB565_MMX( src, rgba[i], n1 );
736 #else
737                   _generic_read_RGBA_span_BGRA8888_REV_MMX( src, rgba[i], n1 );
738 #endif
739                }
740           }
741         HW_ENDCLIPLOOP();
742      }
743    HW_READ_UNLOCK();
744 #ifndef USE_INNER_EMMS
745    __asm__ __volatile__( "emms" );
746 #endif
747 }
748 #endif
749
750
751 #if defined(GET_PTR) && \
752    defined(USE_SSE_ASM) && \
753    (SPANTMP_PIXEL_FMT == GL_BGRA) && \
754      (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
755 static void TAG2(ReadRGBASpan,_SSE2)( struct gl_context *ctx,
756                                       struct gl_renderbuffer *rb,
757                                       GLuint n, GLint x, GLint y,
758                                       void *values)
759 {
760    HW_READ_LOCK()
761      {
762         GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
763         GLint x1,n1;
764         LOCAL_VARS;
765
766         y = Y_FLIP(y);
767
768         if (DBG) fprintf(stderr, "ReadRGBASpan\n");
769
770         HW_READ_CLIPLOOP()
771           {
772              GLint i = 0;
773              CLIPSPAN(x,y,n,x1,n1,i);
774
775                {
776                   const void * src = GET_PTR( x1, y );
777                   _generic_read_RGBA_span_BGRA8888_REV_SSE2( src, rgba[i], n1 );
778                }
779           }
780         HW_ENDCLIPLOOP();
781      }
782    HW_READ_UNLOCK();
783 }
784 #endif
785
786 #if defined(GET_PTR) && \
787    defined(USE_SSE_ASM) && \
788    (SPANTMP_PIXEL_FMT == GL_BGRA) && \
789      (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
790 static void TAG2(ReadRGBASpan,_SSE)( struct gl_context *ctx,
791                                      struct gl_renderbuffer *rb,
792                                      GLuint n, GLint x, GLint y,
793                                      void *values)
794 {
795 #ifndef USE_INNER_EMMS
796    /* The EMMS instruction is directly in-lined here because using GCC's
797     * built-in _mm_empty function was found to utterly destroy performance.
798     */
799    __asm__ __volatile__( "emms" );
800 #endif
801
802    HW_READ_LOCK()
803      {
804         GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
805         GLint x1,n1;
806         LOCAL_VARS;
807
808         y = Y_FLIP(y);
809
810         if (DBG) fprintf(stderr, "ReadRGBASpan\n");
811
812         HW_READ_CLIPLOOP()
813           {
814              GLint i = 0;
815              CLIPSPAN(x,y,n,x1,n1,i);
816
817                {
818                   const void * src = GET_PTR( x1, y );
819                   _generic_read_RGBA_span_BGRA8888_REV_SSE( src, rgba[i], n1 );
820                }
821           }
822         HW_ENDCLIPLOOP();
823      }
824    HW_READ_UNLOCK();
825 #ifndef USE_INNER_EMMS
826    __asm__ __volatile__( "emms" );
827 #endif
828 }
829 #endif
830
831
832 static void TAG(ReadRGBAPixels)( struct gl_context *ctx,
833                                  struct gl_renderbuffer *rb,
834                                  GLuint n, const GLint x[], const GLint y[],
835                                  void *values )
836 {
837    HW_READ_LOCK()
838       {
839          GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
840          GLint i;
841          LOCAL_VARS;
842
843          if (DBG) fprintf(stderr, "ReadRGBAPixels\n");
844
845          HW_READ_CLIPLOOP()
846             {
847                for (i=0;i<n;i++) {
848                   int fy = Y_FLIP( y[i] );
849                      if (CLIPPIXEL( x[i], fy ))
850                         READ_RGBA( rgba[i], x[i], fy );
851                }
852             }
853          HW_ENDCLIPLOOP();
854       }
855    HW_READ_UNLOCK();
856 }
857
858 static void TAG(InitPointers)(struct gl_renderbuffer *rb)
859 {
860    rb->PutRow = TAG(WriteRGBASpan);
861    rb->PutRowRGB = TAG(WriteRGBSpan);
862    rb->PutMonoRow = TAG(WriteMonoRGBASpan);
863    rb->PutValues = TAG(WriteRGBAPixels);
864    rb->PutMonoValues = TAG(WriteMonoRGBAPixels);
865    rb->GetValues = TAG(ReadRGBAPixels);
866
867 #if defined(GET_PTR)
868 #if defined(USE_SSE_ASM) && \
869    (SPANTMP_PIXEL_FMT == GL_BGRA) && \
870      (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
871    if ( cpu_has_xmm2 ) {
872       if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "SSE2" );
873       rb->GetRow = TAG2(ReadRGBASpan, _SSE2);
874    }
875    else
876 #endif
877 #if defined(USE_SSE_ASM) && \
878    (SPANTMP_PIXEL_FMT == GL_BGRA) && \
879      (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
880    if ( cpu_has_xmm ) {
881       if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "SSE" );
882       rb->GetRow = TAG2(ReadRGBASpan, _SSE);
883    }
884    else
885 #endif
886 #if defined(USE_MMX_ASM) && \
887    (((SPANTMP_PIXEL_FMT == GL_BGRA) && \
888         (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)) || \
889     ((SPANTMP_PIXEL_FMT == GL_RGB) && \
890         (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5)))
891    if ( cpu_has_mmx ) {
892       if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "MMX" );
893       rb->GetRow = TAG2(ReadRGBASpan, _MMX);
894    }
895    else
896 #endif
897 #endif /* GET_PTR */
898    {
899       if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "C" );
900       rb->GetRow = TAG(ReadRGBASpan);
901    }
902
903 }
904
905
906 #undef INIT_MONO_PIXEL
907 #undef WRITE_PIXEL
908 #undef WRITE_RGBA
909 #undef READ_RGBA
910 #undef TAG
911 #undef TAG2
912 #undef GET_VALUE
913 #undef PUT_VALUE
914 #undef GET_PTR
915 #undef SPANTMP_PIXEL_FMT
916 #undef SPANTMP_PIXEL_TYPE