Browse Source

Import s3virge and trident drivers. Not functional yet; no Makefile, no DRI-aware DDX.

tags/unichrome-last-xinerama
Adam Jackson 20 years ago
parent
commit
c403bcb8a7

+ 258
- 0
src/mesa/drivers/dri/s3v/s3v_context.c View File

@@ -0,0 +1,258 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "s3v_context.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"


#include "s3v_vb.h"
#include "s3v_tris.h"

#if 0
extern const struct gl_pipeline_stage _s3v_render_stage;

static const struct gl_pipeline_stage *s3v_pipeline[] = {
&_tnl_vertex_transform_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
/* REMOVE: point attenuation stage */
#if 1
&_s3v_render_stage, /* ADD: unclipped rastersetup-to-dma */
#endif
&_tnl_render_stage,
0,
};
#endif

GLboolean s3vCreateContext( Display *dpy, const __GLcontextModes *glVisual,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate)
{
GLcontext *ctx, *shareCtx;
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
s3vContextPtr vmesa;
s3vScreenPtr s3vScrn;
S3VSAREAPtr saPriv=(S3VSAREAPtr)(((char*)sPriv->pSAREA)+
sizeof(XF86DRISAREARec));

DEBUG_WHERE(("*** s3vCreateContext ***\n"));

vmesa = (s3vContextPtr) CALLOC( sizeof(*vmesa) );
if ( !vmesa ) return GL_FALSE;

/* Allocate the Mesa context */
if (sharedContextPrivate)
shareCtx = ((s3vContextPtr) sharedContextPrivate)->glCtx;
else
shareCtx = NULL;

vmesa->glCtx = _mesa_create_context(glVisual, shareCtx, vmesa, GL_TRUE);
if (!vmesa->glCtx) {
FREE(vmesa);
return GL_FALSE;
}

vmesa->display = dpy;

vmesa->driContext = driContextPriv;
vmesa->driScreen = sPriv;
vmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */

vmesa->hHWContext = driContextPriv->hHWContext;
vmesa->driHwLock = &sPriv->pSAREA->lock;
vmesa->driFd = sPriv->fd;
vmesa->sarea = saPriv;

s3vScrn = vmesa->s3vScreen = (s3vScreenPtr)(sPriv->private);

ctx = vmesa->glCtx;

ctx->Const.MaxTextureLevels = 11; /* it is (11-1) -> 1024 * 1024 FIXME */

ctx->Const.MaxTextureUnits = 1; /* FIXME: or 2 ? */

/* No wide points.
*/
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
ctx->Const.MaxPointSize = 1.0;
ctx->Const.MaxPointSizeAA = 1.0;

/* No wide lines.
*/
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 1.0;
ctx->Const.MaxLineWidthAA = 1.0;
ctx->Const.LineWidthGranularity = 1.0;

vmesa->texHeap = mmInit( 0, vmesa->s3vScreen->textureSize );
DEBUG(("vmesa->s3vScreen->textureSize = 0x%x\n",
vmesa->s3vScreen->textureSize));
/* NOTE */
/* mmInit(offset, size); */

/* allocates a structure like this:

struct mem_block_t {
struct mem_block_t *next;
struct mem_block_t *heap;
int ofs,size;
int align;
int free:1;
int reserved:1;
};

*/

make_empty_list(&vmesa->TexObjList);
make_empty_list(&vmesa->SwappedOut);

vmesa->CurrentTexObj[0] = 0;
vmesa->CurrentTexObj[1] = 0; /* FIXME */

vmesa->RenderIndex = ~0;

/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );

/* Install the customized pipeline:
*/
#if 0
_tnl_destroy_pipeline( ctx );
_tnl_install_pipeline( ctx, s3v_pipeline );
#endif
/* Configure swrast to match hardware characteristics:
*/
#if 0
_swrast_allow_pixel_fog( ctx, GL_FALSE );
_swrast_allow_vertex_fog( ctx, GL_TRUE );
#endif
vmesa->_3d_mode = 0;

/* 3D lines / gouraud tris */
vmesa->CMD = ( AUTO_EXEC_ON | HW_CLIP_ON | DEST_COL_1555
| FOG_OFF | ALPHA_OFF | Z_OFF | Z_UPDATE_OFF
| Z_LESS | TEX_WRAP_ON | TEX_MODULATE | LINEAR
| TEX_COL_ARGB1555 | CMD_3D );

vmesa->_alpha[0] = vmesa->_alpha[1] = ALPHA_OFF;
vmesa->alpha_cmd = vmesa->_alpha[0];
vmesa->_tri[0] = DO_GOURAUD_TRI;
vmesa->_tri[1] = DO_TEX_LIT_TRI;
vmesa->prim_cmd = vmesa->_tri[0];

/* printf("first vmesa->CMD = 0x%x\n", vmesa->CMD); */

vmesa->TexOffset = vmesa->s3vScreen->texOffset;

s3vInitVB( ctx );
s3vInitExtensions( ctx );
s3vInitDriverFuncs( ctx );
s3vInitStateFuncs( ctx );
s3vInitSpanFuncs( ctx );
s3vInitTextureFuncs( ctx );
s3vInitTriFuncs( ctx );
s3vInitState( vmesa );

driContextPriv->driverPrivate = (void *)vmesa;

/* HACK */
vmesa->bufSize = S3V_DMA_BUF_SZ;

DEBUG(("vmesa->bufSize = %i\n", vmesa->bufSize));
DEBUG(("vmesa->bufCount = %i\n", vmesa->bufCount));


/* dma init */
DEBUG_BUFS(("GET_FIRST_DMA\n"));
vmesa->_bufNum = 0;

GET_FIRST_DMA(vmesa->driFd, vmesa->hHWContext,
1, &(vmesa->bufIndex[0]), &(vmesa->bufSize),
&vmesa->_buf[0], &vmesa->bufCount, s3vScrn);

GET_FIRST_DMA(vmesa->driFd, vmesa->hHWContext,
1, &(vmesa->bufIndex[1]), &(vmesa->bufSize),
&vmesa->_buf[1], &vmesa->bufCount, s3vScrn);

vmesa->buf = vmesa->_buf[vmesa->_bufNum];
/*
vmesa->CMD = (AUTO_EXEC_ON | HW_CLIP_ON | DEST_COL_1555
| FOG_OFF | ALPHA_OFF | Z_OFF | Z_UPDATE_OFF
| DO_GOURAUD_TRI | CMD_3D);

vmesa->TexOffset = vmesa->s3vScreen->texOffset;
*/

/* ... but we should support only 15 bit in virge (out of 8/15/24)... */

DEBUG(("glVisual->depthBits = %i\n", glVisual->depthBits));

switch (glVisual->depthBits) {
case 8:
break;
case 15:
case 16:
vmesa->depth_scale = 1.0f / 0xffff;
break;
case 24:
vmesa->depth_scale = 1.0f / 0xffffff;
break;
default:
break;
}

vmesa->cull_zero = 0.0f;

vmesa->DepthSize = glVisual->depthBits;
vmesa->Flags = S3V_FRONT_BUFFER;
vmesa->Flags |= (glVisual->doubleBufferMode ? S3V_BACK_BUFFER : 0);
vmesa->Flags |= (vmesa->DepthSize > 0 ? S3V_DEPTH_BUFFER : 0);

vmesa->EnabledFlags = S3V_FRONT_BUFFER;
vmesa->EnabledFlags |= (glVisual->doubleBufferMode ? S3V_BACK_BUFFER : 0);


if (vmesa->Flags & S3V_BACK_BUFFER) {
vmesa->readOffset = vmesa->drawOffset = vmesa->s3vScreen->backOffset;
} else {
vmesa->readOffset = vmesa->drawOffset = 0;
}

s3vInitHW( vmesa );

driContextPriv->driverPrivate = (void *)vmesa;

return GL_TRUE;
}

+ 443
- 0
src/mesa/drivers/dri/s3v/s3v_context.h View File

@@ -0,0 +1,443 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef _S3V_CONTEXT_H_
#define _S3V_CONTEXT_H_

#include "dri_util.h"

#include "s3v_dri.h"
#include "s3v_regs.h"
#include "s3v_macros.h"
#include "s3v_screen.h"
#include "macros.h"
#include "mtypes.h"
#include "drm.h"
#include "mm.h"

/* Flags for context */
#define S3V_FRONT_BUFFER 0x00000001
#define S3V_BACK_BUFFER 0x00000002
#define S3V_DEPTH_BUFFER 0x00000004

/* FIXME: check */
#define S3V_MAX_TEXTURE_SIZE 2048

/* These are the minimum requirements and should probably be increased */
#define MAX_MODELVIEW_STACK 16
#define MAX_PROJECTION_STACK 2
#define MAX_TEXTURE_STACK 2

extern void s3vDDUpdateHWState(GLcontext *ctx);
extern s3vScreenPtr s3vCreateScreen(__DRIscreenPrivate *sPriv);
extern void s3vDestroyScreen(__DRIscreenPrivate *sPriv);
extern GLboolean s3vCreateContext( Display *dpy,
const __GLcontextModes *glVisual,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);

#define S3V_UPLOAD_ALL 0xffffffff
/* #define S3V_UPLOAD_CLIPRECTS 0x00000002 */
#define S3V_UPLOAD_ALPHA 0x00000004
#define S3V_UPLOAD_BLEND 0x00000008
#define S3V_UPLOAD_DEPTH 0x00000010
#define S3V_UPLOAD_VIEWPORT 0x00000020
#define S3V_UPLOAD_SHADE 0x00000040
#define S3V_UPLOAD_CLIP 0x00000080
#define S3V_UPLOAD_MASKS 0x00000100
#define S3V_UPLOAD_WINDOW 0x00000200 /* defunct */
#define S3V_UPLOAD_GEOMETRY 0x00000400
#define S3V_UPLOAD_POLYGON 0x00000800
#define S3V_UPLOAD_DITHER 0x00001000
#define S3V_UPLOAD_LOGICOP 0x00002000
#define S3V_UPLOAD_FOG 0x00004000
#define S3V_UPLOAD_LIGHT 0x00008000
#define S3V_UPLOAD_CONTEXT 0x00010000
#define S3V_UPLOAD_TEX0 0x00020000
#define S3V_UPLOAD_STIPPLE 0x00040000
#define S3V_UPLOAD_TRANSFORM 0x00080000
#define S3V_UPLOAD_LINEMODE 0x00100000
#define S3V_UPLOAD_POINTMODE 0x00200000
#define S3V_UPLOAD_TRIMODE 0x00400000

#define S3V_NEW_CLIP 0x00000001
#define S3V_NEW_WINDOW 0x00000002
#define S3V_NEW_CONTEXT 0x00000004
#define S3V_NEW_TEXTURE 0x00000008 /* defunct */
#define S3V_NEW_ALPHA 0x00000010
#define S3V_NEW_DEPTH 0x00000020
#define S3V_NEW_MASKS 0x00000040
#define S3V_NEW_POLYGON 0x00000080
#define S3V_NEW_CULL 0x00000100
#define S3V_NEW_LOGICOP 0x00000200
#define S3V_NEW_FOG 0x00000400
#define S3V_NEW_LIGHT 0x00000800
#define S3V_NEW_STIPPLE 0x00001000
#define S3V_NEW_ALL 0xffffffff

#define S3V_FALLBACK_TRI 0x00000001
#define S3V_FALLBACK_TEXTURE 0x00000002

struct s3v_context;
typedef struct s3v_context s3vContextRec;
typedef struct s3v_context *s3vContextPtr;
typedef struct s3v_texture_object_t *s3vTextureObjectPtr;

#define VALID_S3V_TEXTURE_OBJECT(tobj) (tobj)

#define S3V_TEX_MAXLEVELS 12

/* For shared texture space managment, these texture objects may also
* be used as proxies for regions of texture memory containing other
* client's textures. Such proxy textures (not to be confused with GL
* proxy textures) are subject to the same LRU aging we use for our
* own private textures, and thus we have a mechanism where we can
* fairly decide between kicking out our own textures and those of
* other clients.
*
* Non-local texture objects have a valid MemBlock to describe the
* region managed by the other client, and can be identified by
* 't->globj == 0'
*/
struct s3v_texture_object_t {
struct s3v_texture_object_t *next, *prev;

GLuint age;
struct gl_texture_object *globj;
int Pitch;
int Height;
int WidthLog2;
int texelBytes;
int totalSize;
int bound;

PMemBlock MemBlock;
GLuint BufAddr;
GLuint min_level;
GLuint max_level;
GLuint dirty_images;

GLint firstLevel, lastLevel; /* upload tObj->Image[first .. lastLevel] */

struct {
const struct gl_texture_image *image;
int offset; /* into BufAddr */
int height;
int internalFormat;
} image[S3V_TEX_MAXLEVELS];

CARD32 TextureCMD;

CARD32 TextureColorMode;
CARD32 TextureFilterMode;
CARD32 TextureBorderColor;
CARD32 TextureWrap;
CARD32 TextureMipSize;

CARD32 TextureBaseAddr[S3V_TEX_MAXLEVELS];
CARD32 TextureFormat;
CARD32 TextureReadMode;
};

#define S3V_NO_PALETTE 0x0
#define S3V_USE_PALETTE 0x1
#define S3V_UPDATE_PALETTE 0x2
#define S3V_FALLBACK_PALETTE 0x4

void s3vUpdateTextureState( GLcontext *ctx );

void s3vDestroyTexObj( s3vContextPtr vmesa, s3vTextureObjectPtr t);
void s3vUploadTexImages( s3vContextPtr vmesa, s3vTextureObjectPtr t );

void s3vResetGlobalLRU( s3vContextPtr vmesa );
void s3vTexturesGone( s3vContextPtr vmesa,
GLuint start, GLuint end,
GLuint in_use );

void s3vEmitHwState( s3vContextPtr vmesa );
void s3vGetLock( s3vContextPtr vmesa, GLuint flags );
void s3vInitExtensions( GLcontext *ctx );
void s3vInitDriverFuncs( GLcontext *ctx );
void s3vInitSpanFuncs( GLcontext *ctx );
void s3vInitState( s3vContextPtr vmesa );
void s3vInitHW( s3vContextPtr vmesa );
void s3vInitStateFuncs( GLcontext *ctx );
void s3vInitTextureFuncs( GLcontext *ctx );
void s3vInitTriFuncs( GLcontext *ctx );

void s3vUpdateWindow( GLcontext *ctx );
void s3vUpdateViewportOffset( GLcontext *ctx );

void s3vPrintLocalLRU( s3vContextPtr vmesa );
void s3vPrintGlobalLRU( s3vContextPtr vmesa );

extern void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode );
#define FALLBACK( imesa, bit, mode ) s3vFallback( imesa, bit, mode )

/* Use the templated vertex formats. Only one of these is used in s3v.
*/
#define TAG(x) s3v##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG

typedef void (*s3v_quad_func)( s3vContextPtr,
const s3vVertex *,
const s3vVertex *,
const s3vVertex *,
const s3vVertex * );
typedef void (*s3v_tri_func)( s3vContextPtr,
const s3vVertex *,
const s3vVertex *,
const s3vVertex * );
typedef void (*s3v_line_func)( s3vContextPtr,
const s3vVertex *,
const s3vVertex * );
typedef void (*s3v_point_func)( s3vContextPtr,
const s3vVertex * );


/* static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end); */
typedef void (*emit_func)( GLcontext *, GLuint, GLuint);

struct s3v_context {
GLcontext *glCtx; /* Mesa context */

__DRIcontextPrivate *driContext;
__DRIscreenPrivate *driScreen;
__DRIdrawablePrivate *driDrawable;

GLuint new_gl_state;
GLuint new_state;
GLuint dirty;

S3VSAREAPtr sarea;

/* 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 */

drmContext hHWContext;
drmLock *driHwLock;
int driFd;

GLuint numClipRects; /* Cliprects for the draw buffer */
XF86DRIClipRectPtr pClipRects;

CARD32* buf; /* FIXME */
CARD32* _buf[2];
int _bufNum;
int bufIndex[2];
int bufSize;
int bufCount;

s3vScreenPtr s3vScreen; /* Screen private DRI data */

int drawOffset;
int readOffset;

s3v_point_func draw_point;
s3v_line_func draw_line;
s3v_tri_func draw_tri;
s3v_quad_func draw_quad;

GLuint Fallback;
GLuint RenderIndex;
GLuint SetupNewInputs;
GLuint SetupIndex;

GLuint vertex_format;
GLuint vertex_size;
GLuint vertex_stride_shift;
char *verts;

GLfloat hw_viewport[16];
GLuint hw_primitive;
GLenum render_primitive;

GLfloat depth_scale;

s3vTextureObjectPtr CurrentTexObj[2];
struct s3v_texture_object_t TexObjList;
struct s3v_texture_object_t SwappedOut;
GLenum TexEnvImageFmt[2];

memHeap_t *texHeap;

int lastSwap;
int texAge;
int ctxAge;
int dirtyAge;
int lastStamp;

/* max was here: don't touch */
unsigned int S3V_REG[S3V_REGS_NUM];

CARD32 texMode;
CARD32 alphaMode;
CARD32 lightMode;

CARD32 SrcBase;
CARD32 DestBase;
CARD32 DestBlit;
CARD32 ScissorLR;
CARD32 ScissorTB;
CARD32 ScissorWH; /* SubScissorWH */ /* RectWH */
CARD32 FrontStride;
CARD32 BackStride;
CARD32 SrcStride;
CARD32 DestStride;
CARD32 SrcXY;
CARD32 DestXY;

CARD32 ClearColor;
CARD32 Color;
CARD32 DitherMode;
CARD32 ClearDepth;

CARD32 TextureBorderColor;
CARD32 TexOffset;
CARD32 TexStride;

CARD32 CMD;
CARD32 prim_cmd;
CARD32 _tri[2]; /* 0 = gouraud; 1 = tex (lit or unlit) */
CARD32 alpha_cmd; /* actual alpha cmd */
CARD32 _alpha[2];
CARD32 _alpha_tex; /* tex alpha type */
/* (3d_mode) 0 = 3d line/gourad tri; 1 = 3d tex tri */
CARD32 _3d_mode;
GLfloat backface_sign;
GLfloat cull_zero;

int restore_primitive;

/* *** 2check *** */

CARD32 FogMode;
CARD32 AreaStippleMode;
CARD32 LBReadFormat;
CARD32 LBWriteFormat;
CARD32 LineMode;
CARD32 PointMode;
CARD32 TriangleMode;
CARD32 AntialiasMode;
GLfloat ViewportScaleX;
GLfloat ViewportScaleY;
GLfloat ViewportScaleZ;
GLfloat ViewportOffsetX;
GLfloat ViewportOffsetY;
GLfloat ViewportOffsetZ;
int MatrixMode;
int DepthMode;
int TransformMode;
int LBReadMode;
int FBReadMode;
int FBWindowBase;
int LBWindowBase;
int ColorDDAMode;
int GeometryMode;
int AlphaTestMode;
int AlphaBlendMode;
int AB_FBReadMode;
int AB_FBReadMode_Save;
int DeltaMode;
int ColorMaterialMode;
int FBHardwareWriteMask;
int MaterialMode;
int NormalizeMode;
int LightingMode;
int Light0Mode;
int Light1Mode;
int Light2Mode;
int Light3Mode;
int Light4Mode;
int Light5Mode;
int Light6Mode;
int Light7Mode;
int Light8Mode;
int Light9Mode;
int Light10Mode;
int Light11Mode;
int Light12Mode;
int Light13Mode;
int Light14Mode;
int Light15Mode;
int LogicalOpMode;
int ScissorMode;
int ScissorMaxXY;
int ScissorMinXY;
int Window; /* GID part probably should be in draw priv */
int WindowOrigin;
int x, y, w, h; /* Probably should be in drawable priv */
int FrameCount; /* Probably should be in drawable priv */
int NotClipped; /* Probably should be in drawable priv */
int WindowChanged; /* Probably should be in drawabl... */
int Flags;
int EnabledFlags;
int DepthSize;
int Begin;
GLenum ErrorValue;
int Texture1DEnabled;
int Texture2DEnabled;

float ModelView[16];
float Proj[16];
float ModelViewProj[16];
float Texture[16];

float ModelViewStack[(MAX_MODELVIEW_STACK-1)*16];
int ModelViewCount;
float ProjStack[(MAX_PROJECTION_STACK-1)*16];
int ProjCount;
float TextureStack[(MAX_TEXTURE_STACK-1)*16];
int TextureCount;
};

