~ubuntu-branches/ubuntu/jaunty/mesa/jaunty

« back to all changes in this revision

Viewing changes to src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2009-01-23 10:20:24 UTC
  • mfrom: (1.2.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20090123102024-1f3kmb3aea7wzk67
Tags: 7.3~rc3-1ubuntu1
* Merge with Debian experimental.
* Drop 102_dont_vblank.patch, since the new drm code in the kernel
  fixes the bugs that it worked around.
* Bump the build-dependency of libdrm to 2.4.4. It's the first version
  with necessary changes to build this.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
*
3
 
*                        Mesa 3-D graphics library
4
 
*                        Direct3D Driver Interface
5
 
*
6
 
*  ========================================================================
7
 
*
8
 
*   Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
9
 
*
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:
16
 
*
17
 
*   The above copyright notice and this permission notice shall be included
18
 
*   in all copies or substantial portions of the Software.
19
 
*
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
26
 
*   SOFTWARE.
27
 
*
28
 
*  ======================================================================
29
 
*
30
 
* Language:     ANSI C
31
 
* Environment:  Windows 9x/2000/XP/XBox (Win32)
32
 
*
33
 
* Description:  Driver interface code to Mesa
34
 
*
35
 
****************************************************************************/
36
 
 
37
 
//#include <windows.h>
38
 
#include "dglcontext.h"
39
 
#include "ddlog.h"
40
 
#include "gld_dx9.h"
41
 
 
42
 
#include "glheader.h"
43
 
#include "context.h"
44
 
#include "colormac.h"
45
 
#include "depth.h"
46
 
#include "extensions.h"
47
 
#include "macros.h"
48
 
#include "matrix.h"
49
 
// #include "mem.h"
50
 
//#include "mmath.h"
51
 
#include "mtypes.h"
52
 
#include "texformat.h"
53
 
#include "teximage.h"
54
 
#include "texstore.h"
55
 
#include "vbo/vbo.h"
56
 
#include "swrast_setup/swrast_setup.h"
57
 
#include "swrast_setup/ss_context.h"
58
 
#include "tnl/tnl.h"
59
 
#include "tnl/t_context.h"
60
 
#include "tnl/t_pipeline.h"
61
 
 
62
 
extern BOOL dglSwapBuffers(HDC hDC);
63
 
 
64
 
// HACK: Hack the _33 member of the OpenGL perspective projection matrix
65
 
const float _fPersp_33 = 1.6f;
66
 
 
67
 
//---------------------------------------------------------------------------
68
 
// Internal functions
69
 
//---------------------------------------------------------------------------
70
 
 
71
 
void _gld_mesa_warning(
72
 
        __GLcontext *gc,
73
 
        char *str)
74
 
{
75
 
        // Intercept Mesa's internal warning mechanism
76
 
        gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str);
77
 
}
78
 
 
79
 
//---------------------------------------------------------------------------
80
 
 
81
 
void _gld_mesa_fatal(
82
 
        __GLcontext *gc,
83
 
        char *str)
84
 
{
85
 
        // Intercept Mesa's internal fatal-message mechanism
86
 
        gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str);
87
 
 
88
 
        // Mesa calls abort(0) here.
89
 
        ddlogClose();
90
 
        exit(0);
91
 
}
92
 
 
93
 
//---------------------------------------------------------------------------
94
 
 
95
 
D3DSTENCILOP _gldConvertStencilOp(
96
 
        GLenum StencilOp)
97
 
{
98
 
        // Used by Stencil: pass, fail and zfail
99
 
 
100
 
        switch (StencilOp) {
101
 
        case GL_KEEP:
102
 
                return D3DSTENCILOP_KEEP;
103
 
        case GL_ZERO:
104
 
                return D3DSTENCILOP_ZERO;
105
 
        case GL_REPLACE:
106
 
            return D3DSTENCILOP_REPLACE;
107
 
        case GL_INCR:
108
 
                return D3DSTENCILOP_INCRSAT;
109
 
        case GL_DECR:
110
 
            return D3DSTENCILOP_DECRSAT;
111
 
        case GL_INVERT:
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;
117
 
        }
118
 
 
119
 
#ifdef _DEBUG
120
 
        gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n");
121
 
#endif
122
 
 
123
 
        return D3DSTENCILOP_KEEP;
124
 
}
125
 
 
126
 
//---------------------------------------------------------------------------
127
 
 
128
 
D3DCMPFUNC _gldConvertCompareFunc(
129
 
        GLenum CmpFunc)
