Merge branch 'master' of git+ssh://keithw@git.freedesktop.org/git/mesa/mesa into...
[mesa.git] / src / mesa / drivers / dri / s3v / s3v_xmesa.c
1 /*
2 * Author: Max Lingua <sunmax@libero.it>
3 */
4
5 #include "s3v_context.h"
6 #include "s3v_vb.h"
7 #include "context.h"
8 #include "matrix.h"
9 #include "s3v_dri.h"
10 #include "framebuffer.h"
11 #include "renderbuffer.h"
12
13 #include "swrast/swrast.h"
14 #include "swrast_setup/swrast_setup.h"
15 #include "tnl/tnl.h"
16 #include "vbo/vbo.h"
17
18 /* #define DEBUG(str) printf str */
19
20 static GLboolean
21 s3vInitDriver(__DRIscreenPrivate *sPriv)
22 {
23 sPriv->private = (void *) s3vCreateScreen( sPriv );
24
25 if (!sPriv->private) {
26 s3vDestroyScreen( sPriv );
27 return GL_FALSE;
28 }
29
30 return GL_TRUE;
31 }
32
33 static void
34 s3vDestroyContext(__DRIcontextPrivate *driContextPriv)
35 {
36 s3vContextPtr vmesa = (s3vContextPtr)driContextPriv->driverPrivate;
37
38 if (vmesa) {
39 _swsetup_DestroyContext( vmesa->glCtx );
40 _tnl_DestroyContext( vmesa->glCtx );
41 _vbo_DestroyContext( vmesa->glCtx );
42 _swrast_DestroyContext( vmesa->glCtx );
43
44 s3vFreeVB( vmesa->glCtx );
45
46 /* free the Mesa context */
47 vmesa->glCtx->DriverCtx = NULL;
48 _mesa_destroy_context(vmesa->glCtx);
49
50 _mesa_free(vmesa);
51 driContextPriv->driverPrivate = NULL;
52 }
53 }
54
55
56 static GLboolean
57 s3vCreateBuffer( __DRIscreenPrivate *driScrnPriv,
58 __DRIdrawablePrivate *driDrawPriv,
59 const __GLcontextModes *mesaVis,
60 GLboolean isPixmap )
61 {
62 s3vScreenPtr screen = (s3vScreenPtr) driScrnPriv->private;
63
64 if (isPixmap) {
65 return GL_FALSE; /* not implemented */
66 }
67 else {
68 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
69
70 {
71 driRenderbuffer *frontRb
72 = driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
73 screen->frontOffset, screen->frontPitch,
74 driDrawPriv);
75 s3vSetSpanFunctions(frontRb, mesaVis);
76 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
77 }
78
79 if (mesaVis->doubleBufferMode) {
80 driRenderbuffer *backRb
81 = driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
82 screen->backOffset, screen->backPitch,
83 driDrawPriv);
84 s3vSetSpanFunctions(backRb, mesaVis);
85 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
86 backRb->backBuffer = GL_TRUE;
87 }
88
89 if (mesaVis->depthBits == 16) {
90 driRenderbuffer *depthRb
91 = driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, screen->cpp,
92 screen->depthOffset, screen->depthPitch,
93 driDrawPriv);
94 s3vSetSpanFunctions(depthRb, mesaVis);
95 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
96 }
97 else if (mesaVis->depthBits == 24) {
98 driRenderbuffer *depthRb
99 = driNewRenderbuffer(GL_DEPTH_COMPONENT24, NULL, screen->cpp,
100 screen->depthOffset, screen->depthPitch,
101 driDrawPriv);
102 s3vSetSpanFunctions(depthRb, mesaVis);
103 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
104 }
105
106 /* no h/w stencil yet?
107 if (mesaVis->stencilBits > 0) {
108 driRenderbuffer *stencilRb
109 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL,
110 screen->cpp, screen->depthOffset,
111 screen->depthPitch, driDrawPriv);
112 s3vSetSpanFunctions(stencilRb, mesaVis);
113 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
114 }
115 */
116
117 _mesa_add_soft_renderbuffers(fb,
118 GL_FALSE, /* color */
119 GL_FALSE, /* depth */
120 mesaVis->stencilBits > 0,
121 mesaVis->accumRedBits > 0,
122 GL_FALSE, /* alpha */
123 GL_FALSE /* aux */);
124 driDrawPriv->driverPrivate = (void *) fb;
125
126 return (driDrawPriv->driverPrivate != NULL);
127 }
128 }
129
130
131 static void
132 s3vDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
133 {
134 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
135 }
136
137 static void
138 s3vSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
139 {
140 __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
141 __DRIscreenPrivate *sPriv;
142 GLcontext *ctx;
143 s3vContextPtr vmesa;
144 s3vScreenPtr s3vscrn;
145
146 vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
147 sPriv = vmesa->driScreen;
148 s3vscrn = vmesa->s3vScreen;
149 ctx = vmesa->glCtx;
150
151 DEBUG(("*** s3vSwapBuffers ***\n"));
152
153 /* DMAFLUSH(); */
154
155 _mesa_notifySwapBuffers( ctx );
156
157 vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
158 /* driScrnPriv = vmesa->driScreen; */
159
160 /* if (vmesa->EnabledFlags & S3V_BACK_BUFFER) */
161
162 /* _mesa_notifySwapBuffers( ctx ); */
163 #if 1
164 {
165 int x0, y0, x1, y1;
166 /*
167 int nRect = dPriv->numClipRects;
168 XF86DRIClipRectPtr pRect = dPriv->pClipRects;
169
170 __DRIscreenPrivate *driScrnPriv = vmesa->driScreen;
171 */
172
173 /*
174 DEBUG(("s3vSwapBuffers: S3V_BACK_BUFFER = 1 - nClip = %i\n", nRect));
175 */
176 /* vmesa->drawOffset=vmesa->s3vScreen->backOffset; */
177
178 x0 = dPriv->x;
179 y0 = dPriv->y;
180
181 x1 = x0 + dPriv->w - 1;
182 y1 = y0 + dPriv->h - 1;
183
184 DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
185 DMAOUT(vmesa->s3vScreen->backOffset);
186 DMAOUT(0); /* 0xc0000000 */
187 DMAOUT( ((x0 << 16) | x1) );
188 DMAOUT( ((y0 << 16) | y1) );
189 DMAOUT( (vmesa->DestStride << 16) | vmesa->SrcStride );
190 DMAOUT( (~(0)) );
191 DMAOUT( (~(0)) );
192 DMAOUT(0);
193 DMAOUT(0);
194 /* FIXME */
195 DMAOUT(0);
196 DMAOUT(0);
197 DMAOUT( (0x01 | /* Autoexecute */
198 0x02 | /* clip */
199 0x04 | /* 16 bit */
200 0x20 | /* draw */
201 0x400 | /* word alignment (bit 10=1) */
202 (0x2 << 11) | /* offset = 1 byte */
203 (0xCC << 17) | /* rop #204 */
204 (0x3 << 25)) ); /* l-r, t-b */
205 DMAOUT(vmesa->ScissorWH);
206 DMAOUT( /* 0 */ vmesa->SrcXY );
207 DMAOUT( (dPriv->x << 16) | dPriv->y );
208 DMAFINISH();
209
210 DMAFLUSH();
211
212 vmesa->restore_primitive = -1;
213
214 }
215 #endif
216 }
217
218 static GLboolean
219 s3vMakeCurrent(__DRIcontextPrivate *driContextPriv,
220 __DRIdrawablePrivate *driDrawPriv,
221 __DRIdrawablePrivate *driReadPriv)
222 {
223 int x1,x2,y1,y2;
224 int cx, cy, cw, ch;
225 unsigned int src_stride, dest_stride;
226 int cl;
227
228 s3vContextPtr vmesa;
229 __DRIdrawablePrivate *dPriv = driDrawPriv;
230 vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
231
232 DEBUG(("s3vMakeCurrent\n"));
233
234 DEBUG(("dPriv->x=%i y=%i w=%i h=%i\n", dPriv->x, dPriv->y,
235 dPriv->w, dPriv->h));
236
237 if (driContextPriv) {
238 GET_CURRENT_CONTEXT(ctx);
239 s3vContextPtr oldVirgeCtx = ctx ? S3V_CONTEXT(ctx) : NULL;
240 s3vContextPtr newVirgeCtx = (s3vContextPtr) driContextPriv->driverPrivate;
241
242 if ( newVirgeCtx != oldVirgeCtx ) {
243
244 newVirgeCtx->dirty = ~0;
245 cl = 1;
246 DEBUG(("newVirgeCtx != oldVirgeCtx\n"));
247 /* s3vUpdateClipping(newVirgeCtx->glCtx ); */
248 }
249
250 if (newVirgeCtx->driDrawable != driDrawPriv) {
251 newVirgeCtx->driDrawable = driDrawPriv;
252 DEBUG(("driDrawable != driDrawPriv\n"));
253 s3vUpdateWindow ( newVirgeCtx->glCtx );
254 s3vUpdateViewportOffset( newVirgeCtx->glCtx );
255 /* s3vUpdateClipping(newVirgeCtx->glCtx ); */
256 }
257 /*
258 s3vUpdateWindow ( newVirgeCtx->glCtx );
259 s3vUpdateViewportOffset( newVirgeCtx->glCtx );
260 */
261
262 /*
263 _mesa_make_current( newVirgeCtx->glCtx,
264 (GLframebuffer *) driDrawPriv->driverPrivate,
265 (GLframebuffer *) driReadPriv->driverPrivate );
266
267 _mesa_set_viewport(newVirgeCtx->glCtx, 0, 0,
268 newVirgeCtx->driDrawable->w,
269 newVirgeCtx->driDrawable->h);
270 */
271
272 #if 0
273 newVirgeCtx->Window &= ~W_GIDMask;
274 newVirgeCtx->Window |= (driDrawPriv->index << 5);
275 CHECK_DMA_BUFFER(newVirgeCtx,1);
276 WRITE(newVirgeCtx->buf, S3VWindow, newVirgeCtx->Window);
277 #endif
278
279 newVirgeCtx->new_state |= S3V_NEW_WINDOW; /* FIXME */
280
281 _mesa_make_current( newVirgeCtx->glCtx,
282 (GLframebuffer *) driDrawPriv->driverPrivate,
283 (GLframebuffer *) driReadPriv->driverPrivate );
284
285 if (!newVirgeCtx->glCtx->Viewport.Width) {
286 _mesa_set_viewport(newVirgeCtx->glCtx, 0, 0,
287 driDrawPriv->w, driDrawPriv->h);
288
289 /* s3vUpdateClipping(newVirgeCtx->glCtx ); */
290 }
291
292 /*
293 if (cl) {
294 s3vUpdateClipping(newVirgeCtx->glCtx );
295 cl =0;
296 }
297 */
298
299 newVirgeCtx->new_state |= S3V_NEW_CLIP;
300
301 if (1) {
302 cx = dPriv->x;
303 cw = dPriv->w;
304 cy = dPriv->y;
305 ch = dPriv->h;
306 }
307
308 x1 = y1 = 0;
309 x2 = cw-1;
310 y2 = ch-1;
311
312 /* src_stride = vmesa->s3vScreen->w * vmesa->s3vScreen->cpp;
313 dest_stride = ((x2+31)&~31) * vmesa->s3vScreen->cpp; */
314 src_stride = vmesa->driScreen->fbWidth * 2;
315 dest_stride = ((x2+31)&~31) * 2;
316 } else {
317 _mesa_make_current( NULL, NULL, NULL );
318 }
319
320 return GL_TRUE;
321 }
322
323
324 static GLboolean
325 s3vUnbindContext( __DRIcontextPrivate *driContextPriv )
326 {
327 return GL_TRUE;
328 }
329
330
331 static struct __DriverAPIRec s3vAPI = {
332 s3vInitDriver,
333 s3vDestroyScreen,
334 s3vCreateContext,
335 s3vDestroyContext,
336 s3vCreateBuffer,
337 s3vDestroyBuffer,
338 s3vSwapBuffers,
339 s3vMakeCurrent,
340 s3vUnbindContext,
341 };
342
343
344 #if 0
345 /*
346 * This is the bootstrap function for the driver.
347 * The __driCreateScreen name is the symbol that libGL.so fetches.
348 * Return: pointer to a __DRIscreenPrivate.
349 */
350 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
351 int numConfigs, __GLXvisualConfig *config)
352 {
353 __DRIscreenPrivate *psp=NULL;
354
355 DEBUG(("__driCreateScreen: psp = %p\n", psp));
356 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &s3vAPI);
357 DEBUG(("__driCreateScreen: psp = %p\n", psp));
358 return (void *) psp;
359 }
360 #endif