#define S3VIRGEPACKCOLOR555( r, g, b, a ) \
((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
((a) ? 0x8000 : 0))

#define S3VIRGEPACKCOLOR565( r, g, b ) \
((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))

#define S3VIRGEPACKCOLOR888( r, g, b ) \
(((r) << 16) | ((g) << 8) | (b))

#define S3VIRGEPACKCOLOR8888( r, g, b, a ) \
(((a) << 24) | ((r) << 16) | ((g) << 8) | (b))

#define S3VIRGEPACKCOLOR4444( r, g, b, a ) \
((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))

static __inline GLuint s3vPackColor( GLuint cpp,
GLubyte r, GLubyte g,
GLubyte b, GLubyte a )
{
unsigned int ret;
DEBUG(("cpp = %i, r=0x%x, g=0x%x, b=0x%x, a=0x%x\n", cpp, r, g, b, a));

switch ( cpp ) {
case 2:
ret = S3VIRGEPACKCOLOR555( r, g, b, a );
DEBUG(("ret = 0x%x\n", ret));
return ret;
case 4:
return PACK_COLOR_8888( a, r, g, b );
default:
return 0;
}
}

#define S3V_CONTEXT(ctx) ((s3vContextPtr)(ctx->DriverCtx))

#endif /* _S3V_CONTEXT_H_ */

+ 107
- 0
src/mesa/drivers/dri/s3v/s3v_dd.c View File

@@ -0,0 +1,107 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "s3v_context.h"
#include "s3v_vb.h"
#include "s3v_lock.h"
#if defined(USE_X86_ASM)
#include "X86/common_x86_asm.h"
#endif

#include "context.h"
#include "swrast/swrast.h"

#define S3V_DATE "20020207"


/* Return the width and height of the current color buffer.
*/
static void s3vDDGetBufferSize( GLframebuffer *buffer,
GLuint *width, GLuint *height )
{
GET_CURRENT_CONTEXT(ctx);
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

/* S3VHW_LOCK( vmesa ); */
*width = vmesa->driDrawable->w;
*height = vmesa->driDrawable->h;
/* S3VHW_UNLOCK( vmesa ); */
}


/* Return various strings for glGetString().
*/
static const GLubyte *s3vDDGetString( GLcontext *ctx, GLenum name )
{
static char buffer[128];

switch ( name ) {
case GL_VENDOR:
return (GLubyte *)"Max Lingua (ladybug)";

case GL_RENDERER:
sprintf( buffer, "Mesa DRI S3 Virge " S3V_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 s3vInitExtensions( GLcontext *ctx )
{
/* None... */
}

/* Initialize the driver's misc functions.
*/
void s3vInitDriverFuncs( GLcontext *ctx )
{
ctx->Driver.GetBufferSize = s3vDDGetBufferSize;
ctx->Driver.GetString = s3vDDGetString;

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;
}

+ 79
- 0
src/mesa/drivers/dri/s3v/s3v_inithw.c View File

@@ -0,0 +1,79 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include <sys/ioctl.h>

#include "s3v_context.h"

void s3vInitHW( s3vContextPtr vmesa )
{
int i;
static short _reset = 1;

DEBUG(("vmesa->driDrawable = %p\n", vmesa->driDrawable));
DEBUG(("stride = %i\n",
vmesa->driScreen->fbWidth*vmesa->s3vScreen->cpp));
DEBUG(("frontOffset = 0x%x\n", vmesa->s3vScreen->frontOffset));
DEBUG(("backOffset = 0x%x\n", vmesa->s3vScreen->backOffset));
DEBUG(("depthOffset = 0x%x\n", vmesa->s3vScreen->depthOffset));
DEBUG(("textureOffset = 0x%x\n", vmesa->s3vScreen->texOffset));

/* if (_reset) { */
/* ioctl(vmesa->driFd, 0x4a); */
ioctl(vmesa->driFd, 0x41); /* reset */
_reset = 0;
/* ioctl(vmesa->driFd, 0x4c); */
/* } */

/* FIXME */
switch (vmesa->s3vScreen->cpp) {
case 2:
break;
case 4:
break;
}

/* FIXME for stencil, gid, etc */
switch (vmesa->DepthSize) {
case 15:
case 16:
break;
case 24:
break;
case 32:
break;
}

vmesa->FogMode = 1;
vmesa->ClearDepth = 0xffff;
vmesa->x = 0;
vmesa->y = 0;
vmesa->w = 0;
vmesa->h = 0;
vmesa->FrameCount = 0;
vmesa->MatrixMode = GL_MODELVIEW;
vmesa->ModelViewCount = 0;
vmesa->ProjCount = 0;
vmesa->TextureCount = 0;


/* FIXME: do we need the following? */

for (i = 0; i < 16; i++)
if (i % 5 == 0)
vmesa->ModelView[i] =
vmesa->Proj[i] =
vmesa->ModelViewProj[i] =
vmesa->Texture[i] = 1.0;
else
vmesa->ModelView[i] =
vmesa->Proj[i] =
vmesa->ModelViewProj[i] =
vmesa->Texture[i] = 0.0;

vmesa->LBWindowBase = vmesa->driScreen->fbWidth *
(vmesa->driScreen->fbHeight - 1);
vmesa->FBWindowBase = vmesa->driScreen->fbWidth *
(vmesa->driScreen->fbHeight - 1);
}

+ 62
- 0
src/mesa/drivers/dri/s3v/s3v_lock.c View File

@@ -0,0 +1,62 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "s3v_context.h"

#if DEBUG_LOCKING
char *prevLockFile = NULL;
int prevLockLine = 0;
#endif


/* Update the hardware state. This is called if another context has
* grabbed the hardware lock, which includes the X server. This
* function also updates the driver's window state after the X server
* moves, resizes or restacks a window -- the change will be reflected
* in the drawable position and clip rects. Since the X server grabs
* the hardware lock when it changes the window state, this routine will
* automatically be called after such a change.
*/
void s3vGetLock( s3vContextPtr vmesa, GLuint flags )
{
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
/* __DRIscreenPrivate *sPriv = vmesa->driScreen; */

printf("s3vGetLock <- ***\n");

drmGetLock( vmesa->driFd, vmesa->hHWContext, flags );

/* The window might have moved, so we might need to get new clip
* rects.
*
* NOTE: This releases and regrabs the hw lock to allow the X server
* to respond to the DRI protocol request for new drawable info.
* Since the hardware state depends on having the latest drawable
* clip rects, all state checking must be done _after_ this call.
*/
/* DRI_VALIDATE_DRAWABLE_INFO( vmesa->display, sPriv, dPriv ); */

if ( vmesa->lastStamp != dPriv->lastStamp ) {
vmesa->lastStamp = dPriv->lastStamp;
vmesa->new_state |= S3V_NEW_WINDOW | S3V_NEW_CLIP;
}

vmesa->numClipRects = dPriv->numClipRects;
vmesa->pClipRects = dPriv->pClipRects;

#if 0
vmesa->dirty = ~0;

if ( sarea->ctxOwner != vmesa->hHWContext ) {
sarea->ctxOwner = vmesa->hHWContext;
vmesa->dirty = S3V_UPLOAD_ALL;
}

for ( i = 0 ; i < vmesa->lastTexHeap ; i++ ) {
if ( sarea->texAge[i] != vmesa->lastTexAge[i] ) {
s3vAgeTextures( vmesa, i );
}
}
#endif
}

+ 103
- 0
src/mesa/drivers/dri/s3v/s3v_lock.h View File

@@ -0,0 +1,103 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef __S3V_LOCK_H__
#define __S3V_LOCK_H__

#include <sys/ioctl.h>

#ifdef GLX_DIRECT_RENDERING

extern void s3vGetLock( s3vContextPtr vmesa, GLuint flags );

/* Turn DEBUG_LOCKING on to find locking conflicts.
*/
#define DEBUG_LOCKING 0

#if DEBUG_LOCKING
extern char *prevLockFile;
extern int prevLockLine;

#define DEBUG_LOCK() \
do { \
prevLockFile = (__FILE__); \
prevLockLine = (__LINE__); \
} while (0)

#define DEBUG_RESET() \
do { \
prevLockFile = 0; \
prevLockLine = 0; \
} while (0)

#define DEBUG_CHECK_LOCK() \
do { \
if ( prevLockFile ) { \
fprintf( stderr, \
"LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
exit(1); \
} \
} while (0)

#else

#define DEBUG_LOCK()
#define DEBUG_RESET()
#define DEBUG_CHECK_LOCK()

#endif

/*
* !!! We may want to separate locks from locks with validation. This
* could be used to improve performance for those things commands that
* do not do any drawing !!!
*/

/* Lock the hardware and validate our state.
*/
#define LOCK_HARDWARE( vmesa ) \
do { \
char __ret = 0; \
DEBUG_CHECK_LOCK(); \
DRM_CAS( vmesa->driHwLock, vmesa->hHWContext, \
(DRM_LOCK_HELD | vmesa->hHWContext), __ret ); \
if ( __ret ) \
s3vGetLock( vmesa, 0 ); \
DEBUG_LOCK(); \
} while (0)

/* Unlock the hardware.
*/
#define UNLOCK_HARDWARE( vmesa ) \
do { \
DRM_UNLOCK( vmesa->driFd, \
vmesa->driHwLock, \
vmesa->hHWContext ); \
DEBUG_RESET(); \
} while (0)

#endif

#define S3VHW_LOCK( vmesa ) \
DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext); \
DRM_SPINLOCK(&vmesa->driScreen->pSAREA->drawable_lock, \
vmesa->driScreen->drawLockID); \
/* VALIDATE_DRAWABLE_INFO_NO_LOCK(vmesa); */

#define S3VHW_UNLOCK( vmesa ) \
DRM_SPINUNLOCK(&vmesa->driScreen->pSAREA->drawable_lock, \
vmesa->driScreen->drawLockID); \
/* VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(vmesa); */

#define S3V_SIMPLE_LOCK( vmesa ) \
ioctl(vmesa->driFd, 0x4a)

#define S3V_SIMPLE_FLUSH_LOCK( vmesa ) \
ioctl(vmesa->driFd, 0x4b)

#define S3V_SIMPLE_UNLOCK( vmesa ) \
ioctl(vmesa->driFd, 0x4c)

#endif /* __S3V_LOCK_H__ */

+ 233
- 0
src/mesa/drivers/dri/s3v/s3v_macros.h View File

@@ -0,0 +1,233 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef _S3V_MACROS_H_
#define _S3V_MACROS_H_

#ifdef GLX_DIRECT_RENDERING

/**************/
/* DRI macros */
/**************/

#define GENERIC_DEBUG 0
#define FLOW_DEBUG 0
#define DMABUFS_DEBUG 0

/* Note: The argument to DEBUG*() _must_ be enclosed in parenthesis */

#if (GENERIC_DEBUG || FLOW_DEBUG || DMABUFS_DEBUG)
#include <stdio.h>
#endif

#if GENERIC_DEBUG
#define DEBUG(str) printf str
#else
#define DEBUG(str)
#endif

#if FLOW_DEBUG
#define DEBUG_WHERE(str) printf str
#else
#define DEBUG_WHERE(str)
#endif

#if DMABUFS_DEBUG
#define DEBUG_BUFS(str) printf str
#else
#define DEBUG_BUFS(str)
#endif


#if 0
#define S3V_DMA_SEND_FLAGS DRM_DMA_PRIORITY
#define S3V_DMA_SEND_FLAGS DRM_DMA_BLOCK
#else
#define S3V_DMA_SEND_FLAGS 0
#endif

#if 0
#define S3V_DMA_GET_FLAGS \
(DRM_DMA_SMALLER_OK | DRM_DMA_LARGER_OK | DRM_DMA_WAIT)
#else
#define S3V_DMA_GET_FLAGS DRM_DMA_WAIT
#endif


#define DMAOUT_CHECK(reg,len) \
do { \
DEBUG(("DMAOUT_CHECK: reg = 0x%x\n", S3V_##reg##_REG)); \
DEBUG_BUFS(("DMAOUT_CHECK (was): ")); \
DEBUG_BUFS(("vmesa->bufCount=%i of vmesa->bufSize=%i\n", \
vmesa->bufCount, vmesa->bufSize)); \
/* FIXME: > or >= */ \
if (vmesa->bufCount+(len+1) >= vmesa->bufSize) \
DMAFLUSH(); \
\
vmesa->bufCount += (len+1); \
DEBUG_BUFS(("DMAOUT_CHECK (is): vmesa->bufCount=%i len=%i, reg=%x\n", \
vmesa->bufCount, len, S3V_##reg##_REG)); \
DMAOUT( ((len & 0xffff) | ((S3V_##reg##_REG & 0xfffc) << 14)) ); \
} while (0)

#define DMAOUT(val) \
do { \
*(vmesa->buf++)=val; \
DEBUG_BUFS(("DMAOUT: val=0x%x\n", (unsigned int)val)); \
} while(0)

#define DMAFINISH() \
do { \
/* NOTE: it does nothing - it just prints some summary infos */ \
DEBUG(("DMAFINISH: vmesa->bufCount=%i\n", vmesa->bufCount)); \
DEBUG(("buf: index=%i; addr=%p\n", vmesa->bufIndex[vmesa->_bufNum], \
vmesa->s3vScreen->bufs->list[vmesa->bufIndex[vmesa->_bufNum]].address)); \
} while(0)

#define DMAFLUSH() \
do { \
if (vmesa->bufCount) { \
SEND_DMA(vmesa->driFd, vmesa->hHWContext, 1, \
&vmesa->bufIndex[vmesa->_bufNum], &vmesa->bufCount); \
/*
GET_DMA(vmesa->driFd, vmesa->hHWContext, 1, \
&vmesa->bufIndex, &vmesa->bufSize); \
*/ \
vmesa->_bufNum = !(vmesa->_bufNum); \
vmesa->buf = vmesa->_buf[vmesa->_bufNum]; \
/*
vmesa->buf = \
vmesa->s3vScreen->bufs->list[vmesa->bufIndex].address; \
*/ \
vmesa->bufCount = 0; \
} \
} while (0)

#define CMDCHANGE() \
do { \
DMAOUT_CHECK(3DTRI_CMDSET, 1); /* FIXME: TRI/LINE */ \
DMAOUT(vmesa->CMD); \
DMAFINISH(); \
} while (0)

#ifdef DONT_SEND_DMA
#define GET_DMA(fd, hHWCtx, n, idx, size)
#define SEND_DMA(fd, hHWCtx,n, idx, cnt)
#else
#define GET_DMA(fd, hHWCtx, n, idx, size) \
do { \
drmDMAReq dma; \
int retcode, i; \
\
DEBUG(("GET_DMA: ")); \
DEBUG(("req_count=%i; req_list[#0]=%i; req_size[#0]=%i\n", \
n, (idx)[n-1], (size)[n-1])); \
\
dma.context = (hHWCtx); \
dma.send_count = 0; \
dma.send_list = NULL; \
dma.send_sizes = NULL; \
dma.flags = S3V_DMA_GET_FLAGS; \
dma.request_count = (n); \
dma.request_size = S3V_DMA_BUF_SZ; \
dma.request_list = (idx); \
dma.request_sizes = (size); \
\
do { \
if ((retcode = drmDMA((fd), &dma))) { \
DEBUG_BUFS(("drmDMA (get) returned %d\n", retcode)); \
} \
} while (!(dma).granted_count); \
\
for (i = 0; i < (n); i++) { \
DEBUG(("Got buffer %i (index #%i)\n", (idx)[i], i)); \
DEBUG(("of %i bytes (%i words) size\n", \
(size)[i], (size)[i] >>2)); \
/* Convert from bytes to words */ \
(size)[i] >>= 2; \
} \
} while (0)

#define SEND_DMA(fd, hHWCtx, n, idx, cnt) \
do { \
drmDMAReq dma; \
int retcode, i; \
\
DEBUG(("SEND_DMA: ")); \
DEBUG(("send_count=%i; send_list[#0]=%i; send_sizes[#0]=%i\n", \
n, (idx)[n-1], (cnt)[n-1])); \
\
for (i = 0; i < (n); i++) { \
/* Convert from words to bytes */ \
(cnt)[i] <<= 2; \
} \
\
dma.context = (hHWCtx); \
dma.send_count = (n); \
dma.send_list = (idx); \
dma.send_sizes = (cnt); \
dma.flags = S3V_DMA_SEND_FLAGS; \
dma.request_count = 0; \
dma.request_size = 0; \
dma.request_list = NULL; \
dma.request_sizes = NULL; \
\
if ((retcode = drmDMA((fd), &dma))) { \
DEBUG_BUFS(("drmDMA (send) returned %d\n", retcode)); \
} \
\
for (i = 0; i < (n); i++) { \
DEBUG(("Sent buffer %i (index #%i)\n", (idx)[i], i)); \
DEBUG(("of %i bytes (%i words) size\n", \
(cnt)[i], (cnt)[i] >>2)); \
(cnt)[i] = 0; \
} \
} while (0)
#endif /* DONT_SEND_DMA */

#define GET_FIRST_DMA(fd, hHWCtx, n, idx, size, buf, cnt, vPriv) \
do { \
int i; \
DEBUG_BUFS(("GET_FIRST_DMA\n")); \
DEBUG_BUFS(("n=%i idx=%i size=%i\n", n, *idx, *size)); \
DEBUG_BUFS(("going to GET_DMA\n")); \
GET_DMA(fd, hHWCtx, n, idx, size); \
DEBUG_BUFS(("coming from GET_DMA\n")); \
DEBUG_BUFS(("n=%i idx=%i size=%i\n", n, (idx)[0], (size)[0])); \
for (i = 0; i < (n); i++) { \
DEBUG_BUFS(("buf #%i @%p\n", \
i, (vPriv)->bufs->list[(idx)[i]].address)); \
(buf)[i] = (vPriv)->bufs->list[(idx)[i]].address; \
(cnt)[i] = 0; \
} \
DEBUG(("GOING HOME\n")); \
} while (0)

#endif

/**************************/
/* generic, global macros */
/**************************/

#define CALC_LOG2(l2,s) \
do { \
int __s = s; \
l2 = 0; \
while (__s > 1) { ++l2; __s >>= 1; } \
} while (0)

#define PrimType_Null 0x00000000
#define PrimType_Points 0x10000000
#define PrimType_Lines 0x20000000
#define PrimType_LineLoop 0x30000000
#define PrimType_LineStrip 0x40000000
#define PrimType_Triangles 0x50000000
#define PrimType_TriangleStrip 0x60000000
#define PrimType_TriangleFan 0x70000000
#define PrimType_Quads 0x80000000
#define PrimType_QuadStrip 0x90000000
#define PrimType_Polygon 0xa0000000
#define PrimType_Mask 0xf0000000

#endif /* _S3V_MACROS_H_ */

+ 367
- 0
src/mesa/drivers/dri/s3v/s3v_regs.h View File

@@ -0,0 +1,367 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef _S3V_REG_H
#define _S3V_REG_H

#define S3V_REGS_NUM 256

/************
* DMA REGS *
************/

#define S3V_DMA_ID 0
#define S3V_DMA_REG 0x8590
#define S3V_DMA_WRITEP_ID 1
#define S3V_DMA_WRITEP_REG 0x8594
#define S3V_DMA_READP_ID 2
#define S3V_DMA_READP_REG 0x8598
#define S3V_DMA_ENABLE_ID 3
#define S3V_DMA_ENABLE_REG 0x859C
#define S3V_DMA_UPDATE_ID 4
#define S3V_DMA_UPDATE_REG 0x10000

/***************
* STATUS REGS *
***************/

#define S3V_STAT_ID 10
#define S3V_STAT_REG 0x8504
#define S3V_STAT_VSYNC_ID 11
#define S3V_STAT_VSYNC_REG 0x8505
#define S3V_STAT_3D_DONE_ID 12
#define S3V_STAT_3D_DONE_REG 0x8506
#define S3V_STAT_FIFO_OVER_ID 13
#define S3V_STAT_FIFO_OVER_REG 0x8508
#define S3V_STAT_FIFO_EMPTY_ID 14
#define S3V_STAT_FIFO_EMPTY_REG 0x850C
#define S3V_STAT_HDMA_DONE_ID 15
#define S3V_STAT_HDMA_DONE_REG 0x8514
#define S3V_STAT_CDMA_DONE_ID 16
#define S3V_STAT_CDMA_DONE_REG 0x8524
#define S3V_STAT_3D_FIFO_EMPTY_ID 17
#define S3V_STAT_3D_FIFO_EMPTY_REG 0x8544
#define S3V_STAT_LPB_ID 18
#define S3V_STAT_LPB_REG 0x8584
#define S3V_STAT_3D_BUSY_ID 19
#define S3V_STAT_3D_BUSY_REG 0x8704

/***********
* 2D REGS *
***********/

#define S3V_BITBLT_ID 30
#define S3V_BITBLT_REG 0xA400
#define S3V_BITBLT_SRC_BASE_ID 31
#define S3V_BITBLT_SRC_BASE_REG 0xA4D4
#define S3V_BITBLT_DEST_BASE_ID 32
#define S3V_BITBLT_DEST_BASE_REG 0xA4D8
#define S3V_BITBLT_CLIP_L_R_ID 33
#define S3V_BITBLT_CLIP_L_R_REG 0xA4DC
#define S3V_BITBLT_CLIP_T_B_ID 34
#define S3V_BITBLT_CLIP_T_B_REG 0xA4E0
#define S3V_BITBLT_DEST_SRC_STRIDE_ID 35
#define S3V_BITBLT_DEST_SRC_STRIDE_REG 0xA4E4
#define S3V_BITBLT_MONO_PAT0_ID 36
#define S3V_BITBLT_MONO_PAT0_REG 0xA4E8
#define S3V_BITBLT_MONO_PAT1_ID 37
#define S3V_BITBLT_MONO_PAT1_REG 0xA4EC
#define S3V_BITBLT_PAT_BG_COLOR_ID 38
#define S3V_BITBLT_PAT_BG_COLOR_REG 0xA4F0
#define S3V_BITBLT_PAT_FG_COLOR_ID 39
#define S3V_BITBLT_PAT_FG_COLOR_REG 0xA4F4
#define S3V_BITBLT_CMDSET_ID 40
#define S3V_BITBLT_CMDSET_REG 0xA500
#define S3V_BITBLT_WIDTH_HEIGHT_ID 41
#define S3V_BITBLT_WIDTH_HEIGHT_REG 0xA504
#define S3V_BITBLT_SRC_X_Y_ID 42
#define S3V_BITBLT_SRC_X_Y_REG 0xA508
#define S3V_BITBLT_DEST_X_Y_ID 43
#define S3V_BITBLT_DEST_X_Y_REG 0xA50C
#define S3V_2DLINE_ID 44
#define S3V_2DLINE_REG 0xA800
#define S3V_2DPOLY_ID 45
#define S3V_2DPOLY_REG 0xAC00

/***************
* 3DLINE REGS *
***************/
/* base regs */
#define S3V_3DLINE_ID 50
#define S3V_3DLINE_REG 0xB000
#define S3V_3DLINE_Z_BASE_ID 51
#define S3V_3DLINE_Z_BASE_REG 0xB0D4
#define S3V_3DLINE_SRC_BASE_ID 52 /* it is the same reg */
#define S3V_3DLINE_SRC_BASE_REG 0xB0D4
#define S3V_3DLINE_DEST_BASE_ID 53
#define S3V_3DLINE_DEST_BASE_REG 0xB0D8
#define S3V_3DLINE_CLIP_L_R_ID 54
#define S3V_3DLINE_CLIP_L_R_REG 0xB0DC
#define S3V_3DLINE_CLIP_T_B_ID 55
#define S3V_3DLINE_CLIP_T_B_REG 0xB0E0
#define S3V_3DLINE_DEST_SRC_STRIDE_ID 56
#define S3V_3DLINE_DEST_SRC_STRIDE_REG 0xB0E4
#define S3V_3DLINE_Z_STRIDE_ID 57
#define S3V_3DLINE_Z_STRIDE_REG 0xB0E8
#define S3V_3DLINE_TEX_BASE_ID 58
#define S3V_3DLINE_TEX_BASE_REG 0xB0EC
#define S3V_3DLINE_TEX_B_COLOR_ID 59
#define S3V_3DLINE_TEX_B_COLOR_REG 0xB0F0
#define S3V_3DLINE_FOG_COLOR_ID 60
#define S3V_3DLINE_FOG_COLOR_REG 0xB0F4
#define S3V_3DLINE_COLOR0_ID 61
#define S3V_3DLINE_COLOR0_REG 0xB0F8
#define S3V_3DLINE_COLOR1_ID 62
#define S3V_3DLINE_COLOR1_REG 0xB0FC
#define S3V_3DLINE_CMDSET_ID 63
#define S3V_3DLINE_CMDSET_REG 0xB100 /* special */
/* tex regs */
/* FIXME: shouldn't it be a 1D tex for lines? */
#define S3V_3DLINE_BASEV_ID 64
#define S3V_3DLINE_BASEV_REG 0xB104
#define S3V_3DLINE_BASEU_ID 65
#define S3V_3DLINE_BASEU_REG 0xB108
#define S3V_3DLINE_WXD_ID 66
#define S3V_3DLINE_WXD_REG 0xB10C
#define S3V_3DLINE_WYD_ID 67
#define S3V_3DLINE_WYD_REG 0xB110
#define S3V_3DLINE_WSTART_ID 68
#define S3V_3DLINE_WSTART_REG 0xB114
#define S3V_3DLINE_DXD_ID 69
#define S3V_3DLINE_DXD_REG 0xB118
#define S3V_3DLINE_VXD_ID 70
#define S3V_3DLINE_VXD_REG 0xB11C
#define S3V_3DLINE_UXD_ID 71
#define S3V_3DLINE_UXD_REG 0xB120
#define S3V_3DLINE_DYD_ID 72
#define S3V_3DLINE_DYD_REG 0xB124
#define S3V_3DLINE_VYD_ID 73
#define S3V_3DLINE_VYD_REG 0xB128
#define S3V_3DLINE_UYD_ID 74
#define S3V_3DLINE_UYD_REG 0xB12C
#define S3V_3DLINE_DSTART_ID 75
#define S3V_3DLINE_DSTART_REG 0xB130
#define S3V_3DLINE_VSTART_ID 76
#define S3V_3DLINE_VSTART_REG 0xB134
#define S3V_3DLINE_USTART_ID 77
#define S3V_3DLINE_USTART_REG 0xB138
/* gourad regs */
#define S3V_3DLINE_GBD_ID 78
#define S3V_3DLINE_GBD_REG 0xB144
#define S3V_3DLINE_ARD_ID 79
#define S3V_3DLINE_ARD_REG 0xB148
#define S3V_3DLINE_GS_BS_ID 80
#define S3V_3DLINE_GS_BS_REG 0xB14C
#define S3V_3DLINE_AS_RS_ID 81
#define S3V_3DLINE_AS_RS_REG 0xB150
/* vertex regs */
#define S3V_3DLINE_DZ_ID 82
#define S3V_3DLINE_DZ_REG 0xB158
#define S3V_3DLINE_ZSTART_ID 83
#define S3V_3DLINE_ZSTART_REG 0xB15C
#define S3V_3DLINE_XEND0_END1_ID 84
#define S3V_3DLINE_XEND0_END1_REG 0xB16C
#define S3V_3DLINE_DX_ID 85
#define S3V_3DLINE_DX_REG 0xB170
#define S3V_3DLINE_XSTART_ID 86
#define S3V_3DLINE_XSTART_REG 0xB174
#define S3V_3DLINE_YSTART_ID 87
#define S3V_3DLINE_YSTART_REG 0xB178
#define S3V_3DLINE_YCNT_ID 88
#define S3V_3DLINE_YCNT_REG 0xB17C

/**************
* 3DTRI REGS *
**************/
/* base regs */
#define S3V_3DTRI_ID 100
#define S3V_3DTRI_REG 0xB400
#define S3V_3DTRI_Z_BASE_ID 101
#define S3V_3DTRI_Z_BASE_REG 0xB4D4
#define S3V_3DTRI_SRC_BASE_ID 102 /* it is the same reg */
#define S3V_3DTRI_SRC_BASE_REG 0xB4D4
#define S3V_3DTRI_DEST_BASE_ID 103
#define S3V_3DTRI_DEST_BASE_REG 0xB4D8
#define S3V_3DTRI_CLIP_L_R_ID 104
#define S3V_3DTRI_CLIP_L_R_REG 0xB4DC
#define S3V_3DTRI_CLIP_T_B_ID 105
#define S3V_3DTRI_CLIP_T_B_REG 0xB4E0
#define S3V_3DTRI_DEST_SRC_STRIDE_ID 106
#define S3V_3DTRI_DEST_SRC_STRIDE_REG 0xB4E4
#define S3V_3DTRI_Z_STRIDE_ID 107
#define S3V_3DTRI_Z_STRIDE_REG 0xB4E8
#define S3V_3DTRI_TEX_BASE_ID 108
#define S3V_3DTRI_TEX_BASE_REG 0xB4EC
#define S3V_3DTRI_TEX_B_COLOR_ID 109
#define S3V_3DTRI_TEX_B_COLOR_REG 0xB4F0
#define S3V_3DTRI_FOG_COLOR_ID 110
#define S3V_3DTRI_FOG_COLOR_REG 0xB4F4
#define S3V_3DTRI_COLOR0_ID 111
#define S3V_3DTRI_COLOR0_REG 0xB4F8
#define S3V_3DTRI_COLOR1_ID 112
#define S3V_3DTRI_COLOR1_REG 0xB4FC
#define S3V_3DTRI_CMDSET_ID 113 /* special */
#define S3V_3DTRI_CMDSET_REG 0xB500
/* tex regs */
#define S3V_3DTRI_BASEV_ID 114
#define S3V_3DTRI_BASEV_REG 0xB504
#define S3V_3DTRI_BASEU_ID 115
#define S3V_3DTRI_BASEU_REG 0xB508
#define S3V_3DTRI_WXD_ID 116
#define S3V_3DTRI_WXD_REG 0xB50C
#define S3V_3DTRI_WYD_ID 117
#define S3V_3DTRI_WYD_REG 0xB510
#define S3V_3DTRI_WSTART_ID 118
#define S3V_3DTRI_WSTART_REG 0xB514
#define S3V_3DTRI_DXD_ID 119
#define S3V_3DTRI_DXD_REG 0xB518
#define S3V_3DTRI_VXD_ID 120
#define S3V_3DTRI_VXD_REG 0xB51C
#define S3V_3DTRI_UXD_ID 121
#define S3V_3DTRI_UXD_REG 0xB520
#define S3V_3DTRI_DYD_ID 122
#define S3V_3DTRI_DYD_REG 0xB524
#define S3V_3DTRI_VYD_ID 123
#define S3V_3DTRI_VYD_REG 0xB528
#define S3V_3DTRI_UYD_ID 124
#define S3V_3DTRI_UYD_REG 0xB52C
#define S3V_3DTRI_DSTART_ID 125
#define S3V_3DTRI_DSTART_REG 0xB530
#define S3V_3DTRI_VSTART_ID 126
#define S3V_3DTRI_VSTART_REG 0xB534
#define S3V_3DTRI_USTART_ID 127
#define S3V_3DTRI_USTART_REG 0xB538
/* gourad regs */
#define S3V_3DTRI_GBX_ID 128
#define S3V_3DTRI_GBX_REG 0xB53C
#define S3V_3DTRI_ARX_ID 129
#define S3V_3DTRI_ARX_REG 0xB540
#define S3V_3DTRI_GBY_ID 130
#define S3V_3DTRI_GBY_REG 0xB544
#define S3V_3DTRI_ARY_ID 131
#define S3V_3DTRI_ARY_REG 0xB548
#define S3V_3DTRI_GS_BS_ID 132
#define S3V_3DTRI_GS_BS_REG 0xB54C
#define S3V_3DTRI_AS_RS_ID 133
#define S3V_3DTRI_AS_RS_REG 0xB550
/* vertex regs */
#define S3V_3DTRI_ZXD_ID 134
#define S3V_3DTRI_ZXD_REG 0xB554
#define S3V_3DTRI_ZYD_ID 135
#define S3V_3DTRI_ZYD_REG 0xB558
#define S3V_3DTRI_ZSTART_ID 136
#define S3V_3DTRI_ZSTART_REG 0xB55C
#define S3V_3DTRI_TXDELTA12_ID 137
#define S3V_3DTRI_TXDELTA12_REG 0xB560
#define S3V_3DTRI_TXEND12_ID 138
#define S3V_3DTRI_TXEND12_REG 0xB564
#define S3V_3DTRI_TXDELTA01_ID 139
#define S3V_3DTRI_TXDELTA01_REG 0xB568
#define S3V_3DTRI_TXEND01_ID 140
#define S3V_3DTRI_TXEND01_REG 0xB56C
#define S3V_3DTRI_TXDELTA02_ID 141
#define S3V_3DTRI_TXDELTA02_REG 0xB570
#define S3V_3DTRI_TXSTART02_ID 142
#define S3V_3DTRI_TXSTART02_REG 0xB574
#define S3V_3DTRI_TYS_ID 143
#define S3V_3DTRI_TYS_REG 0xB578
#define S3V_3DTRI_TY01_Y12_ID 144
#define S3V_3DTRI_TY01_Y12_REG 0xB57C

/* COMMANDS (to 0xB100 [lines] or 0xB500 [tris]) */

/* Auto execute */
#define AUTO_EXEC_MASK 0x00000001
#define AUTO_EXEC_OFF (0x0)
#define AUTO_EXEC_ON (0x1)
/* HW clipping */
#define HW_CLIP_MASK 0x00000002
#define HW_CLIP_OFF (0x0 << 1)
#define HW_CLIP_ON (0x1 << 1)
/* Destination color */
#define DEST_COL_MASK 0x0000001c
#define DEST_COL_PAL (0x0 << 2) /* 8 bpp - palettized */
#define DEST_COL_1555 (0x1 << 2) /* 16 bpp - ZRGB */
#define DEST_COL_888 (0x2 << 2) /* 24 bpp - RGB */
/* Texture color */
#define TEX_COL_MASK 0x000000e0
#define TEX_COL_ARGB8888 (0x0 << 5) /* 32 bpp - ARGB */
#define TEX_COL_ARGB4444 (0x1 << 5) /* 16 bpp - ARGB */
#define TEX_COL_ARGB1555 (0x2 << 5) /* 16 bpp - ARGB */
#define TEX_COL_ALPHA4 (0x3 << 5) /* 8 bpp - ALPHA4 */
#define TEX_COL_BLEND4_LOW (0x4 << 5) /* 4 bpp - BLEND4 low nibble */
#define TEX_COL_BLEND4_HIGH (0x5 << 5) /* 4 bpp - BLEND4 high nibble */
#define TEX_COL_PAL (0x6 << 5) /* 8 bpp - palettized */
#define TEX_COL_YUV (0x7 << 5) /* 16 bpp - YUV */
/* Mipmap level */
#define MIP_MASK 0x00000f00
#define MIPMAP_LEVEL(s) (s << 8) /* 8 -> 11 bits */
/* Texture filtering */
#define TEX_FILTER_MASK 0x00007000
#define MIP_NEAREST (0x0 << 12)
#define LINEAR_MIP_NEAREST (0x1 << 12)
#define MIP_LINEAR (0x2 << 12)
#define LINEAR_MIP_LINEAR (0x3 << 12)
#define NEAREST (0x4 << 12)
#define FAST_BILINEAR (0x5 << 12)
#define LINEAR (0x6 << 12)
/* Texture blending */
#define TEX_BLEND_MAKS 0x00018000
#define TEX_REFLECT (0x0 << 15)
#define TEX_MODULATE (0x1 << 15)
#define TEX_DECAL (0x2 << 15)
/* Fog */
#define FOG_MASK 0x00020000
#define FOG_OFF (0x0 << 17)
#define FOG_ON (0x1 << 17)
/* Alpha blending */
#define ALPHA_BLEND_MASK 0x000c0000
#define ALPHA_OFF (0x0 << 18) | (0x0 << 19)
#define ALPHA_TEX (0x2 << 18)
#define ALPHA_SRC (0x3 << 18)
/* Depth compare mode */
#define Z_MODE_MASK 0x00700000
#define Z_NEVER (0x0 << 20)
#define Z_GREATER (0x1 << 20)
#define Z_EQUAL (0x2 << 20)
#define Z_GEQUAL (0x3 << 20)
#define Z_LESS (0x4 << 20)
#define Z_NOTEQUAL (0x5 << 20)
#define Z_LEQUAL (0x6 << 20)
#define Z_ALWAYS (0x7 << 20)
/* Depth update */
#define Z_UPDATE_MASK 0x00800000
#define Z_UPDATE_OFF (0x0 << 23) /* disable z update */
#define Z_UPDATE_ON (0x1 << 23)
/* Depth buffering mode */
#define Z_BUFFER_MASK 0x03000000
#define Z_BUFFER (0x0 << 24) | (0x0 << 25)
#define Z_MUX_BUF (0x1 << 24) | (0x0 << 25)
#define Z_MUX_DRAW (0x2 << 24)
#define Z_OFF (0x3 << 24) /* no z buffering */
/* Texture wrapping */
#define TEX_WRAP_MASK 0x04000000
#define TEX_WRAP_OFF (0x0 << 26)
#define TEX_WRAP_ON (0x1 << 26)
/* 3d command */
#define DO_MASK 0x78000000
#define DO_GOURAUD_TRI (0x0 << 27)
#define DO_TEX_LIT_TRI_OLD (0x1 << 27)
#define DO_TEX_UNLIT_TRI_OLD (0x2 << 27)
#define DO_TEX_LIT_TRI (0x5 << 27)
#define DO_TEX_UNLIT_TRI (0x6 << 27)
#define DO_3D_LINE (0x8 << 27)
#define DO_NOP (0xf << 27) /* turn on autoexec */
/* status */
#define CMD_MASK 0x80000000
#define CMD_2D (0x0 << 31) /* execute a 2d cmd */
#define CMD_3D (0x1 << 31) /* execute a 3d cmd */

/* global masks */
#define TEX_MASK ( TEX_COL_MASK | TEX_WRAP_MASK | MIP_MASK \
| TEX_FILTER_MASK | TEX_BLEND_MAKS \
| TEX_WRAP_MASK )
#define Z_MASK ( Z_MODE_MASK | Z_UPDATE_MASK | Z_BUFFER_MASK )

#endif /* _S3V_REG_H */

+ 251
- 0
src/mesa/drivers/dri/s3v/s3v_render.c View File

@@ -0,0 +1,251 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "mem.h"
#include "mtypes.h"
#include "mmath.h"

#include "tnl/t_context.h"

#include "s3v_context.h"
#include "s3v_tris.h"
#include "s3v_vb.h"


#define HAVE_POINTS 0
#define HAVE_LINES 0
#define HAVE_LINE_STRIPS 0
#define HAVE_TRIANGLES 0
#define HAVE_TRI_STRIPS 0
#define HAVE_TRI_STRIP_1 0
#define HAVE_TRI_FANS 0
#define HAVE_QUADS 0
#define HAVE_QUAD_STRIPS 0
#define HAVE_POLYGONS 0

#define HAVE_ELTS 0

static void VERT_FALLBACK( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
/* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
int _flags;
DEBUG(("VERT_FALLBACK: flags & PRIM_MODE_MASK = %i\n",
flags & PRIM_MODE_MASK));
DEBUG(("VERT_FALLBACK: flags=%i PRIM_MODE_MASK=%i\n",
flags, PRIM_MODE_MASK));
#if 0
tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
#endif
tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );

_flags = flags & PRIM_MODE_MASK;

tnl->Driver.Render.PrimTabVerts[_flags]( ctx, start, count, flags );
S3V_CONTEXT(ctx)->SetupNewInputs = VERT_CLIP;
}

static const GLuint hw_prim[GL_POLYGON+1] = {
PrimType_Points,
PrimType_Lines,
PrimType_LineLoop,
PrimType_LineStrip,
PrimType_Triangles,
PrimType_TriangleStrip,
PrimType_TriangleFan,
PrimType_Quads,
PrimType_QuadStrip,
PrimType_Polygon
};

static __inline void s3vStartPrimitive( s3vContextPtr vmesa, GLenum prim )
{
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;

int _hw_prim = hw_prim[prim];

DEBUG(("s3vStartPrimitive (new #%i) ", prim));

if (_hw_prim != vmesa->restore_primitive) {

if (prim == 4) { /* TRI */
DEBUG(("switching to tri\n"));
vmesa->prim_cmd = vmesa->_tri[vmesa->_3d_mode];
vmesa->alpha_cmd = vmesa->_alpha[vmesa->_3d_mode];
DMAOUT_CHECK(3DTRI_Z_BASE, 12);
} else if (prim == 1) { /* LINE */
DEBUG(("switching to line\n"));
vmesa->prim_cmd = DO_3D_LINE;
vmesa->alpha_cmd = vmesa->_alpha[0];
DMAOUT_CHECK(3DLINE_Z_BASE, 12);
} else {
DEBUG(("Never mind the bollocks!\n"));
}

DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8);
DMAOUT(vmesa->DestBase);
/* DMAOUT(vmesa->ScissorLR); */
/* DMAOUT(vmesa->ScissorTB); */
DMAOUT( (0 << 16) | (dPriv->w-1) );
DMAOUT( (0 << 16) | (dPriv->h-1) );
DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride );
DMAOUT(vmesa->SrcStride);
DMAOUT(vmesa->TexOffset);
DMAOUT(vmesa->TextureBorderColor);
DMAOUT(0); /* FOG */
DMAOUT(0);
DMAOUT(0);
DMAOUT(vmesa->CMD | vmesa->prim_cmd | vmesa->alpha_cmd);
DMAFINISH();
}

vmesa->restore_primitive = _hw_prim;
}

static __inline void s3vEndPrimitive( s3vContextPtr vmesa )
{
/* GLcontext *ctx = vmesa->glCtx; */
DEBUG(("s3vEndPrimitive\n"));
}

#define LOCAL_VARS s3vContextPtr vmesa = S3V_CONTEXT(ctx)
#define INIT( prim ) s3vStartPrimitive( vmesa, prim )
#define FINISH s3vEndPrimitive( vmesa )
#define NEW_PRIMITIVE() (void) vmesa
#define NEW_BUFFER() (void) vmesa
#define FIRE_VERTICES() (void) vmesa
#define GET_CURRENT_VB_MAX_VERTS() \
(vmesa->bufSize - vmesa->bufCount) / 2
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
S3V_DMA_BUF_SZ / 2
#define EMIT_VERTS( ctx, j, nr ) \
do { \
printf("Alas, emit...\n"); \
/* s3v_emit(ctx, j, (j)+(nr)) */ \
/* we don't need emit on s3v */ \
} while (0)

#define TAG(x) s3v_##x

#include "tnl_dd/t_dd_dmatmp.h"

/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/


static GLboolean s3v_run_render( GLcontext *ctx,
struct gl_pipeline_stage *stage )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i, length, flags = 0;
render_func *tab;

DEBUG(("s3v_run_render\n"));
/* FIXME: hw clip */
if (VB->ClipOrMask || vmesa->RenderIndex != 0) {
DEBUG(("*** CLIPPED in render ***\n"));
#if 1
return GL_TRUE; /* don't handle clipping here */
#endif
}


/* We don't do elts */
if (VB->Elts)
return GL_TRUE;

tab = TAG(render_tab_verts);

tnl->Driver.Render.Start( ctx );

for (i = 0 ; !(flags & PRIM_LAST) ; i += length)
{
flags = VB->Primitive[i];
length = VB->PrimitiveLength[i];

DEBUG(("s3v_run_render (loop=%i) (lenght=%i)\n", i, length));

if (length) {
tnl->Driver.Render.BuildVertices( ctx, i, i+length,
~0 /*stage->inputs*/);
tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK]
( ctx, i, i + length, flags );
vmesa->SetupNewInputs = VERT_CLIP;
}
}
tnl->Driver.Render.Finish( ctx );

return GL_FALSE; /* finished the pipe */
}


static void s3v_check_render( GLcontext *ctx,
struct gl_pipeline_stage *stage )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
GLuint inputs = VERT_CLIP | VERT_RGBA;

DEBUG(("s3v_check_render\n"));

if (ctx->RenderMode == GL_RENDER) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
DEBUG(("DD_SEPARATE_SPECULAR\n"));
inputs |= VERT_SPEC_RGB;
}
if (ctx->Texture.Unit[0]._ReallyEnabled) {
DEBUG(("ctx->Texture.Unit[0]._ReallyEnabled\n"));
inputs |= VERT_TEX(0);
}

if (ctx->Texture.Unit[1]._ReallyEnabled) {
DEBUG(("ctx->Texture.Unit[1]._ReallyEnabled\n"));
inputs |= VERT_TEX(1);
}

if (ctx->Fog.Enabled) {
DEBUG(("ctx->Fog.Enabled\n"));
inputs |= VERT_FOG_COORD;
}
}

stage->inputs = inputs;
vmesa->SetupNewInputs = inputs;
}


static void dtr( struct gl_pipeline_stage *stage )
{
(void)stage;
}


const struct gl_pipeline_stage _s3v_render_stage =
{
"s3v render",
(_DD_NEW_SEPARATE_SPECULAR |
_NEW_TEXTURE|
_NEW_FOG|
_NEW_RENDERMODE), /* re-check (new inputs) */
0, /* re-run (always runs) */
GL_TRUE, /* active */
0, 0, /* inputs (set in check_render), outputs */
0, 0, /* changed_inputs, private */
dtr, /* destructor */
s3v_check_render, /* check - initially set to alloc data */
s3v_run_render /* run */
};

+ 96
- 0
src/mesa/drivers/dri/s3v/s3v_screen.c View File

@@ -0,0 +1,96 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "s3v_context.h"
#include "s3v_vb.h"
#include "s3v_dri.h"

#include "mem.h"

s3vScreenPtr s3vCreateScreen( __DRIscreenPrivate *sPriv )
{
s3vScreenPtr s3vScreen;
S3VDRIPtr vDRIPriv = (S3VDRIPtr)sPriv->pDevPriv;

/* int i; */

DEBUG(("s3vCreateScreen\n"));
DEBUG(("sPriv->pDevPriv at %p\n", sPriv->pDevPriv));
DEBUG(("size = %i\n", sizeof(*vDRIPriv)));

/* Allocate the private area */
s3vScreen = (s3vScreenPtr) CALLOC( sizeof(*s3vScreen) );
if ( !s3vScreen ) return NULL;

s3vScreen->regionCount = 4; /* Magic number. Can we fix this? */
s3vScreen->regions = Xmalloc(s3vScreen->regionCount *
sizeof(s3vRegion));
DEBUG(("sPriv->fd = %i\nvDRIPriv->dmaBufHandle = %x\n",
sPriv->fd, vDRIPriv->dmaBufHandle));

DEBUG(("vDRIPriv->dmaBufSize=%i\nvDRIPriv->dmaBuf=%p\n",
vDRIPriv->dmaBufSize, vDRIPriv->dmaBuf));


/* Get the list of dma buffers */
s3vScreen->bufs = drmMapBufs(sPriv->fd);

if (!s3vScreen->bufs) {
DEBUG(("Helter/skelter with drmMapBufs\n"));
return GL_FALSE;
}

s3vScreen->textureSize = vDRIPriv->texSize;
s3vScreen->logTextureGranularity = vDRIPriv->logTextureGranularity;
s3vScreen->cpp = vDRIPriv->cpp;
s3vScreen->frontOffset = vDRIPriv->frontOffset;
s3vScreen->frontPitch = vDRIPriv->frontPitch;
s3vScreen->backOffset = vDRIPriv->backOffset;
s3vScreen->backPitch = vDRIPriv->frontPitch; /* FIXME: check */
s3vScreen->depthOffset = vDRIPriv->depthOffset;
s3vScreen->depthPitch = vDRIPriv->frontPitch;
s3vScreen->texOffset = vDRIPriv->texOffset;

s3vScreen->driScreen = sPriv;

DEBUG(("vDRIPriv->width =%i; vDRIPriv->deviceID =%x\n", vDRIPriv->width,
vDRIPriv->deviceID));
DEBUG(("vDRIPriv->mem =%i\n", vDRIPriv->mem));
DEBUG(("vDRIPriv->fbOffset =%i\n", vDRIPriv->fbOffset));
DEBUG((" ps3vDRI->fbStride =%i\n", vDRIPriv->fbStride));
DEBUG(("s3vScreen->cpp = %i\n", s3vScreen->cpp));
DEBUG(("s3vScreen->backOffset = %x\n", s3vScreen->backOffset));
DEBUG(("s3vScreen->depthOffset = %x\n", s3vScreen->depthOffset));
DEBUG(("s3vScreen->texOffset = %x\n", s3vScreen->texOffset));
DEBUG(("I will return from s3vCreateScreen now\n"));
DEBUG(("s3vScreen->bufs = 0x%x\n", s3vScreen->bufs));
return s3vScreen;
}

/* Destroy the device specific screen private data struct.
*/
void s3vDestroyScreen( __DRIscreenPrivate *sPriv )
{
s3vScreenPtr s3vScreen = (s3vScreenPtr)sPriv->private;

DEBUG(("s3vDestroyScreen\n"));

/* First, unmap the dma buffers */
/*
drmUnmapBufs( s3vScreen->bufs );
*/
/* Next, unmap all the regions */
/* while (s3vScreen->regionCount > 0) {

(void)drmUnmap(s3vScreen->regions[s3vScreen->regionCount].map,
s3vScreen->regions[s3vScreen->regionCount].size);
s3vScreen->regionCount--;

}
FREE(s3vScreen->regions); */
if (s3vScreen)
FREE(s3vScreen);
}

+ 36
- 0
src/mesa/drivers/dri/s3v/s3v_screen.h View File

@@ -0,0 +1,36 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

typedef struct _s3vRegion {
drmHandle handle;
drmSize size;
drmAddress map;
} s3vRegion, *s3vRegionPtr;

typedef struct {

int regionCount; /* Count of register regions */
s3vRegion *regions; /* Vector of mapped region info */

drmBufMapPtr bufs; /* Map of DMA buffers */

__DRIscreenPrivate *driScreen; /* Back pointer to DRI screen */

int cpp;
int frontPitch;
int frontOffset;

int backPitch;
int backOffset;
int backX;
int backY;

int depthOffset;
int depthPitch;

int texOffset;
int textureOffset;
int textureSize;
int logTextureGranularity;
} s3vScreenRec, *s3vScreenPtr;

+ 308
- 0
src/mesa/drivers/dri/s3v/s3v_span.c View File

@@ -0,0 +1,308 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "s3v_context.h"
#include "s3v_lock.h"

#include "swrast/swrast.h"

#define _SPANLOCK 1
#define DBG 0

#define LOCAL_VARS \
s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
s3vScreenPtr s3vscrn = vmesa->s3vScreen; \
__DRIscreenPrivate *sPriv = vmesa->driScreen; \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
GLuint pitch = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \
((dPriv->w+31)&~31) * s3vscrn->cpp \
: sPriv->fbWidth * s3vscrn->cpp); \
GLuint height = dPriv->h; \
char *buf = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \
(char *)(sPriv->pFB + vmesa->drawOffset) \
: (char *)(sPriv->pFB + vmesa->drawOffset \
+ dPriv->x * s3vscrn->cpp + dPriv->y * pitch) ); \
char *read_buf = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \
(char *)(sPriv->pFB + vmesa->drawOffset) \
: (char *)(sPriv->pFB + vmesa->drawOffset \
+ dPriv->x * s3vscrn->cpp + dPriv->y * pitch) ); \
GLuint p; \
(void) read_buf; (void) buf; (void) p; (void) pitch

