533166ddbb3d6e9b9abf0cf1589ea21239b69ab6
[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
44 #define CLIPPIXEL( _x, _y ) \
45 ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
46
47
48 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
49 if ( _y < miny || _y >= maxy ) { \
50 _n1 = 0, _x1 = x; \
51 } else { \
52 _n1 = _n; \
53 _x1 = _x; \
54 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
55 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
56 }
57
58 #define Y_FLIP( _y ) (height - _y - 1)
59
60 #define HW_LOCK() \
61 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); \
62 FLUSH_DMA_BUFFER(gmesa); \
63 gammaGetLock( gmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); \
64 GAMMAHW_LOCK( gmesa );
65
66 #define HW_CLIPLOOP() \
67 do { \
68 __DRIdrawablePrivate *dPriv = gmesa->driDrawable; \
69 int _nc = dPriv->numClipRects; \
70 \
71 while ( _nc-- ) { \
72 int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
73 int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
74 int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
75 int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
76
77 #define HW_ENDCLIPLOOP() \
78 } \
79 } while (0)
80
81 #define HW_UNLOCK() GAMMAHW_UNLOCK( gmesa )
82
83
84
85 /* ================================================================
86 * Color buffer
87 */
88
89 /* 16 bit, RGB565 color spanline and pixel functions
90 */
91 #define INIT_MONO_PIXEL(p, color) \
92 p = PACK_COLOR_565( color[0], color[1], color[2] )
93
94 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
95 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
96 (((int)g & 0xfc) << 3) | \
97 (((int)b & 0xf8) >> 3))
98
99 #define WRITE_PIXEL( _x, _y, p ) \
100 *(GLushort *)(buf + _x*2 + _y*pitch) = p
101
102 #define READ_RGBA( rgba, _x, _y ) \
103 do { \
104 GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
105 rgba[0] = (p >> 8) & 0xf8; \
106 rgba[1] = (p >> 3) & 0xfc; \
107 rgba[2] = (p << 3) & 0xf8; \
108 rgba[3] = 0xff; \
109 if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
110 if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
111 if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \
112 } while (0)
113
114 #define TAG(x) gamma##x##_RGB565
115 #include "spantmp.h"
116
117
118 /* 32 bit, ARGB8888 color spanline and pixel functions
119 */
120
121 #undef INIT_MONO_PIXEL
122 #define INIT_MONO_PIXEL(p, color) \
123 p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
124
125 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
126 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
127 (g << 8) | \
128 (r << 16) | \
129 (a << 24) )
130
131 #define WRITE_PIXEL( _x, _y, p ) \
132 *(GLuint *)(buf + _x*4 + _y*pitch) = p
133
134 #define READ_RGBA( rgba, _x, _y ) \
135 do { \
136 GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
137 rgba[0] = (p >> 16) & 0xff; \
138 rgba[1] = (p >> 8) & 0xff; \
139 rgba[2] = (p >> 0) & 0xff; \
140 rgba[3] = (p >> 24) & 0xff; \
141 } while (0)
142
143 #define TAG(x) gamma##x##_ARGB8888
144 #include "spantmp.h"
145
146
147 /* 16 bit depthbuffer functions.
148 */
149 #define WRITE_DEPTH( _x, _y, d ) \
150 *(GLushort *)(buf + _x*2 + _y*pitch) = d;
151
152 #define READ_DEPTH( d, _x, _y ) \
153 d = *(GLushort *)(buf + _x*2 + _y*pitch);
154
155 #define TAG(x) gamma##x##_16
156 #include "depthtmp.h"
157
158
159
160 #if 0 /* Unused */
161 /* 32 bit depthbuffer functions.
162 */
163 #define WRITE_DEPTH( _x, _y, d ) \
164 *(GLuint *)(buf + _x*4 + _y*pitch) = d;
165
166 #define READ_DEPTH( d, _x, _y ) \
167 d = *(GLuint *)(buf + _x*4 + _y*pitch);
168
169 #define TAG(x) gamma##x##_32
170 #include "depthtmp.h"
171 #endif
172
173
174 /* 24/8 bit interleaved depth/stencil functions
175 */
176 #define WRITE_DEPTH( _x, _y, d ) { \
177 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
178 tmp &= 0xff; \
179 tmp |= (d) & 0xffffff00; \
180 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
181 }
182
183 #define READ_DEPTH( d, _x, _y ) \
184 d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff;
185
186
187 #define TAG(x) gamma##x##_24_8
188 #include "depthtmp.h"
189
190 #if 0
191 #define WRITE_STENCIL( _x, _y, d ) { \
192 GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
193 tmp &= 0xffffff00; \
194 tmp |= d & 0xff; \
195 *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
196 }
197
198 #define READ_STENCIL( d, _x, _y ) \
199 d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff;
200
201 #define TAG(x) gamma##x##_24_8
202 #include "stenciltmp.h"
203
204 static void gammaReadRGBASpan8888( const GLcontext *ctx,
205 GLuint n, GLint x, GLint y,
206 GLubyte rgba[][4])
207 {
208 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
209 gammaScreenPtr gammascrn = gmesa->gammaScreen;
210 uint32_t dwords1, dwords2, i = 0;
211 char *src = (char *)rgba[0];
212 GLuint read = n * gammascrn->cpp; /* Number of bytes we are expecting */
213 uint32_t data;
214
215 FLUSH_DMA_BUFFER(gmesa);
216 CHECK_DMA_BUFFER(gmesa, 16);
217 WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode & ~(LBReadSrcEnable | LBReadDstEnable));
218 WRITE(gmesa->buf, ColorDDAMode, ColorDDAEnable);
219 WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);
220 WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode & ~FBReadSrcEnable) | FBReadDstEnable | FBDataTypeColor);
221 WRITE(gmesa->buf, FilterMode, 0x200); /* Pass FBColorData */
222 WRITE(gmesa->buf, FBWriteMode, FBW_UploadColorData | FBWriteModeDisable);
223 WRITE(gmesa->buf, StartXSub, (x+n)<<16);
224 WRITE(gmesa->buf, StartXDom, x<<16);
225 WRITE(gmesa->buf, StartY, y<<16);
226 WRITE(gmesa->buf, GLINTCount, 1);
227 WRITE(gmesa->buf, dXDom, 0<<16);
228 WRITE(gmesa->buf, dXSub, 0<<16);
229 WRITE(gmesa->buf, dY, 1<<16);
230 WRITE(gmesa->buf, Render, PrimitiveTrapezoid);
231 FLUSH_DMA_BUFFER(gmesa);
232
233 moredata:
234
235 dwords1 = *(volatile uint32_t*)(void *)(((uint8_t*)gammascrn->regions[0].map) + (GlintOutFIFOWords));
236 dwords2 = *(volatile uint32_t*)(void *)(((uint8_t*)gammascrn->regions[2].map) + (GlintOutFIFOWords));
237
238 if (dwords1) {
239 memcpy(src, (char*)gammascrn->regions[1].map + 0x1000, dwords1 << 2);
240 src += dwords1 << 2;
241 read -= dwords1 << 2;
242 }
243 if (dwords2) {
244 memcpy(src, (char*)gammascrn->regions[3].map + 0x1000, dwords2 << 2);
245 src += dwords2 << 2;
246 read -= dwords2 << 2;
247 }
248
249 if (read)
250 goto moredata;
251
252 done:
253
254 CHECK_DMA_BUFFER(gmesa, 6);
255 WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
256 WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
257 WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
258 WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode);
259 WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
260 WRITE(gmesa->buf, FilterMode, 0x400);
261 }
262 #endif
263
264 static void gammaSetBuffer( GLcontext *ctx,
265 GLframebuffer *colorBuffer,
266 GLuint bufferBit )
267 {
268 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
269
270 switch ( bufferBit ) {
271 case DD_FRONT_LEFT_BIT:
272 gmesa->readOffset = 0;
273 break;
274 case DD_BACK_LEFT_BIT:
275 gmesa->readOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp;
276 break;
277 default:
278 _mesa_problem(ctx, "Unexpected buffer 0x%x in gammaSetBuffer()", bufferBit);
279 }
280 }
281
282
283 void gammaDDInitSpanFuncs( GLcontext *ctx )
284 {
285 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
286 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
287
288 swdd->SetBuffer = gammaSetBuffer;
289
290 switch ( gmesa->gammaScreen->cpp ) {
291 case 2:
292 swdd->WriteRGBASpan = gammaWriteRGBASpan_RGB565;
293 swdd->WriteRGBSpan = gammaWriteRGBSpan_RGB565;
294 swdd->WriteMonoRGBASpan = gammaWriteMonoRGBASpan_RGB565;
295 swdd->WriteRGBAPixels = gammaWriteRGBAPixels_RGB565;
296 swdd->WriteMonoRGBAPixels = gammaWriteMonoRGBAPixels_RGB565;
297 swdd->ReadRGBASpan = gammaReadRGBASpan_RGB565;
298 swdd->ReadRGBAPixels = gammaReadRGBAPixels_RGB565;
299 break;
300
301 case 4:
302 swdd->WriteRGBASpan = gammaWriteRGBASpan_ARGB8888;
303 swdd->WriteRGBSpan = gammaWriteRGBSpan_ARGB8888;
304 swdd->WriteMonoRGBASpan = gammaWriteMonoRGBASpan_ARGB8888;
305 swdd->WriteRGBAPixels = gammaWriteRGBAPixels_ARGB8888;
306 swdd->WriteMonoRGBAPixels = gammaWriteMonoRGBAPixels_ARGB8888;
307 #if 1
308 swdd->ReadRGBASpan = gammaReadRGBASpan_ARGB8888;
309 #else
310 swdd->ReadRGBASpan = gammaReadRGBASpan8888;
311 #endif
312 swdd->ReadRGBAPixels = gammaReadRGBAPixels_ARGB8888;
313 break;
314
315 default:
316 break;
317 }
318
319 switch ( gmesa->glCtx->Visual.depthBits ) {
320 case 16:
321 swdd->ReadDepthSpan = gammaReadDepthSpan_16;
322 swdd->WriteDepthSpan = gammaWriteDepthSpan_16;
323 swdd->ReadDepthPixels = gammaReadDepthPixels_16;
324 swdd->WriteDepthPixels = gammaWriteDepthPixels_16;
325 break;
326
327 case 24:
328 swdd->ReadDepthSpan = gammaReadDepthSpan_24_8;
329 swdd->WriteDepthSpan = gammaWriteDepthSpan_24_8;
330 swdd->ReadDepthPixels = gammaReadDepthPixels_24_8;
331 swdd->WriteDepthPixels = gammaWriteDepthPixels_24_8;
332
333 #if 0
334 swdd->ReadStencilSpan = gammaReadStencilSpan_24_8;
335 swdd->WriteStencilSpan = gammaWriteStencilSpan_24_8;
336 swdd->ReadStencilPixels = gammaReadStencilPixels_24_8;
337 swdd->WriteStencilPixels = gammaWriteStencilPixels_24_8;
338 #endif
339 break;
340
341 default:
342 break;
343 }
344 }