#include "tdfx_context.h"
#include "tdfx_dd.h"
#include "tdfx_lock.h"
#include "tdfx_vb.h"
#include "tdfx_pixels.h"
#include "context.h"
#include "enums.h"
#include "swrast/swrast.h"
#if defined(USE_X86_ASM)
#include "X86/common_x86_asm.h"
#endif
#define TDFX_DATE "20021125"
const GLboolean false4[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE };
const GLboolean true4[4] = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE };
static const GLubyte *tdfxDDGetString( GLcontext *ctx, GLenum name )
{
tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
switch ( name ) {
case GL_RENDERER:
{
char *buffer = fxMesa->rendererString;
char hardware[100];
LOCK_HARDWARE(fxMesa);
strcpy( hardware, fxMesa->Glide.grGetString(GR_HARDWARE) );
UNLOCK_HARDWARE(fxMesa);
strcpy( buffer, "Mesa DRI " );
strcat( buffer, TDFX_DATE );
strcat( buffer, " " );
if ( strcmp( hardware, "Voodoo3 (tm)" ) == 0 ) {
strcat( buffer, "Voodoo3" );
}
else if ( strcmp( hardware, "Voodoo Banshee (tm)" ) == 0 ) {
strcat( buffer, "VoodooBanshee" );
}
else if ( strcmp( hardware, "Voodoo4 (tm)" ) == 0 ) {
strcat( buffer, "Voodoo4" );
}
else if ( strcmp( hardware, "Voodoo5 (tm)" ) == 0 ) {
strcat( buffer, "Voodoo5" );
}
else {
int i;
for ( i = 0 ; hardware[i] && i < 60 ; i++ ) {
if ( hardware[i] == ' ' || hardware[i] == '\t' )
hardware[i] = '-';
}
strcat( buffer, hardware );
}
#ifdef USE_X86_ASM
if ( _mesa_x86_cpu_features ) {
strncat( buffer, " x86", 4 );
}
#endif
#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
return (const GLubyte *) buffer;
}
case GL_VENDOR:
return (const GLubyte *)"VA Linux Systems, Inc.";
default:
return NULL;
}
}
static void tdfxDDGetBufferSize( GLframebuffer *buffer,
GLuint *width, GLuint *height )
{
GET_CURRENT_CONTEXT(ctx);
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
LOCK_HARDWARE( fxMesa );
*width = fxMesa->width;
*height = fxMesa->height;
UNLOCK_HARDWARE( fxMesa );
}
static GLboolean get_occlusion_result( GLcontext *ctx )
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
GLboolean result;
LOCK_HARDWARE( fxMesa );
fxMesa->Glide.grFinish();
if (ctx->Depth.OcclusionTest) {
if (ctx->OcclusionResult) {
result = GL_TRUE;
}
else {
FxI32 zfail, in;
fxMesa->Glide.grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, 4, &zfail);
fxMesa->Glide.grGet(GR_STATS_PIXELS_IN, 4, &in);
result = ((in - zfail) < 1 || in == 0) ? GL_FALSE : GL_TRUE;
}
}
else {
result = ctx->OcclusionResultSaved;
}
fxMesa->Glide.grReset(GR_STATS_PIXELS);
ctx->OcclusionResult = GL_FALSE;
ctx->OcclusionResultSaved = GL_FALSE;
UNLOCK_HARDWARE( fxMesa );
return result;
}
static GLboolean tdfxDDGetBooleanv( GLcontext *ctx, GLenum pname,
GLboolean *result )
{
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) {
*result = get_occlusion_result( ctx );
return GL_TRUE;
}
return GL_FALSE;
}
static GLboolean tdfxDDGetDoublev( GLcontext *ctx, GLenum pname,
GLdouble *result )
{
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) {
*result = (GLdouble) get_occlusion_result( ctx );
return GL_TRUE;
}
return GL_FALSE;
}
static GLboolean tdfxDDGetFloatv( GLcontext *ctx, GLenum pname,
GLfloat *result )
{
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) {
*result = (GLfloat) get_occlusion_result( ctx );
return GL_TRUE;
}
return GL_FALSE;
}
static GLboolean tdfxDDGetIntegerv( GLcontext *ctx, GLenum pname,
GLint *result )
{
if ( pname == GL_OCCLUSION_TEST_RESULT_HP ) {
*result = (GLint) get_occlusion_result( ctx );
return GL_TRUE;
}
return GL_FALSE;
}
#define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \
((vis.redBits == r) && \
(vis.greenBits == g) && \
(vis.blueBits == b) && \
(vis.alphaBits == a))
void tdfxDDInitDriverFuncs( GLcontext *ctx )
{
if ( MESA_VERBOSE & VERBOSE_DRIVER ) {
fprintf( stderr, "tdfx: %s()\n", __FUNCTION__ );
}
ctx->Driver.GetString = tdfxDDGetString;
ctx->Driver.GetBufferSize = tdfxDDGetBufferSize;
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
ctx->Driver.Error = NULL;
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;
if ( VISUAL_EQUALS_RGBA(ctx->Visual, 8, 8, 8, 8) )
{
ctx->Driver.DrawPixels = tdfx_drawpixels_R8G8B8A8;
ctx->Driver.ReadPixels = tdfx_readpixels_R8G8B8A8;
}
else if ( VISUAL_EQUALS_RGBA(ctx->Visual, 5, 6, 5, 0) )
{
ctx->Driver.ReadPixels = tdfx_readpixels_R5G6B5;
}
ctx->Driver.GetBooleanv = tdfxDDGetBooleanv;
ctx->Driver.GetDoublev = tdfxDDGetDoublev;
ctx->Driver.GetFloatv = tdfxDDGetFloatv;
ctx->Driver.GetIntegerv = tdfxDDGetIntegerv;
ctx->Driver.GetPointerv = NULL;
}
void
FX_grColorMaskv(GLcontext *ctx, const GLboolean rgba[4])
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
LOCK_HARDWARE(fxMesa);
if (ctx->Visual.redBits == 8) {
ASSERT( fxMesa->Glide.grColorMaskExt );
fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP],
rgba[BCOMP], rgba[ACOMP]);
}
else {
fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP],
GL_FALSE);
}
UNLOCK_HARDWARE(fxMesa);
}
void
FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4])
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
if (ctx->Visual.redBits == 8) {
ASSERT( fxMesa->Glide.grColorMaskExt );
fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP],
rgba[BCOMP], rgba[ACOMP]);
}
else {
fxMesa->Glide.grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP],
GL_FALSE);
}
}