/* FIXME! Depth/Stencil read/writes don't work ! */
#define LOCAL_DEPTH_VARS \
s3vScreenPtr s3vscrn = vmesa->s3vScreen; \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
__DRIscreenPrivate *sPriv = vmesa->driScreen; \
GLuint pitch = s3vscrn->depthPitch; \
GLuint height = dPriv->h; \
char *buf = (char *)(sPriv->pFB + \
s3vscrn->depthOffset); /* + \
dPriv->x * s3vscrn->cpp + \
dPriv->y * pitch)*/ \
(void) pitch

#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS


#define CLIPPIXEL( _x, _y ) \
((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))


#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
if ( _y < miny || _y >= maxy ) { \
_n1 = 0, _x1 = x; \
} else { \
_n1 = _n; \
_x1 = _x; \
if ( _x1 < minx ) \
_i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
if ( _x1 + _n1 >= maxx ) \
n1 -= (_x1 + n1 - maxx); \
}

#define Y_FLIP( _y ) (height - _y - 1)

#if _SPANLOCK /* OK, we lock */

#define HW_LOCK() \
s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
(void) vmesa; \
DMAFLUSH(); \
S3V_SIMPLE_FLUSH_LOCK(vmesa);
#define HW_UNLOCK() S3V_SIMPLE_UNLOCK(vmesa);

#else /* plz, don't lock */

#define HW_LOCK() \
s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
(void) vmesa; \
DMAFLUSH();
#define HW_UNLOCK()

#endif

#define HW_CLIPLOOP() \
do { \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
int _nc = dPriv->numClipRects; \
\
while ( _nc-- ) { \
int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;

#define HW_ENDCLIPLOOP() \
} \
} while (0)


/* ================================================================
* Color buffer
*/

/* 16 bit, RGB565 color spanline and pixel functions
*/
#define INIT_MONO_PIXEL(p, color) \
p = S3VIRGEPACKCOLOR555( color[0], color[1], color[2], color[3] )

#define WRITE_RGBA( _x, _y, r, g, b, a ) \
do { \
*(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 7) | \
(((int)g & 0xf8) << 2) | \
(((int)b & 0xf8) >> 3)); \
DEBUG(("buf=0x%x drawOffset=0x%x dPriv->x=%i s3vscrn->cpp=%i dPriv->y=%i pitch=%i\n", \
sPriv->pFB, vmesa->drawOffset, dPriv->x, s3vscrn->cpp, dPriv->y, pitch)); \
DEBUG(("dPriv->w = %i\n", dPriv->w)); \
} while(0)

#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p

#define READ_RGBA( rgba, _x, _y ) \
do { \
GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
rgba[0] = (p >> 7) & 0xf8; \
rgba[1] = (p >> 2) & 0xf8; \
rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 0xff; /*
if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; */ \
} while (0)

#define TAG(x) s3v##x##_RGB555
#include "spantmp.h"


/* 32 bit, ARGB8888 color spanline and pixel functions
*/

#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p, color) \
p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )

#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
(g << 8) | \
(r << 16) | \
(a << 24) )

#define WRITE_PIXEL( _x, _y, p ) \
*(GLuint *)(buf + _x*4 + _y*pitch) = p

#define READ_RGBA( rgba, _x, _y ) \
do { \
GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
rgba[0] = (p >> 16) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 0) & 0xff; \
rgba[3] = (p >> 24) & 0xff; \
} while (0)

#define TAG(x) s3v##x##_ARGB8888
#include "spantmp.h"


/* 16 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)(buf + _x*2 + _y*dPriv->w*2) = d

#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + _x*2 + _y*dPriv->w*2);

#define TAG(x) s3v##x##_16
#include "depthtmp.h"




/* 32 bit depthbuffer functions.
*/
#if 0
#define WRITE_DEPTH( _x, _y, d ) \
*(GLuint *)(buf + _x*4 + _y*pitch) = d;

#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + _x*4 + _y*pitch);

#define TAG(x) s3v##x##_32
#include "depthtmp.h"
#endif


/* 24/8 bit interleaved depth/stencil functions
*/
#if 0
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
tmp &= 0xff; \
tmp |= (d) & 0xffffff00; \
*(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
}

#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff


#define TAG(x) s3v##x##_24_8
#include "depthtmp.h"

#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \
tmp &= 0xffffff00; \
tmp |= d & 0xff; \
*(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \
}

#define READ_STENCIL( d, _x, _y ) \
d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff

#define TAG(x) s3v##x##_24_8
#include "stenciltmp.h"

#endif

static void s3vSetReadBuffer( GLcontext *ctx,
GLframebuffer *colorBuffer,
GLenum mode )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

switch ( mode ) {
case GL_FRONT_LEFT:
vmesa->readOffset = 0;
break;
case GL_BACK_LEFT:
vmesa->readOffset = vmesa->driScreen->fbHeight * vmesa->driScreen->fbWidth * vmesa->s3vScreen->cpp;
break;
}
}


void s3vInitSpanFuncs( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);

swdd->SetReadBuffer = s3vSetReadBuffer;

switch ( vmesa->s3vScreen->cpp ) {
case 2:
swdd->WriteRGBASpan = s3vWriteRGBASpan_RGB555;
swdd->WriteRGBSpan = s3vWriteRGBSpan_RGB555;
swdd->WriteMonoRGBASpan = s3vWriteMonoRGBASpan_RGB555;
swdd->WriteRGBAPixels = s3vWriteRGBAPixels_RGB555;
swdd->WriteMonoRGBAPixels = s3vWriteMonoRGBAPixels_RGB555;
swdd->ReadRGBASpan = s3vReadRGBASpan_RGB555;
swdd->ReadRGBAPixels = s3vReadRGBAPixels_RGB555;
break;

case 4:
swdd->WriteRGBASpan = s3vWriteRGBASpan_ARGB8888;
swdd->WriteRGBSpan = s3vWriteRGBSpan_ARGB8888;
swdd->WriteMonoRGBASpan = s3vWriteMonoRGBASpan_ARGB8888;
swdd->WriteRGBAPixels = s3vWriteRGBAPixels_ARGB8888;
swdd->WriteMonoRGBAPixels = s3vWriteMonoRGBAPixels_ARGB8888;
#if 1
swdd->ReadRGBASpan = s3vReadRGBASpan_ARGB8888;
#else
swdd->ReadRGBASpan = s3vReadRGBASpan8888;
#endif
swdd->ReadRGBAPixels = s3vReadRGBAPixels_ARGB8888;
break;

default:
break;
}

