Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / windows / gldirect / dx9 / gld_driver_dx9.c
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 __struct gl_context *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 __struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *ctx,
241 struct gl_framebuffer *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 struct gl_context *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[0];
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 // struct gl_context *ctx,
344 struct gl_framebuffer *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 struct gl_context *ctx)
358 {
359 }
360
361 //---------------------------------------------------------------------------
362
363 static void gld_Flush_DX9(
364 struct gl_context *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 struct gl_context *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 struct gl_context *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][0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
428 if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
429 if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
430 if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
431 _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags));
432 }
433
434 //---------------------------------------------------------------------------
435
436 void gld_NEW_DEPTH(
437 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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 struct gl_context *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(struct gl_context *ctx, BOOL bDefaultDriver);
1067
1068 // Mesa 5: Parameter change
1069 void gldResizeBuffers_DX9(
1070 // struct gl_context *ctx)
1071 struct gl_framebuffer *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 struct gl_context *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(struct gl_context*, GLenum);
1096
1097 void gldSetupDriverPointers_DX9(
1098 struct gl_context *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 //---------------------------------------------------------------------------