#include "sis_context.h"
#include "sis_state.h"
#include "sis_tris.h"
#include "sis_lock.h"
#include "sis_tex.h"
#include "context.h"
#include "enums.h"
#include "colormac.h"
#include "swrast/swrast.h"
#include "array_cache/acache.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/t_pipeline.h"
static void
sisDDAlphaFunc( GLcontext * ctx, GLenum func, GLfloat ref )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
GLubyte refbyte;
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
CLAMPED_FLOAT_TO_UBYTE(refbyte, ref);
current->hwAlpha = refbyte << 16;
switch (func)
{
case GL_NEVER:
current->hwAlpha |= SiS_ALPHA_NEVER;
break;
case GL_LESS:
current->hwAlpha |= SiS_ALPHA_LESS;
break;
case GL_EQUAL:
current->hwAlpha |= SiS_ALPHA_EQUAL;
break;
case GL_LEQUAL:
current->hwAlpha |= SiS_ALPHA_LEQUAL;
break;
case GL_GREATER:
current->hwAlpha |= SiS_ALPHA_GREATER;
break;
case GL_NOTEQUAL:
current->hwAlpha |= SiS_ALPHA_NOTEQUAL;
break;
case GL_GEQUAL:
current->hwAlpha |= SiS_ALPHA_GEQUAL;
break;
case GL_ALWAYS:
current->hwAlpha |= SiS_ALPHA_ALWAYS;
break;
}
prev->hwAlpha = current->hwAlpha;
smesa->GlobalFlag |= GFLAG_ALPHASETTING;
}
static void
sisDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
current->hwDstSrcBlend = 0x10000;
switch (dfactor)
{
case GL_ZERO:
current->hwDstSrcBlend |= SiS_D_ZERO;
break;
case GL_ONE:
current->hwDstSrcBlend |= SiS_D_ONE;
break;
case GL_SRC_COLOR:
current->hwDstSrcBlend |= SiS_D_SRC_COLOR;
break;
case GL_ONE_MINUS_SRC_COLOR:
current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_COLOR;
break;
case GL_SRC_ALPHA:
current->hwDstSrcBlend |= SiS_D_SRC_ALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
current->hwDstSrcBlend |= SiS_D_DST_ALPHA;
break;
case GL_ONE_MINUS_DST_ALPHA:
current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_ALPHA;
break;
}
switch (sfactor)
{
case GL_ZERO:
current->hwDstSrcBlend |= SiS_S_ZERO;
break;
case GL_ONE:
current->hwDstSrcBlend |= SiS_S_ONE;
break;
case GL_SRC_ALPHA:
current->hwDstSrcBlend |= SiS_S_SRC_ALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
current->hwDstSrcBlend |= SiS_S_DST_ALPHA;
break;
case GL_ONE_MINUS_DST_ALPHA:
current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_ALPHA;
break;
case GL_DST_COLOR:
current->hwDstSrcBlend |= SiS_S_DST_COLOR;
break;
case GL_ONE_MINUS_DST_COLOR:
current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_COLOR;
break;
case GL_SRC_ALPHA_SATURATE:
current->hwDstSrcBlend |= SiS_S_SRC_ALPHA_SATURATE;
break;
}
if (current->hwDstSrcBlend != prev->hwDstSrcBlend) {
prev->hwDstSrcBlend = current->hwDstSrcBlend;
smesa->GlobalFlag |= GFLAG_DSTBLEND;
}
}
static void
sisDDDepthFunc( GLcontext * ctx, GLenum func )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
current->hwZ &= ~MASK_ZTestMode;
switch (func)
{
case GL_LESS:
current->hwZ |= SiS_Z_COMP_S_LT_B;
break;
case GL_GEQUAL:
current->hwZ |= SiS_Z_COMP_S_GE_B;
break;
case GL_LEQUAL:
current->hwZ |= SiS_Z_COMP_S_LE_B;
break;
case GL_GREATER:
current->hwZ |= SiS_Z_COMP_S_GT_B;
break;
case GL_NOTEQUAL:
current->hwZ |= SiS_Z_COMP_S_NE_B;
break;
case GL_EQUAL:
current->hwZ |= SiS_Z_COMP_S_EQ_B;
break;
case GL_ALWAYS:
current->hwZ |= SiS_Z_COMP_ALWAYS;
break;
case GL_NEVER:
current->hwZ |= SiS_Z_COMP_NEVER;
break;
}
if (current->hwZ != prev->hwZ) {
prev->hwZ = current->hwZ;
smesa->GlobalFlag |= GFLAG_ZSETTING;
}
}
void
sisDDDepthMask( GLcontext * ctx, GLboolean flag )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
if (!ctx->Depth.Test)
flag = GL_FALSE;
if (ctx->Visual.stencilBits) {
if (flag || (ctx->Stencil.WriteMask[0] != 0)) {
current->hwCapEnable |= MASK_ZWriteEnable;
if (flag && (ctx->Stencil.WriteMask[0] == 0xff)) {
current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
} else {
current->hwCapEnable2 |= MASK_ZMaskWriteEnable;
current->hwZMask = (ctx->Stencil.WriteMask[0] << 24) |
((flag) ? 0x00ffffff : 0);
if (current->hwZMask ^ prev->hwZMask) {
prev->hwZMask = current->hwZMask;
smesa->GlobalFlag |= GFLAG_ZSETTING;
}
}
} else {
current->hwCapEnable &= ~MASK_ZWriteEnable;
}
} else {
if (flag) {
current->hwCapEnable |= MASK_ZWriteEnable;
current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
} else {
current->hwCapEnable &= ~MASK_ZWriteEnable;
}
}
}
void
sisUpdateClipping( GLcontext *ctx )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
GLint x1, y1, x2, y2;
x1 = 0;
y1 = 0;
x2 = smesa->width - 1;
y2 = smesa->height - 1;
if (ctx->Scissor.Enabled) {
if (ctx->Scissor.X > x1)
x1 = ctx->Scissor.X;
if (ctx->Scissor.Y > y1)
y1 = ctx->Scissor.Y;
if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2)
y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
}
y1 = Y_FLIP(y1);
y2 = Y_FLIP(y2);
current->clipTopBottom = (y2 << 13) | y1;
current->clipLeftRight = (x1 << 13) | x2;
if ((current->clipTopBottom ^ prev->clipTopBottom) ||
(current->clipLeftRight ^ prev->clipLeftRight))
{
prev->clipTopBottom = current->clipTopBottom;
prev->clipLeftRight = current->clipLeftRight;
smesa->GlobalFlag |= GFLAG_CLIPPING;
}
}
static void
sisDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
{
if (ctx->Scissor.Enabled)
sisUpdateClipping( ctx );
}
static void
sisUpdateCull( GLcontext *ctx )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
GLint cullflag, frontface;
cullflag = ctx->Polygon.CullFaceMode;
frontface = ctx->Polygon.FrontFace;
smesa->AGPParseSet &= ~(MASK_PsCullDirection_CCW);
smesa->dwPrimitiveSet &= ~(MASK_CullDirection);
if((cullflag == GL_FRONT && frontface == GL_CCW) ||
(cullflag == GL_BACK && frontface == GL_CW))
{
smesa->AGPParseSet |= MASK_PsCullDirection_CCW;
smesa->dwPrimitiveSet |= OP_3D_CullDirection_CCW;
}
}
static void
sisDDCullFace( GLcontext *ctx, GLenum mode )
{
sisUpdateCull( ctx );
}
static void
sisDDFrontFace( GLcontext *ctx, GLenum mode )
{
sisUpdateCull( ctx );
}
static void sisDDColorMask( GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) {
current->hwCapEnable2 &= ~(MASK_AlphaMaskWriteEnable |
MASK_ColorMaskWriteEnable);
} else {
current->hwCapEnable2 |= (MASK_AlphaMaskWriteEnable |
MASK_ColorMaskWriteEnable);
current->hwDstMask = (r) ? smesa->redMask : 0 |
(g) ? smesa->greenMask : 0 |
(b) ? smesa->blueMask : 0 |
(a) ? smesa->alphaMask : 0;
}
if (current->hwDstMask != prev->hwDstMask) {
prev->hwDstMask = current->hwDstMask;
smesa->GlobalFlag |= GFLAG_DESTSETTING;
}
}
static void sisDDShadeModel( GLcontext *ctx, GLenum mode )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
smesa->hw_primitive = -1;
}
static void sisCalcViewport( GLcontext *ctx )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
const GLfloat *v = ctx->Viewport._WindowMap.m;
GLfloat *m = smesa->hw_viewport;
m[MAT_SX] = v[MAT_SX];
m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
m[MAT_SY] = - v[MAT_SY];
m[MAT_TY] = - v[MAT_TY] + smesa->driDrawable->h + SUBPIXEL_Y;
m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale;
m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale;
}
static void sisDDViewport( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height )
{
sisCalcViewport( ctx );
}
static void sisDDDepthRange( GLcontext *ctx,
GLclampd nearval, GLclampd farval )
{
sisCalcViewport( ctx );
}
static void
sisDDLogicOpCode( GLcontext *ctx, GLenum opcode )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
if (!ctx->Color.ColorLogicOpEnabled)
return;
current->hwDstSet &= ~MASK_ROP2;
switch (opcode)
{
case GL_CLEAR:
current->hwDstSet |= LOP_CLEAR;
break;
case GL_SET:
current->hwDstSet |= LOP_SET;
break;
case GL_COPY:
current->hwDstSet |= LOP_COPY;
break;
case GL_COPY_INVERTED:
current->hwDstSet |= LOP_COPY_INVERTED;
break;
case GL_NOOP:
current->hwDstSet |= LOP_NOOP;
break;
case GL_INVERT:
current->hwDstSet |= LOP_INVERT;
break;
case GL_AND:
current->hwDstSet |= LOP_AND;
break;
case GL_NAND:
current->hwDstSet |= LOP_NAND;
break;
case GL_OR:
current->hwDstSet |= LOP_OR;
break;
case GL_NOR:
current->hwDstSet |= LOP_NOR;
break;
case GL_XOR:
current->hwDstSet |= LOP_XOR;
break;
case GL_EQUIV:
current->hwDstSet |= LOP_EQUIV;
break;
case GL_AND_REVERSE:
current->hwDstSet |= LOP_AND_REVERSE;
break;
case GL_AND_INVERTED:
current->hwDstSet |= LOP_AND_INVERTED;
break;
case GL_OR_REVERSE:
current->hwDstSet |= LOP_OR_REVERSE;
break;
case GL_OR_INVERTED:
current->hwDstSet |= LOP_OR_INVERTED;
break;
}
if (current->hwDstSet ^ prev->hwDstSet) {
prev->hwDstSet = current->hwDstSet;
smesa->GlobalFlag |= GFLAG_DESTSETTING;
}
}
void sisDDDrawBuffer( GLcontext *ctx, GLenum mode )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
switch ( ctx->Color._DrawDestMask ) {
case FRONT_LEFT_BIT:
case BACK_LEFT_BIT:
FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
_swrast_DrawBuffer(ctx, mode);
current->hwOffsetDest = (smesa->drawOffset) >> 1;
current->hwDstSet &= ~MASK_DstBufferPitch;
current->hwDstSet |= smesa->drawPitch >> 2;
if (current->hwDstSet != prev->hwDstSet) {
prev->hwDstSet = current->hwDstSet;
smesa->GlobalFlag |= GFLAG_DESTSETTING;
}
if (current->hwOffsetDest != prev->hwOffsetDest) {
prev->hwOffsetDest = current->hwOffsetDest;
smesa->GlobalFlag |= GFLAG_DESTSETTING;
}
}
static void
sisDDEnable( GLcontext * ctx, GLenum cap, GLboolean state )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *current = &smesa->current;
switch (cap)
{
case GL_ALPHA_TEST:
if (state)
current->hwCapEnable |= MASK_AlphaTestEnable;
else
current->hwCapEnable &= ~MASK_AlphaTestEnable;
break;
case GL_BLEND:
if (state)
current->hwCapEnable |= MASK_BlendEnable;
else
current->hwCapEnable &= ~MASK_BlendEnable;
break;
case GL_CULL_FACE:
if (state)
current->hwCapEnable |= MASK_CullEnable;
else
current->hwCapEnable &= ~MASK_CullEnable;
break;
case GL_DEPTH_TEST:
if (state && smesa->depthbuffer)
current->hwCapEnable |= MASK_ZTestEnable;
else
current->hwCapEnable &= ~MASK_ZTestEnable;
sisDDDepthMask( ctx, ctx->Depth.Mask );
break;
case GL_DITHER:
if (state)
current->hwCapEnable |= MASK_DitherEnable;
else
current->hwCapEnable &= ~MASK_DitherEnable;
break;
case GL_FOG:
if (state)
current->hwCapEnable |= MASK_FogEnable;
else
current->hwCapEnable &= ~MASK_FogEnable;
break;
case GL_COLOR_LOGIC_OP:
if (state)
sisDDLogicOpCode( ctx, ctx->Color.LogicOp );
else
sisDDLogicOpCode( ctx, GL_COPY );
break;
case GL_SCISSOR_TEST:
sisUpdateClipping( ctx );
break;
case GL_STENCIL_TEST:
if (state) {
if (smesa->zFormat != SiS_ZFORMAT_S8Z24)
FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1);
else
current->hwCapEnable |= (MASK_StencilTestEnable |
MASK_StencilWriteEnable);
} else {
FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0);
current->hwCapEnable &= ~(MASK_StencilTestEnable |
MASK_StencilWriteEnable);
}
break;
}
}
static void
sisDDDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
LOCK_HARDWARE();
_swrast_DrawPixels( ctx, x, y, width, height, format, type, unpack, pixels );
UNLOCK_HARDWARE();
}
static void
sisDDReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
LOCK_HARDWARE();
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,
pixels);
UNLOCK_HARDWARE();
}
static void
sisDDBitmap( GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
LOCK_HARDWARE();
_swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap );
UNLOCK_HARDWARE();
}
void
sisUpdateHWState( GLcontext *ctx )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
__GLSiSHardware *prev = &smesa->prev;
__GLSiSHardware *current = &smesa->current;
if (smesa->NewGLState & _NEW_TEXTURE)
sisUpdateTextureState( ctx );
if (current->hwCapEnable ^ prev->hwCapEnable) {
prev->hwCapEnable = current->hwCapEnable;
smesa->GlobalFlag |= GFLAG_ENABLESETTING;
}
if (current->hwCapEnable2 ^ prev->hwCapEnable2) {
prev->hwCapEnable2 = current->hwCapEnable2;
smesa->GlobalFlag |= GFLAG_ENABLESETTING2;
}
if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
sis_update_render_state( smesa );
if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES)
sis_update_texture_state( smesa );
}
static void
sisDDInvalidateState( GLcontext *ctx, GLuint new_state )
{
sisContextPtr smesa = SIS_CONTEXT(ctx);
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
_ac_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
smesa->NewGLState |= new_state;
}
void sisDDInitState( sisContextPtr smesa )
{
__GLSiSHardware *current = &smesa->current;
__GLSiSHardware *prev = &(smesa->prev);
GLcontext *ctx = smesa->glCtx;
prev->hwCapEnable = MASK_FogPerspectiveEnable | MASK_TextureCacheEnable |
MASK_TexturePerspectiveEnable | MASK_DitherEnable;
prev->hwCapEnable2 = MASK_TextureMipmapBiasEnable;
prev->hwZ = SiS_Z_COMP_S_LT_B;
prev->hwZMask = 0xffffffff;
prev->hwAlpha = SiS_ALPHA_ALWAYS;
prev->hwDstSet = LOP_COPY;
prev->hwDstMask = 0xffffffff;
prev->hwLinePattern = 0x00008000;
prev->hwDstSrcBlend = SiS_S_ONE | SiS_D_ZERO;
prev->hwStSetting = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | 0xff;
prev->hwStSetting2 = SiS_SFAIL_KEEP | SiS_SPASS_ZFAIL_KEEP |
SiS_SPASS_ZPASS_KEEP;
#if 0
prev->texture[0].hwTextureSet = 0x00030000;
#endif
#if 0
prev->texture[0].hwTextureMip = 0;
#endif
prev->hwTexBlendColor0 = STAGE0_C_CF;
prev->hwTexBlendColor1 = STAGE1_C_CF;
prev->hwTexBlendAlpha0 = STAGE0_A_AF;
prev->hwTexBlendAlpha1 = STAGE1_A_AF;
switch (smesa->bytesPerPixel)
{
case 2:
prev->hwDstSet |= DST_FORMAT_RGB_565;
break;
case 4:
prev->hwDstSet |= DST_FORMAT_ARGB_8888;
break;
}
switch (ctx->Visual.depthBits)
{
case 0:
prev->hwCapEnable &= ~MASK_ZWriteEnable;
case 16:
smesa->zFormat = SiS_ZFORMAT_Z16;
prev->hwCapEnable |= MASK_ZWriteEnable;
smesa->depth_scale = 1.0 / (GLfloat)0xffff;
break;
case 32:
smesa->zFormat = SiS_ZFORMAT_Z32;
prev->hwCapEnable |= MASK_ZWriteEnable;
smesa->depth_scale = 1.0 / (GLfloat)0xffffffff;
break;
case 24:
assert (ctx->Visual.stencilBits);
smesa->zFormat = SiS_ZFORMAT_S8Z24;
prev->hwCapEnable |= MASK_StencilBufferEnable;
prev->hwCapEnable |= MASK_ZWriteEnable;
smesa->depth_scale = 1.0 / (GLfloat)0xffffff;
break;
}
prev->hwZ |= smesa->zFormat;
smesa->clearTexCache = GL_TRUE;
smesa->clearColorPattern = 0;
smesa->AGPParseSet = MASK_PsTexture1FromB;
smesa->dwPrimitiveSet = OP_3D_Texture1FromB | OP_3D_TextureBumpFromC;
sisUpdateZStencilPattern( smesa, 1.0, 0 );
sisUpdateCull( ctx );
memcpy( current, prev, sizeof (__GLSiSHardware) );
sisDDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
sisDDFogfv( ctx, GL_FOG_END, &ctx->Fog.End );
sisDDFogfv( ctx, GL_FOG_MODE, NULL );
}
void sisDDInitStateFuncs( GLcontext *ctx )
{
ctx->Driver.UpdateState = sisDDInvalidateState;
ctx->Driver.Clear = sisDDClear;
ctx->Driver.ClearColor = sisDDClearColor;
ctx->Driver.ClearDepth = sisDDClearDepth;
ctx->Driver.ClearStencil = sisDDClearStencil;
ctx->Driver.AlphaFunc = sisDDAlphaFunc;
ctx->Driver.Bitmap = sisDDBitmap;
ctx->Driver.BlendFunc = sisDDBlendFunc;
ctx->Driver.ColorMask = sisDDColorMask;
ctx->Driver.CullFace = sisDDCullFace;
ctx->Driver.DepthMask = sisDDDepthMask;
ctx->Driver.DepthFunc = sisDDDepthFunc;
ctx->Driver.DepthRange = sisDDDepthRange;
ctx->Driver.DrawBuffer = sisDDDrawBuffer;
ctx->Driver.DrawPixels = sisDDDrawPixels;
ctx->Driver.Enable = sisDDEnable;
ctx->Driver.FrontFace = sisDDFrontFace;
ctx->Driver.Fogfv = sisDDFogfv;
ctx->Driver.Hint = NULL;
ctx->Driver.Lightfv = NULL;
ctx->Driver.LogicOpcode = sisDDLogicOpCode;
ctx->Driver.PolygonMode = NULL;
ctx->Driver.PolygonStipple = NULL;
ctx->Driver.ReadBuffer = NULL;
ctx->Driver.ReadPixels = sisDDReadPixels;
ctx->Driver.RenderMode = NULL;
ctx->Driver.Scissor = sisDDScissor;
ctx->Driver.ShadeModel = sisDDShadeModel;
ctx->Driver.Viewport = sisDDViewport;
ctx->Driver.Accum = _swrast_Accum;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
}