switch ( vmesa->glCtx->Visual.depthBits ) {
case 15:
case 16:
swdd->ReadDepthSpan = s3vReadDepthSpan_16;
swdd->WriteDepthSpan = s3vWriteDepthSpan_16;
swdd->ReadDepthPixels = s3vReadDepthPixels_16;
swdd->WriteDepthPixels = s3vWriteDepthPixels_16;
break;

#if 0
case 24:
swdd->ReadDepthSpan = s3vReadDepthSpan_24_8;
swdd->WriteDepthSpan = s3vWriteDepthSpan_24_8;
swdd->ReadDepthPixels = s3vReadDepthPixels_24_8;
swdd->WriteDepthPixels = s3vWriteDepthPixels_24_8;

swdd->ReadStencilSpan = s3vReadStencilSpan_24_8;
swdd->WriteStencilSpan = s3vWriteStencilSpan_24_8;
swdd->ReadStencilPixels = s3vReadStencilPixels_24_8;
swdd->WriteStencilPixels = s3vWriteStencilPixels_24_8;
break;
#endif

default:
break;
}
}

+ 885
- 0
src/mesa/drivers/dri/s3v/s3v_state.c View File

@@ -0,0 +1,885 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include <X11/Xlibint.h>
#include "s3v_context.h"
#include "s3v_macros.h"
#include "macros.h"
#include "s3v_dri.h"
#include "colormac.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "array_cache/acache.h"
#include "tnl/tnl.h"

/* #define DEBUG(str) printf str */
#define ENABLELIGHTING 0


/* =============================================================
* Alpha blending
*/

static void s3vUpdateAlphaMode( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
CARD32 cmd = vmesa->CMD;
cmd &= ~ALPHA_BLEND_MASK;

if ( ctx->Color.BlendEnabled ) {
DEBUG(("ctx->Color.AlphaEnabled = 1"));
vmesa->_alpha[0] = ALPHA_SRC;
vmesa->_alpha[1] = vmesa->_alpha_tex; /* FIXME: not all tex modes
support alpha */
} else {
DEBUG(("ctx->Color.AlphaEnabled = 0"));
vmesa->_alpha[0] = vmesa->_alpha[1] = ALPHA_OFF;
}
#if 1
if ((cmd & DO_MASK) & DO_3D_LINE) { /* we are drawing 3d lines */
/* which don't support tex */
cmd |= vmesa->_alpha[0];
} else {
cmd |= vmesa->_alpha[vmesa->_3d_mode];
}

vmesa->CMD = cmd; /* FIXME: enough? */
#else
vmesa->restore_primitive = -1;
#endif
}

static void s3vDDAlphaFunc( GLcontext *ctx, GLenum func, GLchan ref )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

DEBUG(("s3vDDAlphaFunc\n"));

vmesa->new_state |= S3V_NEW_ALPHA;
}

static void s3vDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

DEBUG(("s3vDDBlendFunc\n"));

vmesa->new_state |= S3V_NEW_ALPHA;
}

/* ================================================================
* Buffer clear
*/

static void s3vDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
unsigned int _stride;

vmesa->restore_primitive = -1;

/* Update and emit any new state. We need to do this here to catch
* changes to the masks.
* FIXME: Just update the masks?
*/

if ( vmesa->new_state )
s3vDDUpdateHWState( ctx );

/* s3vUpdateMasks( ctx ); */
/* s3vUpdateClipping( ctx ); */
/* s3vEmitHwState( vmesa ); */

#if 1 /* soft (0)/hw (1)*/

DEBUG(("*** s3vDDClear ***\n"));

DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
DMAOUT(vmesa->SrcBase);
DMAOUT(vmesa->DestBlit);
DMAOUT( vmesa->ScissorLR );
DMAOUT( vmesa->ScissorTB );
DMAOUT( (vmesa->SrcStride << 16) | vmesa->SrcStride ); /* FIXME: unify */
DMAOUT( (~(0)) ); /* masks */
DMAOUT( (~(0)) );
DMAOUT(0);
DMAOUT(vmesa->ClearColor);
DMAOUT(0);
DMAOUT(0);
/* FIXME */
DMAOUT(0x16000122 | 0x5 | (0xF0 << 17)); /* black magic to me */
DMAOUT(vmesa->ScissorWH);
DMAOUT(vmesa->SrcXY);
DMAOUT(vmesa->DestXY);
DMAFINISH();

if (mask & DD_DEPTH_BIT) { /* depth */
DEBUG(("DD_DEPTH_BIT\n"));
_stride = ((cw+31)&~31) * 2;

DMAOUT_CHECK(BITBLT_SRC_BASE, 15);
DMAOUT(0);
DMAOUT(vmesa->s3vScreen->depthOffset);
DMAOUT( (0 << 16) | cw );
DMAOUT( (0 << 16) | ch );
DMAOUT( (vmesa->SrcStride << 16) | vmesa->DestStride );
DMAOUT( (~(0)) ); /* masks */
DMAOUT( (~(0)) );
DMAOUT(0);
DMAOUT(vmesa->ClearDepth); /* 0x7FFF */
/* FIXME */
DMAOUT(0);
DMAOUT(0);
DMAOUT(0x16000122 | 0x5 | (0xF0 << 17));
DMAOUT( ((cw-1) << 16) | (ch-1) );
DMAOUT(0);
DMAOUT( (0 << 16) | 0 );
DMAFINISH();

DEBUG(("vmesa->ClearDepth = 0x%x\n", vmesa->ClearDepth));
mask &= ~DD_DEPTH_BIT;
}

if (!vmesa->NotClipped) {
DEBUG(("vmesa->NotClipped\n")); /* yes */
}

if (!(vmesa->EnabledFlags & S3V_BACK_BUFFER)) {
DEBUG(("!S3V_BACK_BUFFER -> flush\n"));
DMAFLUSH();
}
/*
if ( mask )
DEBUG(("still masked ;3(\n")); */ /* yes */
#else
_swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
#endif
}

/* =============================================================
* Depth testing
*/

static void s3vUpdateZMode( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
CARD32 cmd = vmesa->CMD;

DEBUG(("Depth.Test = %i\n", ctx->Depth.Test));
DEBUG(("CMD was = 0x%x ", cmd));

/* printf("depth --- CMD was = 0x%x \n", cmd); */

cmd &= ~Z_MASK; /* 0xfc0fffff; */
/* Z_BUFFER */ /* 000 mode */ /* Z_UPDATE_OFF */

if (!ctx->Depth.Test)
cmd |= Z_OFF;

if ( ctx->Depth.Mask )
cmd |= Z_UPDATE_ON;
switch ( ctx->Depth.Func ) {
case GL_NEVER:
cmd |= Z_NEVER;
break;
case GL_ALWAYS:
cmd |= Z_ALWAYS;
break;
case GL_LESS:
cmd |= Z_LESS;
break;
case GL_LEQUAL:
cmd |= Z_LEQUAL;
break;
case GL_EQUAL:
cmd |= Z_EQUAL;
break;
case GL_GEQUAL:
cmd |= Z_GEQUAL;
break;
case GL_GREATER:
cmd |= Z_GREATER;
break;
case GL_NOTEQUAL:
cmd |= Z_NOTEQUAL;
break;
}

DEBUG(("CMD is 0x%x\n", cmd));

vmesa->dirty |= S3V_UPLOAD_DEPTH;
vmesa->CMD = cmd;
}

static void s3vDDDepthFunc( GLcontext *ctx, GLenum func )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

/* FLUSH_BATCH( vmesa ); */
DEBUG(("s3vDDDepthFunc\n"));
vmesa->new_state |= S3V_NEW_DEPTH;
}

static void s3vDDDepthMask( GLcontext *ctx, GLboolean flag )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

/* FLUSH_BATCH( vmesa ); */
DEBUG(("s3vDDDepthMask\n"));
vmesa->new_state |= S3V_NEW_DEPTH;
}

static void s3vDDClearDepth( GLcontext *ctx, GLclampd d )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

switch ( vmesa->DepthSize ) {
case 15:
case 16:
vmesa->ClearDepth = d * 0x0000ffff; /* 65536 */
DEBUG(("GLclampd d = %f\n", d));
DEBUG(("ctx->Depth.Clear = %f\n", ctx->Depth.Clear));
DEBUG(("(They should be the same)\n"));
break;
case 24:
vmesa->ClearDepth = d * 0x00ffffff;
break;
case 32:
vmesa->ClearDepth = d * 0xffffffff;
break;
}
}

static void s3vDDFinish( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
DMAFLUSH();
}

static void s3vDDFlush( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
DMAFLUSH();
}

/* =============================================================
* Fog
*/

static void s3vUpdateFogAttrib( GLcontext *ctx )
{
/* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */

if (ctx->Fog.Enabled) {
} else {
}

switch (ctx->Fog.Mode) {
case GL_LINEAR:
break;
case GL_EXP:
break;
case GL_EXP2:
break;
}
}

static void s3vDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
vmesa->new_state |= S3V_NEW_FOG;
}

/* =============================================================
* Lines
*/
static void s3vDDLineWidth( GLcontext *ctx, GLfloat width )
{
/* FIXME: on virge you only have one size of 3d lines *
* if we wanted more, we should start using tris instead *
* but virge has problem with some tris when all of the *
* vertices stay on a line */
}

/* =============================================================
* Points
*/
static void s3vDDPointSize( GLcontext *ctx, GLfloat size )
{
/* FIXME: we use 3d line to fake points. So same limitations
* as above apply */
}

/* =============================================================
* Polygon
*/

static void s3vUpdatePolygon( GLcontext *ctx )
{
/* FIXME: I don't think we could do much here */

s3vContextPtr vmesa = S3V_CONTEXT(ctx);
vmesa->dirty |= S3V_UPLOAD_POLYGON;
}

/* =============================================================
* Clipping
*/

static void s3vUpdateClipping( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;

int x0,y0,x1,y1;

DEBUG((">>> s3vUpdateClipping <<<\n"));
/*
if ( vmesa->driDrawable ) {
DEBUG(("s3vUpdateClipping\n"));
*/
if (vmesa->EnabledFlags & S3V_BACK_BUFFER) {
DEBUG(("S3V_BACK_BUFFER\n"));

x0 = 0;
y0 = 0;
x1 = dPriv->w - 1;
y1 = dPriv->h - 1;

vmesa->SrcBase = 0;
vmesa->DestBase = vmesa->s3vScreen->backOffset;
vmesa->DestBlit = vmesa->DestBase;
vmesa->ScissorLR = ( (0 << 16) | (dPriv->w-1) );
vmesa->ScissorTB = ( (0 << 16) | (dPriv->h-1) );
/*
vmesa->ScissorLR = ( (x0 << 16) | x1 );
vmesa->ScissorTB = ( (y0 << 16) | y1 );
*/
vmesa->SrcStride = ( ((dPriv->w+31)&~31) * vmesa->s3vScreen->cpp );
vmesa->DestStride = vmesa->driScreen->fbWidth*vmesa->s3vScreen->cpp;
vmesa->ScissorWH = ( (dPriv->w << 16) | dPriv->h );
vmesa->SrcXY = 0;
/* vmesa->DestXY = ( (dPriv->x << 16) | dPriv->y ); */
vmesa->DestXY = ( (0 << 16) | 0 );
} else {
DEBUG(("S3V_FRONT_BUFFER\n"));

x0 = dPriv->x;
y0 = dPriv->y;
x1 = x0 + dPriv->w - 1;
y1 = y0 + dPriv->h - 1;

vmesa->SrcBase = 0;
vmesa->DestBase = 0;
vmesa->ScissorLR = ( (x0 << 16) | x1 );
vmesa->ScissorTB = ( (y0 << 16) | y1 );
vmesa->DestStride = vmesa->driScreen->fbWidth*vmesa->s3vScreen->cpp;
vmesa->SrcStride = vmesa->DestStride;
vmesa->DestBase = (y0 * vmesa->DestStride)
+ x0*vmesa->s3vScreen->cpp;
vmesa->DestBlit = 0;
vmesa->ScissorWH = ( (x1 << 16) | y1 );
vmesa->SrcXY = 0;
vmesa->DestXY = ( (0 << 16) | 0 );
/* vmesa->DestXY = ( (dPriv->x << 16) | dPriv->y ); */
}

DEBUG(("x0=%i y0=%i x1=%i y1=%i\n", x0, y0, x1, y1));
DEBUG(("stride=%i rectWH=0x%x\n\n", vmesa->DestStride, vmesa->ScissorWH));

/* FIXME: how could we use the following info? */
/* if (ctx->Scissor.Enabled) {} */

vmesa->dirty |= S3V_UPLOAD_CLIP;
/* } */
}

static void s3vDDScissor( GLcontext *ctx,
GLint x, GLint y, GLsizei w, GLsizei h )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

DEBUG((">>> s3vDDScissor <<<"));
/* FLUSH_BATCH( vmesa ); */
vmesa->new_state |= S3V_NEW_CLIP;
}

/* =============================================================
* Culling
*/

static void s3vUpdateCull( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
GLfloat backface_sign = 1;

DEBUG(("s3vUpdateCull\n"));
/* FIXME: GL_FRONT_AND_BACK */

switch ( ctx->Polygon.CullFaceMode ) {
case GL_BACK:
if (ctx->Polygon.FrontFace == GL_CCW)
backface_sign = -1;
break;

case GL_FRONT:
if (ctx->Polygon.FrontFace != GL_CCW)
backface_sign = -1;
break;

default:
break;
}

vmesa->backface_sign = backface_sign;
vmesa->dirty |= S3V_UPLOAD_GEOMETRY;
}


static void s3vDDCullFace( GLcontext *ctx, GLenum mode )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
/* FLUSH_BATCH( vmesa ); */
vmesa->new_state |= S3V_NEW_CULL;
}

static void s3vDDFrontFace( GLcontext *ctx, GLenum mode )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
/* FLUSH_BATCH( vmesa ); */
vmesa->new_state |= S3V_NEW_CULL;
}

/* =============================================================
* Masks
*/

static void s3vUpdateMasks( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

GLuint mask = s3vPackColor( vmesa->s3vScreen->cpp,
ctx->Color.ColorMask[RCOMP],
ctx->Color.ColorMask[GCOMP],
ctx->Color.ColorMask[BCOMP],
ctx->Color.ColorMask[ACOMP] );

if (vmesa->s3vScreen->cpp == 2) mask |= mask << 16;

/* FIXME: can we do something in virge? */
}
/*
static void s3vDDColorMask( GLcontext *ctx, GLboolean r, GLboolean g,
GLboolean b, GLboolean a)
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

FLUSH_BATCH( vmesa );
vmesa->new_state |= S3V_NEW_MASKS;
}
*/
/* =============================================================
* Rendering attributes
*/

/* =============================================================
* Miscellaneous
*/

static void s3vDDClearColor( GLcontext *ctx, const GLchan color[4])
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

DEBUG(("*** s3vDDClearColor\n"));

vmesa->ClearColor = s3vPackColor( 2, /* vmesa->s3vScreen->cpp, */
color[0], color[1], color[2], color[3] );

#if 0
if (vmesa->s3vScreen->cpp == 2) vmesa->ClearColor |= vmesa->ClearColor<<16;
#endif
}

static void s3vDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
int found = GL_TRUE;

DEBUG(("*** s3vDDSetDrawBuffer ***\n"));

/* FLUSH_BATCH( vmesa ); */

switch ( mode ) {
case GL_FRONT_LEFT:
vmesa->drawOffset = vmesa->s3vScreen->frontOffset;
break;
case GL_BACK_LEFT:
vmesa->drawOffset = vmesa->s3vScreen->backOffset;
/* vmesa->driScreen->fbHeight *
* vmesa->driScreen->fbWidth *
* vmesa->s3vScreen->cpp; */
break;
default:
found = GL_FALSE;
break;
}

DEBUG(("vmesa->drawOffset = 0x%x\n", vmesa->drawOffset));
/* return GL_TRUE; */
}

/* =============================================================
* Window position and viewport transformation
*/

void s3vUpdateWindow( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
GLfloat xoffset = (GLfloat)dPriv->x;
GLfloat yoffset =
vmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
const GLfloat *v = ctx->Viewport._WindowMap.m;

GLfloat sx = v[MAT_SX];
GLfloat tx = v[MAT_TX] + xoffset;
GLfloat sy = v[MAT_SY];
GLfloat ty = v[MAT_TY] + yoffset;
GLfloat sz = v[MAT_SZ] * vmesa->depth_scale;
GLfloat tz = v[MAT_TZ] * vmesa->depth_scale;

vmesa->dirty |= S3V_UPLOAD_VIEWPORT;

vmesa->ViewportScaleX = sx;
vmesa->ViewportScaleY = sy;
vmesa->ViewportScaleZ = sz;
vmesa->ViewportOffsetX = tx;
vmesa->ViewportOffsetY = ty;
vmesa->ViewportOffsetZ = tz;
}


/*
static void s3vDDViewport( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height )
{
s3vUpdateWindow( ctx );
}

static void s3vDDDepthRange( GLcontext *ctx, GLclampd nearval,
GLclampd farval )
{
s3vUpdateWindow( ctx );
}
*/
void s3vUpdateViewportOffset( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
GLfloat xoffset = (GLfloat)dPriv->x;
GLfloat yoffset =
vmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
const GLfloat *v = ctx->Viewport._WindowMap.m;

GLfloat tx = v[MAT_TX] + xoffset;
GLfloat ty = v[MAT_TY] + yoffset;

DEBUG(("*** s3vUpdateViewportOffset ***\n"));

if ( vmesa->ViewportOffsetX != tx ||
vmesa->ViewportOffsetY != ty )
{
vmesa->ViewportOffsetX = tx;
vmesa->ViewportOffsetY = ty;

vmesa->new_state |= S3V_NEW_WINDOW;
}

/* vmesa->new_state |= S3V_NEW_CLIP; */
}

/* =============================================================
* State enable/disable
*/

static void s3vDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

switch ( cap ) {
case GL_ALPHA_TEST:
case GL_BLEND:
vmesa->new_state |= S3V_NEW_ALPHA;
DEBUG(("s3vDDEnable: GL_BLEND\n"));
break;

case GL_CULL_FACE:
vmesa->new_state |= S3V_NEW_CULL;
DEBUG(("s3vDDEnable: GL_CULL_FACE\n"));
break;

case GL_DEPTH_TEST:
vmesa->new_state |= S3V_NEW_DEPTH;
DEBUG(("s3vDDEnable: GL_DEPTH\n"));
break;
#if 0
case GL_FOG:
vmesa->new_state |= S3V_NEW_FOG;
break;
#endif

case GL_SCISSOR_TEST:
vmesa->new_state |= S3V_NEW_CLIP;
break;

case GL_TEXTURE_2D:
DEBUG(("*** GL_TEXTURE_2D: %i\n", state));
vmesa->_3d_mode = state;
vmesa->restore_primitive = -1;
break;
default:
return;
}
}

/* =============================================================
* State initialization, management
*/


/*
* Load the current context's state into the hardware.
*
* NOTE: Be VERY careful about ensuring the context state is marked for
* upload, the only place it shouldn't be uploaded is when the setup
* state has changed in ReducedPrimitiveChange as this comes right after
* a state update.
*
* Blits of any type should always upload the context and masks after
* they are done.
*/
void s3vEmitHwState( s3vContextPtr vmesa )
{
if (!vmesa->driDrawable) return;
if (!vmesa->dirty) return;

DEBUG(("**********************\n"));
DEBUG(("*** s3vEmitHwState ***\n"));
DEBUG(("**********************\n"));

if (vmesa->dirty & S3V_UPLOAD_VIEWPORT) {
vmesa->dirty &= ~S3V_UPLOAD_VIEWPORT;
DEBUG(("S3V_UPLOAD_VIEWPORT\n"));
}
if ( (vmesa->dirty & S3V_UPLOAD_POINTMODE) ||
(vmesa->dirty & S3V_UPLOAD_LINEMODE) ||
(vmesa->dirty & S3V_UPLOAD_TRIMODE) ) {

}
if (vmesa->dirty & S3V_UPLOAD_POINTMODE) {
vmesa->dirty &= ~S3V_UPLOAD_POINTMODE;
}

if (vmesa->dirty & S3V_UPLOAD_LINEMODE) {
vmesa->dirty &= ~S3V_UPLOAD_LINEMODE;
}
if (vmesa->dirty & S3V_UPLOAD_TRIMODE) {
vmesa->dirty &= ~S3V_UPLOAD_TRIMODE;
}

if (vmesa->dirty & S3V_UPLOAD_FOG) {
GLchan c[3], col;
UNCLAMPED_FLOAT_TO_RGB_CHAN( c, vmesa->glCtx->Fog.Color );
DEBUG(("uploading ** FOG **\n"));
col = s3vPackColor(2, c[0], c[1], c[2], 0);
vmesa->dirty &= ~S3V_UPLOAD_FOG;
}
if (vmesa->dirty & S3V_UPLOAD_DITHER) {
vmesa->dirty &= ~S3V_UPLOAD_DITHER;
}
if (vmesa->dirty & S3V_UPLOAD_LOGICOP) {
vmesa->dirty &= ~S3V_UPLOAD_LOGICOP;
}
if (vmesa->dirty & S3V_UPLOAD_CLIP) {
vmesa->dirty &= ~S3V_UPLOAD_CLIP;
DEBUG(("S3V_UPLOAD_CLIP\n"));
DEBUG(("vmesa->ScissorLR: %i\n", vmesa->ScissorLR));
DEBUG(("vmesa->ScissorTB: %i\n", vmesa->ScissorTB));
}

if (vmesa->dirty & S3V_UPLOAD_MASKS) {
vmesa->dirty &= ~S3V_UPLOAD_MASKS;
DEBUG(("S3V_UPLOAD_BLEND\n"));
}
if (vmesa->dirty & S3V_UPLOAD_ALPHA) {
vmesa->dirty &= ~S3V_UPLOAD_ALPHA;
DEBUG(("S3V_UPLOAD_ALPHA\n"));
}
if (vmesa->dirty & S3V_UPLOAD_SHADE) {
vmesa->dirty &= ~S3V_UPLOAD_SHADE;
}
if (vmesa->dirty & S3V_UPLOAD_POLYGON) {
vmesa->dirty &= ~S3V_UPLOAD_POLYGON;
}
if (vmesa->dirty & S3V_UPLOAD_DEPTH) {
vmesa->dirty &= ~S3V_UPLOAD_DEPTH;
DEBUG(("S3V_UPLOAD_DEPTH: DepthMode = 0x%x08\n", vmesa->DepthMode));
}
if (vmesa->dirty & S3V_UPLOAD_GEOMETRY) {
vmesa->dirty &= ~S3V_UPLOAD_GEOMETRY;
}

if (vmesa->dirty & S3V_UPLOAD_TRANSFORM) {
vmesa->dirty &= ~S3V_UPLOAD_TRANSFORM;
}
if (vmesa->dirty & S3V_UPLOAD_TEX0) {
s3vTextureObjectPtr curTex = vmesa->CurrentTexObj[0];
vmesa->dirty &= ~S3V_UPLOAD_TEX0;
DEBUG(("S3V_UPLOAD_TEX0\n"));
if (curTex) {
DEBUG(("S3V_UPLOAD_TEX0: curTex\n"));
} else {
DEBUG(("S3V_UPLOAD_TEX0: !curTex\n"));
}
}
}

void s3vDDUpdateHWState( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

int new_state = vmesa->new_state;

/* s3vUpdateClipping( ctx ); */

if ( new_state )
{

vmesa->new_state = 0;

/* Update the various parts of the context's state.
*/
if ( new_state & S3V_NEW_ALPHA )
s3vUpdateAlphaMode( ctx );

if ( new_state & S3V_NEW_DEPTH )
s3vUpdateZMode( ctx );

if ( new_state & S3V_NEW_FOG )
s3vUpdateFogAttrib( ctx );

if ( new_state & S3V_NEW_CLIP )
{
DEBUG(("---> going to s3vUpdateClipping\n"));
s3vUpdateClipping( ctx );
}

if ( new_state & S3V_NEW_POLYGON )
s3vUpdatePolygon( ctx );

if ( new_state & S3V_NEW_CULL )
s3vUpdateCull( ctx );

if ( new_state & S3V_NEW_MASKS )
s3vUpdateMasks( ctx );

if ( new_state & S3V_NEW_WINDOW )
s3vUpdateWindow( ctx );
/*
if ( new_state & S3_NEW_TEXTURE )
s3vUpdateTextureState( ctx );
*/
CMDCHANGE();
}

/* HACK ! */
s3vEmitHwState( vmesa );
}


static void s3vDDUpdateState( 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 );
S3V_CONTEXT(ctx)->new_gl_state |= new_state;
}


/* Initialize the context's hardware state.
*/
void s3vInitState( s3vContextPtr vmesa )
{
vmesa->new_state = 0;
}

/* Initialize the driver's state functions.
*/
void s3vInitStateFuncs( GLcontext *ctx )
{
ctx->Driver.UpdateState = s3vDDUpdateState;

ctx->Driver.Clear = s3vDDClear;
ctx->Driver.ClearIndex = NULL;
ctx->Driver.ClearColor = s3vDDClearColor;
ctx->Driver.SetDrawBuffer = s3vDDSetDrawBuffer;

ctx->Driver.IndexMask = NULL;
ctx->Driver.ColorMask = NULL; /* s3vDDColorMask; */ /* FIXME */

ctx->Driver.AlphaFunc = s3vDDAlphaFunc; /* FIXME */
ctx->Driver.BlendEquation = NULL; /* s3vDDBlendEquation; */
ctx->Driver.BlendFunc = s3vDDBlendFunc; /* FIXME */
ctx->Driver.BlendFuncSeparate = NULL; /* s3vDDBlendFuncSeparate; */
ctx->Driver.ClearDepth = s3vDDClearDepth;
ctx->Driver.CullFace = s3vDDCullFace;
ctx->Driver.FrontFace = s3vDDFrontFace;
ctx->Driver.DepthFunc = s3vDDDepthFunc; /* FIXME */
ctx->Driver.DepthMask = s3vDDDepthMask; /* FIXME */
ctx->Driver.DepthRange = NULL; /* s3vDDDepthRange; */
ctx->Driver.Enable = s3vDDEnable; /* FIXME */
ctx->Driver.Finish = s3vDDFinish;
ctx->Driver.Flush = s3vDDFlush;
#if 1
ctx->Driver.Fogfv = NULL; /* s3vDDFogfv; */
#endif
ctx->Driver.Hint = NULL;
ctx->Driver.LineWidth = NULL; /* s3vDDLineWidth; */
ctx->Driver.LineStipple = NULL; /* s3vDDLineStipple; */
#if ENABLELIGHTING
ctx->Driver.Lightfv = NULL; /* s3vDDLightfv; */

ctx->Driver.LightModelfv = NULL; /* s3vDDLightModelfv; */
#endif
ctx->Driver.LogicOpcode = NULL; /* s3vDDLogicalOpcode; */
ctx->Driver.PointSize = NULL; /* s3vDDPointSize; */
ctx->Driver.PolygonMode = NULL; /* s3vDDPolygonMode; */
ctx->Driver.PolygonStipple = NULL; /* s3vDDPolygonStipple; */
ctx->Driver.Scissor = s3vDDScissor; /* ScissorLR / ScissorTB */
ctx->Driver.ShadeModel = NULL; /* s3vDDShadeModel; */
ctx->Driver.ClearStencil = NULL;
ctx->Driver.StencilFunc = NULL;
ctx->Driver.StencilMask = NULL;
ctx->Driver.StencilOp = NULL;
ctx->Driver.Viewport = NULL; /* s3vDDViewport; */
}