130
 
{
131
 
        // Used for Alpha func, depth func and stencil func.
132
 
 
133
 
        switch (CmpFunc) {
134
 
        case GL_NEVER:
135
 
                return D3DCMP_NEVER;
136
 
        case GL_LESS:
137
 
                return D3DCMP_LESS;
138
 
        case GL_EQUAL:
139
 
                return D3DCMP_EQUAL;
140
 
        case GL_LEQUAL:
141
 
                return D3DCMP_LESSEQUAL;
142
 
        case GL_GREATER:
143
 
                return D3DCMP_GREATER;
144
 
        case GL_NOTEQUAL:
145
 
                return D3DCMP_NOTEQUAL;
146
 
        case GL_GEQUAL:
147
 
                return D3DCMP_GREATEREQUAL;
148
 
        case GL_ALWAYS:
149
 
                return D3DCMP_ALWAYS;
150
 
        };
151
 
 
152
 
#ifdef _DEBUG
153
 
        gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n");
154
 
#endif
155
 
 
156
 
        return D3DCMP_ALWAYS;
157
 
}
158
 
 
159
 
//---------------------------------------------------------------------------
160
 
 
161
 
D3DBLEND _gldConvertBlendFunc(
162
 
        GLenum blend,
163
 
        GLenum DefaultBlend)
164
 
{
165
 
        switch (blend) {
166
 
        case GL_ZERO:
167
 
                return D3DBLEND_ZERO;
168
 
        case GL_ONE:
169
 
                return D3DBLEND_ONE;
170
 
        case GL_DST_COLOR:
171
 
                return D3DBLEND_DESTCOLOR;
172
 
        case GL_SRC_COLOR:
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;
178
 
        case GL_SRC_ALPHA:
179
 
                return D3DBLEND_SRCALPHA;
180
 
        case GL_ONE_MINUS_SRC_ALPHA:
181
 
                return D3DBLEND_INVSRCALPHA;
182
 
        case GL_DST_ALPHA:
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;
188
 
        }
189
 
 
190
 
#ifdef _DEBUG
191
 
        gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n");
192
 
#endif
193
 
 
194
 
        return DefaultBlend;
195
 
}
196
 
 
197
 
//---------------------------------------------------------------------------
198
 
// Misc. functions
199
 
//---------------------------------------------------------------------------
200
 
 
201
 
void gld_Noop_DX9(
202
 
        GLcontext *ctx)
203
 
{
204
 
#ifdef _DEBUG
205
 
        gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n");
206
 
#endif
207
 
}
208
 
 
209
 
//---------------------------------------------------------------------------
210
 
 
211
 
void gld_Error_DX9(
212
 
        GLcontext *ctx)
213
 
{
214
 
#ifdef _DEBUG
215
 
        // Quite useless.
216
 
//      gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n");
217
 
#endif
218
 
}
219
 
 
220
 
//---------------------------------------------------------------------------
221
 
// Required Mesa functions
222
 
//---------------------------------------------------------------------------
223
 
 
224
 
static GLboolean gld_set_draw_buffer_DX9(
225
 
        GLcontext *ctx,
226
 
        GLenum mode)
227
 
{
228
 
   (void) ctx;
229
 
   if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) {
230
 
      return GL_TRUE;
231
 
   }
232
 
   else {
233
 
      return GL_FALSE;
234
 
   }
235
 
}
236
 
 
237
 
//---------------------------------------------------------------------------
238
 
 
239
 
static void gld_set_read_buffer_DX9(
240
 
        GLcontext *ctx,
241
 
        GLframebuffer *buffer,
242
 
        GLenum mode)
243
 
{
244
 
   /* separate read buffer not supported */
245
 
/*
246
 
   ASSERT(buffer == ctx->DrawBuffer);
247
 
   ASSERT(mode == GL_FRONT_LEFT);
248
 
*/
249
 
}
250
 
 
251
 
//---------------------------------------------------------------------------
252
 
 
253
 
void gld_Clear_DX9(
254
 
        GLcontext *ctx,
255
 
        GLbitfield mask,
256
 
        GLboolean all,
257
 
        GLint x,
258
 
        GLint y,
259
 
        GLint width,
260
 
        GLint height)
261
 
