| /**************************************************************************** |
| * |
| * Mesa 3-D graphics library |
| * Direct3D Driver Interface |
| * |
| * ======================================================================== |
| * |
| * Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
| * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * ====================================================================== |
| * |
| * Language: ANSI C |
| * Environment: Windows 9x/2000/XP/XBox (Win32) |
| * |
| * Description: Driver interface code to Mesa |
| * |
| ****************************************************************************/ |
| |
| //#include <windows.h> |
| #include "dglcontext.h" |
| #include "ddlog.h" |
| #include "gld_dx9.h" |
| |
| #include "glheader.h" |
| #include "context.h" |
| #include "colormac.h" |
| #include "depth.h" |
| #include "extensions.h" |
| #include "macros.h" |
| #include "matrix.h" |
| // #include "mem.h" |
| //#include "mmath.h" |
| #include "mtypes.h" |
| #include "texformat.h" |
| #include "teximage.h" |
| #include "texstore.h" |
| #include "vbo/vbo.h" |
| #include "swrast_setup/swrast_setup.h" |
| #include "swrast_setup/ss_context.h" |
| #include "tnl/tnl.h" |
| #include "tnl/t_context.h" |
| #include "tnl/t_pipeline.h" |
| |
| extern BOOL dglSwapBuffers(HDC hDC); |
| |
| // HACK: Hack the _33 member of the OpenGL perspective projection matrix |
| const float _fPersp_33 = 1.6f; |
| |
| //--------------------------------------------------------------------------- |
| // Internal functions |
| //--------------------------------------------------------------------------- |
| |
| void _gld_mesa_warning( |
| __GLcontext *gc, |
| char *str) |
| { |
| // Intercept Mesa's internal warning mechanism |
| gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void _gld_mesa_fatal( |
| __GLcontext *gc, |
| char *str) |
| { |
| // Intercept Mesa's internal fatal-message mechanism |
| gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str); |
| |
| // Mesa calls abort(0) here. |
| ddlogClose(); |
| exit(0); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| D3DSTENCILOP _gldConvertStencilOp( |
| GLenum StencilOp) |
| { |
| // Used by Stencil: pass, fail and zfail |
| |
| switch (StencilOp) { |
| case GL_KEEP: |
| return D3DSTENCILOP_KEEP; |
| case GL_ZERO: |
| return D3DSTENCILOP_ZERO; |
| case GL_REPLACE: |
| return D3DSTENCILOP_REPLACE; |
| case GL_INCR: |
| return D3DSTENCILOP_INCRSAT; |
| case GL_DECR: |
| return D3DSTENCILOP_DECRSAT; |
| case GL_INVERT: |
| return D3DSTENCILOP_INVERT; |
| case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap |
| return D3DSTENCILOP_INCR; |
| case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap |
| return D3DSTENCILOP_DECR; |
| } |
| |
| #ifdef _DEBUG |
| gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n"); |
| #endif |
| |
| return D3DSTENCILOP_KEEP; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| D3DCMPFUNC _gldConvertCompareFunc( |
| GLenum CmpFunc) |
| { |
| // Used for Alpha func, depth func and stencil func. |
| |
| switch (CmpFunc) { |
| case GL_NEVER: |
| return D3DCMP_NEVER; |
| case GL_LESS: |
| return D3DCMP_LESS; |
| case GL_EQUAL: |
| return D3DCMP_EQUAL; |
| case GL_LEQUAL: |
| return D3DCMP_LESSEQUAL; |
| case GL_GREATER: |
| return D3DCMP_GREATER; |
| case GL_NOTEQUAL: |
| return D3DCMP_NOTEQUAL; |
| case GL_GEQUAL: |
| return D3DCMP_GREATEREQUAL; |
| case GL_ALWAYS: |
| return D3DCMP_ALWAYS; |
| }; |
| |
| #ifdef _DEBUG |
| gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n"); |
| #endif |
| |
| return D3DCMP_ALWAYS; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| D3DBLEND _gldConvertBlendFunc( |
| GLenum blend, |
| GLenum DefaultBlend) |
| { |
| switch (blend) { |
| case GL_ZERO: |
| return D3DBLEND_ZERO; |
| case GL_ONE: |
| return D3DBLEND_ONE; |
| case GL_DST_COLOR: |
| return D3DBLEND_DESTCOLOR; |
| case GL_SRC_COLOR: |
| return D3DBLEND_SRCCOLOR; |
| case GL_ONE_MINUS_DST_COLOR: |
| return D3DBLEND_INVDESTCOLOR; |
| case GL_ONE_MINUS_SRC_COLOR: |
| return D3DBLEND_INVSRCCOLOR; |
| case GL_SRC_ALPHA: |
| return D3DBLEND_SRCALPHA; |
| case GL_ONE_MINUS_SRC_ALPHA: |
| return D3DBLEND_INVSRCALPHA; |
| case GL_DST_ALPHA: |
| return D3DBLEND_DESTALPHA; |
| case GL_ONE_MINUS_DST_ALPHA: |
| return D3DBLEND_INVDESTALPHA; |
| case GL_SRC_ALPHA_SATURATE: |
| return D3DBLEND_SRCALPHASAT; |
| } |
| |
| #ifdef _DEBUG |
| gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n"); |
| #endif |
| |
| return DefaultBlend; |
| } |
| |
| //--------------------------------------------------------------------------- |
| // Misc. functions |
| //--------------------------------------------------------------------------- |
| |
| void gld_Noop_DX9( |
| GLcontext *ctx) |
| { |
| #ifdef _DEBUG |
| gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n"); |
| #endif |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_Error_DX9( |
| GLcontext *ctx) |
| { |
| #ifdef _DEBUG |
| // Quite useless. |
| // gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n"); |
| #endif |
| } |
| |
| //--------------------------------------------------------------------------- |
| // Required Mesa functions |
| //--------------------------------------------------------------------------- |
| |
| static GLboolean gld_set_draw_buffer_DX9( |
| GLcontext *ctx, |
| GLenum mode) |
| { |
| (void) ctx; |
| if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) { |
| return GL_TRUE; |
| } |
| else { |
| return GL_FALSE; |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void gld_set_read_buffer_DX9( |
| GLcontext *ctx, |
| GLframebuffer *buffer, |
| GLenum mode) |
| { |
| /* separate read buffer not supported */ |
| /* |
| ASSERT(buffer == ctx->DrawBuffer); |
| ASSERT(mode == GL_FRONT_LEFT); |
| */ |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_Clear_DX9( |
| GLcontext *ctx, |
| GLbitfield mask, |
| GLboolean all, |
| GLint x, |
| GLint y, |
| GLint width, |
| GLint height) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| DWORD dwFlags = 0; |
| D3DCOLOR Color = 0; |
| float Z = 0.0f; |
| DWORD Stencil = 0; |
| D3DRECT d3dClearRect; |
| |
| // TODO: Colourmask |
| const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0]; |
| |
| if (!gld->pDev) |
| return; |
| |
| if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { |
| GLubyte col[4]; |
| CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]); |
| CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]); |
| CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]); |
| CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]); |
| dwFlags |= D3DCLEAR_TARGET; |
| Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]); |
| } |
| |
| if (mask & DD_DEPTH_BIT) { |
| // D3D8 will fail the Clear call if we try and clear a |
| // depth buffer and we haven't created one. |
| // Also, some apps try and clear a depth buffer, |
| // when a depth buffer hasn't been requested by the app. |
| if (ctx->Visual.depthBits == 0) { |
| mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask |
| } else { |
| dwFlags |= D3DCLEAR_ZBUFFER; |
| Z = ctx->Depth.Clear; |
| } |
| } |
| |
| if (mask & DD_STENCIL_BIT) { |
| if (ctx->Visual.stencilBits == 0) { |
| // No stencil bits in depth buffer |
| mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask |
| } else { |
| dwFlags |= D3DCLEAR_STENCIL; |
| Stencil = ctx->Stencil.Clear; |
| } |
| } |
| |
| // Some apps do really weird things with the rect, such as Quake3. |
| if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { |
| all = GL_TRUE; |
| } |
| |
| if (!all) { |
| // Calculate clear subrect |
| d3dClearRect.x1 = x; |
| d3dClearRect.y1 = gldCtx->dwHeight - (y + height); |
| d3dClearRect.x2 = x + width; |
| d3dClearRect.y2 = d3dClearRect.y1 + height; |
| // gldLogPrintf(GLDLOG_INFO, "Rect %d,%d %d,%d", x,y,width,height); |
| } |
| |
| // dwFlags will be zero if there's nothing to clear |
| if (dwFlags) { |
| _GLD_DX9_DEV(Clear( |
| gld->pDev, |
| all ? 0 : 1, |
| all ? NULL : &d3dClearRect, |
| dwFlags, |
| Color, Z, Stencil)); |
| } |
| |
| if (mask & DD_ACCUM_BIT) { |
| // Clear accumulation buffer |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| // Mesa 5: Parameter change |
| static void gld_buffer_size_DX9( |
| // GLcontext *ctx, |
| GLframebuffer *fb, |
| GLuint *width, |
| GLuint *height) |
| { |
| // GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| |
| *width = fb->Width; // gldCtx->dwWidth; |
| *height = fb->Height; // gldCtx->dwHeight; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void gld_Finish_DX9( |
| GLcontext *ctx) |
| { |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void gld_Flush_DX9( |
| GLcontext *ctx) |
| { |
| GLD_context *gld = GLD_GET_CONTEXT(ctx); |
| |
| // TODO: Detect apps that glFlush() then SwapBuffers() ? |
| |
| if (gld->EmulateSingle) { |
| // Emulating a single-buffered context. |
| // [Direct3D doesn't allow rendering to front buffer] |
| dglSwapBuffers(gld->hDC); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_STENCIL( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| // Two-sided stencil. New for Mesa 5 |
| const GLuint uiFace = 0UL; |
| |
| struct gl_stencil_attrib *pStencil = &ctx->Stencil; |
| |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE)); |
| if (pStencil->Enabled) { |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace]))); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILREF, pStencil->Ref[uiFace])); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILMASK, pStencil->ValueMask[uiFace])); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILWRITEMASK, pStencil->WriteMask[uiFace])); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace]))); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace]))); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace]))); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_COLOR( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| DWORD dwFlags = 0; |
| D3DBLEND src; |
| D3DBLEND dest; |
| |
| // Alpha func |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc))); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAREF, (DWORD)ctx->Color.AlphaRef)); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, ctx->Color.AlphaEnabled)); |
| |
| // Blend func |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHABLENDENABLE, ctx->Color.BlendEnabled)); |
| src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE); |
| dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SRCBLEND, src)); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest)); |
| |
| // Color mask |
| if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED; |
| if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN; |
| if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE; |
| if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA; |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags)); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_DEPTH( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE)); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func))); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE)); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_POLYGON( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| D3DFILLMODE d3dFillMode = D3DFILL_SOLID; |
| D3DCULL d3dCullMode = D3DCULL_NONE; |
| float fOffset = 0; // Changed from int to float for DX9 |
| |
| // Fillmode |
| switch (ctx->Polygon.FrontMode) { |
| case GL_POINT: |
| d3dFillMode = D3DFILL_POINT; |
| break; |
| case GL_LINE: |
| d3dFillMode = D3DFILL_WIREFRAME; |
| break; |
| case GL_FILL: |
| d3dFillMode = D3DFILL_SOLID; |
| break; |
| } |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode)); |
| |
| if (ctx->Polygon.CullFlag) { |
| switch (ctx->Polygon.CullFaceMode) { |
| case GL_BACK: |
| if (ctx->Polygon.FrontFace == GL_CCW) |
| d3dCullMode = D3DCULL_CW; |
| else |
| d3dCullMode = D3DCULL_CCW; |
| break; |
| case GL_FRONT: |
| if (ctx->Polygon.FrontFace == GL_CCW) |
| d3dCullMode = D3DCULL_CCW; |
| else |
| d3dCullMode = D3DCULL_CW; |
| break; |
| case GL_FRONT_AND_BACK: |
| d3dCullMode = D3DCULL_NONE; |
| break; |
| default: |
| break; |
| } |
| } else { |
| d3dCullMode = D3DCULL_NONE; |
| } |
| // d3dCullMode = D3DCULL_NONE; // FOR DEBUGGING |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode)); |
| |
| // Polygon offset |
| // ZBIAS ranges from 0 to 16 and can only move towards the viewer |
| // Mesa5: ctx->Polygon._OffsetAny removed |
| if (ctx->Polygon.OffsetFill) { |
| fOffset = ctx->Polygon.OffsetUnits; |
| // if (iOffset < 0.0f) |
| // iOffset = -iOffset; |
| // else |
| // iOffset = 0.0f; // D3D can't push away |
| } |
| // NOTE: SetRenderState() required a DWORD, so need to cast |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DEPTHBIAS, *((DWORD*)&fOffset))); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_FOG( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| D3DCOLOR d3dFogColour; |
| D3DFOGMODE d3dFogMode = D3DFOG_LINEAR; |
| |
| // TODO: Fog is calculated seperately in the Mesa pipeline |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE)); |
| return; |
| |
| // Fog enable |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, ctx->Fog.Enabled)); |
| if (!ctx->Fog.Enabled) { |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, D3DFOG_NONE)); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); |
| return; // If disabled, don't bother setting any fog state |
| } |
| |
| // Fog colour |
| d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0], |
| ctx->Fog.Color[1], |
| ctx->Fog.Color[2], |
| ctx->Fog.Color[3]); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour)); |
| |
| // Fog density |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density)))); |
| |
| // Fog start |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start)))); |
| |
| // Fog end |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End)))); |
| |
| // Fog mode |
| switch (ctx->Fog.Mode) { |
| case GL_LINEAR: |
| d3dFogMode = D3DFOG_LINEAR; |
| break; |
| case GL_EXP: |
| d3dFogMode = D3DFOG_EXP; |
| break; |
| case GL_EXP2: |
| d3dFogMode = D3DFOG_EXP2; |
| break; |
| } |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode)); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_LIGHT( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| DWORD dwSpecularEnable; |
| |
| // Shademode |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT)); |
| |
| // Separate specular colour |
| if (ctx->Light.Enabled) |
| dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE; |
| else |
| dwSpecularEnable = FALSE; |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable)); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_MODELVIEW( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| D3DMATRIX m; |
| //GLfloat *pM = ctx->ModelView.m; |
| // Mesa5: Model-view is now a stack |
| GLfloat *pM = ctx->ModelviewMatrixStack.Top->m; |
| m._11 = pM[0]; |
| m._12 = pM[1]; |
| m._13 = pM[2]; |
| m._14 = pM[3]; |
| m._21 = pM[4]; |
| m._22 = pM[5]; |
| m._23 = pM[6]; |
| m._24 = pM[7]; |
| m._31 = pM[8]; |
| m._32 = pM[9]; |
| m._33 = pM[10]; |
| m._34 = pM[11]; |
| m._41 = pM[12]; |
| m._42 = pM[13]; |
| m._43 = pM[14]; |
| m._44 = pM[15]; |
| |
| gld->matModelView = m; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_PROJECTION( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| D3DMATRIX m; |
| //GLfloat *pM = ctx->ProjectionMatrix.m; |
| // Mesa 5: Now a stack |
| GLfloat *pM = ctx->ProjectionMatrixStack.Top->m; |
| m._11 = pM[0]; |
| m._12 = pM[1]; |
| m._13 = pM[2]; |
| m._14 = pM[3]; |
| |
| m._21 = pM[4]; |
| m._22 = pM[5]; |
| m._23 = pM[6]; |
| m._24 = pM[7]; |
| |
| m._31 = pM[8]; |
| m._32 = pM[9]; |
| m._33 = pM[10] / _fPersp_33; // / 1.6f; |
| m._34 = pM[11]; |
| |
| m._41 = pM[12]; |
| m._42 = pM[13]; |
| m._43 = pM[14] / 2.0f; |
| m._44 = pM[15]; |
| |
| gld->matProjection = m; |
| } |
| |
| //--------------------------------------------------------------------------- |
| /* |
| void gldFrustumHook_DX9( |
| GLdouble left, |
| GLdouble right, |
| GLdouble bottom, |
| GLdouble top, |
| GLdouble nearval, |
| GLdouble farval) |
| { |
| GET_CURRENT_CONTEXT(ctx); |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| // Pass values on to Mesa first (in case we mess with them) |
| _mesa_Frustum(left, right, bottom, top, nearval, farval); |
| |
| _fPersp_33 = farval / (nearval - farval); |
| |
| // ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gldOrthoHook_DX9( |
| GLdouble left, |
| GLdouble right, |
| GLdouble bottom, |
| GLdouble top, |
| GLdouble nearval, |
| GLdouble farval) |
| { |
| GET_CURRENT_CONTEXT(ctx); |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| // Pass values on to Mesa first (in case we mess with them) |
| _mesa_Ortho(left, right, bottom, top, nearval, farval); |
| |
| _fPersp_33 = 1.6f; |
| |
| // ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval); |
| } |
| */ |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_VIEWPORT( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| D3DVIEWPORT9 d3dvp; |
| // GLint x, y; |
| // GLsizei w, h; |
| |
| // Set depth range |
| _GLD_DX9_DEV(GetViewport(gld->pDev, &d3dvp)); |
| // D3D can't do Quake1/Quake2 z-trick |
| if (ctx->Viewport.Near <= ctx->Viewport.Far) { |
| d3dvp.MinZ = ctx->Viewport.Near; |
| d3dvp.MaxZ = ctx->Viewport.Far; |
| } else { |
| d3dvp.MinZ = ctx->Viewport.Far; |
| d3dvp.MaxZ = ctx->Viewport.Near; |
| } |
| /* x = ctx->Viewport.X; |
| y = ctx->Viewport.Y; |
| w = ctx->Viewport.Width; |
| h = ctx->Viewport.Height; |
| if (x < 0) x = 0; |
| if (y < 0) y = 0; |
| if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; |
| if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; |
| // Ditto for D3D viewport dimensions |
| if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; |
| if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; |
| d3dvp.X = x; |
| d3dvp.Y = gldCtx->dwHeight - (y + h); |
| d3dvp.Width = w; |
| d3dvp.Height = h;*/ |
| _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp)); |
| |
| // gld->fFlipWindowY = (float)gldCtx->dwHeight; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_NEW_SCISSOR( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| // Bail if IHV driver cannot scissor |
| if (!gld->bCanScissor) |
| return; |
| |
| // Set scissor rect |
| if (ctx->Scissor.Enabled) { |
| RECT rcRect; |
| // Keep in mind that RECT's need an extra row and column |
| rcRect.left = ctx->Scissor.X; |
| rcRect.right = ctx->Scissor.X + ctx->Scissor.Width; // + 1; |
| rcRect.top = gldCtx->dwHeight - (ctx->Scissor.Y + ctx->Scissor.Height); |
| rcRect.bottom = rcRect.top + ctx->Scissor.Height; |
| IDirect3DDevice9_SetScissorRect(gld->pDev, &rcRect); |
| } |
| |
| // Enable/disable scissor as required |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SCISSORTESTENABLE, ctx->Scissor.Enabled)); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| __inline BOOL _gldAnyEvalEnabled( |
| GLcontext *ctx) |
| { |
| struct gl_eval_attrib *eval = &ctx->Eval; |
| |
| if ((eval->AutoNormal) || |
| (eval->Map1Color4) || |
| (eval->Map1Index) || |
| (eval->Map1Normal) || |
| (eval->Map1TextureCoord1) || |
| (eval->Map1TextureCoord2) || |
| (eval->Map1TextureCoord3) || |
| (eval->Map1TextureCoord4) || |
| (eval->Map1Vertex3) || |
| (eval->Map1Vertex4) || |
| (eval->Map2Color4) || |
| (eval->Map2Index) || |
| (eval->Map2Normal) || |
| (eval->Map2TextureCoord1) || |
| (eval->Map2TextureCoord2) || |
| (eval->Map2TextureCoord3) || |
| (eval->Map2TextureCoord4) || |
| (eval->Map2Vertex3) || |
| (eval->Map2Vertex4) |
| ) |
| return TRUE; |
| |
| return FALSE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL _gldChooseInternalPipeline( |
| GLcontext *ctx, |
| GLD_driver_dx9 *gld) |
| { |
| // return TRUE; // DEBUGGING: ALWAYS USE MESA |
| // return FALSE; // DEBUGGING: ALWAYS USE D3D |
| |
| if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE)) |
| { |
| gld->PipelineUsage.qwMesa.QuadPart++; |
| return TRUE; // Force Mesa TnL |
| } |
| |
| if ((ctx->Light.Enabled) || |
| (1) || |
| (ctx->Texture._TexGenEnabled) || |
| (ctx->Texture._TexMatEnabled) || |
| // (ctx->Transform._AnyClip) || |
| (ctx->Scissor.Enabled) || |
| _gldAnyEvalEnabled(ctx) // Put this last so we can early-out |
| ) |
| { |
| gld->PipelineUsage.qwMesa.QuadPart++; |
| return TRUE; |
| } |
| |
| gld->PipelineUsage.qwD3DFVF.QuadPart++; |
| return FALSE; |
| |
| /* // Force Mesa pipeline? |
| if (glb.dwTnL == GLDS_TNL_MESA) { |
| gld->PipelineUsage.dwMesa.QuadPart++; |
| return GLD_PIPELINE_MESA; |
| } |
| |
| // Test for functionality not exposed in the D3D pathways |
| if ((ctx->Texture._GenFlags)) { |
| gld->PipelineUsage.dwMesa.QuadPart++; |
| return GLD_PIPELINE_MESA; |
| } |
| |
| // Now decide if vertex shader can be used. |
| // If two sided lighting is enabled then we must either |
| // use Mesa TnL or the vertex shader |
| if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { |
| if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) { |
| // Use Vertex Shader |
| gld->PipelineUsage.dwD3D2SVS.QuadPart++; |
| return GLD_PIPELINE_D3D_VS_TWOSIDE; |
| } else { |
| // Use Mesa TnL |
| gld->PipelineUsage.dwMesa.QuadPart++; |
| return GLD_PIPELINE_MESA; |
| } |
| } |
| |
| // Must be D3D fixed-function pipeline |
| gld->PipelineUsage.dwD3DFVF.QuadPart++; |
| return GLD_PIPELINE_D3D_FVF; |
| */ |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void gld_update_state_DX9( |
| GLcontext *ctx, |
| GLuint new_state) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| TNLcontext *tnl = TNL_CONTEXT(ctx); |
| GLD_pb_dx9 *gldPB; |
| |
| if (!gld || !gld->pDev) |
| return; |
| |
| _swsetup_InvalidateState( ctx, new_state ); |
| _vbo_InvalidateState( ctx, new_state ); |
| _tnl_InvalidateState( ctx, new_state ); |
| |
| // SetupIndex will be used in the pipelines for choosing setup function |
| if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) || |
| (ctx->Fog.Enabled)) |
| { |
| if (ctx->_TriangleCaps & DD_FLATSHADE) |
| gld->iSetupFunc = GLD_SI_FLAT_EXTRAS; |
| else |
| gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS; |
| } else { |
| if (ctx->_TriangleCaps & DD_FLATSHADE) |
| gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture |
| else |
| gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture |
| } |
| |
| gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld); |
| if (gld->bUseMesaTnL) { |
| gldPB = &gld->PB2d; |
| _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, TRUE)); |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, FALSE)); |
| _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL)); |
| _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF)); |
| } else { |
| gldPB = &gld->PB3d; |
| _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE)); |
| // if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) { |
| // _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware)); |
| // _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); |
| // } else { |
| // _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL)); |
| _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, !gld->bHasHWTnL)); |
| _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL)); |
| _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF)); |
| // } |
| } |
| |
| #define _GLD_TEST_STATE(a) \ |
| if (new_state & (a)) { \ |
| gld##a(ctx); \ |
| new_state &= ~(a); \ |
| } |
| |
| #define _GLD_TEST_STATE_DX9(a) \ |
| if (new_state & (a)) { \ |
| gld##a##_DX9(ctx); \ |
| new_state &= ~(a); \ |
| } |
| |
| #define _GLD_IGNORE_STATE(a) new_state &= ~(a); |
| |
| // if (!gld->bUseMesaTnL) { |
| // Not required if Mesa is doing the TnL. |
| // Problem: If gld->bUseMesaTnL is TRUE when these are signaled, |
| // then we'll miss updating the D3D TnL pipeline. |
| // Therefore, don't test for gld->bUseMesaTnL |
| _GLD_TEST_STATE(_NEW_MODELVIEW); |
| _GLD_TEST_STATE(_NEW_PROJECTION); |
| // } |
| |
| _GLD_TEST_STATE_DX9(_NEW_TEXTURE); // extern, so guard with _DX9 |
| _GLD_TEST_STATE(_NEW_COLOR); |
| _GLD_TEST_STATE(_NEW_DEPTH); |
| _GLD_TEST_STATE(_NEW_POLYGON); |
| _GLD_TEST_STATE(_NEW_STENCIL); |
| _GLD_TEST_STATE(_NEW_FOG); |
| _GLD_TEST_STATE(_NEW_LIGHT); |
| _GLD_TEST_STATE(_NEW_VIEWPORT); |
| |
| _GLD_IGNORE_STATE(_NEW_TRANSFORM); |
| |
| // Scissor Test: New for DX9 |
| _GLD_TEST_STATE(_NEW_SCISSOR); |
| |
| // Stubs for future use. |
| /* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX); |
| _GLD_TEST_STATE(_NEW_COLOR_MATRIX); |
| _GLD_TEST_STATE(_NEW_ACCUM); |
| _GLD_TEST_STATE(_NEW_EVAL); |
| _GLD_TEST_STATE(_NEW_HINT); |
| _GLD_TEST_STATE(_NEW_LINE); |
| _GLD_TEST_STATE(_NEW_PIXEL); |
| _GLD_TEST_STATE(_NEW_POINT); |
| _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE); |
| _GLD_TEST_STATE(_NEW_PACKUNPACK); |
| _GLD_TEST_STATE(_NEW_ARRAY); |
| _GLD_TEST_STATE(_NEW_RENDERMODE); |
| _GLD_TEST_STATE(_NEW_BUFFERS); |
| _GLD_TEST_STATE(_NEW_MULTISAMPLE); |
| */ |
| |
| // For debugging. |
| #if 0 |
| #define _GLD_TEST_UNHANDLED_STATE(a) \ |
| if (new_state & (a)) { \ |
| gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \ |
| } |
| _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_ACCUM); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_HINT); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_LINE); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_POINT); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE); |
| // _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS); |
| _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE); |
| #undef _GLD_UNHANDLED_STATE |
| #endif |
| |
| #undef _GLD_TEST_STATE |
| } |
| |
| //--------------------------------------------------------------------------- |
| // Viewport |
| //--------------------------------------------------------------------------- |
| |
| void gld_Viewport_DX9( |
| GLcontext *ctx, |
| GLint x, |
| GLint y, |
| GLsizei w, |
| GLsizei h) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| D3DVIEWPORT9 d3dvp; |
| |
| if (!gld || !gld->pDev) |
| return; |
| |
| // This is a hack. When the app is minimized, Mesa passes |
| // w=1 and h=1 for viewport dimensions. Without this test |
| // we get a GPF in gld_wgl_resize_buffers(). |
| if ((w==1) && (h==1)) |
| return; |
| |
| // Call ResizeBuffersMESA. This function will early-out |
| // if no resize is needed. |
| //ctx->Driver.ResizeBuffersMESA(ctx); |
| // Mesa 5: Changed parameters |
| ctx->Driver.ResizeBuffers(gldCtx->glBuffer); |
| |
| #if 0 |
| ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h); |
| #endif |
| |
| // ** D3D viewport must not be outside the render target surface ** |
| // Sanity check the GL viewport dimensions |
| if (x < 0) x = 0; |
| if (y < 0) y = 0; |
| if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; |
| if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; |
| // Ditto for D3D viewport dimensions |
| if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; |
| if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; |
| |
| d3dvp.X = x; |
| d3dvp.Y = gldCtx->dwHeight - (y + h); |
| d3dvp.Width = w; |
| d3dvp.Height = h; |
| if (ctx->Viewport.Near <= ctx->Viewport.Far) { |
| d3dvp.MinZ = ctx->Viewport.Near; |
| d3dvp.MaxZ = ctx->Viewport.Far; |
| } else { |
| d3dvp.MinZ = ctx->Viewport.Far; |
| d3dvp.MaxZ = ctx->Viewport.Near; |
| } |
| |
| // TODO: DEBUGGING |
| // d3dvp.MinZ = 0.0f; |
| // d3dvp.MaxZ = 1.0f; |
| |
| _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp)); |
| |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| extern BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); |
| |
| // Mesa 5: Parameter change |
| void gldResizeBuffers_DX9( |
| // GLcontext *ctx) |
| GLframebuffer *fb) |
| { |
| GET_CURRENT_CONTEXT(ctx); |
| dglWglResizeBuffers(ctx, TRUE); |
| } |
| |
| //--------------------------------------------------------------------------- |
| #ifdef _DEBUG |
| // This is only for debugging. |
| // To use, plug into ctx->Driver.Enable pointer below. |
| void gld_Enable( |
| GLcontext *ctx, |
| GLenum e, |
| GLboolean b) |
| { |
| char buf[1024]; |
| sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE"); |
| ddlogMessage(DDLOG_SYSTEM, buf); |
| } |
| #endif |
| //--------------------------------------------------------------------------- |
| // Driver pointer setup |
| //--------------------------------------------------------------------------- |
| |
| extern const GLubyte* _gldGetStringGeneric(GLcontext*, GLenum); |
| |
| void gldSetupDriverPointers_DX9( |
| GLcontext *ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); |
| |
| TNLcontext *tnl = TNL_CONTEXT(ctx); |
| |
| // Mandatory functions |
| ctx->Driver.GetString = _gldGetStringGeneric; |
| ctx->Driver.UpdateState = gld_update_state_DX9; |
| ctx->Driver.Clear = gld_Clear_DX9; |
| ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX9; |
| ctx->Driver.GetBufferSize = gld_buffer_size_DX9; |
| ctx->Driver.Finish = gld_Finish_DX9; |
| ctx->Driver.Flush = gld_Flush_DX9; |
| ctx->Driver.Error = gld_Error_DX9; |
| |
| // Hardware accumulation buffer |
| ctx->Driver.Accum = NULL; // TODO: gld_Accum; |
| |
| // Bitmap functions |
| ctx->Driver.CopyPixels = gld_CopyPixels_DX9; |
| ctx->Driver.DrawPixels = gld_DrawPixels_DX9; |
| ctx->Driver.ReadPixels = gld_ReadPixels_DX9; |
| ctx->Driver.Bitmap = gld_Bitmap_DX9; |
| |
| // Buffer resize |
| ctx->Driver.ResizeBuffers = gldResizeBuffers_DX9; |
| |
| // Texture image functions |
| ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX9; |
| ctx->Driver.TexImage1D = gld_TexImage1D_DX9; |
| ctx->Driver.TexImage2D = gld_TexImage2D_DX9; |
| ctx->Driver.TexImage3D = _mesa_store_teximage3d; |
| ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX9; |
| ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX9; |
| ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; |
| |
| ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX9; //NULL; |
| ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX9; //NULL; |
| ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX9; //NULL; |
| ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX9; //NULL; |
| ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX9; |
| ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; |
| |
| // Texture object functions |
| ctx->Driver.BindTexture = NULL; |
| ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!; |
| ctx->Driver.DeleteTexture = gld_DeleteTexture_DX9; |
| ctx->Driver.PrioritizeTexture = NULL; |
| |
| // Imaging functionality |
| ctx->Driver.CopyColorTable = NULL; |
| ctx->Driver.CopyColorSubTable = NULL; |
| ctx->Driver.CopyConvolutionFilter1D = NULL; |
| ctx->Driver.CopyConvolutionFilter2D = NULL; |
| |
| // State changing functions |
| ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc; |
| ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc; |
| ctx->Driver.ClearColor = NULL; //gld_ClearColor; |
| ctx->Driver.ClearDepth = NULL; //gld_ClearDepth; |
| ctx->Driver.ClearStencil = NULL; //gld_ClearStencil; |
| ctx->Driver.ColorMask = NULL; //gld_ColorMask; |
| ctx->Driver.CullFace = NULL; //gld_CullFace; |
| ctx->Driver.ClipPlane = NULL; //gld_ClipPlane; |
| ctx->Driver.FrontFace = NULL; //gld_FrontFace; |
| ctx->Driver.DepthFunc = NULL; //gld_DepthFunc; |
| ctx->Driver.DepthMask = NULL; //gld_DepthMask; |
| ctx->Driver.DepthRange = NULL; |
| ctx->Driver.Enable = NULL; //gld_Enable; |
| ctx->Driver.Fogfv = NULL; //gld_Fogfv; |
| ctx->Driver.Hint = NULL; //gld_Hint; |
| ctx->Driver.Lightfv = NULL; //gld_Lightfv; |
| ctx->Driver.LightModelfv = NULL; //gld_LightModelfv; |
| ctx->Driver.LineStipple = NULL; //gld_LineStipple; |
| ctx->Driver.LineWidth = NULL; //gld_LineWidth; |
| ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode; |
| ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv; |
| ctx->Driver.PointSize = NULL; //gld_PointSize; |
| ctx->Driver.PolygonMode = NULL; //gld_PolygonMode; |
| ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset; |
| ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple; |
| ctx->Driver.RenderMode = NULL; //gld_RenderMode; |
| ctx->Driver.Scissor = NULL; //gld_Scissor; |
| ctx->Driver.ShadeModel = NULL; //gld_ShadeModel; |
| ctx->Driver.StencilFunc = NULL; //gld_StencilFunc; |
| ctx->Driver.StencilMask = NULL; //gld_StencilMask; |
| ctx->Driver.StencilOp = NULL; //gld_StencilOp; |
| ctx->Driver.TexGen = NULL; //gld_TexGen; |
| ctx->Driver.TexEnv = NULL; |
| ctx->Driver.TexParameter = NULL; |
| ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix; |
| ctx->Driver.Viewport = gld_Viewport_DX9; |
| |
| _swsetup_Wakeup(ctx); |
| |
| tnl->Driver.RunPipeline = _tnl_run_pipeline; |
| tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX9; |
| tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; |
| tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; |
| |
| // Hook into glFrustum() and glOrtho() |
| // ctx->Exec->Frustum = gldFrustumHook_DX9; |
| // ctx->Exec->Ortho = gldOrthoHook_DX9; |
| |
| } |
| |
| //--------------------------------------------------------------------------- |