+ 560
- 0
src/mesa/drivers/dri/s3v/s3v_tex.c View File

@@ -0,0 +1,560 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include <stdlib.h>
#include <stdio.h>

#include "glheader.h"
#include "mtypes.h"
#include "mem.h"
#include "simple_list.h"
#include "enums.h"
#include "texstore.h"
#include "texformat.h"
#include "swrast/swrast.h"

#include "mm.h"
#include "mmath.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)
{
CARD32 t0 = t->TextureCMD;
CARD32 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)
{
CARD32 t0 = t->TextureCMD;
CARD32 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,
GLubyte color[4])
{
#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(color[0], color[1], color[2], color[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;
CARD32 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
}

if (!ctx->Texture._ReallyEnabled) {
DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n"));
return;
}

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].Current1D;
s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );

texObj = ctx->Texture.Unit[0].Current2D;
s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
#endif

#if 0
ctx->Texture.CurrentUnit = 1;

texObj = ctx->Texture.Unit[1].Current1D;
s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );

texObj = ctx->Texture.Unit[1].Current2D;
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.ChooseTextureFormat = _mesa_choose_tex_format;
ctx->Driver.TexImage1D = _mesa_store_teximage1d;
ctx->Driver.TexImage2D = s3vTexImage2D;
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
ctx->Driver.TexSubImage2D = s3vTexSubImage2D;
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
ctx->Driver.BindTexture = s3vBindTexture;
ctx->Driver.DeleteTexture = s3vDeleteTexture;
ctx->Driver.TexParameter = s3vTexParameter;
ctx->Driver.UpdateTexturePalette = 0;
ctx->Driver.IsTextureResident = s3vIsTextureResident;
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;

s3vInitTextureObjects( ctx );
}

+ 26
- 0
src/mesa/drivers/dri/s3v/s3v_tex.h View File

@@ -0,0 +1,26 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef _S3V_TEX_H
#define _S3V_TEX_H

#define TEX_DEBUG_ON 0

#if TEX_DEBUG_ON
#define DEBUG_TEX(str) printf str
#else
#define DEBUG_TEX(str) /* str */
#endif

#define _TEXFLUSH 1 /* flush before uploading */
#define _TEXLOCK 1 /* lock before writing new texures to card mem */
/* if you turn it on you will gain stability and image
quality, but you will loose performance (~10%) */
#define _TEXFALLBACK 0 /* fallback to software for -big- textures (slow) */
/* turning this off, you will lose some tex (e.g. mountains
on tuxracer) but you will increase average playability */

#define _TEXALIGN 0x00000007

#endif

+ 583
- 0
src/mesa/drivers/dri/s3v/s3v_texmem.c View File

@@ -0,0 +1,583 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include <stdlib.h>
#include <stdio.h>

#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"

#include "mm.h"
#include "mem.h"
#include "s3v_context.h"
#include "s3v_lock.h"
#include "s3v_tex.h"

void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
void s3vUpdateTexLRU( s3vContextPtr vmesa, s3vTextureObjectPtr t );


void s3vDestroyTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t)
{
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vDestroyTexObj: #%i ***\n", ++times));
#endif

if (!t) return;

/* FIXME: useful? */
#if _TEXFLUSH
if (vmesa)
DMAFLUSH();
#endif

/* This is sad - need to sync *in case* we upload a texture
* to this newly free memory...
*/
if (t->MemBlock) {
mmFreeMem(t->MemBlock);
t->MemBlock = 0;

if (vmesa && t->age > vmesa->dirtyAge)
vmesa->dirtyAge = t->age;
}

if (t->globj)
t->globj->DriverData = NULL;

if (vmesa) {
if (vmesa->CurrentTexObj[0] == t) {
vmesa->CurrentTexObj[0] = 0;
vmesa->dirty &= ~S3V_UPLOAD_TEX0;
}

#if 0
if (vmesa->CurrentTexObj[1] == t) {
vmesa->CurrentTexObj[1] = 0;
vmesa->dirty &= ~S3V_UPLOAD_TEX1;
}
#endif
}

remove_from_list(t);
FREE(t);
}


void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t)
{
/* int i; */
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vSwapOutTexObj: #%i ***\n", ++times));
#endif

if (t->MemBlock) {

mmFreeMem(t->MemBlock);
t->MemBlock = 0;

if (t->age > vmesa->dirtyAge)
vmesa->dirtyAge = t->age;
t->dirty_images = ~0;
move_to_tail(&(vmesa->SwappedOut), t);
}
}


/* Upload an image from mesa's internal copy.
*/

static void s3vUploadTexLevel( s3vContextPtr vmesa, s3vTextureObjectPtr t,
int level )
{
__DRIscreenPrivate *sPriv = vmesa->driScreen;
const struct gl_texture_image *image = t->image[level].image;
int i,j;
int l2d;
/* int offset = 0; */
int words;
CARD32* dest;
#if TEX_DEBUG_ON
static unsigned int times=0;
#endif
if ( !image ) return;
if (image->Data == 0) return;

DEBUG_TEX(("*** s3vUploadTexLevel: #%i ***\n", ++times));
DEBUG_TEX(("level = %i\n", level));

l2d = 5; /* 32bits per texel == 1<<5 */
/*
if (level == 0)
;
*/
DEBUG_TEX(("t->image[%i].offset = 0x%x\n",
level, t->image[level].offset));
t->TextureBaseAddr[level] = (CARD32)(t->BufAddr + t->image[level].offset
+ _TEXALIGN) & (CARD32)(~_TEXALIGN);
dest = (CARD32*)(sPriv->pFB + t->TextureBaseAddr[level]);

DEBUG_TEX(("sPriv->pFB = 0x%x\n", sPriv->pFB));
DEBUG_TEX(("dest = 0x%x\n", dest));
DEBUG_TEX(("dest - sPriv->pFB = 0x%x\n", ((int)dest - (int)sPriv->pFB)));

/* NOTE: we implicitly suppose t->texelBytes == 2 */

words = (image->Width * image->Height) >> 1;

DEBUG_TEX(("\n\n"));

switch (t->image[level].internalFormat) {
case GL_RGB:
case 3:
{
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_RGB:\n"));
/*
if (level == 0)
;
*/
/* The UGLY way, and SLOW : use DMA FIXME ! */

for (i = 0; i < words; i++) {
unsigned int data;
/* data = PACK_COLOR_565(src[0],src[1],src[2]); */
data = S3VIRGEPACKCOLOR555(src[0],src[1],src[2],255)
|(S3VIRGEPACKCOLOR555(src[3],src[4],src[5],255)<<16);

*dest++ = data;
/* src += 3; */
src +=6;
}
}
break;

case GL_RGBA:
case 4:
{
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_RGBA:\n"));
/*
if (level == 0)
;
*/
for (i = 0; i < words; i++) {
unsigned int data;
/* data = PACK_COLOR_8888(src[0],src[1],src[2],src[3]); */
data = S3VIRGEPACKCOLOR4444(src[0], src[1],src[2], src[3])
| (S3VIRGEPACKCOLOR4444(src[4], src[5], src[6], src[7]) << 16);
*dest++ = data;
/* src += 4; */
src += 8;
}
}
break;

case GL_LUMINANCE:
{
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_LUMINANCE:\n"));
/*
if (level == 0)
;
*/
for (i = 0; i < words; i++) {
unsigned int data;
/* data = PACK_COLOR_888(src[0],src[0],src[0]); */
data = S3VIRGEPACKCOLOR4444(src[0],src[0],src[0],src[0])
| (S3VIRGEPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16);
*dest++ = data;
/* src ++; */
src +=2;
}
}
break;

case GL_INTENSITY:
{
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_INTENSITY:\n"));
/*
if (level == 0)
;
*/
for (i = 0; i < words; i++) {
unsigned int data;
/* data = PACK_COLOR_8888(src[0],src[0],src[0],src[0]); */
data = S3VIRGEPACKCOLOR4444(src[0],src[0],src[0],src[0])
| (S3VIRGEPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16);

*dest++ = data;
/* src ++; */
src += 2;
}
}
break;

case GL_LUMINANCE_ALPHA:
{
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_LUMINANCE_ALPHA:\n"));
/*
if (level == 0)
;
*/
for (i = 0; i < words; i++) {
unsigned int data;
/* data = PACK_COLOR_8888(src[0],src[0],src[0],src[1]); */
data = S3VIRGEPACKCOLOR4444(src[0],src[0],src[0],src[1])
| (S3VIRGEPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16);
*dest++ = data;
/* src += 2; */
src += 4;
}
}
break;

case GL_ALPHA:
{
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_ALPHA:\n"));
/*
if (level == 0)
;
*/
for (i = 0; i < words; i++) {
unsigned int data;
/* data = PACK_COLOR_8888(255,255,255,src[0]); */
data = S3VIRGEPACKCOLOR4444(255,255,255,src[0])
| (S3VIRGEPACKCOLOR4444(255,255,255,src[1]) << 16);
*dest++ = data;
/* src += 1; */
src += 2;
}
}
break;

/* TODO: Translate color indices *now*:
*/
case GL_COLOR_INDEX:
{
GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset);
GLubyte *src = (GLubyte *)image->Data;

DEBUG_TEX(("GL_COLOR_INDEX:\n"));

for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
for (i = 0 ; i < image->Width ; i++) {
dst[i] = src[0];
src += 1;
}
}
}
break;

default:
fprintf(stderr, "Not supported texture format %s\n",
_mesa_lookup_enum_by_nr(image->Format));
}

DEBUG_TEX(("words = %i\n\n", words));
}

void s3vPrintLocalLRU( s3vContextPtr vmesa )
{
s3vTextureObjectPtr t;
int sz = 1 << (vmesa->s3vScreen->logTextureGranularity);

#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vPrintLocalLRU: #%i ***\n", ++times));
#endif

foreach( t, &vmesa->TexObjList ) {
if (!t->globj)
fprintf(stderr, "Placeholder %d at %x sz %x\n",
t->MemBlock->ofs / sz,
t->MemBlock->ofs,
t->MemBlock->size);
else
fprintf(stderr, "Texture at %x sz %x\n",
t->MemBlock->ofs,
t->MemBlock->size);

}
}

void s3vPrintGlobalLRU( s3vContextPtr vmesa )
{
int i, j;
S3VTexRegionPtr list = vmesa->sarea->texList;
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vPrintGlobalLRU: #%i ***\n", ++times));
#endif

for (i = 0, j = S3V_NR_TEX_REGIONS ; i < S3V_NR_TEX_REGIONS ; i++) {
fprintf(stderr, "list[%d] age %d next %d prev %d\n",
j, list[j].age, list[j].next, list[j].prev);
j = list[j].next;
if (j == S3V_NR_TEX_REGIONS) break;
}

if (j != S3V_NR_TEX_REGIONS)
fprintf(stderr, "Loop detected in global LRU\n");
}


void s3vResetGlobalLRU( s3vContextPtr vmesa )
{
S3VTexRegionPtr list = vmesa->sarea->texList;
int sz = 1 << vmesa->s3vScreen->logTextureGranularity;
int i;

#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vResetGlobalLRU: #%i ***\n", ++times));
#endif

/* (Re)initialize the global circular LRU list. The last element
* in the array (S3V_NR_TEX_REGIONS) is the sentinal. Keeping it
* at the end of the array allows it to be addressed rationally
* when looking up objects at a particular location in texture
* memory.
*/
for (i = 0 ; (i+1) * sz <= vmesa->s3vScreen->textureSize ; i++) {
list[i].prev = i-1;
list[i].next = i+1;
list[i].age = 0;
}

i--;
list[0].prev = S3V_NR_TEX_REGIONS;
list[i].prev = i-1;
list[i].next = S3V_NR_TEX_REGIONS;
list[S3V_NR_TEX_REGIONS].prev = i;
list[S3V_NR_TEX_REGIONS].next = 0;
vmesa->sarea->texAge = 0;
}


void s3vUpdateTexLRU( s3vContextPtr vmesa, s3vTextureObjectPtr t )
{
/*
int i;
int logsz = vmesa->s3vScreen->logTextureGranularity;
int start = t->MemBlock->ofs >> logsz;
int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
S3VTexRegionPtr list = vmesa->sarea->texList;
*/

#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vUpdateTexLRU: #%i ***\n", ++times));
#endif

vmesa->texAge = ++vmesa->sarea->texAge;

/* Update our local LRU
*/
move_to_head( &(vmesa->TexObjList), t );

/* Update the global LRU
*/
#if 0
for (i = start ; i <= end ; i++) {

list[i].in_use = 1;
list[i].age = vmesa->texAge;

/* remove_from_list(i)
*/
list[(unsigned)list[i].next].prev = list[i].prev;
list[(unsigned)list[i].prev].next = list[i].next;

/* insert_at_head(list, i)
*/
list[i].prev = S3V_NR_TEX_REGIONS;
list[i].next = list[S3V_NR_TEX_REGIONS].next;
list[(unsigned)list[S3V_NR_TEX_REGIONS].next].prev = i;
list[S3V_NR_TEX_REGIONS].next = i;
}
#endif
}


/* Called for every shared texture region which has increased in age
* since we last held the lock.
*
* Figures out which of our textures have been ejected by other clients,
* and pushes a placeholder texture onto the LRU list to represent
* the other client's textures.
*/
void s3vTexturesGone( s3vContextPtr vmesa,
GLuint offset,
GLuint size,
GLuint in_use )
{
s3vTextureObjectPtr t, tmp;
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vTexturesGone: #%i ***\n", ++times));
#endif

foreach_s ( t, tmp, &vmesa->TexObjList ) {

if (t->MemBlock->ofs >= offset + size ||
t->MemBlock->ofs + t->MemBlock->size <= offset)
continue;

/* It overlaps - kick it off. Need to hold onto the currently bound
* objects, however.
*/
s3vSwapOutTexObj( vmesa, t );
}

if (in_use) {
t = (s3vTextureObjectPtr) calloc(1,sizeof(*t));
if (!t) return;

t->MemBlock = mmAllocMem( vmesa->texHeap, size, 0, offset);
insert_at_head( &vmesa->TexObjList, t );
}

/* Reload any lost textures referenced by current vertex buffer.
*/
#if 0
if (vmesa->vertex_buffer) {
int i, j;

fprintf(stderr, "\n\nreload tex\n");

for (i = 0 ; i < vmesa->statenr ; i++) {
for (j = 0 ; j < 2 ; j++) {
s3vTextureObjectPtr t = vmesa->state_tex[j][i];
if (t) {
if (t->MemBlock == 0)
s3vUploadTexImages( vmesa, t );
}
}
}

/* Hard to do this with the lock held:
*/
/* S3V_FIREVERTICES( vmesa ); */
}
#endif
}


/* This is called with the lock held. May have to eject our own and/or
* other client's texture objects to make room for the upload.
*/
void s3vUploadTexImages( s3vContextPtr vmesa, s3vTextureObjectPtr t )
{
int i;
int ofs;
int numLevels;
#if TEX_DEBUG_ON
static unsigned int times=0;
static unsigned int try=0;

DEBUG_TEX(("*** s3vUploadTexImages: #%i ***\n", ++times));
DEBUG_TEX(("vmesa->texHeap = 0x%x; t->totalSize = %i\n",
(unsigned int)vmesa->texHeap, t->totalSize));
#endif

/* Do we need to eject LRU texture objects?
*/
if (!t->MemBlock) {

while (1)
{
/* int try = 0; */
DEBUG_TEX(("trying to alloc mem for tex (try %i)\n", ++try));

t->MemBlock = mmAllocMem( vmesa->texHeap, t->totalSize, 12, 0 );

if (t->MemBlock)
break;

if (vmesa->TexObjList.prev == vmesa->CurrentTexObj[0]) {
/* || vmesa->TexObjList.prev == vmesa->CurrentTexObj[1]) {
fprintf(stderr, "Hit bound texture in upload\n");
s3vPrintLocalLRU( vmesa ); */
return;
}

if (vmesa->TexObjList.prev == &(vmesa->TexObjList)) {
/* fprintf(stderr, "Failed to upload texture, sz %d\n",
t->totalSize);
mmDumpMemInfo( vmesa->texHeap ); */
return;
}

DEBUG_TEX(("swapping out: %p\n", vmesa->TexObjList.prev));
s3vSwapOutTexObj( vmesa, vmesa->TexObjList.prev );
}

ofs = t->MemBlock->ofs;

t->BufAddr = vmesa->s3vScreen->texOffset + ofs;

DEBUG_TEX(("ofs = 0x%x\n", ofs));
DEBUG_TEX(("t->BufAddr = 0x%x\n", t->BufAddr));

/* FIXME: check if we need it */
#if 0
if (t == vmesa->CurrentTexObj[0]) {
vmesa->dirty |= S3V_UPLOAD_TEX0;
vmesa->restore_primitive = -1;
}
#endif

#if 0
if (t == vmesa->CurrentTexObj[1])
vmesa->dirty |= S3V_UPLOAD_TEX1;
#endif

s3vUpdateTexLRU( vmesa, t );
}

#if 0
if (vmesa->dirtyAge >= GET_DISPATCH_AGE(vmesa))
s3vWaitAgeLocked( vmesa, vmesa->dirtyAge );
#endif

#if _TEXLOCK
S3V_SIMPLE_FLUSH_LOCK(vmesa);
#endif
numLevels = t->lastLevel - t->firstLevel + 1;
for (i = 0 ; i < numLevels ; i++)
if (t->dirty_images & (1<<i))
s3vUploadTexLevel( vmesa, t, i );

t->dirty_images = 0;
#if _TEXLOCK
S3V_SIMPLE_UNLOCK(vmesa);
#endif
}

+ 303
- 0
src/mesa/drivers/dri/s3v/s3v_texstate.c View File

@@ -0,0 +1,303 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include <stdlib.h>
#include <stdio.h>

#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"

#include "mm.h"
#include "s3v_context.h"
#include "s3v_tex.h"


static void s3vSetTexImages( s3vContextPtr vmesa,
struct gl_texture_object *tObj )
{
GLuint height, width, pitch, i, /*textureFormat,*/ log_pitch;
s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
GLint firstLevel, lastLevel, numLevels;
GLint log2Width, log2Height;
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vSetTexImages: #%i ***\n", ++times));
#endif

t->texelBytes = 2; /* FIXME: always 2 ? */

/* Compute which mipmap levels we really want to send to the hardware.
* This depends on the base image size, GL_TEXTURE_MIN_LOD,
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
* Yes, this looks overly complicated, but it's all needed.
*/
if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) {
firstLevel = lastLevel = tObj->BaseLevel;
}
else {
firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
firstLevel = MAX2(firstLevel, tObj->BaseLevel);
lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
lastLevel = MAX2(lastLevel, tObj->BaseLevel);
lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
lastLevel = MIN2(lastLevel, tObj->MaxLevel);
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
}

/* save these values */
t->firstLevel = firstLevel;
t->lastLevel = lastLevel;

numLevels = lastLevel - firstLevel + 1;

log2Width = tObj->Image[firstLevel]->WidthLog2;
log2Height = tObj->Image[firstLevel]->HeightLog2;


/* Figure out the amount of memory required to hold all the mipmap
* levels. Choose the smallest pitch to accomodate the largest
* mipmap:
*/
width = tObj->Image[firstLevel]->Width * t->texelBytes;
for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
log_pitch++;
/* All images must be loaded at this pitch. Count the number of
* lines required:
*/
for ( height = i = 0 ; i < numLevels ; i++ ) {
t->image[i].image = tObj->Image[firstLevel + i];
t->image[i].offset = height * pitch;
t->image[i].internalFormat = baseImage->Format;
height += t->image[i].image->Height;
t->TextureBaseAddr[i] = (t->BufAddr + t->image[i].offset +
_TEXALIGN) & (CARD32)(~_TEXALIGN);
}

t->Pitch = pitch;
t->WidthLog2 = log2Width;
t->totalSize = height*pitch;
t->max_level = i-1;
vmesa->dirty |= S3V_UPLOAD_TEX0 /* | S3V_UPLOAD_TEX1*/;
vmesa->restore_primitive = -1;
DEBUG(("<><>pitch = TexStride = %i\n", pitch));
DEBUG(("log2Width = %i\n", log2Width));

s3vUploadTexImages( vmesa, t );
}

static void s3vUpdateTexEnv( GLcontext *ctx, GLuint unit )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const struct gl_texture_object *tObj = texUnit->_Current;
const GLuint format = tObj->Image[tObj->BaseLevel]->Format;
/*
s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
GLuint tc;
*/
GLuint alpha = 0;
CARD32 cmd = vmesa->CMD;
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vUpdateTexEnv: %i ***\n", ++times));
#endif

cmd &= ~TEX_COL_MASK;
cmd &= ~TEX_BLEND_MAKS;
/* cmd &= ~ALPHA_BLEND_MASK; */

DEBUG(("format = "));

switch (format) {
case GL_RGB:
DEBUG_TEX(("GL_RGB\n"));
cmd |= TEX_COL_ARGB1555;
break;
case GL_LUMINANCE:
DEBUG_TEX(("GL_LUMINANCE\n"));
cmd |= TEX_COL_ARGB4444;
alpha = 1; /* FIXME: check */
break;
case GL_ALPHA:
DEBUG_TEX(("GL_ALPHA\n"));
cmd |= TEX_COL_ARGB4444;
alpha = 1;
break;
case GL_LUMINANCE_ALPHA:
DEBUG_TEX(("GL_LUMINANCE_ALPHA\n"));
cmd |= TEX_COL_ARGB4444;
alpha = 1;
break;
case GL_INTENSITY:
DEBUG_TEX(("GL_INTENSITY\n"));
cmd |= TEX_COL_ARGB4444;
alpha = 1;
break;
case GL_RGBA:
DEBUG_TEX(("GL_RGBA\n"));
cmd |= TEX_COL_ARGB4444;
alpha = 1;
break;
case GL_COLOR_INDEX:
DEBUG_TEX(("GL_COLOR_INDEX\n"));
cmd |= TEX_COL_PAL;
break;
}

DEBUG_TEX(("EnvMode = "));

switch (texUnit->EnvMode) {
case GL_REPLACE:
DEBUG_TEX(("GL_REPLACE\n"));
cmd |= TEX_REFLECT; /* FIXME */
vmesa->_tri[1] = DO_TEX_UNLIT_TRI; /* FIXME: white tri hack */
vmesa->_alpha_tex = ALPHA_TEX /* * alpha */;
break;
case GL_MODULATE:
DEBUG_TEX(("GL_MODULATE\n"));
cmd |= TEX_MODULATE;
vmesa->_tri[1] = DO_TEX_LIT_TRI;
#if 0
if (alpha)
vmesa->_alpha_tex = ALPHA_TEX /* * alpha */;
else
vmesa->_alpha_tex = ALPHA_SRC /* * alpha */;
#else
vmesa->_alpha_tex = ALPHA_TEX ;
#endif
break;
case GL_ADD:
DEBUG_TEX(("DEBUG_TEX\n"));
/* do nothing ???*/
break;
case GL_DECAL:
DEBUG_TEX(("GL_DECAL\n"));
cmd |= TEX_DECAL;
vmesa->_tri[1] = DO_TEX_LIT_TRI;
vmesa->_alpha_tex = ALPHA_OFF;
break;
case GL_BLEND:
DEBUG_TEX(("GL_BLEND\n"));
cmd |= TEX_DECAL;
vmesa->_tri[1] = DO_TEX_LIT_TRI;
vmesa->_alpha_tex = ALPHA_OFF; /* FIXME: sure? */
break;
default:
fprintf(stderr, "unknown tex env mode");
return;
}
DEBUG_TEX(("\n\n vmesa->CMD was 0x%x\n", vmesa->CMD));
DEBUG_TEX(( " vmesa->CMD is 0x%x\n\n", cmd ));

vmesa->_alpha[1] = vmesa->_alpha_tex;
vmesa->CMD = cmd; /* | MIPMAP_LEVEL(8); */
vmesa->restore_primitive = -1;
}

static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
CARD32 cmd = vmesa->CMD;
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vUpdateTexUnit: %i ***\n", ++times));
DEBUG_TEX(("and vmesa->CMD was 0x%x\n", vmesa->CMD));
#endif

if (texUnit->_ReallyEnabled == TEXTURE0_2D)
{
struct gl_texture_object *tObj = texUnit->_Current;
s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;

/* Upload teximages (not pipelined)
*/
if (t->dirty_images) {
#if _TEXFLUSH
DMAFLUSH();
#endif
s3vSetTexImages( vmesa, tObj );
if (!t->MemBlock) {
#if _TEXFALLBACK
FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE );
#endif
return;
}
}

/* Update state if this is a different texture object to last
* time.
*/
#if 1
if (vmesa->CurrentTexObj[unit] != t) {
vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */;
vmesa->CurrentTexObj[unit] = t;
s3vUpdateTexLRU( vmesa, t ); /* done too often */
}
#endif
/* Update texture environment if texture object image format or
* texture environment state has changed.
*/
if (tObj->Image[tObj->BaseLevel]->Format != vmesa->TexEnvImageFmt[unit]) {
vmesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
s3vUpdateTexEnv( ctx, unit );
}
#if 1
cmd = vmesa->CMD & ~MIP_MASK;
vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */;
vmesa->CurrentTexObj[unit] = t;
vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
vmesa->TexStride = t->Pitch;
cmd |= MIPMAP_LEVEL(t->WidthLog2);
DEBUG_TEX(("\n\n>> vmesa->CMD was 0x%x\n", vmesa->CMD));
DEBUG_TEX(( ">> vmesa->CMD is 0x%x\n\n", cmd ));
DEBUG_TEX(("t->WidthLog2 = %i\n", t->WidthLog2));
DEBUG_TEX(("MIPMAP_LEVEL(t->WidthLog2) = 0x%x\n", MIPMAP_LEVEL(t->WidthLog2)));

