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: GLDirect Direct3D 8.x WGL (WindowsGL)
35 ****************************************************************************/
37 #include "dglcontext.h"
38 #include "gld_driver.h"
39 #include "gld_dxerr8.h"
43 #include "tnl/t_context.h"
45 // Copied from dglcontect.c
48 #define GLDERR_DDRAW 2
52 // This external var keeps track of any error
53 extern int nContextError
;
55 #define DDLOG_CRITICAL_OR_WARN DDLOG_CRITICAL
57 extern void _gld_mesa_warning(struct gl_context
*, char *);
58 extern void _gld_mesa_fatal(struct gl_context
*, char *);
60 //---------------------------------------------------------------------------
62 static char szColorDepthWarning
[] =
63 "GLDirect does not support the current desktop\n\
65 You may need to change the display resolution to\n\
66 16 bits per pixel or higher color depth using\n\
67 the Windows Display Settings control panel\n\
68 before running this OpenGL application.\n";
70 // The only depth-stencil formats currently supported by Direct3D
71 // Surface Format Depth Stencil Total Bits
73 // D3DFMT_D15S1 15 1 16
74 // D3DFMT_D24S8 24 8 32
76 // D3DFMT_D24X8 24 - 32
77 // D3DFMT_D24X4S4 24 4 32
79 // This pixel format will be used as a template when compiling the list
80 // of pixel formats supported by the hardware. Many fields will be
81 // filled in at runtime.
82 // PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM
83 static DGL_pixelFormat pfTemplateHW
=
86 sizeof(PIXELFORMATDESCRIPTOR
), // Size of the data structure
87 1, // Structure version - should be 1
89 PFD_DRAW_TO_WINDOW
| // The buffer can draw to a window or device surface.
90 PFD_DRAW_TO_BITMAP
| // The buffer can draw to a bitmap. (DaveM)
91 PFD_SUPPORT_GDI
| // The buffer supports GDI drawing. (DaveM)
92 PFD_SUPPORT_OPENGL
| // The buffer supports OpenGL drawing.
93 PFD_DOUBLEBUFFER
| // The buffer is double-buffered.
94 0, // Placeholder for easy commenting of above flags
95 PFD_TYPE_RGBA
, // Pixel type RGBA.
96 16, // Total colour bitplanes (excluding alpha bitplanes)
97 5, 0, // Red bits, shift
98 5, 0, // Green bits, shift
99 5, 0, // Blue bits, shift
100 0, 0, // Alpha bits, shift (destination alpha)
101 0, // Accumulator bits (total)
102 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha
105 0, // Number of auxiliary buffers
107 0, // Specifies the number of overlay and underlay planes.
109 0, // Specifies the transparent color or index of an underlay plane.
112 D3DFMT_UNKNOWN
, // No depth/stencil buffer
115 //---------------------------------------------------------------------------
117 //---------------------------------------------------------------------------
119 // Vertex Shader Declaration
120 static DWORD dwTwoSidedLightingDecl
[] =
123 D3DVSD_REG(0, D3DVSDT_FLOAT3
), // XYZ position
124 D3DVSD_REG(1, D3DVSDT_FLOAT3
), // XYZ normal
125 D3DVSD_REG(2, D3DVSDT_D3DCOLOR
), // Diffuse color
126 D3DVSD_REG(3, D3DVSDT_D3DCOLOR
), // Specular color
127 D3DVSD_REG(4, D3DVSDT_FLOAT2
), // 2D texture unit 0
128 D3DVSD_REG(5, D3DVSDT_FLOAT2
), // 2D texture unit 1
132 // Vertex Shader for two-sided lighting
133 static char *szTwoSidedLightingVS
=
134 // This is a test shader!
143 //---------------------------------------------------------------------------
144 //---------------------------------------------------------------------------
147 HINSTANCE hD3D8DLL
; // Handle to d3d8.dll
148 FNDIRECT3DCREATE8 fnDirect3DCreate8
; // Direct3DCreate8 function prototype
149 BOOL bDirect3D
; // Persistant Direct3D8 exists
150 BOOL bDirect3DDevice
; // Persistant Direct3DDevice8 exists
151 IDirect3D8
*pD3D
; // Persistant Direct3D8
152 IDirect3DDevice8
*pDev
; // Persistant Direct3DDevice8
155 // These are "global" to all DX8 contexts. KeithH
156 static GLD_dx8_globals dx8Globals
;
158 //---------------------------------------------------------------------------
159 //---------------------------------------------------------------------------
161 BOOL
gldGetDXErrorString_DX(
167 // Return a string describing the input HRESULT error code
170 D3DXGetErrorString(hr
, buf
, nBufSize
);
174 //---------------------------------------------------------------------------
176 static D3DMULTISAMPLE_TYPE
_gldGetDeviceMultiSampleType(
178 D3DFORMAT SurfaceFormat
,
179 D3DDEVTYPE d3dDevType
,
185 if (glb
.dwMultisample
== GLDS_MULTISAMPLE_NONE
)
186 return D3DMULTISAMPLE_NONE
;
188 if (glb
.dwMultisample
== GLDS_MULTISAMPLE_FASTEST
) {
189 // Find fastest multisample
190 for (i
=2; i
<17; i
++) {
191 hr
= IDirect3D8_CheckDeviceMultiSampleType(
197 (D3DMULTISAMPLE_TYPE
)i
);
199 return (D3DMULTISAMPLE_TYPE
)i
;
203 // Find nicest multisample
204 for (i
=16; i
>1; i
--) {
205 hr
= IDirect3D8_CheckDeviceMultiSampleType(
211 (D3DMULTISAMPLE_TYPE
)i
);
213 return (D3DMULTISAMPLE_TYPE
)i
;
218 // Nothing found - return default
219 return D3DMULTISAMPLE_NONE
;
222 //---------------------------------------------------------------------------
224 void _gldDestroyPrimitiveBuffer(
227 SAFE_RELEASE(gldVB
->pVB
);
230 gldVB
->nLines
= gldVB
->nPoints
= gldVB
->nTriangles
= 0;
233 //---------------------------------------------------------------------------
235 HRESULT
_gldCreatePrimitiveBuffer(
236 struct gl_context
*ctx
,
237 GLD_driver_dx8
*lpCtx
,
241 char *szCreateVertexBufferFailed
= "CreateVertexBuffer failed";
242 DWORD dwMaxVertices
; // Max number of vertices in vertex buffer
243 DWORD dwVBSize
; // Total size of vertex buffer
245 // If CVA (Compiled Vertex Array) is used by an OpenGL app, then we
246 // will need enough vertices to cater for Mesa::Const.MaxArrayLockSize.
247 // We'll use IMM_SIZE if it's larger (which it should not be).
248 dwMaxVertices
= MAX_ARRAY_LOCK_SIZE
;
250 // Now calculate how many vertices to allow for in total
251 // 1 per point, 2 per line, 6 per quad = 9
252 dwVBSize
= dwMaxVertices
* 9 * gldVB
->dwStride
;
254 hResult
= IDirect3DDevice8_CreateVertexBuffer(
261 if (FAILED(hResult
)) {
262 ddlogMessage(DDLOG_CRITICAL_OR_WARN
, szCreateVertexBufferFailed
);
266 gldVB
->nLines
= gldVB
->nPoints
= gldVB
->nTriangles
= 0;
267 gldVB
->pPoints
= gldVB
->pLines
= gldVB
->pTriangles
= NULL
;
268 gldVB
->iFirstLine
= dwMaxVertices
; // Index of first line in VB
269 gldVB
->iFirstTriangle
= dwMaxVertices
*3; // Index of first triangle in VB
274 //---------------------------------------------------------------------------
275 // Function: _gldCreateVertexShaders
276 // Create DX8 Vertex Shaders.
277 //---------------------------------------------------------------------------
279 void _gldCreateVertexShaders(
283 LPD3DXBUFFER pVSOpcodeBuffer; // Vertex Shader opcode buffer
287 dwFlags = D3DXASM_DEBUG;
289 dwFlags = 0; // D3DXASM_SKIPVALIDATION;
292 ddlogMessage(DDLOG_INFO, "Creating shaders...\n");
294 // Init the shader handle
295 gld->VStwosidelight.hShader = 0;
297 if (gld->d3dCaps8.MaxStreams == 0) {
298 // Lame DX8 driver doesn't support streams
299 // Not fatal, as defaults will be used
300 ddlogMessage(DDLOG_WARN, "Driver doesn't support Vertex Shaders (MaxStreams==0)\n");
304 // ** THIS DISABLES VERTEX SHADER SUPPORT **
306 // ** THIS DISABLES VERTEX SHADER SUPPORT **
309 // Two-sided lighting
314 // DEBUGGING: Load shader from a text file
317 LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer
318 hr = D3DXAssembleShaderFromFile(
321 NULL, // No constants
324 if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer))
325 ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer));
326 SAFE_RELEASE(pVSErrorBuffer);
330 LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer
331 // Assemble ascii shader text into shader opcodes
332 hr = D3DXAssembleShader(
333 szTwoSidedLightingVS,
334 strlen(szTwoSidedLightingVS),
336 NULL, // No constants
339 if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer))
340 ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer));
341 SAFE_RELEASE(pVSErrorBuffer);
345 ddlogError(DDLOG_WARN, "AssembleShader failed", hr);
346 SAFE_RELEASE(pVSOpcodeBuffer);
350 // This is for debugging. Remove to enable vertex shaders in HW
351 #define _GLD_FORCE_SW_VS 0
353 if (_GLD_FORCE_SW_VS) {
354 // _GLD_FORCE_SW_VS should be disabled for Final Release
355 ddlogMessage(DDLOG_SYSTEM, "[Forcing shaders in SW]\n");
358 // Try and create shader in hardware.
359 // NOTE: The D3D Ref device appears to succeed when trying to
360 // create the device in hardware, but later complains
361 // when trying to set it with SetVertexShader(). Go figure.
362 if (_GLD_FORCE_SW_VS || glb.dwDriver == GLDS_DRIVER_REF) {
363 // Don't try and create a hardware shader with the Ref device
364 hr = E_FAIL; // COM error/fail result
366 gld->VStwosidelight.bHardware = TRUE;
367 hr = IDirect3DDevice8_CreateVertexShader(
369 dwTwoSidedLightingDecl,
370 pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer),
371 &gld->VStwosidelight.hShader,
375 ddlogMessage(DDLOG_INFO, "... HW failed, trying SW...\n");
376 // Failed. Try and create shader for software processing
377 hr = IDirect3DDevice8_CreateVertexShader(
379 dwTwoSidedLightingDecl,
380 pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer),
381 &gld->VStwosidelight.hShader,
382 D3DUSAGE_SOFTWAREPROCESSING);
384 gld->VStwosidelight.hShader = 0; // Sanity check
385 ddlogError(DDLOG_WARN, "CreateVertexShader failed", hr);
388 // Succeeded, but for software processing
389 gld->VStwosidelight.bHardware = FALSE;
392 SAFE_RELEASE(pVSOpcodeBuffer);
394 ddlogMessage(DDLOG_INFO, "... OK\n");
397 //---------------------------------------------------------------------------
399 void _gldDestroyVertexShaders(
402 if (gld->VStwosidelight.hShader) {
403 IDirect3DDevice8_DeleteVertexShader(gld->pDev, gld->VStwosidelight.hShader);
404 gld->VStwosidelight.hShader = 0;
408 //---------------------------------------------------------------------------
410 LPVOID lpOpaque1
= NULL
;
411 LPVOID lpOpaque2
= NULL
;
413 BOOL
gldCreateDrawable_DX(
415 // BOOL bDefaultDriver,
416 BOOL bDirectDrawPersistant
,
417 BOOL bPersistantBuffers
)
420 // bDirectDrawPersistant: applies to IDirect3D8
421 // bPersistantBuffers: applies to IDirect3DDevice8
425 GLD_driver_dx8
*lpCtx
= NULL
;
426 D3DDEVTYPE d3dDevType
;
427 D3DPRESENT_PARAMETERS d3dpp
;
428 D3DDISPLAYMODE d3ddm
;
429 DWORD dwBehaviourFlags
;
430 D3DADAPTER_IDENTIFIER8 d3dIdent
;
432 // Error if context is NULL.
438 // Release any existing interfaces
439 SAFE_RELEASE(lpCtx
->pDev
);
440 SAFE_RELEASE(lpCtx
->pD3D
);
442 lpCtx
= (GLD_driver_dx8
*)malloc(sizeof(GLD_driver_dx8
));
443 ZeroMemory(lpCtx
, sizeof(lpCtx
));
446 d3dDevType
= (glb
.dwDriver
== GLDS_DRIVER_HAL
) ? D3DDEVTYPE_HAL
: D3DDEVTYPE_REF
;
448 // if (bDefaultDriver)
449 // d3dDevType = D3DDEVTYPE_REF;
451 // Use persistant interface if needed
452 if (bDirectDrawPersistant
&& dx8Globals
.bDirect3D
) {
453 lpCtx
->pD3D
= dx8Globals
.pD3D
;
454 IDirect3D8_AddRef(lpCtx
->pD3D
);
455 goto SkipDirectDrawCreate
;
458 // Create Direct3D8 object
459 lpCtx
->pD3D
= dx8Globals
.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95
);
460 if (lpCtx
->pD3D
== NULL
) {
461 MessageBox(NULL
, "Unable to initialize Direct3D8", "GLDirect", MB_OK
);
462 ddlogMessage(DDLOG_CRITICAL_OR_WARN
, "Unable to create Direct3D8 interface");
463 nContextError
= GLDERR_D3D
;
464 goto return_with_error
;
467 // Cache Direct3D interface for subsequent GLRCs
468 if (bDirectDrawPersistant
&& !dx8Globals
.bDirect3D
) {
469 dx8Globals
.pD3D
= lpCtx
->pD3D
;
470 IDirect3D8_AddRef(dx8Globals
.pD3D
);
471 dx8Globals
.bDirect3D
= TRUE
;
473 SkipDirectDrawCreate
:
475 // Get the display mode so we can make a compatible backbuffer
476 hResult
= IDirect3D8_GetAdapterDisplayMode(lpCtx
->pD3D
, glb
.dwAdapter
, &d3ddm
);
477 if (FAILED(hResult
)) {
478 nContextError
= GLDERR_D3D
;
479 goto return_with_error
;
483 hResult
= IDirect3D8_GetDeviceCaps(lpCtx
->pD3D
, glb
.dwAdapter
, d3dDevType
, &lpCtx
->d3dCaps8
);
484 if (FAILED(hResult
)) {
485 ddlogError(DDLOG_CRITICAL_OR_WARN
, "IDirect3D8_GetDeviceCaps failed", hResult
);
486 nContextError
= GLDERR_D3D
;
487 goto return_with_error
;
490 // Check for hardware transform & lighting
491 lpCtx
->bHasHWTnL
= lpCtx
->d3dCaps8
.DevCaps
& D3DDEVCAPS_HWTRANSFORMANDLIGHT
? TRUE
: FALSE
;
493 // If this flag is present then we can't default to Mesa
494 // SW rendering between BeginScene() and EndScene().
495 if (lpCtx
->d3dCaps8
.Caps2
& D3DCAPS2_NO2DDURING3DSCENE
) {
496 ddlogMessage(DDLOG_WARN
,
497 "Warning : No 2D allowed during 3D scene.\n");
501 // Create the Direct3D context
504 // Re-use original IDirect3DDevice if persistant buffers exist.
505 // Note that we test for persistant IDirect3D8 as well
506 // bDirectDrawPersistant == persistant IDirect3D8 (DirectDraw8 does not exist)
507 if (bDirectDrawPersistant
&& bPersistantBuffers
&& dx8Globals
.pD3D
&& dx8Globals
.pDev
) {
508 lpCtx
->pDev
= dx8Globals
.pDev
;
509 IDirect3DDevice8_AddRef(dx8Globals
.pDev
);
510 goto skip_direct3ddevice_create
;
513 // Clear the presentation parameters (sets all members to zero)
514 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
516 // Recommended by MS; needed for MultiSample.
517 // Be careful if altering this for FullScreenBlit
518 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
520 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
521 d3dpp
.BackBufferCount
= 1;
522 d3dpp
.MultiSampleType
= _gldGetDeviceMultiSampleType(lpCtx
->pD3D
, d3ddm
.Format
, d3dDevType
, !ctx
->bFullscreen
);
523 d3dpp
.AutoDepthStencilFormat
= ctx
->lpPF
->dwDriverData
;
524 d3dpp
.EnableAutoDepthStencil
= (d3dpp
.AutoDepthStencilFormat
== D3DFMT_UNKNOWN
) ? FALSE
: TRUE
;
526 if (ctx
->bFullscreen
) {
527 ddlogWarnOption(FALSE
); // Don't popup any messages in fullscreen
528 d3dpp
.Windowed
= FALSE
;
529 d3dpp
.BackBufferWidth
= d3ddm
.Width
;
530 d3dpp
.BackBufferHeight
= d3ddm
.Height
;
531 d3dpp
.hDeviceWindow
= ctx
->hWnd
;
532 d3dpp
.FullScreen_RefreshRateInHz
= D3DPRESENT_RATE_DEFAULT
;
534 // Support for vertical retrace synchronisation.
535 // Set default presentation interval in case caps bits are missing
536 d3dpp
.FullScreen_PresentationInterval
= D3DPRESENT_INTERVAL_DEFAULT
;
537 if (glb
.bWaitForRetrace
) {
538 if (lpCtx
->d3dCaps8
.PresentationIntervals
& D3DPRESENT_INTERVAL_ONE
)
539 d3dpp
.FullScreen_PresentationInterval
= D3DPRESENT_INTERVAL_ONE
;
541 if (lpCtx
->d3dCaps8
.PresentationIntervals
& D3DPRESENT_INTERVAL_IMMEDIATE
)
542 d3dpp
.FullScreen_PresentationInterval
= D3DPRESENT_INTERVAL_IMMEDIATE
;
545 ddlogWarnOption(glb
.bMessageBoxWarnings
); // OK to popup messages
546 d3dpp
.Windowed
= TRUE
;
547 d3dpp
.BackBufferWidth
= ctx
->dwWidth
;
548 d3dpp
.BackBufferHeight
= ctx
->dwHeight
;
549 d3dpp
.hDeviceWindow
= ctx
->hWnd
;
550 d3dpp
.FullScreen_RefreshRateInHz
= 0;
551 // FullScreen_PresentationInterval must be default for Windowed mode
552 d3dpp
.FullScreen_PresentationInterval
= D3DPRESENT_INTERVAL_DEFAULT
;
555 // Decide if we can use hardware TnL
556 dwBehaviourFlags
= (lpCtx
->bHasHWTnL
) ?
557 D3DCREATE_MIXED_VERTEXPROCESSING
: D3DCREATE_SOFTWARE_VERTEXPROCESSING
;
558 // Add flag to tell D3D to be thread-safe
559 if (glb
.bMultiThreaded
)
560 dwBehaviourFlags
|= D3DCREATE_MULTITHREADED
;
561 // Add flag to tell D3D to be FPU-safe
563 dwBehaviourFlags
|= D3DCREATE_FPU_PRESERVE
;
564 hResult
= IDirect3D8_CreateDevice(lpCtx
->pD3D
,
571 if (FAILED(hResult
)) {
572 ddlogError(DDLOG_CRITICAL_OR_WARN
, "IDirect3D8_CreateDevice failed", hResult
);
573 nContextError
= GLDERR_D3D
;
574 goto return_with_error
;
577 if (bDirectDrawPersistant
&& bPersistantBuffers
&& dx8Globals
.pD3D
) {
578 dx8Globals
.pDev
= lpCtx
->pDev
;
579 dx8Globals
.bDirect3DDevice
= TRUE
;
583 // See if DDraw interfaces are available (DaveM)
584 hResult = IDirect3D8_QueryInterface(lpCtx->pDev,
585 &IID_IDirectDraw7, (LPVOID*)&lpOpaque1);
586 if (FAILED(hResult) || lpOpaque1 == NULL) {
587 ddlogMessage(DDLOG_INFO, "DirectDraw QueryInterface unavailable\n");
590 hResult = IDirect3DDevice8_QueryInterface(lpCtx->pDev,
591 &IID_IDirectDrawSurface7, (LPVOID*)&lpOpaque2);
592 if (FAILED(hResult) || lpOpaque2 == NULL) {
593 ddlogMessage(DDLOG_INFO, "DirectDrawSurface QueryInterface unavialable\n");
596 // Dump some useful stats
597 hResult
= IDirect3D8_GetAdapterIdentifier(
600 D3DENUM_NO_WHQL_LEVEL
, // Avoids 1 to 2 second delay
602 if (SUCCEEDED(hResult
)) {
603 ddlogPrintf(DDLOG_INFO
, "[Driver Description: %s]", &d3dIdent
.Description
);
604 ddlogPrintf(DDLOG_INFO
, "[Driver file: %s %d.%d.%02d.%d]",
606 HIWORD(d3dIdent
.DriverVersion
.HighPart
),
607 LOWORD(d3dIdent
.DriverVersion
.HighPart
),
608 HIWORD(d3dIdent
.DriverVersion
.LowPart
),
609 LOWORD(d3dIdent
.DriverVersion
.LowPart
));
610 ddlogPrintf(DDLOG_INFO
, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]",
611 d3dIdent
.VendorId
, d3dIdent
.DeviceId
, d3dIdent
.SubSysId
, d3dIdent
.Revision
);
614 // Init projection matrix for D3D TnL
615 D3DXMatrixIdentity(&lpCtx
->matProjection
);
616 lpCtx
->matModelView
= lpCtx
->matProjection
;
617 // gld->bUseMesaProjection = TRUE;
619 skip_direct3ddevice_create
:
621 // Create buffers to hold primitives
622 lpCtx
->PB2d
.dwFVF
= GLD_FVF_2D_VERTEX
;
623 lpCtx
->PB2d
.dwPool
= D3DPOOL_SYSTEMMEM
;
624 lpCtx
->PB2d
.dwStride
= sizeof(GLD_2D_VERTEX
);
625 lpCtx
->PB2d
.dwUsage
= D3DUSAGE_DONOTCLIP
|
627 D3DUSAGE_SOFTWAREPROCESSING
|
629 hResult
= _gldCreatePrimitiveBuffer(ctx
->glCtx
, lpCtx
, &lpCtx
->PB2d
);
631 goto return_with_error
;
633 lpCtx
->PB3d
.dwFVF
= GLD_FVF_3D_VERTEX
;
634 lpCtx
->PB3d
.dwPool
= D3DPOOL_DEFAULT
;
635 lpCtx
->PB3d
.dwStride
= sizeof(GLD_3D_VERTEX
);
636 lpCtx
->PB3d
.dwUsage
= D3DUSAGE_DYNAMIC
|
637 D3DUSAGE_SOFTWAREPROCESSING
|
639 hResult
= _gldCreatePrimitiveBuffer(ctx
->glCtx
, lpCtx
, &lpCtx
->PB3d
);
641 goto return_with_error
;
643 /* // NOTE: A FVF code of zero indicates a non-FVF vertex buffer (for vertex shaders)
644 lpCtx->PBtwosidelight.dwFVF = 0; //GLD_FVF_TWOSIDED_VERTEX;
645 lpCtx->PBtwosidelight.dwPool = D3DPOOL_DEFAULT;
646 lpCtx->PBtwosidelight.dwStride = sizeof(GLD_TWOSIDED_VERTEX);
647 lpCtx->PBtwosidelight.dwUsage = D3DUSAGE_DONOTCLIP |
649 D3DUSAGE_SOFTWAREPROCESSING |
651 hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PBtwosidelight);
653 goto return_with_error;*/
655 // Now try and create the DX8 Vertex Shaders
656 // _gldCreateVertexShaders(lpCtx);
658 // Zero the pipeline usage counters
659 lpCtx
->PipelineUsage
.qwMesa
.QuadPart
=
660 // lpCtx->PipelineUsage.dwD3D2SVS.QuadPart =
661 lpCtx
->PipelineUsage
.qwD3DFVF
.QuadPart
= 0;
663 // Assign drawable to GL private
670 // _gldDestroyVertexShaders(lpCtx);
672 // _gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight);
673 _gldDestroyPrimitiveBuffer(&lpCtx
->PB3d
);
674 _gldDestroyPrimitiveBuffer(&lpCtx
->PB2d
);
676 SAFE_RELEASE(lpCtx
->pDev
);
677 SAFE_RELEASE(lpCtx
->pD3D
);
681 //---------------------------------------------------------------------------
683 BOOL
gldResizeDrawable_DX(
686 BOOL bPersistantInterface
,
687 BOOL bPersistantBuffers
)
689 GLD_driver_dx8
*gld
= NULL
;
690 D3DDEVTYPE d3dDevType
;
691 D3DPRESENT_PARAMETERS d3dpp
;
692 D3DDISPLAYMODE d3ddm
;
695 // Error if context is NULL.
703 if (ctx
->bSceneStarted
) {
704 IDirect3DDevice8_EndScene(gld
->pDev
);
705 ctx
->bSceneStarted
= FALSE
;
708 d3dDevType
= (glb
.dwDriver
== GLDS_DRIVER_HAL
) ? D3DDEVTYPE_HAL
: D3DDEVTYPE_REF
;
710 d3dDevType
= D3DDEVTYPE_REF
; // Force Direct3D Reference Rasterise (software)
712 // Get the display mode so we can make a compatible backbuffer
713 hResult
= IDirect3D8_GetAdapterDisplayMode(gld
->pD3D
, glb
.dwAdapter
, &d3ddm
);
714 if (FAILED(hResult
)) {
715 nContextError
= GLDERR_D3D
;
716 // goto return_with_error;
720 // Destroy DX8 Vertex Shaders before Reset()
721 // _gldDestroyVertexShaders(gld);
723 // Release POOL_DEFAULT objects before Reset()
724 if (gld
->PB2d
.dwPool
== D3DPOOL_DEFAULT
)
725 _gldDestroyPrimitiveBuffer(&gld
->PB2d
);
726 if (gld
->PB3d
.dwPool
== D3DPOOL_DEFAULT
)
727 _gldDestroyPrimitiveBuffer(&gld
->PB3d
);
728 // if (gld->PBtwosidelight.dwPool == D3DPOOL_DEFAULT)
729 // _gldDestroyPrimitiveBuffer(&gld->PBtwosidelight);
731 // Clear the presentation parameters (sets all members to zero)
732 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
734 // Recommended by MS; needed for MultiSample.
735 // Be careful if altering this for FullScreenBlit
736 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
738 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
739 d3dpp
.BackBufferCount
= 1;
740 d3dpp
.MultiSampleType
= _gldGetDeviceMultiSampleType(gld
->pD3D
, d3ddm
.Format
, d3dDevType
, !ctx
->bFullscreen
);
741 d3dpp
.AutoDepthStencilFormat
= ctx
->lpPF
->dwDriverData
;
742 d3dpp
.EnableAutoDepthStencil
= (d3dpp
.AutoDepthStencilFormat
== D3DFMT_UNKNOWN
) ? FALSE
: TRUE
;
744 // TODO: Sync to refresh
746 if (ctx
->bFullscreen
) {
747 ddlogWarnOption(FALSE
); // Don't popup any messages in fullscreen
748 d3dpp
.Windowed
= FALSE
;
749 d3dpp
.BackBufferWidth
= d3ddm
.Width
;
750 d3dpp
.BackBufferHeight
= d3ddm
.Height
;
751 d3dpp
.hDeviceWindow
= ctx
->hWnd
;
752 d3dpp
.FullScreen_RefreshRateInHz
= D3DPRESENT_RATE_DEFAULT
;
753 d3dpp
.FullScreen_PresentationInterval
= D3DPRESENT_INTERVAL_DEFAULT
;
754 // Get better benchmark results? KeithH
755 // d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_UNLIMITED;
757 ddlogWarnOption(glb
.bMessageBoxWarnings
); // OK to popup messages
758 d3dpp
.Windowed
= TRUE
;
759 d3dpp
.BackBufferWidth
= ctx
->dwWidth
;
760 d3dpp
.BackBufferHeight
= ctx
->dwHeight
;
761 d3dpp
.hDeviceWindow
= ctx
->hWnd
;
762 d3dpp
.FullScreen_RefreshRateInHz
= 0;
763 d3dpp
.FullScreen_PresentationInterval
= D3DPRESENT_INTERVAL_DEFAULT
;
765 hResult
= IDirect3DDevice8_Reset(gld
->pDev
, &d3dpp
);
766 if (FAILED(hResult
)) {
767 ddlogError(DDLOG_CRITICAL_OR_WARN
, "dglResize: Reset failed", hResult
);
769 //goto cleanup_and_return_with_error;
772 // Explicitly Clear resized surfaces (DaveM)
774 D3DVIEWPORT8 d3dvp1
, d3dvp2
;
775 IDirect3DDevice8_GetViewport(gld
->pDev
, &d3dvp1
);
776 IDirect3DDevice8_GetViewport(gld
->pDev
, &d3dvp2
);
779 d3dvp1
.Width
= ctx
->dwWidth
;
780 d3dvp1
.Height
= ctx
->dwHeight
;
781 IDirect3DDevice8_SetViewport(gld
->pDev
, &d3dvp1
);
782 IDirect3DDevice8_Clear(gld
->pDev
,0,NULL
,D3DCLEAR_TARGET
,0,0,0);
783 IDirect3DDevice8_SetViewport(gld
->pDev
, &d3dvp2
);
787 // Recreate POOL_DEFAULT objects
789 if (gld
->PB2d
.dwPool
== D3DPOOL_DEFAULT
) {
790 _gldCreatePrimitiveBuffer(ctx
->glCtx
, gld
, &gld
->PB2d
);
792 if (gld
->PB3d
.dwPool
== D3DPOOL_DEFAULT
) {
793 _gldCreatePrimitiveBuffer(ctx
->glCtx
, gld
, &gld
->PB3d
);
795 // if (gld->PBtwosidelight.dwPool == D3DPOOL_DEFAULT) {
796 // _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB2d);
799 // Recreate DX8 Vertex Shaders
800 // _gldCreateVertexShaders(gld);
802 // Signal a complete state update
803 ctx
->glCtx
->Driver
.UpdateState(ctx
->glCtx
, _NEW_ALL
);
806 IDirect3DDevice8_BeginScene(gld
->pDev
);
807 ctx
->bSceneStarted
= TRUE
;
812 //---------------------------------------------------------------------------
814 BOOL
gldDestroyDrawable_DX(
817 GLD_driver_dx8
*lpCtx
= NULL
;
819 // Error if context is NULL.
823 // Error if the drawable does not exist.
831 ddlogPrintf(DDLOG_SYSTEM
, "Usage: M:0x%X%X, D:0x%X%X",
832 lpCtx
->PipelineUsage
.qwMesa
.HighPart
,
833 lpCtx
->PipelineUsage
.qwMesa
.LowPart
,
834 lpCtx
->PipelineUsage
.qwD3DFVF
.HighPart
,
835 lpCtx
->PipelineUsage
.qwD3DFVF
.LowPart
);
838 // _gldDestroyVertexShaders(lpCtx);
840 // _gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight);
841 _gldDestroyPrimitiveBuffer(&lpCtx
->PB3d
);
842 _gldDestroyPrimitiveBuffer(&lpCtx
->PB2d
);
844 SAFE_RELEASE(lpCtx
->pDev
);
845 SAFE_RELEASE(lpCtx
->pD3D
);
847 // Free the private drawable data
854 //---------------------------------------------------------------------------
856 BOOL
gldCreatePrivateGlobals_DX(void)
858 ZeroMemory(&dx8Globals
, sizeof(dx8Globals
));
861 dx8Globals
.hD3D8DLL
= LoadLibrary("D3D8.DLL");
862 if (dx8Globals
.hD3D8DLL
== NULL
)
865 // Now try and obtain Direct3DCreate8
866 dx8Globals
.fnDirect3DCreate8
= (FNDIRECT3DCREATE8
)GetProcAddress(dx8Globals
.hD3D8DLL
, "Direct3DCreate8");
867 if (dx8Globals
.fnDirect3DCreate8
== NULL
) {
868 FreeLibrary(dx8Globals
.hD3D8DLL
);
875 //---------------------------------------------------------------------------
877 BOOL
gldDestroyPrivateGlobals_DX(void)
879 if (dx8Globals
.bDirect3DDevice
) {
880 SAFE_RELEASE(dx8Globals
.pDev
);
881 dx8Globals
.bDirect3DDevice
= FALSE
;
883 if (dx8Globals
.bDirect3D
) {
884 SAFE_RELEASE(dx8Globals
.pD3D
);
885 dx8Globals
.bDirect3D
= FALSE
;
888 FreeLibrary(dx8Globals
.hD3D8DLL
);
889 dx8Globals
.hD3D8DLL
= NULL
;
890 dx8Globals
.fnDirect3DCreate8
= NULL
;
895 //---------------------------------------------------------------------------
897 static void _BitsFromDisplayFormat(
906 case D3DFMT_X1R5G5B5
:
920 case D3DFMT_X8R8G8B8
:
927 case D3DFMT_A8R8G8B8
:
936 // Should not get here!
944 //---------------------------------------------------------------------------
946 static void _BitsFromDepthStencilFormat(
951 // NOTE: GL expects either 32 or 16 as depth bits.
980 //---------------------------------------------------------------------------
982 BOOL
gldBuildPixelformatList_DX(void)
984 D3DDISPLAYMODE d3ddm
;
986 IDirect3D8
*pD3D
= NULL
;
988 int nSupportedFormats
= 0;
990 DGL_pixelFormat
*pPF
;
991 BYTE cColorBits
, cRedBits
, cGreenBits
, cBlueBits
, cAlphaBits
;
995 // Direct3D (SW or HW)
996 // These are arranged so that 'best' pixelformat
997 // is higher in the list (for ChoosePixelFormat).
998 const D3DFORMAT DepthStencil
[6] = {
1008 ddlogMessage(GLDLOG_SYSTEM
, "DirectX Version : 8.0\n");
1010 // Release any existing pixelformat list
1015 glb
.nPixelFormatCount
= 0;
1019 // Pixelformats for Direct3D (SW or HW) rendering
1022 // Get a Direct3D 8.0 interface
1023 pD3D
= dx8Globals
.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95
);
1028 // We will use the display mode format when finding compliant
1029 // rendertarget/depth-stencil surfaces.
1030 hr
= IDirect3D8_GetAdapterDisplayMode(pD3D
, glb
.dwAdapter
, &d3ddm
);
1032 IDirect3D8_Release(pD3D
);
1036 // Run through the possible formats and detect supported formats
1037 for (i
=0; i
<6; i
++) {
1038 hr
= IDirect3D8_CheckDeviceFormat(
1041 glb
.dwDriver
==GLDS_DRIVER_HAL
? D3DDEVTYPE_HAL
: D3DDEVTYPE_REF
,
1043 D3DUSAGE_DEPTHSTENCIL
,
1047 // A failure here is not fatal.
1050 // Verify that the depth format is compatible.
1051 hr
= IDirect3D8_CheckDepthStencilMatch(
1054 glb
.dwDriver
==GLDS_DRIVER_HAL
? D3DDEVTYPE_HAL
: D3DDEVTYPE_REF
,
1059 // A failure here is not fatal, just means depth-stencil
1060 // format is not compatible with this display mode.
1063 fmt
[nSupportedFormats
++] = DepthStencil
[i
];
1066 IDirect3D8_Release(pD3D
);
1068 if (nSupportedFormats
== 0)
1069 return FALSE
; // Bail: no compliant pixelformats
1071 // Total count of pixelformats is:
1072 // (nSupportedFormats+1)*2
1073 glb
.lpPF
= (DGL_pixelFormat
*)calloc((nSupportedFormats
)*2, sizeof(DGL_pixelFormat
));
1074 glb
.nPixelFormatCount
= (nSupportedFormats
)*2;
1075 if (glb
.lpPF
== NULL
) {
1076 glb
.nPixelFormatCount
= 0;
1080 // Get a copy of pointer that we can alter
1083 // Cache colour bits from display format
1084 _BitsFromDisplayFormat(d3ddm
.Format
, &cColorBits
, &cRedBits
, &cGreenBits
, &cBlueBits
, &cAlphaBits
);
1087 // Add single-buffer formats
1090 // Single-buffer, no depth-stencil buffer
1091 /* memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat));
1092 pPF->pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag
1093 pPF->pfd.cColorBits = cColorBits;
1094 pPF->pfd.cRedBits = cRedBits;
1095 pPF->pfd.cGreenBits = cGreenBits;
1096 pPF->pfd.cBlueBits = cBlueBits;
1097 pPF->pfd.cAlphaBits = cAlphaBits;
1098 pPF->pfd.cDepthBits = 0;
1099 pPF->pfd.cStencilBits = 0;
1100 pPF->dwDriverData = D3DFMT_UNKNOWN;
1103 for (i
=0; i
<nSupportedFormats
; i
++, pPF
++) {
1104 memcpy(pPF
, &pfTemplateHW
, sizeof(DGL_pixelFormat
));
1105 pPF
->pfd
.dwFlags
&= ~PFD_DOUBLEBUFFER
; // Remove doublebuffer flag
1106 pPF
->pfd
.cColorBits
= cColorBits
;
1107 pPF
->pfd
.cRedBits
= cRedBits
;
1108 pPF
->pfd
.cGreenBits
= cGreenBits
;
1109 pPF
->pfd
.cBlueBits
= cBlueBits
;
1110 pPF
->pfd
.cAlphaBits
= cAlphaBits
;
1111 _BitsFromDepthStencilFormat(fmt
[i
], &pPF
->pfd
.cDepthBits
, &pPF
->pfd
.cStencilBits
);
1112 pPF
->dwDriverData
= fmt
[i
];
1116 // Add double-buffer formats
1119 /* memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat));
1120 pPF->pfd.cColorBits = cColorBits;
1121 pPF->pfd.cRedBits = cRedBits;
1122 pPF->pfd.cGreenBits = cGreenBits;
1123 pPF->pfd.cBlueBits = cBlueBits;
1124 pPF->pfd.cAlphaBits = cAlphaBits;
1125 pPF->pfd.cDepthBits = 0;
1126 pPF->pfd.cStencilBits = 0;
1127 pPF->dwDriverData = D3DFMT_UNKNOWN;
1130 for (i
=0; i
<nSupportedFormats
; i
++, pPF
++) {
1131 memcpy(pPF
, &pfTemplateHW
, sizeof(DGL_pixelFormat
));
1132 pPF
->pfd
.cColorBits
= cColorBits
;
1133 pPF
->pfd
.cRedBits
= cRedBits
;
1134 pPF
->pfd
.cGreenBits
= cGreenBits
;
1135 pPF
->pfd
.cBlueBits
= cBlueBits
;
1136 pPF
->pfd
.cAlphaBits
= cAlphaBits
;
1137 _BitsFromDepthStencilFormat(fmt
[i
], &pPF
->pfd
.cDepthBits
, &pPF
->pfd
.cStencilBits
);
1138 pPF
->dwDriverData
= fmt
[i
];
1141 // Popup warning message if non RGB color mode
1143 // This is a hack. KeithH
1144 HDC hdcDesktop
= GetDC(NULL
);
1145 DWORD dwDisplayBitDepth
= GetDeviceCaps(hdcDesktop
, BITSPIXEL
);
1146 ReleaseDC(0, hdcDesktop
);
1147 if (dwDisplayBitDepth
<= 8) {
1148 ddlogPrintf(DDLOG_WARN
, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth
);
1149 MessageBox(NULL
, szColorDepthWarning
, "GLDirect", MB_OK
| MB_ICONWARNING
);
1153 // Mark list as 'current'
1154 glb
.bPixelformatsDirty
= FALSE
;
1159 //---------------------------------------------------------------------------
1161 BOOL
gldInitialiseMesa_DX(
1164 GLD_driver_dx8
*gld
= NULL
;
1165 int MaxTextureSize
, TextureLevels
;
1171 gld
= lpCtx
->glPriv
;
1175 if (glb
.bMultitexture
) {
1176 lpCtx
->glCtx
->Const
.MaxTextureUnits
= gld
->d3dCaps8
.MaxSimultaneousTextures
;
1177 // Only support MAX_TEXTURE_UNITS texture units.
1178 // ** If this is altered then the FVF formats must be reviewed **.
1179 if (lpCtx
->glCtx
->Const
.MaxTextureUnits
> GLD_MAX_TEXTURE_UNITS_DX8
)
1180 lpCtx
->glCtx
->Const
.MaxTextureUnits
= GLD_MAX_TEXTURE_UNITS_DX8
;
1182 // Multitexture override
1183 lpCtx
->glCtx
->Const
.MaxTextureUnits
= 1;
1187 MaxTextureSize
= min(gld
->d3dCaps8
.MaxTextureHeight
, gld
->d3dCaps8
.MaxTextureWidth
);
1188 if (MaxTextureSize
== 0)
1189 MaxTextureSize
= 256; // Sanity check
1193 if (MaxTextureSize
> 1024)
1194 MaxTextureSize
= 1024; // HACK - CLAMP TO 1024
1198 // Got to set MAX_TEXTURE_SIZE as max levels.
1199 // Who thought this stupid idea up? ;)
1201 // Calculate power-of-two.
1202 while (MaxTextureSize
) {
1204 MaxTextureSize
>>= 1;
1206 lpCtx
->glCtx
->Const
.MaxTextureLevels
= (TextureLevels
) ? TextureLevels
: 8;
1207 lpCtx
->glCtx
->Const
.MaxDrawBuffers
= 1;
1209 IDirect3DDevice8_SetRenderState(gld
->pDev
, D3DRS_LIGHTING
, FALSE
);
1210 IDirect3DDevice8_SetRenderState(gld
->pDev
, D3DRS_CULLMODE
, D3DCULL_NONE
);
1211 IDirect3DDevice8_SetRenderState(gld
->pDev
, D3DRS_DITHERENABLE
, TRUE
);
1212 IDirect3DDevice8_SetRenderState(gld
->pDev
, D3DRS_SHADEMODE
, D3DSHADE_GOURAUD
);
1214 IDirect3DDevice8_SetRenderState(gld
->pDev
, D3DRS_ZENABLE
,
1215 (lpCtx
->lpPF
->dwDriverData
!=D3DFMT_UNKNOWN
) ? D3DZB_TRUE
: D3DZB_FALSE
);
1217 // Set the view matrix
1221 D3DXMatrixIdentity(&vm
);
1223 D3DXVECTOR3
Eye(0.0f
, 0.0f
, 0.0f
);
1224 D3DXVECTOR3
At(0.0f
, 0.0f
, -1.0f
);
1225 D3DXVECTOR3
Up(0.0f
, 1.0f
, 0.0f
);
1226 D3DXMatrixLookAtRH(&vm
, &Eye
, &At
, &Up
);
1232 IDirect3DDevice8_SetTransform(gld
->pDev
, D3DTS_VIEW
, &vm
);
1235 if (gld
->bHasHWTnL
) {
1236 if (glb
.dwTnL
== GLDS_TNL_DEFAULT
)
1237 bSoftwareTnL
= FALSE
; // HW TnL
1239 bSoftwareTnL
= ((glb
.dwTnL
== GLDS_TNL_MESA
) || (glb
.dwTnL
== GLDS_TNL_D3DSW
)) ? TRUE
: FALSE
;
1242 // No HW TnL, so no choice possible
1243 bSoftwareTnL
= TRUE
;
1245 IDirect3DDevice8_SetRenderState(gld
->pDev
, D3DRS_SOFTWAREVERTEXPROCESSING
, bSoftwareTnL
);
1247 // Dump this in a Release build as well, now.
1249 ddlogPrintf(DDLOG_INFO
, "HW TnL: %s",
1250 gld
->bHasHWTnL
? (bSoftwareTnL
? "Disabled" : "Enabled") : "Unavailable");
1253 gldEnableExtensions_DX8(lpCtx
->glCtx
);
1254 gldInstallPipeline_DX8(lpCtx
->glCtx
);
1255 gldSetupDriverPointers_DX8(lpCtx
->glCtx
);
1257 // Signal a complete state update
1258 lpCtx
->glCtx
->Driver
.UpdateState(lpCtx
->glCtx
, _NEW_ALL
);
1261 IDirect3DDevice8_BeginScene(gld
->pDev
);
1262 lpCtx
->bSceneStarted
= TRUE
;
1267 //---------------------------------------------------------------------------
1269 BOOL
gldSwapBuffers_DX(
1275 GLD_driver_dx8
*gld
= NULL
;
1284 if (ctx
->bSceneStarted
) {
1285 IDirect3DDevice8_EndScene(gld
->pDev
);
1286 ctx
->bSceneStarted
= FALSE
;
1289 // Swap the buffers. hWnd may override the hWnd used for CreateDevice()
1290 hr
= IDirect3DDevice8_Present(gld
->pDev
, NULL
, NULL
, hWnd
, NULL
);
1292 IDirect3DDevice8_BeginScene(gld
->pDev
);
1293 ctx
->bSceneStarted
= TRUE
;
1295 return (FAILED(hr
)) ? FALSE
: TRUE
;
1298 //---------------------------------------------------------------------------
1300 BOOL
gldGetDisplayMode_DX(
1302 GLD_displayMode
*glddm
)
1304 D3DDISPLAYMODE d3ddm
;
1306 GLD_driver_dx8
*lpCtx
= NULL
;
1307 BYTE cColorBits
, cRedBits
, cGreenBits
, cBlueBits
, cAlphaBits
;
1309 if ((glddm
== NULL
) || (ctx
== NULL
))
1312 lpCtx
= ctx
->glPriv
;
1316 if (lpCtx
->pD3D
== NULL
)
1319 hr
= IDirect3D8_GetAdapterDisplayMode(lpCtx
->pD3D
, glb
.dwAdapter
, &d3ddm
);
1323 // Get info from the display format
1324 _BitsFromDisplayFormat(d3ddm
.Format
,
1325 &cColorBits
, &cRedBits
, &cGreenBits
, &cBlueBits
, &cAlphaBits
);
1327 glddm
->Width
= d3ddm
.Width
;
1328 glddm
->Height
= d3ddm
.Height
;
1329 glddm
->BPP
= cColorBits
;
1330 glddm
->Refresh
= d3ddm
.RefreshRate
;
1335 //---------------------------------------------------------------------------