Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / s3v / s3v_span.c
1 /*
2 * Author: Max Lingua <sunmax@libero.it>
3 */
4
5 #include "s3v_context.h"
6 #include "s3v_lock.h"
7
8 #include "swrast/swrast.h"
9
10 #define _SPANLOCK 1
11 #define DBG 0
12
13 #define LOCAL_VARS \
14 s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
15 __DRIscreenPrivate *sPriv = vmesa->driScreen; \
16 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
17 driRenderbuffer *drb = (driRenderbuffer *) rb; \
18 GLuint cpp = drb->cpp; \
19 GLuint pitch = ( (drb->backBuffer) ? \
20 ((dPriv->w+31)&~31) * cpp \
21 : sPriv->fbWidth * cpp); \
22 GLuint height = dPriv->h; \
23 char *buf = (char *)(sPriv->pFB + drb->offset \
24 + (drb->backBuffer ? 0 : dPriv->x * cpp + dPriv->y * pitch));\
25 GLuint p; \
26 (void) p
27
28 /* FIXME! Depth/Stencil read/writes don't work ! */
29 #define LOCAL_DEPTH_VARS \
30 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
31 __DRIscreenPrivate *sPriv = vmesa->driScreen; \
32 driRenderbuffer *drb = (driRenderbuffer *) rb; \
33 GLuint pitch = drb->pitch; \
34 GLuint height = dPriv->h; \
35 char *buf = (char *)(sPriv->pFB + drb->offset); \
36 (void) pitch
37
38 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
39
40 #define Y_FLIP( _y ) (height - _y - 1)
41
42 #if _SPANLOCK /* OK, we lock */
43
44 #define HW_LOCK() \
45 s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
46 (void) vmesa; \
47 DMAFLUSH(); \
48 S3V_SIMPLE_FLUSH_LOCK(vmesa);
49 #define HW_UNLOCK() S3V_SIMPLE_UNLOCK(vmesa);
50
51 #else /* plz, don't lock */
52
53 #define HW_LOCK() \
54 s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
55 (void) vmesa; \
56 DMAFLUSH();
57 #define HW_UNLOCK()
58
59 #endif
60
61
62 /* ================================================================
63 * Color buffer
64 */
65
66 /* 16 bit, RGB565 color spanline and pixel functions
67 */
68 #define INIT_MONO_PIXEL(p, color) \
69 p = S3VIRGEPACKCOLOR555( color[0], color[1], color[2], color[3] )
70
71 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
72 do { \
73 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 7) | \
74 (((int)g & 0xf8) << 2) | \
75 (((int)b & 0xf8) >> 3)); \
76 DEBUG(("buf=0x%x drawOffset=0x%x dPriv->x=%i drb->cpp=%i dPriv->y=%i pitch=%i\n", \
77 sPriv->pFB, vmesa->drawOffset, dPriv->x, drb->cpp, dPriv->y, pitch)); \
78 DEBUG(("dPriv->w = %i\n", dPriv->w)); \
79 } while(0)
80
81 #define WRITE_PIXEL( _x, _y, p ) \
82 *(GLushort *)(buf + _x*2 + _y*pitch) = p
83
84 #define READ_RGBA( rgba, _x, _y ) \
85 do { \
86 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
87 rgba[0] = (p >> 7) & 0xf8; \
88 rgba[1] = (p >> 2) & 0xf8; \
89 rgba[2] = (p << 3) & 0xf8; \
90 rgba[3] = 0xff; /*
91 if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
92 if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
93 if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; */ \
94 } while (0)
95
96 #define TAG(x) s3v##x##_RGB555
97 #include "spantmp.h"
98
99
100 /* 32 bit, ARGB8888 color spanline and pixel functions
101 */
102
103 #undef INIT_MONO_PIXEL
104 #define INIT_MONO_PIXEL(p, color) \
105 p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
106
107 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
108 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
109 (g << 8) | \
110 (r << 16) | \
111 (a << 24) )
112
113 #define WRITE_PIXEL( _x, _y, p ) \
114 *(GLuint *)(buf + _x*4 + _y*pitch) = p
115
116 #define READ_RGBA( rgba, _x, _y ) \
117 do { \
118 GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
119 rgba[0] = (p >> 16) & 0xff; \
120 rgba[1] = (p >> 8) & 0xff; \
121 rgba[2] = (p >> 0) & 0xff; \
122 rgba[3] = (p >> 24) & 0xff; \
123 } while (0)
124
125 #define TAG(x) s3v##x##_ARGB8888
126 #include "spantmp.h"
127
128
129 /* 16 bit depthbuffer functions.
130 */
131 #define VALUE_TYPE GLushort
132
133 #define WRITE_DEPTH( _x, _y, d ) \
134 *(GLushort *)(buf + _x*2 + _y*dPriv->w*2) = d
135
136 #define READ_DEPTH( d, _x, _y ) \
137 d = *(GLushort *)(buf + _x*2 + _y*dPriv->w*2);
138
139 #define TAG(x) s3v##x##_z16
140 #include "depthtmp.h"
141
142
143
144
145 /* 32 bit depthbuffer functions.
146 */
147 #if 0
148 #define VALUE_TYPE GLuint
149
150 #define WRITE_DEPTH( _x, _y, d ) \
151 *(GLuint *)(buf + _x*4 + _y*pitch) = d;
152
153 #define READ_DEPTH( d, _x, _y ) \
154 d = *(GLuint *)(buf + _x*4 + _y*pitch);
155
156 #define TAG(x) s3v##x##_32
157 #include "depthtmp.h"
158 #endif
159
160
161 /* 24/8 bit interleaved depth/stencil functions
162 */
163 #if 0
164 #define VALUE_TYPE GLuint
165
166 #define WRITE_DEPTH( _x, _y, d ) { \
167 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
168 tmp &= 0xff; \
169 tmp |= (d) & 0xffffff00; \
170 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
171 }
172
173 #define READ_DEPTH( d, _x, _y ) \
174 d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff
175
176
177 #define TAG(x) s3v##x##_24_8
178 #include "depthtmp.h"
179
180 #define WRITE_STENCIL( _x, _y, d ) { \
181 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
182 tmp &= 0xffffff00; \
183 tmp |= d & 0xff; \
184 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
185 }
186
187 #define READ_STENCIL( d, _x, _y ) \
188 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff
189
190 #define TAG(x) s3v##x##_24_8
191 #include "stenciltmp.h"
192
193 #endif
194
195
196 /**
197 * Plug in the Get/Put routines for the given driRenderbuffer.
198 */
199 void
200 s3vSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
201 {
202 if (drb->Base.InternalFormat == GL_RGBA) {
203 if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
204 s3vInitPointers_RGB555(&drb->Base);
205 }
206 else {
207 s3vInitPointers_ARGB8888(&drb->Base);
208 }
209 }
210 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
211 s3vInitDepthPointers_z16(&drb->Base);
212 }
213 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
214 /* not done yet */
215 }
216 else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
217 /* not done yet */
218 }
219 }