{
262
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
263
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
264
 
 
265
 
        DWORD           dwFlags = 0;
266
 
        D3DCOLOR        Color = 0;
267
 
        float           Z = 0.0f;
268
 
        DWORD           Stencil = 0;
269
 
        D3DRECT         d3dClearRect;
270
 
 
271
 
        // TODO: Colourmask
272
 
        const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
273
 
 
274
 
        if (!gld->pDev)
275
 
                return;
276
 
 
277
 
        if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
278
 
                GLubyte col[4];
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]);
285
 
        }
286
 
 
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
294
 
                } else {
295
 
                        dwFlags |= D3DCLEAR_ZBUFFER;
296
 
                        Z = ctx->Depth.Clear;
297
 
                }
298
 
        }
299
 
 
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
304
 
                } else {
305
 
                        dwFlags |= D3DCLEAR_STENCIL;
306
 
                        Stencil = ctx->Stencil.Clear;
307
 
                }
308
 
        }
309
 
 
310
 
        // Some apps do really weird things with the rect, such as Quake3.
311
 
        if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) {
312
 
                all = GL_TRUE;
313
 
        }
314
 
 
315
 
        if (!all) {
316
 
                // Calculate clear subrect
317
 
                d3dClearRect.x1 = x;
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);
322
 
        }
323
 
 
324
 
        // dwFlags will be zero if there's nothing to clear
325
 
        if (dwFlags) {
326
 
                _GLD_DX9_DEV(Clear(
327
 
                        gld->pDev,
328
 
                        all ? 0 : 1,
329
 
                        all ? NULL : &d3dClearRect,
330
 
                        dwFlags,
331
 
                        Color, Z, Stencil));
332
 
        }
333
 
 
334
 
        if (mask & DD_ACCUM_BIT) {
335
 
                // Clear accumulation buffer
336
 
        }
337
 
}
338
 
 
339
 
//---------------------------------------------------------------------------
340
 
 
341
 
// Mesa 5: Parameter change
342
 
static void gld_buffer_size_DX9(
343
 
//      GLcontext *ctx,
344
 
        GLframebuffer *fb,
345
 
        GLuint *width,
346
 
        GLuint *height)
347
 
{
348
 
//      GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
349
 
 
350
 
        *width = fb->Width; // gldCtx->dwWidth;
351
 
        *height = fb->Height; // gldCtx->dwHeight;
352
 
}
353
 
 
354
 
//---------------------------------------------------------------------------
355
 
 
356
 
static void gld_Finish_DX9(
357
 
        GLcontext *ctx)
358
 
{
359
 
}
360
 
 
361
 
//---------------------------------------------------------------------------
362
 
 
363
 
static void gld_Flush_DX9(
364
 
        GLcontext *ctx)
365
 
{
366
 
        GLD_context             *gld    = GLD_GET_CONTEXT(ctx);
367
 
 
368
 
        // TODO: Detect apps that glFlush() then SwapBuffers() ?
369
 
 
370
 
        if (gld->EmulateSingle) {
371
 
                // Emulating a single-buffered context.
372
 
                // [Direct3D doesn't allow rendering to front buffer]
373
 
                dglSwapBuffers(gld->hDC);
374
 
        }
375
 
}
376
 
 
377
 
//---------------------------------------------------------------------------
378
 
 
379
 
void gld_NEW_STENCIL(
380
 
        GLcontext *ctx)
381
 
{
382
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
383
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
384
 
 
385
 
        // Two-sided stencil. New for Mesa 5
386
 
        const GLuint            uiFace  = 0UL;
387
 
 
388
 
        struct gl_stencil_attrib *pStencil = &ctx->Stencil;
389
 
 
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])));
399
 
        }
400
 
}
401
 
 
402
 
//---------------------------------------------------------------------------
403
 
 
404
 
void gld_NEW_COLOR(
405
 
        GLcontext *ctx)
406
 
{
407
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
408
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
409
 
 
410
 
        DWORD           dwFlags = 0;
411
 
        D3DBLEND        src;
412
 
        D3DBLEND        dest;
413
 
 
414
 
        // Alpha func
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));
418
 
 
419
 
        // Blend func
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));
425
 
 
426
 
        // Color mask
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));
432
 
}
433
 
 
434
 
//---------------------------------------------------------------------------
435
 
 
436
 
void gld_NEW_DEPTH(
437
 
        GLcontext *ctx)
438
 
{
439
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
440
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
441
 
 
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));
445
 
}
446
 
 
447
 
//---------------------------------------------------------------------------
448
 
 
449
 
void gld_NEW_POLYGON(
450
 
        GLcontext *ctx)
451
 
