blob: 663dabdb914c2a91852b9eea15991378b0372d9b [file] [log] [blame]
/*
* Author: Max Lingua <sunmax@libero.it>
*/
#include "s3v_context.h"
#include "s3v_vb.h"
#include "context.h"
#include "matrix.h"
#include "s3v_dri.h"
#include "framebuffer.h"
#include "renderbuffer.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "vbo/vbo.h"
/* #define DEBUG(str) printf str */
static const __DRIconfig **
s3vInitScreen(__DRIscreen *sPriv)
{
sPriv->private = (void *) s3vCreateScreen( sPriv );
if (!sPriv->private) {
s3vDestroyScreen( sPriv );
return GL_FALSE;
}
return NULL;
}
static void
s3vDestroyContext(__DRIcontextPrivate *driContextPriv)
{
s3vContextPtr vmesa = (s3vContextPtr)driContextPriv->driverPrivate;
if (vmesa) {
_swsetup_DestroyContext( vmesa->glCtx );
_tnl_DestroyContext( vmesa->glCtx );
_vbo_DestroyContext( vmesa->glCtx );
_swrast_DestroyContext( vmesa->glCtx );
s3vFreeVB( vmesa->glCtx );
/* free the Mesa context */
vmesa->glCtx->DriverCtx = NULL;
_mesa_destroy_context(vmesa->glCtx);
_mesa_free(vmesa);
driContextPriv->driverPrivate = NULL;
}
}
static GLboolean
s3vCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
s3vScreenPtr screen = (s3vScreenPtr) driScrnPriv->private;
if (isPixmap) {
return GL_FALSE; /* not implemented */
}
else {
struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
{
driRenderbuffer *frontRb
= driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
screen->frontOffset, screen->frontPitch,
driDrawPriv);
s3vSetSpanFunctions(frontRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
}
if (mesaVis->doubleBufferMode) {
driRenderbuffer *backRb
= driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
screen->backOffset, screen->backPitch,
driDrawPriv);
s3vSetSpanFunctions(backRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
backRb->backBuffer = GL_TRUE;
}
if (mesaVis->depthBits == 16) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, screen->cpp,
screen->depthOffset, screen->depthPitch,
driDrawPriv);
s3vSetSpanFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
else if (mesaVis->depthBits == 24) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT24, NULL, screen->cpp,
screen->depthOffset, screen->depthPitch,
driDrawPriv);
s3vSetSpanFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
/* no h/w stencil yet?
if (mesaVis->stencilBits > 0) {
driRenderbuffer *stencilRb
= driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL,
screen->cpp, screen->depthOffset,
screen->depthPitch, driDrawPriv);
s3vSetSpanFunctions(stencilRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
}
*/
_mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* color */
GL_FALSE, /* depth */
mesaVis->stencilBits > 0,
mesaVis->accumRedBits > 0,
GL_FALSE, /* alpha */
GL_FALSE /* aux */);
driDrawPriv->driverPrivate = (void *) fb;
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
s3vDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
}
static void
s3vSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
{
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
__DRIscreenPrivate *sPriv;
GLcontext *ctx;
s3vContextPtr vmesa;
s3vScreenPtr s3vscrn;
vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
sPriv = vmesa->driScreen;
s3vscrn = vmesa->s3vScreen;
ctx = vmesa->glCtx;
DEBUG(("*** s3vSwapBuffers ***\n"));
/* DMAFLUSH(); */
_mesa_notifySwapBuffers( ctx );
vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
/* driScrnPriv = vmesa->driScreen; */
/* if (vmesa->EnabledFlags & S3V_BACK_BUFFER) */
/* _mesa_notifySwapBuffers( ctx ); */
#if 1
{
int x0, y0, x1, y1;
/*
int nRect = dPriv->numClipRects;
XF86DRIClipRectPtr pRect = dPriv->pClipRects;
__DRIscreenPrivate *driScrnPriv = vmesa->driScreen;
*/
/*
DEBUG(("s3vSwapBuffers: S3V_BACK_BUFFER = 1 - nClip = %i\n", nRect));
*/
/* vmesa->drawOffset=vmesa->s3vScreen->backOffset; */
x0 = dPriv->x;
y0 = dPriv->y;
x1 = x0 + dPriv->w - 1;
y1 = y0 + dPriv->h - 1;
DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
DMAOUT(vmesa->s3vScreen->backOffset);
DMAOUT(0); /* 0xc0000000 */
DMAOUT( ((x0 << 16) | x1) );
DMAOUT( ((y0 << 16) | y1) );
DMAOUT( (vmesa->DestStride << 16) | vmesa->SrcStride );
DMAOUT( (~(0)) );
DMAOUT( (~(0)) );
DMAOUT(0);
DMAOUT(0);
/* FIXME */
DMAOUT(0);
DMAOUT(0);
DMAOUT( (0x01 | /* Autoexecute */
0x02 | /* clip */
0x04 | /* 16 bit */
0x20 | /* draw */
0x400 | /* word alignment (bit 10=1) */
(0x2 << 11) | /* offset = 1 byte */
(0xCC << 17) | /* rop #204 */
(0x3 << 25)) ); /* l-r, t-b */
DMAOUT(vmesa->ScissorWH);
DMAOUT( /* 0 */ vmesa->SrcXY );
DMAOUT( (dPriv->x << 16) | dPriv->y );
DMAFINISH();
DMAFLUSH();
vmesa->restore_primitive = -1;
}
#endif
}
static GLboolean
s3vMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
int x1,x2,y1,y2;
int cx, cy, cw, ch;
unsigned int src_stride, dest_stride;
int cl;
s3vContextPtr vmesa;
__DRIdrawablePrivate *dPriv = driDrawPriv;
vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
DEBUG(("s3vMakeCurrent\n"));
DEBUG(("dPriv->x=%i y=%i w=%i h=%i\n", dPriv->x, dPriv->y,
dPriv->w, dPriv->h));
if (driContextPriv) {
GET_CURRENT_CONTEXT(ctx);
s3vContextPtr oldVirgeCtx = ctx ? S3V_CONTEXT(ctx) : NULL;
s3vContextPtr newVirgeCtx = (s3vContextPtr) driContextPriv->driverPrivate;
if ( newVirgeCtx != oldVirgeCtx ) {
newVirgeCtx->dirty = ~0;
cl = 1;
DEBUG(("newVirgeCtx != oldVirgeCtx\n"));
/* s3vUpdateClipping(newVirgeCtx->glCtx ); */
}
if (newVirgeCtx->driDrawable != driDrawPriv) {
newVirgeCtx->driDrawable = driDrawPriv;
DEBUG(("driDrawable != driDrawPriv\n"));
s3vUpdateWindow ( newVirgeCtx->glCtx );
s3vUpdateViewportOffset( newVirgeCtx->glCtx );
/* s3vUpdateClipping(newVirgeCtx->glCtx ); */
}
/*
s3vUpdateWindow ( newVirgeCtx->glCtx );
s3vUpdateViewportOffset( newVirgeCtx->glCtx );
*/
/*
_mesa_make_current( newVirgeCtx->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );
_mesa_set_viewport(newVirgeCtx->glCtx, 0, 0,
newVirgeCtx->driDrawable->w,
newVirgeCtx->driDrawable->h);
*/
#if 0
newVirgeCtx->Window &= ~W_GIDMask;
newVirgeCtx->Window |= (driDrawPriv->index << 5);
CHECK_DMA_BUFFER(newVirgeCtx,1);
WRITE(newVirgeCtx->buf, S3VWindow, newVirgeCtx->Window);
#endif
newVirgeCtx->new_state |= S3V_NEW_WINDOW; /* FIXME */
_mesa_make_current( newVirgeCtx->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );
if (!newVirgeCtx->glCtx->Viewport.Width) {
_mesa_set_viewport(newVirgeCtx->glCtx, 0, 0,
driDrawPriv->w, driDrawPriv->h);
/* s3vUpdateClipping(newVirgeCtx->glCtx ); */
}
/*
if (cl) {
s3vUpdateClipping(newVirgeCtx->glCtx );
cl =0;
}
*/
newVirgeCtx->new_state |= S3V_NEW_CLIP;
if (1) {
cx = dPriv->x;
cw = dPriv->w;
cy = dPriv->y;
ch = dPriv->h;
}
x1 = y1 = 0;
x2 = cw-1;
y2 = ch-1;
/* src_stride = vmesa->s3vScreen->w * vmesa->s3vScreen->cpp;
dest_stride = ((x2+31)&~31) * vmesa->s3vScreen->cpp; */
src_stride = vmesa->driScreen->fbWidth * 2;
dest_stride = ((x2+31)&~31) * 2;
} else {
_mesa_make_current( NULL, NULL, NULL );
}
return GL_TRUE;
}
static GLboolean
s3vUnbindContext( __DRIcontextPrivate *driContextPriv )
{
return GL_TRUE;
}
const struct __DriverAPIRec driDriverAPI = {
.InitScreen = s3vInitScreen,
.DestroyScreen = s3vDestroyScreen,
.CreateContext = s3vCreateContext,
.DestroyContext = s3vDestroyContext,
.CreateBuffer = s3vCreateBuffer,
.DestroyBuffer = s3vDestroyBuffer,
.SwapBuffers = s3vSwapBuffers,
.MakeCurrent = s3vMakeCurrent,
.UnbindContext = s3vUnbindContext,
};