summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/s3v
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/s3v')
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_tex.c544
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_xmesa.c341
2 files changed, 885 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/s3v/s3v_tex.c b/src/mesa/drivers/dri/s3v/s3v_tex.c
new file mode 100644
index 0000000000..517f5e5ca7
--- /dev/null
+++ b/src/mesa/drivers/dri/s3v/s3v_tex.c
@@ -0,0 +1,544 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/simple_list.h"
+#include "main/enums.h"
+#include "main/mm.h"
+#include "main/texstore.h"
+#include "main/teximage.h"
+#include "swrast/swrast.h"
+
+#include "s3v_context.h"
+#include "s3v_tex.h"
+
+
+extern void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
+extern void s3vDestroyTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
+
+/*
+static GLuint s3vComputeLodBias(GLfloat bias)
+{
+#if TEX_DEBUG_ON
+ DEBUG_TEX(("*** s3vComputeLodBias ***\n"));
+#endif
+ return bias;
+}
+*/
+
+static void s3vSetTexWrapping(s3vContextPtr vmesa,
+ s3vTextureObjectPtr t,
+ GLenum wraps, GLenum wrapt)
+{
+ GLuint t0 = t->TextureCMD;
+ GLuint cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vSetTexWrapping: #%i ***\n", ++times));
+#endif
+
+
+ t0 &= ~TEX_WRAP_MASK;
+ cmd &= ~TEX_WRAP_MASK;
+
+ if ((wraps != GL_CLAMP) || (wrapt != GL_CLAMP)) {
+ DEBUG(("TEX_WRAP_ON\n"));
+ t0 |= TEX_WRAP_ON;
+ cmd |= TEX_WRAP_ON;
+ }
+
+ cmd |= TEX_WRAP_ON; /* FIXME: broken if off */
+ t->TextureCMD = t0;
+ vmesa->CMD = cmd;
+}
+
+
+static void s3vSetTexFilter(s3vContextPtr vmesa,
+ s3vTextureObjectPtr t,
+ GLenum minf, GLenum magf)
+{
+ GLuint t0 = t->TextureCMD;
+ GLuint cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vSetTexFilter: #%i ***\n", ++times));
+#endif
+
+ t0 &= ~TEX_FILTER_MASK;
+ cmd &= ~TEX_FILTER_MASK;
+
+ switch (minf) {
+ case GL_NEAREST:
+ DEBUG(("GL_NEAREST\n"));
+ t0 |= NEAREST;
+ cmd |= NEAREST;
+ break;
+ case GL_LINEAR:
+ DEBUG(("GL_LINEAR\n"));
+ t0 |= LINEAR;
+ cmd |= LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ DEBUG(("GL_MIPMAP_NEAREST\n"));
+ t0 |= MIP_NEAREST;
+ cmd |= MIP_NEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ DEBUG(("GL_LINEAR_MIPMAP_NEAREST\n"));
+ t0 |= LINEAR_MIP_NEAREST;
+ cmd |= LINEAR_MIP_NEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ DEBUG(("GL_NEAREST_MIPMAP_LINEAR\n"));
+ t0 |= MIP_LINEAR;
+ cmd |= MIP_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ DEBUG(("GL_LINEAR_MIPMAP_LINEAR\n"));
+ t0 |= LINEAR_MIP_LINEAR;
+ cmd |= LINEAR_MIP_LINEAR;
+ break;
+ default:
+ break;
+ }
+ /* FIXME: bilinear? */
+
+#if 0
+ switch (magf) {
+ case GL_NEAREST:
+ break;
+ case GL_LINEAR:
+ break;
+ default:
+ break;
+ }
+#endif
+
+ t->TextureCMD = t0;
+
+ DEBUG(("CMD was = 0x%x\n", vmesa->CMD));
+ DEBUG(("CMD is = 0x%x\n", cmd));
+
+ vmesa->CMD = cmd;
+ /* CMDCHANGE(); */
+}
+
+
+static void s3vSetTexBorderColor(s3vContextPtr vmesa,
+ s3vTextureObjectPtr t,
+ const GLfloat color[4])
+{
+ GLubyte c[4];
+ CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vSetTexBorderColor: #%i ***\n", ++times));
+#endif
+
+ /*FIXME: it should depend on tex col format */
+ /* switch(t0 ... t->TextureColorMode) */
+
+ /* case TEX_COL_ARGB1555: */
+ t->TextureBorderColor = S3VIRGEPACKCOLOR555(c[0], c[1], c[2], c[3]);
+
+ DEBUG(("TextureBorderColor = 0x%x\n", t->TextureBorderColor));
+
+ vmesa->TextureBorderColor = t->TextureBorderColor;
+}
+
+static void s3vTexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT(ctx);
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vTexParameter: #%i ***\n", ++times));
+#endif
+
+ if (!t) return;
+
+ /* Can't do the update now as we don't know whether to flush
+ * vertices or not. Setting vmesa->new_state means that
+ * s3vUpdateTextureState() will be called before any triangles are
+ * rendered. If a statechange has occurred, it will be detected at
+ * that point, and buffered vertices flushed.
+ */
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ s3vSetTexFilter( vmesa, t, tObj->MinFilter, tObj->MagFilter );
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ s3vSetTexWrapping( vmesa, t, tObj->WrapS, tObj->WrapT );
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ /* This isn't the most efficient solution but there doesn't appear to
+ * be a nice alternative for Virge. Since there's no LOD clamping,
+ * we just have to rely on loading the right subset of mipmap levels
+ * to simulate a clamped LOD.
+ */
+ s3vSwapOutTexObj( vmesa, t );
+ break;
+
+ default:
+ return;
+ }
+
+ if (t == vmesa->CurrentTexObj[0])
+ vmesa->dirty |= S3V_UPLOAD_TEX0;
+
+#if 0
+ if (t == vmesa->CurrentTexObj[1]) {
+ vmesa->dirty |= S3V_UPLOAD_TEX1;
+ }
+#endif
+}
+
+
+static void s3vTexEnv( GLcontext *ctx, GLenum target,
+ GLenum pname, const GLfloat *param )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+ GLuint unit = ctx->Texture.CurrentUnit;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vTexEnv: #%i ***\n", ++times));
+#endif
+
+ /* Only one env color. Need a fallback if env colors are different
+ * and texture setup references env color in both units.
+ */
+ switch (pname) {
+ case GL_TEXTURE_ENV_COLOR: {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLfloat *fc = texUnit->EnvColor;
+ GLuint r, g, b, a, col;
+ CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
+ CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
+ CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
+ CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
+
+ col = ((a << 24) |
+ (r << 16) |
+ (g << 8) |
+ (b << 0));
+
+ break;
+ }
+ case GL_TEXTURE_ENV_MODE:
+ vmesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
+ break;
+ case GL_TEXTURE_LOD_BIAS_EXT: {
+/*
+ struct gl_texture_object *tObj =
+ ctx->Texture.Unit[unit]._Current;
+
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+*/
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void s3vTexImage1D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *pack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vTexImage1D: #%i ***\n", ++times));
+#endif
+
+#if 1
+ if (t) {
+#if _TEXFLUSH
+ DMAFLUSH();
+#endif
+ s3vSwapOutTexObj( vmesa, t );
+/*
+ s3vDestroyTexObj( vmesa, t );
+ texObj->DriverData = 0;
+*/
+ }
+#endif
+ _mesa_store_teximage1d( ctx, target, level, internalFormat,
+ width, border, format, type,
+ pixels, pack, texObj, texImage );
+}
+
+static void s3vTexSubImage1D( GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *pack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vTexSubImage1D: #%i ***\n", ++times));
+#endif
+
+#if 1
+ if (t) {
+#if _TEXFLUSH
+ DMAFLUSH();
+#endif
+ s3vSwapOutTexObj( vmesa, t );
+/*
+ s3vDestroyTexObj( vmesa, t );
+ texObj->DriverData = 0;
+*/
+ }
+#endif
+ _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
+ format, type, pixels, pack, texObj,
+ texImage);
+}
+
+static void s3vTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vTexImage2D: #%i ***\n", ++times));
+#endif
+
+#if 1
+ if (t) {
+#if _TEXFLUSH
+ DMAFLUSH();
+#endif
+ s3vSwapOutTexObj( vmesa, t );
+/*
+ s3vDestroyTexObj( vmesa, t );
+ texObj->DriverData = 0;
+*/
+ }
+#endif
+ _mesa_store_teximage2d( ctx, target, level, internalFormat,
+ width, height, border, format, type,
+ pixels, packing, texObj, texImage );
+}
+
+static void s3vTexSubImage2D( GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vTexSubImage2D: #%i ***\n", ++times));
+#endif
+
+#if 1
+ if (t) {
+#if _TEXFLUSH
+ DMAFLUSH();
+#endif
+ s3vSwapOutTexObj( vmesa, t );
+/*
+ s3vDestroyTexObj( vmesa, t );
+ texObj->DriverData = 0;
+*/
+ }
+#endif
+ _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
+ height, format, type, pixels, packing, texObj,
+ texImage);
+}
+
+
+static void s3vBindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
+{
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
+ GLuint cmd = vmesa->CMD;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vBindTexture: #%i ***\n", ++times));
+#endif
+
+ if (!t) {
+/*
+ GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
+*/
+ t = CALLOC_STRUCT(s3v_texture_object_t);
+
+ /* Initialize non-image-dependent parts of the state:
+ */
+ t->globj = tObj;
+#if 0
+ if (target == GL_TEXTURE_2D) {
+ } else
+ if (target == GL_TEXTURE_1D) {
+ }
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ t->TextureFormat = (TF_LittleEndian |
+#else
+ t->TextureFormat = (TF_BigEndian |
+#endif
+#endif
+ t->dirty_images = ~0;
+
+ tObj->DriverData = t;
+ make_empty_list( t );
+#if 0
+ s3vSetTexWrapping( vmesa, t, tObj->WrapS, tObj->WrapT );
+ s3vSetTexFilter( vmesa, t, tObj->MinFilter, tObj->MagFilter );
+ s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
+#endif
+ }
+
+ cmd = vmesa->CMD & ~MIP_MASK;
+ vmesa->dirty |= S3V_UPLOAD_TEX0;
+ vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
+ vmesa->TexStride = t->Pitch;
+ cmd |= MIPMAP_LEVEL(t->WidthLog2);
+ vmesa->CMD = cmd;
+ vmesa->restore_primitive = -1;
+#if 0
+ printf("t->TextureBaseAddr[0] = 0x%x\n", t->TextureBaseAddr[0]);
+ printf("t->TextureBaseAddr[1] = 0x%x\n", t->TextureBaseAddr[1]);
+ printf("t->TextureBaseAddr[2] = 0x%x\n", t->TextureBaseAddr[2]);
+#endif
+}
+
+
+static void s3vDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vDeleteTexture: #%i ***\n", ++times));
+#endif
+
+ if (t) {
+ s3vContextPtr vmesa = S3V_CONTEXT( ctx );
+
+#if _TEXFLUSH
+ if (vmesa) {
+ DMAFLUSH();
+ }
+#endif
+
+ s3vDestroyTexObj( vmesa, t );
+ tObj->DriverData = 0;
+
+ }
+}
+
+static GLboolean s3vIsTextureResident( GLcontext *ctx,
+ struct gl_texture_object *tObj )
+{
+ s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vIsTextureResident: #%i ***\n", ++times));
+#endif
+
+ return (t && t->MemBlock);
+}
+
+static void s3vInitTextureObjects( GLcontext *ctx )
+{
+ /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
+ struct gl_texture_object *texObj;
+ GLuint tmp = ctx->Texture.CurrentUnit;
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vInitTextureObjects: #%i ***\n", ++times));
+#endif
+
+#if 1
+ ctx->Texture.CurrentUnit = 0;
+
+ texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_1D_INDEX];
+ s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );
+
+ texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
+ s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
+#endif
+
+#if 0
+ ctx->Texture.CurrentUnit = 1;
+
+ texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_1D_INDEX];
+ s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );
+
+ texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_2D_INDEX];
+ s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
+#endif
+
+ ctx->Texture.CurrentUnit = tmp;
+}
+
+
+void s3vInitTextureFuncs( GLcontext *ctx )
+{
+#if TEX_DEBUG_ON
+ static unsigned int times=0;
+ DEBUG_TEX(("*** s3vInitTextureFuncs: #%i ***\n", ++times));
+#endif
+
+ ctx->Driver.TexEnv = s3vTexEnv;
+ ctx->Driver.TexImage2D = s3vTexImage2D;
+ ctx->Driver.TexSubImage2D = s3vTexSubImage2D;
+ ctx->Driver.BindTexture = s3vBindTexture;
+ ctx->Driver.DeleteTexture = s3vDeleteTexture;
+ ctx->Driver.TexParameter = s3vTexParameter;
+ ctx->Driver.UpdateTexturePalette = 0;
+ ctx->Driver.IsTextureResident = s3vIsTextureResident;
+
+ s3vInitTextureObjects( ctx );
+}
diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
new file mode 100644
index 0000000000..f1e123d676
--- /dev/null
+++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c
@@ -0,0 +1,341 @@
+/*
+ * Author: Max Lingua <sunmax@libero.it>
+ */
+
+#include "s3v_context.h"
+#include "s3v_vb.h"
+#include "s3v_dri.h"
+#include "main/context.h"
+#include "main/matrix.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "main/viewport.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(MESA_FORMAT_ARGB8888, 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(MESA_FORMAT_ARGB8888, 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(MESA_FORMAT_Z16, 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(MESA_FORMAT_Z24_S8, 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(MESA_FORMAT_S8, 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_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
+}
+
+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,
+};