{
452
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
453
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
454
 
 
455
 
        D3DFILLMODE     d3dFillMode = D3DFILL_SOLID;
456
 
        D3DCULL         d3dCullMode = D3DCULL_NONE;
457
 
        float           fOffset = 0; // Changed from int to float for DX9
458
 
 
459
 
        // Fillmode
460
 
        switch (ctx->Polygon.FrontMode) {
461
 
        case GL_POINT:
462
 
                d3dFillMode = D3DFILL_POINT;
463
 
                break;
464
 
        case GL_LINE:
465
 
                d3dFillMode = D3DFILL_WIREFRAME;
466
 
                break;
467
 
        case GL_FILL:
468
 
                d3dFillMode = D3DFILL_SOLID;
469
 
                break;
470
 
        }
471
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode));
472
 
 
473
 
        if (ctx->Polygon.CullFlag) {
474
 
                switch (ctx->Polygon.CullFaceMode) {
475
 
                case GL_BACK:
476
 
                        if (ctx->Polygon.FrontFace == GL_CCW)
477
 
                                d3dCullMode = D3DCULL_CW;
478
 
                        else
479
 
                                d3dCullMode = D3DCULL_CCW;
480
 
                        break;
481
 
                case GL_FRONT:
482
 
                        if (ctx->Polygon.FrontFace == GL_CCW)
483
 
                                d3dCullMode = D3DCULL_CCW;
484
 
                        else
485
 
                                d3dCullMode = D3DCULL_CW;
486
 
                        break;
487
 
                case GL_FRONT_AND_BACK:
488
 
                        d3dCullMode = D3DCULL_NONE;
489
 
                        break;
490
 
                default:
491
 
                        break;
492
 
                }
493
 
        } else {
494
 
                d3dCullMode = D3DCULL_NONE;
495
 
        }
496
 
//      d3dCullMode = D3DCULL_NONE; // FOR DEBUGGING
497
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode));
498
 
 
499
 
        // Polygon offset
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;
506
 
//              else
507
 
//                      iOffset = 0.0f; // D3D can't push away
508
 
        }
509
 
        // NOTE: SetRenderState() required a DWORD, so need to cast
510
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DEPTHBIAS, *((DWORD*)&fOffset)));
511
 
}
512
 
 
513
 
//---------------------------------------------------------------------------
514
 
 
515
 
void gld_NEW_FOG(
516
 
        GLcontext *ctx)
517
 
{
518
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
519
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
520
 
 
521
 
        D3DCOLOR        d3dFogColour;
522
 
        D3DFOGMODE      d3dFogMode = D3DFOG_LINEAR;
523
 
 
524
 
        // TODO: Fog is calculated seperately in the Mesa pipeline
525
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE));
526
 
        return;
527
 
 
528
 
        // Fog enable
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
534
 
        }
535
 
 
536
 
        // Fog colour
537
 
        d3dFogColour = D3DCOLOR_COLORVALUE(     ctx->Fog.Color[0],
538
 
                                                                ctx->Fog.Color[1],
539
 
                                                                ctx->Fog.Color[2],
540
 
                                                                ctx->Fog.Color[3]);
541
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour));
542
 
 
543
 
        // Fog density
544
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density))));
545
 
 
546
 
        // Fog start
547
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start))));
548
 
 
549
 
        // Fog end
550
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End))));
551
 
 
552
 
        // Fog mode
553
 
        switch (ctx->Fog.Mode) {
554
 
        case GL_LINEAR:
555
 
                d3dFogMode = D3DFOG_LINEAR;
556
 
                break;
557
 
        case GL_EXP:
558
 
                d3dFogMode = D3DFOG_EXP;
559
 
                break;
560
 
        case GL_EXP2:
561
 
                d3dFogMode = D3DFOG_EXP2;
562
 
                break;
563
 
        }
564
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode));
565
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE));
566
 
}
567
 
 
568
 
//---------------------------------------------------------------------------
569
 
 
570
 
void gld_NEW_LIGHT(
571
 
        GLcontext *ctx)
572
 
{
573
 
        GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
574
 
        GLD_driver_dx9  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
575
 
        DWORD                   dwSpecularEnable;
576
 
 
577
 
        // Shademode
578
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT));
579
 
 
580
 
        // Separate specular colour
581
 
        if (ctx->Light.Enabled)
582
 
                dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE;
583
 
        else
584
 
                dwSpecularEnable = FALSE;
585
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable));
586
 
}
587
 
 
588
 
