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