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