vmesa->CMD = cmd;
vmesa->restore_primitive = -1;
#endif
}
else if (texUnit->_ReallyEnabled) { /* _ReallyEnabled but != TEXTURE0_2D */
#if _TEXFALLBACK
FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE );
#endif
}
else /*if (vmesa->CurrentTexObj[unit])*/ { /* !_ReallyEnabled */
vmesa->CurrentTexObj[unit] = 0;
vmesa->TexEnvImageFmt[unit] = 0;
vmesa->dirty &= ~(S3V_UPLOAD_TEX0<<unit);
}
}


void s3vUpdateTextureState( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
#if TEX_DEBUG_ON
static unsigned int times=0;
DEBUG_TEX(("*** s3vUpdateTextureState: #%i ***\n", ++times));
#endif

if (!ctx->Texture._ReallyEnabled) {
DEBUG_TEX(("!ctx->Texture._ReallyEnabled\n"));
return;
}

#if _TEXFALLBACK
FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_FALSE );
#endif
s3vUpdateTexUnit( ctx, 0 );
#if 0
s3vUpdateTexUnit( ctx, 1 );
#endif
}

+ 850
- 0
src/mesa/drivers/dri/s3v/s3v_tris.c View File

@@ -0,0 +1,850 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include <stdio.h>
#include <stdlib.h>

#include <sys/ioctl.h>

#include "s3v_context.h"
#include "s3v_vb.h"
#include "s3v_tris.h"

#include "glheader.h"
#include "mtypes.h"
#include "macros.h"
#include "colormac.h"

#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"


/***********************************************************************
* Build hardware rasterization functions *
***********************************************************************/

#define DO_TRI 1
#define HAVE_RGBA 1
#define HAVE_SPEC 0
#define HAVE_BACK_COLORS 0
#define HAVE_HW_FLATSHADE 1
#define VERTEX s3vVertex
#define TAB rast_tab

#define VERT_SET_RGBA( v, c ) \
do { \
UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c); \
/* *(v->ub4[4]) = c; \ */ \
} while (0)
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
/*
#define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
*/
#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]

#define S3V_OFFSET_BIT 0x01
#define S3V_TWOSIDE_BIT 0x02
#define S3V_UNFILLED_BIT 0x04
#define S3V_FALLBACK_BIT 0x08
#define S3V_MAX_TRIFUNC 0x10


static struct {
points_func points;
line_func line;
triangle_func triangle;
quad_func quad;
} rast_tab[S3V_MAX_TRIFUNC];

#define S3V_RAST_CULL_BIT 0x01
#define S3V_RAST_FLAT_BIT 0x02
#define S3V_RAST_TEX_BIT 0x04

static s3v_point_func s3v_point_tab[0x8];
static s3v_line_func s3v_line_tab[0x8];
static s3v_tri_func s3v_tri_tab[0x8];
static s3v_quad_func s3v_quad_tab[0x8];

#define IND (0)
#define TAG(x) x
#include "s3v_tritmp.h"

#define IND (S3V_RAST_CULL_BIT)
#define TAG(x) x##_cull
#include "s3v_tritmp.h"

#define IND (S3V_RAST_FLAT_BIT)
#define TAG(x) x##_flat
#include "s3v_tritmp.h"

#define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT)
#define TAG(x) x##_cull_flat
#include "s3v_tritmp.h"

#define IND (S3V_RAST_TEX_BIT)
#define TAG(x) x##_tex
#include "s3v_tritmp.h"

#define IND (S3V_RAST_CULL_BIT|S3V_RAST_TEX_BIT)
#define TAG(x) x##_cull_tex
#include "s3v_tritmp.h"

#define IND (S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
#define TAG(x) x##_flat_tex
#include "s3v_tritmp.h"

#define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
#define TAG(x) x##_cull_flat_tex
#include "s3v_tritmp.h"

static void init_rast_tab( void )
{
DEBUG(("*** init_rast_tab ***\n"));

s3v_init();
s3v_init_cull();
s3v_init_flat();
s3v_init_cull_flat();
s3v_init_tex();
s3v_init_cull_tex();
s3v_init_flat_tex();
s3v_init_cull_flat_tex();
}

/***********************************************************************
* 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.
*/

#if 0
static void
s3v_fallback_quad( s3vContextPtr vmesa,
const s3vVertex *v0,
const s3vVertex *v1,
const s3vVertex *v2,
const s3vVertex *v3 )
{
GLcontext *ctx = vmesa->glCtx;
SWvertex v[4];
s3v_translate_vertex( ctx, v0, &v[0] );
s3v_translate_vertex( ctx, v1, &v[1] );
s3v_translate_vertex( ctx, v2, &v[2] );
s3v_translate_vertex( ctx, v3, &v[3] );
DEBUG(("s3v_fallback_quad\n"));
/* _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] ); */
}

static void
s3v_fallback_tri( s3vContextPtr vmesa,
const s3vVertex *v0,
const s3vVertex *v1,
const s3vVertex *v2 )
{
GLcontext *ctx = vmesa->glCtx;
SWvertex v[3];
s3v_translate_vertex( ctx, v0, &v[0] );
s3v_translate_vertex( ctx, v1, &v[1] );
s3v_translate_vertex( ctx, v2, &v[2] );
DEBUG(("s3v_fallback_tri\n"));
/* _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); */
}

static void
s3v_fallback_line( s3vContextPtr vmesa,
const s3vVertex *v0,
const s3vVertex *v1 )
{
GLcontext *ctx = vmesa->glCtx;
SWvertex v[2];
s3v_translate_vertex( ctx, v0, &v[0] );
s3v_translate_vertex( ctx, v1, &v[1] );
DEBUG(("s3v_fallback_line\n"));
_swrast_Line( ctx, &v[0], &v[1] );
}

/*
static void
s3v_fallback_point( s3vContextPtr vmesa,
const s3vVertex *v0 )
{
GLcontext *ctx = vmesa->glCtx;
SWvertex v[1];
s3v_translate_vertex( ctx, v0, &v[0] );
_swrast_Point( ctx, &v[0] );
}
*/
#endif

/***********************************************************************
* Choose rasterization functions *
***********************************************************************/

#define _S3V_NEW_RASTER_STATE (_NEW_FOG | \
_NEW_TEXTURE | \
_DD_NEW_TRI_SMOOTH | \
_DD_NEW_LINE_SMOOTH | \
_DD_NEW_POINT_SMOOTH | \
_DD_NEW_TRI_STIPPLE | \
_DD_NEW_LINE_STIPPLE)

#define LINE_FALLBACK (0)
#define TRI_FALLBACK (0)

static void s3v_nodraw_triangle(GLcontext *ctx, s3vVertex *v0,
s3vVertex *v1, s3vVertex *v2)
{
(void) (ctx && v0 && v1 && v2);
}

static void s3v_nodraw_quad(GLcontext *ctx,
s3vVertex *v0, s3vVertex *v1,
s3vVertex *v2, s3vVertex *v3)
{
(void) (ctx && v0 && v1 && v2 && v3);
}

void s3vChooseRasterState(GLcontext *ctx);

void s3vChooseRasterState(GLcontext *ctx)
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint ind = 0;

DEBUG(("*** s3vChooseRasterState ***\n"));

if (ctx->Polygon.CullFlag) {
if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
vmesa->draw_tri = (s3v_tri_func)s3v_nodraw_triangle;
vmesa->draw_quad = (s3v_quad_func)s3v_nodraw_quad;
return;
}
ind |= S3V_RAST_CULL_BIT;
/* s3v_update_cullsign(ctx); */
} /* else vmesa->backface_sign = 0; */

if ( flags & DD_FLATSHADE )
ind |= S3V_RAST_FLAT_BIT;

if ( ctx->Texture._ReallyEnabled ) {
ind |= S3V_RAST_TEX_BIT;
}

DEBUG(("ind = %i\n", ind));

vmesa->draw_line = s3v_line_tab[ind];
vmesa->draw_tri = s3v_tri_tab[ind];
vmesa->draw_quad = s3v_quad_tab[ind];
vmesa->draw_point = s3v_point_tab[ind];

#if 0
/* Hook in fallbacks for specific primitives. CURRENTLY DISABLED
*/
if (flags & LINE_FALLBACK)
vmesa->draw_line = s3v_fallback_line;
if (flags & TRI_FALLBACK) {
DEBUG(("TRI_FALLBACK\n"));
vmesa->draw_tri = s3v_fallback_tri;
vmesa->draw_quad = s3v_fallback_quad;
}
#endif
}




/***********************************************************************
* Macros for t_dd_tritmp.h to draw basic primitives *
***********************************************************************/

#define TRI( v0, v1, v2 ) \
do { \
/*
if (DO_FALLBACK) \
vmesa->draw_tri( vmesa, v0, v1, v2 ); \
else */ \
DEBUG(("TRI: max was here\n")); /* \
s3v_draw_tex_triangle( vmesa, v0, v1, v2 ); */ \
vmesa->draw_tri( vmesa, v0, v1, v2 ); \
} while (0)

#define QUAD( v0, v1, v2, v3 ) \
do { \
DEBUG(("QUAD: max was here\n")); \
vmesa->draw_quad( vmesa, v0, v1, v2, v3 ); \
} while (0)

#define LINE( v0, v1 ) \
do { \
DEBUG(("LINE: max was here\n")); \
vmesa->draw_line( vmesa, v0, v1 ); \
} while (0)

#define POINT( v0 ) \
do { \
vmesa->draw_point( vmesa, v0 ); \
} while (0)


/***********************************************************************
* Build render functions from dd templates *
***********************************************************************/

/*
#define S3V_OFFSET_BIT 0x01
#define S3V_TWOSIDE_BIT 0x02
#define S3V_UNFILLED_BIT 0x04
#define S3V_FALLBACK_BIT 0x08
#define S3V_MAX_TRIFUNC 0x10


static struct {
points_func points;
line_func line;
triangle_func triangle;
quad_func quad;
} rast_tab[S3V_MAX_TRIFUNC];
*/

#define DO_FALLBACK (IND & S3V_FALLBACK_BIT)
#define DO_OFFSET (IND & S3V_OFFSET_BIT)
#define DO_UNFILLED (IND & S3V_UNFILLED_BIT)
#define DO_TWOSIDE (IND & S3V_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 0
#define HAVE_BACK_COLORS 0
#define HAVE_HW_FLATSHADE 1
#define VERTEX s3vVertex
#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) (vmesa->verts + (e<<vmesa->vertex_stride_shift))

#if 0
#define VERT_SET_RGBA( v, c ) \
do { \
/* UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c) */ \
} while (0)

#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
/*
#define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
*/
#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
#endif

#define LOCAL_VARS(n) \
s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
GLuint color[n]; \
(void) color;


/***********************************************************************
* Helpers for rendering unfilled primitives *
***********************************************************************/

static const GLuint hw_prim[GL_POLYGON+1] = {
PrimType_Points,
PrimType_Lines,
PrimType_Lines,
PrimType_Lines,
PrimType_Triangles,
PrimType_Triangles,
PrimType_Triangles,
PrimType_Triangles,
PrimType_Triangles,
PrimType_Triangles
};

static void s3vResetLineStipple( GLcontext *ctx );
static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim );
static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim );
/*
extern static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end);
extern static void s3v_tris_emit(GLcontext *ctx, GLuint start, GLuint end);
*/
#define RASTERIZE(x) if (vmesa->hw_primitive != hw_prim[x]) \
s3vRasterPrimitive( ctx, hw_prim[x] )
#define RENDER_PRIMITIVE vmesa->render_primitive
#define TAG(x) x
#define IND S3V_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 (S3V_OFFSET_BIT)
#define TAG(x) x##_offset
#include "tnl_dd/t_dd_tritmp.h"

#define IND (S3V_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "tnl_dd/t_dd_tritmp.h"

#define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT)
#define TAG(x) x##_twoside_offset
#include "tnl_dd/t_dd_tritmp.h"

#define IND (S3V_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "tnl_dd/t_dd_tritmp.h"

#define IND (S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"

#define IND (S3V_TWOSIDE_BIT|S3V_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "tnl_dd/t_dd_tritmp.h"

#define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
#define TAG(x) x##_twoside_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"


static void init_render_tab( void )
{
DEBUG(("*** init_render_tab ***\n"));

init();
init_offset();
init_twoside();
init_twoside_offset();
init_unfilled();
init_offset_unfilled();
init_twoside_unfilled();
init_twoside_offset_unfilled();
}


/**********************************************************************/
/* Render unclipped begin/end objects */
/**********************************************************************/

#define VERT(x) (s3vVertex *)(s3vverts + (x << shift))

#define RENDER_POINTS( start, count ) \
DEBUG(("RENDER_POINTS...(ok)\n")); \
for ( ; start < count ; start++) \
vmesa->draw_line( vmesa, VERT(start), VERT(start) )
/* vmesa->draw_point( vmesa, VERT(start) ) */

#define RENDER_LINE( v0, v1 ) \
/* DEBUG(("RENDER_LINE...(ok)\n")); \ */ \
vmesa->draw_line( vmesa, VERT(v0), VERT(v1) ); \
DEBUG(("RENDER_LINE...(ok)\n"))

#define RENDER_TRI( v0, v1, v2 ) \
DEBUG(("RENDER_TRI...(ok)\n")); \
vmesa->draw_tri( vmesa, VERT(v0), VERT(v1), VERT(v2) )

#define RENDER_QUAD( v0, v1, v2, v3 ) \
DEBUG(("RENDER_QUAD...(ok)\n")); \
/* s3v_draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2),VERT(v3) ) */\
/* s3v_draw_triangle( vmesa, VERT(v0), VERT(v1), VERT(v2) ); \
s3v_draw_triangle( vmesa, VERT(v0), VERT(v2), VERT(v3) ) */ \
vmesa->draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
#define INIT(x) s3vRenderPrimitive( ctx, x );
#undef LOCAL_VARS
#define LOCAL_VARS \
s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
const GLuint shift = vmesa->vertex_stride_shift; \
const char *s3vverts = (char *)vmesa->verts; \
const GLboolean stipple = ctx->Line.StippleFlag; \
(void) stipple;
#define RESET_STIPPLE if ( stipple ) s3vResetLineStipple( ctx );
#define RESET_OCCLUSION
#define PRESERVE_VB_DEFS
#define ELT(x) (x)
#define TAG(x) s3v_##x##_verts
#include "tnl_dd/t_dd_rendertmp.h"


/**********************************************************************/
/* Render clipped primitives */
/**********************************************************************/

static void s3vRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
GLuint n )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint prim = vmesa->render_primitive;

DEBUG(("I AM in: s3vRenderClippedPoly\n"));

/* Render the new vertices as an unclipped polygon.
*/
if (1)
{
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 1
if (prim != GL_POLYGON) {
DEBUG(("and prim != GL_POLYGON\n"));
tnl->Driver.Render.PrimitiveNotify( ctx, prim );
}
#endif
}

static void s3vRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
/*tnl->Driver.LineFunc = s3v_line_tab[2];*/ /* _swsetup_Line; */

DEBUG(("I AM in: s3vRenderClippedLine\n"));
tnl->Driver.Render.Line( ctx, ii, jj );
}


/**********************************************************************/
/* Choose render functions */
/**********************************************************************/



#define _S3V_NEW_RENDERSTATE (_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_DD_NEW_TRI_OFFSET)

#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)

static void s3vChooseRenderState(GLcontext *ctx)
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint index = 0;

DEBUG(("s3vChooseRenderState\n"));

if (flags & ANY_RASTER_FLAGS) {
if (flags & DD_TRI_LIGHT_TWOSIDE) index |= S3V_TWOSIDE_BIT;
if (flags & DD_TRI_OFFSET) index |= S3V_OFFSET_BIT;
if (flags & DD_TRI_UNFILLED) index |= S3V_UNFILLED_BIT;
}

DEBUG(("vmesa->RenderIndex = %i\n", vmesa->RenderIndex));
DEBUG(("index = %i\n", index));

if (vmesa->RenderIndex != index) {
vmesa->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 (vmesa->RenderIndex == 0)
tnl->Driver.Render.PrimTabVerts = s3v_render_tab_verts;
else
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ClippedLine = s3vRenderClippedLine;
tnl->Driver.Render.ClippedPolygon = s3vRenderClippedPoly;
}
}


/**********************************************************************/
/* 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 s3v_render.c.
*/

static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
/* __DRIdrawablePrivate *dPriv = vmesa->driDrawable; */
CARD32 cmd = vmesa->CMD;
unsigned int _hw_prim = hwprim;

DEBUG(("s3vRasterPrimitive: hwprim = 0x%x ", _hw_prim));

/* printf("* vmesa->CMD = 0x%x\n", vmesa->CMD); */

if (vmesa->hw_primitive != _hw_prim)
{
DEBUG(("(new one) ***\n"));
cmd &= ~DO_MASK;
cmd &= ~ALPHA_BLEND_MASK;
vmesa->hw_primitive = _hw_prim;

if (_hw_prim == PrimType_Triangles) {
/* TRI */
DEBUG(("->switching to tri\n"));
cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
} else if (_hw_prim == PrimType_Lines
|| _hw_prim == PrimType_Points) {
/* LINE */
DEBUG(("->switching to line\n"));
cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
} else {
/* ugh? */
DEBUG(("->switching to your sis'ass\n"));
}
DEBUG(("\n"));

vmesa->restore_primitive = _hw_prim;
/* 0xacc16827: good value -> lightened newave!!! */
vmesa->CMD = cmd;
CMDCHANGE();
}
}

static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
CARD32 cmd = vmesa->CMD;

unsigned int _hw_prim = hw_prim[prim];

vmesa->render_primitive = prim;
vmesa->hw_primitive = _hw_prim;
DEBUG(("s3vRenderPrimitive #%i ", prim));
DEBUG(("_hw_prim = 0x%x\n", _hw_prim));

/* printf(" vmesa->CMD = 0x%x\n", vmesa->CMD); */

if (_hw_prim != vmesa->restore_primitive) {
DEBUG(("_hw_prim != vmesa->restore_primitive (was 0x%x)\n",
vmesa->restore_primitive));
#if 1
cmd &= ~DO_MASK;
cmd &= ~ALPHA_BLEND_MASK;
/*
printf(" cmd = 0x%x\n", cmd);
printf(" vmesa->_3d_mode=%i; vmesa->_tri[vmesa->_3d_mode]=0x%x\n",
vmesa->_3d_mode, vmesa->_tri[vmesa->_3d_mode]);
printf("vmesa->alpha[0] = 0x%x; vmesa->alpha[1] = 0x%x\n",
vmesa->_alpha[0], vmesa->_alpha[1]);
*/
if (_hw_prim == PrimType_Triangles) { /* TRI */
DEBUG(("->switching to tri\n"));
cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
DEBUG(("vmesa->TexStride = %i\n", vmesa->TexStride));
DEBUG(("vmesa->TexOffset = %i\n", vmesa->TexOffset));
DMAOUT_CHECK(3DTRI_Z_BASE, 12);
} else { /* LINE */
DEBUG(("->switching to line\n"));
cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
DMAOUT_CHECK(3DLINE_Z_BASE, 12);
}

DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8);
DMAOUT(vmesa->DestBase);
/* DMAOUT(vmesa->ScissorLR); */
/* DMAOUT(vmesa->ScissorTB); */

/* NOTE: we need to restore all these values since we
* are coming back from a vmesa->restore_primitive */
DMAOUT( (0 << 16) | (dPriv->w-1) );
DMAOUT( (0 << 16) | (dPriv->h-1) );
DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride );
DMAOUT(vmesa->SrcStride);
DMAOUT(vmesa->TexOffset);
DMAOUT(vmesa->TextureBorderColor);
DMAOUT(0); /* FOG */
DMAOUT(0);
DMAOUT(0);
DMAOUT(cmd);
/* 0xacc16827: good value -> lightened newave!!! */
DMAFINISH();

vmesa->CMD = cmd;
#endif
}

DEBUG(("\n"));

vmesa->restore_primitive = _hw_prim;
}

static void s3vRunPipeline( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);

DEBUG(("*** s3vRunPipeline ***\n"));

if ( vmesa->new_state )
s3vDDUpdateHWState( ctx );

if (vmesa->new_gl_state) {

if (vmesa->new_gl_state & _NEW_TEXTURE) {
s3vUpdateTextureState( ctx );
}

if (!vmesa->Fallback) {
if (vmesa->new_gl_state & _S3V_NEW_VERTEX)
s3vChooseVertexState( ctx );
if (vmesa->new_gl_state & _S3V_NEW_RASTER_STATE)
s3vChooseRasterState( ctx );
if (vmesa->new_gl_state & _S3V_NEW_RENDERSTATE)
s3vChooseRenderState( ctx );
}

vmesa->new_gl_state = 0;
}

_tnl_run_pipeline( ctx );
}

static void s3vRenderStart( GLcontext *ctx )
{
/* Check for projective texturing. Make sure all texcoord
* pointers point to something. (fix in mesa?)
*/

DEBUG(("s3vRenderStart\n"));
/* s3vCheckTexSizes( ctx ); */
}

static void s3vRenderFinish( GLcontext *ctx )
{
if (0)
_swrast_flush( ctx ); /* never needed */
}

static void s3vResetLineStipple( GLcontext *ctx )
{
/* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */

/* Reset the hardware stipple counter.
*/
/*
CHECK_DMA_BUFFER(vmesa, 1);
WRITE(vmesa->buf, UpdateLineStippleCounters, 0);
*/
}


/**********************************************************************/
/* Transition to/from hardware rasterization. */
/**********************************************************************/


void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode )
{
GLcontext *ctx = vmesa->glCtx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = vmesa->Fallback;

DEBUG(("*** s3vFallback: "));

if (mode) {
vmesa->Fallback |= bit;
if (oldfallback == 0) {
DEBUG(("oldfallback == 0 ***\n"));
_swsetup_Wakeup( ctx );
_tnl_need_projected_coords( ctx, GL_TRUE );
vmesa->RenderIndex = ~0;
}
}
else {
DEBUG(("***\n"));
vmesa->Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
tnl->Driver.Render.Start = s3vRenderStart;
tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
tnl->Driver.Render.Finish = s3vRenderFinish;
tnl->Driver.Render.BuildVertices = s3vBuildVertices;
tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
vmesa->new_gl_state |= (_S3V_NEW_RENDERSTATE|
_S3V_NEW_RASTER_STATE|
_S3V_NEW_VERTEX);
}
}
}


/**********************************************************************/
/* Initialization. */
/**********************************************************************/


void s3vInitTriFuncs( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
static int firsttime = 1;

if (firsttime) {
init_rast_tab();
init_render_tab();
firsttime = 0;
}
vmesa->RenderIndex = ~0;

tnl->Driver.RunPipeline = s3vRunPipeline;
tnl->Driver.Render.Start = s3vRenderStart;
tnl->Driver.Render.Finish = s3vRenderFinish;
tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
/*
tnl->Driver.RenderInterp = _swsetup_RenderInterp;
tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
*/
tnl->Driver.Render.BuildVertices = s3vBuildVertices;
}

+ 11
- 0
src/mesa/drivers/dri/s3v/s3v_tris.h View File

@@ -0,0 +1,11 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef _S3V_TRIS_H
#define _S3V_TRIS_H

extern void s3vDDTrifuncInit(void);
extern void s3vDDChooseTriRenderState(GLcontext *);

#endif /* !(_S3V_TRIS_H) */

+ 899
- 0
src/mesa/drivers/dri/s3v/s3v_tritmp.h View File

@@ -0,0 +1,899 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

/**** MACROS start ****/

/* point/line macros */

#define LINE_VERT_VARS \
SWvertex v[3]; \
s3vVertex* vvv[2]; \
int x[3], y[3], z[3]; \
int idx[3]; \
int dx01, dy01; \
int delt02; \
int deltzy, zstart; \
int start02, end01; \
int ystart, y01y12; \
int i, tmp, tmp2, tmp3; \
GLfloat ydiff, fy[3]

#define LINE_FLAT_VARS \
int arstart, gbstart; \
int deltarx, deltgbx, deltary, deltgby; \
GLubyte *(col)[3]

#define LINE_GOURAUD_VARS \
int arstart, gbstart; \
int deltary, deltgby; \
int ctmp, ctmp2, ctmp3, ctmp4; \
GLubyte *(col)[3]

#define SORT_LINE_VERT() \
do { \
if(v[0].win[1] <= v[1].win[1]) { \
\
idx[0] = 0; \
idx[1] = 1; \
\
} else if (v[0].win[1] > v[1].win[1]) { \
\
idx[0] = 1; \
idx[1] = 0; \
\
} \
} while(0)

#define SET_LINE_VERT() \
do { \
x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \
z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \
\
x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
y[1] = dPriv->h - v[idx[1]].win[1]; \
z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \
} while(0)

#define SET_LINE_XY() \
do { \
tmp = v[idx[0]].win[0]; \
tmp2 = v[idx[1]].win[0]; \
\
dx01 = x[0] - x[1]; \
dy01 = y[0] - y[1]; \
\
ydiff = fy[0] - (float)y[0]; \
ystart = y[0]; \
y01y12 = dy01 + 1; \
} while (0)

#define SET_LINE_DIR() \
do { \
if (tmp2 > tmp) { \
y01y12 |= 0x80000000; \
tmp3 = tmp2-tmp; \
} else { \
tmp3 = tmp-tmp2; \
} \
\
end01 = ((tmp << 16) | tmp2); \
\
if (dy01) \
delt02 = -(dx01/dy01); \
else \
delt02 = 0; \
\
if (dy01 > tmp3) { /* Y MAJ */ \
/* NOTE: tmp3 always >=0 */ \
start02 = x[0]; \
} else if (delt02 >= 0){ /* X MAJ - positive delta */ \
start02 = x[0] + delt02/2; \
dy01 = tmp3; /* could be 0 */ \
} else { /* X MAJ - negative delta */ \
start02 = x[0] + delt02/2 + ((1 << 20) - 1); \
dy01 = tmp3; /* could be 0 */ \
} \
} while(0)

#define SET_LINE_Z() \
do { \
zstart = z[0]; \
\
if (dy01) { \
deltzy = (z[1] - z[0])/dy01; \
} else { \
deltzy = 0; /* dy01 = tmp3 = 0 (it's a point)*/ \
} \
} while (0)