//---------------------------------------------------------------------------
589
 
 
590
 
void gld_NEW_MODELVIEW(
591
 
        GLcontext *ctx)
592
 
{
593
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
594
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
595
 
 
596
 
        D3DMATRIX       m;
597
 
        //GLfloat               *pM = ctx->ModelView.m;
598
 
        // Mesa5: Model-view is now a stack
599
 
        GLfloat         *pM = ctx->ModelviewMatrixStack.Top->m;
600
 
        m._11 = pM[0];
601
 
        m._12 = pM[1];
602
 
        m._13 = pM[2];
603
 
        m._14 = pM[3];
604
 
        m._21 = pM[4];
605
 
        m._22 = pM[5];
606
 
        m._23 = pM[6];
607
 
        m._24 = pM[7];
608
 
        m._31 = pM[8];
609
 
        m._32 = pM[9];
610
 
        m._33 = pM[10];
611
 
        m._34 = pM[11];
612
 
        m._41 = pM[12];
613
 
        m._42 = pM[13];
614
 
        m._43 = pM[14];
615
 
        m._44 = pM[15];
616
 
 
617
 
        gld->matModelView = m;
618
 
}
619
 
 
620
 
//---------------------------------------------------------------------------
621
 
 
622
 
void gld_NEW_PROJECTION(
623
 
        GLcontext *ctx)
624
 
{
625
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
626
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
627
 
 
628
 
        D3DMATRIX       m;
629
 
        //GLfloat               *pM = ctx->ProjectionMatrix.m;
630
 
        // Mesa 5: Now a stack
631
 
        GLfloat         *pM = ctx->ProjectionMatrixStack.Top->m;
632
 
        m._11 = pM[0];
633
 
        m._12 = pM[1];
634
 
        m._13 = pM[2];
635
 
        m._14 = pM[3];
636
 
 
637
 
        m._21 = pM[4];
638
 
        m._22 = pM[5];
639
 
        m._23 = pM[6];
640
 
        m._24 = pM[7];
641
 
 
642
 
        m._31 = pM[8];
643
 
        m._32 = pM[9];
644
 
        m._33 = pM[10] / _fPersp_33; // / 1.6f;
645
 
        m._34 = pM[11];
646
 
 
647
 
        m._41 = pM[12];
648
 
        m._42 = pM[13];
649
 
        m._43 = pM[14] / 2.0f;
650
 
        m._44 = pM[15];
651
 
 
652
 
        gld->matProjection = m;
653
 
}
654
 
 
655
 
//---------------------------------------------------------------------------
656
 
/*
657
 
void gldFrustumHook_DX9(
658
 
        GLdouble left,
659
 
        GLdouble right,
660
 
        GLdouble bottom,
661
 
        GLdouble top,
662
 
        GLdouble nearval,
663
 
        GLdouble farval)
664
 
{
665
 
        GET_CURRENT_CONTEXT(ctx);
666
 
        GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
667
 
        GLD_driver_dx9  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
668
 
 
669
 
        // Pass values on to Mesa first (in case we mess with them)
670
 
        _mesa_Frustum(left, right, bottom, top, nearval, farval);
671
 
 
672
 
        _fPersp_33 = farval / (nearval - farval);
673
 
 
674
 
//      ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval);
675
 
}
676
 
 
677
 
//---------------------------------------------------------------------------
678
 
 
679
 
void gldOrthoHook_DX9(
680
 
        GLdouble left,
681
 
        GLdouble right,
682
 
        GLdouble bottom,
683
 
        GLdouble top,
684
 
        GLdouble nearval,
685
 
        GLdouble farval)
686
 
{
687
 
        GET_CURRENT_CONTEXT(ctx);
688
 
        GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
689
 
        GLD_driver_dx9  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
690
 
 
691
 
        // Pass values on to Mesa first (in case we mess with them)
692
 
        _mesa_Ortho(left, right, bottom, top, nearval, farval);
693
 
 
694
 
        _fPersp_33 = 1.6f;
695
 
 
696
 
//      ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval);
697
 
}
698
 
*/
699
 
//---------------------------------------------------------------------------
700
 
 
701
 
void gld_NEW_VIEWPORT(
702
 
        GLcontext *ctx)
703
 
{
704
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
705
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
706
 
 
707
 
        D3DVIEWPORT9    d3dvp;
708
 
//      GLint                   x, y;
709
 
//      GLsizei                 w, h;
710
 
 
711
 
        // Set depth range
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;
717
 
        } else {
718
 
                d3dvp.MinZ              = ctx->Viewport.Far;
719
 
                d3dvp.MaxZ              = ctx->Viewport.Near;
720
 
        }
