summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/trident
diff options
context:
space:
mode:
authorAdam Jackson <[email protected]>2004-12-16 19:26:23 +0000
committerAdam Jackson <[email protected]>2004-12-16 19:26:23 +0000
commitc403bcb8a7be437976d5adce41189fff1e7f690f (patch)
treefcd53d612d1725eb2609c49031e04da54a52370b /src/mesa/drivers/dri/trident
parent8662c5d98febd8efaf5f8ee47d34c7fcfd597ce3 (diff)
Import s3virge and trident drivers. Not functional yet; no Makefile, no DRI-aware DDX.
Diffstat (limited to 'src/mesa/drivers/dri/trident')
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.c419
-rw-r--r--src/mesa/drivers/dri/trident/trident_context.h209
-rw-r--r--src/mesa/drivers/dri/trident/trident_dd.c127
-rw-r--r--src/mesa/drivers/dri/trident/trident_state.c552
-rw-r--r--src/mesa/drivers/dri/trident/trident_tris.c1112
-rw-r--r--src/mesa/drivers/dri/trident/trident_vb.c435
6 files changed, 2854 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c
new file mode 100644
index 00000000000..168e7d1fc43
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_context.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_dri.h"
+#include "trident_context.h"
+#include "trident_lock.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+#include "context.h"
+#include "simple_list.h"
+#include "mem.h"
+#include "matrix.h"
+#include "extensions.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+#include "simple_list.h"
+#include "mem.h"
+#include "mm.h"
+
+static const struct gl_pipeline_stage *trident_pipeline[] = {
+ &_tnl_vertex_transform_stage,
+ &_tnl_normal_transform_stage,
+ &_tnl_lighting_stage,
+ &_tnl_texgen_stage,
+ &_tnl_texture_transform_stage,
+ &_tnl_render_stage,
+ 0,
+};
+
+
+GLboolean tridentCreateContext( Display *dpy, const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ GLcontext *ctx, *shareCtx;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ tridentContextPtr tmesa;
+ tridentScreenPtr tridentscrn;
+#if 0
+ drm_trident_sarea_t *saPriv=(drm_trident_sarea_t *)(((char*)sPriv->pSAREA)+
+ sizeof(XF86DRISAREARec));
+#endif
+
+ tmesa = (tridentContextPtr) CALLOC( sizeof(*tmesa) );
+ if ( !tmesa ) return GL_FALSE;
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((tridentContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+
+ tmesa->glCtx = _mesa_create_context(glVisual, shareCtx, tmesa, GL_TRUE);
+ if (!tmesa->glCtx) {
+ FREE(tmesa);
+ return GL_FALSE;
+ }
+
+ tmesa->display = dpy;
+
+ tmesa->driContext = driContextPriv;
+ tmesa->driScreen = sPriv;
+ tmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+ tmesa->hHWContext = driContextPriv->hHWContext;
+ tmesa->driHwLock = &sPriv->pSAREA->lock;
+ tmesa->driFd = sPriv->fd;
+#if 0
+ tmesa->sarea = saPriv;
+#endif
+
+ tridentscrn = tmesa->tridentScreen = (tridentScreenPtr)(sPriv->private);
+
+ ctx = tmesa->glCtx;
+
+ ctx->Const.MaxTextureLevels = 13; /* 4K by 4K? Is that right? */
+ ctx->Const.MaxTextureUnits = 1; /* Permedia 3 */
+
+ ctx->Const.MinLineWidth = 0.0;
+ ctx->Const.MaxLineWidth = 255.0;
+
+ ctx->Const.MinLineWidthAA = 0.0;
+ ctx->Const.MaxLineWidthAA = 65536.0;
+
+ ctx->Const.MinPointSize = 0.0;
+ ctx->Const.MaxPointSize = 255.0;
+
+ ctx->Const.MinPointSizeAA = 0.5; /* 4x4 quality mode */
+ ctx->Const.MaxPointSizeAA = 16.0;
+ ctx->Const.PointSizeGranularity = 0.25;
+
+#if 0
+ tmesa->texHeap = mmInit( 0, tmesa->tridentScreen->textureSize );
+
+ make_empty_list(&tmesa->TexObjList);
+ make_empty_list(&tmesa->SwappedOut);
+
+ tmesa->CurrentTexObj[0] = 0;
+ tmesa->CurrentTexObj[1] = 0; /* Permedia 3, second texture */
+
+ tmesa->RenderIndex = ~0;
+#endif
+
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext( ctx );
+ _ac_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ /* Install the customized pipeline:
+ */
+ _tnl_destroy_pipeline( ctx );
+ _tnl_install_pipeline( ctx, trident_pipeline );
+
+ /* Configure swrast to match hardware characteristics:
+ */
+ _swrast_allow_pixel_fog( ctx, GL_FALSE );
+ _swrast_allow_vertex_fog( ctx, GL_TRUE );
+
+ tridentInitVB( ctx );
+ tridentDDInitExtensions( ctx );
+ tridentDDInitDriverFuncs( ctx );
+ tridentDDInitStateFuncs( ctx );
+#if 0
+ tridentDDInitSpanFuncs( ctx );
+ tridentDDInitTextureFuncs( ctx );
+#endif
+ tridentDDInitTriFuncs( ctx );
+ tridentDDInitState( tmesa );
+
+ driContextPriv->driverPrivate = (void *)tmesa;
+
+ UNLOCK_HARDWARE(tmesa);
+
+ return GL_TRUE;
+}
+
+static void
+tridentDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ tridentContextPtr tmesa = (tridentContextPtr)driContextPriv->driverPrivate;
+
+ if (tmesa) {
+ _swsetup_DestroyContext( tmesa->glCtx );
+ _tnl_DestroyContext( tmesa->glCtx );
+ _ac_DestroyContext( tmesa->glCtx );
+ _swrast_DestroyContext( tmesa->glCtx );
+
+ /* free the Mesa context */
+ tmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context(tmesa->glCtx);
+
+ Xfree(tmesa);
+ driContextPriv->driverPrivate = NULL;
+ }
+}
+
+
+static GLboolean
+tridentCreateBuffer( Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap )
+{
+ if (isPixmap) {
+ return GL_FALSE; /* not implemented */
+ }
+ else {
+ driDrawPriv->driverPrivate = (void *)
+ _mesa_create_framebuffer(mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->stencilBits > 0,
+ mesaVis->accumRedBits > 0,
+ mesaVis->alphaBits > 0
+ );
+ return (driDrawPriv->driverPrivate != NULL);
+ }
+}
+
+
+static void
+tridentDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+}
+
+static void
+tridentSwapBuffers(Display *dpy, void *drawablePrivate)
+{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ (void) dpy;
+
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ tridentContextPtr tmesa;
+ GLcontext *ctx;
+ tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
+ ctx = tmesa->glCtx;
+ if (ctx->Visual.doubleBufferMode) {
+ _mesa_swapbuffers( ctx ); /* flush pending rendering comands */
+ tridentCopyBuffer( dPriv );
+ }
+ }
+ else {
+ /* XXX this shouldn't be an error but we can't handle it for now */
+ _mesa_problem(NULL, "tridentSwapBuffers: drawable has no context!\n");
+ }
+}
+
+static GLboolean
+tridentMakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ if (driContextPriv) {
+ GET_CURRENT_CONTEXT(ctx);
+ tridentContextPtr oldCtx = ctx ? TRIDENT_CONTEXT(ctx) : NULL;
+ tridentContextPtr newCtx = (tridentContextPtr) driContextPriv->driverPrivate;
+
+ if ( newCtx != oldCtx ) {
+ newCtx->dirty = ~0;
+ }
+
+ if (newCtx->driDrawable != driDrawPriv) {
+ newCtx->driDrawable = driDrawPriv;
+#if 0
+ tridentUpdateWindow ( newCtx->glCtx );
+ tridentUpdateViewportOffset( newCtx->glCtx );
+#endif
+ }
+
+ newCtx->drawOffset = newCtx->tridentScreen->backOffset;
+ newCtx->drawPitch = newCtx->tridentScreen->backPitch;
+
+ _mesa_make_current2( newCtx->glCtx,
+ (GLframebuffer *) driDrawPriv->driverPrivate,
+ (GLframebuffer *) driReadPriv->driverPrivate );
+
+ if (!newCtx->glCtx->Viewport.Width) {
+ _mesa_set_viewport(newCtx->glCtx, 0, 0,
+ driDrawPriv->w, driDrawPriv->h);
+ }
+ } else {
+ _mesa_make_current( 0, 0 );
+ }
+ return GL_TRUE;
+}
+
+
+static GLboolean
+tridentUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+static GLboolean
+tridentOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+ return GL_TRUE;
+}
+
+static GLboolean
+tridentCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+{
+ return GL_TRUE;
+}
+
+
+tridentScreenPtr tridentCreateScreen( __DRIscreenPrivate *sPriv )
+{
+ TRIDENTDRIPtr tDRIPriv = (TRIDENTDRIPtr)sPriv->pDevPriv;
+ tridentScreenPtr tridentScreen;
+ int i;
+
+#if 0
+ /* Check the DRI version */
+ {
+ int major, minor, patch;
+ if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) {
+ if ( major != 3 || minor != 1 || patch < 0 ) {
+ __driUtilMessage( "r128 DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch );
+ return GL_FALSE;
+ }
+ }
+ }
+
+ /* Check that the DDX driver version is compatible */
+ if ( sPriv->ddxMajor != 4 ||
+ sPriv->ddxMinor != 0 ||
+ sPriv->ddxPatch < 0 ) {
+ __driUtilMessage( "r128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
+ return GL_FALSE;
+ }
+
+ /* Check that the DRM driver version is compatible */
+ if ( sPriv->drmMajor != 2 ||
+ sPriv->drmMinor != 1 ||
+ sPriv->drmPatch < 0 ) {
+ __driUtilMessage( "r128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
+ return GL_FALSE;
+ }
+#endif
+
+ /* Allocate the private area */
+ tridentScreen = (tridentScreenPtr) CALLOC( sizeof(*tridentScreen) );
+ if ( !tridentScreen ) return NULL;
+
+ tridentScreen->driScreen = sPriv;
+
+ tridentScreen->frontOffset = tDRIPriv->frontOffset;
+ tridentScreen->backOffset = tDRIPriv->backOffset;
+ tridentScreen->depthOffset = tDRIPriv->depthOffset;
+ tridentScreen->frontPitch = tDRIPriv->frontPitch;
+ tridentScreen->backPitch = tDRIPriv->backPitch;
+ tridentScreen->depthPitch = tDRIPriv->depthPitch;
+ tridentScreen->width = tDRIPriv->width;
+ tridentScreen->height = tDRIPriv->height;
+
+printf("%d %d\n",tridentScreen->width,tridentScreen->height);
+printf("%d %d\n",tridentScreen->frontPitch,tridentScreen->backPitch);
+printf("offset 0x%x 0x%x\n",tridentScreen->backOffset,tridentScreen->depthOffset);
+
+ tridentScreen->mmio.handle = tDRIPriv->regs;
+ tridentScreen->mmio.size = 0x20000;
+
+ if (drmMap(sPriv->fd,
+ tridentScreen->mmio.handle, tridentScreen->mmio.size,
+ (drmAddressPtr)&tridentScreen->mmio.map)) {
+ FREE(tridentScreen);
+ return GL_FALSE;
+ }
+printf("MAPPED at 0x%x\n",tridentScreen->mmio.map);
+
+ return tridentScreen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+void tridentDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+ tridentScreenPtr tridentScreen = (tridentScreenPtr)sPriv->private;
+
+ FREE(tridentScreen);
+}
+static GLboolean
+tridentInitDriver(__DRIscreenPrivate *sPriv)
+{
+ sPriv->private = (void *) tridentCreateScreen( sPriv );
+
+ if (!sPriv->private) {
+ tridentDestroyScreen( sPriv );
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static struct __DriverAPIRec tridentAPI = {
+ tridentInitDriver,
+ tridentDestroyScreen,
+ tridentCreateContext,
+ tridentDestroyContext,
+ tridentCreateBuffer,
+ tridentDestroyBuffer,
+ tridentSwapBuffers,
+ tridentMakeCurrent,
+ tridentUnbindContext,
+ tridentOpenFullScreen,
+ tridentCloseFullScreen
+};
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return: pointer to a __DRIscreenPrivate.
+ */
+void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
+ int numConfigs, __GLXvisualConfig *config)
+{
+ __DRIscreenPrivate *psp;
+ psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tridentAPI);
+ return (void *) psp;
+}
+
+void __driRegisterExtensions(void)
+{
+ /* No extensions */
+}
diff --git a/src/mesa/drivers/dri/trident/trident_context.h b/src/mesa/drivers/dri/trident/trident_context.h
new file mode 100644
index 00000000000..ee098e5e7da
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_context.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#ifndef _TRIDENT_CONTEXT_H_
+#define _TRIDENT_CONTEXT_H_
+
+#include "compiler.h"
+#include "dri_util.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "drm.h"
+#include "mm.h"
+
+#define SUBPIXEL_X (0.0F)
+#define SUBPIXEL_Y (0.125F)
+
+#define _TRIDENT_NEW_VERTEX (_NEW_TEXTURE | \
+ _DD_NEW_TRI_UNFILLED | \
+ _DD_NEW_TRI_LIGHT_TWOSIDE)
+
+#define TRIDENT_FALLBACK_TEXTURE 0x01
+#define TRIDENT_FALLBACK_DRAW_BUFFER 0x02
+
+#define TRIDENT_NEW_CLIP 0x01
+
+#define TRIDENT_UPLOAD_COMMAND_D 0x00000001
+#define TRIDENT_UPLOAD_CONTEXT 0x04000000
+#define TRIDENT_UPLOAD_CLIPRECTS 0x80000000
+
+#define TAG(x) trident##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+struct trident_context;
+typedef struct trident_context tridentContextRec;
+typedef struct trident_context *tridentContextPtr;
+
+typedef void (*trident_quad_func)( tridentContextPtr,
+ const tridentVertex *,
+ const tridentVertex *,
+ const tridentVertex *,
+ const tridentVertex * );
+typedef void (*trident_tri_func)( tridentContextPtr,
+ const tridentVertex *,
+ const tridentVertex *,
+ const tridentVertex * );
+typedef void (*trident_line_func)( tridentContextPtr,
+ const tridentVertex *,
+ const tridentVertex * );
+typedef void (*trident_point_func)( tridentContextPtr,
+ const tridentVertex * );
+
+typedef struct {
+ drmHandle handle; /* Handle to the DRM region */
+ drmSize size; /* Size of the DRM region */
+ unsigned char *map; /* Mapping of the DRM region */
+} tridentRegionRec, *tridentRegionPtr;
+
+typedef struct {
+ __DRIscreenPrivate *driScreen; /* Back pointer to DRI screen */
+
+ drmBufMapPtr buffers;
+
+ unsigned int frontOffset;
+ unsigned int frontPitch;
+ unsigned int backOffset;
+ unsigned int backPitch;
+ unsigned int depthOffset;
+ unsigned int depthPitch;
+ unsigned int width;
+ unsigned int height;
+ unsigned int cpp;
+
+#if 0
+ unsigned int sarea_priv_offset;
+#endif
+
+ tridentRegionRec mmio;
+} tridentScreenRec, *tridentScreenPtr;
+
+struct trident_context {
+ GLcontext *glCtx; /* Mesa context */
+
+ __DRIcontextPrivate *driContext;
+ __DRIscreenPrivate *driScreen;
+ __DRIdrawablePrivate *driDrawable;
+
+ GLuint new_gl_state;
+ GLuint new_state;
+ GLuint dirty;
+
+#if 0
+ drm_trident_sarea_t *sarea;
+#endif
+
+ /* Temporaries for translating away float colors:
+ */
+ struct gl_client_array UbyteColor;
+ struct gl_client_array UbyteSecondaryColor;
+
+ /* Mirrors of some DRI state
+ */
+ Display *display; /* X server display */
+
+ int lastStamp; /* mirror driDrawable->lastStamp */
+
+ drmContext hHWContext;
+ drmLock *driHwLock;
+ int driFd;
+
+ tridentScreenPtr tridentScreen; /* Screen private DRI data */
+
+ /* Visual, drawable, cliprect and scissor information
+ */
+ GLenum DrawBuffer;
+ GLint drawOffset, drawPitch;
+ GLint drawX, drawY; /* origin of drawable in draw buffer */
+ GLint readOffset, readPitch;
+
+ GLuint numClipRects; /* Cliprects for the draw buffer */
+ XF86DRIClipRectPtr pClipRects;
+
+ GLint scissor;
+ XF86DRIClipRectRec ScissorRect; /* Current software scissor */
+
+ GLuint Fallback;
+ GLuint RenderIndex;
+ GLuint SetupNewInputs;
+ GLuint SetupIndex;
+ GLfloat hw_viewport[16];
+ GLfloat depth_scale;
+ GLuint vertex_format;
+ GLuint vertex_size;
+ GLuint vertex_stride_shift;
+ char *verts;
+
+ GLint tmu_source[2];
+
+ GLuint hw_primitive;
+ GLenum render_primitive;
+
+ trident_point_func draw_point;
+ trident_line_func draw_line;
+ trident_tri_func draw_tri;
+ trident_quad_func draw_quad;
+
+#if 0
+ gammaTextureObjectPtr CurrentTexObj[2];
+ struct gamma_texture_object_t TexObjList;
+ struct gamma_texture_object_t SwappedOut;
+ GLenum TexEnvImageFmt[2];
+
+ memHeap_t *texHeap;
+
+ int lastSwap;
+ int texAge;
+ int ctxAge;
+ int dirtyAge;
+ int lastStamp;
+#endif
+
+ /* Chip state */
+
+ int commandD;
+
+ /* Context State */
+
+ int ClearColor;
+};
+
+void tridentDDInitExtensions( GLcontext *ctx );
+void tridentDDInitDriverFuncs( GLcontext *ctx );
+void tridentDDInitSpanFuncs( GLcontext *ctx );
+void tridentDDInitState( tridentContextPtr tmesa );
+void tridentInitHW( tridentContextPtr tmesa );
+void tridentDDInitStateFuncs( GLcontext *ctx );
+void tridentDDInitTextureFuncs( GLcontext *ctx );
+void tridentDDInitTriFuncs( GLcontext *ctx );
+extern void tridentBuildVertices( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint newinputs );
+
+#define TRIDENT_CONTEXT(ctx) ((tridentContextPtr)(ctx->DriverCtx))
+
+#endif /* _TRIDENT_CONTEXT_H_ */
diff --git a/src/mesa/drivers/dri/trident/trident_dd.c b/src/mesa/drivers/dri/trident/trident_dd.c
new file mode 100644
index 00000000000..2f79ffcf6af
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_dd.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_context.h"
+#include "trident_lock.h"
+#if defined(USE_X86_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+
+#include "swrast/swrast.h"
+#include "context.h"
+
+#define TRIDENT_DATE "20020318"
+
+
+/* Return the width and height of the current color buffer.
+ */
+static void tridentDDGetBufferSize( GLframebuffer *framebuffer,
+ GLuint *width, GLuint *height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+ LOCK_HARDWARE(tmesa);
+ *width = tmesa->driDrawable->w;
+ *height = tmesa->driDrawable->h;
+ UNLOCK_HARDWARE(tmesa);
+}
+
+
+/* Return various strings for glGetString().
+ */
+static const GLubyte *tridentDDGetString( GLcontext *ctx, GLenum name )
+{
+ static char buffer[128];
+
+ switch ( name ) {
+ case GL_VENDOR:
+ return (GLubyte *)"Alan Hourihane";
+
+ case GL_RENDERER:
+ sprintf( buffer, "Mesa DRI Trident " TRIDENT_DATE );
+
+ /* Append any CPU-specific information.
+ */
+#ifdef USE_X86_ASM
+ if ( _mesa_x86_cpu_features ) {
+ strncat( buffer, " x86", 4 );
+ }
+#ifdef USE_MMX_ASM
+ if ( cpu_has_mmx ) {
+ strncat( buffer, "/MMX", 4 );
+ }
+#endif
+#ifdef USE_3DNOW_ASM
+ if ( cpu_has_3dnow ) {
+ strncat( buffer, "/3DNow!", 7 );
+ }
+#endif
+#ifdef USE_SSE_ASM
+ if ( cpu_has_xmm ) {
+ strncat( buffer, "/SSE", 4 );
+ }
+#endif
+#endif
+ return (GLubyte *)buffer;
+
+ default:
+ return NULL;
+ }
+}
+
+/* Enable the extensions supported by this driver.
+ */
+void tridentDDInitExtensions( GLcontext *ctx )
+{
+ /* None... */
+}
+
+/* Initialize the driver's misc functions.
+ */
+void tridentDDInitDriverFuncs( GLcontext *ctx )
+{
+ ctx->Driver.GetBufferSize = tridentDDGetBufferSize;
+ ctx->Driver.GetString = tridentDDGetString;
+
+ ctx->Driver.Error = NULL;
+
+ /* Pixel path fallbacks
+ */
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+ ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+
+ /* Swrast hooks for imaging extensions:
+ */
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c
new file mode 100644
index 00000000000..49318824f5c
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_state.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "trident_context.h"
+#include "trident_lock.h"
+#include "swrast/swrast.h"
+
+#define TRIDENTPACKCOLOR332(r, g, b) \
+ (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
+
+#define TRIDENTPACKCOLOR1555(r, g, b, a) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define TRIDENTPACKCOLOR565(r, g, b) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define TRIDENTPACKCOLOR888(r, g, b) \
+ (((r) << 16) | ((g) << 8) | (b))
+
+#define TRIDENTPACKCOLOR8888(r, g, b, a) \
+ (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define TRIDENTPACKCOLOR4444(r, g, b, a) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+static __inline__ GLuint tridentPackColor( GLuint cpp,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ switch ( cpp ) {
+ case 2:
+ return TRIDENTPACKCOLOR565( r, g, b );
+ case 4:
+ return TRIDENTPACKCOLOR8888( r, g, b, a );
+ default:
+ return 0;
+ }
+}
+
+void tridentUploadHwStateLocked( tridentContextPtr tmesa )
+{
+ unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+#if 0
+ ATISAREAPrivPtr sarea = tmesa->sarea;
+ trident_context_regs_t *regs = &(sarea->ContextState);
+#endif
+
+ if ( tmesa->dirty & TRIDENT_UPLOAD_COMMAND_D ) {
+ MMIO_OUT32(MMIO, 0x00281C, tmesa->commandD );
+ tmesa->dirty &= ~TRIDENT_UPLOAD_COMMAND_D;
+ }
+
+ if ( tmesa->dirty & TRIDENT_UPLOAD_CLIPRECTS ) {
+ /* XXX FIX ME ! */
+ MMIO_OUT32(MMIO, 0x002C80 , 0x20008000 | tmesa->tridentScreen->height );
+ MMIO_OUT32(MMIO, 0x002C84 , 0x20000000 | tmesa->tridentScreen->width );
+ tmesa->dirty &= ~TRIDENT_UPLOAD_CLIPRECTS;
+ }
+
+ tmesa->dirty = 0;
+}
+
+/* Copy the back color buffer to the front color buffer.
+ */
+void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv )
+{
+ unsigned char *MMIO;
+ tridentContextPtr tmesa;
+ GLint nbox, i, ret;
+ int busy;
+ XF86DRIClipRectPtr pbox;
+
+ assert(dPriv);
+ assert(dPriv->driContextPriv);
+ assert(dPriv->driContextPriv->driverPrivate);
+
+ tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate;
+ MMIO = tmesa->tridentScreen->mmio.map;
+
+ LOCK_HARDWARE( tmesa );
+
+ /* use front buffer cliprects */
+ nbox = dPriv->numClipRects;
+ pbox = dPriv->pClipRects;
+
+ for ( i = 0 ; i < nbox ; i++ ) {
+#if 0
+ GLint nr = MIN2( i + MACH64_NR_SAREA_CLIPRECTS , nbox );
+ XF86DRIClipRectPtr b = tmesa->sarea->boxes;
+ GLint n = 0;
+
+ for ( ; i < nr ; i++ ) {
+ *b++ = pbox[i];
+ n++;
+ }
+ tmesa->sarea->nbox = n;
+#endif
+
+ MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4);
+ MMIO_OUT32(MMIO, 0x2154, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4);
+ MMIO_OUT8(MMIO, 0x2127, 0xCC); /* Copy Rop */
+ MMIO_OUT32(MMIO, 0x2128, 0x4); /* scr2scr */
+ MMIO_OUT32(MMIO, 0x2138, (pbox->x1 << 16) | pbox->y1);
+ MMIO_OUT32(MMIO, 0x213C, (pbox->x1 << 16) | pbox->y1);
+ MMIO_OUT32(MMIO, 0x2140, (pbox->x2 - pbox->x1) << 16 | (pbox->y2 - pbox->y1) );
+ MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+ for (;;) {
+ busy = MMIO_IN8(MMIO, 0x2120);
+ if ( !(busy & GE_BUSY) )
+ break;
+ }
+ }
+
+ UNLOCK_HARDWARE( tmesa );
+
+#if 0
+ tmesa->dirty |= (MACH64_UPLOAD_CONTEXT |
+ MACH64_UPLOAD_MISC |
+ MACH64_UPLOAD_CLIPRECTS);
+#endif
+}
+
+
+static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+ __DRIdrawablePrivate *dPriv = tmesa->driDrawable;
+ int busy;
+ GLuint flags = 0;
+ GLint i;
+ GLint ret;
+
+#define DRM_TRIDENT_FRONT 0x01
+#define DRM_TRIDENT_BACK 0x02
+#define DRM_TRIDENT_DEPTH 0x04
+
+ if ( tmesa->new_state )
+ tridentDDUpdateHWState( ctx );
+
+ if ( mask & DD_FRONT_LEFT_BIT ) {
+ flags |= DRM_TRIDENT_FRONT;
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
+
+ if ( mask & DD_BACK_LEFT_BIT ) {
+ flags |= DRM_TRIDENT_BACK;
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
+
+ if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) {
+ flags |= DRM_TRIDENT_DEPTH;
+ mask &= ~DD_DEPTH_BIT;
+ }
+
+ LOCK_HARDWARE(tmesa);
+
+ if ( flags ) {
+
+ cx += tmesa->drawX;
+ cy += tmesa->drawY;
+
+ /* HACK!!!
+ */
+ if ( tmesa->dirty & ~TRIDENT_UPLOAD_CLIPRECTS ) {
+ tridentUploadHwStateLocked( tmesa );
+ }
+
+ for ( i = 0 ; i < tmesa->numClipRects ; i++ ) {
+#if 0
+ int nr = MIN2( i + TRIDENT_NR_SAREA_CLIPRECTS, tmesa->numClipRects );
+ XF86DRIClipRectPtr box = tmesa->pClipRects;
+ XF86DRIClipRectPtr b = tmesa->sarea->boxes;
+ GLint n = 0;
+
+ if ( !all ) {
+ for ( ; i < nr ; i++ ) {
+ GLint x = box[i].x1;
+ GLint y = box[i].y1;
+ GLint w = box[i].x2 - x;
+ GLint h = box[i].y2 - y;
+
+ if ( x < cx ) w -= cx - x, x = cx;
+ if ( y < cy ) h -= cy - y, y = cy;
+ if ( x + w > cx + cw ) w = cx + cw - x;
+ if ( y + h > cy + ch ) h = cy + ch - y;
+ if ( w <= 0 ) continue;
+ if ( h <= 0 ) continue;
+
+ b->x1 = x;
+ b->y1 = y;
+ b->x2 = x + w;
+ b->y2 = y + h;
+ b++;
+ n++;
+ }
+ } else {
+ for ( ; i < nr ; i++ ) {
+ *b++ = box[i];
+ n++;
+ }
+ }
+
+ tmesa->sarea->nbox = n;
+#endif
+
+if (flags & DRM_TRIDENT_BACK) {
+ MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4);
+ MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
+ MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
+ MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
+ MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
+ MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
+ MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+ for (;;) {
+ busy = MMIO_IN8(MMIO, 0x2120);
+ if ( !(busy & GE_BUSY) )
+ break;
+ }
+}
+if (flags & DRM_TRIDENT_DEPTH) {
+ MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->depthPitch << 20 | tmesa->tridentScreen->depthOffset>>4);
+ MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
+ MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
+ MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
+ MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
+ MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
+ MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+ for (;;) {
+ busy = MMIO_IN8(MMIO, 0x2120);
+ if ( !(busy & GE_BUSY) )
+ break;
+ }
+}
+ MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4);
+if (flags & DRM_TRIDENT_FRONT) {
+ MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */
+ MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor);
+ MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */
+ MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy);
+ MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch);
+ MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */
+#define GE_BUSY 0x80
+ for (;;) {
+ busy = MMIO_IN8(MMIO, 0x2120);
+ if ( !(busy & GE_BUSY) )
+ break;
+ }
+}
+
+ }
+
+#if 0
+ tmesa->dirty |= (TRIDENT_UPLOAD_CONTEXT |
+ TRIDENT_UPLOAD_MISC |
+ TRIDENT_UPLOAD_CLIPRECTS);
+#endif
+ }
+
+ UNLOCK_HARDWARE(tmesa);
+
+ if ( mask )
+ _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
+}
+
+static void tridentDDShadeModel( GLcontext *ctx, GLenum mode )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ GLuint s = tmesa->commandD;
+
+#define TRIDENT_FLAT_SHADE 0x000000E0
+#define TRIDENT_FLAT_SHADE_VERTEX_C 0x00000060
+#define TRIDENT_FLAT_SHADE_GOURAUD 0x00000080
+
+ s &= ~TRIDENT_FLAT_SHADE;
+
+ switch ( mode ) {
+ case GL_FLAT:
+ s |= TRIDENT_FLAT_SHADE_VERTEX_C;
+ break;
+ case GL_SMOOTH:
+ s |= TRIDENT_FLAT_SHADE_GOURAUD;
+ break;
+ default:
+ return;
+ }
+
+ if ( tmesa->commandD != s ) {
+ tmesa->commandD = s;
+
+ tmesa->dirty |= TRIDENT_UPLOAD_COMMAND_D;
+ }
+}
+
+void tridentCalcViewport( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ GLfloat *m = tmesa->hw_viewport;
+
+ /* See also trident_translate_vertex.
+ */
+ m[MAT_SX] = v[MAT_SX];
+ m[MAT_TX] = v[MAT_TX] + tmesa->drawX + SUBPIXEL_X;
+ m[MAT_SY] = - v[MAT_SY];
+ m[MAT_TY] = - v[MAT_TY] + tmesa->driDrawable->h + tmesa->drawY + SUBPIXEL_Y;
+#if 0
+ m[MAT_SZ] = v[MAT_SZ] * tmesa->depth_scale;
+ m[MAT_TZ] = v[MAT_TZ] * tmesa->depth_scale;
+#else
+ m[MAT_SZ] = v[MAT_SZ];
+ m[MAT_TZ] = v[MAT_TZ];
+#endif
+
+ tmesa->SetupNewInputs = ~0;
+}
+
+static void tridentDDViewport( GLcontext *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height )
+{
+ tridentCalcViewport( ctx );
+}
+
+static void tridentDDDepthRange( GLcontext *ctx,
+ GLclampd nearval, GLclampd farval )
+{
+ tridentCalcViewport( ctx );
+}
+
+void tridentSetCliprects( tridentContextPtr tmesa, GLenum mode )
+{
+ __DRIdrawablePrivate *dPriv = tmesa->driDrawable;
+
+ switch ( mode ) {
+ case GL_FRONT_LEFT:
+ if (dPriv->numClipRects == 0) {
+ static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+ tmesa->numClipRects = 1;
+ tmesa->pClipRects = &zeroareacliprect;
+ } else {
+ tmesa->numClipRects = dPriv->numClipRects;
+ tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
+ }
+ tmesa->drawX = dPriv->x;
+ tmesa->drawY = dPriv->y;
+ break;
+ case GL_BACK_LEFT:
+ if ( dPriv->numBackClipRects == 0 ) {
+ if (dPriv->numClipRects == 0) {
+ static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+ tmesa->numClipRects = 1;
+ tmesa->pClipRects = &zeroareacliprect;
+ } else {
+ tmesa->numClipRects = dPriv->numClipRects;
+ tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
+ tmesa->drawX = dPriv->x;
+ tmesa->drawY = dPriv->y;
+ }
+ }
+ else {
+ tmesa->numClipRects = dPriv->numBackClipRects;
+ tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pBackClipRects;
+ tmesa->drawX = dPriv->backX;
+ tmesa->drawY = dPriv->backY;
+ }
+ break;
+ default:
+ return;
+ }
+
+#if 0
+ tmesa->dirty |= TRIDENT_UPLOAD_CLIPRECTS;
+#endif
+}
+
+static GLboolean tridentDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ int found = GL_TRUE;
+
+ if ( tmesa->DrawBuffer != mode ) {
+ tmesa->DrawBuffer = mode;
+
+ switch ( mode ) {
+ case GL_FRONT_LEFT:
+ tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ tmesa->drawOffset = tmesa->tridentScreen->frontOffset;
+ tmesa->drawPitch = tmesa->tridentScreen->frontPitch;
+ tridentSetCliprects( tmesa, GL_FRONT_LEFT );
+ break;
+ case GL_BACK_LEFT:
+ tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ tmesa->drawOffset = tmesa->tridentScreen->backOffset;
+ tmesa->drawPitch = tmesa->tridentScreen->backPitch;
+ tridentSetCliprects( tmesa, GL_BACK_LEFT );
+ break;
+ default:
+ tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ found = GL_FALSE;
+ break;
+ }
+
+#if 0
+ tmesa->setup.dst_off_pitch = (((tmesa->drawPitch/8) << 22) |
+ (tmesa->drawOffset >> 3));
+
+ tmesa->dirty |= MACH64_UPLOAD_DST_OFF_PITCH | MACH64_UPLOAD_CONTEXT;
+#endif
+
+ }
+
+ return found;
+}
+
+static void tridentDDClearColor( GLcontext *ctx,
+ const GLchan color[4] )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+ tmesa->ClearColor = tridentPackColor( tmesa->tridentScreen->cpp,
+ color[0], color[1],
+ color[2], color[3] );
+}
+
+
+void tridentDDUpdateState( GLcontext *ctx, GLuint new_state )
+{
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _ac_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+ TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state;
+}
+
+
+/* Initialize the context's hardware state.
+ */
+void tridentDDInitState( tridentContextPtr tmesa )
+{
+ tmesa->new_state = 0;
+
+ switch ( tmesa->glCtx->Visual.depthBits ) {
+ case 16:
+ tmesa->depth_scale = 1.0 / (GLfloat)0xffff;
+ break;
+ case 24:
+ tmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
+ break;
+ }
+}
+
+void tridentDDUpdateHWState( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ int new_state = tmesa->new_state;
+
+ if ( new_state )
+ {
+ tmesa->new_state = 0;
+
+#if 0
+ /* Update the various parts of the context's state.
+ */
+ if ( new_state & GAMMA_NEW_ALPHA )
+ tridentUpdateAlphaMode( ctx );
+
+ if ( new_state & GAMMA_NEW_DEPTH )
+ tridentUpdateZMode( ctx );
+
+ if ( new_state & GAMMA_NEW_FOG )
+ gammaUpdateFogAttrib( ctx );
+
+ if ( new_state & GAMMA_NEW_CLIP )
+ gammaUpdateClipping( ctx );
+
+ if ( new_state & GAMMA_NEW_POLYGON )
+ gammaUpdatePolygon( ctx );
+
+ if ( new_state & GAMMA_NEW_CULL )
+ gammaUpdateCull( ctx );
+
+ if ( new_state & GAMMA_NEW_MASKS )
+ gammaUpdateMasks( ctx );
+
+ if ( new_state & GAMMA_NEW_STIPPLE )
+ gammaUpdateStipple( ctx );
+#endif
+ }
+
+ /* HACK ! */
+
+#if 0
+ gammaEmitHwState( tmesa );
+#endif
+}
+
+/* Initialize the driver's state functions.
+ */
+void tridentDDInitStateFuncs( GLcontext *ctx )
+{
+ ctx->Driver.UpdateState = tridentDDUpdateState;
+
+ ctx->Driver.Clear = tridentDDClear;
+ ctx->Driver.DepthRange = tridentDDDepthRange;
+ ctx->Driver.ShadeModel = tridentDDShadeModel;
+ ctx->Driver.Viewport = tridentDDViewport;
+
+ /* Pixel path fallbacks.
+ */
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+ ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+
+ /* Swrast hooks for imaging extensions:
+ */
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+}
diff --git a/src/mesa/drivers/dri/trident/trident_tris.c b/src/mesa/drivers/dri/trident/trident_tris.c
new file mode 100644
index 00000000000..890e34ed910
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_tris.c
@@ -0,0 +1,1112 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+
+#include "trident_context.h"
+#include "trident_lock.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "swrast/swrast.h"
+
+static int first = 1;
+
+typedef struct reg {
+ int addr;
+ int data;
+} RegData;
+
+RegData initRegData[]={
+ {0x2804, 0x19980824},
+ {0x2F70, 0x46455858},
+ {0x2F74, 0x41584998},
+ {0x2F00, 0x00000000},
+ {0x2F04, 0x80000800},
+ {0x2F08, 0x00550200},
+ {0x2F40, 0x00000001},
+ {0x2F40, 0x00000001},
+ {0x2F44, 0x00830097},
+ {0x2F48, 0x0087009F},
+ {0x2F4C, 0x00BF0003},
+ {0x2F50, 0xF00B6C1B},
+ {0x2C04, 0x00000000},
+ {0x2D00, 0x00000080},
+ {0x2D00, 0x00000000},
+ {0x2DD4, 0x00100000},
+ {0x2DD4, 0x00100010},
+ {0x2DD8, 0x00100000},
+ {0x2DD8, 0x00100010},
+ {0x2C88, 0xFFFFFFFF},
+ {0x2C94 , 0xFFFFFFFF},
+ {0x281C, 0x00008000},
+ {0x2C80, 0x00000000},
+ {0x2C80, 0x00000000},
+ {0x2C80 , 0x00008000},
+ {0x2C00 , 0x00000000},
+ {0x2C04 , 0x00000000},
+ {0x2C08 , 0x00000000},
+ {0x2C0C , 0x00000000},
+ {0x2C10 , 0x00000000},
+ {0x2C14 , 0x00000000},
+ {0x2C18 , 0x00000000},
+ {0x2C1C , 0x00000000},
+ {0x2C20 , 0x00000000},
+ {0x2C24 , 0x00000000},
+ {0x2C2C , 0x00000000},
+ {0x2C30 , 0x00000000},
+ {0x2C34 , 0x00000000},
+ {0x2C38 , 0x00000000},
+ {0x2C3C , 0x00000000},
+ {0x2C40 , 0x00000000},
+ {0x2C44 , 0x00000000},
+ {0x2C48 , 0x00000000},
+ {0x2C4C , 0x00000000},
+ {0x2C50 , 0x00000000},
+ {0x2C54 , 0x00000000},
+ {0x2C58 , 0x00000000},
+ {0x2C5C , 0x00000000},
+ {0x2C60 , 0x00000000},
+ {0x2C64 , 0x00000000},
+ {0x2C68 , 0x00000000},
+ {0x2C6C , 0x00000000},
+ {0x2C70 , 0x00000000},
+ {0x2C74 , 0x00000000},
+ {0x2C78 , 0x00000000},
+ {0x2C7C , 0x00000000},
+ {0x2C80 , 0x00008000},
+ {0x2C84 , 0x00000000},
+ {0x2C88 , 0xFFFFFFFF},
+ {0x2C8C , 0x00000000},
+ {0x2C90 , 0x00000000},
+ {0x2C94 , 0xFFFFFFFF},
+ {0x2C98 , 0x00000000},
+ {0x2C9C , 0x00000000},
+ {0x2CA0 , 0x00000000},
+ {0x2CA4 , 0x00000000},
+ {0x2CA8 , 0x00000000},
+ {0x2CAC , 0x00000000},
+ {0x2CB0 , 0x00000000},
+ {0x2CB4 , 0x00000000},
+ {0x2CB8 , 0x00000000},
+ {0x2CBC , 0x00000000},
+ {0x2CC0 , 0x00000000},
+ {0x2CC4 , 0x00000000},
+ {0x2CC8 , 0x00000000},
+ {0x2CCC , 0x00000000},
+ {0x2CD0 , 0x00000000},
+ {0x2CD4 , 0x00000000},
+ {0x2CD8 , 0x00000000},
+ {0x2CDC , 0x00000000},
+ {0x2CE0 , 0x00000000},
+ {0x2CE4 , 0x00000000},
+ {0x2CE8 , 0x00000000},
+ {0x2CEC , 0x00000000},
+ {0x2CF0 , 0x00000000},
+ {0x2CF4 , 0x00000000},
+ {0x2CF8 , 0x00000000},
+ {0x2CFC , 0x00000000},
+ {0x2D00 , 0x00000000},
+ {0x2D04 , 0x00000000},
+ {0x2D08 , 0x00000000},
+ {0x2D0C , 0x00000000},
+ {0x2D10 , 0x00000000},
+ {0x2D14 , 0x00000000},
+ {0x2D18 , 0x00000000},
+ {0x2D1C , 0x00000000},
+ {0x2D20 , 0x00000000},
+ {0x2D24 , 0x00000000},
+ {0x2D28 , 0x00000000},
+ {0x2D2C , 0x00000000},
+ {0x2D30 , 0x00000000},
+ {0x2D34 , 0x00000000},
+ {0x2D38 , 0x00000000},
+ {0x2D3C , 0x00000000},
+ {0x2D40 , 0x00000000},
+ {0x2D44 , 0x00000000},
+ {0x2D48 , 0x00000000},
+ {0x2D4C , 0x00000000},
+ {0x2D50 , 0x00000000},
+ {0x2D54 , 0x00000000},
+ {0x2D58 , 0x00000000},
+ {0x2D5C , 0x00000000},
+ {0x2D60 , 0x00000000},
+ {0x2D64 , 0x00000000},
+ {0x2D68 , 0x00000000},
+ {0x2D6C , 0x00000000},
+ {0x2D70 , 0x00000000},
+ {0x2D74 , 0x00000000},
+ {0x2D78 , 0x00000000},
+ {0x2D7C , 0x00000000},
+ {0x2D80 , 0x00000000},
+ {0x2D84 , 0x00000000},
+ {0x2D88 , 0x00000000},
+ {0x2D8C , 0x00000000},
+ {0x2D90 , 0x00000000},
+ {0x2D94 , 0x00000000},
+ {0x2D98 , 0x00000000},
+ {0x2D9C , 0x00000000},
+ {0x2DA0 , 0x00000000},
+ {0x2DA4 , 0x00000000},
+ {0x2DA8 , 0x00000000},
+ {0x2DAC , 0x00000000},
+ {0x2DB0 , 0x00000000},
+ {0x2DB4 , 0x00000000},
+ {0x2DB8 , 0x00000000},
+ {0x2DBC , 0x00000000},
+ {0x2DC0 , 0x00000000},
+ {0x2DC4 , 0x00000000},
+ {0x2DC8 , 0x00000000},
+ {0x2DCC , 0x00000000},
+ {0x2DD0 , 0x00000000},
+ {0x2DD4 , 0x00100010},
+ {0x2DD8 , 0x00100010},
+ {0x2DDC , 0x00000000},
+ {0x2DE0 , 0x00000000},
+ {0x2DE4 , 0x00000000},
+ {0x2DE8 , 0x00000000},
+ {0x2DEC , 0x00000000},
+ {0x2DF0 , 0x00000000},
+ {0x2DF4 , 0x00000000},
+ {0x2DF8 , 0x00000000},
+ {0x2DFC , 0x00000000},
+ {0x2E00 , 0x00000000},
+ {0x2E04 , 0x00000000},
+ {0x2E08 , 0x00000000},
+ {0x2E0C , 0x00000000},
+ {0x2E10 , 0x00000000},
+ {0x2E14 , 0x00000000},
+ {0x2E18 , 0x00000000},
+ {0x2E1C , 0x00000000},
+ {0x2E20 , 0x00000000},
+ {0x2E24 , 0x00000000},
+ {0x2E28 , 0x00000000},
+ {0x2E2C , 0x00000000},
+ {0x2E30 , 0x00000000},
+ {0x2E34 , 0x00000000},
+ {0x2E38 , 0x00000000},
+ {0x2E3C , 0x00000000},
+ {0x2E40 , 0x00000000},
+ {0x2E44 , 0x00000000},
+ {0x2E48 , 0x00000000},
+ {0x2E4C , 0x00000000},
+ {0x2E50 , 0x00000000},
+ {0x2E54 , 0x00000000},
+ {0x2E58 , 0x00000000},
+ {0x2E5C , 0x00000000},
+ {0x2E60 , 0x00000000},
+ {0x2E64 , 0x00000000},
+ {0x2E68 , 0x00000000},
+ {0x2E6C , 0x00000000},
+ {0x2E70 , 0x00000000},
+ {0x2E74 , 0x00000000},
+ {0x2E78 , 0x00000000},
+ {0x2E7C , 0x00000000},
+ {0x2E80 , 0x00000000},
+ {0x2E84 , 0x00000000},
+ {0x2E88 , 0x00000000},
+ {0x2E8C , 0x00000000},
+ {0x2E90 , 0x00000000},
+ {0x2E94 , 0x00000000},
+ {0x2E98 , 0x00000000},
+ {0x2E9C , 0x00000000},
+ {0x2EA0 , 0x00000000},
+ {0x2EA4 , 0x00000000},
+ {0x2EA8 , 0x00000000},
+ {0x2EAC , 0x00000000},
+ {0x2EB0 , 0x00000000},
+ {0x2EB4 , 0x00000000},
+ {0x2EB8 , 0x00000000},
+ {0x2EBC , 0x00000000},
+ {0x2EC0 , 0x00000000},
+ {0x2EC4 , 0x00000000},
+ {0x2EC8 , 0x00000000},
+ {0x2ECC , 0x00000000},
+ {0x2ED0 , 0x00000000},
+ {0x2ED4 , 0x00000000},
+ {0x2ED8 , 0x00000000},
+ {0x2EDC , 0x00000000},
+ {0x2EE0 , 0x00000000},
+ {0x2EE4 ,0x00000000},
+ {0x2EE8 ,0x00000000},
+ {0x2EEC , 0x00000000},
+ {0x2EF0 , 0x00000000},
+ {0x2EF4 , 0x00000000},
+ {0x2EF8 , 0x00000000},
+ {0x2EFC , 0x00000000},
+ /*{0x2F60 , 0x00000000},*/
+};
+
+int initRegDataNum=sizeof(initRegData)/sizeof(RegData);
+
+typedef union {
+ unsigned int i;
+ float f;
+} dmaBufRec, *dmaBuf;
+
+void Init3D( tridentContextPtr tmesa )
+{
+ unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+ int i;
+
+ for(i=0;i<initRegDataNum;++i)
+ MMIO_OUT32(MMIO, initRegData[i].addr, initRegData[i].data);
+}
+
+int DrawTriangle( tridentContextPtr tmesa)
+{
+ volatile unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+ dmaBufRec clr;
+
+printf("DRAW TRI\n");
+ Init3D(tmesa);
+
+printf("ENGINE STATUS 0x%x\n",MMIO_IN32(MMIO, 0x2800));
+ MMIO_OUT32(MMIO, 0x002800, 0x00000000 );
+#if 0
+ MMIO_OUT32(MMIO, 0x002368 , MMIO_IN32(MMIO,0x002368)|1 );
+#endif
+
+ MMIO_OUT32(MMIO, 0x002C00 , 0x00000014 );
+#if 0
+ MMIO_OUT32(MMIO, 0x002C04 , 0x0A8004C0 );
+#else
+ MMIO_OUT32(MMIO, 0x002C04 , 0x0A8000C0 );
+#endif
+
+#if 0
+ MMIO_OUT32(MMIO, 0x002C08 , 0x00000000 );
+ MMIO_OUT32(MMIO, 0x002C0C , 0xFFCCCCCC );
+ MMIO_OUT32(MMIO, 0x002C10 , 0x3F800000 );
+ MMIO_OUT32(MMIO, 0x002C14 , 0x3D0D3DCB );
+ MMIO_OUT32(MMIO, 0x002C2C , 0x70000000 );
+ MMIO_OUT32(MMIO, 0x002C24 , 0x00202C00 );
+ MMIO_OUT32(MMIO, 0x002C28 , 0xE0002500 );
+ MMIO_OUT32(MMIO, 0x002C30 , 0x00000000 );
+ MMIO_OUT32(MMIO, 0x002C34 , 0xE0000000 );
+ MMIO_OUT32(MMIO, 0x002C38 , 0x00000000 );
+#endif
+
+ MMIO_OUT32(MMIO, 0x002C50 , 0x00000000 );
+ MMIO_OUT32(MMIO, 0x002C54 , 0x0C320C80 );
+ MMIO_OUT32(MMIO, 0x002C50 , 0x00000000 );
+ MMIO_OUT32(MMIO, 0x002C54 , 0x0C320C80 );
+ MMIO_OUT32(MMIO, 0x002C80 , 0x20008258 );
+ MMIO_OUT32(MMIO, 0x002C84 , 0x20000320 );
+ MMIO_OUT32(MMIO, 0x002C94 , 0xFFFFFFFF );
+
+#if 0
+ MMIO_OUT32(MMIO, 0x002D00 , 0x00009009 );
+ MMIO_OUT32(MMIO, 0x002D38 , 0x00000000 );
+ MMIO_OUT32(MMIO, 0x002D94 , 0x20002000 );
+ MMIO_OUT32(MMIO, 0x002D50 , 0xf0000000 );
+ MMIO_OUT32(MMIO, 0x002D80 , 0x24002000 );
+ MMIO_OUT32(MMIO, 0x002D98 , 0x81000000 );
+ MMIO_OUT32(MMIO, 0x002DB0 , 0x81000000 );
+ MMIO_OUT32(MMIO, 0x002DC8 , 0x808000FF );
+ MMIO_OUT32(MMIO, 0x002DD4 , 0x02000200 );
+ MMIO_OUT32(MMIO, 0x002DD8 , 0x02000200 );
+ MMIO_OUT32(MMIO, 0x002D30 , 0x02092400 );
+ MMIO_OUT32(MMIO, 0x002D04 , 0x00102120 );
+ MMIO_OUT32(MMIO, 0x002D08 , 0xFFFFFFFF );
+ MMIO_OUT32(MMIO, 0x002D0C , 0xF00010D0 );
+ MMIO_OUT32(MMIO, 0x002D10 , 0xC0000400 );
+#endif
+
+ MMIO_OUT32(MMIO, 0x002814, 0x00000000 );
+#if 0
+ MMIO_OUT32(MMIO, 0x002818 , 0x00036C20 );
+#else
+ MMIO_OUT32(MMIO, 0x002818 , 0x00036020 );
+#endif
+ MMIO_OUT32(MMIO, 0x00281C , 0x00098081 );
+
+printf("first TRI\n");
+ clr.f = 5.0;
+ MMIO_OUT32(MMIO, 0x002820 , clr.i );
+ clr.f = 595.0;
+ MMIO_OUT32(MMIO, 0x002824 , clr.i );
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002828 , clr.i );
+ MMIO_OUT32(MMIO, 0x00282C , 0x00FF00 );
+#if 0
+ clr.f = 0.0;
+ MMIO_OUT32(MMIO, 0x002830 , clr.i );
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+ clr.f = 5.0;
+ MMIO_OUT32(MMIO, 0x002820 , clr.i );
+ clr.f = 5.0;
+ MMIO_OUT32(MMIO, 0x002824 , clr.i );
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002828 , clr.i );
+ MMIO_OUT32(MMIO, 0x00282C , 0xFF0000 );
+#if 0
+ clr.f = 0.0;
+ MMIO_OUT32(MMIO, 0x002830 , clr.i );
+ clr.f = 0.0;
+ MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+ clr.f = 395.0;
+printf("0x%x\n",clr.i);
+ MMIO_OUT32(MMIO, 0x002820 , clr.i );
+ clr.f = 5.0;
+ MMIO_OUT32(MMIO, 0x002824 , clr.i );
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002828 , clr.i );
+ MMIO_OUT32(MMIO, 0x00282C , 0xFF );
+#if 0
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002830 , clr.i );
+ clr.f = 0.0;
+ MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+printf("sec TRI\n");
+ MMIO_OUT32(MMIO, 0x00281C , 0x00093980 );
+ clr.f = 395.0;
+ MMIO_OUT32(MMIO, 0x002820 , clr.i );
+ clr.f = 595.0;
+ MMIO_OUT32(MMIO, 0x002824 , clr.i );
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002828 , clr.i );
+ MMIO_OUT32(MMIO, 0x00282C , 0x00FF00 );
+#if 0
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002830 , clr.i );
+ clr.f = 1.0;
+ MMIO_OUT32(MMIO, 0x002834 , clr.i );
+#endif
+
+#if 0
+ MMIO_OUT32(MMIO, 0x002368 , MMIO_IN32(MMIO,0x002368)&0xfffffffe );
+#endif
+
+printf("fin TRI\n");
+
+ return 0;
+}
+
+static INLINE void trident_draw_point(tridentContextPtr tmesa,
+ const tridentVertex *v0 )
+{
+ unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+}
+
+static INLINE void trident_draw_line( tridentContextPtr tmesa,
+ const tridentVertex *v0,
+ const tridentVertex *v1 )
+{
+ unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+}
+
+static INLINE void trident_draw_triangle( tridentContextPtr tmesa,
+ const tridentVertex *v0,
+ const tridentVertex *v1,
+ const tridentVertex *v2 )
+{
+}
+
+static INLINE void trident_draw_quad( tridentContextPtr tmesa,
+ const tridentVertex *v0,
+ const tridentVertex *v1,
+ const tridentVertex *v2,
+ const tridentVertex *v3 )
+{
+ GLuint vertsize = tmesa->vertex_size;
+ GLint coloridx = (vertsize > 4) ? 4 : 3;
+ unsigned char *MMIO = tmesa->tridentScreen->mmio.map;
+ int clr;
+ float *ftmp = (float *)(&clr);
+
+ if (tmesa->dirty)
+ tridentUploadHwStateLocked( tmesa );
+#if 0
+ DrawTriangle(tmesa);
+ exit(0);
+#else
+#if 1
+ if (first) {
+ Init3D(tmesa);
+#if 0
+ DrawTriangle(tmesa);
+#endif
+ first = 0;
+ }
+#endif
+
+ LOCK_HARDWARE( tmesa );
+
+ MMIO_OUT32(MMIO, 0x002C00 , 0x00000010 );
+ MMIO_OUT32(MMIO, 0x002C04 , 0x029C00C0 );
+
+ /* Z buffer */
+ MMIO_OUT32(MMIO, 0x002C24 , 0x00100000 /*| (tmesa->tridentScreen->depthOffset)*/ );
+ MMIO_OUT32(MMIO, 0x002C28 , 0xE0000000 | (tmesa->tridentScreen->depthPitch * 4) );
+
+ /* front buffer */
+ MMIO_OUT32(MMIO, 0x002C50 , 0x00000000 | (tmesa->drawOffset) );
+ MMIO_OUT32(MMIO, 0x002C54 , 0x0C320000 | (tmesa->drawPitch * 4) );
+
+ /* clipper */
+ MMIO_OUT32(MMIO, 0x002C80 , 0x20008000 | tmesa->tridentScreen->height );
+ MMIO_OUT32(MMIO, 0x002C84 , 0x20000000 | tmesa->tridentScreen->width );
+
+ /* writemask */
+ MMIO_OUT32(MMIO, 0x002C94 , 0xFFFFFFFF );
+
+if (vertsize == 4) {
+ MMIO_OUT32(MMIO, 0x002818 , 0x0003A020 );
+ MMIO_OUT32(MMIO, 0x00281C , 0x00098021 );
+
+ *ftmp = v0->v.x;
+ MMIO_OUT32(MMIO, 0x002820 , clr );
+ *ftmp = v0->v.y;
+ MMIO_OUT32(MMIO, 0x002824 , clr );
+ *ftmp = v0->v.z;
+ MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+ *ftmp = v0->v.w;
+ MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+ MMIO_OUT32(MMIO, 0x00282C , v0->ui[coloridx] );
+
+ *ftmp = v1->v.x;
+ MMIO_OUT32(MMIO, 0x002820 , clr );
+ *ftmp = v1->v.y;
+ MMIO_OUT32(MMIO, 0x002824 , clr );
+ *ftmp = v1->v.z;
+ MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+ *ftmp = v1->v.w;
+ MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+ MMIO_OUT32(MMIO, 0x00282C , v1->ui[coloridx] );
+
+ *ftmp = v2->v.x;
+ MMIO_OUT32(MMIO, 0x002820 , clr );
+ *ftmp = v2->v.y;
+ MMIO_OUT32(MMIO, 0x002824 , clr );
+ *ftmp = v2->v.z;
+ MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+ *ftmp = v2->v.w;
+ MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+ MMIO_OUT32(MMIO, 0x00282C , v2->ui[coloridx] );
+
+ MMIO_OUT32(MMIO, 0x00281C , 0x00093020 );
+ *ftmp = v3->v.x;
+ MMIO_OUT32(MMIO, 0x002820 , clr );
+ *ftmp = v3->v.y;
+ MMIO_OUT32(MMIO, 0x002824 , clr );
+ *ftmp = v3->v.z;
+ MMIO_OUT32(MMIO, 0x002828 , clr );
+#if 0
+ *ftmp = v3->v.w;
+ MMIO_OUT32(MMIO, 0x00282C , clr );
+#endif
+ MMIO_OUT32(MMIO, 0x00282C , v3->ui[coloridx] );
+
+}
+#endif
+
+ UNLOCK_HARDWARE( tmesa );
+}
+/***********************************************************************
+ * Rasterization fallback helpers *
+ ***********************************************************************/
+
+
+/* This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.
+ */
+static void
+trident_fallback_quad( tridentContextPtr tmesa,
+ const tridentVertex *v0,
+ const tridentVertex *v1,
+ const tridentVertex *v2,
+ const tridentVertex *v3 )
+{
+ GLcontext *ctx = tmesa->glCtx;
+ SWvertex v[4];
+ trident_translate_vertex( ctx, v0, &v[0] );
+ trident_translate_vertex( ctx, v1, &v[1] );
+ trident_translate_vertex( ctx, v2, &v[2] );
+ trident_translate_vertex( ctx, v3, &v[3] );
+ _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] );
+}
+
+static void
+trident_fallback_tri( tridentContextPtr tmesa,
+ const tridentVertex *v0,
+ const tridentVertex *v1,
+ const tridentVertex *v2 )
+{
+ GLcontext *ctx = tmesa->glCtx;
+ SWvertex v[3];
+ trident_translate_vertex( ctx, v0, &v[0] );
+ trident_translate_vertex( ctx, v1, &v[1] );
+ trident_translate_vertex( ctx, v2, &v[2] );
+ _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+}
+
+static void
+trident_fallback_line( tridentContextPtr tmesa,
+ const tridentVertex *v0,
+ const tridentVertex *v1 )
+{
+ GLcontext *ctx = tmesa->glCtx;
+ SWvertex v[2];
+ trident_translate_vertex( ctx, v0, &v[0] );
+ trident_translate_vertex( ctx, v1, &v[1] );
+ _swrast_Line( ctx, &v[0], &v[1] );
+}
+
+
+static void
+trident_fallback_point( tridentContextPtr tmesa,
+ const tridentVertex *v0 )
+{
+ GLcontext *ctx = tmesa->glCtx;
+ SWvertex v[1];
+ trident_translate_vertex( ctx, v0, &v[0] );
+ _swrast_Point( ctx, &v[0] );
+}
+
+/***********************************************************************
+ * Macros for t_dd_tritmp.h to draw basic primitives *
+ ***********************************************************************/
+
+#define TRI( a, b, c ) \
+do { \
+ if (DO_FALLBACK) \
+ tmesa->draw_tri( tmesa, a, b, c ); \
+ else \
+ trident_draw_triangle( tmesa, a, b, c ); \
+} while (0)
+
+#define QUAD( a, b, c, d ) \
+do { \
+ if (DO_FALLBACK) { \
+ tmesa->draw_tri( tmesa, a, b, d ); \
+ tmesa->draw_tri( tmesa, b, c, d ); \
+ } else \
+ trident_draw_quad( tmesa, a, b, c, d ); \
+} while (0)
+
+#define LINE( v0, v1 ) \
+do { \
+ if (DO_FALLBACK) \
+ tmesa->draw_line( tmesa, v0, v1 ); \
+ else \
+ trident_draw_line( tmesa, v0, v1 ); \
+} while (0)
+
+#define POINT( v0 ) \
+do { \
+ if (DO_FALLBACK) \
+ tmesa->draw_point( tmesa, v0 ); \
+ else \
+ trident_draw_point( tmesa, v0 ); \
+} while (0)
+
+/***********************************************************************
+ * Build render functions from dd templates *
+ ***********************************************************************/
+
+#define TRIDENT_OFFSET_BIT 0x01
+#define TRIDENT_TWOSIDE_BIT 0x02
+#define TRIDENT_UNFILLED_BIT 0x04
+#define TRIDENT_FALLBACK_BIT 0x08
+#define TRIDENT_MAX_TRIFUNC 0x10
+
+
+static struct {
+ points_func points;
+ line_func line;
+ triangle_func triangle;
+ quad_func quad;
+} rast_tab[TRIDENT_MAX_TRIFUNC];
+
+
+#define DO_FALLBACK (IND & TRIDENT_FALLBACK_BIT)
+#define DO_OFFSET (IND & TRIDENT_OFFSET_BIT)
+#define DO_UNFILLED (IND & TRIDENT_UNFILLED_BIT)
+#define DO_TWOSIDE (IND & TRIDENT_TWOSIDE_BIT)
+#define DO_FLAT 0
+#define DO_TRI 1
+#define DO_QUAD 1
+#define DO_LINE 1
+#define DO_POINTS 1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA 1
+#define HAVE_SPEC 1
+#define HAVE_BACK_COLORS 0
+#define HAVE_HW_FLATSHADE 1
+#define VERTEX tridentVertex
+#define TAB rast_tab
+
+#define DEPTH_SCALE 1.0
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a > 0)
+#define GET_VERTEX(e) (tmesa->verts + (e<<tmesa->vertex_stride_shift))
+
+#define TRIDENT_COLOR( dst, src ) \
+do { \
+ dst[0] = src[2]; \
+ dst[1] = src[1]; \
+ dst[2] = src[0]; \
+ dst[3] = src[3]; \
+} while (0)
+
+#define TRIDENT_SPEC( dst, src ) \
+do { \
+ dst[0] = src[2]; \
+ dst[1] = src[1]; \
+ dst[2] = src[0]; \
+} while (0)
+
+#define VERT_SET_RGBA( v, c ) TRIDENT_COLOR( v->ub4[coloroffset], c )
+#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
+#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
+
+#define VERT_SET_SPEC( v, c ) if (havespec) TRIDENT_SPEC( v->ub4[5], c )
+#define VERT_COPY_SPEC( v0, v1 ) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5])
+#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
+#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
+
+#define LOCAL_VARS(n) \
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); \
+ GLuint color[n], spec[n]; \
+ GLuint coloroffset = (tmesa->vertex_size == 4 ? 3 : 4); \
+ GLboolean havespec = (tmesa->vertex_size == 4 ? 0 : 1); \
+ (void) color; (void) spec; (void) coloroffset; (void) havespec;
+/***********************************************************************
+ * Helpers for rendering unfilled primitives *
+ ***********************************************************************/
+#if 0
+static const GLuint hw_prim[GL_POLYGON+1] = {
+ B_PrimType_Points,
+ B_PrimType_Lines,
+ B_PrimType_Lines,
+ B_PrimType_Lines,
+ B_PrimType_Triangles,
+ B_PrimType_Triangles,
+ B_PrimType_Triangles,
+ B_PrimType_Triangles,
+ B_PrimType_Triangles,
+ B_PrimType_Triangles
+};
+#endif
+
+static void tridentResetLineStipple( GLcontext *ctx );
+static void tridentRasterPrimitive( GLcontext *ctx, GLuint hwprim );
+static void tridentRenderPrimitive( GLcontext *ctx, GLenum prim );
+
+#define RASTERIZE(x) /*if (tmesa->hw_primitive != hw_prim[x]) \
+ tridentRasterPrimitive( ctx, hw_prim[x] ) */
+#define RENDER_PRIMITIVE tmesa->render_primitive
+#define TAG(x) x
+#define IND TRIDENT_FALLBACK_BIT
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ * Generate GL render functions *
+ ***********************************************************************/
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (TRIDENT_TWOSIDE_BIT|TRIDENT_OFFSET_BIT|TRIDENT_UNFILLED_BIT|TRIDENT_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+static void init_rast_tab( void )
+{
+ init();
+ init_offset();
+ init_twoside();
+ init_twoside_offset();
+ init_unfilled();
+ init_offset_unfilled();
+ init_twoside_unfilled();
+ init_twoside_offset_unfilled();
+ init_fallback();
+ init_offset_fallback();
+ init_twoside_fallback();
+ init_twoside_offset_fallback();
+ init_unfilled_fallback();
+ init_offset_unfilled_fallback();
+ init_twoside_unfilled_fallback();
+ init_twoside_offset_unfilled_fallback();
+}
+
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+#define VERT(x) (tridentVertex *)(tridentverts + (x << shift))
+#define RENDER_POINTS( start, count ) \
+ for ( ; start < count ; start++) \
+ trident_draw_point( tmesa, VERT(start) )
+#define RENDER_LINE( v0, v1 ) \
+ trident_draw_line( tmesa, VERT(v0), VERT(v1) )
+#define RENDER_TRI( v0, v1, v2 ) \
+ trident_draw_triangle( tmesa, VERT(v0), VERT(v1), VERT(v2) )
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+ trident_draw_quad( tmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
+#define INIT(x) tridentRenderPrimitive( ctx, x );
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); \
+ const GLuint shift = tmesa->vertex_stride_shift; \
+ const char *tridentverts = (char *)tmesa->verts; \
+ const GLboolean stipple = ctx->Line.StippleFlag; \
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
+ (void) elt;
+#define RESET_STIPPLE if ( stipple ) tridentResetLineStipple( ctx );
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) (x)
+#define TAG(x) trident_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) trident_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+/**********************************************************************/
+/* Render clipped primitives */
+/**********************************************************************/
+
+static void tridentRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
+ GLuint n )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint prim = tmesa->render_primitive;
+
+ /* Render the new vertices as an unclipped polygon.
+ */
+ {
+ GLuint *tmp = VB->Elts;
+ VB->Elts = (GLuint *)elts;
+ tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
+ VB->Elts = tmp;
+ }
+
+ /* Restore the render primitive
+ */
+ if (prim != GL_POLYGON)
+ tnl->Driver.Render.PrimitiveNotify( ctx, prim );
+}
+
+static void tridentRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+
+#define _TRIDENT_NEW_RENDER_STATE (_DD_NEW_LINE_STIPPLE | \
+ _DD_NEW_LINE_SMOOTH | \
+ _DD_NEW_POINT_SMOOTH | \
+ _DD_NEW_TRI_SMOOTH | \
+ _DD_NEW_TRI_UNFILLED | \
+ _DD_NEW_TRI_LIGHT_TWOSIDE | \
+ _DD_NEW_TRI_OFFSET) \
+
+
+#define POINT_FALLBACK (DD_POINT_SMOOTH)
+#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
+#define TRI_FALLBACK (DD_TRI_SMOOTH)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
+
+
+static void tridentChooseRenderState(GLcontext *ctx)
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint flags = ctx->_TriangleCaps;
+ GLuint index = 0;
+
+ if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
+ tmesa->draw_point = trident_draw_point;
+ tmesa->draw_line = trident_draw_line;
+ tmesa->draw_tri = trident_draw_triangle;
+
+ if (flags & ANY_RASTER_FLAGS) {
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= TRIDENT_TWOSIDE_BIT;
+ if (flags & DD_TRI_OFFSET) index |= TRIDENT_OFFSET_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= TRIDENT_UNFILLED_BIT;
+ }
+
+ /* Hook in fallbacks for specific primitives.
+ */
+ if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) {
+ if (flags & POINT_FALLBACK) tmesa->draw_point = trident_fallback_point;
+ if (flags & LINE_FALLBACK) tmesa->draw_line = trident_fallback_line;
+ if (flags & TRI_FALLBACK) tmesa->draw_tri = trident_fallback_tri;
+ index |= TRIDENT_FALLBACK_BIT;
+ }
+ }
+
+ if (tmesa->RenderIndex != index) {
+ tmesa->RenderIndex = index;
+
+ tnl->Driver.Render.Points = rast_tab[index].points;
+ tnl->Driver.Render.Line = rast_tab[index].line;
+ tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+ tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+ if (tmesa->RenderIndex == 0) {
+ tnl->Driver.Render.PrimTabVerts = trident_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = trident_render_tab_elts;
+ } else {
+ tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+ }
+ tnl->Driver.Render.ClippedLine = tridentRenderClippedLine;
+ tnl->Driver.Render.ClippedPolygon = tridentRenderClippedPoly;
+ }
+}
+
+
+/**********************************************************************/
+/* High level hooks for t_vb_render.c */
+/**********************************************************************/
+
+
+
+/* Determine the rasterized primitive when not drawing unfilled
+ * polygons.
+ *
+ * Used only for the default render stage which always decomposes
+ * primitives to trianges/lines/points. For the accelerated stage,
+ * which renders strips as strips, the equivalent calculations are
+ * performed in tridentrender.c.
+ */
+
+static void tridentRasterPrimitive( GLcontext *ctx, GLuint hwprim )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ if (tmesa->hw_primitive != hwprim)
+ tmesa->hw_primitive = hwprim;
+}
+
+static void tridentRenderPrimitive( GLcontext *ctx, GLenum prim )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ tmesa->render_primitive = prim;
+}
+
+static void tridentRunPipeline( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+ if ( tmesa->new_state )
+ tridentDDUpdateHWState( ctx );
+
+ if (tmesa->new_gl_state) {
+#if 0
+ if (tmesa->new_gl_state & _NEW_TEXTURE)
+ tridentUpdateTextureState( ctx );
+#endif
+
+ if (!tmesa->Fallback) {
+ if (tmesa->new_gl_state & _TRIDENT_NEW_VERTEX)
+ tridentChooseVertexState( ctx );
+
+ if (tmesa->new_gl_state & _TRIDENT_NEW_RENDER_STATE)
+ tridentChooseRenderState( ctx );
+ }
+
+ tmesa->new_gl_state = 0;
+ }
+
+ _tnl_run_pipeline( ctx );
+}
+
+static void tridentRenderStart( GLcontext *ctx )
+{
+ /* Check for projective texturing. Make sure all texcoord
+ * pointers point to something. (fix in mesa?)
+ */
+ tridentCheckTexSizes( ctx );
+}
+
+static void tridentRenderFinish( GLcontext *ctx )
+{
+ if (0)
+ _swrast_flush( ctx ); /* never needed */
+}
+
+static void tridentResetLineStipple( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+ /* Reset the hardware stipple counter.
+ */
+}
+
+
+/**********************************************************************/
+/* Transition to/from hardware rasterization. */
+/**********************************************************************/
+
+
+void tridentFallback( tridentContextPtr tmesa, GLuint bit, GLboolean mode )
+{
+ GLcontext *ctx = tmesa->glCtx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint oldfallback = tmesa->Fallback;
+
+ _tnl_need_projected_coords( ctx, GL_FALSE );
+
+ if (mode) {
+ tmesa->Fallback |= bit;
+ if (oldfallback == 0) {
+ _swsetup_Wakeup( ctx );
+ tmesa->RenderIndex = ~0;
+ }
+ }
+ else {
+ tmesa->Fallback &= ~bit;
+ if (oldfallback == bit) {
+ _swrast_flush( ctx );
+ tnl->Driver.Render.Start = tridentRenderStart;
+ tnl->Driver.Render.PrimitiveNotify = tridentRenderPrimitive;
+ tnl->Driver.Render.Finish = tridentRenderFinish;
+ tnl->Driver.Render.BuildVertices = tridentBuildVertices;
+ tnl->Driver.Render.ResetLineStipple = tridentResetLineStipple;
+ tmesa->new_gl_state |= (_TRIDENT_NEW_RENDER_STATE|
+ _TRIDENT_NEW_VERTEX);
+ }
+ }
+}
+
+
+/**********************************************************************/
+/* Initialization. */
+/**********************************************************************/
+
+
+void tridentDDInitTriFuncs( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ static int firsttime = 1;
+
+ if (firsttime) {
+ init_rast_tab();
+ firsttime = 0;
+ }
+
+ tmesa->RenderIndex = ~0;
+
+ tnl->Driver.RunPipeline = tridentRunPipeline;
+ tnl->Driver.Render.Start = tridentRenderStart;
+ tnl->Driver.Render.Finish = tridentRenderFinish;
+ tnl->Driver.Render.PrimitiveNotify = tridentRenderPrimitive;
+ tnl->Driver.Render.ResetLineStipple = tridentResetLineStipple;
+ tnl->Driver.Render.BuildVertices = tridentBuildVertices;
+}
diff --git a/src/mesa/drivers/dri/trident/trident_vb.c b/src/mesa/drivers/dri/trident/trident_vb.c
new file mode 100644
index 00000000000..4c6e088da46
--- /dev/null
+++ b/src/mesa/drivers/dri/trident/trident_vb.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * Trident CyberBladeXP driver.
+ *
+ */
+#include "glheader.h"
+#include "mtypes.h"
+#include "mem.h"
+#include "macros.h"
+#include "colormac.h"
+#include "mmath.h"
+
+#include "swrast_setup/swrast_setup.h"
+#include "swrast/swrast.h"
+#include "tnl/t_context.h"
+#include "tnl/tnl.h"
+
+#include "trident_context.h"
+
+#define TRIDENT_TEX1_BIT 0x1
+#define TRIDENT_TEX0_BIT 0x2
+#define TRIDENT_RGBA_BIT 0x4
+#define TRIDENT_SPEC_BIT 0x8
+#define TRIDENT_FOG_BIT 0x10
+#define TRIDENT_XYZW_BIT 0x20
+#define TRIDENT_PTEX_BIT 0x40
+#define TRIDENT_MAX_SETUP 0x80
+
+static struct {
+ void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
+ interp_func interp;
+ copy_pv_func copy_pv;
+ GLboolean (*check_tex_sizes)( GLcontext *ctx );
+ GLuint vertex_size;
+ GLuint vertex_stride_shift;
+ GLuint vertex_format;
+} setup_tab[TRIDENT_MAX_SETUP];
+
+#define TINY_VERTEX_FORMAT 1
+#define NOTEX_VERTEX_FORMAT 2
+#define TEX0_VERTEX_FORMAT 3
+#define TEX1_VERTEX_FORMAT 4
+#define PROJ_TEX1_VERTEX_FORMAT 5
+#define TEX2_VERTEX_FORMAT 6
+#define TEX3_VERTEX_FORMAT 7
+#define PROJ_TEX3_VERTEX_FORMAT 8
+
+#define DO_XYZW (IND & TRIDENT_XYZW_BIT)
+#define DO_RGBA (IND & TRIDENT_RGBA_BIT)
+#define DO_SPEC (IND & TRIDENT_SPEC_BIT)
+#define DO_FOG (IND & TRIDENT_FOG_BIT)
+#define DO_TEX0 (IND & TRIDENT_TEX0_BIT)
+#define DO_TEX1 (IND & TRIDENT_TEX1_BIT)
+#define DO_TEX2 0
+#define DO_TEX3 0
+#define DO_PTEX (IND & TRIDENT_PTEX_BIT)
+
+#define VERTEX tridentVertex
+#define LOCALVARS tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+#define GET_VIEWPORT_MAT() tmesa->hw_viewport
+#define GET_TEXSOURCE(n) tmesa->tmu_source[n]
+#define GET_VERTEX_FORMAT() tmesa->vertex_format
+#define GET_VERTEX_STORE() tmesa->verts
+#define GET_VERTEX_STRIDE_SHIFT() tmesa->vertex_stride_shift
+#define GET_UBYTE_COLOR_STORE() &tmesa->UbyteColor
+#define GET_UBYTE_SPEC_COLOR_STORE() &tmesa->UbyteSecondaryColor
+
+#define HAVE_HW_VIEWPORT 0
+#define HAVE_HW_DIVIDE 0
+#define HAVE_RGBA_COLOR 0
+#define HAVE_TINY_VERTICES 1
+#define HAVE_NOTEX_VERTICES 1
+#define HAVE_TEX0_VERTICES 1
+#define HAVE_TEX1_VERTICES 1
+#define HAVE_TEX2_VERTICES 0
+#define HAVE_TEX3_VERTICES 0
+#define HAVE_PTEX_VERTICES 0
+
+#define UNVIEWPORT_VARS \
+ const GLfloat dx = - tmesa->drawX - SUBPIXEL_X; \
+ const GLfloat dy = (tmesa->driDrawable->h + \
+ tmesa->drawY + SUBPIXEL_Y); \
+ const GLfloat sz = 1.0 / tmesa->depth_scale
+
+#define UNVIEWPORT_X(x) x + dx;
+#define UNVIEWPORT_Y(y) - y + dy;
+#define UNVIEWPORT_Z(z) z * sz;
+
+#define PTEX_FALLBACK() tridentFallback(TRIDENT_CONTEXT(ctx), TRIDENT_FALLBACK_TEXTURE, 1)
+
+#define IMPORT_FLOAT_COLORS trident_import_float_colors
+#define IMPORT_FLOAT_SPEC_COLORS trident_import_float_spec_colors
+
+#define INTERP_VERTEX setup_tab[tmesa->SetupIndex].interp
+#define COPY_PV_VERTEX setup_tab[tmesa->SetupIndex].copy_pv
+
+/***********************************************************************
+ * Generate pv-copying and translation functions *
+ ***********************************************************************/
+
+#define TAG(x) trident_##x
+#include "tnl_dd/t_dd_vb.c"
+
+/***********************************************************************
+ * Generate vertex emit and interp functions *
+ ***********************************************************************/
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT)
+#define TAG(x) x##_wg
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_wgs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT)
+#define TAG(x) x##_wgf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_wgfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgfpt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_wgfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_wgfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_PTEX_BIT)
+#define TAG(x) x##_wgfspt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_TEX0_BIT)
+#define TAG(x) x##_t0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_t0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_FOG_BIT)
+#define TAG(x) x##_f
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_ft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_ft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT)
+#define TAG(x) x##_g
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_gs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gt0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gt0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT)
+#define TAG(x) x##_gf
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT)
+#define TAG(x) x##_gfs
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gft0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gft0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT)
+#define TAG(x) x##_gfst0
+#include "tnl_dd/t_dd_vbtmp.h"
+
+#define IND (TRIDENT_RGBA_BIT|TRIDENT_FOG_BIT|TRIDENT_SPEC_BIT|TRIDENT_TEX0_BIT|TRIDENT_TEX1_BIT)
+#define TAG(x) x##_gfst0t1
+#include "tnl_dd/t_dd_vbtmp.h"
+
+static void init_setup_tab( void )
+{
+ init_wg();
+ init_wgs();
+ init_wgt0();
+ init_wgt0t1();
+ init_wgpt0();
+ init_wgst0();
+ init_wgst0t1();
+ init_wgspt0();
+ init_wgf();
+ init_wgfs();
+ init_wgft0();
+ init_wgft0t1();
+ init_wgfpt0();
+ init_wgfst0();
+ init_wgfst0t1();
+ init_wgfspt0();
+ init_t0();
+ init_t0t1();
+ init_f();
+ init_ft0();
+ init_ft0t1();
+ init_g();
+ init_gs();
+ init_gt0();
+ init_gt0t1();
+ init_gst0();
+ init_gst0t1();
+ init_gf();
+ init_gfs();
+ init_gft0();
+ init_gft0t1();
+ init_gfst0();
+ init_gfst0t1();
+}
+
+void tridentBuildVertices( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint newinputs )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT( ctx );
+ GLubyte *v = ((GLubyte *)tmesa->verts + (start<<tmesa->vertex_stride_shift));
+ GLuint stride = 1<<tmesa->vertex_stride_shift;
+
+ newinputs |= tmesa->SetupNewInputs;
+ tmesa->SetupNewInputs = 0;
+
+ if (!newinputs)
+ return;
+
+ if (newinputs & VERT_CLIP) {
+ setup_tab[tmesa->SetupIndex].emit( ctx, start, count, v, stride );
+ } else {
+ GLuint ind = 0;
+
+ if (newinputs & VERT_RGBA)
+ ind |= TRIDENT_RGBA_BIT;
+
+ if (newinputs & VERT_SPEC_RGB)
+ ind |= TRIDENT_SPEC_BIT;
+
+ if (newinputs & VERT_TEX0)
+ ind |= TRIDENT_TEX0_BIT;
+
+ if (newinputs & VERT_TEX1)
+ ind |= TRIDENT_TEX1_BIT;
+
+ if (newinputs & VERT_FOG_COORD)
+ ind |= TRIDENT_FOG_BIT;
+
+ if (tmesa->SetupIndex & TRIDENT_PTEX_BIT)
+ ind = ~0;
+
+ ind &= tmesa->SetupIndex;
+
+ if (ind) {
+ setup_tab[ind].emit( ctx, start, count, v, stride );
+ }
+ }
+}
+
+void tridentCheckTexSizes( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT( ctx );
+
+ if (!setup_tab[tmesa->SetupIndex].check_tex_sizes(ctx)) {
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ /* Invalidate stored verts
+ */
+ tmesa->SetupNewInputs = ~0;
+ tmesa->SetupIndex |= TRIDENT_PTEX_BIT;
+
+ if (!tmesa->Fallback &&
+ !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+ tnl->Driver.Render.Interp = setup_tab[tmesa->SetupIndex].interp;
+ tnl->Driver.Render.CopyPV = setup_tab[tmesa->SetupIndex].copy_pv;
+ }
+ }
+}
+
+void tridentChooseVertexState( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint ind = TRIDENT_XYZW_BIT|TRIDENT_RGBA_BIT;
+
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+ ind |= TRIDENT_SPEC_BIT;
+
+ if (ctx->Fog.Enabled)
+ ind |= TRIDENT_FOG_BIT;
+
+ if (ctx->Texture._ReallyEnabled) {
+ ind |= TRIDENT_TEX0_BIT;
+ if (ctx->Texture.Unit[0]._ReallyEnabled &&
+ ctx->Texture.Unit[1]._ReallyEnabled) {
+ ind |= TRIDENT_TEX1_BIT;
+ }
+ }
+
+ tmesa->SetupIndex = ind;
+
+ if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
+ tnl->Driver.Render.Interp = trident_interp_extras;
+ tnl->Driver.Render.CopyPV = trident_copy_pv_extras;
+ } else {
+ tnl->Driver.Render.Interp = setup_tab[ind].interp;
+ tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+ }
+
+ if (setup_tab[ind].vertex_format != tmesa->vertex_format) {
+ tmesa->vertex_format = setup_tab[ind].vertex_format;
+ tmesa->vertex_size = setup_tab[ind].vertex_size;
+ tmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
+ }
+}
+
+void tridentInitVB( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+ GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+
+ tmesa->verts = (char *)ALIGN_MALLOC( size * 16 * 4, 32 );
+
+ {
+ static int firsttime = 1;
+ if (firsttime) {
+ init_setup_tab();
+ firsttime = 0;
+ }
+ }
+}
+
+void tridentFreeVB( GLcontext *ctx )
+{
+ tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx);
+
+ if (tmesa->verts) {
+ ALIGN_FREE(tmesa->verts);
+ tmesa->verts = 0;
+ }
+
+ if (tmesa->UbyteSecondaryColor.Ptr) {
+ ALIGN_FREE(tmesa->UbyteSecondaryColor.Ptr);
+ tmesa->UbyteSecondaryColor.Ptr = 0;
+ }
+
+ if (tmesa->UbyteColor.Ptr) {
+ ALIGN_FREE(tmesa->UbyteColor.Ptr);
+ tmesa->UbyteColor.Ptr = 0;
+ }
+}