#define SET_LINE_FLAT_COL() \
do { \
col[0] = &(v[idx[0]].color[0]); \
deltarx = deltary = deltgbx = deltgby = 0; \
gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
} while(0)

#define SET_LINE_GOURAUD_COL() \
do { \
col[0] = &(v[idx[0]].color[0]); \
col[1] = &(v[idx[1]].color[0]); \
\
vvv[0] = _v0; \
vvv[1] = _v1; \
\
for (i=0; i<2; i++) { \
/* FIXME: swapped ! */ \
col[i][0] = vvv[!idx[i]]->v.color.red; \
col[i][1] = vvv[!idx[i]]->v.color.green; \
col[i][2] = vvv[!idx[i]]->v.color.blue; \
col[i][3] = vvv[!idx[i]]->v.color.alpha; \
} \
\
if (dy01) { \
\
ctmp = ((col[0][1] - col[1][1]) << 7) / dy01; \
ctmp2 = ((col[0][2] - col[1][2]) << 7) / dy01; \
deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
\
ctmp3 = ((col[0][3] - col[1][3]) << 7) / dy01; \
ctmp4 = ((col[0][0] - col[1][0]) << 7) / dy01; \
deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
} else { \
ctmp = ((col[1][1] - col[0][1]) << 7); \
ctmp2 = ((col[1][2] - col[0][2]) << 7); \
deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
\
ctmp3 = ((col[1][3] - col[0][3]) << 7); \
ctmp4 = ((col[1][0] - col[0][0]) << 7); \
deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
deltgby = deltary = 0; \
} \
\
idx[0] = 1; /* FIXME: swapped */ \
\
gbstart = \
(((int)((ydiff * ctmp) + (col[idx[0]][1] << 7)) << 16) & 0x7FFF0000) \
| ((int)((ydiff * ctmp2) + (col[idx[0]][2] << 7)) & 0x7FFF); \
arstart = \
(((int)((ydiff * ctmp3) + (col[idx[0]][3] << 7)) << 16) & 0x7FFF0000) \
| ((int)((ydiff * ctmp4) + (col[idx[0]][0] << 7)) & 0x7FFF); \
} while(0)

#define SEND_LINE_COL() \
do { \
DMAOUT(deltgby); \
DMAOUT(deltary); \
DMAOUT(gbstart); \
DMAOUT(arstart); \
} while (0)

#define SEND_LINE_VERT() \
do { \
DMAOUT(deltzy); \
DMAOUT(zstart); \
DMAOUT(0); \
DMAOUT(0); \
DMAOUT(0); \
DMAOUT(end01); \
DMAOUT(delt02); \
DMAOUT(start02); \
DMAOUT(ystart); \
DMAOUT(y01y12); \
} while (0)


/* tri macros (mostly stolen from utah-glx...) */

#define VERT_VARS \
SWvertex v[3]; \
int x[3], y[3], z[3]; \
int idx[3]; \
int dx01, dy01; \
int dx02, dy02; \
int dx12, dy12; \
int delt01, delt02, delt12; \
int deltzx, deltzy, zstart; \
int start02, end01, end12; \
int ystart, y01y12; \
int i, tmp, lr; \
GLfloat ydiff, fy[3]

#define GOURAUD_VARS \
int arstart, gbstart; \
int deltarx, deltgbx, deltary, deltgby; \
int ctmp, ctmp2, ctmp3, ctmp4; \
GLubyte *(col)[3]

#define FLAT_VARS \
int arstart, gbstart; \
int deltarx, deltgbx, deltary, deltgby; \
GLubyte *(col)[3]

#define TEX_VARS \
int u0, u1, u2; \
GLfloat ru0, ru1, ru2; \
int v0, v1, v2; \
GLfloat rv0, rv1, rv2; \
GLfloat w0, w1, w2; \
GLfloat rw0, rw1, rw2; \
int baseu, basev; \
int d0, d1, d2; \
int deltdx, deltvx, deltux, deltdy, deltvy, deltuy; \
int deltwx, deltwy; \
int rbaseu, rbasev; \
int dstart, ustart, wstart, vstart; \
static int stmp = 0; \
s3vTextureObjectPtr t

#define SORT_VERT() \
do { \
for (i=0; i<3; i++) \
fy[i] = v[i].win[1]; \
\
if (fy[1] > fy[0]) { /* (fy[1] > fy[0]) */ \
\
if (fy[2] > fy[0]) { \
idx[0] = 0; \
if (fy[1] > fy[2]) { \
idx[1] = 2; \
idx[2] = 1; \
} else { \
idx[1] = 1; \
idx[2] = 2; \
} \
} else { \
idx[0] = 2; \
idx[1] = 0; \
idx[2] = 1; \
} \
} else { /* (fy[1] < y[0]) */ \
if (fy[2] > fy[0]) { \
idx[0] = 1; \
idx[1] = 0; \
idx[2] = 2; \
} else { \
idx[2] = 0; \
if (fy[2] > fy[1]) { \
idx[0] = 1; \
idx[1] = 2; \
} else { \
idx[0] = 2; \
idx[1] = 1; \
} \
} \
} \
} while(0)

#define SET_VERT() \
do { \
for (i=0; i<3; i++) \
{ \
x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/ 1024.0 * 1024.0); \
y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \
z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \
} \
\
ydiff = fy[0] - (float)y[0]; \
\
ystart = y[0]; \
\
dx12 = x[2] - x[1]; \
dy12 = y[1] - y[2]; \
dx01 = x[1] - x[0]; \
dy01 = y[0] - y[1]; \
dx02 = x[2] - x[0]; \
dy02 = y[0] - y[2]; \
\
delt01 = delt02 = delt12 = 0; \
} while (0)


#define SET_XY() \
do { \
if (dy01) delt01 = dx01 / dy01; \
if (dy12) delt12 = dx12 / dy12; \
delt02 = dx02 / dy02; \
\
start02 = x[0] + (ydiff * delt02); \
end01 = x[0] + (ydiff * delt01); \
end12 = x[1] + ((fy[1] - (GLfloat)y[1]) * delt12); \
} while (0)

#define SET_DIR() \
do { \
tmp = x[1] - (dy01 * delt02 + x[0]); \
if (tmp > 0) { \
lr = 0x80000000; \
} else { \
tmp *= -1; \
lr = 0; \
} \
tmp >>= 20; \
\
y01y12 = ((((y[0] - y[1]) & 0x7FF) << 16) \
| ((y[1] - y[2]) & 0x7FF) | lr); \
} while (0)

#define SET_Z() \
do { \
deltzy = (z[2] - z[0]) / dy02; \
if (tmp) { \
deltzx = (z[1] - (dy01 * deltzy + z[0])) / tmp; \
} else { \
deltzx = 0; \
} \
zstart = (deltzy * ydiff) + z[0]; \
} while (0)

#define SET_FLAT_COL() \
do { \
col[0] = &(v[0].color[0]); \
deltarx = deltary = deltgbx = deltgby = 0; \
gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
} while(0)

#define SET_GOURAUD_COL() \
do { \
col[0] = &(v[idx[0]].color[0]); \
col[1] = &(v[idx[1]].color[0]); \
col[2] = &(v[idx[2]].color[0]); \
\
ctmp = ((col[2][3] - col[0][3]) << 7) / dy02; \
ctmp2 = ((col[2][0] - col[0][0]) << 7) / dy02; \
deltary = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
ctmp3 = ((col[2][1] - col[0][1]) << 7) / dy02; \
ctmp4 = ((col[2][2] - col[0][2]) << 7) / dy02; \
deltgby = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
gbstart = \
(((int)((ydiff * ctmp3) + (col[0][1] << 7)) << 16) & 0x7FFF0000) \
| ((int)((ydiff * ctmp4) + (col[0][2] << 7)) & 0x7FFF); \
arstart = \
(((int)((ydiff * ctmp) + (col[0][3] << 7)) << 16) & 0x7FFF0000) \
| ((int)((ydiff * ctmp2) + (col[0][0] << 7)) & 0x7FFF); \
if (tmp) { \
int ax, rx, gx, bx; \
ax = ((col[1][3] << 7) - (dy01 * ctmp + (col[0][3] << 7))) / tmp; \
rx = ((col[1][0] << 7) - (dy01 * ctmp2 + (col[0][0] << 7))) / tmp; \
gx = ((col[1][1] << 7) - (dy01 * ctmp3 + (col[0][1] << 7))) / tmp; \
bx = ((col[1][2] << 7) - (dy01 * ctmp4 + (col[0][2] << 7))) / tmp; \
deltarx = ((ax << 16) & 0xFFFF0000) | (rx & 0xFFFF); \
deltgbx = ((gx << 16) & 0xFFFF0000) | (bx & 0xFFFF); \
} else { \
deltgbx = deltarx = 0; \
} \
} while (0)