721
 
/*      x = ctx->Viewport.X;
722
 
        y = ctx->Viewport.Y;
723
 
        w = ctx->Viewport.Width;
724
 
        h = ctx->Viewport.Height;
725
 
        if (x < 0) x = 0;
726
 
        if (y < 0) y = 0;
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;
732
 
        d3dvp.X                 = x;
733
 
        d3dvp.Y                 = gldCtx->dwHeight - (y + h);
734
 
        d3dvp.Width             = w;
735
 
        d3dvp.Height    = h;*/
736
 
        _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
737
 
 
738
 
//      gld->fFlipWindowY = (float)gldCtx->dwHeight;
739
 
}
740
 
 
741
 
//---------------------------------------------------------------------------
742
 
 
743
 
void gld_NEW_SCISSOR(
744
 
        GLcontext *ctx)
745
 
{
746
 
        GLD_context                     *gldCtx = GLD_GET_CONTEXT(ctx);
747
 
        GLD_driver_dx9          *gld    = GLD_GET_DX9_DRIVER(gldCtx);
748
 
 
749
 
        // Bail if IHV driver cannot scissor
750
 
        if (!gld->bCanScissor)
751
 
                return;
752
 
 
753
 
        // Set scissor rect
754
 
        if (ctx->Scissor.Enabled) {
755
 
                RECT rcRect;
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);
762
 
        }
763
 
 
764
 
        // Enable/disable scissor as required
765
 
        _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SCISSORTESTENABLE, ctx->Scissor.Enabled));
766
 
}
767
 
 
768
 
//---------------------------------------------------------------------------
769
 
 
770
 
__inline BOOL _gldAnyEvalEnabled(
771
 
        GLcontext *ctx)
772
 
{
773
 
        struct gl_eval_attrib *eval = &ctx->Eval;
774
 
 
775
 
        if ((eval->AutoNormal) ||
776
 
                (eval->Map1Color4) ||
777
 
                (eval->Map1Index) ||
778
 
                (eval->Map1Normal) ||
779
 
                (eval->Map1TextureCoord1) ||
780
 
                (eval->Map1TextureCoord2) ||
781
 
                (eval->Map1TextureCoord3) ||
782
 
                (eval->Map1TextureCoord4) ||
783
 
                (eval->Map1Vertex3) ||
784
 
                (eval->Map1Vertex4) ||
785
 
                (eval->Map2Color4) ||
786
 
                (eval->Map2Index) ||
787
 
                (eval->Map2Normal) ||
788
 
                (eval->Map2TextureCoord1) ||
789
 
                (eval->Map2TextureCoord2) ||
790
 
                (eval->Map2TextureCoord3) ||
791
 
                (eval->Map2TextureCoord4) ||
792
 
                (eval->Map2Vertex3) ||
793
 
                (eval->Map2Vertex4)
794
 
                )
795
 
        return TRUE;
796
 
 
797
 
        return FALSE;
798
 
}
799
 
 
800
 
//---------------------------------------------------------------------------
801
 
 
802
 
BOOL _gldChooseInternalPipeline(
803
 
        GLcontext *ctx,
804
 
        GLD_driver_dx9 *gld)
805
 
{
806
 
//      return TRUE;    // DEBUGGING: ALWAYS USE MESA
807
 
//      return FALSE;   // DEBUGGING: ALWAYS USE D3D
808
 
 
809
 
        if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE))
810
 
        {
811
 
                gld->PipelineUsage.qwMesa.QuadPart++;
812
 
                return TRUE; // Force Mesa TnL
813
 
        }
814
 
 
815
 
        if ((ctx->Light.Enabled) ||
816
 
                (1) ||
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
822
 
                )
823
 
        {
824
 
                gld->PipelineUsage.qwMesa.QuadPart++;
825
 
                return TRUE;
826
 
        }
827
 
 
828
 
        gld->PipelineUsage.qwD3DFVF.QuadPart++;
829
 
        return FALSE;
830
 
 
831
 
