1
/*===========================================================================*/
3
/* Mesa-3.0 DirectX 6 Driver Build 5 */
7
/* http://www.altsoftware.com/ */
9
/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */
10
/*===========================================================================*/
12
/*===========================================================================*/
13
/* Local function prototypes. */
14
/*===========================================================================*/
15
static void DestroyAllSurfaces( PMESAD3DHAL pHAL );
16
static void DestroyDevice( PMESAD3DHAL pHAL );
17
static void DestroyInterfaces( PMESAD3DHAL pHAL );
19
HRESULT WINAPI EnumSurfacesHook( LPDIRECTDRAWSURFACE4 lpDDS, LPDDSURFACEDESC2 lpDDSDesc, LPVOID pVoid );
20
HRESULT CALLBACK EnumZBufferHook( DDPIXELFORMAT* pddpf, VOID *pVoid );
21
HRESULT CALLBACK EnumDeviceHook( GUID FAR* lpGuid, LPSTR lpDesc, LPSTR lpName, LPD3DDEVICEDESC lpD3DHWDesc, LPD3DDEVICEDESC lpD3DHELDesc, void *pVoid );
22
/*===========================================================================*/
24
/*===========================================================================*/
26
/*===========================================================================*/
27
/* This function is responable for allocating the actual MESAD3DHAL struct. */
28
/* Each Mesa context will have its own MESAD3DHAL struct so its like a mini */
29
/* context to some extent. All one time allocations/operations get done here.*/
30
/*===========================================================================*/
31
/* RETURN: TRUE, FALSE. */
32
/*===========================================================================*/
33
extern "C" PMESAD3DSHARED InitHAL( HWND hwnd )
38
DPF(( DBG_FUNC, "InitHAL();" ));
39
DPF(( DBG_CNTX_INFO, "hwnd: %d", hwnd ));
41
/* Allocate the structure and zero it out. */
42
pHAL = (PMESAD3DHAL)ALLOC( sizeof(MESAD3DHAL) );
45
RIP( pHAL, "InitHAL->", "Memory Allocation" );
46
return (PMESAD3DSHARED)NULL;
48
memset( pHAL, 0, sizeof(MESAD3DHAL) );
50
/* Get the texture manager going. */
51
rc = InitTMgrHAL( pHAL );
54
RIP( pHAL, "InitTMgrHAL->", "Failed" );
55
return (PMESAD3DSHARED)NULL;
58
/* Fill in the window parameters if we can. */
59
pHAL->shared.hwnd = hwnd;
61
/* Parse the user's enviroment variables to generate a debug mask. */
64
return (PMESAD3DSHARED)pHAL;
66
/*===========================================================================*/
67
/* This function will unload all the resources that the MESAD3DHAL struct */
68
/* has bound to it. The actual structure itself will be freed. */
69
/*===========================================================================*/
71
/*===========================================================================*/
72
extern "C" void TermHAL( PMESAD3DSHARED pShared )
74
PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared;
76
DPF(( DBG_FUNC, "TermHAL();" ));
78
/* Check for an empty wrapper structure. */
82
/* Kill this texture manager. */
85
/* Kill any DDraw stuff if exists. */
86
DestroyDevice( pHAL );
87
DestroyAllSurfaces( pHAL );
88
DestroyInterfaces( pHAL );
92
/*===========================================================================*/
93
/* This function is used to init and resize the rendering surface as the two*/
94
/* are almost the same. First the device and all the surfaces are destoryed */
95
/* if they already exist. Next we create a OffScreen rendering surface and */
96
/* save some pixelformat info to do color convertions. Next we start to take */
97
/* care of getting the most out of the hardware. I use bHardware to determine*/
98
/* the state of the device we found in the device enumeration. The enum proc*/
99
/* will try for hardware first. I next use a bForceSW to make the enum proc */
100
/* choose a software device. So I will try some combinations with HW first */
101
/* until I feel I have to set the bForceSW and call this function again. If */
102
/* this function is called with no width or height then use the internals. */
103
/* NOTE: The worst case is that all will be in SW (RGBDevice) and really */
104
/* I should forget the whole thing and fall back to a DDraw span type*/
105
/* rendering but what is the point. This way I always know I have a */
106
/* D3DDevice and that makes things easier. I do impliment the span */
107
/* rendering function for stuff that I haven't done support for such */
108
/* as points and lines. */
109
/*===========================================================================*/
110
/* RETURN: TRUE, FALSE */
111
/*===========================================================================*/
112
extern "C" BOOL CreateHAL( PMESAD3DSHARED pShared )
114
PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared;
115
DDSURFACEDESC2 ddsd2;
116
D3DDEVICEDESC D3DSWDevDesc;
123
DPF(( DBG_FUNC, "CreateHAL();" ));
125
#define InitDDSD2(f) memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); \
126
ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); \
132
/* Use the internal rectangle struct. */
133
dwWidth = pShared->rectW.right - pShared->rectW.left;
134
dwHeight = pShared->rectW.bottom - pShared->rectW.top;
136
DPF(( DBG_CNTX_INFO, "Width: %d Height: %d", dwWidth, dwHeight ));
138
/* The dimensions might still be the same so just leave. */
139
if ( (dwWidth == pShared->dwWidth) && (dwHeight == pShared->dwHeight) )
141
DPF(( DBG_CNTX_WARN, "Context size hasn't changed" ));
145
/* If one of the dimensions are zero then leave. WM_SIZE should get us back here. */
146
if ( (dwWidth == 0) || (dwHeight == 0) )
149
/* Save the renders dimensions. */
150
pShared->dwWidth = dwWidth;
151
pShared->dwHeight = dwHeight;
153
DPF(( DBG_CNTX_INFO, "Creating Context:\n cx:%d cy:%d", pShared->dwWidth, pShared->dwHeight ));
155
/*=================================*/
156
/* Create all required interfaces. */
157
/*=================================*/
159
/* Kill any DDraw stuff if exists. */
160
DestroyDevice( pHAL );
161
DestroyAllSurfaces( pHAL );
162
DestroyInterfaces( pHAL );
164
/* Create a instance of DDraw using the Primary display driver. */
165
rc = DirectDrawCreate( NULL, &pHAL->lpDD, NULL );
168
RIP( pHAL, "DirectDrawCreate->", ErrorStringD3D(rc) );
172
/* Get the DDraw4 interface. */
173
rc = pHAL->lpDD->QueryInterface( IID_IDirectDraw4, (void **)&pHAL->lpDD4 );
176
RIP( pHAL, "QueryInterface (IID_IDirectDraw4) ->", ErrorStringD3D(rc) );
180
/* Get the Direct3D3 interface. */
181
rc = pHAL->lpDD4->QueryInterface( IID_IDirect3D3, (void **)&pHAL->lpD3D3 );
184
RIP( pHAL, "QueryInterface (IID_IDirect3D3) ->", ErrorStringD3D(rc) );
188
/* Set the Cooperative level. NOTE: we need to know if we are FS at this point.*/
189
dwCoopFlags = (pShared->bWindow == TRUE) ? DDSCL_NORMAL : (DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
190
rc = pHAL->lpDD4->SetCooperativeLevel( pShared->hwnd, dwCoopFlags );
193
RIP( pHAL, "SetCooperativeLevel->", ErrorStringD3D(rc) );
197
/*==================================================================*/
198
/* Get the best device we can and note whether its hardware or not. */
199
/*==================================================================*/
200
pShared->bForceSW = FALSE;
201
pHAL->lpD3D3->EnumDevices( EnumDeviceHook, (void *)pHAL );
202
pShared->bHardware = IsEqualIID( pHAL->guid, IID_IDirect3DHALDevice );
203
DPF(( DBG_CNTX_INFO, "bHardware: %s", (pShared->bHardware) ? "TRUE" : "FALSE" ));
204
DPF(( DBG_CNTX_INFO, "bWindowed: %s", (pShared->bWindow) ? "TRUE" : "FALSE" ));
206
/*========================================================================*/
207
/* HARDWARE was found. */
208
/*========================================================================*/
209
if ( pShared->bHardware == TRUE )
211
/*===================================*/
212
/* HARDWARE -> Z-BUFFER. */
213
/*===================================*/
215
/* Get a Z-Buffer pixelformat. */
216
memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );
217
ddsd2.dwSize = sizeof( DDSURFACEDESC2 );
218
rc = pHAL->lpD3D3->EnumZBufferFormats( pHAL->guid, EnumZBufferHook, (VOID*)&ddsd2.ddpfPixelFormat );
221
RIP( pHAL, "EnumZBufferFormatsl->", ErrorStringD3D(rc) );
225
/* Setup our request structure for the Z-buffer surface. */
226
ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
227
ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
228
ddsd2.dwWidth = dwWidth;
229
ddsd2.dwHeight = dwHeight;
230
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSZbuffer, NULL );
233
DPF(( DBG_CNTX_INFO, "HW ZBuffer" ));
235
/*===================================*/
236
/* HARDWARE -> Z-BUFFER -> FLIPABLE */
237
/*===================================*/
238
if ( pShared->bWindow == FALSE )
240
InitDDSD2( DDSD_CAPS | DDSD_BACKBUFFERCOUNT );
241
ddsd2.dwBackBufferCount = 1;
242
ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
243
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );
246
/* Make sure we try the next fall back. */
247
DPF(( DBG_CNTX_WARN, "HW Flip/Complex not available" ));
248
pHAL->lpDDSPrimary = NULL;
252
/* Get the back buffer that was created. */
253
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
254
rc = pHAL->lpDDSPrimary->GetAttachedSurface( &ddscaps, &pHAL->lpDDSRender );
257
DPF(( DBG_CNTX_WARN, "GetAttachedSurface failed -> HW Flip/Complex" ));
259
/* Make sure we try the next fall back. */
260
pHAL->lpDDSPrimary->Release();
261
pHAL->lpDDSPrimary = NULL;
265
/* I have had problems when a complex surface comes back */
266
/* with the back buffer being created in SW. Not sure why */
267
/* or how this is possable but I'm checking for it here. */
268
memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );
269
ddsd2.dwSize = sizeof( DDSURFACEDESC2 );
270
DX_RESTORE( pHAL->lpDDSRender );
271
rc = pHAL->lpDDSRender->GetSurfaceDesc( &ddsd2 );
274
RIP( pHAL, "GetSurfaceDesc (RENDER) ->", ErrorStringD3D(rc) );
278
/* If the surface is in VID then we are happy with are Flipable. */
279
if ( ddsd2.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM )
281
pShared->bFlipable = TRUE;
282
DPF(( DBG_CNTX_INFO, "HW Flip/Complex!" ));
286
/* Kill this setup. */
287
pHAL->lpDDSPrimary->Release();
288
pHAL->lpDDSPrimary = NULL;
294
/*===================================*/
295
/* HARDWARE -> Z-BUFFER -> BLT */
296
/*===================================*/
297
if ( pHAL->lpDDSPrimary == NULL )
299
pShared->bFlipable = FALSE;
301
/* Create the Primary (front buffer). */
302
InitDDSD2( DDSD_CAPS );
303
ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
304
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );
307
/* This is an error as we should be able to do this at minimum. */
308
RIP( pHAL, "CreateSurface (PRIMARY) ->", ErrorStringD3D(rc) );
312
/* Create the Render (back buffer). */
313
InitDDSD2( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT );
314
ddsd2.dwWidth = dwWidth;
315
ddsd2.dwHeight = dwHeight;
316
ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
317
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSRender, NULL );
320
DPF(( DBG_CNTX_WARN, "Failed HW Offscreen surface" ));
322
/* Make sure we try the next fall back. */
323
pHAL->lpDDSPrimary->Release();
324
pHAL->lpDDSPrimary = NULL;
328
/* Might as well check here too see if this surface is in */
329
/* hardware. If nothing else just to be consistant. */
330
memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );
331
ddsd2.dwSize = sizeof( DDSURFACEDESC2 );
332
DX_RESTORE( pHAL->lpDDSRender );
333
rc = pHAL->lpDDSRender->GetSurfaceDesc( &ddsd2 );
336
RIP( pHAL, "GetSurfaceDesc (RENDER) ->", ErrorStringD3D(rc) );
340
/* If the surface is in VID then we are happy. */
341
if ( ddsd2.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM )
343
/* Create a clipper object so that DDraw will be able to blt windows that */
344
/* have been clipped by the screen or other windows. */
345
pHAL->lpDD4->CreateClipper( 0, &pHAL->lpClipper, NULL );
346
pHAL->lpClipper->SetHWnd( 0, pShared->hwnd );
347
pHAL->lpDDSPrimary->SetClipper( pHAL->lpClipper );
348
pHAL->lpClipper->Release();
349
DPF(( DBG_CNTX_INFO, "HW RENDER surface" ));
353
/* Kill this setup. */
354
pHAL->lpDDSRender->Release();
355
pHAL->lpDDSRender = NULL;
356
pHAL->lpDDSPrimary->Release();
357
pHAL->lpDDSPrimary = NULL;
362
/*===================================*/
363
/* Create D3DDEVICE -> HARDWARE. */
364
/*===================================*/
365
if ( pHAL->lpDDSZbuffer && pHAL->lpDDSPrimary && pHAL->lpDDSRender )
367
DX_RESTORE( pHAL->lpDDSRender );
368
DX_RESTORE( pHAL->lpDDSZbuffer );
370
rc = pHAL->lpDDSRender->AddAttachedSurface( pHAL->lpDDSZbuffer );
373
RIP( pHAL, "AddAttachedSurface (ZBUFFER) ->", ErrorStringD3D(rc) );
377
rc = pHAL->lpD3D3->CreateDevice( IID_IDirect3DHALDevice, pHAL->lpDDSRender, &pHAL->lpD3DDevice, NULL );
380
DPF(( DBG_CNTX_WARN, "Failed HW Device" ));
381
pHAL->lpD3DDevice = NULL;
385
DPF(( DBG_CNTX_INFO, "HW Device" ));
391
/*========================================================================*/
392
/* SOFTWARE fallback. */
393
/*========================================================================*/
394
if ( pHAL->lpD3DDevice == NULL )
396
DPF(( DBG_CNTX_INFO, "SW fallback :(" ));
398
/* Make sure we have no surfaces allocated. Just incase. */
399
DestroyAllSurfaces( pHAL );
401
/* Get a software device. */
402
pShared->bFlipable = FALSE;
403
pShared->bForceSW = TRUE;
404
pHAL->lpD3D3->EnumDevices( EnumDeviceHook, (void *)pHAL );
405
pShared->bHardware = IsEqualIID( pHAL->guid, IID_IDirect3DHALDevice );
407
/*===================================*/
408
/* SOFTWARE -> Z-BUFFER. */
409
/*===================================*/
411
/*===================================*/
412
/* SOFTWARE -> Z-BUFFER -> FLIPABLE */
413
/*===================================*/
414
if ( pShared->bWindow == FALSE )
416
InitDDSD2( DDSD_CAPS | DDSD_BACKBUFFERCOUNT );
417
ddsd2.dwBackBufferCount = 1;
418
ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
419
ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT );
420
ddsd2.ddpfPixelFormat.dwFlags = (DDPF_RGB | DDPF_ALPHAPIXELS);
421
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );
424
DPF(( DBG_CNTX_WARN, "Failed SW Flip/Complex" ));
426
/* Make sure we try the next fall back. */
427
pHAL->lpDDSPrimary = NULL;
431
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
432
rc = pHAL->lpDDSPrimary->GetAttachedSurface( &ddscaps, &pHAL->lpDDSRender );
435
/* Make sure we try the next fall back. */
436
DPF(( DBG_CNTX_WARN, "GetAttachedSurface failed -> SW Flip/Complex" ));
437
pHAL->lpDDSPrimary->Release();
438
pHAL->lpDDSPrimary = NULL;
442
DPF(( DBG_CNTX_INFO, "SW Flip/Complex" ));
443
pShared->bFlipable = TRUE;
448
/*===================================*/
449
/* SOFTWARE -> Z-BUFFER -> BLT */
450
/*===================================*/
451
if ( pHAL->lpDDSPrimary == NULL )
453
/* Create the Primary (front buffer). */
454
InitDDSD2( DDSD_CAPS );
455
ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
456
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );
459
/* This is an error as we should be able to do this at minimum. */
460
RIP( pHAL, "CreateSurface (PRIMARY) ->", ErrorStringD3D(rc) );
464
/* Create the Render (back buffer). */
465
InitDDSD2( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT );
466
ddsd2.dwWidth = dwWidth;
467
ddsd2.dwHeight = dwHeight;
468
ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
469
ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT );
470
ddsd2.ddpfPixelFormat.dwFlags = (DDPF_RGB | DDPF_ALPHAPIXELS);
471
rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSRender, NULL );
474
/* That was our last hope. */
475
RIP( pHAL, "CreateSurface (RENDER) ->", ErrorStringD3D(rc) );
480
DPF(( DBG_CNTX_INFO, "SW RENDER surface" ));
482
/* Create a clipper object so that DDraw will be able to blt windows that */
483
/* have been clipped by the screen or other windows. */
484
pHAL->lpDD4->CreateClipper( 0, &pHAL->lpClipper, NULL );
485
pHAL->lpClipper->SetHWnd( 0, pShared->hwnd );
486
pHAL->lpDDSPrimary->SetClipper( pHAL->lpClipper );
487
pHAL->lpClipper->Release();
491
/*===================================*/
492
/* Create D3DDEVICE -> SOFTWARE. */
493
/*===================================*/
494
if ( pHAL->lpDDSPrimary && pHAL->lpDDSRender )
496
DX_RESTORE( pHAL->lpDDSRender );
497
rc = pHAL->lpD3D3->CreateDevice( IID_IDirect3DRGBDevice, pHAL->lpDDSRender, &pHAL->lpD3DDevice, NULL );
500
/* That was our last hope. */
501
RIP( pHAL, "CreateDevice (IID_IDirect3DRGBDevice) ->", ErrorStringD3D(rc) );
505
DPF(( DBG_CNTX_INFO, "SW Device" ));
509
/*==============================================================================*/
510
/* Get a copy of the render pixelformat so that wgl.c can call GetPixelInfoD3D. */
511
/*==============================================================================*/
512
memset( &pHAL->ddpf, 0, sizeof(DDPIXELFORMAT) );
513
pHAL->ddpf.dwSize = sizeof( DDPIXELFORMAT );
514
rc = pHAL->lpDDSRender->GetPixelFormat( &pHAL->ddpf );
517
RIP( pHAL, "GetPixelFormat ->", ErrorStringD3D(rc) );
520
DebugPixelFormat( "Using OFFSCREEN", &pHAL->ddpf );
521
DebugPixelFormat( "Using ZBUFFER", &ddsd2.ddpfPixelFormat );
523
/* Get a copy of what the D3DDevice supports for later use. */
524
memset( &D3DSWDevDesc, 0, sizeof(D3DDEVICEDESC) );
525
memset( &pHAL->D3DHWDevDesc, 0, sizeof(D3DDEVICEDESC) );
526
D3DSWDevDesc.dwSize = sizeof( D3DDEVICEDESC );
527
pHAL->D3DHWDevDesc.dwSize = sizeof( D3DDEVICEDESC );
528
rc = pHAL->lpD3DDevice->GetCaps( &pHAL->D3DHWDevDesc, &D3DSWDevDesc );
531
RIP( pHAL, "GetCaps ->", ErrorStringD3D(rc) );
535
/* Get a copy of the pixel convertion stuff for direct buffer access. */
536
Solve8BitChannelPixelFormat( &pHAL->ddpf, &pShared->pixel );
537
AlphaBlendTableHAL( pHAL );
539
/* We must prime the Begin/End scene for SwapBuffers to work. */
540
rc = pHAL->lpD3DDevice->BeginScene();
543
RIP( pHAL, "BeginScene ->", ErrorStringD3D(rc) );
551
/*===========================================================================*/
552
/* This function will make sure a viewport is created and set for the device*/
553
/* in the supplied structure. If a rect is supplied then it will be used for*/
554
/* the viewport otherwise the current setting in the strucute will be used. */
555
/* Note that the rect is relative to the window. So left/top must be 0,0 to */
556
/* use the whole window else there is scissoring going down. */
557
/*===========================================================================*/
558
/* RETURN: TRUE, FALSE. */
559
/*===========================================================================*/
560
extern "C" BOOL SetViewportHAL( PMESAD3DSHARED pShared, RECT *pRect, float minZ, float maxZ )
562
PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared;
567
DPF(( DBG_FUNC, "SetViewportHAL();" ));
569
/* Make sure we have enough info. */
570
if ( !pHAL || !pHAL->lpDDSPrimary || !pHAL->lpD3DDevice )
572
DPF(( DBG_CNTX_WARN, "SetViewport() -> NULL Pointer" ));
576
/* TODO: this is just a temp fix to stop redundant changes. */
578
(pShared->rectV.left == pRect->left) &&
579
(pShared->rectV.right == pRect->right) &&
580
(pShared->rectV.top == pRect->top) &&
581
(pShared->rectV.bottom == pRect->bottom) )
583
DPF(( DBG_CNTX_WARN, "Redundant viewport" ));
587
DPF(( DBG_CNTX_INFO, "Current Viewport:" ));
588
DPF(( DBG_CNTX_INFO, "x: %d y: %d", pShared->rectV.left, pShared->rectV.top ));
589
DPF(( DBG_CNTX_INFO, "cx: %d cy: %d", (pShared->rectV.right-pShared->rectV.left), (pShared->rectV.bottom-pShared->rectV.top) ));
590
DPF(( DBG_CNTX_INFO, "New Viewport:" ));
591
DPF(( DBG_CNTX_INFO, "x: %d y: %d", pRect->left, pRect->top ));
592
DPF(( DBG_CNTX_INFO, "cx: %d cy: %d", (pRect->right-pRect->left), (pRect->bottom-pRect->top) ));
594
/* Update the current viewport rect if one is supplied. */
596
memcpy( &pShared->rectV, pRect, sizeof(RECT) );
598
/* Build the request structure. */
599
memset( &vdData, 0, sizeof(D3DVIEWPORT2) );
600
vdData.dwSize = sizeof(D3DVIEWPORT2);
601
vdData.dwX = pShared->rectV.left;
602
vdData.dwY = pShared->rectV.top;
603
vdData.dwWidth = (pShared->rectV.right - pShared->rectV.left);
604
vdData.dwHeight = (pShared->rectV.bottom - pShared->rectV.top);
606
if ( !vdData.dwWidth || !vdData.dwHeight )
608
GetClientRect( pShared->hwnd, &pShared->rectW );
610
ClientToScreen( pShared->hwnd, &pt );
611
OffsetRect( &pShared->rectW, pt.x, pt.y);
612
vdData.dwX = pShared->rectW.left;
613
vdData.dwY = pShared->rectW.top;
614
vdData.dwWidth = (pShared->rectW.right - pShared->rectW.left);
615
vdData.dwHeight = (pShared->rectW.bottom - pShared->rectW.top);
616
memcpy( &pShared->rectV, &pShared->rectW, sizeof(RECT) );
619
// The dvClipX, dvClipY, dvClipWidth, dvClipHeight, dvMinZ,
620
// and dvMaxZ members define the non-normalized post-perspective
621
// 3-D view volume which is visible to the viewer. In most cases,
622
// dvClipX is set to -1.0 and dvClipY is set to the inverse of
623
// the viewport's aspect ratio on the target surface, which can be
624
// calculated by dividing the dwHeight member by dwWidth. Similarly,
625
// the dvClipWidth member is typically 2.0 and dvClipHeight is set
626
// to twice the aspect ratio set in dwClipY. The dvMinZ and dvMaxZ
627
// are usually set to 0.0 and 1.0.
628
vdData.dvClipX = -1.0f;
629
vdData.dvClipWidth = 2.0f;
630
vdData.dvClipY = 1.0f;
631
vdData.dvClipHeight = 2.0f;
632
vdData.dvMaxZ = maxZ;
633
vdData.dvMinZ = minZ;
635
DPF(( DBG_CNTX_INFO, "zMin: %f zMax: %f", minZ, maxZ ));
637
/* I'm going to destroy the viewport everytime as when we size we will */
638
/* have a new D3DDevice. As this area doesn't need to be fast... */
639
if ( pHAL->lpViewport )
641
DPF(( DBG_CNTX_INFO, "DeleteViewport" ));
643
pHAL->lpD3DDevice->DeleteViewport( pHAL->lpViewport );
644
rc = pHAL->lpViewport->Release();
645
pHAL->lpViewport = NULL;
648
rc = pHAL->lpD3D3->CreateViewport( &pHAL->lpViewport, NULL );
651
DPF(( DBG_CNTX_ERROR, "CreateViewport Failed" ));
655
/* Update the device with the new viewport. */
656
pHAL->lpD3DDevice->AddViewport( pHAL->lpViewport );
657
pHAL->lpViewport->SetViewport2( &vdData );
658
pHAL->lpD3DDevice->SetCurrentViewport( pHAL->lpViewport );
662
/*===========================================================================*/
665
/*===========================================================================*/
667
/*===========================================================================*/
668
HRESULT WINAPI EnumSurfacesHook( LPDIRECTDRAWSURFACE4 lpDDS, LPDDSURFACEDESC2 lpDDSDesc, LPVOID pVoid )
670
DDSURFACEDESC2 *pddsd2 = (DDSURFACEDESC2 *)pVoid;
672
DPF(( DBG_FUNC, "EnumSurfacesHook();" ));
674
if ( (lpDDSDesc->ddpfPixelFormat.dwFlags == pddsd2->ddpfPixelFormat.dwFlags) && (lpDDSDesc->ddsCaps.dwCaps == pddsd2->ddsCaps.dwCaps) )
676
/* Save the pixelformat now so that we know we have one. */
677
memcpy( pddsd2, lpDDSDesc, sizeof(DDSURFACEDESC2) );
679
return D3DENUMRET_CANCEL;
682
return D3DENUMRET_OK;
684
/*===========================================================================*/
685
/* This is the callback proc to get a Z-Buffer. Thats it. */
686
/*===========================================================================*/
688
/*===========================================================================*/
689
HRESULT CALLBACK EnumZBufferHook( DDPIXELFORMAT* pddpf, VOID *pVoid )
691
DDPIXELFORMAT *pddpfChoice = (DDPIXELFORMAT *)pVoid;
693
DPF(( DBG_FUNC, "EnumZBufferHook();" ));
695
/* If this is ANY type of depth-buffer, stop. */
696
if( pddpf->dwFlags == DDPF_ZBUFFER )
698
/* Save the pixelformat now so that we know we have one. */
699
memcpy( pddpfChoice, pddpf, sizeof(DDPIXELFORMAT) );
701
/* I feel if the hardware supports this low then lets use it. Could get ugly. */
702
if( pddpf->dwZBufferBitDepth >= 8 )
704
return D3DENUMRET_CANCEL;
708
return D3DENUMRET_OK;
710
/*===========================================================================*/
711
/* This function handles the callback for the D3DDevice enumeration. Good */
712
/* god who's idea was this? The D3D wrapper has two variable related to what*/
713
/* kind of device we want and have. First we have a Bool that is set if we */
714
/* have allocated a HW device. We always look for the HW device first. The */
715
/* other variable is used to force SW. If we have run into a case that we */
716
/* want to fallback to SW then we set this. We will fallback if we cannot */
717
/* texture in video memory (among others). */
718
/*===========================================================================*/
720
/*===========================================================================*/
721
HRESULT CALLBACK EnumDeviceHook( GUID FAR* lpGuid, LPSTR lpDesc, LPSTR lpName, LPD3DDEVICEDESC lpD3DHWDesc, LPD3DDEVICEDESC lpD3DHELDesc, void *pVoid )
723
PMESAD3DHAL pHAL = (PMESAD3DHAL)pVoid;
724
LPD3DDEVICEDESC pChoice = lpD3DHWDesc;
726
DPF(( DBG_FUNC, "EnumDeviceHook();" ));
728
/* Determine if which device description is valid. */
729
if ( pChoice->dcmColorModel == 0 )
730
pChoice = lpD3DHELDesc;
732
/* Make sure we always have a GUID. */
733
memcpy( &pHAL->guid, lpGuid, sizeof(GUID) );
735
/* This controls whether we will except HW or not. */
736
if ( pHAL->shared.bForceSW == TRUE )
738
return (pChoice == lpD3DHELDesc) ? D3DENUMRET_CANCEL : D3DENUMRET_OK;
741
/* Always try for hardware. */
742
if ( pChoice == lpD3DHWDesc )
744
return D3DENUMRET_CANCEL;
747
return D3DENUMRET_OK;
749
/*===========================================================================*/
750
/* This function will destroy any and all surfaces that this context has */
751
/* allocated. If there is a clipper object then it will also be destoryed as*/
752
/* it is part of the Primary Surface. */
753
/*===========================================================================*/
755
/*===========================================================================*/
756
static void DestroyAllSurfaces( PMESAD3DHAL pHAL )
760
DPF(( DBG_FUNC, "DestroyAllSurfaces();" ));
762
DX_RESTORE( pHAL->lpDDSPrimary );
763
DX_RESTORE( pHAL->lpDDSRender );
764
DX_RESTORE( pHAL->lpDDSZbuffer);
766
if ( pHAL->lpDDSRender )
768
pHAL->lpDDSRender->Unlock( NULL );
770
/* If this isn't a Flipable surface then we must clean up the render. */
771
if ( pHAL->shared.bFlipable == FALSE)
773
if ( pHAL->lpDDSZbuffer )
775
DPF(( DBG_CNTX_INFO, "Remove attached surfaces from RENDER" ));
776
pHAL->lpDDSRender->DeleteAttachedSurface( 0, NULL );
779
DPF(( DBG_CNTX_INFO, "Release RENDER" ));
780
refCount = pHAL->lpDDSRender->Release();
781
pHAL->lpDDSRender = NULL;
785
if ( pHAL->lpDDSZbuffer )
787
DPF(( DBG_CNTX_INFO, "Release ZBuffer" ));
788
pHAL->lpDDSZbuffer->Unlock( NULL );
789
refCount = pHAL->lpDDSZbuffer->Release();
790
pHAL->lpDDSZbuffer = NULL;
793
if ( pHAL->lpClipper )
795
DPF(( DBG_CNTX_INFO, "Release Clipper" ));
796
refCount = pHAL->lpClipper->Release();
797
pHAL->lpClipper = NULL;
800
if ( pHAL->lpDDSPrimary )
802
pHAL->lpDDSPrimary->Unlock( NULL );
804
DPF(( DBG_CNTX_INFO, "Release PRIMARY" ));
805
refCount = pHAL->lpDDSPrimary->Release();
806
pHAL->lpDDSPrimary = NULL;
809
/*===========================================================================*/
810
/* This function will destroy the current D3DDevice and any resources that */
812
/*===========================================================================*/
814
/*===========================================================================*/
815
static void DestroyDevice( PMESAD3DHAL pHAL )
819
DPF(( DBG_FUNC, "DestroyDevice();" ));
821
/* Kill the D3D stuff if exists. */
822
if ( pHAL->lpViewport )
824
DPF(( DBG_CNTX_INFO, "Delete Viewport" ));
825
pHAL->lpD3DDevice->DeleteViewport( pHAL->lpViewport );
827
DPF(( DBG_CNTX_INFO, "Release Viewport" ));
828
refCount = pHAL->lpViewport->Release();
829
pHAL->lpViewport = NULL;
832
if ( pHAL->lpD3DDevice != NULL )
834
DPF(( DBG_CNTX_INFO, "Release D3DDevice" ));
835
refCount = pHAL->lpD3DDevice->EndScene();
836
refCount = pHAL->lpD3DDevice->Release();
837
pHAL->lpD3DDevice = NULL;
840
/*===========================================================================*/
841
/* This function will destroy the current D3DDevice and any resources that */
843
/*===========================================================================*/
845
/*===========================================================================*/
846
static void DestroyInterfaces( PMESAD3DHAL pHAL )
850
DPF(( DBG_FUNC, "DestroyInterfaces();" ));
852
if ( pHAL->lpD3D3 != NULL )
854
DPF(( DBG_CNTX_INFO, "Release Direct3D3" ));
855
refCount = pHAL->lpD3D3->Release();
859
if ( pHAL->lpDD4 != NULL )
861
DPF(( DBG_CNTX_INFO, "Release DDraw4" ));
862
refCount = pHAL->lpDD4->Release();
866
if ( pHAL->lpDD != NULL )
868
DPF(( DBG_CNTX_INFO, "Release DDraw" ));
869
refCount = pHAL->lpDD->Release();
873
/*===========================================================================*/
874
/* This function will first send (not post) a message to the client window */
875
/* that this context is using. The client will respond by unbinding itself */
876
/* and binding the 'default' context. This allows the API to be supported */
877
/* until the window can be destroyed. Finally we post the quit message to */
878
/* the client in hopes to end the application. */
879
/*===========================================================================*/
881
/*===========================================================================*/
882
void FatalShutDown( PMESAD3DHAL pHAL )
884
/* Whip this baby in too try and support the API until we die... */
886
SendMessage( pHAL->shared.hwnd, UM_FATALSHUTDOWN, 0L, 0L );
888
/* Close the client application down. */
889
PostQuitMessage( 0 );