#define SET_TEX_VERT() \
do { \
t = ((s3vTextureObjectPtr) \
ctx->Texture.Unit[0]._Current->DriverData); \
deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
\
u0 = (v[idx[0]].texcoord[0][0] \
* (GLfloat)(t->image[0].image->Width) * 256.0); \
u1 = (v[idx[1]].texcoord[0][0] \
* (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
u2 = (v[idx[2]].texcoord[0][0] \
* (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
v0 = (v[idx[0]].texcoord[0][1] \
* (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
v1 = (v[idx[1]].texcoord[0][1] \
* (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
v2 = (v[idx[2]].texcoord[0][1] \
* (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
\
w0 = (v[idx[0]].win[3]); \
w1 = (v[idx[1]].win[3]); \
w2 = (v[idx[2]].win[3]); \
} while (0)

#define SET_BASEUV() \
do { \
if (u0 < u1) { \
if (u0 < u2) { \
baseu = u0; \
} else { \
baseu = u2; \
} \
} else { \
if (u1 < u2) { \
baseu = u1; \
} else { \
baseu = u2; \
} \
} \
\
if (v0 < v1) { \
if (v0 < v2) { \
basev = v0; \
} else { \
basev = v2; \
} \
} else { \
if (v1 < v2) { \
basev = v1; \
} else { \
basev = v2; \
} \
} \
} while (0)


#define SET_RW() \
do { \
/* GLfloat minW; \
\
if (w0 < w1) { \
if (w0 < w2) { \
minW = w0; \
} else { \
minW = w2; \
} \
} else { \
if (w1 < w2) { \
minW = w1; \
} else { \
minW = w2; \
} \
} */ \
\
rw0 = (512.0 * w0); \
rw1 = (512.0 * w1); \
rw2 = (512.0 * w2); \
} while (0)

#define SET_D() \
do { \
GLfloat sxy, suv; \
int lev; \
\
suv = (v[idx[0]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[1]].texcoord[0][1] - \
v[idx[2]].texcoord[0][1]) - \
(v[idx[1]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[0]].texcoord[0][1] - \
v[idx[2]].texcoord[0][2]); \
\
sxy = (v[idx[0]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[1]].texcoord[0][1] - \
v[idx[2]].texcoord[0][1]) - \
(v[idx[1]].texcoord[0][0] - \
v[idx[2]].texcoord[0][0]) * \
(v[idx[0]].texcoord[0][1] - \
v[idx[2]].texcoord[0][2]); \
\
if (sxy < 0) sxy *= -1.0; \
if (suv < 0) suv *= -1.0; \
\
lev = *(int*)&suv - *(int *)&sxy; \
if (lev < 0) \
lev = 0; \
else \
lev >>=23; \
dstart = (lev << 27); \
} while (0)

#define SET_UVWD() \
do { \
SET_BASEUV(); \
SET_RW(); \
SET_D(); \
ru0 = (((u0 - baseu) * rw0)); \
ru1 = (((u1 - baseu) * rw1)); \
ru2 = (((u2 - baseu) * rw2)); \
rv0 = (((v0 - basev) * rw0)); \
rv1 = (((v1 - basev) * rw1)); \
rv2 = (((v2 - basev) * rw2)); \
\
while (baseu < 0) { baseu += (t->globj->Image[0]->Width << 8); } \
while (basev < 0) { basev += (t->globj->Image[0]->Height << 8); } \
\
if (!(baseu & 0xFF)) \
{ baseu = (baseu >> 8); } \
else \
{ baseu = (baseu >> 8) + 1; } \
\
if ((basev & 0x80) || !(basev & 0xFF)) \
{ basev = (basev >> 8); } \
else \
{ basev = (basev >> 8) - 1; } \
\
rbaseu = (baseu) << (16 - t->globj->Image[0]->WidthLog2); \
rbasev = (basev) << (16 - t->globj->Image[0]->WidthLog2); \
deltuy = (((ru2 - ru0) / dy02)); \
deltvy = (((rv2 - rv0) / dy02)); \
rw0 *= (1024.0 * 512.0); \
rw1 *= (1024.0 * 512.0); \
rw2 *= (1024.0 * 512.0); \
deltwy = ((rw2 - rw0) / dy02); \
if (tmp) { \
deltux = ((ru1 - (dy01 * deltuy + ru0)) / tmp); \
deltvx = ((rv1 - (dy01 * deltvy + rv0)) / tmp); \
deltwx = ((rw1 - (dy01 * deltwy + rw0)) / tmp); \
} else { deltux = deltvx = deltwx = 0; } \
ustart = (deltuy * ydiff) + (ru0); \
vstart = (deltvy * ydiff) + (rv0); \
wstart = (deltwy * ydiff) + (rw0); \
} while (0)

#define SEND_UVWD() \
do { \
DMAOUT((rbasev & 0xFFFF)); \
DMAOUT((0xa0000000 | (rbaseu & 0xFFFF))); \
DMAOUT(deltwx); \
DMAOUT(deltwy); \
DMAOUT(wstart); \
DMAOUT(deltdx); \
DMAOUT(deltvx); \
DMAOUT(deltux); \
DMAOUT(deltdy); \
DMAOUT(deltvy); \
DMAOUT(deltuy); \
DMAOUT(dstart); \
DMAOUT(vstart); \
DMAOUT(ustart); \
} while (0)

#define SEND_VERT() \
do { \
DMAOUT(deltzx); \
DMAOUT(deltzy); \
DMAOUT(zstart); \
DMAOUT(delt12); \
DMAOUT(end12); \
DMAOUT(delt01); \
DMAOUT(end01); \
DMAOUT(delt02); \
DMAOUT(start02); \
DMAOUT(ystart); \
DMAOUT(y01y12); \
} while (0)

#define SEND_COL() \
do { \
DMAOUT(deltgbx); \
DMAOUT(deltarx); \
DMAOUT(deltgby); \
DMAOUT(deltary); \
DMAOUT(gbstart); \
DMAOUT(arstart); \
} while (0)

/**** MACROS end ****/




static void TAG(s3v_point)( s3vContextPtr vmesa,
const s3vVertex *_v0 )
{
}

static void TAG(s3v_line)( s3vContextPtr vmesa,
const s3vVertex *_v0,
const s3vVertex *_v1 )
{
GLcontext *ctx = vmesa->glCtx;
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;

LINE_VERT_VARS;
#if (IND & S3V_RAST_FLAT_BIT)
LINE_FLAT_VARS;
#else
LINE_GOURAUD_VARS;
#endif
#if (IND & S3V_RAST_CULL_BIT)
GLfloat cull;
#endif

DEBUG(("*** s3v_line: "));
#if (IND & S3V_RAST_CULL_BIT)
DEBUG(("cull "));
#endif
#if (IND & S3V_RAST_FLAT_BIT)
DEBUG(("flat "));
#endif

DEBUG(("***\n"));

#if 0
s3v_print_vertex(ctx, _v0);
s3v_print_vertex(ctx, _v1);
#endif

s3v_translate_vertex( ctx, _v0, &v[0] );
s3v_translate_vertex( ctx, _v1, &v[1] );

#if (IND & S3V_RAST_CULL_BIT)
/* FIXME: should we cull lines too? */
#endif
(void)v; /* v[0]; v[1]; */

SORT_LINE_VERT();
SET_LINE_VERT();

SET_LINE_XY();
SET_LINE_DIR();
SET_LINE_Z();

#if (IND & S3V_RAST_FLAT_BIT)
SET_LINE_FLAT_COL();
#else
SET_LINE_GOURAUD_COL();
#endif

DMAOUT_CHECK(3DLINE_GBD, 15);
SEND_LINE_COL();
DMAOUT(0);
SEND_LINE_VERT();
DMAFINISH();
}

static void TAG(s3v_triangle)( s3vContextPtr vmesa,
const s3vVertex *_v0,
const s3vVertex *_v1,
const s3vVertex *_v2 )
{
GLcontext *ctx = vmesa->glCtx;
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;

VERT_VARS;
#if (IND & S3v_RAST_FLAT_BIT)
FLAT_VARS;
#else
GOURAUD_VARS;
#endif
#if (IND & S3V_RAST_TEX_BIT)
TEX_VARS;
#endif
#if (IND & S3V_RAST_CULL_BIT)
GLfloat cull;
#endif

DEBUG(("*** s3v_triangle: "));
#if (IND & S3V_RAST_CULL_BIT)
DEBUG(("cull "));
#endif
#if (IND & S3V_RAST_FLAT_BIT)
DEBUG(("flat "));
#endif
#if (IND & S3V_RAST_TEX_BIT)
DEBUG(("tex "));
#endif

DEBUG(("***\n"));

#if 0
s3v_print_vertex(ctx, _v0);
s3v_print_vertex(ctx, _v1);
s3v_print_vertex(ctx, _v2);
#endif

s3v_translate_vertex( ctx, _v0, &v[0] );
s3v_translate_vertex( ctx, _v1, &v[1] );
s3v_translate_vertex( ctx, _v2, &v[2] );

#if (IND & S3V_RAST_CULL_BIT)
cull = vmesa->backface_sign *
((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
(v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));

if (cull < vmesa->cull_zero /* -0.02f */) return;
#endif

(void)v; /* v[0]; v[1]; v[2]; */

SORT_VERT();
SET_VERT();

if (dy02 == 0) return;

SET_XY();
SET_DIR();
SET_Z();
#if (IND & S3V_RAST_TEX_BIT)
SET_TEX_VERT();
SET_UVWD();
#endif

#if (IND & S3V_RAST_FLAT_BIT)
SET_FLAT_COL();
#else
SET_GOURAUD_COL();
#endif

#if (IND & S3V_RAST_TEX_BIT)
DMAOUT_CHECK(3DTRI_BASEV, 31);
SEND_UVWD();
SEND_COL();
SEND_VERT();
DMAFINISH();
#else
DMAOUT_CHECK(3DTRI_GBX, 17);
SEND_COL();
SEND_VERT();
DMAFINISH();
#endif
}

static void TAG(s3v_quad)( s3vContextPtr vmesa,
const s3vVertex *_v0,
const s3vVertex *_v1,
const s3vVertex *_v2,
const s3vVertex *_v3 )
{
GLcontext *ctx = vmesa->glCtx;
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;

SWvertex temp_v[4];
VERT_VARS;
#if (IND & S3v_RAST_FLAT_BIT)
FLAT_VARS;
#else
GOURAUD_VARS;
#endif
#if (IND & S3V_RAST_TEX_BIT)
TEX_VARS;
#endif
#if (IND & S3V_RAST_CULL_BIT)
GLfloat cull;
#endif

DEBUG(("*** s3v_quad: "));
#if (IND & S3V_RAST_CULL_BIT)
DEBUG(("cull "));
/* printf(""); */ /* speed trick */
#endif
#if (IND & S3V_RAST_FLAT_BIT)
DEBUG(("flat "));
#endif
#if (IND & S3V_RAST_TEX_BIT)
DEBUG(("tex "));
#endif

DEBUG(("***\n"));

#if 0
s3v_print_vertex(ctx, _v0);
s3v_print_vertex(ctx, _v1);
s3v_print_vertex(ctx, _v2);
s3v_print_vertex(ctx, _v3);
#endif
s3v_translate_vertex( ctx, _v0, &temp_v[0] );
s3v_translate_vertex( ctx, _v1, &temp_v[1] );
s3v_translate_vertex( ctx, _v2, &temp_v[2] );
s3v_translate_vertex( ctx, _v3, &temp_v[3] );

/* FIRST TRI (0,1,2) */

/* ROMEO */
/* printf(""); */ /* speed trick (a) [turn on if (a) is return]*/

v[0] = temp_v[0];
v[1] = temp_v[1];
v[2] = temp_v[2];

#if (IND & S3V_RAST_CULL_BIT)
cull = vmesa->backface_sign *
((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
(v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));

if (cull < vmesa->cull_zero /* -0.02f */) goto second; /* return; */ /* (a) */
#endif
#if 0
v[0] = temp_v[0];
v[1] = temp_v[1];
v[2] = temp_v[2];
#else
(void) v;
#endif
SORT_VERT();
SET_VERT();

if (dy02 == 0) goto second;

SET_XY();
SET_DIR();
SET_Z();

#if (IND & S3V_RAST_TEX_BIT)
SET_TEX_VERT();
SET_UVWD();
#endif

#if (IND & S3V_RAST_FLAT_BIT)
SET_FLAT_COL();
#else
SET_GOURAUD_COL();
#endif

#if (IND & S3V_RAST_TEX_BIT)
DMAOUT_CHECK(3DTRI_BASEV, 31);
SEND_UVWD();
SEND_COL();
SEND_VERT();
DMAFINISH();
#else
DMAOUT_CHECK(3DTRI_GBX, 17);
SEND_COL();
SEND_VERT();
DMAFINISH();
#endif

/* SECOND TRI (0,2,3) */

second:
v[0] = temp_v[0];
v[1] = temp_v[2];
v[2] = temp_v[3];

#if (IND & S3V_RAST_CULL_BIT)
cull = vmesa->backface_sign *
((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
(v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
if (cull < /* -0.02f */ vmesa->cull_zero) return;
#endif

/* second: */

/* ROMEO */
/* printf(""); */ /* speed trick */

v[0] = temp_v[0];
v[1] = temp_v[2];
v[2] = temp_v[3];

SORT_VERT();
SET_VERT();

if (dy02 == 0) return;

SET_XY();
SET_DIR();
SET_Z();

#if (IND & S3V_RAST_TEX_BIT)
SET_TEX_VERT();
SET_UVWD();
#endif

#if (IND & S3V_RAST_FLAT_BIT)
SET_FLAT_COL();
#else
SET_GOURAUD_COL();
#endif

#if (IND & S3V_RAST_TEX_BIT)
DMAOUT_CHECK(3DTRI_BASEV, 31);
SEND_UVWD();
SEND_COL();
SEND_VERT();
DMAFINISH();
#else
DMAOUT_CHECK(3DTRI_GBX, 17);
SEND_COL();
SEND_VERT();
DMAFINISH();
#endif
}

static void TAG(s3v_init)(void)
{
s3v_point_tab[IND] = TAG(s3v_point);
s3v_line_tab[IND] = TAG(s3v_line);
s3v_tri_tab[IND] = TAG(s3v_triangle);
s3v_quad_tab[IND] = TAG(s3v_quad);
}

#undef IND
#undef TAG

+ 341
- 0
src/mesa/drivers/dri/s3v/s3v_vb.c View File

@@ -0,0 +1,341 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#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 "tnl/t_context.h"
#include "tnl/tnl.h"

#include "s3v_context.h"
#include "s3v_vb.h"
#include "s3v_tris.h"

#define S3V_XYZW_BIT 0x1
#define S3V_RGBA_BIT 0x2
#define S3V_TEX0_BIT 0x4
#define S3V_PTEX_BIT 0x8
#define S3V_FOG_BIT 0x10
#define S3V_MAX_SETUP 0x20

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[S3V_MAX_SETUP];


/* Only one vertex format, atm, so no need to give them names:
*/
#define TINY_VERTEX_FORMAT 1
#define NOTEX_VERTEX_FORMAT 0
#define TEX0_VERTEX_FORMAT 0
#define TEX1_VERTEX_FORMAT 0
#define PROJ_TEX1_VERTEX_FORMAT 0
#define TEX2_VERTEX_FORMAT 0
#define TEX3_VERTEX_FORMAT 0
#define PROJ_TEX3_VERTEX_FORMAT 0

#define DO_XYZW (IND & S3V_XYZW_BIT)
#define DO_RGBA (IND & S3V_RGBA_BIT)
#define DO_SPEC 0
#define DO_FOG (IND & S3V_FOG_BIT)
#define DO_TEX0 (IND & S3V_TEX0_BIT)
#define DO_TEX1 0
#define DO_TEX2 0
#define DO_TEX3 0
#define DO_PTEX (IND & S3V_PTEX_BIT)
#define VERTEX s3vVertex
#define LOCALVARS /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
#define GET_VIEWPORT_MAT() 0 /* vmesa->hw_viewport */
#define GET_TEXSOURCE(n) n
#define GET_VERTEX_FORMAT() 0
#define GET_VERTEX_STORE() S3V_CONTEXT(ctx)->verts
#define GET_VERTEX_STRIDE_SHIFT() S3V_CONTEXT(ctx)->vertex_stride_shift
#define INVALIDATE_STORED_VERTICES()
#define GET_UBYTE_COLOR_STORE() &S3V_CONTEXT(ctx)->UbyteColor
#define GET_UBYTE_SPEC_COLOR_STORE() &S3V_CONTEXT(ctx)->UbyteSecondaryColor

#define HAVE_HW_VIEWPORT 1 /* FIXME */
#define HAVE_HW_DIVIDE 1
#define HAVE_RGBA_COLOR 0 /* we're BGRA */
#define HAVE_TINY_VERTICES 1
#define HAVE_NOTEX_VERTICES 1
#define HAVE_TEX0_VERTICES 1
#define HAVE_TEX1_VERTICES 0
#define HAVE_TEX2_VERTICES 0
#define HAVE_TEX3_VERTICES 0
#define HAVE_PTEX_VERTICES 1

/*
#define SUBPIXEL_X -.5
#define SUBPIXEL_Y -.5
#define UNVIEWPORT_VARS GLfloat h = S3V_CONTEXT(ctx)->driDrawable->h
#define UNVIEWPORT_X(x) x - SUBPIXEL_X
#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
#define UNVIEWPORT_Z(z) z / vmesa->depth_scale
*/

#define PTEX_FALLBACK() /* never needed */

#define IMPORT_QUALIFIER
#define IMPORT_FLOAT_COLORS s3v_import_float_colors
#define IMPORT_FLOAT_SPEC_COLORS s3v_import_float_spec_colors

#define INTERP_VERTEX setup_tab[S3V_CONTEXT(ctx)->SetupIndex].interp
#define COPY_PV_VERTEX setup_tab[S3V_CONTEXT(ctx)->SetupIndex].copy_pv



/***********************************************************************
* Generate pv-copying and translation functions *
***********************************************************************/

#define TAG(x) s3v_##x
#include "tnl_dd/t_dd_vb.c"

/***********************************************************************
* Generate vertex emit and interp functions *
***********************************************************************/


#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT)
#define TAG(x) x##_wg
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_TEX0_BIT)
#define TAG(x) x##_wgt0
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_TEX0_BIT|S3V_PTEX_BIT)
#define TAG(x) x##_wgpt0
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_TEX0_BIT)
#define TAG(x) x##_t0
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_RGBA_BIT)
#define TAG(x) x##_g
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_RGBA_BIT|S3V_TEX0_BIT)
#define TAG(x) x##_gt0
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT)
#define TAG(x) x##_wgf
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT|S3V_TEX0_BIT)
#define TAG(x) x##_wgft0
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_XYZW_BIT|S3V_RGBA_BIT|S3V_FOG_BIT|S3V_TEX0_BIT|S3V_PTEX_BIT)
#define TAG(x) x##_wgfpt0
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_FOG_BIT)
#define TAG(x) x##_f
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_RGBA_BIT | S3V_FOG_BIT)
#define TAG(x) x##_gf
#include "tnl_dd/t_dd_vbtmp.h"

#define IND (S3V_RGBA_BIT | S3V_FOG_BIT | S3V_TEX0_BIT)
#define TAG(x) x##_gft0
#include "tnl_dd/t_dd_vbtmp.h"

static void init_setup_tab( void )
{
init_wg(); /* pos + col */
init_wgt0(); /* pos + col + tex0 */
init_wgpt0(); /* pos + col + p-tex0 (?) */
init_t0(); /* tex0 */
init_g(); /* col */
init_gt0(); /* col + tex */
init_wgf();
init_wgft0();
init_wgfpt0();
init_f();
init_gf();
init_gft0();
}


#if 0
void s3vPrintSetupFlags(char *msg, GLuint flags )
{
fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
msg,
(int)flags,
(flags & S3V_XYZW_BIT) ? " xyzw," : "",
(flags & S3V_RGBA_BIT) ? " rgba," : "",
(flags & S3V_SPEC_BIT) ? " spec," : "",
(flags & S3V_FOG_BIT) ? " fog," : "",
(flags & S3V_TEX0_BIT) ? " tex-0," : "",
(flags & S3V_TEX1_BIT) ? " tex-1," : "");
}
#endif


void s3vCheckTexSizes( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
s3vContextPtr vmesa = S3V_CONTEXT( ctx );

if (!setup_tab[vmesa->SetupIndex].check_tex_sizes(ctx)) {

vmesa->SetupIndex |= (S3V_PTEX_BIT|S3V_RGBA_BIT);

if (1 || !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
tnl->Driver.Render.Interp = setup_tab[vmesa->SetupIndex].interp;
tnl->Driver.Render.CopyPV = setup_tab[vmesa->SetupIndex].copy_pv;
}
}
}

void s3vBuildVertices( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint newinputs )
{
s3vContextPtr vmesa = S3V_CONTEXT( ctx );
GLubyte *v = ((GLubyte *)vmesa->verts +
(start<<vmesa->vertex_stride_shift));
GLuint stride = 1<<vmesa->vertex_stride_shift;
GLuint ind = 0;

DEBUG(("*** s3vBuildVertices ***\n"));
DEBUG(("vmesa->SetupNewInputs = 0x%x\n", vmesa->SetupNewInputs));
DEBUG(("vmesa->SetupIndex = 0x%x\n", vmesa->SetupIndex));

#if 1
setup_tab[vmesa->SetupIndex].emit( ctx, start, count, v, stride );
#else
newinputs |= vmesa->SetupNewInputs;
vmesa->SetupNewInputs = 0;

DEBUG(("newinputs is 0x%x\n", newinputs));

if (!newinputs) {
DEBUG(("!newinputs\n"));
return;
}

if (newinputs & VERT_CLIP) {
setup_tab[vmesa->SetupIndex].emit( ctx, start, count, v, stride );
DEBUG(("newinputs & VERT_CLIP\n"));
return;
} /* else { */
/* GLuint ind = 0; */

if (newinputs & VERT_RGBA) {
DEBUG(("newinputs & VERT_RGBA\n"));
ind |= S3V_RGBA_BIT;
}
if (newinputs & VERT_TEX0) {
DEBUG(("newinputs & VERT_TEX0\n"));
ind |= S3V_TEX0_BIT;
}

if (newinputs & VERT_FOG_COORD)
ind |= S3V_FOG_BIT;

if (vmesa->SetupIndex & S3V_PTEX_BIT)
ind = ~0;

ind &= vmesa->SetupIndex;

DEBUG(("vmesa->SetupIndex = 0x%x\n", vmesa->SetupIndex));
DEBUG(("ind = 0x%x\n", ind));
DEBUG(("ind & vmesa->SetupIndex = 0x%x\n", (ind & vmesa->SetupIndex)));

if (ind) {
setup_tab[ind].emit( ctx, start, count, v, stride );
}
#endif
}

void s3vChooseVertexState( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);

GLuint ind = S3V_XYZW_BIT | S3V_RGBA_BIT;

/* FIXME: will segv in tnl_dd/t_dd_vbtmp.h (line 196) on some demos */
/*
if (ctx->Fog.Enabled)
ind |= S3V_FOG_BIT;
*/


if (ctx->Texture._ReallyEnabled) {
_tnl_need_projected_coords( ctx, GL_FALSE );
ind |= S3V_TEX0_BIT;
} else {
_tnl_need_projected_coords( ctx, GL_TRUE );
}

vmesa->SetupIndex = ind;

if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
tnl->Driver.Render.Interp = s3v_interp_extras;
tnl->Driver.Render.CopyPV = s3v_copy_pv_extras;
} else {
tnl->Driver.Render.Interp = setup_tab[ind].interp;
tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
}
}


void s3vInitVB( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
GLuint size = TNL_CONTEXT(ctx)->vb.Size;

vmesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32);

{
static int firsttime = 1;
if (firsttime) {
init_setup_tab();
firsttime = 0;
vmesa->vertex_stride_shift = 6 /* 4 */; /* FIXME - only one vertex setup */
}
}
}


void s3vFreeVB( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
if (vmesa->verts) {
ALIGN_FREE(vmesa->verts);
vmesa->verts = 0;
}

if (vmesa->UbyteSecondaryColor.Ptr) {
ALIGN_FREE(vmesa->UbyteSecondaryColor.Ptr);
vmesa->UbyteSecondaryColor.Ptr = 0;
}

if (vmesa->UbyteColor.Ptr) {
ALIGN_FREE(vmesa->UbyteColor.Ptr);
vmesa->UbyteColor.Ptr = 0;
}
}

+ 39
- 0
src/mesa/drivers/dri/s3v/s3v_vb.h View File

@@ -0,0 +1,39 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#ifndef S3VVB_INC
#define S3VVB_INC

#include "mtypes.h"
#include "swrast/swrast.h"

#define _S3V_NEW_VERTEX (_NEW_TEXTURE | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE)


extern void s3vChooseVertexState( GLcontext *ctx );
extern void s3vCheckTexSizes( GLcontext *ctx );
extern void s3vBuildVertices( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint newinputs );


extern void s3v_import_float_colors( GLcontext *ctx );
extern void s3v_import_float_spec_colors( GLcontext *ctx );

extern void s3v_translate_vertex( GLcontext *ctx,
const s3vVertex *src,
SWvertex *dst );

extern void s3vInitVB( GLcontext *ctx );
extern void s3vFreeVB( GLcontext *ctx );

extern void s3v_print_vertex( GLcontext *ctx, const s3vVertex *v );
#if 0
extern void s3vPrintSetupFlags(char *msg, GLuint flags );
#endif

#endif

+ 326
- 0
src/mesa/drivers/dri/s3v/s3v_xmesa.c View File

@@ -0,0 +1,326 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#include "s3v_context.h"
#include "s3v_vb.h"
#include "context.h"
#include "mmath.h"
#include "matrix.h"
#include "s3v_dri.h"

#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "array_cache/acache.h"

/* #define DEBUG(str) printf str */

static GLboolean
s3vInitDriver(__DRIscreenPrivate *sPriv)
{
sPriv->private = (void *) s3vCreateScreen( sPriv );

if (!sPriv->private) {
s3vDestroyScreen( sPriv );
return GL_FALSE;
}

return GL_TRUE;
}

static void
s3vDestroyContext(__DRIcontextPrivate *driContextPriv)
{
s3vContextPtr vmesa = (s3vContextPtr)driContextPriv->driverPrivate;

if (vmesa) {
_swsetup_DestroyContext( vmesa->glCtx );
_tnl_DestroyContext( vmesa->glCtx );
_ac_DestroyContext( vmesa->glCtx );
_swrast_DestroyContext( vmesa->glCtx );

s3vFreeVB( vmesa->glCtx );

/* free the Mesa context */
vmesa->glCtx->DriverCtx = NULL;
_mesa_destroy_context(vmesa->glCtx);

Xfree(vmesa);
driContextPriv->driverPrivate = NULL;
}
}


static GLboolean
s3vCreateBuffer( 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
s3vDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
}

static void
s3vSwapBuffers(Display *dpy, void *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_swapbuffers( ctx );

vmesa = (s3vContextPtr) dPriv->driContextPriv->driverPrivate;
/* driScrnPriv = vmesa->driScreen; */

/* if (vmesa->EnabledFlags & S3V_BACK_BUFFER) */

/* _mesa_swapbuffers( 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;
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_current2( 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_current2( 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( 0, 0 );
}

return GL_TRUE;
}


static GLboolean
s3vUnbindContext( __DRIcontextPrivate *driContextPriv )
{
return GL_TRUE;
}

static GLboolean
s3vOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}

static GLboolean
s3vCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}


static struct __DriverAPIRec s3vAPI = {
s3vInitDriver,
s3vDestroyScreen,
s3vCreateContext,
s3vDestroyContext,
s3vCreateBuffer,
s3vDestroyBuffer,
s3vSwapBuffers,
s3vMakeCurrent,
s3vUnbindContext,
s3vOpenFullScreen,
s3vCloseFullScreen
};



/*
* 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=NULL;

DEBUG(("__driCreateScreen: psp = %p\n", psp));
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &s3vAPI);
DEBUG(("__driCreateScreen: psp = %p\n", psp));
return (void *) psp;
}

void __driRegisterExtensions(void)
{
/* No extensions */
}

+ 383
- 0
src/mesa/drivers/dri/s3v/s3virgetri.h View File

@@ -0,0 +1,383 @@
/*
* Author: Max Lingua <sunmax@libero.it>
*/

#define LOCAL_VARS \
int vert0, vert1, vert2; \
GLfloat y0, y1, y2, ydiff; \
int iy0, iy1, iy2; \
int x0, x1, x2, z0, z1, z2; \
int dy01, dy02, dy12, dx01, dx02, dx12; \
int delt02, delt01, delt12, end01, end12, start02; \
int zstart, arstart, gbstart; \
int deltzy, deltzx, deltarx, deltgbx, deltary, deltgby; \
GLubyte (*colours)[4]; \
GLubyte (*scolours)[4]; \
static int tp = 0; \
int tmp, lr

#define LOCAL_TEX_VARS \
int u0, u1, u2; \
GLfloat ru0, ru1, ru2; \
int v0, v1, v2; \
GLfloat rv0, rv1, rv2; \
GLfloat w0, w1, w2; \
GLfloat rw0, rw1, rw2; \
int baseu, basev; \
int d0, d1, d2; \
int deltdx, deltvx, deltux, deltdy, deltvy, deltuy; \
int deltwx, deltwy; \
int rbaseu, rbasev; \
int dstart, ustart, wstart, vstart; \
static int stmp = 0; \
s3virgeTextureObject_t *t

#define CULL_BACKFACE() \
do { \
GLfloat *w0 = VB->Win.data[e0]; \
GLfloat *w1 = VB->Win.data[e1]; \
GLfloat *w2 = VB->Win.data[e2]; \
float cull; \
cull = ctx->backface_sign * ((w1[0] - w0[0]) * (w0[1] - w2[1]) + \
(w1[1] - w0[1]) * (w2[0] - w0[0])); \
if (cull < 0) \
return; \
} while (0)
#define SORT_VERTICES() \
do { \
y0 = VB->Win.data[e0][1]; \
y1 = VB->Win.data[e1][1]; \
y2 = VB->Win.data[e2][1]; \
if (y1 > y0) { \
if (y2 > y0) { \
vert0 = e0; \
if (y1 > y2) { vert2 = e1; vert1 = e2; } else { vert2 = e2; vert1 = e1; } \
} else { vert0 = e2; vert1 = e0; vert2 = e1; } \
} else { \
if (y2 > y0) { vert0 = e1; vert1 = e0; vert2 = e2; } else { \
vert2 = e0; \
if (y2 > y1) { vert0 = e1; vert1 = e2; } else { vert0 = e2; vert1 = e1; } \
} \
} \
} while (0)

#define SET_VARIABLES() \
do { \
iy0 = y0 = ((s3virgeDB->height - (VB->Win.data[vert0][1]))); \
iy1 = y1 = ((s3virgeDB->height - (VB->Win.data[vert1][1]))); \
iy2 = y2 = ((s3virgeDB->height - (VB->Win.data[vert2][1]))); \
if (iy0 == iy2) { return; } \
ydiff = y0 - (float)iy0; \
x0 = ((VB->Win.data[vert0][0]) * 1024.0 * 1024.0); \
x1 = ((VB->Win.data[vert1][0]) * 1024.0 * 1024.0); \
x2 = ((VB->Win.data[vert2][0]) * 1024.0 * 1024.0); \
z0 = (VB->Win.data[vert0][2] * 1024.0 * 32.0); \
z1 = (VB->Win.data[vert1][2] * 1024.0 * 32.0); \
z2 = (VB->Win.data[vert2][2] * 1024.0 * 32.0); \
dx12 = x2 - x1; \
dy12 = iy1 - iy2; \
dx01 = x1 - x0; \
dy01 = iy0 - iy1; \
dx02 = x2 - x0; \
dy02 = iy0 - iy2; \
delt12 = delt02 = delt01 = 0; \
} while (0)
#define SET_TEX_VARIABLES() \
do { \
t = ((s3virgeTextureObject_t *)ctx->Texture.Unit[0].Current->DriverData); \
deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
u0 = (VB->TexCoordPtr[0]->data[vert0][0] * (GLfloat)(t->tObj->Image[0]->Width) * 256.0); \
u1 = (VB->TexCoordPtr[0]->data[vert1][0] * (GLfloat)(t->tObj->Image[0]->Width) * 256.0); \
u2 = (VB->TexCoordPtr[0]->data[vert2][0] * (GLfloat)(t->tObj->Image[0]->Width) * 256.0); \
v0 = (VB->TexCoordPtr[0]->data[vert0][1] * (GLfloat)(t->tObj->Image[0]->Height) * 256.0); \
v1 = (VB->TexCoordPtr[0]->data[vert1][1] * (GLfloat)(t->tObj->Image[0]->Height) * 256.0); \
v2 = (VB->TexCoordPtr[0]->data[vert2][1] * (GLfloat)(t->tObj->Image[0]->Height) * 256.0); \
w0 = (VB->Win.data[vert0][3]); \
w1 = (VB->Win.data[vert1][3]); \
w2 = (VB->Win.data[vert2][3]); \
} while (0)

#define FLATSHADE_COLORS() \
do { \
GLubyte *col = &(colours[pv][0]); \
deltarx = deltary = deltgbx = deltgby = 0; \
gbstart = (((col[1]) << 23) | ((col[2]) << 7)); \
arstart = (((col[3]) << 23) | ((col[0]) << 7)); \
} while (0)

#define GOURAUD_COLORS() \
do { \
int ctmp, ctmp2, ctmp3, ctmp4; \
GLubyte *col0, *col1, *col2; \
col0 = &(colours[vert0][0]); \
col1 = &(colours[vert1][0]); \
col2 = &(colours[vert2][0]); \
ctmp = ((col2[3] - col0[3]) << 7) / dy02; \
ctmp2 = ((col2[0] - col0[0]) << 7) / dy02; \
deltary = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
ctmp3 = ((col2[1] - col0[1]) << 7) / dy02; \
ctmp4 = ((col2[2] - col0[2]) << 7) / dy02; \
deltgby = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
gbstart = (((int)((ydiff * ctmp3) + (col0[1] << 7)) << 16) & 0x7FFF0000) | \
((int)((ydiff * ctmp4) + (col0[2] << 7)) & 0x7FFF); \
arstart = (((int)((ydiff * ctmp) + (col0[3] << 7)) << 16) & 0x7FFF0000) | \
((int)((ydiff * ctmp2) + (col0[0] << 7)) & 0x7FFF); \
if (tmp) { \
int ax, rx, gx, bx; \
ax = ((col1[3] << 7) - (dy01 * ctmp + (col0[3] << 7))) / tmp; \
rx = ((col1[0] << 7) - (dy01 * ctmp2 + (col0[0] << 7))) / tmp; \
gx = ((col1[1] << 7) - (dy01 * ctmp3 + (col0[1] << 7))) / tmp; \
bx = ((col1[2] << 7) - (dy01 * ctmp4 + (col0[2] << 7))) / tmp; \
deltarx = ((ax << 16) & 0xFFFF0000) | (rx & 0xFFFF); \
deltgbx = ((gx << 16) & 0xFFFF0000) | (bx & 0xFFFF); \
} else { \
deltgbx = deltarx = 0; \
} \
} while (0)

#define SET_XY() \
do { \
delt02 = dx02 / dy02; \
if (dy12) delt12 = dx12 / dy12; \
if (dy01) delt01 = dx01 / dy01; \
start02 = (ydiff * delt02) + x0; \
end01 = (ydiff * delt01) + x0; \
end12 = ((y1 - (GLfloat)iy1) * delt12) + x1; \
} while (0)

#define SET_DIR() \
do { \
tmp = x1 - (dy01 * delt02 + x0); \
if (tmp > 0) { \
lr = 0x80000000; \
} else { \
tmp *= -1; \
lr = 0; \
} \
tmp >>= 20; \
} while (0)

#define SET_Z() \
do { \
deltzy = (z2 - z0) / dy02; \
if (tmp) { \
deltzx = (z1 - (dy01 * deltzy + z0)) / tmp; \
} else { deltzx = 0; } \
zstart = (deltzy * ydiff) + z0; \
} while (0)

#define SET_BASEUV() \
do { \
if (u0 < u1) { \
if (u0 < u2) { \
baseu = u0; \
} else { \
baseu = u2; \
} \
} else { \
if (u1 < u2) { \
baseu = u1; \
} else { \
baseu = u2; \
} \
} \
if (v0 < v1) { \
if (v0 < v2) { \
basev = v0; \
} else { \
basev = v2; \
} \
} else { \
if (v1 < v2) { \
basev = v1; \
} else { \
basev = v2; \
} \
} \
} while (0)

#define SET_RW() \
do { \
/* GLfloat minW; \
if (w0 < w1) { \
if (w0 < w2) { \
minW = w0; \
} else { \
minW = w2; \
} \
} else { \
if (w1 < w2) { \
minW = w1; \
} else { \
minW = w2; \
} \
} */ \
rw0 = (512.0 * w0); \
rw1 = (512.0 * w1); \
rw2 = (512.0 * w2); \
} while (0)


#define SET_D() \
do { \
GLfloat sxy, suv; \
int lev; \
suv = (VB->TexCoordPtr[0]->data[vert0][0] - \
VB->TexCoordPtr[0]->data[vert2][0]) * \
(VB->TexCoordPtr[0]->data[vert1][1] - \
VB->TexCoordPtr[0]->data[vert2][1]) - \
(VB->TexCoordPtr[0]->data[vert1][0] - \
VB->TexCoordPtr[0]->data[vert2][0]) * \
(VB->TexCoordPtr[0]->data[vert0][1] - \
VB->TexCoordPtr[0]->data[vert2][2]); \
sxy = (VB->Win.data[vert0][0] - \
VB->Win.data[vert2][0]) * \
(VB->Win.data[vert1][1] - \
VB->Win.data[vert2][1]) - \
(VB->Win.data[vert1][0] - \
VB->Win.data[vert2][0]) * \
(VB->Win.data[vert0][1] - \
VB->Win.data[vert2][2]); \
if (sxy < 0) sxy *= -1.0; \
if (suv < 0) suv *= -1.0; \
lev = *(int*)&suv - *(int *)&sxy; \
if (lev < 0) \
lev = 0; \
else \
lev >>=23; \
dstart = (lev << 27); \
} while (0)


#define SET_UVWD() \
do { \
SET_BASEUV(); \
SET_RW(); \
SET_D(); \
ru0 = (((u0 - baseu) * rw0)); \
ru1 = (((u1 - baseu) * rw1)); \
ru2 = (((u2 - baseu) * rw2)); \
rv0 = (((v0 - basev) * rw0)); \
rv1 = (((v1 - basev) * rw1)); \
rv2 = (((v2 - basev) * rw2)); \
while (baseu < 0) { baseu += (t->tObj->Image[0]->Width << 8); } \
while (basev < 0) { basev += (t->tObj->Image[0]->Height << 8); } \
if (!(baseu & 0xFF)) { baseu = (baseu >> 8); } else { baseu = (baseu >> 8) + 1; } \
if ((basev & 0x80) || !(basev & 0xFF)) { basev = (basev >> 8); } else { basev = (basev >> 8) - 1; } \
rbaseu = (baseu) << (16 - t->widthLog2); \
rbasev = (basev) << (16 - t->widthLog2); \
deltuy = (((ru2 - ru0) / dy02)); \
deltvy = (((rv2 - rv0) / dy02)); \
rw0 *= (1024.0 * 512.0); \
rw1 *= (1024.0 * 512.0); \
rw2 *= (1024.0 * 512.0); \
deltwy = ((rw2 - rw0) / dy02); \
if (tmp) { \
deltux = ((ru1 - (dy01 * deltuy + ru0)) / tmp); \
deltvx = ((rv1 - (dy01 * deltvy + rv0)) / tmp); \
deltwx = ((rw1 - (dy01 * deltwy + rw0)) / tmp); \
} else { deltux = deltvx = deltwx = 0; } \
ustart = (deltuy * ydiff) + (ru0); \
vstart = (deltvy * ydiff) + (rv0); \
wstart = (deltwy * ydiff) + (rw0); \
} while (0)


#define SEND_COLORS() \
do { \
WAITFIFOEMPTY(6); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_GBX), deltgbx); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ARX), deltarx); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_GBY), deltgby); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ARY), deltary); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_GS_BS), gbstart); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_AS_RS), arstart); \
} while (0)

#define SEND_VERTICES() \
do { \
WAITFIFOEMPTY(6); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ZSTART), zstart); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ZXD), deltzx); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_ZYD), deltzy); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXDELTA12), delt12); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXEND12), end12); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXDELTA01), delt01); \
WAITFIFOEMPTY(5); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXEND01), end01); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXDELTA02), delt02); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TXSTART02), start02); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TYS), iy0); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_TY01_Y12), \
((((iy0 - iy1) & 0x7FF) << 16) | \
((iy1 - iy2) & 0x7FF) | lr)); \
} while (0)

#define SEND_UVWD() \
do { \
WAITFIFOEMPTY(7); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_BASEV), (rbasev & 0xFFFF)); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_BASEU), (0xa0000000 | (rbaseu & 0xFFFF))); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_WXD), deltwx); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_WYD), deltwy); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_WSTART), wstart); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_DXD), deltdx); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_VXD), deltvx); \
WAITFIFOEMPTY(7); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_UXD), deltux); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_DYD), deltdy); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_VYD), deltvy); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_UYD), deltuy); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_DSTART), dstart); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_VSTART), vstart); \
OUTREG( (S3VIRGE_3DTRI_REG | S3VIRGE_3DTRI_USTART), ustart); \
} while (0)

#define DMA_SEND_UVWD() \
do { \
DMAOUT((rbasev & 0xFFFF)); \
DMAOUT((0xa0000000 | (rbaseu & 0xFFFF))); \
DMAOUT(deltwx); \
DMAOUT(deltwy); \
DMAOUT(wstart); \
DMAOUT(deltdx); \
DMAOUT(deltvx); \
DMAOUT(deltux); \
DMAOUT(deltdy); \
DMAOUT(deltvy); \
DMAOUT(deltuy); \
DMAOUT(dstart); \
DMAOUT(vstart); \
DMAOUT(ustart); \
} while (0)


#define DMA_SEND_COLORS() \
do { \
DMAOUT(deltgbx); \
DMAOUT(deltarx); \
DMAOUT(deltgby); \
DMAOUT(deltary); \
DMAOUT(gbstart); \
DMAOUT(arstart); \
} while (0)

#define DMA_SEND_VERTICES() \
do { \
DMAOUT(deltzx); \
DMAOUT(deltzy); \
DMAOUT(zstart); \
DMAOUT(delt12); \
DMAOUT(end12); \
DMAOUT(delt01); \
DMAOUT(end01); \
DMAOUT(delt02); \
DMAOUT(start02); \
DMAOUT(iy0); \
DMAOUT(((((iy0 - iy1) & 0x7FF) << 16) | \
((iy1 - iy2) & 0x7FF) | lr)); \
} while (0)


+ 419
- 0
src/mesa/drivers/dri/trident/trident_context.c View File

@@ -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, <alanh@fairlite.demon.co.uk>
*
* 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 */
}

+ 209
- 0
src/mesa/drivers/dri/trident/trident_context.h View File

@@ -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, <alanh@fairlite.demon.co.uk>
*
* 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_ */

+ 127
- 0
src/mesa/drivers/dri/trident/trident_dd.c View File

@@ -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, <alanh@fairlite.demon.co.uk>
*
* 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;
}

+ 552
- 0
src/mesa/drivers/dri/trident/trident_state.c View File

@@ -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, <alanh@fairlite.demon.co.uk>
*
* 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;
}

+ 1112
- 0
src/mesa/drivers/dri/trident/trident_tris.c
File diff suppressed because it is too large
View File


+ 435
- 0
src/mesa/drivers/dri/trident/trident_vb.c View File

@@ -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, <alanh@fairlite.demon.co.uk>
*
* 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;
}
}

Loading…
Cancel
Save