/*      // Force Mesa pipeline?
832
 
        if (glb.dwTnL == GLDS_TNL_MESA) {
833
 
                gld->PipelineUsage.dwMesa.QuadPart++;
834
 
                return GLD_PIPELINE_MESA;
835
 
        }
836
 
 
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;
841
 
        }
842
 
 
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) {
848
 
                        // Use Vertex Shader
849
 
                        gld->PipelineUsage.dwD3D2SVS.QuadPart++;
850
 
                        return GLD_PIPELINE_D3D_VS_TWOSIDE;
851
 
                } else {
852
 
                        // Use Mesa TnL
853
 
                        gld->PipelineUsage.dwMesa.QuadPart++;
854
 
                        return GLD_PIPELINE_MESA;
855
 
                }
856
 
        }
857
 
 
858
 
        // Must be D3D fixed-function pipeline
859
 
        gld->PipelineUsage.dwD3DFVF.QuadPart++;
860
 
        return GLD_PIPELINE_D3D_FVF;
861
 
*/
862
 
}
863
 
 
864
 
//---------------------------------------------------------------------------
865
 
 
866
 
void gld_update_state_DX9(
867
 
        GLcontext *ctx,
868
 
        GLuint new_state)
869
 
{
870
 
        GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
871
 
        GLD_driver_dx9  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
872
 
        TNLcontext              *tnl = TNL_CONTEXT(ctx);
873
 
        GLD_pb_dx9              *gldPB;
874
 
 
875
 
        if (!gld || !gld->pDev)
876
 
                return;
877
 
 
878
 
        _swsetup_InvalidateState( ctx, new_state );
879
 
        _vbo_InvalidateState( ctx, new_state );
880
 
        _tnl_InvalidateState( ctx, new_state );
881
 
 
882
 
        // SetupIndex will be used in the pipelines for choosing setup function
883
 
        if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) ||
884
 
                (ctx->Fog.Enabled))
885
 
        {
886
 
                if (ctx->_TriangleCaps & DD_FLATSHADE)
887
 
                        gld->iSetupFunc = GLD_SI_FLAT_EXTRAS;
888
 
                else
889
 
                        gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS;
890
 
        } else {
891
 
                if (ctx->_TriangleCaps & DD_FLATSHADE)
892
 
                        gld->iSetupFunc = GLD_SI_FLAT;  // Setup flat shade + texture
893
 
                else
894
 
                        gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture
895
 
        }
896
 
 
897
 
        gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld);
898
 
        if (gld->bUseMesaTnL) {
899
 
                gldPB = &gld->PB2d;
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));
904
 
        } else {
905
 
                gldPB = &gld->PB3d;
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));
910
 
//              } else {
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));
915
 
//              }
916
 
        }
917
 
 
918
 
#define _GLD_TEST_STATE(a)              \
919
 
        if (new_state & (a)) {          \
920
 
                gld##a(ctx);                    \
921
 
                new_state &= ~(a);              \
922
 
        }
923
 
 
924
 
#define _GLD_TEST_STATE_DX9(a)  \
925
 
        if (new_state & (a)) {          \
926
 
                gld##a##_DX9(ctx);              \
927
 
                new_state &= ~(a);              \
928
 
        }
929
 
 
930
 
#define _GLD_IGNORE_STATE(a) new_state &= ~(a);
931
 
 
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);
939
 
//      }
940
 
 
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);
949
 
 
950
 
        _GLD_IGNORE_STATE(_NEW_TRANSFORM);
951
 
 
952
 
        // Scissor Test: New for DX9
953
 
        _GLD_TEST_STATE(_NEW_SCISSOR);
954
 
 
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);
970
 
*/
971
 
 
972
 
// For debugging.
973
 
#if 0
974
 
#define _GLD_TEST_UNHANDLED_STATE(a)                                                                    \
975
 
        if (new_state & (a)) {                                                                  \
976
 
                gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n");      \
977
 
        }
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
994
 
#endif
995
 
 
996
 
#undef _GLD_TEST_STATE
997
 
}
998
 
 
999
 
//---------------------------------------------------------------------------
1000
 
// Viewport
1001
 
//---------------------------------------------------------------------------
1002
 
 
1003
 
void gld_Viewport_DX9(
1004
 
        GLcontext *ctx,
1005
 
        GLint x,
1006
 
        GLint y,
1007
 
        GLsizei w,
1008
 
        GLsizei h)
1009
 
{
1010
 
        GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
1011
 
        GLD_driver_dx9  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
1012
 
 
1013
 
        D3DVIEWPORT9    d3dvp;
1014
 
 
1015
 
        if (!gld || !gld->pDev)
1016
 
                return;
1017
 
 
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))
1022
 
                return;
