66cc961c64f90d7de4aa6c4c967b86e7ed6e8580
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_span.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_span.c,v 1.4 2002/11/05 17:46:07 tsi Exp $ */
2
3 #include "gamma_context.h"
4 #include "gamma_lock.h"
5 #include "colormac.h"
6
7 #include "swrast/swrast.h"
8
9 #define DBG 0
10
11 #define LOCAL_VARS \
12 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); \
13 gammaScreenPtr gammascrn = gmesa->gammaScreen; \
14 __DRIscreenPrivate *sPriv = gmesa->driScreen; \
15 __DRIdrawablePrivate *dPriv = gmesa->driDrawable; \
16 GLuint pitch = sPriv->fbWidth * gammascrn->cpp; \
17 GLuint height = dPriv->h; \
18 char *buf = (char *)(sPriv->pFB + \
19 gmesa->drawOffset + \
20 (dPriv->x * gammascrn->cpp) + \
21 (dPriv->y * pitch)); \
22 char *read_buf = (char *)(sPriv->pFB + \
23 gmesa->readOffset + \
24 (dPriv->x * gammascrn->cpp) + \
25 (dPriv->y * pitch)); \
26 GLuint p; \
27 (void) read_buf; (void) buf; (void) p
28
29 /* FIXME! Depth/Stencil read/writes don't work ! */
30 #define LOCAL_DEPTH_VARS \
31 gammaScreenPtr gammascrn = gmesa->gammaScreen; \
32 __DRIdrawablePrivate *dPriv = gmesa->driDrawable; \
33 __DRIscreenPrivate *sPriv = gmesa->driScreen; \
34 GLuint pitch = gammascrn->depthPitch; \
35 GLuint height = dPriv->h; \
36 char *buf = (char *)(sPriv->pFB + \
37 gammascrn->depthOffset + \
38 dPriv->x * gammascrn->cpp + \
39 dPriv->y * pitch)
40
41 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
42
43 #define Y_FLIP( _y ) (height - _y - 1)
44
45 #define HW_LOCK() \
46 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); \
47 FLUSH_DMA_BUFFER(gmesa); \
48 gammaGetLock( gmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); \
49 GAMMAHW_LOCK( gmesa );
50
51 #define HW_UNLOCK() GAMMAHW_UNLOCK( gmesa )
52
53
54
55 /* ================================================================
56 * Color buffer
57 */
58
59 /* 16 bit, RGB565 color spanline and pixel functions
60 */
61 #define INIT_MONO_PIXEL(p, color) \
62 p = PACK_COLOR_565( color[0], color[1], color[2] )
63
64 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
65 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
66 (((int)g & 0xfc) << 3) | \
67 (((int)b & 0xf8) >> 3))
68
69 #define WRITE_PIXEL( _x, _y, p ) \
70 *(GLushort *)(buf + _x*2 + _y*pitch) = p
71
72 #define READ_RGBA( rgba, _x, _y ) \
73 do { \
74 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
75 rgba[0] = (p >> 8) & 0xf8; \
76 rgba[1] = (p >> 3) & 0xfc; \
77 rgba[2] = (p << 3) & 0xf8; \
78 rgba[3] = 0xff; \
79 if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
80 if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
81 if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \
82 } while (0)
83
84 #define TAG(x) gamma##x##_RGB565
85 #include "spantmp.h"
86
87
88 /* 32 bit, ARGB8888 color spanline and pixel functions
89 */
90
91 #undef INIT_MONO_PIXEL
92 #define INIT_MONO_PIXEL(p, color) \
93 p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
94
95 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
96 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
97 (g << 8) | \
98 (r << 16) | \
99 (a << 24) )
100
101 #define WRITE_PIXEL( _x, _y, p ) \
102 *(GLuint *)(buf + _x*4 + _y*pitch) = p
103
104 #define READ_RGBA( rgba, _x, _y ) \
105 do { \
106 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
107 rgba[0] = (p >> 16) & 0xff; \
108 rgba[1] = (p >> 8) & 0xff; \
109 rgba[2] = (p >> 0) & 0xff; \
110 rgba[3] = (p >> 24) & 0xff; \
111 } while (0)
112
113 #define TAG(x) gamma##x##_ARGB8888
114 #include "spantmp.h"
115
116
117 /* 16 bit depthbuffer functions.
118 */
119 #define WRITE_DEPTH( _x, _y, d ) \
120 *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
121
122 #define READ_DEPTH( d, _x, _y ) \
123 d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
124
125 #define TAG(x) gamma##x##_16
126 #include "depthtmp.h"
127
128
129 #if 0 /* Unused */
130 /* 32 bit depthbuffer functions.
131 */
132 #define WRITE_DEPTH( _x, _y, d ) \
133 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = d;
134
135 #define READ_DEPTH( d, _x, _y ) \
136 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch);
137
138 #define TAG(x) gamma##x##_32
139 #include "depthtmp.h"
140 #endif
141
142
143 /* 24/8 bit interleaved depth/stencil functions
144 */
145 #define WRITE_DEPTH( _x, _y, d ) { \
146 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
147 tmp &= 0xff; \
148 tmp |= (d) & 0xffffff00; \
149 *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
150 }
151
152 #define READ_DEPTH( d, _x, _y ) \
153 d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & ~0xff;
154
155
156 #define TAG(x) gamma##x##_24_8
157 #include "depthtmp.h"
158
159 #if 0
160 #define WRITE_STENCIL( _x, _y, d ) { \
161 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
162 tmp &= 0xffffff00; \
163 tmp |= d & 0xff; \
164 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
165 }
166
167 #define READ_STENCIL( d, _x, _y ) \
168 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
169
170 #define TAG(x) gamma##x##_24_8
171 #include "stenciltmp.h"
172
173 static void gammaReadRGBASpan8888( const GLcontext *ctx,
174 GLuint n, GLint x, GLint y,
175 GLubyte rgba[][4])
176 {
177 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
178 gammaScreenPtr gammascrn = gmesa->gammaScreen;
179 u_int32_t dwords1, dwords2, i = 0;
180 char *src = (char *)rgba[0];
181 GLuint read = n * gammascrn->cpp; /* Number of bytes we are expecting */
182 u_int32_t data;
183
184 FLUSH_DMA_BUFFER(gmesa);
185 CHECK_DMA_BUFFER(gmesa, 16);
186 WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode & ~(LBReadSrcEnable | LBReadDstEnable));
187 WRITE(gmesa->buf, ColorDDAMode, ColorDDAEnable);
188 WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);
189 WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode & ~FBReadSrcEnable) | FBReadDstEnable | FBDataTypeColor);
190 WRITE(gmesa->buf, FilterMode, 0x200); /* Pass FBColorData */
191 WRITE(gmesa->buf, FBWriteMode, FBW_UploadColorData | FBWriteModeDisable);
192 WRITE(gmesa->buf, StartXSub, (x+n)<<16);
193 WRITE(gmesa->buf, StartXDom, x<<16);
194 WRITE(gmesa->buf, StartY, y<<16);
195 WRITE(gmesa->buf, GLINTCount, 1);
196 WRITE(gmesa->buf, dXDom, 0<<16);
197 WRITE(gmesa->buf, dXSub, 0<<16);
198 WRITE(gmesa->buf, dY, 1<<16);
199 WRITE(gmesa->buf, Render, PrimitiveTrapezoid);
200 FLUSH_DMA_BUFFER(gmesa);
201
202 moredata:
203
204 dwords1 = *(volatile u_int32_t*)(void *)(((u_int8_t*)gammascrn->regions[0].map) + (GlintOutFIFOWords));
205 dwords2 = *(volatile u_int32_t*)(void *)(((u_int8_t*)gammascrn->regions[2].map) + (GlintOutFIFOWords));
206
207 if (dwords1) {
208 memcpy(src, (char*)gammascrn->regions[1].map + 0x1000, dwords1 << 2);
209 src += dwords1 << 2;
210 read -= dwords1 << 2;
211 }
212 if (dwords2) {
213 memcpy(src, (char*)gammascrn->regions[3].map + 0x1000, dwords2 << 2);
214 src += dwords2 << 2;
215 read -= dwords2 << 2;
216 }
217
218 if (read)
219 goto moredata;
220
221 done:
222
223 CHECK_DMA_BUFFER(gmesa, 6);
224 WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
225 WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
226 WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
227 WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode);
228 WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
229 WRITE(gmesa->buf, FilterMode, 0x400);
230 }
231 #endif
232
233 static void gammaSetBuffer( GLcontext *ctx,
234 GLframebuffer *colorBuffer,
235 GLuint bufferBit )
236 {
237 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
238
239 switch ( bufferBit ) {
240 case BUFFER_BIT_FRONT_LEFT:
241 gmesa->readOffset = 0;
242 break;
243 case BUFFER_BIT_BACK_LEFT:
244 gmesa->readOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp;
245 break;
246 default:
247 _mesa_problem(ctx, "Unexpected buffer 0x%x in gammaSetBuffer()", bufferBit);
248 }
249 }
250
251
252 void gammaDDInitSpanFuncs( GLcontext *ctx )
253 {
254 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
255 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
256
257 swdd->SetBuffer = gammaSetBuffer;
258
259 switch ( gmesa->gammaScreen->cpp ) {
260 case 2:
261 swdd->WriteRGBASpan = gammaWriteRGBASpan_RGB565;
262 swdd->WriteRGBSpan = gammaWriteRGBSpan_RGB565;
263 swdd->WriteMonoRGBASpan = gammaWriteMonoRGBASpan_RGB565;
264 swdd->WriteRGBAPixels = gammaWriteRGBAPixels_RGB565;
265 swdd->WriteMonoRGBAPixels = gammaWriteMonoRGBAPixels_RGB565;
266 swdd->ReadRGBASpan = gammaReadRGBASpan_RGB565;
267 swdd->ReadRGBAPixels = gammaReadRGBAPixels_RGB565;
268 break;
269
270 case 4:
271 swdd->WriteRGBASpan = gammaWriteRGBASpan_ARGB8888;
272 swdd->WriteRGBSpan = gammaWriteRGBSpan_ARGB8888;
273 swdd->WriteMonoRGBASpan = gammaWriteMonoRGBASpan_ARGB8888;
274 swdd->WriteRGBAPixels = gammaWriteRGBAPixels_ARGB8888;
275 swdd->WriteMonoRGBAPixels = gammaWriteMonoRGBAPixels_ARGB8888;
276 #if 1
277 swdd->ReadRGBASpan = gammaReadRGBASpan_ARGB8888;
278 #else
279 swdd->ReadRGBASpan = gammaReadRGBASpan8888;
280 #endif
281 swdd->ReadRGBAPixels = gammaReadRGBAPixels_ARGB8888;
282 break;
283
284 default:
285 break;
286 }
287
288 switch ( gmesa->glCtx->Visual.depthBits ) {
289 case 16:
290 swdd->ReadDepthSpan = gammaReadDepthSpan_16;
291 swdd->WriteDepthSpan = gammaWriteDepthSpan_16;
292 swdd->ReadDepthPixels = gammaReadDepthPixels_16;
293 swdd->WriteDepthPixels = gammaWriteDepthPixels_16;
294 break;
295
296 case 24:
297 swdd->ReadDepthSpan = gammaReadDepthSpan_24_8;
298 swdd->WriteDepthSpan = gammaWriteDepthSpan_24_8;
299 swdd->ReadDepthPixels = gammaReadDepthPixels_24_8;
300 swdd->WriteDepthPixels = gammaWriteDepthPixels_24_8;
301
302 #if 0
303 swdd->ReadStencilSpan = gammaReadStencilSpan_24_8;
304 swdd->WriteStencilSpan = gammaWriteStencilSpan_24_8;
305 swdd->ReadStencilPixels = gammaReadStencilPixels_24_8;
306 swdd->WriteStencilPixels = gammaWriteStencilPixels_24_8;
307 #endif
308 break;
309
310 default:
311 break;
312 }
313 }