1
/****************************************************************************
3
* Mesa 3-D graphics library
4
* Direct3D Driver Interface
6
* ========================================================================
8
* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
10
* Permission is hereby granted, free of charge, to any person obtaining a
11
* copy of this software and associated documentation files (the "Software"),
12
* to deal in the Software without restriction, including without limitation
13
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
14
* and/or sell copies of the Software, and to permit persons to whom the
15
* Software is furnished to do so, subject to the following conditions:
17
* The above copyright notice and this permission notice shall be included
18
* in all copies or substantial portions of the Software.
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
* ======================================================================
31
* Environment: Windows 9x/2000/XP/XBox (Win32)
33
* Description: Driver interface code to Mesa
35
****************************************************************************/
37
//#include <windows.h>
38
#include "dglcontext.h"
46
#include "extensions.h"
52
#include "texformat.h"
56
#include "swrast_setup/swrast_setup.h"
57
#include "swrast_setup/ss_context.h"
59
#include "tnl/t_context.h"
60
#include "tnl/t_pipeline.h"
62
extern BOOL dglSwapBuffers(HDC hDC);
64
// HACK: Hack the _33 member of the OpenGL perspective projection matrix
65
const float _fPersp_33 = 1.6f;
67
//---------------------------------------------------------------------------
69
//---------------------------------------------------------------------------
71
void _gld_mesa_warning(
75
// Intercept Mesa's internal warning mechanism
76
gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str);
79
//---------------------------------------------------------------------------
85
// Intercept Mesa's internal fatal-message mechanism
86
gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str);
88
// Mesa calls abort(0) here.
93
//---------------------------------------------------------------------------
95
D3DSTENCILOP _gldConvertStencilOp(
98
// Used by Stencil: pass, fail and zfail
102
return D3DSTENCILOP_KEEP;
104
return D3DSTENCILOP_ZERO;
106
return D3DSTENCILOP_REPLACE;
108
return D3DSTENCILOP_INCRSAT;
110
return D3DSTENCILOP_DECRSAT;
112
return D3DSTENCILOP_INVERT;
113
case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap
114
return D3DSTENCILOP_INCR;
115
case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap
116
return D3DSTENCILOP_DECR;
120
gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n");
123
return D3DSTENCILOP_KEEP;
126
//---------------------------------------------------------------------------
128
D3DCMPFUNC _gldConvertCompareFunc(
131
// Used for Alpha func, depth func and stencil func.
141
return D3DCMP_LESSEQUAL;
143
return D3DCMP_GREATER;
145
return D3DCMP_NOTEQUAL;
147
return D3DCMP_GREATEREQUAL;
149
return D3DCMP_ALWAYS;
153
gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n");
156
return D3DCMP_ALWAYS;
159
//---------------------------------------------------------------------------
161
D3DBLEND _gldConvertBlendFunc(
167
return D3DBLEND_ZERO;
171
return D3DBLEND_DESTCOLOR;
173
return D3DBLEND_SRCCOLOR;
174
case GL_ONE_MINUS_DST_COLOR:
175
return D3DBLEND_INVDESTCOLOR;
176
case GL_ONE_MINUS_SRC_COLOR:
177
return D3DBLEND_INVSRCCOLOR;
179
return D3DBLEND_SRCALPHA;
180
case GL_ONE_MINUS_SRC_ALPHA:
181
return D3DBLEND_INVSRCALPHA;
183
return D3DBLEND_DESTALPHA;
184
case GL_ONE_MINUS_DST_ALPHA:
185
return D3DBLEND_INVDESTALPHA;
186
case GL_SRC_ALPHA_SATURATE:
187
return D3DBLEND_SRCALPHASAT;
191
gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n");
197
//---------------------------------------------------------------------------
199
//---------------------------------------------------------------------------
205
gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n");
209
//---------------------------------------------------------------------------
216
// gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n");
220
//---------------------------------------------------------------------------
221
// Required Mesa functions
222
//---------------------------------------------------------------------------
224
static GLboolean gld_set_draw_buffer_DX9(
229
if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) {
237
//---------------------------------------------------------------------------
239
static void gld_set_read_buffer_DX9(
241
GLframebuffer *buffer,
244
/* separate read buffer not supported */
246
ASSERT(buffer == ctx->DrawBuffer);
247
ASSERT(mode == GL_FRONT_LEFT);
251
//---------------------------------------------------------------------------
262
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
263
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
269
D3DRECT d3dClearRect;
272
const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
277
if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
279
CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]);
280
CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]);
281
CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]);
282
CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]);
283
dwFlags |= D3DCLEAR_TARGET;
284
Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]);
287
if (mask & DD_DEPTH_BIT) {
288
// D3D8 will fail the Clear call if we try and clear a
289
// depth buffer and we haven't created one.
290
// Also, some apps try and clear a depth buffer,
291
// when a depth buffer hasn't been requested by the app.
292
if (ctx->Visual.depthBits == 0) {
293
mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask
295
dwFlags |= D3DCLEAR_ZBUFFER;
296
Z = ctx->Depth.Clear;
300
if (mask & DD_STENCIL_BIT) {
301
if (ctx->Visual.stencilBits == 0) {
302
// No stencil bits in depth buffer
303
mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask
305
dwFlags |= D3DCLEAR_STENCIL;
306
Stencil = ctx->Stencil.Clear;
310
// Some apps do really weird things with the rect, such as Quake3.
311
if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) {
316
// Calculate clear subrect
318
d3dClearRect.y1 = gldCtx->dwHeight - (y + height);
319
d3dClearRect.x2 = x + width;
320
d3dClearRect.y2 = d3dClearRect.y1 + height;
321
// gldLogPrintf(GLDLOG_INFO, "Rect %d,%d %d,%d", x,y,width,height);
324
// dwFlags will be zero if there's nothing to clear
329
all ? NULL : &d3dClearRect,
334
if (mask & DD_ACCUM_BIT) {
335
// Clear accumulation buffer
339
//---------------------------------------------------------------------------
341
// Mesa 5: Parameter change
342
static void gld_buffer_size_DX9(
348
// GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
350
*width = fb->Width; // gldCtx->dwWidth;
351
*height = fb->Height; // gldCtx->dwHeight;
354
//---------------------------------------------------------------------------
356
static void gld_Finish_DX9(
361
//---------------------------------------------------------------------------
363
static void gld_Flush_DX9(
366
GLD_context *gld = GLD_GET_CONTEXT(ctx);
368
// TODO: Detect apps that glFlush() then SwapBuffers() ?
370
if (gld->EmulateSingle) {
371
// Emulating a single-buffered context.
372
// [Direct3D doesn't allow rendering to front buffer]
373
dglSwapBuffers(gld->hDC);
377
//---------------------------------------------------------------------------
379
void gld_NEW_STENCIL(
382
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
383
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
385
// Two-sided stencil. New for Mesa 5
386
const GLuint uiFace = 0UL;
388
struct gl_stencil_attrib *pStencil = &ctx->Stencil;
390
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE));
391
if (pStencil->Enabled) {
392
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace])));
393
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILREF, pStencil->Ref[uiFace]));
394
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILMASK, pStencil->ValueMask[uiFace]));
395
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILWRITEMASK, pStencil->WriteMask[uiFace]));
396
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace])));
397
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace])));
398
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace])));
402
//---------------------------------------------------------------------------
407
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
408
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
415
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc)));
416
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAREF, (DWORD)ctx->Color.AlphaRef));
417
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, ctx->Color.AlphaEnabled));
420
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHABLENDENABLE, ctx->Color.BlendEnabled));
421
src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE);
422
dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO);
423
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SRCBLEND, src));
424
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest));
427
if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
428
if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
429
if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
430
if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
431
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags));
434
//---------------------------------------------------------------------------
439
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
440
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
442
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE));
443
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func)));
444
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE));
447
//---------------------------------------------------------------------------
449
void gld_NEW_POLYGON(
452
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
453
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
455
D3DFILLMODE d3dFillMode = D3DFILL_SOLID;
456
D3DCULL d3dCullMode = D3DCULL_NONE;
457
float fOffset = 0; // Changed from int to float for DX9
460
switch (ctx->Polygon.FrontMode) {
462
d3dFillMode = D3DFILL_POINT;
465
d3dFillMode = D3DFILL_WIREFRAME;
468
d3dFillMode = D3DFILL_SOLID;
471
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode));
473
if (ctx->Polygon.CullFlag) {
474
switch (ctx->Polygon.CullFaceMode) {
476
if (ctx->Polygon.FrontFace == GL_CCW)
477
d3dCullMode = D3DCULL_CW;
479
d3dCullMode = D3DCULL_CCW;
482
if (ctx->Polygon.FrontFace == GL_CCW)
483
d3dCullMode = D3DCULL_CCW;
485
d3dCullMode = D3DCULL_CW;
487
case GL_FRONT_AND_BACK:
488
d3dCullMode = D3DCULL_NONE;
494
d3dCullMode = D3DCULL_NONE;
496
// d3dCullMode = D3DCULL_NONE; // FOR DEBUGGING
497
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode));
500
// ZBIAS ranges from 0 to 16 and can only move towards the viewer
501
// Mesa5: ctx->Polygon._OffsetAny removed
502
if (ctx->Polygon.OffsetFill) {
503
fOffset = ctx->Polygon.OffsetUnits;
504
// if (iOffset < 0.0f)
505
// iOffset = -iOffset;
507
// iOffset = 0.0f; // D3D can't push away
509
// NOTE: SetRenderState() required a DWORD, so need to cast
510
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DEPTHBIAS, *((DWORD*)&fOffset)));
513
//---------------------------------------------------------------------------
518
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
519
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
521
D3DCOLOR d3dFogColour;
522
D3DFOGMODE d3dFogMode = D3DFOG_LINEAR;
524
// TODO: Fog is calculated seperately in the Mesa pipeline
525
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE));
529
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, ctx->Fog.Enabled));
530
if (!ctx->Fog.Enabled) {
531
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, D3DFOG_NONE));
532
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
533
return; // If disabled, don't bother setting any fog state
537
d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0],
541
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour));
544
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density))));
547
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start))));
550
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End))));
553
switch (ctx->Fog.Mode) {
555
d3dFogMode = D3DFOG_LINEAR;
558
d3dFogMode = D3DFOG_EXP;
561
d3dFogMode = D3DFOG_EXP2;
564
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode));
565
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
568
//---------------------------------------------------------------------------
573
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
574
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
575
DWORD dwSpecularEnable;
578
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT));
580
// Separate specular colour
581
if (ctx->Light.Enabled)
582
dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE;
584
dwSpecularEnable = FALSE;
585
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable));
588
//---------------------------------------------------------------------------
590
void gld_NEW_MODELVIEW(
593
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
594
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
597
//GLfloat *pM = ctx->ModelView.m;
598
// Mesa5: Model-view is now a stack
599
GLfloat *pM = ctx->ModelviewMatrixStack.Top->m;
617
gld->matModelView = m;
620
//---------------------------------------------------------------------------
622
void gld_NEW_PROJECTION(
625
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
626
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
629
//GLfloat *pM = ctx->ProjectionMatrix.m;
630
// Mesa 5: Now a stack
631
GLfloat *pM = ctx->ProjectionMatrixStack.Top->m;
644
m._33 = pM[10] / _fPersp_33; // / 1.6f;
649
m._43 = pM[14] / 2.0f;
652
gld->matProjection = m;
655
//---------------------------------------------------------------------------
657
void gldFrustumHook_DX9(
665
GET_CURRENT_CONTEXT(ctx);
666
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
667
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
669
// Pass values on to Mesa first (in case we mess with them)
670
_mesa_Frustum(left, right, bottom, top, nearval, farval);
672
_fPersp_33 = farval / (nearval - farval);
674
// ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval);
677
//---------------------------------------------------------------------------
679
void gldOrthoHook_DX9(
687
GET_CURRENT_CONTEXT(ctx);
688
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
689
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
691
// Pass values on to Mesa first (in case we mess with them)
692
_mesa_Ortho(left, right, bottom, top, nearval, farval);
696
// ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval);
699
//---------------------------------------------------------------------------
701
void gld_NEW_VIEWPORT(
704
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
705
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
712
_GLD_DX9_DEV(GetViewport(gld->pDev, &d3dvp));
713
// D3D can't do Quake1/Quake2 z-trick
714
if (ctx->Viewport.Near <= ctx->Viewport.Far) {
715
d3dvp.MinZ = ctx->Viewport.Near;
716
d3dvp.MaxZ = ctx->Viewport.Far;
718
d3dvp.MinZ = ctx->Viewport.Far;
719
d3dvp.MaxZ = ctx->Viewport.Near;
721
/* x = ctx->Viewport.X;
723
w = ctx->Viewport.Width;
724
h = ctx->Viewport.Height;
727
if (w > gldCtx->dwWidth) w = gldCtx->dwWidth;
728
if (h > gldCtx->dwHeight) h = gldCtx->dwHeight;
729
// Ditto for D3D viewport dimensions
730
if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x;
731
if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y;
733
d3dvp.Y = gldCtx->dwHeight - (y + h);
736
_GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
738
// gld->fFlipWindowY = (float)gldCtx->dwHeight;
741
//---------------------------------------------------------------------------
743
void gld_NEW_SCISSOR(
746
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
747
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
749
// Bail if IHV driver cannot scissor
750
if (!gld->bCanScissor)
754
if (ctx->Scissor.Enabled) {
756
// Keep in mind that RECT's need an extra row and column
757
rcRect.left = ctx->Scissor.X;
758
rcRect.right = ctx->Scissor.X + ctx->Scissor.Width; // + 1;
759
rcRect.top = gldCtx->dwHeight - (ctx->Scissor.Y + ctx->Scissor.Height);
760
rcRect.bottom = rcRect.top + ctx->Scissor.Height;
761
IDirect3DDevice9_SetScissorRect(gld->pDev, &rcRect);
764
// Enable/disable scissor as required
765
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SCISSORTESTENABLE, ctx->Scissor.Enabled));
768
//---------------------------------------------------------------------------
770
__inline BOOL _gldAnyEvalEnabled(
773
struct gl_eval_attrib *eval = &ctx->Eval;
775
if ((eval->AutoNormal) ||
776
(eval->Map1Color4) ||
778
(eval->Map1Normal) ||
779
(eval->Map1TextureCoord1) ||
780
(eval->Map1TextureCoord2) ||
781
(eval->Map1TextureCoord3) ||
782
(eval->Map1TextureCoord4) ||
783
(eval->Map1Vertex3) ||
784
(eval->Map1Vertex4) ||
785
(eval->Map2Color4) ||
787
(eval->Map2Normal) ||
788
(eval->Map2TextureCoord1) ||
789
(eval->Map2TextureCoord2) ||
790
(eval->Map2TextureCoord3) ||
791
(eval->Map2TextureCoord4) ||
792
(eval->Map2Vertex3) ||
800
//---------------------------------------------------------------------------
802
BOOL _gldChooseInternalPipeline(
806
// return TRUE; // DEBUGGING: ALWAYS USE MESA
807
// return FALSE; // DEBUGGING: ALWAYS USE D3D
809
if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE))
811
gld->PipelineUsage.qwMesa.QuadPart++;
812
return TRUE; // Force Mesa TnL
815
if ((ctx->Light.Enabled) ||
817
(ctx->Texture._TexGenEnabled) ||
818
(ctx->Texture._TexMatEnabled) ||
819
// (ctx->Transform._AnyClip) ||
820
(ctx->Scissor.Enabled) ||
821
_gldAnyEvalEnabled(ctx) // Put this last so we can early-out
824
gld->PipelineUsage.qwMesa.QuadPart++;
828
gld->PipelineUsage.qwD3DFVF.QuadPart++;
831
/* // Force Mesa pipeline?
832
if (glb.dwTnL == GLDS_TNL_MESA) {
833
gld->PipelineUsage.dwMesa.QuadPart++;
834
return GLD_PIPELINE_MESA;
837
// Test for functionality not exposed in the D3D pathways
838
if ((ctx->Texture._GenFlags)) {
839
gld->PipelineUsage.dwMesa.QuadPart++;
840
return GLD_PIPELINE_MESA;
843
// Now decide if vertex shader can be used.
844
// If two sided lighting is enabled then we must either
845
// use Mesa TnL or the vertex shader
846
if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
847
if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) {
849
gld->PipelineUsage.dwD3D2SVS.QuadPart++;
850
return GLD_PIPELINE_D3D_VS_TWOSIDE;
853
gld->PipelineUsage.dwMesa.QuadPart++;
854
return GLD_PIPELINE_MESA;
858
// Must be D3D fixed-function pipeline
859
gld->PipelineUsage.dwD3DFVF.QuadPart++;
860
return GLD_PIPELINE_D3D_FVF;
864
//---------------------------------------------------------------------------
866
void gld_update_state_DX9(
870
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
871
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
872
TNLcontext *tnl = TNL_CONTEXT(ctx);
875
if (!gld || !gld->pDev)
878
_swsetup_InvalidateState( ctx, new_state );
879
_vbo_InvalidateState( ctx, new_state );
880
_tnl_InvalidateState( ctx, new_state );
882
// SetupIndex will be used in the pipelines for choosing setup function
883
if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) ||
886
if (ctx->_TriangleCaps & DD_FLATSHADE)
887
gld->iSetupFunc = GLD_SI_FLAT_EXTRAS;
889
gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS;
891
if (ctx->_TriangleCaps & DD_FLATSHADE)
892
gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture
894
gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture
897
gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld);
898
if (gld->bUseMesaTnL) {
900
_GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, TRUE));
901
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, FALSE));
902
_GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
903
_GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
906
_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE));
907
// if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) {
908
// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware));
909
// _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader));
911
// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL));
912
_GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, !gld->bHasHWTnL));
913
_GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL));
914
_GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF));
918
#define _GLD_TEST_STATE(a) \
919
if (new_state & (a)) { \
924
#define _GLD_TEST_STATE_DX9(a) \
925
if (new_state & (a)) { \
930
#define _GLD_IGNORE_STATE(a) new_state &= ~(a);
932
// if (!gld->bUseMesaTnL) {
933
// Not required if Mesa is doing the TnL.
934
// Problem: If gld->bUseMesaTnL is TRUE when these are signaled,
935
// then we'll miss updating the D3D TnL pipeline.
936
// Therefore, don't test for gld->bUseMesaTnL
937
_GLD_TEST_STATE(_NEW_MODELVIEW);
938
_GLD_TEST_STATE(_NEW_PROJECTION);
941
_GLD_TEST_STATE_DX9(_NEW_TEXTURE); // extern, so guard with _DX9
942
_GLD_TEST_STATE(_NEW_COLOR);
943
_GLD_TEST_STATE(_NEW_DEPTH);
944
_GLD_TEST_STATE(_NEW_POLYGON);
945
_GLD_TEST_STATE(_NEW_STENCIL);
946
_GLD_TEST_STATE(_NEW_FOG);
947
_GLD_TEST_STATE(_NEW_LIGHT);
948
_GLD_TEST_STATE(_NEW_VIEWPORT);
950
_GLD_IGNORE_STATE(_NEW_TRANSFORM);
952
// Scissor Test: New for DX9
953
_GLD_TEST_STATE(_NEW_SCISSOR);
955
// Stubs for future use.
956
/* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX);
957
_GLD_TEST_STATE(_NEW_COLOR_MATRIX);
958
_GLD_TEST_STATE(_NEW_ACCUM);
959
_GLD_TEST_STATE(_NEW_EVAL);
960
_GLD_TEST_STATE(_NEW_HINT);
961
_GLD_TEST_STATE(_NEW_LINE);
962
_GLD_TEST_STATE(_NEW_PIXEL);
963
_GLD_TEST_STATE(_NEW_POINT);
964
_GLD_TEST_STATE(_NEW_POLYGONSTIPPLE);
965
_GLD_TEST_STATE(_NEW_PACKUNPACK);
966
_GLD_TEST_STATE(_NEW_ARRAY);
967
_GLD_TEST_STATE(_NEW_RENDERMODE);
968
_GLD_TEST_STATE(_NEW_BUFFERS);
969
_GLD_TEST_STATE(_NEW_MULTISAMPLE);
974
#define _GLD_TEST_UNHANDLED_STATE(a) \
975
if (new_state & (a)) { \
976
gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \
978
_GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX);
979
_GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX);
980
_GLD_TEST_UNHANDLED_STATE(_NEW_ACCUM);
981
_GLD_TEST_UNHANDLED_STATE(_NEW_EVAL);
982
_GLD_TEST_UNHANDLED_STATE(_NEW_HINT);
983
_GLD_TEST_UNHANDLED_STATE(_NEW_LINE);
984
_GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL);
985
_GLD_TEST_UNHANDLED_STATE(_NEW_POINT);
986
_GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE);
987
// _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR);
988
_GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK);
989
_GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY);
990
_GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE);
991
_GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS);
992
_GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE);
993
#undef _GLD_UNHANDLED_STATE
996
#undef _GLD_TEST_STATE
999
//---------------------------------------------------------------------------
1001
//---------------------------------------------------------------------------
1003
void gld_Viewport_DX9(
1010
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1011
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
1015
if (!gld || !gld->pDev)
1018
// This is a hack. When the app is minimized, Mesa passes
1019
// w=1 and h=1 for viewport dimensions. Without this test
1020
// we get a GPF in gld_wgl_resize_buffers().
1021
if ((w==1) && (h==1))
1024
// Call ResizeBuffersMESA. This function will early-out
1025
// if no resize is needed.
1026
//ctx->Driver.ResizeBuffersMESA(ctx);
1027
// Mesa 5: Changed parameters
1028
ctx->Driver.ResizeBuffers(gldCtx->glBuffer);
1031
ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h);
1034
// ** D3D viewport must not be outside the render target surface **
1035
// Sanity check the GL viewport dimensions
1038
if (w > gldCtx->dwWidth) w = gldCtx->dwWidth;
1039
if (h > gldCtx->dwHeight) h = gldCtx->dwHeight;
1040
// Ditto for D3D viewport dimensions
1041
if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x;
1042
if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y;
1045
d3dvp.Y = gldCtx->dwHeight - (y + h);
1048
if (ctx->Viewport.Near <= ctx->Viewport.Far) {
1049
d3dvp.MinZ = ctx->Viewport.Near;
1050
d3dvp.MaxZ = ctx->Viewport.Far;
1052
d3dvp.MinZ = ctx->Viewport.Far;
1053
d3dvp.MaxZ = ctx->Viewport.Near;
1057
// d3dvp.MinZ = 0.0f;
1058
// d3dvp.MaxZ = 1.0f;
1060
_GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
1064
//---------------------------------------------------------------------------
1066
extern BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver);
1068
// Mesa 5: Parameter change
1069
void gldResizeBuffers_DX9(
1073
GET_CURRENT_CONTEXT(ctx);
1074
dglWglResizeBuffers(ctx, TRUE);
1077
//---------------------------------------------------------------------------
1079
// This is only for debugging.
1080
// To use, plug into ctx->Driver.Enable pointer below.
1087
sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE");
1088
ddlogMessage(DDLOG_SYSTEM, buf);
1091
//---------------------------------------------------------------------------
1092
// Driver pointer setup
1093
//---------------------------------------------------------------------------
1095
extern const GLubyte* _gldGetStringGeneric(GLcontext*, GLenum);
1097
void gldSetupDriverPointers_DX9(
1100
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1101
GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx);
1103
TNLcontext *tnl = TNL_CONTEXT(ctx);
1105
// Mandatory functions
1106
ctx->Driver.GetString = _gldGetStringGeneric;
1107
ctx->Driver.UpdateState = gld_update_state_DX9;
1108
ctx->Driver.Clear = gld_Clear_DX9;
1109
ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX9;
1110
ctx->Driver.GetBufferSize = gld_buffer_size_DX9;
1111
ctx->Driver.Finish = gld_Finish_DX9;
1112
ctx->Driver.Flush = gld_Flush_DX9;
1113
ctx->Driver.Error = gld_Error_DX9;
1115
// Hardware accumulation buffer
1116
ctx->Driver.Accum = NULL; // TODO: gld_Accum;
1119
ctx->Driver.CopyPixels = gld_CopyPixels_DX9;
1120
ctx->Driver.DrawPixels = gld_DrawPixels_DX9;
1121
ctx->Driver.ReadPixels = gld_ReadPixels_DX9;
1122
ctx->Driver.Bitmap = gld_Bitmap_DX9;
1125
ctx->Driver.ResizeBuffers = gldResizeBuffers_DX9;
1127
// Texture image functions
1128
ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX9;
1129
ctx->Driver.TexImage1D = gld_TexImage1D_DX9;
1130
ctx->Driver.TexImage2D = gld_TexImage2D_DX9;
1131
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1132
ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX9;
1133
ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX9;
1134
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1136
ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX9; //NULL;
1137
ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX9; //NULL;
1138
ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX9; //NULL;
1139
ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX9; //NULL;
1140
ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX9;
1141
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1143
// Texture object functions
1144
ctx->Driver.BindTexture = NULL;
1145
ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!;
1146
ctx->Driver.DeleteTexture = gld_DeleteTexture_DX9;
1147
ctx->Driver.PrioritizeTexture = NULL;
1149
// Imaging functionality
1150
ctx->Driver.CopyColorTable = NULL;
1151
ctx->Driver.CopyColorSubTable = NULL;
1152
ctx->Driver.CopyConvolutionFilter1D = NULL;
1153
ctx->Driver.CopyConvolutionFilter2D = NULL;
1155
// State changing functions
1156
ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc;
1157
ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc;
1158
ctx->Driver.ClearColor = NULL; //gld_ClearColor;
1159
ctx->Driver.ClearDepth = NULL; //gld_ClearDepth;
1160
ctx->Driver.ClearStencil = NULL; //gld_ClearStencil;
1161
ctx->Driver.ColorMask = NULL; //gld_ColorMask;
1162
ctx->Driver.CullFace = NULL; //gld_CullFace;
1163
ctx->Driver.ClipPlane = NULL; //gld_ClipPlane;
1164
ctx->Driver.FrontFace = NULL; //gld_FrontFace;
1165
ctx->Driver.DepthFunc = NULL; //gld_DepthFunc;
1166
ctx->Driver.DepthMask = NULL; //gld_DepthMask;
1167
ctx->Driver.DepthRange = NULL;
1168
ctx->Driver.Enable = NULL; //gld_Enable;
1169
ctx->Driver.Fogfv = NULL; //gld_Fogfv;
1170
ctx->Driver.Hint = NULL; //gld_Hint;
1171
ctx->Driver.Lightfv = NULL; //gld_Lightfv;
1172
ctx->Driver.LightModelfv = NULL; //gld_LightModelfv;
1173
ctx->Driver.LineStipple = NULL; //gld_LineStipple;
1174
ctx->Driver.LineWidth = NULL; //gld_LineWidth;
1175
ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode;
1176
ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv;
1177
ctx->Driver.PointSize = NULL; //gld_PointSize;
1178
ctx->Driver.PolygonMode = NULL; //gld_PolygonMode;
1179
ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset;
1180
ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple;
1181
ctx->Driver.RenderMode = NULL; //gld_RenderMode;
1182
ctx->Driver.Scissor = NULL; //gld_Scissor;
1183
ctx->Driver.ShadeModel = NULL; //gld_ShadeModel;
1184
ctx->Driver.StencilFunc = NULL; //gld_StencilFunc;
1185
ctx->Driver.StencilMask = NULL; //gld_StencilMask;
1186
ctx->Driver.StencilOp = NULL; //gld_StencilOp;
1187
ctx->Driver.TexGen = NULL; //gld_TexGen;
1188
ctx->Driver.TexEnv = NULL;
1189
ctx->Driver.TexParameter = NULL;
1190
ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix;
1191
ctx->Driver.Viewport = gld_Viewport_DX9;
1193
_swsetup_Wakeup(ctx);
1195
tnl->Driver.RunPipeline = _tnl_run_pipeline;
1196
tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX9;
1197
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
1198
tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
1200
// Hook into glFrustum() and glOrtho()
1201
// ctx->Exec->Frustum = gldFrustumHook_DX9;
1202
// ctx->Exec->Ortho = gldOrthoHook_DX9;
1206
//---------------------------------------------------------------------------