1023
 
 
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);
1029
 
 
1030
 
#if 0
1031
 
        ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h);
1032
 
#endif
1033
 
 
1034
 
        // ** D3D viewport must not be outside the render target surface **
1035
 
        // Sanity check the GL viewport dimensions
1036
 
        if (x < 0) x = 0;
1037
 
        if (y < 0) y = 0;
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;
1043
 
 
1044
 
        d3dvp.X                 = x;
1045
 
        d3dvp.Y                 = gldCtx->dwHeight - (y + h);
1046
 
        d3dvp.Width             = w;
1047
 
        d3dvp.Height    = h;
1048
 
        if (ctx->Viewport.Near <= ctx->Viewport.Far) {
1049
 
                d3dvp.MinZ              = ctx->Viewport.Near;
1050
 
                d3dvp.MaxZ              = ctx->Viewport.Far;
1051
 
        } else {
1052
 
                d3dvp.MinZ              = ctx->Viewport.Far;
1053
 
                d3dvp.MaxZ              = ctx->Viewport.Near;
1054
 
        }
1055
 
 
1056
 
        // TODO: DEBUGGING
1057
 
//      d3dvp.MinZ              = 0.0f;
1058
 
//      d3dvp.MaxZ              = 1.0f;
1059
 
 
1060
 
        _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp));
1061
 
 
1062
 
}
1063
 
 
1064
 
//---------------------------------------------------------------------------
1065
 
 
1066
 
extern BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver);
1067
 
 
1068
 
// Mesa 5: Parameter change
1069
 
void gldResizeBuffers_DX9(
1070
 
//      GLcontext *ctx)
1071
 
        GLframebuffer *fb)
1072
 
{
1073
 
        GET_CURRENT_CONTEXT(ctx);
1074
 
        dglWglResizeBuffers(ctx, TRUE);
1075
 
}
1076
 
 
1077
 
//---------------------------------------------------------------------------
1078
 
#ifdef _DEBUG
1079
 
// This is only for debugging.
1080
 
// To use, plug into ctx->Driver.Enable pointer below.
1081
 
void gld_Enable(
1082
 
        GLcontext *ctx,
1083
 
        GLenum e,
1084
 
        GLboolean b)
1085
 
{
1086
 
        char buf[1024];
1087
 
        sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE");
1088
 
        ddlogMessage(DDLOG_SYSTEM, buf);
1089
 
}
1090
 
#endif
1091
 
//---------------------------------------------------------------------------
1092
 
// Driver pointer setup
1093
 
//---------------------------------------------------------------------------
1094
 
 
1095
 
extern const GLubyte* _gldGetStringGeneric(GLcontext*, GLenum);
1096
 
 
1097
 
void gldSetupDriverPointers_DX9(
1098
 
        GLcontext *ctx)
1099
 
{
1100
 
        GLD_context             *gldCtx = GLD_GET_CONTEXT(ctx);
1101
 
        GLD_driver_dx9  *gld    = GLD_GET_DX9_DRIVER(gldCtx);
1102
 
 
1103
 
        TNLcontext *tnl = TNL_CONTEXT(ctx);
1104
 
 
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;
1114
 
 
1115
 
        // Hardware accumulation buffer
1116
 
        ctx->Driver.Accum                                       = NULL; // TODO: gld_Accum;
1117
 
 
1118
 
        // Bitmap functions
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;
1123
 
 
1124
 
        // Buffer resize
1125
 
        ctx->Driver.ResizeBuffers                       = gldResizeBuffers_DX9;
1126
 
        
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;
1135
 
        
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;
1142
 
 
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;
1148
 
 
1149
 
        // Imaging functionality
1150
 
        ctx->Driver.CopyColorTable                      = NULL;
1151
 
        ctx->Driver.CopyColorSubTable           = NULL;
1152
 
        ctx->Driver.CopyConvolutionFilter1D = NULL;
1153
 
        ctx->Driver.CopyConvolutionFilter2D = NULL;
1154
 
 
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;
1192
 
 
1193
 
        _swsetup_Wakeup(ctx);
1194
 
 
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;
1199
 
 
1200
 
        // Hook into glFrustum() and glOrtho()
1201
 
//      ctx->Exec->Frustum                                      = gldFrustumHook_DX9;
1202
 
//      ctx->Exec->Ortho                                        = gldOrthoHook_DX9;
1203
 
 
1204
 
}
1205
 
 
1206
 
//---------------------------------------------------------------------------