2 * Author: Max Lingua <sunmax@libero.it>
5 #include "s3v_context.h"
10 #include "framebuffer.h"
11 #include "renderbuffer.h"
13 #include "swrast/swrast.h"
14 #include "swrast_setup/swrast_setup.h"
16 #include "array_cache/acache.h"
18 /* #define DEBUG(str) printf str */
21 s3vInitDriver(__DRIscreenPrivate
*sPriv
)
23 sPriv
->private = (void *) s3vCreateScreen( sPriv
);
25 if (!sPriv
->private) {
26 s3vDestroyScreen( sPriv
);
34 s3vDestroyContext(__DRIcontextPrivate
*driContextPriv
)
36 s3vContextPtr vmesa
= (s3vContextPtr
)driContextPriv
->driverPrivate
;
39 _swsetup_DestroyContext( vmesa
->glCtx
);
40 _tnl_DestroyContext( vmesa
->glCtx
);
41 _ac_DestroyContext( vmesa
->glCtx
);
42 _swrast_DestroyContext( vmesa
->glCtx
);
44 s3vFreeVB( vmesa
->glCtx
);
46 /* free the Mesa context */
47 vmesa
->glCtx
->DriverCtx
= NULL
;
48 _mesa_destroy_context(vmesa
->glCtx
);
51 driContextPriv
->driverPrivate
= NULL
;
57 s3vCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
58 __DRIdrawablePrivate
*driDrawPriv
,
59 const __GLcontextModes
*mesaVis
,
62 s3vScreenPtr screen
= (s3vScreenPtr
) driScrnPriv
->private;
65 return GL_FALSE
; /* not implemented */
68 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
71 driRenderbuffer
*frontRb
72 = driNewRenderbuffer(GL_RGBA
, NULL
, screen
->cpp
,
73 screen
->frontOffset
, screen
->frontPitch
,
75 s3vSetSpanFunctions(frontRb
, mesaVis
);
76 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
79 if (mesaVis
->doubleBufferMode
) {
80 driRenderbuffer
*backRb
81 = driNewRenderbuffer(GL_RGBA
, NULL
, screen
->cpp
,
82 screen
->backOffset
, screen
->backPitch
,
84 s3vSetSpanFunctions(backRb
, mesaVis
);
85 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
86 backRb
->backBuffer
= GL_TRUE
;
89 if (mesaVis
->depthBits
== 16) {
90 driRenderbuffer
*depthRb
91 = driNewRenderbuffer(GL_DEPTH_COMPONENT16
, NULL
, screen
->cpp
,
92 screen
->depthOffset
, screen
->depthPitch
,
94 s3vSetSpanFunctions(depthRb
, mesaVis
);
95 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
97 else if (mesaVis
->depthBits
== 24) {
98 driRenderbuffer
*depthRb
99 = driNewRenderbuffer(GL_DEPTH_COMPONENT24
, NULL
, screen
->cpp
,
100 screen
->depthOffset
, screen
->depthPitch
,
102 s3vSetSpanFunctions(depthRb
, mesaVis
);
103 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
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);
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 */
124 driDrawPriv
->driverPrivate
= (void *) fb
;
126 return (driDrawPriv
->driverPrivate
!= NULL
);
132 s3vDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
134 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
138 s3vSwapBuffers(__DRIdrawablePrivate
*drawablePrivate
)
140 __DRIdrawablePrivate
*dPriv
= (__DRIdrawablePrivate
*) drawablePrivate
;
141 __DRIscreenPrivate
*sPriv
;
144 s3vScreenPtr s3vscrn
;
146 vmesa
= (s3vContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
147 sPriv
= vmesa
->driScreen
;
148 s3vscrn
= vmesa
->s3vScreen
;
151 DEBUG(("*** s3vSwapBuffers ***\n"));
155 _mesa_notifySwapBuffers( ctx
);
157 vmesa
= (s3vContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
158 /* driScrnPriv = vmesa->driScreen; */
160 /* if (vmesa->EnabledFlags & S3V_BACK_BUFFER) */
162 /* _mesa_notifySwapBuffers( ctx ); */
167 int nRect = dPriv->numClipRects;
168 XF86DRIClipRectPtr pRect = dPriv->pClipRects;
170 __DRIscreenPrivate *driScrnPriv = vmesa->driScreen;
174 DEBUG(("s3vSwapBuffers: S3V_BACK_BUFFER = 1 - nClip = %i\n", nRect));
176 /* vmesa->drawOffset=vmesa->s3vScreen->backOffset; */
181 x1
= x0
+ dPriv
->w
- 1;
182 y1
= y0
+ dPriv
->h
- 1;
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
);
197 DMAOUT( (0x01 | /* Autoexecute */
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
);
212 vmesa
->restore_primitive
= -1;
219 s3vMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
220 __DRIdrawablePrivate
*driDrawPriv
,
221 __DRIdrawablePrivate
*driReadPriv
)
225 unsigned int src_stride
, dest_stride
;
229 __DRIdrawablePrivate
*dPriv
= driDrawPriv
;
230 vmesa
= (s3vContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
232 DEBUG(("s3vMakeCurrent\n"));
234 DEBUG(("dPriv->x=%i y=%i w=%i h=%i\n", dPriv
->x
, dPriv
->y
,
235 dPriv
->w
, dPriv
->h
));
237 if (driContextPriv
) {
238 GET_CURRENT_CONTEXT(ctx
);
239 s3vContextPtr oldVirgeCtx
= ctx
? S3V_CONTEXT(ctx
) : NULL
;
240 s3vContextPtr newVirgeCtx
= (s3vContextPtr
) driContextPriv
->driverPrivate
;
242 if ( newVirgeCtx
!= oldVirgeCtx
) {
244 newVirgeCtx
->dirty
= ~0;
246 DEBUG(("newVirgeCtx != oldVirgeCtx\n"));
247 /* s3vUpdateClipping(newVirgeCtx->glCtx ); */
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 ); */
258 s3vUpdateWindow ( newVirgeCtx->glCtx );
259 s3vUpdateViewportOffset( newVirgeCtx->glCtx );
263 _mesa_make_current( newVirgeCtx->glCtx,
264 (GLframebuffer *) driDrawPriv->driverPrivate,
265 (GLframebuffer *) driReadPriv->driverPrivate );
267 _mesa_set_viewport(newVirgeCtx->glCtx, 0, 0,
268 newVirgeCtx->driDrawable->w,
269 newVirgeCtx->driDrawable->h);
273 newVirgeCtx
->Window
&= ~W_GIDMask
;
274 newVirgeCtx
->Window
|= (driDrawPriv
->index
<< 5);
275 CHECK_DMA_BUFFER(newVirgeCtx
,1);
276 WRITE(newVirgeCtx
->buf
, S3VWindow
, newVirgeCtx
->Window
);
279 newVirgeCtx
->new_state
|= S3V_NEW_WINDOW
; /* FIXME */
281 _mesa_make_current( newVirgeCtx
->glCtx
,
282 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
283 (GLframebuffer
*) driReadPriv
->driverPrivate
);
285 if (!newVirgeCtx
->glCtx
->Viewport
.Width
) {
286 _mesa_set_viewport(newVirgeCtx
->glCtx
, 0, 0,
287 driDrawPriv
->w
, driDrawPriv
->h
);
289 /* s3vUpdateClipping(newVirgeCtx->glCtx ); */
294 s3vUpdateClipping(newVirgeCtx->glCtx );
299 newVirgeCtx
->new_state
|= S3V_NEW_CLIP
;
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;
317 _mesa_make_current( NULL
, NULL
, NULL
);
325 s3vUnbindContext( __DRIcontextPrivate
*driContextPriv
)
331 static struct __DriverAPIRec s3vAPI
= {
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.
350 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
351 int numConfigs
, __GLXvisualConfig
*config
)
353 __DRIscreenPrivate
*psp
=NULL
;
355 DEBUG(("__driCreateScreen: psp = %p\n", psp
));
356 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &s3vAPI
);
357 DEBUG(("__driCreateScreen: psp = %p\n", psp
));