You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7086 lines
281 KiB
7086 lines
281 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1994-1999 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: ddgdi32.c
|
|
* Content: Contains the cross-process mapping layer similar to gdi32.dll
|
|
* on NT that the per-process DLL calls into on Win9X.
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 11-oct-99 smac initial implementation
|
|
*
|
|
***************************************************************************/
|
|
#include "ddrawpr.h"
|
|
#include "dx8priv.h"
|
|
|
|
#include "d3d8p.h"
|
|
#include "d3d8ddi.h"
|
|
#include "d3d8sddi.h"
|
|
#include "ddithunk.h"
|
|
|
|
extern HRESULT DDAPI DD_CreateSurface4_Main(LPDIRECTDRAW lpDD,LPDDSURFACEDESC2 lpDDSurfaceDesc,
|
|
LPDIRECTDRAWSURFACE FAR *lplpDDSurface,IUnknown FAR *pUnkOuter,BOOL bDoSurfaceDescCheck,
|
|
LPDDSURFACEINFO pSysMemInfo, DWORD DX8Flags);
|
|
|
|
extern void invalidateSurface(LPDDRAWI_DDRAWSURFACE_LCL this_lcl);
|
|
extern void makeDEVMODE(LPDDRAWI_DIRECTDRAW_GBL this, LPDDHALMODEINFO pmi, BOOL inexcl, BOOL useRefreshRate, LPDWORD pcds_flags, LPDEVMODE pdm);
|
|
|
|
void LoseDevice (DDDEVICEHANDLE* pDevice);
|
|
|
|
DDDEVICEHANDLE* pDeviceList = NULL;
|
|
|
|
// Bogus value used to initialize write only fields when communicating
|
|
// with the driver in debug builds
|
|
#define BOGUS_FIELD_VALUE 0xBAADCAFEul
|
|
|
|
typedef struct _KNOWNENTRY
|
|
{
|
|
DWORD PCIID;
|
|
DWORD VersionMajor; // 0 means all versions
|
|
DWORD VersionMinor; // 0 means all versions
|
|
DWORD Flags;
|
|
} KNOWNENTRY;
|
|
|
|
const KNOWNENTRY gKnownDeviceList[] =
|
|
{
|
|
// NVidia
|
|
{0x12D20018, 0, 0, KNOWN_ZSTENCILDEPTH}, // Riva 128
|
|
{0x10DE0020, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT
|
|
{0x10DE0028, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2
|
|
{0x10DE0029, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2 Ultra
|
|
{0x10DE002C, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Vanta
|
|
{0x10DE002D, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // TNT2 Model 64
|
|
{0x10DE00A0, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Aladdin TNT2
|
|
{0x10DE0100, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (GeForce)
|
|
{0x10DE0101, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (GeForce DDR)
|
|
{0x10DE0103, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV10 (Quadro)
|
|
{0x10DE0110, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV11 (GeForce2 MX)
|
|
{0x10DE0111, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV11 (GeForce2 MX)
|
|
{0x10DE0113, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV11 (Quadro2 MXR)
|
|
{0x10DE0150, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2)
|
|
{0x10DE0151, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2 DDR)
|
|
{0x10DE0152, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (GeForce2 BR)
|
|
{0x10DE0153, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV15 (Quadro2)
|
|
{0x10DE0200, 0, 0, KNOWN_LIGHTWEIGHT|KNOWN_D16_LOCKABLE|KNOWN_MIPPEDCUBEMAPS|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // NV20 (GeForce 3)
|
|
// 3DFX
|
|
{0x121A0003, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5}, // Banshee
|
|
{0x121A0005, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5}, // Voodoo3
|
|
{0x121a0009, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A8R8G8B8}, // Voodoo4/5; same PCI-ID
|
|
// ATI
|
|
{0x10024742, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024744, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024749, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x1002474D, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x1002474E, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x1002474F, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024750, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024752, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024C42, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro (PCI)
|
|
{0x10024C49, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro (PCI)
|
|
{0x10024C4E, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024C52, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024C53, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro
|
|
{0x10024C60, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // RagePro LT
|
|
|
|
{0x10024C4D, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X1R5G5B5}, // Rage Mobility AGP
|
|
|
|
{0x10024C46, 0x0004000c, 0x00010411, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
|
|
{0x10024C46, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
|
|
{0x10024D46, 0x0004000c, 0x00010411, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
|
|
{0x10024D46, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage Mobility 128
|
|
|
|
{0x10025046, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS
|
|
{0x10025046, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS
|
|
{0x10025245, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
|
|
{0x10025245, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
|
|
{0x10025246, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
|
|
{0x10025246, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
|
|
{0x1002524B, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 VR PCI //DX8.1
|
|
{0x1002524B, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 VR PCI //DX8.1
|
|
{0x1002524C, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
|
|
{0x1002524C, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128
|
|
|
|
//New 128s for DX8.1:
|
|
{0x10025041, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
|
|
{0x10025041, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
|
|
{0x10025042, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x10025042, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x10025043, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x10025043, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x10025044, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x10025044, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x10025045, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x10025045, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x10025047, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
|
|
{0x10025047, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
|
|
{0x10025048, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x10025048, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x10025049, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x10025049, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x1002504a, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x1002504a, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x1002504b, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x1002504b, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x1002504c, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
|
|
{0x1002504c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
|
|
{0x1002504d, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP DX8.1
|
|
{0x1002504d, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP DX8.1
|
|
{0x1002504e, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x1002504e, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x1002504f, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x1002504f, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x10025050, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x10025050, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x10025051, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x10025051, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x10025052, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
|
|
{0x10025052, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
|
|
{0x10025053, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
|
|
{0x10025053, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI DX8.1
|
|
{0x10025054, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x10025054, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X DX8.1
|
|
{0x10025055, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x10025055, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X DX8.1
|
|
{0x10025056, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x10025056, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO PCI TMDS DX8.1
|
|
{0x10025057, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x10025057, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 2X TMDS DX8.1
|
|
{0x10025058, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
|
|
{0x10025058, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO AGP 4X TMDS DX8.1
|
|
|
|
{0x10025345, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
|
|
{0x10025345, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
|
|
{0x10025346, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
|
|
{0x10025346, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
|
|
{0x10025347, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
|
|
{0x10025347, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
|
|
{0x10025348, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
|
|
{0x10025348, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
|
|
{0x1002534b, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
|
|
{0x1002534b, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X PCI DX8.1
|
|
{0x1002534c, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
|
|
{0x1002534c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 2X DX8.1
|
|
{0x1002534d, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
|
|
{0x1002534d, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X AGP 4X DX8.1
|
|
{0x1002534e, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
|
|
{0x1002534e, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 4X DX8.1
|
|
|
|
{0x10025446, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA GL AGP DX8.1
|
|
{0x10025446, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA GL AGP DX8.1
|
|
{0x1002544c, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA VR AGP DX8.1
|
|
{0x1002544c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA VR AGP DX8.1
|
|
{0x10025452, 0x0004000c, 0x00011f43, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA4XL VR-R AGP DX8.1
|
|
{0x10025452, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage128 PRO ULTRA4XL VR-R AGP DX8.1
|
|
|
|
{0x10025144, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
|
|
{0x10025145, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
|
|
{0x10025146, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
|
|
{0x10025147, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Rage6
|
|
|
|
// Intel
|
|
{0x80867800, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Intel i740
|
|
{0x80867123, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 810
|
|
{0x80867125, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 810e
|
|
{0x80861132, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_R5G6B5}, // Intel 815
|
|
{0x80861A12, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Intel Timna
|
|
|
|
// Matrox
|
|
{0x102b0520, 0x0004000b, 0x000110ea, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G200 PCI
|
|
{0x102b0520, 0, 0, KNOWN_ZSTENCILDEPTH}, // G200 PCI
|
|
{0x102b0521, 0x0004000b, 0x000110ea, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G200 AGP
|
|
{0x102b0521, 0, 0, KNOWN_ZSTENCILDEPTH}, // G200 AGP
|
|
{0x102b0525, 0x0004000b, 0x000110ea, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G400, G450
|
|
{0x102b0525, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // G400, G450
|
|
// 3DLabs
|
|
{0x3d3d0008, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH}, // 3DLabs Gamma
|
|
{0x104c3d07, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8}, // Perm2
|
|
{0x3d3d0009, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8}, // Perm2
|
|
{0x3d3d000a, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
|
|
{0x3d3d000c, 0, 0, KNOWN_CANMISMATCHRT|KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Perm3
|
|
|
|
// Videologic
|
|
{0x104a0010, 0x0004000c, 0x0001080c, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // PowerVR Kyro updated driver
|
|
{0x104a0010, 0, 0, KNOWN_ZSTENCILDEPTH}, // PowerVR Kyro
|
|
// S3
|
|
{0x53338811, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge
|
|
{0x53335631, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge
|
|
{0x53338a01, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge DX/GX DX8.1
|
|
{0x53338c01, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge MX DX8.1
|
|
{0x53338a10, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X1R5G5B5}, // Virge GX2 DX8.1
|
|
{0x53338a20, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Savage3D
|
|
{0x53338a22, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage4
|
|
{0x53339102, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Savage2K
|
|
{0x53338c10, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // Savage MX DX8.1
|
|
{0x53338c12, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5}, // Savage IX DX8.1
|
|
{0x53338a25, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage Pro DX8.1
|
|
{0x53338a26, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Savage Pro DX8.1
|
|
// Trident
|
|
{0x10239880, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER}, // Trident Blade 3D 9880
|
|
{0x10238500, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident Blade 3D/ProMedia DX8.1
|
|
{0x10238400, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident Blade 3D/MVP4 DX8.1
|
|
{0x10238420, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident CyberBlade i7
|
|
{0x10239910, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // Trident CyberBlade DX8.1
|
|
// SiS
|
|
{0x10390300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_RTTEXTURE_R5G6B5}, // SiS 300
|
|
{0x10390300, 0x0004000d, 0x000107da, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 300
|
|
{0x10395300, 0x0004000d, 0x000107da, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 300
|
|
{0x10396326, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_NOTAWINDOWEDBLTQUEUER}, // SiS 6326
|
|
{0x10396300, 0, 0, KNOWN_ZSTENCILDEPTH|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5}, // SiS 6300
|
|
{0x10396300, 0x0004000d, 0x000107da, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
|
|
{0x10390310, 0x0004000d, 0x00010352, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
|
|
{0x10390315, 0x0004000d, 0x00010352, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
|
|
{0x10390325, 0x0004000c, 0x000107d3, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 6300
|
|
{0x10396325, 0x0004000c, 0x000107d3, KNOWN_ZSTENCILDEPTH|KNOWN_D16_LOCKABLE|KNOWN_CANMISMATCHRT|KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_A1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A4R4G4B4|KNOWN_RTTEXTURE_X8R8G8B8|KNOWN_RTTEXTURE_A8R8G8B8}, // SiS 640/740
|
|
{0x126f0720, 0, 0, KNOWN_RTTEXTURE_X1R5G5B5|KNOWN_RTTEXTURE_R5G6B5|KNOWN_RTTEXTURE_A1R5G5B5} //Silicon Motion Lynx3DM
|
|
};
|
|
|
|
#define NUM_KNOWN_DEVICES (sizeof(gKnownDeviceList)/sizeof(KNOWNENTRY))
|
|
|
|
|
|
#define CACHE_GROW_SIZE 30
|
|
|
|
#define RESPATH_D3D "Software\\Microsoft\\Direct3D"
|
|
|
|
|
|
|
|
// Minimum size of DrawPrimitive buffer associated with a context.
|
|
#define MIN_PRIM_BUFFER_SIZE (1 << 14)
|
|
// Maximum
|
|
#define MAX_PRIM_BUFFER_SIZE (1 << 20)
|
|
// Default
|
|
#define DEF_PRIM_BUFFER_SIZE (1 << 16)
|
|
|
|
const DWORD dwOrderedFaces[6] = {
|
|
DDSCAPS2_CUBEMAP_POSITIVEX,
|
|
DDSCAPS2_CUBEMAP_NEGATIVEX,
|
|
DDSCAPS2_CUBEMAP_POSITIVEY,
|
|
DDSCAPS2_CUBEMAP_NEGATIVEY,
|
|
DDSCAPS2_CUBEMAP_POSITIVEZ,
|
|
DDSCAPS2_CUBEMAP_NEGATIVEZ
|
|
};
|
|
|
|
__inline LPDDRAWI_DDRAWSURFACE_INT GetHeavyweightSurf(DDSURFACE* pSurf)
|
|
{
|
|
return (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT) ? MapLightweightSurface(pSurf) : pSurf->Surface.pHeavy;
|
|
}
|
|
|
|
#define DONE_HEAVYWEIGHT_SURF(x) \
|
|
if (((PDDSURFACE)(x))->dwFlags & DDSURFACE_LIGHTWEIGHT) \
|
|
UnmapLightweightSurface(x)
|
|
|
|
HRESULT MapLegacyResult(HRESULT in)
|
|
{
|
|
HRESULT hr;
|
|
switch (in)
|
|
{
|
|
case DD_OK:
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case DDERR_OUTOFVIDEOMEMORY:
|
|
hr = D3DERR_OUTOFVIDEOMEMORY;
|
|
break;
|
|
|
|
case DDERR_CURRENTLYNOTAVAIL:
|
|
case DDERR_UNSUPPORTED:
|
|
hr = D3DERR_NOTAVAILABLE;
|
|
break;
|
|
|
|
case DDERR_OUTOFMEMORY:
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
|
|
default:
|
|
hr = D3DERR_DRIVERINTERNALERROR;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL FormatCompatibleWithDisplayFormat(
|
|
PDDDEVICEHANDLE pDD,
|
|
D3DFORMAT Format)
|
|
{
|
|
return (BOOL) (Format == pDD->DisplayFormatWithAlpha);
|
|
}
|
|
|
|
HRESULT LockDibEngine(LPDDRAWI_DIRECTDRAW_GBL pdrv)
|
|
{
|
|
HRESULT ret;
|
|
LPWORD pdflags;
|
|
BOOL isbusy;
|
|
|
|
pdflags = pdrv->lpwPDeviceFlags;
|
|
isbusy = 0;
|
|
|
|
_asm
|
|
{
|
|
mov eax, pdflags
|
|
bts word ptr [eax], BUSY_BIT
|
|
adc isbusy,0
|
|
}
|
|
if (isbusy && (0 == pdrv->dwWin16LockCnt))
|
|
{
|
|
D3D_WARN(2, "LOCK_DIBENGINE, dibengine is busy");
|
|
ret = DDERR_SURFACEBUSY;
|
|
} else
|
|
ret = DD_OK;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void UnlockDibEngine(LPDDRAWI_DIRECTDRAW_GBL pdrv)
|
|
{
|
|
if (0 == pdrv->dwWin16LockCnt)
|
|
{
|
|
*pdrv->lpwPDeviceFlags &= ~BUSY;
|
|
}
|
|
}
|
|
|
|
#define CALL_D3DHAL_TAKEBUSY_NOWIN16(ret, pDevice, func, data) \
|
|
{ \
|
|
if (func) \
|
|
{ \
|
|
ret = LockDibEngine((pDevice)->pDD->lpLcl->lpGbl); \
|
|
if (ret != DD_OK) \
|
|
{ \
|
|
ret = DDHAL_DRIVER_HANDLED; \
|
|
} \
|
|
else \
|
|
{ \
|
|
ret = (*(func))(data); \
|
|
UnlockDibEngine((pDevice)->pDD->lpLcl->lpGbl); \
|
|
} \
|
|
} \
|
|
else \
|
|
{ \
|
|
DPF_ERR("No HAL call available"); \
|
|
ret = DDHAL_DRIVER_NOTHANDLED; \
|
|
} \
|
|
}
|
|
|
|
#define CALL_D3DHAL_TAKEBUSY_TAKEWIN16(ret, pDevice, func, data) \
|
|
{ \
|
|
ENTER_WIN16LOCK(); \
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret, pDevice, func, data); \
|
|
LEAVE_WIN16LOCK(); \
|
|
}
|
|
|
|
BOOL CanKnownDriverDoThis(PDDDEVICEHANDLE pDevice, DWORD Flag)
|
|
{
|
|
BOOL ret = FALSE;
|
|
int i;
|
|
|
|
if (pDevice->ForceFlagsOff & Flag)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else if (pDevice->ForceFlagsOn & Flag)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// Only drivers in our known good list can support lightweight
|
|
// surfaces
|
|
|
|
if (pDevice->PCIID == 0)
|
|
{
|
|
DDDEVICEIDENTIFIER2 DI;
|
|
|
|
if (InternalGetDeviceIdentifier7( (LPDIRECTDRAW) pDevice->pDD, &DI, 0, FALSE) == DD_OK)
|
|
{
|
|
pDevice->PCIID = (DI.dwVendorId << 16) | DI.dwDeviceId;
|
|
pDevice->DriverVersionHigh = DI.liDriverVersion.HighPart;
|
|
pDevice->DriverVersionLow = DI.liDriverVersion.LowPart;
|
|
}
|
|
}
|
|
for (i = 0; i < NUM_KNOWN_DEVICES; i++)
|
|
{
|
|
if ((gKnownDeviceList[i].PCIID == pDevice->PCIID) &&
|
|
(gKnownDeviceList[i].Flags & Flag) &&
|
|
((pDevice->DriverVersionHigh > gKnownDeviceList[i].VersionMajor) ||
|
|
((pDevice->DriverVersionHigh == gKnownDeviceList[i].VersionMajor) &&
|
|
(pDevice->DriverVersionLow >= gKnownDeviceList[i].VersionMinor))))
|
|
{
|
|
ret = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
BOOL IsLightweightSurface(PDDDEVICEHANDLE pDevice, DDSURFACEDESC2* pddsd2, D3DFORMAT Format)
|
|
{
|
|
// Render targets, Z buffers, cursor surfaces, and any part of flip chain
|
|
// must remain heavyweight surfaces.
|
|
|
|
if (pddsd2->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
|
|
DDSCAPS_3DDEVICE |
|
|
DDSCAPS_ZBUFFER |
|
|
DDSCAPS_OFFSCREENPLAIN))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// All paletized textures must be heavyweight unless it's at least a DX8
|
|
// driver. This is because some DX7 drivers don't handle palettes right.
|
|
|
|
if ((pDevice->DriverLevel < 8) &&
|
|
((Format == D3DFMT_A8P8) || (Format == D3DFMT_P8)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_VOLUME)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// If it's a static VB or IB, then we can let that be lightweight
|
|
if ((pDevice->DriverLevel >= 8) &&
|
|
(pddsd2->ddsCaps.dwCaps2 & DDSCAPS_EXECUTEBUFFER) &&
|
|
(pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_HINTSTATIC))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// Unless it's static, the runtime locks vidmem vbs indefinately,
|
|
// so if we make them lightweight they will fill up our cache table
|
|
// with 1000s of entries. Therefore, we will make them heavyweight.
|
|
if ((pddsd2->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) &&
|
|
(pddsd2->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Dynamic textures will be frequently locked, so it is inefficient
|
|
// to make them light weight.
|
|
if ((pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_HINTDYNAMIC) &&
|
|
(pddsd2->ddsCaps.dwCaps & DDSCAPS_TEXTURE) &&
|
|
(pddsd2->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void UpdateSurfaceCache(DDSURFACE* pSurf)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_LCL pLcl = GET_CACHED_LIGHTWEIGHT_INT(pSurf)->lpLcl;
|
|
LPDDRAWI_DDRAWSURFACE_GBL_MORE lpGblMore;
|
|
|
|
// Update those fields in the lightweight structure that the driver may
|
|
// have changed
|
|
|
|
pSurf->Surface.pLight->GblFlags = pLcl->lpGbl->dwGlobalFlags;
|
|
pSurf->Surface.pLight->fpGblVidMem = pLcl->lpGbl->fpVidMem;
|
|
pSurf->Surface.pLight->GblPitch = pLcl->lpGbl->lPitch;
|
|
pSurf->Surface.pLight->GblReserved1 = pLcl->lpGbl->dwReserved1;
|
|
|
|
pSurf->Surface.pLight->LclFlags = pLcl->dwFlags;
|
|
pSurf->Surface.pLight->LclCaps1 = pLcl->ddsCaps.dwCaps;
|
|
pSurf->Surface.pLight->LclReserved1 = pLcl->dwReserved1;
|
|
|
|
lpGblMore = GET_LPDDRAWSURFACE_GBL_MORE (pLcl->lpGbl);
|
|
pSurf->Surface.pLight->GblMoreDriverReserved = lpGblMore->dwDriverReserved;
|
|
pSurf->Surface.pLight->GblMoreContentsStamp = lpGblMore->dwContentsStamp;
|
|
pSurf->Surface.pLight->pGblMoreUnswappedDriverReserved = lpGblMore->lpvUnswappedDriverReserved;
|
|
pSurf->Surface.pLight->fpGblMoreAliasOfVidMem = lpGblMore->fpAliasOfVidMem;
|
|
pSurf->Surface.pLight->cGblMorePageUnlocks = lpGblMore->cPageUnlocks;
|
|
|
|
if (pSurf->Surface.pLight->LclCaps1 & DDSCAPS_LOCALVIDMEM)
|
|
{
|
|
pSurf->Surface.pLight->fpGblMoreAliasedVidMem = lpGblMore->fpAliasedVidMem;
|
|
}
|
|
else if (pSurf->Surface.pLight->LclCaps1 & DDSCAPS_NONLOCALVIDMEM)
|
|
{
|
|
pSurf->Surface.pLight->fpGblMorePhysicalVidMem = lpGblMore->fpPhysicalVidMem;
|
|
}
|
|
}
|
|
|
|
|
|
LPDDRAWI_DDRAWSURFACE_INT MapLightweightSurface(DDSURFACE* pSurf)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pCached = NULL;
|
|
PDDDEVICEHANDLE pDevice = pSurf->pDevice;
|
|
int i;
|
|
LPDDRAWI_DDRAWSURFACE_GBL_MORE* ppGblMore;
|
|
DWORD Lowest;
|
|
DWORD LowestEntry;
|
|
CACHEENTRY* pCachedEntry = NULL;
|
|
UINT CacheIndex;
|
|
|
|
// If the surface is already mapped, this is pretty easy
|
|
|
|
if (pSurf->Surface.pLight->CachedIndex)
|
|
{
|
|
DDASSERT(pSurf->Surface.pLight->CachedIndex & INDEX_IN_USE);
|
|
|
|
pCachedEntry = GET_CACHED_ENTRY(pSurf);
|
|
pCachedEntry->pSurface->dwReserved2++; // up the ref count
|
|
pCachedEntry->UsageStamp = pDevice->CacheUsageStamp++;
|
|
|
|
// Protect against wrap around of the usage stamp
|
|
if (pDevice->CacheUsageStamp == 0)
|
|
{
|
|
for (i = 0; i < pDevice->NumCachedSurfaces; i++)
|
|
{
|
|
pDevice->pCachedSurfaceTable[i].UsageStamp = 0;
|
|
}
|
|
}
|
|
|
|
return pCachedEntry->pSurface;
|
|
}
|
|
|
|
// Otherwise, find an available surface to use
|
|
|
|
do
|
|
{
|
|
// Look through the list and look for either a surface that isn't being used,
|
|
// or one that we can use with the lowest UsageStamp.
|
|
|
|
Lowest = LowestEntry = (DWORD) -1;
|
|
for (i = 0; i < pDevice->NumCachedSurfaces; i++)
|
|
{
|
|
if (pDevice->pCachedSurfaceTable[i].pSurface->dwReserved1 == (ULONG_PTR) NULL)
|
|
{
|
|
pCachedEntry = &(pDevice->pCachedSurfaceTable[i]);
|
|
CacheIndex = i;
|
|
break;
|
|
}
|
|
else if ((pDevice->pCachedSurfaceTable[i].pSurface->dwReserved2 == 0) &&
|
|
(pDevice->pCachedSurfaceTable[i].UsageStamp < Lowest))
|
|
{
|
|
Lowest = pDevice->pCachedSurfaceTable[i].UsageStamp;
|
|
LowestEntry = (DWORD) i;
|
|
}
|
|
}
|
|
|
|
if ((pCachedEntry == NULL) && (LowestEntry != (DWORD) -1))
|
|
{
|
|
// We don't have an empty one, but we found one that we can flush
|
|
|
|
UpdateSurfaceCache((DDSURFACE*)(pDevice->pCachedSurfaceTable[LowestEntry].pSurface->dwReserved1));
|
|
((DDSURFACE*)(pDevice->pCachedSurfaceTable[LowestEntry].pSurface->dwReserved1))->Surface.pLight->CachedIndex = 0;
|
|
pDevice->pCachedSurfaceTable[LowestEntry].pSurface->dwReserved1 = (ULONG_PTR) NULL;
|
|
pCachedEntry = &(pDevice->pCachedSurfaceTable[LowestEntry]);
|
|
CacheIndex = LowestEntry;
|
|
}
|
|
|
|
if (pCachedEntry == NULL)
|
|
{
|
|
// If we still can't find one, then we need to grow the table
|
|
|
|
int NewNum;
|
|
CACHEENTRY* pNewTable;
|
|
|
|
NewNum = pDevice->NumCachedSurfaces + CACHE_GROW_SIZE;
|
|
pNewTable = (CACHEENTRY*) MemAlloc(sizeof(CACHEENTRY) * NewNum);
|
|
if (pNewTable == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
for (i = 0; i < pDevice->NumCachedSurfaces; i++)
|
|
{
|
|
pNewTable[i] = pDevice->pCachedSurfaceTable[i];
|
|
}
|
|
while (i < NewNum)
|
|
{
|
|
pNewTable[i].UsageStamp = 0;
|
|
pNewTable[i].pSurface = (LPDDRAWI_DDRAWSURFACE_INT)
|
|
MemAlloc(sizeof(DDRAWI_DDRAWSURFACE_INT) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_LCL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_GBL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_MORE) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_GBL_MORE) +
|
|
sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
|
|
if (pNewTable[i].pSurface == NULL)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
if (pDevice->pCachedSurfaceTable != NULL)
|
|
{
|
|
MemFree(pDevice->pCachedSurfaceTable);
|
|
}
|
|
pDevice->NumCachedSurfaces = i;
|
|
pDevice->pCachedSurfaceTable = pNewTable;
|
|
}
|
|
} while (pCachedEntry == NULL);
|
|
|
|
pCachedEntry->UsageStamp = pDevice->CacheUsageStamp++;
|
|
|
|
// Protect against wrap around of the usage stamp
|
|
if (pDevice->CacheUsageStamp == 0)
|
|
{
|
|
for (i = 0; i < pDevice->NumCachedSurfaces; i++)
|
|
{
|
|
pDevice->pCachedSurfaceTable[i].UsageStamp = 0;
|
|
}
|
|
}
|
|
|
|
// We have the memory that we want to use, so now we need to initialze it
|
|
|
|
pCached = pCachedEntry->pSurface;
|
|
|
|
memset(pCached, 0, sizeof(DDRAWI_DDRAWSURFACE_INT) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_LCL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_GBL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_MORE) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_GBL_MORE) +
|
|
sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
|
|
pCached->dwReserved1 = (ULONG_PTR) pSurf;
|
|
pCached->dwReserved2 = 1; // Init the ref count
|
|
pSurf->Surface.pLight->CachedIndex = CacheIndex | INDEX_IN_USE; // So a used entry is never 0
|
|
|
|
pCached->lpLcl = (LPDDRAWI_DDRAWSURFACE_LCL)
|
|
(((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT));
|
|
|
|
pCached->lpLcl->lpSurfMore = (LPDDRAWI_DDRAWSURFACE_MORE)
|
|
(((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_LCL));
|
|
|
|
pCached->lpLcl->lpGbl = (LPDDRAWI_DDRAWSURFACE_GBL)
|
|
(((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_LCL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_MORE) +
|
|
sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
|
|
|
|
ppGblMore = (LPDDRAWI_DDRAWSURFACE_GBL_MORE*) ((BYTE*)(pCached->lpLcl->lpGbl) -
|
|
sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE));
|
|
*ppGblMore = (LPDDRAWI_DDRAWSURFACE_GBL_MORE)
|
|
(((BYTE*)pCached) + sizeof(DDRAWI_DDRAWSURFACE_INT) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_LCL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_MORE) +
|
|
sizeof(LPDDRAWI_DDRAWSURFACE_GBL_MORE) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_GBL));
|
|
|
|
// Now fill it in with the meaningful data
|
|
|
|
pCached->lpLcl->dwFlags = pSurf->Surface.pLight->LclFlags;
|
|
pCached->lpLcl->ddsCaps.dwCaps = pSurf->Surface.pLight->LclCaps1;
|
|
pCached->lpLcl->dwReserved1 = pSurf->Surface.pLight->LclReserved1;
|
|
pCached->lpLcl->dwModeCreatedIn = pSurf->Surface.pLight->LclModeCreatedIn;
|
|
pCached->lpLcl->dwBackBufferCount = pSurf->Surface.pLight->LclBackBufferCount;
|
|
pCached->lpLcl->dwProcessId = pDevice->PID;
|
|
|
|
pCached->lpLcl->lpGbl->dwGlobalFlags = pSurf->Surface.pLight->GblFlags;
|
|
pCached->lpLcl->lpGbl->lPitch = pSurf->Surface.pLight->GblPitch;
|
|
pCached->lpLcl->lpGbl->wWidth = (WORD) pSurf->Surface.pLight->GblWidth;
|
|
pCached->lpLcl->lpGbl->wHeight = (WORD) pSurf->Height;
|
|
pCached->lpLcl->lpGbl->dwReserved1 = pSurf->Surface.pLight->GblReserved1;
|
|
if (pSurf->Surface.pLight->GblFormat != D3DFMT_UNKNOWN)
|
|
{
|
|
ConvertToOldFormat(&pCached->lpLcl->lpGbl->ddpfSurface,
|
|
pSurf->Surface.pLight->GblFormat);
|
|
}
|
|
pCached->lpLcl->lpGbl->lpVidMemHeap = pSurf->Surface.pLight->pGblVidMemHeap;
|
|
pCached->lpLcl->lpGbl->fpVidMem = pSurf->Surface.pLight->fpGblVidMem;
|
|
|
|
pCached->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2 = pSurf->Surface.pLight->MoreCaps2;
|
|
pCached->lpLcl->lpSurfMore->ddsCapsEx.dwCaps3 = pSurf->Surface.pLight->MoreCaps3;
|
|
pCached->lpLcl->lpSurfMore->ddsCapsEx.dwCaps4 = pSurf->Surface.pLight->MoreCaps4;
|
|
pCached->lpLcl->lpSurfMore->rgjunc = pSurf->Surface.pLight->MoreRgjunc;
|
|
pCached->lpLcl->lpSurfMore->dwSurfaceHandle = pSurf->dwCookie;
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
pCached->lpLcl->lpSurfMore->lpDD_lcl = pDevice->pSwDD->lpLcl;
|
|
pCached->lpLcl->lpSurfMore->lpDD_int = pDevice->pSwDD;
|
|
pCached->lpLcl->lpGbl->lpDD = pDevice->pSwDD->lpLcl->lpGbl;
|
|
}
|
|
else
|
|
{
|
|
pCached->lpLcl->lpSurfMore->lpDD_lcl = pDevice->pDD->lpLcl;
|
|
pCached->lpLcl->lpSurfMore->lpDD_int = pDevice->pDD;
|
|
pCached->lpLcl->lpGbl->lpDD = pDevice->pDD->lpLcl->lpGbl;
|
|
}
|
|
|
|
(*ppGblMore)->dwDriverReserved = pSurf->Surface.pLight->GblMoreDriverReserved;
|
|
(*ppGblMore)->dwContentsStamp = pSurf->Surface.pLight->GblMoreContentsStamp;
|
|
(*ppGblMore)->lpvUnswappedDriverReserved = pSurf->Surface.pLight->pGblMoreUnswappedDriverReserved;
|
|
(*ppGblMore)->fpAliasOfVidMem = pSurf->Surface.pLight->fpGblMoreAliasOfVidMem;
|
|
(*ppGblMore)->cPageUnlocks = pSurf->Surface.pLight->cGblMorePageUnlocks;
|
|
|
|
if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
|
|
{
|
|
pCached->lpLcl->lpSurfMore->dwMipMapCount = pSurf->Surface.pLight->MoreMipMapCount;
|
|
}
|
|
else
|
|
{
|
|
pCached->lpLcl->lpSurfMore->dwFVF = pSurf->Surface.pLight->MoreFVF;
|
|
}
|
|
|
|
if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
|
|
{
|
|
pCached->lpLcl->lpSurfMore->dwBytesAllocated = pSurf->Surface.pLight->MoreBytesAllocated;
|
|
}
|
|
else if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
|
|
{
|
|
(*ppGblMore)->fpPhysicalVidMem = pSurf->Surface.pLight->fpGblMorePhysicalVidMem;
|
|
}
|
|
else if (pCached->lpLcl->ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM)
|
|
{
|
|
(*ppGblMore)->fpAliasedVidMem = pSurf->Surface.pLight->fpGblMoreAliasedVidMem;
|
|
}
|
|
|
|
pCached->lpVtbl = (LPVOID) &ddSurface7Callbacks;
|
|
|
|
return pCached;
|
|
}
|
|
|
|
void UnmapLightweightSurface(DDSURFACE* pSurf)
|
|
{
|
|
DDASSERT(pSurf->Surface.pLight->CachedIndex & INDEX_IN_USE);
|
|
DDASSERT(pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT);
|
|
DDASSERT(GET_CACHED_ENTRY(pSurf)->pSurface->dwReserved2 > 0);
|
|
|
|
if (--(GET_CACHED_ENTRY(pSurf)->pSurface->dwReserved2) == 0)
|
|
{
|
|
// Vertex and command buffers are used by DP2, so we want to optimize
|
|
// for them. Even though we are done using the surface, we will keep
|
|
// the heavyweight surface around so we can use it again quickly if
|
|
// we need to.
|
|
|
|
if (!(pSurf->Surface.pLight->LclCaps1 & DDSCAPS_EXECUTEBUFFER))
|
|
{
|
|
UpdateSurfaceCache(pSurf);
|
|
GET_CACHED_ENTRY(pSurf)->pSurface->dwReserved1 = (ULONG_PTR) NULL;
|
|
pSurf->Surface.pLight->CachedIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ReleaseDX7SurfaceHandle(HANDLE hDD, DWORD handle)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
|
|
|
|
pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry =
|
|
pDeviceHandle->SurfaceHandleList.dwFreeList;
|
|
pDeviceHandle->SurfaceHandleList.dwFreeList = handle;
|
|
}
|
|
|
|
DWORD GetDX7SurfaceHandle (HANDLE hDD)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
|
|
DWORD handle = pDeviceHandle->SurfaceHandleList.dwFreeList;
|
|
|
|
if (0==handle)
|
|
{
|
|
// need to grow the dwList
|
|
LPDDSURFACELISTENTRY newList;
|
|
DWORD newsize;
|
|
DWORD index;
|
|
if (NULL != pDeviceHandle->SurfaceHandleList.dwList)
|
|
{
|
|
// old size(current dwFreeList) must not be zero
|
|
DDASSERT(0 != pDeviceHandle->SurfaceHandleList.dwList[0].nextentry);
|
|
// new dwFreeList is always gonna be the old dwList[0].nextentry
|
|
newsize = pDeviceHandle->SurfaceHandleList.dwList[0].nextentry + LISTGROWSIZE;
|
|
newList=(LPDDSURFACELISTENTRY)MemAlloc(newsize*sizeof(DDSURFACELISTENTRY));
|
|
if (NULL == newList)
|
|
{
|
|
DPF_ERR("MemAlloc failure in GetSurfaceHandle()");
|
|
return 0;
|
|
}
|
|
pDeviceHandle->SurfaceHandleList.dwFreeList =
|
|
pDeviceHandle->SurfaceHandleList.dwList[0].nextentry;
|
|
memcpy((LPVOID)newList,(LPVOID)pDeviceHandle->SurfaceHandleList.dwList,
|
|
pDeviceHandle->SurfaceHandleList.dwList[0].nextentry*sizeof(DDSURFACELISTENTRY));
|
|
MemFree(pDeviceHandle->SurfaceHandleList.dwList);
|
|
}
|
|
else
|
|
{
|
|
newsize = LISTGROWSIZE;
|
|
newList=(LPDDSURFACELISTENTRY)MemAlloc(newsize*sizeof(DDSURFACELISTENTRY));
|
|
if (NULL == newList)
|
|
{
|
|
DPF_ERR("MemAlloc failure in GetSurfaceHandle()");
|
|
return 0;
|
|
}
|
|
// start from one as we don't want 0 as a valid handle
|
|
pDeviceHandle->SurfaceHandleList.dwFreeList = 1;
|
|
}
|
|
pDeviceHandle->SurfaceHandleList.dwList=newList;
|
|
pDeviceHandle->SurfaceHandleList.dwList[0].nextentry=newsize;
|
|
|
|
for (index = pDeviceHandle->SurfaceHandleList.dwFreeList;
|
|
index < newsize - 1;
|
|
index++)
|
|
{
|
|
newList[index].nextentry=index+1;
|
|
}
|
|
// indicate end of new FreeList
|
|
newList[newsize-1].nextentry=0;
|
|
// now pop up one and assign it to handle
|
|
handle=pDeviceHandle->SurfaceHandleList.dwFreeList;
|
|
}
|
|
// handle slot is avialable so just remove it from freeList
|
|
pDeviceHandle->SurfaceHandleList.dwFreeList =
|
|
pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry;
|
|
#if DBG
|
|
pDeviceHandle->SurfaceHandleList.dwList[handle].nextentry=0xDEADBEEF;
|
|
#endif
|
|
pDeviceHandle->SurfaceHandleList.dwList[handle].dwFlags=0; //mark it's new
|
|
pDeviceHandle->SurfaceHandleList.dwList[handle].lpSurface=NULL;
|
|
DDASSERT (handle > 0);
|
|
DDASSERT (handle < pDeviceHandle->SurfaceHandleList.dwList[0].nextentry);
|
|
return handle;
|
|
}
|
|
|
|
void FreeSurfaceObject (PDDSURFACE pSurf, BOOL bDestroy)
|
|
{
|
|
if ((pSurf != NULL) &&
|
|
!(pSurf->dwFlags & DDSURFACE_DUMMY))
|
|
{
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
|
|
if (pSurf->Surface.pLight != NULL)
|
|
{
|
|
pHeavy = GetHeavyweightSurf(pSurf);
|
|
if (pHeavy != NULL)
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_CREATECOMPLETE)
|
|
{
|
|
SwDDIDestroySurface (pSurf->pDevice, pSurf, pHeavy->lpLcl);
|
|
}
|
|
else if (pSurf->dwFlags & DDSURFACE_CREATEEX)
|
|
{
|
|
pHeavy->lpLcl->lpGbl->fpVidMem = 0;
|
|
SwDDICreateSurfaceEx (pSurf->pDevice->pSwDD->lpLcl,
|
|
pHeavy->lpLcl);
|
|
}
|
|
|
|
// Uncache the lightweight surface
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
pHeavy->dwReserved1 = (ULONG_PTR) NULL;
|
|
pHeavy->dwReserved2 = 0;
|
|
}
|
|
}
|
|
|
|
MemFree (pSurf->Surface.pLight);
|
|
pSurf->Surface.pLight = NULL;
|
|
}
|
|
|
|
if (pSurf->dwCookie != 0)
|
|
{
|
|
ReleaseDX7SurfaceHandle(pSurf->pDevice, pSurf->dwCookie);
|
|
pSurf->dwCookie = 0;
|
|
}
|
|
}
|
|
|
|
else if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
|
|
{
|
|
// If we created a texture handle, free it now
|
|
|
|
if ((pSurf->dwFlags & DDSURFACE_DX6HANDLE) &&
|
|
(pSurf->pDevice->pContext != NULL) &&
|
|
(pSurf->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy != NULL))
|
|
{
|
|
D3DHAL_TEXTUREDESTROYDATA data;
|
|
DWORD ret;
|
|
|
|
data.dwhContext = (ULONG_PTR) pSurf->pDevice->pContext->Context;
|
|
data.dwHandle = pSurf->dwCookie;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_TAKEWIN16(ret,
|
|
pSurf->pDevice,
|
|
pSurf->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy,
|
|
&data);
|
|
}
|
|
pSurf->dwFlags &= ~DDSURFACE_DX6HANDLE;
|
|
|
|
// Now delete the heavy weight surface
|
|
|
|
if (bDestroy)
|
|
{
|
|
if (pSurf->Surface.pHeavy != NULL)
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_ROOT)
|
|
{
|
|
InternalSurfaceRelease(pSurf->Surface.pHeavy, FALSE, TRUE);
|
|
}
|
|
}
|
|
pSurf->Surface.pHeavy = NULL;
|
|
}
|
|
else if (pSurf->Surface.pHeavy != NULL)
|
|
{
|
|
invalidateSurface(pSurf->Surface.pHeavy->lpLcl);
|
|
}
|
|
}
|
|
else if (pSurf->Surface.pLight != NULL)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
|
|
pHeavy = MapLightweightSurface(pSurf);
|
|
if (pHeavy != NULL)
|
|
{
|
|
if (bDestroy)
|
|
{
|
|
pHeavy->dwIntRefCnt = 1;
|
|
pHeavy->lpLcl->dwLocalRefCnt = 1;
|
|
pHeavy->lpLcl->lpGbl->dwRefCnt = 1;
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_ROOT)
|
|
{
|
|
pHeavy->lpLcl->lpSurfMore->pAddrefedThisOwner = (IUnknown*) pSurf->pDevice->pDD;
|
|
}
|
|
pHeavy->lpLcl->dwFlags &= ~DDRAWISURF_IMPLICITCREATE;
|
|
|
|
InternalSurfaceRelease(pHeavy, TRUE, TRUE);
|
|
|
|
pHeavy->dwReserved1 = (ULONG_PTR) NULL;
|
|
pHeavy->dwReserved2 = 0;
|
|
}
|
|
else
|
|
{
|
|
invalidateSurface(pHeavy->lpLcl);
|
|
DONE_HEAVYWEIGHT_SURF(pSurf);
|
|
}
|
|
}
|
|
if (bDestroy)
|
|
{
|
|
MemFree (pSurf->Surface.pLight);
|
|
pSurf->Surface.pLight = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* DdConvertToOldFormat
|
|
*
|
|
* History:
|
|
* 3-Nov-1999 -by- Scott MacDonald [smac]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
void ConvertToOldFormat(LPDDPIXELFORMAT pOldFormat, D3DFORMAT NewFormat)
|
|
{
|
|
// Zero out the format to avoid missing
|
|
// cases where it isn't initialized right
|
|
ZeroMemory(pOldFormat, sizeof(*pOldFormat));
|
|
|
|
// Set Size
|
|
pOldFormat->dwSize = sizeof(DDPIXELFORMAT);
|
|
|
|
// Convert away
|
|
if (HIWORD((DWORD)NewFormat))
|
|
{
|
|
pOldFormat->dwFlags = DDPF_FOURCC;
|
|
pOldFormat->dwFourCC = (DWORD)NewFormat;
|
|
return;
|
|
}
|
|
|
|
switch (NewFormat)
|
|
{
|
|
case D3DFMT_R8G8B8:
|
|
pOldFormat->dwFlags = DDPF_RGB;
|
|
pOldFormat->dwRBitMask = 0x00ff0000;
|
|
pOldFormat->dwGBitMask = 0x0000ff00;
|
|
pOldFormat->dwBBitMask = 0x000000ff;
|
|
pOldFormat->dwRGBBitCount = 24;
|
|
break;
|
|
|
|
case D3DFMT_A8R8G8B8:
|
|
pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
|
pOldFormat->dwRGBAlphaBitMask = 0xFF000000;
|
|
pOldFormat->dwRBitMask = 0x00ff0000;
|
|
pOldFormat->dwGBitMask = 0x0000ff00;
|
|
pOldFormat->dwBBitMask = 0x000000ff;
|
|
pOldFormat->dwRGBBitCount = 32;
|
|
break;
|
|
|
|
case D3DFMT_X8R8G8B8:
|
|
pOldFormat->dwFlags = DDPF_RGB;
|
|
pOldFormat->dwRBitMask = 0x00ff0000;
|
|
pOldFormat->dwGBitMask = 0x0000ff00;
|
|
pOldFormat->dwBBitMask = 0x000000ff;
|
|
pOldFormat->dwRGBBitCount = 32;
|
|
break;
|
|
|
|
case D3DFMT_R5G6B5:
|
|
pOldFormat->dwFlags = DDPF_RGB;
|
|
pOldFormat->dwRBitMask = 0x0000f800;
|
|
pOldFormat->dwGBitMask = 0x000007e0;
|
|
pOldFormat->dwBBitMask = 0x0000001f;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_X1R5G5B5:
|
|
pOldFormat->dwFlags = DDPF_RGB;
|
|
pOldFormat->dwRBitMask = 0x00007c00;
|
|
pOldFormat->dwGBitMask = 0x000003e0;
|
|
pOldFormat->dwBBitMask = 0x0000001f;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_A1R5G5B5:
|
|
pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
|
pOldFormat->dwRGBAlphaBitMask = 0x00008000;
|
|
pOldFormat->dwRBitMask = 0x00007c00;
|
|
pOldFormat->dwGBitMask = 0x000003e0;
|
|
pOldFormat->dwBBitMask = 0x0000001f;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_A4R4G4B4:
|
|
pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
|
pOldFormat->dwRGBAlphaBitMask = 0x0000f000;
|
|
pOldFormat->dwRBitMask = 0x00000f00;
|
|
pOldFormat->dwGBitMask = 0x000000f0;
|
|
pOldFormat->dwBBitMask = 0x0000000f;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_X4R4G4B4:
|
|
pOldFormat->dwFlags = DDPF_RGB;
|
|
pOldFormat->dwRBitMask = 0x00000f00;
|
|
pOldFormat->dwGBitMask = 0x000000f0;
|
|
pOldFormat->dwBBitMask = 0x0000000f;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_R3G3B2:
|
|
pOldFormat->dwFlags = DDPF_RGB;
|
|
pOldFormat->dwRBitMask = 0x000000e0;
|
|
pOldFormat->dwGBitMask = 0x0000001c;
|
|
pOldFormat->dwBBitMask = 0x00000003;
|
|
pOldFormat->dwRGBBitCount = 8;
|
|
break;
|
|
|
|
case D3DFMT_A8R3G3B2:
|
|
pOldFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
|
pOldFormat->dwRGBAlphaBitMask = 0x0000FF00;
|
|
pOldFormat->dwRBitMask = 0x000000e0;
|
|
pOldFormat->dwGBitMask = 0x0000001c;
|
|
pOldFormat->dwBBitMask = 0x00000003;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_A8P8:
|
|
pOldFormat->dwFlags = DDPF_RGB |
|
|
DDPF_ALPHAPIXELS |
|
|
DDPF_PALETTEINDEXED8;
|
|
|
|
pOldFormat->dwRGBAlphaBitMask = 0x0000FF00;
|
|
pOldFormat->dwRGBBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_P8:
|
|
pOldFormat->dwFlags = DDPF_RGB |
|
|
DDPF_PALETTEINDEXED8;
|
|
pOldFormat->dwRGBBitCount = 8;
|
|
break;
|
|
|
|
case D3DFMT_L8:
|
|
pOldFormat->dwFlags = DDPF_LUMINANCE;
|
|
pOldFormat->dwLuminanceBitMask = 0x000000FF;
|
|
pOldFormat->dwLuminanceBitCount = 8;
|
|
break;
|
|
|
|
case D3DFMT_A8L8:
|
|
pOldFormat->dwFlags = DDPF_LUMINANCE |
|
|
DDPF_ALPHAPIXELS;
|
|
pOldFormat->dwLuminanceAlphaBitMask = 0x0000FF00;
|
|
pOldFormat->dwLuminanceBitMask = 0x000000FF;
|
|
pOldFormat->dwLuminanceBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_A4L4:
|
|
pOldFormat->dwFlags = DDPF_LUMINANCE |
|
|
DDPF_ALPHAPIXELS;
|
|
pOldFormat->dwLuminanceAlphaBitMask = 0x000000F0;
|
|
pOldFormat->dwLuminanceBitMask = 0x0000000F;
|
|
pOldFormat->dwLuminanceBitCount = 8;
|
|
break;
|
|
|
|
case D3DFMT_V8U8:
|
|
pOldFormat->dwFlags = DDPF_BUMPDUDV;
|
|
pOldFormat->dwBumpDvBitMask = 0x0000FF00;
|
|
pOldFormat->dwBumpDuBitMask = 0x000000FF;
|
|
pOldFormat->dwBumpBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_L6V5U5:
|
|
pOldFormat->dwFlags = DDPF_BUMPDUDV |
|
|
DDPF_BUMPLUMINANCE;
|
|
pOldFormat->dwBumpLuminanceBitMask = 0x0000FC00;
|
|
pOldFormat->dwBumpDvBitMask = 0x000003E0;
|
|
pOldFormat->dwBumpDuBitMask = 0x0000001F;
|
|
pOldFormat->dwBumpBitCount = 16;
|
|
break;
|
|
|
|
case D3DFMT_X8L8V8U8:
|
|
pOldFormat->dwFlags = DDPF_BUMPDUDV |
|
|
DDPF_BUMPLUMINANCE;
|
|
pOldFormat->dwBumpLuminanceBitMask = 0x00FF0000;
|
|
pOldFormat->dwBumpDvBitMask = 0x0000FF00;
|
|
pOldFormat->dwBumpDuBitMask = 0x000000FF;
|
|
pOldFormat->dwBumpBitCount = 32;
|
|
break;
|
|
|
|
case D3DFMT_A8:
|
|
pOldFormat->dwFlags = DDPF_ALPHA;
|
|
pOldFormat->dwAlphaBitDepth = 8;
|
|
break;
|
|
|
|
case D3DFMT_D16:
|
|
case D3DFMT_D16_LOCKABLE:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 16;
|
|
pOldFormat->dwZBitMask = 0xFFFF;
|
|
pOldFormat->dwStencilBitDepth = 0;
|
|
pOldFormat->dwStencilBitMask = 0;
|
|
break;
|
|
|
|
case D3DFMT_D32:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0xFFFFFFFF;
|
|
pOldFormat->dwStencilBitDepth = 0;
|
|
pOldFormat->dwStencilBitMask = 0;
|
|
break;
|
|
|
|
case D3DFMT_D15S1:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER |
|
|
DDPF_STENCILBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 16;
|
|
pOldFormat->dwZBitMask = 0xFFFE;
|
|
pOldFormat->dwStencilBitDepth = 1;
|
|
pOldFormat->dwStencilBitMask = 0x0001;
|
|
break;
|
|
case D3DFMT_D24S8:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER |
|
|
DDPF_STENCILBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0xFFFFFF00;
|
|
pOldFormat->dwStencilBitDepth = 8;
|
|
pOldFormat->dwStencilBitMask = 0xFF;
|
|
break;
|
|
case D3DFMT_S1D15:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER |
|
|
DDPF_STENCILBUFFER;;
|
|
pOldFormat->dwZBufferBitDepth = 16;
|
|
pOldFormat->dwZBitMask = 0x7FFF;
|
|
pOldFormat->dwStencilBitDepth = 1;
|
|
pOldFormat->dwStencilBitMask = 0x8000;
|
|
break;
|
|
case D3DFMT_S8D24:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER |
|
|
DDPF_STENCILBUFFER;;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0x00FFFFFF;
|
|
pOldFormat->dwStencilBitDepth = 8;
|
|
pOldFormat->dwStencilBitMask = 0xFF000000;
|
|
break;
|
|
case D3DFMT_X8D24:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0x00FFFFFF;
|
|
pOldFormat->dwStencilBitDepth = 0;
|
|
pOldFormat->dwStencilBitMask = 0x00000000;
|
|
break;
|
|
case D3DFMT_D24X8:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0xFFFFFF00;
|
|
pOldFormat->dwStencilBitDepth = 0;
|
|
pOldFormat->dwStencilBitMask = 0x00000000;
|
|
break;
|
|
case D3DFMT_D24X4S4:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER |
|
|
DDPF_STENCILBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0xFFFFFF00;
|
|
pOldFormat->dwStencilBitDepth = 4;
|
|
pOldFormat->dwStencilBitMask = 0x0000000F;
|
|
break;
|
|
case D3DFMT_X4S4D24:
|
|
pOldFormat->dwFlags = DDPF_ZBUFFER |
|
|
DDPF_STENCILBUFFER;
|
|
pOldFormat->dwZBufferBitDepth = 32;
|
|
pOldFormat->dwZBitMask = 0x00FFFFFF;
|
|
pOldFormat->dwStencilBitDepth = 4;
|
|
pOldFormat->dwStencilBitMask = 0x0F000000;
|
|
break;
|
|
|
|
default:
|
|
// All other formats are treated as a
|
|
// FOURCC
|
|
pOldFormat->dwFlags = DDPF_FOURCC;
|
|
pOldFormat->dwFourCC = (DWORD)NewFormat;
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* DdConvertFromOldFormat
|
|
*
|
|
* History:
|
|
* 13-Nov-1999 -by- Scott MacDonald [smac]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
void ConvertFromOldFormat(LPDDPIXELFORMAT pOldFormat, D3DFORMAT *pNewFormat)
|
|
{
|
|
*pNewFormat = D3DFMT_UNKNOWN;
|
|
if (pOldFormat->dwFlags & DDPF_FOURCC)
|
|
{
|
|
((DWORD)*pNewFormat) = pOldFormat->dwFourCC;
|
|
}
|
|
else if (pOldFormat->dwFlags == DDPF_RGB)
|
|
{
|
|
switch (pOldFormat->dwRGBBitCount)
|
|
{
|
|
case 8:
|
|
if ((pOldFormat->dwRBitMask == 0x000000e0) &&
|
|
(pOldFormat->dwGBitMask == 0x0000001c) &&
|
|
(pOldFormat->dwBBitMask == 0x00000003))
|
|
{
|
|
*pNewFormat = D3DFMT_R3G3B2;
|
|
}
|
|
else
|
|
{
|
|
*pNewFormat = D3DFMT_P8;
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
if ((pOldFormat->dwRBitMask == 0x0000f800) &&
|
|
(pOldFormat->dwGBitMask == 0x000007e0) &&
|
|
(pOldFormat->dwBBitMask == 0x0000001f))
|
|
{
|
|
*pNewFormat = D3DFMT_R5G6B5;
|
|
}
|
|
else if ((pOldFormat->dwRBitMask == 0x00007c00) &&
|
|
(pOldFormat->dwGBitMask == 0x000003e0) &&
|
|
(pOldFormat->dwBBitMask == 0x0000001f))
|
|
{
|
|
*pNewFormat = D3DFMT_X1R5G5B5;
|
|
}
|
|
else if ((pOldFormat->dwRBitMask == 0x00000f00) &&
|
|
(pOldFormat->dwGBitMask == 0x000000f0) &&
|
|
(pOldFormat->dwBBitMask == 0x0000000f))
|
|
{
|
|
*pNewFormat = D3DFMT_X4R4G4B4;
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
if ((pOldFormat->dwRBitMask == 0x00ff0000) &&
|
|
(pOldFormat->dwGBitMask == 0x0000ff00) &&
|
|
(pOldFormat->dwBBitMask == 0x000000ff))
|
|
{
|
|
*pNewFormat = D3DFMT_R8G8B8;
|
|
}
|
|
break;
|
|
|
|
case 32:
|
|
if ((pOldFormat->dwRBitMask == 0x00ff0000) &&
|
|
(pOldFormat->dwGBitMask == 0x0000ff00) &&
|
|
(pOldFormat->dwBBitMask == 0x000000ff))
|
|
{
|
|
*pNewFormat = D3DFMT_X8R8G8B8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS))
|
|
{
|
|
switch (pOldFormat->dwRGBBitCount)
|
|
{
|
|
case 16:
|
|
if ((pOldFormat->dwRGBAlphaBitMask == 0x0000FF00) &&
|
|
(pOldFormat->dwRBitMask == 0x000000e0) &&
|
|
(pOldFormat->dwGBitMask == 0x0000001c) &&
|
|
(pOldFormat->dwBBitMask == 0x00000003))
|
|
{
|
|
*pNewFormat = D3DFMT_A8R3G3B2;
|
|
}
|
|
else if ((pOldFormat->dwRGBAlphaBitMask == 0x0000f000) &&
|
|
(pOldFormat->dwRBitMask == 0x00000f00) &&
|
|
(pOldFormat->dwGBitMask == 0x000000f0) &&
|
|
(pOldFormat->dwBBitMask == 0x0000000f))
|
|
{
|
|
*pNewFormat = D3DFMT_A4R4G4B4;
|
|
}
|
|
else if ((pOldFormat->dwRGBAlphaBitMask == 0x0000FF00) &&
|
|
(pOldFormat->dwRBitMask == 0x00000f00) &&
|
|
(pOldFormat->dwGBitMask == 0x000000f0) &&
|
|
(pOldFormat->dwBBitMask == 0x0000000f))
|
|
{
|
|
*pNewFormat = D3DFMT_A4R4G4B4;
|
|
}
|
|
else if ((pOldFormat->dwRGBAlphaBitMask == 0x00008000) &&
|
|
(pOldFormat->dwRBitMask == 0x00007c00) &&
|
|
(pOldFormat->dwGBitMask == 0x000003e0) &&
|
|
(pOldFormat->dwBBitMask == 0x0000001f))
|
|
{
|
|
*pNewFormat = D3DFMT_A1R5G5B5;
|
|
}
|
|
break;
|
|
|
|
case 32:
|
|
if ((pOldFormat->dwRGBAlphaBitMask == 0xff000000) &&
|
|
(pOldFormat->dwRBitMask == 0x00ff0000) &&
|
|
(pOldFormat->dwGBitMask == 0x0000ff00) &&
|
|
(pOldFormat->dwBBitMask == 0x000000ff))
|
|
{
|
|
*pNewFormat = D3DFMT_A8R8G8B8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == DDPF_ALPHA)
|
|
{
|
|
if (pOldFormat->dwAlphaBitDepth == 8)
|
|
{
|
|
*pNewFormat = D3DFMT_A8;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags & (DDPF_PALETTEINDEXED8 | DDPF_RGB))
|
|
{
|
|
switch (pOldFormat->dwRGBBitCount)
|
|
{
|
|
case 8:
|
|
if (pOldFormat->dwFlags == (DDPF_PALETTEINDEXED8 | DDPF_RGB))
|
|
{
|
|
*pNewFormat = D3DFMT_P8;
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
if (pOldFormat->dwFlags == (DDPF_PALETTEINDEXED8 |
|
|
DDPF_RGB |
|
|
DDPF_ALPHAPIXELS) &&
|
|
pOldFormat->dwRGBAlphaBitMask == 0xFF00)
|
|
{
|
|
|
|
*pNewFormat = D3DFMT_A8P8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == DDPF_ZBUFFER)
|
|
{
|
|
switch (pOldFormat->dwZBufferBitDepth)
|
|
{
|
|
case 32:
|
|
if (pOldFormat->dwZBitMask == 0xffffffff)
|
|
{
|
|
*pNewFormat = D3DFMT_D32;
|
|
}
|
|
else if (pOldFormat->dwZBitMask == 0x00FFFFFF)
|
|
{
|
|
*pNewFormat = D3DFMT_X8D24;
|
|
}
|
|
else if (pOldFormat->dwZBitMask == 0xFFFFFF00)
|
|
{
|
|
*pNewFormat = D3DFMT_D24X8;
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
if (pOldFormat->dwZBitMask == 0xffff)
|
|
{
|
|
*pNewFormat = D3DFMT_D16;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == (DDPF_ZBUFFER | DDPF_STENCILBUFFER))
|
|
{
|
|
switch (pOldFormat->dwZBufferBitDepth)
|
|
{
|
|
case 32:
|
|
if ((pOldFormat->dwZBitMask == 0xffffff00) &&
|
|
(pOldFormat->dwStencilBitMask == 0x000000ff) &&
|
|
(pOldFormat->dwStencilBitDepth == 8))
|
|
{
|
|
*pNewFormat = D3DFMT_D24S8;
|
|
}
|
|
else if ((pOldFormat->dwZBitMask == 0x00ffffff) &&
|
|
(pOldFormat->dwStencilBitMask == 0xff000000) &&
|
|
(pOldFormat->dwStencilBitDepth == 8))
|
|
{
|
|
*pNewFormat = D3DFMT_S8D24;
|
|
}
|
|
break;
|
|
case 16:
|
|
if ((pOldFormat->dwZBitMask == 0xfffe) &&
|
|
(pOldFormat->dwStencilBitMask == 0x0001) &&
|
|
(pOldFormat->dwStencilBitDepth == 1))
|
|
{
|
|
*pNewFormat = D3DFMT_D15S1;
|
|
}
|
|
else if ((pOldFormat->dwZBitMask == 0x7fff) &&
|
|
(pOldFormat->dwStencilBitMask == 0x8000) &&
|
|
(pOldFormat->dwStencilBitDepth == 1))
|
|
{
|
|
*pNewFormat = D3DFMT_S1D15;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == DDPF_LUMINANCE)
|
|
{
|
|
switch (pOldFormat->dwLuminanceBitCount)
|
|
{
|
|
case 8:
|
|
if (pOldFormat->dwLuminanceBitMask == 0xFF)
|
|
{
|
|
*pNewFormat = D3DFMT_L8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == (DDPF_LUMINANCE | DDPF_ALPHAPIXELS))
|
|
{
|
|
switch (pOldFormat->dwLuminanceBitCount)
|
|
{
|
|
case 8:
|
|
if (pOldFormat->dwLuminanceBitMask == 0x0F &&
|
|
pOldFormat->dwLuminanceAlphaBitMask == 0xF0)
|
|
{
|
|
*pNewFormat = D3DFMT_A4L4;
|
|
}
|
|
case 16:
|
|
if (pOldFormat->dwLuminanceBitMask == 0x00FF &&
|
|
pOldFormat->dwLuminanceAlphaBitMask == 0xFF00)
|
|
{
|
|
*pNewFormat = D3DFMT_A8L8;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == DDPF_BUMPDUDV)
|
|
{
|
|
switch (pOldFormat->dwBumpBitCount)
|
|
{
|
|
case 16:
|
|
if (pOldFormat->dwBumpDuBitMask == 0xFF &&
|
|
pOldFormat->dwBumpDvBitMask == 0xFF00)
|
|
{
|
|
*pNewFormat = D3DFMT_V8U8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (pOldFormat->dwFlags == (DDPF_BUMPDUDV | DDPF_BUMPLUMINANCE))
|
|
{
|
|
switch (pOldFormat->dwBumpBitCount)
|
|
{
|
|
case 16:
|
|
if (pOldFormat->dwBumpDuBitMask == 0x001F &&
|
|
pOldFormat->dwBumpDvBitMask == 0x03E0 &&
|
|
pOldFormat->dwBumpLuminanceBitMask == 0xFC00)
|
|
{
|
|
*pNewFormat = D3DFMT_L6V5U5;
|
|
}
|
|
break;
|
|
|
|
case 32:
|
|
if (pOldFormat->dwBumpDuBitMask == 0x0000FF &&
|
|
pOldFormat->dwBumpDvBitMask == 0x00FF00 &&
|
|
pOldFormat->dwBumpLuminanceBitMask == 0xFF0000)
|
|
{
|
|
*pNewFormat = D3DFMT_X8L8V8U8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// How lost devices work:
|
|
//
|
|
// Device can be lost two ways:
|
|
// 1) A mode change or something occurs, in which DDraw knows about it and
|
|
// calls CleanupD3D8. In this case, we free the surfaces and mark the
|
|
// device as lost.
|
|
//
|
|
// This will only happen when the DDRAW critical section is held, so as long
|
|
// as we check for lost devices while the critical section is held, we are
|
|
// safe to use the surface structures.
|
|
//
|
|
// 2) A DOS box or something occurs in which case we don't know about it,
|
|
// but we can find out by polling the busy bit. This can occur at anytime,
|
|
// although we are gaurenteed that it will never happen while we are holding
|
|
// the win16 lock. In fact, if we don't hold the win16 lock while checking
|
|
// the busy bit, we will get false positives simple by dragging another window
|
|
// around.
|
|
//
|
|
// So, we have to grab the busy bit to check for lost, and we need to hold the
|
|
// DDraw critical section throughout the remained of the call since not holding
|
|
// it can cause surfaces to go away out from under us. Also, when calling HAL
|
|
// we always grab the win16 lock, so in each call we could be grabbing it twice.
|
|
// With all of this in mind, it's probably better just to ENTER_BOTH() before
|
|
// we check for device lost and then LEAVE_BOTH() at the end of the funtion.
|
|
//
|
|
// We can also remove the busybit check from the HAL call since we already know
|
|
// that it's not set since we checked it and are still holding the win16 lock, so
|
|
// nobody else can set.
|
|
|
|
void LoseDevice (DDDEVICEHANDLE* pDevice)
|
|
{
|
|
DDSURFACE* pSurf;
|
|
if (!pDevice->bDeviceLost)
|
|
{
|
|
// The device has transitioned to the lost state, so we need
|
|
// walk through the list and free the vidmem surfaces..
|
|
|
|
pDevice->bDeviceLost = TRUE;
|
|
pSurf = pDevice->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if (IS_SURFACE_LOOSABLE(pSurf))
|
|
{
|
|
FreeSurfaceObject(pSurf, FALSE);
|
|
}
|
|
pSurf = pSurf->pNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CheckForDeviceLost (HANDLE hDD)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
|
|
PDDSURFACE pSurf;
|
|
|
|
if (pDeviceHandle->bDeviceLost)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// The below check will only be reliable if we are holding the win16 lock.
|
|
// if dwWin16LockCnt != 0 that means BUSY bit was set by DdLock
|
|
if ( 0 == pDeviceHandle->pDD->lpLcl->lpGbl->dwWin16LockCnt &&
|
|
(*(pDeviceHandle->pDD->lpLcl->lpGbl->lpwPDeviceFlags) & BUSY )
|
|
)
|
|
{
|
|
LoseDevice(pDeviceHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DdBlt( PD3D8_BLTDATA pBlt )
|
|
{
|
|
DDSURFACE* pSrcSurf = (DDSURFACE*) pBlt->hSrcSurface;
|
|
DDSURFACE* pDstSurf = (DDSURFACE*) pBlt->hDestSurface;
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pBlt->hDD;
|
|
|
|
// Return failure on bad paths
|
|
pBlt->ddRVal = E_FAIL;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pBlt->hDD))
|
|
{
|
|
// Some blts should fail, others should succeed:
|
|
// persistant -> non persitant : OK
|
|
// persistant -> persitant : FAIL
|
|
// non persistant -> persistant : FAIL
|
|
// non persistant -> non persistant : OK
|
|
|
|
if ((pDstSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
|
|
(pDstSurf->Pool == D3DPOOL_NONLOCALVIDMEM))
|
|
{
|
|
pBlt->ddRVal = DD_OK;
|
|
}
|
|
else
|
|
{
|
|
pBlt->ddRVal = D3DERR_DEVICELOST;
|
|
}
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
// Just a colorfill? Used only in debug for
|
|
// enforcing DISCARD
|
|
if (pSrcSurf == NULL)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavyDst;
|
|
|
|
pHeavyDst = GetHeavyweightSurf(pDstSurf);
|
|
if (pHeavyDst != NULL)
|
|
{
|
|
pBlt->bltFX.dwSize = sizeof(DDBLTFX);
|
|
pBlt->ddRVal = DD_Surface_Blt((LPDIRECTDRAWSURFACE)pHeavyDst,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
pBlt->dwFlags,
|
|
&pBlt->bltFX);
|
|
if (FAILED(pBlt->ddRVal))
|
|
{
|
|
DPF_ERR("Driver failed color-fill blt");
|
|
}
|
|
|
|
DONE_HEAVYWEIGHT_SURF(pDstSurf);
|
|
}
|
|
|
|
pBlt->ddRVal = S_OK;
|
|
|
|
LEAVE_BOTH();
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
|
|
if (DDBLT_COPYVSYNC & pBlt->dwFlags)
|
|
{
|
|
DWORD msCurrentTime;
|
|
DWORD threshold;
|
|
|
|
// Compute how many milliseconds there
|
|
// are per refresh. We round down.
|
|
if (pDevice->pDD->lpLcl->lpGbl->dwMonitorFrequency == 0)
|
|
{
|
|
// 60Hz = 16.666ms per frame
|
|
// 75Hz = 13.333ms
|
|
// 85Hz = 11.765ms
|
|
threshold = 13;
|
|
}
|
|
else
|
|
{
|
|
threshold = (DWORD)(1000.0f /
|
|
(float)(pDevice->pDD->lpLcl->lpGbl->dwMonitorFrequency));
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
msCurrentTime = GetTickCount();
|
|
|
|
// If the previous blt was long
|
|
// enough ago i.e. a refresh, then
|
|
// we can break out this loop
|
|
if ((msCurrentTime - pBlt->msLastPresent) > threshold )
|
|
break;
|
|
}
|
|
|
|
// For DDBLT_COPYVSYNC remember the
|
|
// time for this blt was sent
|
|
pBlt->msLastPresent = msCurrentTime;
|
|
}
|
|
|
|
if ((pSrcSurf) && (pDstSurf))
|
|
{
|
|
if ((pSrcSurf->Format == pDstSurf->Format ||
|
|
(pBlt->dwFlags & DDBLT_WINDOWCLIP)) &&
|
|
!IS_SOFTWARE_DRIVER_SURFACE(pSrcSurf) &&
|
|
!IS_SOFTWARE_DRIVER_SURFACE(pDstSurf))
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavySrc;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavyDst;
|
|
DWORD dwFlags = pBlt->dwFlags & ~DDBLT_WINDOWCLIP;
|
|
|
|
pHeavySrc = GetHeavyweightSurf(pSrcSurf);
|
|
if (pHeavySrc == NULL)
|
|
{
|
|
pBlt->ddRVal = DDERR_OUTOFMEMORY;
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
pHeavyDst = GetHeavyweightSurf(pDstSurf);
|
|
if (pHeavyDst == NULL)
|
|
{
|
|
DONE_HEAVYWEIGHT_SURF(pSrcSurf);
|
|
pBlt->ddRVal = DDERR_OUTOFMEMORY;
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
|
|
{
|
|
LPDDRAWI_DDRAWCLIPPER_INT pcClipper = pHeavyDst->lpLcl->lpSurfMore->lpDDIClipper;
|
|
|
|
DDASSERT(IsWindow(pBlt->hWnd));
|
|
DDASSERT(DDSCAPS_PRIMARYSURFACE & pHeavyDst->lpLcl->ddsCaps.dwCaps);
|
|
DDASSERT(pcClipper);
|
|
if (pcClipper)
|
|
{
|
|
(HWND) pcClipper->lpLcl->lpGbl->hWnd = pBlt->hWnd;
|
|
dwFlags |= DDBLT_WINDOWCLIP;
|
|
DPF(10,"Updated hWnd=%08lx", pBlt->hWnd);
|
|
}
|
|
}
|
|
pBlt->bltFX.dwSize = sizeof(DDBLTFX);
|
|
pBlt->bltFX.dwROP = SRCCOPY;
|
|
pBlt->ddRVal = DD_Surface_Blt((LPDIRECTDRAWSURFACE)pHeavyDst,
|
|
(LPRECT) &(pBlt->rDest),
|
|
(LPDIRECTDRAWSURFACE)pHeavySrc,
|
|
(LPRECT) &(pBlt->rSrc),
|
|
dwFlags,
|
|
&pBlt->bltFX);
|
|
DONE_HEAVYWEIGHT_SURF(pSrcSurf);
|
|
DONE_HEAVYWEIGHT_SURF(pDstSurf);
|
|
}
|
|
if (FAILED(pBlt->ddRVal))
|
|
{
|
|
// !!! Just use GetDC on the DirectDraw surface for now, though this is
|
|
// probably way too slow on drivers which do not support derived
|
|
// surfaces. DirectDraw Blt support should be added soon.
|
|
HDC hDCTarget;
|
|
if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
|
|
hDCTarget = GetDC(pBlt->hWnd);
|
|
else
|
|
hDCTarget = D3D8GetDC(pBlt->hDestSurface, NULL);
|
|
if (hDCTarget != NULL)
|
|
{
|
|
HDC hDCSource = D3D8GetDC(pBlt->hSrcSurface, NULL);
|
|
if (hDCSource != NULL)
|
|
{
|
|
LONG DestWidth=pBlt->rDest.right - pBlt->rDest.left;
|
|
LONG DestHeight= pBlt->rDest.bottom - pBlt->rDest.top;
|
|
LONG SrcWidth= pBlt->rSrc.right - pBlt->rSrc.left;
|
|
LONG SrcHeight= pBlt->rSrc.bottom - pBlt->rSrc.top;
|
|
if (DestWidth == SrcWidth && DestHeight == SrcHeight)
|
|
{
|
|
if (BitBlt(
|
|
hDCTarget,
|
|
pBlt->rDest.left,
|
|
pBlt->rDest.top,
|
|
DestWidth,
|
|
DestHeight,
|
|
hDCSource,
|
|
pBlt->rSrc.left,
|
|
pBlt->rSrc.top,
|
|
SRCCOPY))
|
|
{
|
|
pBlt->ddRVal = S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// COLORONCOLOR is not the default in NT
|
|
int saved = SetStretchBltMode(hDCTarget,COLORONCOLOR);
|
|
if (StretchBlt(
|
|
hDCTarget,
|
|
pBlt->rDest.left,
|
|
pBlt->rDest.top,
|
|
DestWidth,
|
|
DestHeight,
|
|
hDCSource,
|
|
pBlt->rSrc.left,
|
|
pBlt->rSrc.top,
|
|
SrcWidth,
|
|
SrcHeight,
|
|
SRCCOPY))
|
|
{
|
|
pBlt->ddRVal = S_OK;
|
|
}
|
|
// restore to previous mode
|
|
if (saved)
|
|
SetStretchBltMode(hDCTarget,saved);
|
|
}
|
|
D3D8ReleaseDC(pBlt->hSrcSurface, hDCSource);
|
|
}
|
|
if ((pBlt->hWnd) && (DDBLT_WINDOWCLIP & pBlt->dwFlags))
|
|
ReleaseDC(pBlt->hWnd, hDCTarget);
|
|
else
|
|
D3D8ReleaseDC(pBlt->hDestSurface, hDCTarget);
|
|
}
|
|
}
|
|
|
|
// We only want to report DP2 errors during the present call because
|
|
// checking for it everywhere is too hard.
|
|
if ((pBlt->ddRVal == DD_OK) &&
|
|
(pDevice->bDP2Error) &&
|
|
(pBlt->dwFlags & DDBLT_WINDOWCLIP))
|
|
{
|
|
pDevice->bDP2Error = FALSE;
|
|
|
|
// We use a special error here to mean that the blt succeeded
|
|
// but that that some DP2 failed since the last present
|
|
pBlt->ddRVal = D3DERR_DEFERRED_DP2ERROR;
|
|
}
|
|
|
|
LEAVE_BOTH();
|
|
|
|
pBlt->ddRVal = MapLegacyResult(pBlt->ddRVal);
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
pBlt->ddRVal = MapLegacyResult(pBlt->ddRVal);
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdFlip( PD3D8_FLIPDATA pFlip )
|
|
{
|
|
DDSURFACE* pCurrSurf = (DDSURFACE*) pFlip->hSurfCurr;
|
|
DDSURFACE* pTargSurf = (DDSURFACE*) pFlip->hSurfTarg;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pFlip->hDD))
|
|
{
|
|
LEAVE_BOTH();
|
|
pFlip->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
if ((pCurrSurf) && (pCurrSurf->dwFlags & DDSURFACE_HEAVYWEIGHT) &&
|
|
(pTargSurf) && (pTargSurf->dwFlags & DDSURFACE_HEAVYWEIGHT))
|
|
{
|
|
pFlip->ddRVal = MapLegacyResult( DD_Surface_Flip((LPDIRECTDRAWSURFACE)pCurrSurf->Surface.pHeavy,
|
|
(LPDIRECTDRAWSURFACE)pTargSurf->Surface.pHeavy,
|
|
pFlip->dwFlags));
|
|
if (SUCCEEDED(pFlip->ddRVal))
|
|
{
|
|
DDSURFACE Temp;
|
|
|
|
// The DirectX runtime swaps the surface handles when it flips, so we
|
|
// need to swap them back to preserve the integrity
|
|
|
|
Temp = *pCurrSurf;
|
|
|
|
DDASSERT(pCurrSurf->Pitch == pTargSurf->Pitch);
|
|
DDASSERT(pCurrSurf->Pool == pTargSurf->Pool);
|
|
DDASSERT(pCurrSurf->Type == pTargSurf->Type);
|
|
DDASSERT(pCurrSurf->Height == pTargSurf->Height);
|
|
|
|
pCurrSurf->dwFlags = pTargSurf->dwFlags;
|
|
pCurrSurf->Surface = pTargSurf->Surface;
|
|
pCurrSurf->fpVidMem = pTargSurf->fpVidMem;
|
|
pCurrSurf->pBits = pTargSurf->pBits;
|
|
pCurrSurf->LockFlags = pTargSurf->LockFlags;
|
|
pCurrSurf->LockRect = pTargSurf->LockRect;
|
|
|
|
pTargSurf->dwFlags = Temp.dwFlags;
|
|
pTargSurf->Surface = Temp.Surface;
|
|
pTargSurf->fpVidMem = Temp.fpVidMem;
|
|
pTargSurf->pBits = Temp.pBits;
|
|
pTargSurf->LockFlags = Temp.LockFlags;
|
|
pTargSurf->LockRect = Temp.LockRect;
|
|
|
|
// We only want to report DP2 errors during the present call because
|
|
// checking for it everywhere is too hard.
|
|
if (((DDDEVICEHANDLE*)pFlip->hDD)->bDP2Error)
|
|
{
|
|
((DDDEVICEHANDLE*)pFlip->hDD)->bDP2Error = FALSE;
|
|
|
|
// We use a special error here to mean that the flip succeeded
|
|
// but that that some DP2 failed since the last present
|
|
pFlip->ddRVal = D3DERR_DEFERRED_DP2ERROR;
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdLock( PD3D8_LOCKDATA pLock )
|
|
{
|
|
PDDSURFACE pSurf = (PDDSURFACE) pLock->hSurface;
|
|
HRESULT hr;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavyInt;
|
|
|
|
// Mask off new flags
|
|
pLock->dwFlags &= (D3DLOCK_READONLY |
|
|
D3DLOCK_DISCARD |
|
|
D3DLOCK_NOOVERWRITE |
|
|
D3DLOCK_NOSYSLOCK);
|
|
|
|
// Always turn on Wait
|
|
pLock->dwFlags |= DDLOCK_WAIT;
|
|
|
|
if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
|
|
{
|
|
DWORD Width;
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
pLock->lpSurfData = (LPVOID) pSurf->Surface.pLight->fpGblVidMem;
|
|
pLock->lPitch = pSurf->Surface.pLight->GblPitch;
|
|
Width = pSurf->Surface.pLight->GblWidth;
|
|
}
|
|
else
|
|
{
|
|
ENTER_DDRAW();
|
|
pLock->lpSurfData = (LPVOID) pSurf->Surface.pHeavy->lpLcl->lpGbl->fpVidMem;
|
|
pLock->lPitch = pSurf->Surface.pHeavy->lpLcl->lpGbl->lPitch;
|
|
Width = (DWORD) pSurf->Surface.pHeavy->lpLcl->lpGbl->wWidth;
|
|
LEAVE_DDRAW();
|
|
}
|
|
|
|
if (pLock->bHasRange)
|
|
{
|
|
((BYTE*)pLock->lpSurfData) += pLock->lPitch * pLock->range.Offset;
|
|
}
|
|
else if (pLock->bHasRect)
|
|
{
|
|
((BYTE*)pLock->lpSurfData) += pLock->lPitch * pLock->rArea.top;
|
|
((BYTE*)pLock->lpSurfData) += (pLock->lPitch / Width) * pLock->rArea.left;
|
|
}
|
|
hr = DD_OK;
|
|
}
|
|
|
|
else if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
ENTER_DDRAW();
|
|
pHeavyInt = GetHeavyweightSurf(pSurf);
|
|
if (pHeavyInt == NULL)
|
|
{
|
|
// This can be caused by an out of memory condition when calling
|
|
// MapLightweightSurface
|
|
|
|
hr = DDERR_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
if(pLock->bHasRange)
|
|
{
|
|
pLock->bHasRange = FALSE;
|
|
pLock->bHasRect = TRUE;
|
|
pLock->rArea.left = 0;
|
|
pLock->rArea.right = 0;
|
|
pLock->rArea.top = pLock->range.Offset;
|
|
pLock->rArea.bottom = pLock->range.Offset + pLock->range.Size;
|
|
}
|
|
|
|
hr = SwDDILock (pLock->hDD, pSurf, pLock, pHeavyInt->lpLcl);
|
|
pLock->lPitch = pHeavyInt->lpLcl->lpGbl->lPitch;
|
|
}
|
|
LEAVE_DDRAW();
|
|
}
|
|
else
|
|
{
|
|
ENTER_BOTH();
|
|
if ((CheckForDeviceLost(pLock->hDD) &&
|
|
pSurf->Pool != D3DPOOL_MANAGED) ||
|
|
(pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED))
|
|
{
|
|
DWORD Height = pSurf->Height;
|
|
if (Height == 0)
|
|
{
|
|
Height++;
|
|
}
|
|
|
|
if ((pSurf->fpVidMem == NULL) ||
|
|
!(pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED))
|
|
{
|
|
DDASSERT(pSurf->Pool != D3DPOOL_MANAGED);
|
|
if ((pSurf->Type == D3DRTYPE_VOLUME) ||
|
|
(pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
// For volumes, height actually contains the depth
|
|
pSurf->fpVidMem = (char*) MemAlloc(
|
|
pSurf->iSlicePitch * Height);
|
|
}
|
|
else
|
|
{
|
|
pSurf->fpVidMem = (char*)MemAlloc(pSurf->Pitch * Height);
|
|
}
|
|
if (pSurf->fpVidMem != NULL)
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_SYSMEMALLOCATED;
|
|
}
|
|
}
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED)
|
|
{
|
|
DDASSERT(CheckForDeviceLost(pLock->hDD));
|
|
|
|
pLock->lPitch = pSurf->Pitch;
|
|
pLock->lpSurfData = pSurf->fpVidMem;
|
|
pSurf->dwFlags |= DDSURFACE_SYSMEMLOCK;
|
|
|
|
if ((pSurf->Type == D3DRTYPE_VOLUME) ||
|
|
(pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
pLock->lSlicePitch = pSurf->iSlicePitch;
|
|
}
|
|
|
|
hr = DD_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = DDERR_GENERIC;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pHeavyInt = GetHeavyweightSurf(pSurf);
|
|
if (pHeavyInt == NULL)
|
|
{
|
|
// This can be caused by an out of memory condition when calling
|
|
// MapLightweightSurface
|
|
|
|
hr = DDERR_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
if(pLock->bHasRange)
|
|
{
|
|
pLock->bHasRect = TRUE;
|
|
pSurf->LockRect.left = 0;
|
|
pSurf->LockRect.right = 0;
|
|
pSurf->LockRect.top = pLock->range.Offset;
|
|
pSurf->LockRect.bottom = pLock->range.Offset + pLock->range.Size;
|
|
}
|
|
else
|
|
{
|
|
pSurf->LockRect.left = pLock->rArea.left;
|
|
pSurf->LockRect.right = pLock->rArea.right;
|
|
pSurf->LockRect.top = pLock->rArea.top;
|
|
pSurf->LockRect.bottom = pLock->rArea.bottom;
|
|
}
|
|
if (pLock->bHasBox)
|
|
{
|
|
pLock->bHasRect = TRUE;
|
|
pSurf->LockRect.left = pLock->box.Left;
|
|
pSurf->LockRect.right = pLock->box.Right;
|
|
pSurf->LockRect.top = pLock->box.Top;
|
|
pSurf->LockRect.bottom = pLock->box.Bottom;
|
|
pSurf->LockRect.left |= (pLock->box.Front << 16);
|
|
pSurf->LockRect.right |= (pLock->box.Back << 16);
|
|
}
|
|
|
|
hr = InternalLock (pHeavyInt->lpLcl,
|
|
&pLock->lpSurfData,
|
|
pLock->bHasRect ? &pSurf->LockRect : NULL,
|
|
pLock->dwFlags | DDLOCK_NOSYSLOCK | (pSurf->Pool == D3DPOOL_MANAGED ? 0 : DDLOCK_TAKE_WIN16));
|
|
|
|
if (hr == DD_OK)
|
|
{
|
|
pLock->lPitch = pHeavyInt->lpLcl->lpGbl->lPitch;
|
|
pSurf->pBits = pLock->lpSurfData;
|
|
pSurf->LockFlags = pLock->dwFlags;
|
|
if (pLock->bHasRect)
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_LOCKRECT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
}
|
|
|
|
if ((pSurf->Type == D3DRTYPE_VOLUME) ||
|
|
(pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
pLock->lSlicePitch = pSurf->iSlicePitch;
|
|
}
|
|
|
|
return MapLegacyResult(hr);
|
|
}
|
|
|
|
|
|
DWORD APIENTRY DdUnlock( PD3D8_UNLOCKDATA pUnlock )
|
|
{
|
|
PDDSURFACE pSurf = (PDDSURFACE) pUnlock->hSurface;
|
|
HRESULT hr = DDERR_GENERIC;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
|
|
if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
|
|
{
|
|
hr = DD_OK;
|
|
}
|
|
else
|
|
{
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
ENTER_DDRAW();
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
pHeavy = GET_CACHED_LIGHTWEIGHT_INT(pSurf);
|
|
DDASSERT(pHeavy != NULL);
|
|
}
|
|
else
|
|
{
|
|
pHeavy = pSurf->Surface.pHeavy;
|
|
}
|
|
hr = SwDDIUnlock (pUnlock->hDD, pSurf, pUnlock, pHeavy->lpLcl);
|
|
|
|
DONE_HEAVYWEIGHT_SURF(pSurf);
|
|
LEAVE_DDRAW();
|
|
}
|
|
else
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_SYSMEMLOCK)
|
|
{
|
|
pSurf->dwFlags &= ~DDSURFACE_SYSMEMLOCK;
|
|
hr = DD_OK;
|
|
}
|
|
else if (pSurf->LockFlags)
|
|
{
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pUnlock->hDD) && pSurf->Pool != D3DPOOL_MANAGED)
|
|
{
|
|
hr = DD_OK;
|
|
}
|
|
else
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
pHeavy = GET_CACHED_LIGHTWEIGHT_INT(pSurf);
|
|
DDASSERT(pHeavy != NULL);
|
|
}
|
|
else
|
|
{
|
|
pHeavy = pSurf->Surface.pHeavy;
|
|
}
|
|
|
|
hr = InternalUnlock (pHeavy->lpLcl,
|
|
(pSurf->dwFlags & DDSURFACE_LOCKRECT) ? NULL : pSurf->pBits,
|
|
(pSurf->dwFlags & DDSURFACE_LOCKRECT) ? &pSurf->LockRect : NULL,
|
|
pSurf->LockFlags | DDLOCK_NOSYSLOCK | (pSurf->Pool == D3DPOOL_MANAGED ? 0 : DDLOCK_TAKE_WIN16));
|
|
pSurf->LockFlags = 0;
|
|
pSurf->dwFlags &= ~DDSURFACE_LOCKRECT;
|
|
|
|
DONE_HEAVYWEIGHT_SURF(pSurf);
|
|
}
|
|
LEAVE_BOTH();
|
|
}
|
|
}
|
|
}
|
|
return MapLegacyResult(hr);
|
|
}
|
|
|
|
DWORD APIENTRY DdGetBltStatus( PD3D8_GETBLTSTATUSDATA pGetBltStatus )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pGetBltStatus->hDD;
|
|
PDDSURFACE pSurf = (PDDSURFACE) pGetBltStatus->hSurface;
|
|
DDHAL_GETBLTSTATUSDATA gbsd;
|
|
LPDDHALSURFCB_GETBLTSTATUS gbsfn;
|
|
|
|
// Software drivers will only do memcpy, so we don't need to call
|
|
// the driver
|
|
|
|
pGetBltStatus->ddRVal = DD_OK;
|
|
if (IS_SOFTWARE_DRIVER(pDevice))
|
|
{
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
ENTER_BOTH();
|
|
pGetBltStatus->ddRVal = DD_OK;
|
|
if (CheckForDeviceLost(pDevice))
|
|
{
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
/*
|
|
gbsfn = pDevice->pDD->lpLcl->lpDDCB->HALDDMiscellaneous.GetSysmemBltStatus;
|
|
gbsd.GetBltStatus = pDevice->pDD->lpLcl->lpDDCB->HALDDMiscellaneous.GetSysmemBltStatus;
|
|
|
|
if( gbsd.GetBltStatus != NULL )
|
|
{
|
|
DWORD rc;
|
|
|
|
gbsd.lpDD = pDevice->pDD->lpLcl->lpGbl;
|
|
gbsd.dwFlags = pGetBltStatus->dwFlags;
|
|
gbsd.lpDDSurface = pSurf->Surface.pHeavy->lpLcl;
|
|
DOHALCALL( GetBltStatus, gbsfn, gbsd, rc, FALSE );
|
|
if( rc == DDHAL_DRIVER_HANDLED )
|
|
{
|
|
pGetBltStatus->ddRVal = gbsd.ddRVal;
|
|
}
|
|
}
|
|
*/
|
|
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdGetFlipStatus( PD3D8_GETFLIPSTATUSDATA pGetFlipStatus )
|
|
{
|
|
DPF_ERR("DdGetFlipStatus");
|
|
return DD_OK;
|
|
}
|
|
|
|
DWORD APIENTRY DdSetMode( PD3D8_SETMODEDATA pSetMode )
|
|
{
|
|
UINT BPP;
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) pSetMode->hDD;
|
|
|
|
pSetMode->ddRVal = D3DERR_DRIVERINTERNALERROR;
|
|
|
|
switch (pSetMode->Format)
|
|
{
|
|
case D3DFMT_P8:
|
|
BPP = 8;
|
|
break;
|
|
|
|
case D3DFMT_R5G6B5:
|
|
case D3DFMT_X1R5G5B5:
|
|
BPP = 16;
|
|
break;
|
|
|
|
case D3DFMT_R8G8B8:
|
|
BPP = 24;
|
|
break;
|
|
|
|
case D3DFMT_A8R8G8B8:
|
|
case D3DFMT_X8R8G8B8:
|
|
BPP = 32;
|
|
break;
|
|
|
|
default:
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
pSetMode->ddRVal = D3D8SetMode((HANDLE)pDeviceHandle,
|
|
pDeviceHandle->szDeviceName,
|
|
pSetMode->dwWidth,
|
|
pSetMode->dwHeight,
|
|
BPP,
|
|
pSetMode->dwRefreshRate,
|
|
FALSE);
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdDestroyDDLocal( PD3D8_DESTROYDDLOCALDATA pDestroyDDLocal )
|
|
{
|
|
DPF_ERR("DdDestroyDDLocal");
|
|
return DD_OK;
|
|
}
|
|
|
|
DWORD APIENTRY DdWaitForVerticalBlank( PD3D8_WAITFORVERTICALBLANKDATA pWaitForVerticalBlank )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pWaitForVerticalBlank->hDD;
|
|
LPDDHAL_WAITFORVERTICALBLANK wfvbhalfn;
|
|
LPDDHAL_WAITFORVERTICALBLANK wfvbfn;
|
|
DWORD dwRet = DDHAL_DRIVER_HANDLED;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pDevice))
|
|
{
|
|
static int LostTestVerticalBlank;
|
|
|
|
pWaitForVerticalBlank->ddRVal = DD_OK;
|
|
if (pWaitForVerticalBlank->dwFlags == DDWAITVB_I_TESTVB)
|
|
{
|
|
if (LostTestVerticalBlank > 0)
|
|
{
|
|
pWaitForVerticalBlank->bIsInVB = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pWaitForVerticalBlank->bIsInVB = FALSE;
|
|
}
|
|
LostTestVerticalBlank = LostTestVerticalBlank == 0 ? 1 : 0;
|
|
}
|
|
else if (pWaitForVerticalBlank->dwFlags == DDWAITVB_BLOCKEND)
|
|
{
|
|
pWaitForVerticalBlank->bIsInVB = FALSE;
|
|
}
|
|
else
|
|
{
|
|
pWaitForVerticalBlank->bIsInVB = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wfvbfn = pDevice->pDD->lpLcl->lpDDCB->HALDD.WaitForVerticalBlank;
|
|
wfvbhalfn = pDevice->pDD->lpLcl->lpDDCB->cbDDCallbacks.WaitForVerticalBlank;
|
|
dwRet = DDHAL_DRIVER_NOTHANDLED;
|
|
if( wfvbhalfn != NULL )
|
|
{
|
|
DDHAL_WAITFORVERTICALBLANKDATA wfvbd;
|
|
|
|
wfvbd.WaitForVerticalBlank = wfvbhalfn;
|
|
wfvbd.lpDD = pDevice->pDD->lpLcl->lpGbl;
|
|
wfvbd.dwFlags = pWaitForVerticalBlank->dwFlags;
|
|
wfvbd.hEvent = (ULONG_PTR) NULL;
|
|
DOHALCALL( WaitForVerticalBlank, wfvbfn, wfvbd, dwRet, FALSE );
|
|
if (dwRet == DDHAL_DRIVER_HANDLED)
|
|
{
|
|
pWaitForVerticalBlank->ddRVal = MapLegacyResult(wfvbd.ddRVal);
|
|
if (wfvbd.ddRVal == DDERR_VERTICALBLANKINPROGRESS)
|
|
{
|
|
pWaitForVerticalBlank->ddRVal = DD_OK;
|
|
pWaitForVerticalBlank->bIsInVB = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pWaitForVerticalBlank->bIsInVB = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
return dwRet;
|
|
}
|
|
|
|
void BuildSurfaceDesc( PD3D8_CREATESURFACEDATA pCreateSurface, DDSURFACEDESC2* pddsd2 )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
|
|
LPDDRAWI_DIRECTDRAW_INT pdrv_int = pDevice->pDD;
|
|
HRESULT hr;
|
|
DWORD i;
|
|
PDDSURFACE pSurf;
|
|
LPDIRECTDRAWSURFACE lpDDSurface;
|
|
|
|
memset(pddsd2, 0, sizeof(DDSURFACEDESC2));
|
|
pddsd2->dwSize = sizeof( DDSURFACEDESC2 );
|
|
|
|
//dwCaps3==1 means 1 sample per pixel.
|
|
pddsd2->ddsCaps.dwCaps3 = DDSCAPS3_MULTISAMPLE_MASK & (DWORD) pCreateSurface->MultiSampleType;
|
|
|
|
// Convert all of the caps
|
|
switch (pCreateSurface->Type)
|
|
{
|
|
case D3DRTYPE_SURFACE:
|
|
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_ALPHACHANNEL)
|
|
{
|
|
DPF(0,"Setting alphachannel");
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_ENABLEALPHACHANNEL;
|
|
}
|
|
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_PRIMARYSURFACE)
|
|
{
|
|
// If we aren't creating a primary flip chain, then we
|
|
// don't have to do much here.
|
|
|
|
if (pCreateSurface->dwSCnt == 1)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
|
|
}
|
|
else
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE |
|
|
DDSCAPS_COMPLEX |
|
|
DDSCAPS_FLIP |
|
|
DDSCAPS_3DDEVICE;
|
|
}
|
|
}
|
|
else if (pCreateSurface->dwUsage & D3DUSAGE_DEPTHSTENCIL)
|
|
{
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_ZBUFFER;
|
|
}
|
|
else
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
|
|
}
|
|
|
|
if (pCreateSurface->dwSCnt > 1)
|
|
{
|
|
pddsd2->dwBackBufferCount = pCreateSurface->dwSCnt - 1;
|
|
pddsd2->dwFlags |= DDSD_BACKBUFFERCOUNT;
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
|
|
}
|
|
|
|
break;
|
|
case D3DRTYPE_TEXTURE:
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
|
|
if (pCreateSurface->dwSCnt > 1)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
|
|
pddsd2->dwFlags |= DDSD_MIPMAPCOUNT;
|
|
pddsd2->dwMipMapCount = pCreateSurface->dwSCnt;
|
|
}
|
|
else
|
|
{
|
|
// To DDraw, a mipmap w/ one level is really only a texture
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
|
|
}
|
|
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
|
|
}
|
|
break;
|
|
case D3DRTYPE_CUBETEXTURE:
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP;
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP_ALLFACES;
|
|
|
|
DDASSERT(pCreateSurface->dwSCnt >= 6);
|
|
DDASSERT((pCreateSurface->dwSCnt % 6) == 0);
|
|
|
|
if (pCreateSurface->dwSCnt > 6)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
|
|
pddsd2->dwFlags |= DDSD_MIPMAPCOUNT;
|
|
pddsd2->dwMipMapCount = pCreateSurface->dwSCnt / 6;
|
|
}
|
|
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
|
|
}
|
|
break;
|
|
case D3DRTYPE_IMAGESURFACE:
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
|
|
// Image surfaces are marked as textures since they have the
|
|
// greatest flexibility for formats. But they don't get
|
|
// a CreateSurfaceEx handle since they are never passed to
|
|
// a driver.
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
|
|
break;
|
|
|
|
|
|
case D3DRTYPE_COMMANDBUFFER:
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_COMMANDBUFFER;
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
DDASSERT((pCreateSurface->dwUsage & D3DUSAGE_INTERNALBUFFER) == 0);
|
|
break;
|
|
case D3DRTYPE_VERTEXBUFFER:
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
|
|
if (!(pCreateSurface->dwUsage & D3DUSAGE_INTERNALBUFFER))
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_VERTEXBUFFER;
|
|
}
|
|
if (pDevice->DriverLevel >= 8)
|
|
{
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
|
|
}
|
|
else
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTSTATIC;
|
|
}
|
|
}
|
|
break;
|
|
case D3DRTYPE_INDEXBUFFER:
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_EXECUTEBUFFER;
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_INDEXBUFFER;
|
|
if (pDevice->DriverLevel >= 8)
|
|
{
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
|
|
}
|
|
else
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTSTATIC;
|
|
}
|
|
}
|
|
break;
|
|
case D3DRTYPE_VOLUME:
|
|
// We don't create stand-alone volumes
|
|
DDASSERT(FALSE);
|
|
break;
|
|
case D3DRTYPE_VOLUMETEXTURE:
|
|
DDASSERT(0 == (pCreateSurface->dwUsage & D3DUSAGE_DISCARD) );
|
|
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_VOLUME;
|
|
pddsd2->ddsCaps.dwCaps4 =
|
|
MAKELONG((WORD)(pCreateSurface->pSList[0].cpDepth),0);
|
|
|
|
if (pCreateSurface->dwSCnt > 1)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
|
|
pddsd2->dwFlags |= DDSD_MIPMAPCOUNT;
|
|
}
|
|
pddsd2->dwMipMapCount = pCreateSurface->dwSCnt;
|
|
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DYNAMIC)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_HINTDYNAMIC;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_RENDERTARGET)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
|
|
}
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DEPTHSTENCIL)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_ZBUFFER;
|
|
}
|
|
if (pDevice->DriverLevel >= 8)
|
|
{
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_LOADONCE)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_OPAQUE;
|
|
}
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_WRITEONLY)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_WRITEONLY;
|
|
}
|
|
|
|
// Specify new usages for DX8+ drivers
|
|
if (!(pCreateSurface->dwUsage & D3DUSAGE_LOCK) &&
|
|
!(pCreateSurface->dwUsage & D3DUSAGE_LOADONCE))
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_NOTUSERLOCKABLE;
|
|
}
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_DISCARD)
|
|
{
|
|
DDASSERT(pCreateSurface->Type != D3DRTYPE_TEXTURE);
|
|
DDASSERT(pCreateSurface->Type != D3DRTYPE_CUBETEXTURE);
|
|
DDASSERT(pCreateSurface->Type != D3DRTYPE_VOLUMETEXTURE);
|
|
DDASSERT(pCreateSurface->Type != D3DRTYPE_VOLUME);
|
|
DDASSERT(pCreateSurface->Type != D3DRTYPE_VERTEXBUFFER);
|
|
DDASSERT(pCreateSurface->Type != D3DRTYPE_INDEXBUFFER);
|
|
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_DISCARDBACKBUFFER;
|
|
}
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_POINTS)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_POINTS;
|
|
}
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_RTPATCHES)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_RTPATCHES;
|
|
}
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_NPATCHES)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_NPATCHES;
|
|
}
|
|
}
|
|
else // Pre-DX8 driver
|
|
{
|
|
// We allow LOADONCE through only for textures
|
|
if ((pCreateSurface->Type == D3DRTYPE_TEXTURE) ||
|
|
(pCreateSurface->Type == D3DRTYPE_CUBETEXTURE) ||
|
|
(pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE) ||
|
|
(pCreateSurface->Type == D3DRTYPE_VOLUME))
|
|
{
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_LOADONCE)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_OPAQUE;
|
|
}
|
|
}
|
|
// We allow WRITEONLY through only for VBs
|
|
if (pCreateSurface->Type == D3DRTYPE_VERTEXBUFFER)
|
|
{
|
|
if (pCreateSurface->dwUsage & D3DUSAGE_WRITEONLY)
|
|
{
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_WRITEONLY;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (pCreateSurface->Pool)
|
|
{
|
|
case D3DPOOL_LOCALVIDMEM:
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
|
|
break;
|
|
case D3DPOOL_NONLOCALVIDMEM:
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
|
|
break;
|
|
case D3DPOOL_SYSTEMMEM:
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
|
break;
|
|
case D3DPOOL_MANAGED:
|
|
// We should only see this for DX8+ drivers <kd>
|
|
DDASSERT(pDevice->DriverLevel >= 8);
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
|
pddsd2->ddsCaps.dwCaps2 |= DDSCAPS2_TEXTUREMANAGE;
|
|
break;
|
|
case D3DPOOL_DEFAULT:
|
|
pCreateSurface->Pool = D3DPOOL_LOCALVIDMEM;
|
|
pddsd2->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
|
break;
|
|
default:
|
|
/* Unknown Pool?? */
|
|
DDASSERT(FALSE);
|
|
break;
|
|
}
|
|
pddsd2->dwFlags |= DDSD_CAPS;
|
|
|
|
// Convert the pixel format:
|
|
if ((pCreateSurface->Format != D3DFMT_UNKNOWN) &&
|
|
(pCreateSurface->Format != D3DFMT_VERTEXDATA) &&
|
|
(pCreateSurface->Format != D3DFMT_INDEX16) &&
|
|
(pCreateSurface->Format != D3DFMT_INDEX32) &&
|
|
!(pddsd2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
|
|
{
|
|
pddsd2->dwFlags |= DDSD_PIXELFORMAT;
|
|
|
|
// For non-textures, we want to promote X8R8G8B8 to A8R8G8B8 in some cases;
|
|
// this allows things like RTs and Backbuffers to get created matching the
|
|
// primary which is more consistent with typical DX7 usage.
|
|
if (FormatCompatibleWithDisplayFormat(pDevice, (D3DFORMAT)pCreateSurface->Format) &&
|
|
(pCreateSurface->Type == D3DRTYPE_SURFACE))
|
|
{
|
|
//Surface looks like primary:
|
|
ConvertToOldFormat(&pddsd2->ddpfPixelFormat, pDevice->DisplayFormatWithAlpha);
|
|
}
|
|
else
|
|
{
|
|
ConvertToOldFormat(&pddsd2->ddpfPixelFormat, (D3DFORMAT)pCreateSurface->Format);
|
|
}
|
|
}
|
|
|
|
if (!(pddsd2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
|
|
{
|
|
pddsd2->dwHeight = pCreateSurface->pSList[0].cpHeight;
|
|
pddsd2->dwWidth = pCreateSurface->pSList[0].cpWidth;
|
|
pddsd2->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
|
|
|
|
if (pddsd2->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
|
|
{
|
|
pddsd2->dwHeight = 0;
|
|
pddsd2->dwFlags &= ~DDSD_HEIGHT;
|
|
}
|
|
}
|
|
if (pCreateSurface->Type == D3DRTYPE_VERTEXBUFFER)
|
|
{
|
|
pddsd2->dwFVF = pCreateSurface->dwFVF;
|
|
pddsd2->dwFlags |= DDSD_FVF;
|
|
}
|
|
if (pddsd2->ddsCaps.dwCaps2 & DDSCAPS2_VOLUME)
|
|
{
|
|
pddsd2->dwDepth = pCreateSurface->pSList[0].cpDepth;
|
|
pddsd2->dwFlags |= DDSD_DEPTH;
|
|
}
|
|
}
|
|
|
|
|
|
DWORD InitSoftwareSurface(PD3D8_CREATESURFACEDATA pCreateSurface,
|
|
DWORD SurfIndex,
|
|
DDSURFACEDESC2* pddsd2,
|
|
DDSURFACE* pSurf,
|
|
DDSURFACE* pPrevious)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pInt;
|
|
LPDDRAWI_DDRAWSURFACE_LCL pLcl;
|
|
BYTE * pTemp;
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
|
|
|
|
pInt = MemAlloc( sizeof(DDRAWI_DDRAWSURFACE_LCL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_GBL) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_MORE) +
|
|
sizeof(DDRAWI_DDRAWSURFACE_INT));
|
|
if (pInt == NULL)
|
|
{
|
|
return DDERR_OUTOFMEMORY;
|
|
}
|
|
pTemp = (BYTE*) pInt;
|
|
pTemp += sizeof(DDRAWI_DDRAWSURFACE_INT);
|
|
pInt->lpLcl = (LPDDRAWI_DDRAWSURFACE_LCL) pTemp;
|
|
pLcl = pInt->lpLcl;
|
|
pTemp += sizeof(DDRAWI_DDRAWSURFACE_LCL);
|
|
pLcl->lpGbl = (LPDDRAWI_DDRAWSURFACE_GBL) pTemp;
|
|
pTemp += sizeof(DDRAWI_DDRAWSURFACE_GBL);
|
|
pLcl->lpSurfMore = (LPDDRAWI_DDRAWSURFACE_MORE) pTemp;
|
|
|
|
memcpy(&pInt->lpLcl->lpGbl->ddpfSurface, &pddsd2->ddpfPixelFormat, sizeof(DDPIXELFORMAT));
|
|
if (pddsd2->dwFlags & DDSD_PIXELFORMAT)
|
|
{
|
|
pLcl->dwFlags |= DDRAWISURF_HASPIXELFORMAT;
|
|
}
|
|
pLcl->lpGbl->wWidth = (WORD) pCreateSurface->pSList[SurfIndex].cpWidth;
|
|
pLcl->lpGbl->wHeight = (WORD) pCreateSurface->pSList[SurfIndex].cpHeight;
|
|
|
|
pLcl->ddsCaps.dwCaps = pddsd2->ddsCaps.dwCaps;
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps2 = pddsd2->ddsCaps.dwCaps2;
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps3 = DDSCAPS3_MULTISAMPLE_MASK & (DWORD) pCreateSurface->MultiSampleType;
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps4 = pddsd2->ddsCaps.dwCaps4;
|
|
pLcl->lpSurfMore->dwSurfaceHandle = pSurf->dwCookie;
|
|
|
|
pLcl->lpSurfMore->lpDD_lcl = pDevice->pSwDD->lpLcl;
|
|
|
|
if (pSurf->Pool == D3DPOOL_SYSTEMMEM)
|
|
{
|
|
pLcl->lpGbl->fpVidMem = (FLATPTR) pCreateSurface->pSList[SurfIndex].pbPixels;
|
|
pLcl->lpGbl->lPitch = pCreateSurface->pSList[SurfIndex].iPitch;
|
|
}
|
|
|
|
if ((pCreateSurface->Type == D3DRTYPE_VOLUME) ||
|
|
(pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
pLcl->lpGbl->lSlicePitch = pCreateSurface->pSList[SurfIndex].iSlicePitch;
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps4 =
|
|
MAKELONG((WORD)(pCreateSurface->pSList[SurfIndex].cpDepth),0);
|
|
}
|
|
|
|
// If it is a cube-map face, fix up the face flags in caps2.
|
|
if (pCreateSurface->Type == D3DRTYPE_CUBETEXTURE)
|
|
{
|
|
int MipLevels;
|
|
|
|
if (pCreateSurface->dwSCnt>6)
|
|
pLcl->ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
|
|
|
|
MipLevels = pCreateSurface->dwSCnt/6; //since all faces are always present in DX8
|
|
|
|
DDASSERT(MipLevels>=1);
|
|
|
|
//the first n (where n is mip depth) faces are +x, etc.
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |= DDSCAPS2_CUBEMAP;
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps2 &= ~(DDSCAPS2_CUBEMAP_ALLFACES);
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |=
|
|
dwOrderedFaces[SurfIndex/MipLevels];
|
|
|
|
//every MipLevels'th surface is a top-level face,
|
|
if (SurfIndex % MipLevels)
|
|
{
|
|
// Mark non-top levels as being a sub-level
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
|
|
}
|
|
}
|
|
// If it is a texture, fix up the flags in caps2.
|
|
else if ((pCreateSurface->Type == D3DRTYPE_TEXTURE) ||
|
|
(pCreateSurface->Type == D3DRTYPE_VOLUMETEXTURE) ||
|
|
(pCreateSurface->Type == D3DRTYPE_VOLUME))
|
|
{
|
|
if( SurfIndex > 0 )
|
|
{
|
|
pLcl->lpSurfMore->ddsCapsEx.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
|
|
}
|
|
}
|
|
|
|
pSurf->pTempHeavy = pInt;
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* SelectAttachmentSurface
|
|
*
|
|
* Returns an index into the surface creation list that indicates which
|
|
* surface this surface should be attached to. For mipmap sublevels this is
|
|
* always the preceding surface. For cubemaps, each face attaches to the
|
|
* root face (element 0).
|
|
*
|
|
* History:
|
|
* 21-Mar-2000 -by- Jeff Noyle [jeffno]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "SelectAttachmentSurface"
|
|
|
|
UINT SelectAttachmentSurface(
|
|
PD3D8_CREATESURFACEDATA pCreateSurface,
|
|
UINT iThis)
|
|
{
|
|
|
|
//We should never be called to find the attachment from the root face.
|
|
DDASSERT( iThis > 0);
|
|
|
|
if ((pCreateSurface->Type == D3DRTYPE_CUBETEXTURE) &&
|
|
((iThis % (pCreateSurface->dwSCnt/6)) == 0) //which means we're looking at a top-level face
|
|
)
|
|
{
|
|
//... so we attach this face to the root
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
// nope its just a mip sublevel, so we attach to the previous
|
|
return iThis-1;
|
|
}
|
|
}
|
|
|
|
void ExtractLightweightInfo (DDSURFACE *pSurf, LPDDRAWI_DDRAWSURFACE_INT pInt)
|
|
{
|
|
LIGHTWEIGHTSURFACE* pLight = pSurf->Surface.pLight;
|
|
LPDDRAWI_DDRAWSURFACE_GBL_MORE lpGblMore;
|
|
|
|
pLight->LclFlags = pInt->lpLcl->dwFlags;
|
|
pLight->LclCaps1 = pInt->lpLcl->ddsCaps.dwCaps;
|
|
pLight->LclReserved1 = pInt->lpLcl->dwReserved1;
|
|
pLight->LclModeCreatedIn = pInt->lpLcl->dwModeCreatedIn;
|
|
pLight->LclBackBufferCount = pInt->lpLcl->dwBackBufferCount;
|
|
|
|
pLight->GblFlags = pInt->lpLcl->lpGbl->dwGlobalFlags;
|
|
pLight->GblPitch = pInt->lpLcl->lpGbl->lPitch;
|
|
if (pSurf->Pitch == 0)
|
|
{
|
|
pSurf->Pitch = pLight->GblPitch;
|
|
}
|
|
pLight->GblWidth = pInt->lpLcl->lpGbl->wWidth;
|
|
pLight->GblReserved1 = pInt->lpLcl->lpGbl->dwReserved1;
|
|
if (pLight->LclFlags & DDRAWISURF_HASPIXELFORMAT)
|
|
{
|
|
ConvertFromOldFormat(&pInt->lpLcl->lpGbl->ddpfSurface,
|
|
&pLight->GblFormat);
|
|
}
|
|
else
|
|
{
|
|
pLight->GblFormat = D3DFMT_UNKNOWN;
|
|
}
|
|
pLight->pGblVidMemHeap = pInt->lpLcl->lpGbl->lpVidMemHeap;
|
|
pLight->fpGblVidMem = pInt->lpLcl->lpGbl->fpVidMem;
|
|
|
|
pLight->MoreCaps2 = pInt->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2;
|
|
pLight->MoreCaps3 = pInt->lpLcl->lpSurfMore->ddsCapsEx.dwCaps3;
|
|
pLight->MoreCaps4 = pInt->lpLcl->lpSurfMore->ddsCapsEx.dwCaps4;
|
|
pLight->MoreRgjunc = pInt->lpLcl->lpSurfMore->rgjunc;
|
|
if ((pLight->LclCaps1 & DDSCAPS_MIPMAP) ||
|
|
(pLight->MoreCaps2 & DDSCAPS2_VOLUME))
|
|
{
|
|
pLight->MoreMipMapCount = pInt->lpLcl->lpSurfMore->dwMipMapCount;
|
|
}
|
|
else
|
|
{
|
|
pLight->MoreFVF = pInt->lpLcl->lpSurfMore->dwFVF;
|
|
}
|
|
|
|
lpGblMore = GET_LPDDRAWSURFACE_GBL_MORE (pInt->lpLcl->lpGbl);
|
|
if (lpGblMore != NULL)
|
|
{
|
|
pLight->GblMoreDriverReserved = lpGblMore->dwDriverReserved;
|
|
pLight->GblMoreContentsStamp = lpGblMore->dwContentsStamp;
|
|
pLight->pGblMoreUnswappedDriverReserved = lpGblMore->lpvUnswappedDriverReserved;
|
|
pLight->fpGblMoreAliasOfVidMem = lpGblMore->fpAliasOfVidMem;
|
|
pLight->cGblMorePageUnlocks = lpGblMore->cPageUnlocks;
|
|
}
|
|
|
|
if (pLight->LclCaps1 & DDSCAPS_NONLOCALVIDMEM)
|
|
{
|
|
if (lpGblMore != NULL)
|
|
{
|
|
pLight->fpGblMorePhysicalVidMem = lpGblMore->fpPhysicalVidMem;
|
|
}
|
|
}
|
|
else if (pLight->LclCaps1 & DDSCAPS_LOCALVIDMEM)
|
|
{
|
|
if (lpGblMore != NULL)
|
|
{
|
|
pLight->fpGblMoreAliasedVidMem = lpGblMore->fpAliasedVidMem;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pLight->MoreBytesAllocated = pInt->lpLcl->lpSurfMore->dwBytesAllocated;
|
|
}
|
|
|
|
pSurf->Height = pInt->lpLcl->lpGbl->wHeight;
|
|
pSurf->dwCookie = pInt->lpLcl->lpSurfMore->dwSurfaceHandle;
|
|
}
|
|
|
|
|
|
void DiscardHeavyweightMemory( LPDDRAWI_DDRAWSURFACE_INT pInt)
|
|
{
|
|
if (pInt->lpLcl->lpSurfMore->slist != NULL)
|
|
{
|
|
MemFree (pInt->lpLcl->lpSurfMore->slist);
|
|
}
|
|
MemFree (pInt->lpLcl);
|
|
MemFree (pInt);
|
|
}
|
|
|
|
|
|
DWORD APIENTRY DdCreateSurface( PD3D8_CREATESURFACEDATA pCreateSurface )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
|
|
LPDDRAWI_DIRECTDRAW_INT pdrv_int = pDevice->pDD;
|
|
HRESULT hr;
|
|
DWORD i;
|
|
PDDSURFACE pSurf;
|
|
LPDIRECTDRAWSURFACE lpDDSurface;
|
|
DWORD dwNumToCreate;
|
|
DDSURFACEDESC2 ddsd2;
|
|
DWORD NextWidth;
|
|
DWORD NextHeight;
|
|
DEFERREDCREATE* pDefCreate;
|
|
|
|
ENTER_DDRAW();
|
|
BuildSurfaceDesc (pCreateSurface, &ddsd2);
|
|
|
|
dwNumToCreate = pCreateSurface->dwSCnt;
|
|
|
|
// Allocate the internal surface structures for each surface in the chain
|
|
// and initialize it if we are not reusing the surface
|
|
|
|
if (!pCreateSurface->bReUse)
|
|
{
|
|
NextWidth = ddsd2.dwWidth;
|
|
NextHeight = ddsd2.dwHeight;
|
|
for (i = 0; i < dwNumToCreate; i++)
|
|
{
|
|
pSurf = (PDDSURFACE) MemAlloc(sizeof(DDSURFACE));
|
|
if (pSurf == NULL)
|
|
{
|
|
hr = DDERR_OUTOFMEMORY;
|
|
goto CreateErrorCleanup;
|
|
}
|
|
pSurf->Pool = pCreateSurface->Pool;
|
|
pSurf->Format = pCreateSurface->Format;
|
|
pSurf->Type = pCreateSurface->Type;
|
|
|
|
// For volume textures, we need to know the depth to handle lost
|
|
// devices (for everything else we need to height). To save space,
|
|
// we will re-use the same variable.
|
|
|
|
if ((pSurf->Type == D3DRTYPE_VOLUME) ||
|
|
(pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
pSurf->Height = pCreateSurface->pSList[i].cpDepth;
|
|
}
|
|
else
|
|
{
|
|
pSurf->Height = pCreateSurface->pSList[i].cpHeight;
|
|
}
|
|
pCreateSurface->pSList[i].hKernelHandle = (HANDLE) pSurf;
|
|
pSurf->pDevice = (PDDDEVICEHANDLE) pCreateSurface->hDD;
|
|
|
|
// DX6 drivers cannot handle deep mipmaps, but we want to hide this from
|
|
// the runtime, so we need to determine if the current level is a dummy
|
|
// level
|
|
|
|
if ((pDevice->DriverLevel == 6) &&
|
|
(ddsd2.ddsCaps.dwCaps & DDSCAPS_MIPMAP))
|
|
{
|
|
if ((pCreateSurface->pSList[i].cpWidth == NextWidth) &&
|
|
(pCreateSurface->pSList[i].cpHeight == NextHeight))
|
|
{
|
|
// This level is OK, so mark it as such
|
|
ddsd2.dwMipMapCount = i + 1;
|
|
}
|
|
else
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_DUMMY;
|
|
if (i == 1)
|
|
{
|
|
// If there's only one valid level, then don't call it
|
|
// a mipmap
|
|
ddsd2.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
|
|
ddsd2.dwFlags &= ~DDSD_MIPMAPCOUNT;
|
|
}
|
|
}
|
|
NextWidth /= 2;
|
|
NextHeight /= 2;
|
|
}
|
|
|
|
// Now figure out if this is a software driver
|
|
// surface, or a HAL surface.
|
|
|
|
if (IS_SOFTWARE_DRIVER(pCreateSurface->hDD) &&
|
|
!(pCreateSurface->dwUsage & D3DUSAGE_PRIMARYSURFACE) &&
|
|
!(pCreateSurface->dwUsage & D3DUSAGE_OFFSCREENPLAIN))
|
|
{
|
|
// If they are running w/ a software driver (refrast, RGB HEL, etc.),
|
|
// we will not allow any surfaces to be created in video memory except
|
|
// for the primary flipping chain. And also for surfaces marked
|
|
// D3DUSAGE_OFFSCREENPLAIN (which are used for the cursors)
|
|
|
|
pSurf->dwFlags |= DDSURFACE_SOFTWARE;
|
|
}
|
|
else
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_HAL;
|
|
}
|
|
|
|
if (pCreateSurface->bTreatAsVidMem == TRUE)
|
|
{
|
|
// For objects that should be treated as non-persistent
|
|
// i.e. Reset fails unless these are all freed; we
|
|
// set a flag here and check it in DoVidMemSurfacesExist()
|
|
pSurf->dwFlags |= DDSURFACE_TREATASVIDMEM;
|
|
}
|
|
|
|
if (pDevice->bLightweight && IsLightweightSurface(pDevice, &ddsd2, pCreateSurface->Format))
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_LIGHTWEIGHT;
|
|
pSurf->Surface.pLight = (LIGHTWEIGHTSURFACE*) MemAlloc(sizeof(LIGHTWEIGHTSURFACE));
|
|
if (pSurf->Surface.pLight == NULL)
|
|
{
|
|
hr = DDERR_OUTOFMEMORY;
|
|
goto CreateErrorCleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
pSurf->dwFlags |= DDSURFACE_HEAVYWEIGHT;
|
|
}
|
|
|
|
// Software surfaces are special cased because we want to call the software
|
|
// driver for Create and CreateEx rather than the real driver.
|
|
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
if ((ddsd2.ddsCaps.dwCaps & (DDSCAPS_TEXTURE |
|
|
DDSCAPS_EXECUTEBUFFER |
|
|
DDSCAPS_3DDEVICE |
|
|
DDSCAPS_ZBUFFER)) &&
|
|
(pCreateSurface->Type != D3DRTYPE_IMAGESURFACE))
|
|
{
|
|
pSurf->dwCookie = GetDX7SurfaceHandle(pCreateSurface->hDD);
|
|
}
|
|
|
|
hr = InitSoftwareSurface(pCreateSurface,
|
|
i,
|
|
&ddsd2,
|
|
pSurf,
|
|
i > 0 ? pCreateSurface->pSList[i].hKernelHandle : NULL);
|
|
if (hr != DD_OK)
|
|
{
|
|
goto CreateErrorCleanup;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DDASSERT(pCreateSurface->Pool == D3DPOOL_MANAGED);
|
|
}
|
|
|
|
pSurf = (DDSURFACE*) pCreateSurface->pSList[0].hKernelHandle;
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
if (pCreateSurface->Pool != D3DPOOL_SYSTEMMEM)
|
|
{
|
|
// There is a descrepancy in the surface desc that CreateSurface
|
|
// expects and the driver expects, so we will adjust it here for
|
|
// the driver.
|
|
|
|
if ((ddsd2.dwFlags & DDSD_WIDTH) &&
|
|
!(ddsd2.dwFlags & DDSD_HEIGHT))
|
|
{
|
|
ddsd2.dwFlags |= DDSD_HEIGHT;
|
|
ddsd2.dwHeight = 1;
|
|
}
|
|
|
|
hr = SwDDICreateSurface(pCreateSurface, &ddsd2);
|
|
if (hr != DD_OK)
|
|
{
|
|
goto CreateErrorCleanup;
|
|
}
|
|
for (i = 0; i < pCreateSurface->dwSCnt; i++)
|
|
{
|
|
((DDSURFACE*)pCreateSurface->pSList[i].hKernelHandle)->dwFlags |=
|
|
DDSURFACE_CREATECOMPLETE;
|
|
}
|
|
}
|
|
|
|
// We've already created the object so all
|
|
// we have to do is call CreateSurfaceEx
|
|
if (pSurf->dwCookie != 0)
|
|
{
|
|
// If it's a software driver, we may need to attach surfaces
|
|
|
|
for (i = 1; i < pCreateSurface->dwSCnt; i++)
|
|
{
|
|
SwDDIAttachSurfaces (
|
|
((DDSURFACE*)pCreateSurface->pSList[
|
|
SelectAttachmentSurface(pCreateSurface,i)
|
|
].hKernelHandle)->pTempHeavy->lpLcl,
|
|
((DDSURFACE*)pCreateSurface->pSList[i].hKernelHandle)->pTempHeavy->lpLcl);
|
|
}
|
|
SwDDICreateSurfaceEx (pDevice->pSwDD->lpLcl,
|
|
pSurf->pTempHeavy->lpLcl);
|
|
pSurf->dwFlags |= DDSURFACE_CREATEEX;
|
|
}
|
|
|
|
for (i = 0; i < pCreateSurface->dwSCnt; i++)
|
|
{
|
|
LPATTACHLIST pAttach;
|
|
LPATTACHLIST pAttachTemp;
|
|
|
|
pSurf = (DDSURFACE*)pCreateSurface->pSList[i].hKernelHandle;
|
|
|
|
// For a sw driver, always destroy the attached list now.
|
|
// It serves no purpose after CreateSurfaceEx is called.
|
|
|
|
if (pSurf->pTempHeavy->lpLcl->lpAttachList != NULL)
|
|
{
|
|
pAttach = pSurf->pTempHeavy->lpLcl->lpAttachList->lpLink;
|
|
while (pAttach != NULL)
|
|
{
|
|
pAttachTemp = pAttach;
|
|
pAttach = pAttach->lpLink;
|
|
MemFree(pAttachTemp);
|
|
}
|
|
MemFree(pSurf->pTempHeavy->lpLcl->lpAttachList);
|
|
pSurf->pTempHeavy->lpLcl->lpAttachList = NULL;
|
|
}
|
|
if (pSurf->pTempHeavy->lpLcl->lpAttachListFrom != NULL)
|
|
{
|
|
pAttach = pSurf->pTempHeavy->lpLcl->lpAttachListFrom->lpLink;
|
|
while (pAttach != NULL)
|
|
{
|
|
pAttachTemp = pAttach;
|
|
pAttach = pAttach->lpLink;
|
|
MemFree(pAttachTemp);
|
|
}
|
|
MemFree(pSurf->pTempHeavy->lpLcl->lpAttachListFrom);
|
|
pSurf->pTempHeavy->lpLcl->lpAttachListFrom = NULL;
|
|
}
|
|
|
|
pSurf->iSlicePitch = pSurf->pTempHeavy->lpLcl->lpGbl->lSlicePitch;
|
|
pSurf->pTempHeavy->lpLcl->lpGbl->lSlicePitch = 0;
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
ExtractLightweightInfo (pSurf, pSurf->pTempHeavy);
|
|
MemFree (pSurf->pTempHeavy);
|
|
}
|
|
else
|
|
{
|
|
pSurf->Surface.pHeavy = pSurf->pTempHeavy;
|
|
}
|
|
pSurf->pTempHeavy = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LPDDSURFACEINFO pSysMem = NULL;
|
|
BOOL bLost;
|
|
|
|
// If it's a sysmem surface, we want them to use the memory that we
|
|
// have already allocated, so we need to setup an array of pointers.
|
|
|
|
if ((pCreateSurface->Pool == D3DPOOL_SYSTEMMEM) ||
|
|
(ddsd2.ddsCaps.dwCaps2 & DDSCAPS2_VOLUME))
|
|
{
|
|
pSysMem = pCreateSurface->pSList;
|
|
}
|
|
|
|
// If we are creating a vidmem surface, we need to check for device lost
|
|
// and if it's lost, we don't want to create the surface, but to instead
|
|
// allocate a private buffer that we can return when lock is called. We
|
|
// do not want to fail the call just because the device is lost.
|
|
|
|
ENTER_WIN16LOCK();
|
|
bLost = CheckForDeviceLost(pDevice);
|
|
|
|
// Special early out. If reuse is true, we haven't done anything yet (to
|
|
// verify this, trace code above) so all we need to do is to return SURFACELOST
|
|
// and not worry about jumping to CreateErrorCleanup below.
|
|
if (bLost && pCreateSurface->bReUse)
|
|
{
|
|
DDASSERT(!IS_SOFTWARE_DRIVER_SURFACE(pSurf));
|
|
DDASSERT(pCreateSurface->Pool == D3DPOOL_MANAGED);
|
|
LEAVE_WIN16LOCK();
|
|
LEAVE_DDRAW();
|
|
return DDERR_SURFACELOST;
|
|
}
|
|
|
|
if ((pCreateSurface->Pool != D3DPOOL_SYSTEMMEM) &&
|
|
bLost)
|
|
{
|
|
DWORD j;
|
|
DDASSERT(pCreateSurface->bReUse == FALSE);
|
|
for (i = 0; i < pCreateSurface->dwSCnt; i++)
|
|
{
|
|
pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
|
|
|
|
pSurf->Pitch = pCreateSurface->pSList[i].cpWidth * 8;
|
|
pSurf->iSlicePitch = pSurf->Pitch * pCreateSurface->pSList[i].cpHeight;
|
|
if (!(pSurf->dwFlags & DDSURFACE_DUMMY))
|
|
{
|
|
if ((pSurf->Type == D3DRTYPE_VOLUME) ||
|
|
(pSurf->Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
pSurf->fpVidMem = (char*)
|
|
MemAlloc(pSurf->iSlicePitch * pSurf->Height);
|
|
}
|
|
else
|
|
{
|
|
pSurf->fpVidMem = (char*)
|
|
MemAlloc(pSurf->Pitch * pSurf->Height);
|
|
}
|
|
|
|
|
|
if (pSurf->fpVidMem == (char*) NULL)
|
|
{
|
|
DWORD j;
|
|
|
|
for (j = 0; j < i; j++)
|
|
{
|
|
pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
|
|
MemFree (pSurf->fpVidMem);
|
|
}
|
|
hr = DDERR_OUTOFMEMORY;
|
|
LEAVE_WIN16LOCK();
|
|
goto CreateErrorCleanup;
|
|
}
|
|
else
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_SYSMEMALLOCATED;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If the surface is driver managed, we save the creation info so that
|
|
// we can retry the creation at reset time
|
|
if (ddsd2.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
|
|
{
|
|
DDASSERT(pCreateSurface->Pool == D3DPOOL_MANAGED);
|
|
pDefCreate = (PDEFERREDCREATE)MemAlloc(sizeof(DEFERREDCREATE));
|
|
if (pDefCreate == NULL)
|
|
{
|
|
// Cleanup stuff that we allocated above
|
|
for (i = 0; i < pCreateSurface->dwSCnt; ++i)
|
|
{
|
|
pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
|
|
MemFree(pSurf->fpVidMem);
|
|
pSurf->dwFlags &= ~DDSURFACE_SYSMEMALLOCATED;
|
|
}
|
|
hr = DDERR_OUTOFMEMORY;
|
|
LEAVE_WIN16LOCK();
|
|
goto CreateErrorCleanup;
|
|
}
|
|
|
|
// Copy
|
|
pDefCreate->CreateData = *pCreateSurface;
|
|
|
|
pDefCreate->CreateData.pSList = (LPDDSURFACEINFO)MemAlloc(sizeof(DDSURFACEINFO) * pCreateSurface->dwSCnt);
|
|
if (pDefCreate->CreateData.pSList == NULL)
|
|
{
|
|
// Cleanup stuff that we allocated above
|
|
MemFree(pDefCreate);
|
|
for (i = 0; i < pCreateSurface->dwSCnt; ++i)
|
|
{
|
|
pSurf = (PDDSURFACE) pCreateSurface->pSList[i].hKernelHandle;
|
|
MemFree(pSurf->fpVidMem);
|
|
pSurf->dwFlags &= ~DDSURFACE_SYSMEMALLOCATED;
|
|
}
|
|
hr = DDERR_OUTOFMEMORY;
|
|
LEAVE_WIN16LOCK();
|
|
goto CreateErrorCleanup;
|
|
}
|
|
|
|
// Copy
|
|
CopyMemory(pDefCreate->CreateData.pSList, pCreateSurface->pSList, sizeof(DDSURFACEINFO) * pCreateSurface->dwSCnt);
|
|
|
|
// Linkup
|
|
pDefCreate->pNext = ((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDeferList;
|
|
((PDDDEVICEHANDLE)pCreateSurface->hDD)->pDeferList = pDefCreate;
|
|
|
|
// *************************MEMORY LEAK WARNING*********************** //
|
|
// The DEFERREDCREATE and DDSURFACEINFO allocations above will
|
|
// not be cleaned up immediately if there is a failure after this
|
|
// point. As of 5/2001, there is no case in which we will fail after
|
|
// this point. (snene)
|
|
// ******************************************************************* //
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD DX8Flags = DX8SFLAG_DX8;
|
|
|
|
// If we are creating a sysmem surface while lost, we don't want
|
|
// want to call the driver to create the SurfaceEx handle.
|
|
|
|
if (bLost)
|
|
{
|
|
DX8Flags |= DX8SFLAG_ISLOST;
|
|
}
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
DX8Flags |= DX8SFLAG_ISLIGHTWEIGHT;
|
|
}
|
|
if (pCreateSurface->Type == D3DRTYPE_IMAGESURFACE)
|
|
{
|
|
DX8Flags |= DX8SFLAG_IMAGESURF;
|
|
}
|
|
|
|
hr = DD_CreateSurface4_Main( (LPDIRECTDRAW) pdrv_int,
|
|
&ddsd2,
|
|
&lpDDSurface,
|
|
NULL,
|
|
TRUE,
|
|
pSysMem,
|
|
DX8Flags);
|
|
|
|
if (hr != DD_OK)
|
|
{
|
|
LEAVE_WIN16LOCK();
|
|
goto CreateErrorCleanup;
|
|
}
|
|
|
|
// If we let DDraw decide between local vidmem / AGP, then we need
|
|
// to figure out which one it chose.
|
|
|
|
if (((LPDDRAWI_DDRAWSURFACE_INT)lpDDSurface)->lpLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM)
|
|
{
|
|
pCreateSurface->Pool = D3DPOOL_NONLOCALVIDMEM;
|
|
for (i = 0; i < dwNumToCreate; i++)
|
|
{
|
|
pSurf = (DDSURFACE*) pCreateSurface->pSList[i].hKernelHandle;
|
|
pSurf->Pool = D3DPOOL_NONLOCALVIDMEM;
|
|
}
|
|
}
|
|
|
|
// Everything has worked
|
|
|
|
//Find the pointer to the attached heavyweight surface for
|
|
//each face, mip level, back buffer etc.
|
|
switch(pCreateSurface->Type)
|
|
{
|
|
case D3DRTYPE_VERTEXBUFFER :
|
|
case D3DRTYPE_INDEXBUFFER :
|
|
case D3DRTYPE_COMMANDBUFFER :
|
|
//these types have no attachments
|
|
DDASSERT(0 == ( (LPDDRAWI_DDRAWSURFACE_INT)lpDDSurface)->lpLcl->lpAttachList );
|
|
//but we need to fall through and set the pHeavy for the first one.
|
|
case D3DRTYPE_SURFACE :
|
|
case D3DRTYPE_IMAGESURFACE :
|
|
case D3DRTYPE_VOLUME :
|
|
case D3DRTYPE_TEXTURE :
|
|
case D3DRTYPE_VOLUMETEXTURE :
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT lpTemp;
|
|
LPDDRAWI_DDRAWSURFACE_INT lpTemp1;
|
|
lpTemp = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
|
|
|
|
//these types are allocated in a linear list of attachments
|
|
for (i = 0; i < dwNumToCreate; i++)
|
|
{
|
|
pSurf = (DDSURFACE*) pCreateSurface->pSList[i].hKernelHandle;
|
|
DDASSERT(!(pSurf->dwFlags & DDSURFACE_DUMMY)); //cuz not DX6 driver
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
ExtractLightweightInfo (pSurf, lpTemp);
|
|
}
|
|
else
|
|
{
|
|
pSurf->Surface.pHeavy = lpTemp;
|
|
}
|
|
|
|
lpTemp1 = lpTemp;
|
|
if (lpTemp->lpLcl->lpAttachList)
|
|
lpTemp = lpTemp->lpLcl->lpAttachList->lpIAttached;
|
|
|
|
pSurf->iSlicePitch = lpTemp1->lpLcl->lpGbl->lSlicePitch;
|
|
lpTemp1->lpLcl->lpGbl->lSlicePitch = 0;
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
if (lpTemp1->lpLcl->lpAttachList != NULL)
|
|
{
|
|
MemFree(lpTemp1->lpLcl->lpAttachList);
|
|
}
|
|
if (lpTemp1->lpLcl->lpAttachListFrom != NULL)
|
|
{
|
|
MemFree(lpTemp1->lpLcl->lpAttachListFrom);
|
|
}
|
|
DiscardHeavyweightMemory(lpTemp1);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case D3DRTYPE_CUBETEXTURE :
|
|
//cubes are the hard buggers.
|
|
{
|
|
int face;
|
|
DWORD cLevels = dwNumToCreate/6;
|
|
|
|
for(face=0; face<6; face++)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT lpTemp;
|
|
lpTemp = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
|
|
|
|
//point lpTemp to the next top-level face (which will be
|
|
//attached to the face returned by create-surface)
|
|
//(we are already pointing thereat if it's face 0)
|
|
if (face)
|
|
{
|
|
LPATTACHLIST pal;
|
|
pal = lpTemp->lpLcl->lpAttachList;
|
|
do
|
|
{
|
|
lpTemp = pal->lpIAttached;
|
|
pal = pal->lpLink;
|
|
}
|
|
while(0 == (lpTemp->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2 & dwOrderedFaces[face]));
|
|
}
|
|
|
|
//for each face, we run down the attachment list
|
|
//which are allocated in a linear list of attachments
|
|
for (i = 0; i < cLevels; i++)
|
|
{
|
|
pSurf = (DDSURFACE*) pCreateSurface->pSList[face*cLevels+i].hKernelHandle;
|
|
DDASSERT(!(pSurf->dwFlags & DDSURFACE_DUMMY)); //cuz not DX6 driver
|
|
|
|
pSurf->iSlicePitch = lpTemp->lpLcl->lpGbl->lSlicePitch;
|
|
lpTemp->lpLcl->lpGbl->lSlicePitch = 0;
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
ExtractLightweightInfo (pSurf, lpTemp);
|
|
}
|
|
else
|
|
{
|
|
pSurf->Surface.pHeavy = lpTemp;
|
|
}
|
|
|
|
if ((face == 0) && (i == 0) && (cLevels > 1))
|
|
{
|
|
// Special hack for finding mip-levels
|
|
// of first face; the mip-levels for the pos-x
|
|
// face are actually near the the end of the
|
|
// list (interposed by the top-levels of the
|
|
// other 5 faces)
|
|
int j;
|
|
LPATTACHLIST pal = lpTemp->lpLcl->lpAttachList;
|
|
|
|
for (j = 0; j < 5; j++)
|
|
{
|
|
pal = pal->lpLink;
|
|
}
|
|
|
|
lpTemp = pal->lpIAttached;
|
|
|
|
// Check we found what we were looking for
|
|
DDASSERT(lpTemp->lpLcl->lpSurfMore->ddsCapsEx.dwCaps2 & dwOrderedFaces[face]);
|
|
}
|
|
else if (lpTemp->lpLcl->lpAttachList)
|
|
{
|
|
// Normal case; i.e. just go to the surface we
|
|
// are directly attached to
|
|
lpTemp = lpTemp->lpLcl->lpAttachList->lpIAttached;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If it's a lightweight surface, now we need to free
|
|
// all of the heavyweight memory
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT lpTemp;
|
|
LPATTACHLIST pal;
|
|
LPATTACHLIST pNextPal;
|
|
LPATTACHLIST pFaceList;
|
|
LPATTACHLIST pTemp;
|
|
|
|
lpTemp = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface;
|
|
|
|
pal = lpTemp->lpLcl->lpAttachList;
|
|
DiscardHeavyweightMemory(lpTemp);
|
|
|
|
while (pal != NULL)
|
|
{
|
|
pNextPal = pal->lpLink;
|
|
|
|
pFaceList = pal;
|
|
while (pFaceList != NULL)
|
|
{
|
|
if (pFaceList->lpAttached->lpAttachListFrom)
|
|
{
|
|
MemFree (pFaceList->lpAttached->lpAttachListFrom);
|
|
}
|
|
pTemp = pFaceList->lpAttached->lpAttachList;
|
|
DiscardHeavyweightMemory(pFaceList->lpIAttached);
|
|
MemFree(pFaceList);
|
|
pFaceList = pTemp;
|
|
}
|
|
pal = pNextPal;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DDASSERT(0); //unexpected type
|
|
break;
|
|
}
|
|
|
|
for (i = 0; i < dwNumToCreate; i++)
|
|
{
|
|
DWORD j;
|
|
|
|
pSurf = (DDSURFACE*) pCreateSurface->pSList[i].hKernelHandle;
|
|
if (i == 0)
|
|
{
|
|
pSurf->dwFlags |= DDSURFACE_ROOT;
|
|
}
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
|
|
{
|
|
pSurf->Pitch = pSurf->Surface.pHeavy->lpLcl->lpGbl->lPitch;
|
|
if (!(pSurf->dwFlags & DDSURFACE_DUMMY))
|
|
{
|
|
if (i == 0)
|
|
{
|
|
if (DDSCAPS_PRIMARYSURFACE &
|
|
pSurf->Surface.pHeavy->lpLcl->ddsCaps.dwCaps)
|
|
{
|
|
if (!(DDRAWILCL_HASEXCLUSIVEMODE & pdrv_int->lpLcl->dwLocalFlags))
|
|
{
|
|
LPDIRECTDRAWCLIPPER pcClipper;
|
|
if (SUCCEEDED(DD_CreateClipper((LPDIRECTDRAW) pdrv_int,
|
|
0, &pcClipper, NULL)))
|
|
{
|
|
if (pdrv_int->lpLcl->hWnd)
|
|
DD_Clipper_SetHWnd(pcClipper, 0, (HWND) pdrv_int->lpLcl->hWnd);
|
|
DD_Surface_SetClipper(lpDDSurface, pcClipper);
|
|
DPF(10,"Setting Clipper=%08lx with hWnd=%08lx to Primary"
|
|
" Surface", pcClipper, pdrv_int->lpLcl->hWnd);
|
|
DD_Clipper_Release(pcClipper);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pCreateSurface->pSList[i].hKernelHandle = (HANDLE) pSurf;
|
|
}
|
|
|
|
// If this is a DX6+ driver, the above CreateSurface call would
|
|
// have created the ExSurface and assigned a driver handle value.
|
|
// If it's a DX6 driver, however, we need to create the texture
|
|
// handle ourselves.
|
|
|
|
if (pDevice->DriverLevel > 6)
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
|
|
{
|
|
pSurf->dwCookie = pSurf->Surface.pHeavy->lpLcl->lpSurfMore->dwSurfaceHandle;
|
|
}
|
|
if (pSurf->dwCookie &&
|
|
bLost &&
|
|
(pSurf->dwFlags & DDSURFACE_ROOT))
|
|
{
|
|
// We've created the surface, but we can't create the
|
|
// surface Ex handle yet, so we will defer that creation until later.
|
|
|
|
pSurf->dwFlags |= DDSURFACE_DEFERCREATEEX;
|
|
}
|
|
}
|
|
else if ((pSurf->dwFlags & DDSURFACE_ROOT) &&
|
|
(pSurf->Type == D3DRTYPE_TEXTURE))
|
|
{
|
|
// Don't create a texture handle if the surface is in sysmem
|
|
// and the device doesn't texture from sysmem
|
|
|
|
if ((pCreateSurface->Pool != D3DPOOL_SYSTEMMEM) ||
|
|
pDevice->bCanTextureSysmem)
|
|
{
|
|
D3DHAL_TEXTURECREATEDATA data;
|
|
DWORD ret;
|
|
|
|
if (pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate == NULL)
|
|
{
|
|
hr = DDERR_UNSUPPORTED;
|
|
LEAVE_WIN16LOCK();
|
|
goto CreateErrorCleanup;
|
|
}
|
|
|
|
if (bLost)
|
|
{
|
|
// We cannot create the texture handle at this time,
|
|
// so we will do it later.
|
|
|
|
pSurf->dwFlags |= DDSURFACE_DEFERCREATETEXHANDLE;
|
|
pDevice->pContext->dwFlags |= DDCONTEXT_DEFEREDTEXTUREHANDLES;
|
|
}
|
|
else
|
|
{
|
|
// If it's a palettized texture, we need to associate a
|
|
// palette before calling TextureCreate or else some
|
|
// drivers (Rage128) will fault.
|
|
|
|
if ((pCreateSurface->Format == D3DFMT_P8) ||
|
|
(pCreateSurface->Format == D3DFMT_A8P8))
|
|
{
|
|
if (pDevice->pDefaultPalette == NULL)
|
|
{
|
|
{
|
|
PALETTEENTRY ColorTable[256];
|
|
int i;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
ColorTable[i].peRed = (UCHAR) i;
|
|
ColorTable[i].peGreen = (UCHAR) i;
|
|
ColorTable[i].peBlue = (UCHAR) i;
|
|
}
|
|
DD_CreatePalette ((LPDIRECTDRAW) pDevice->pDD,
|
|
DDPCAPS_8BIT,
|
|
ColorTable,
|
|
&pDevice->pDefaultPalette,
|
|
NULL);
|
|
}
|
|
|
|
if (pDevice->pDefaultPalette == NULL)
|
|
{
|
|
DPF_ERR("Unable to create default palette");
|
|
LEAVE_WIN16LOCK();
|
|
hr = DDERR_OUTOFMEMORY;
|
|
goto CreateErrorCleanup;
|
|
}
|
|
}
|
|
hr = DD_Surface_SetPalette(lpDDSurface,
|
|
pDevice->pDefaultPalette);
|
|
if (hr != DD_OK)
|
|
{
|
|
DPF_ERR("Unable to set default palette");
|
|
LEAVE_WIN16LOCK();
|
|
goto CreateErrorCleanup;
|
|
}
|
|
}
|
|
|
|
memset(&data, 0, sizeof(D3DHAL_TEXTURECREATEDATA));
|
|
data.dwhContext = pDevice->pContext->Context;
|
|
data.lpDDS = lpDDSurface;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pDevice,
|
|
pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate,
|
|
&data);
|
|
|
|
if (ret != DDHAL_DRIVER_HANDLED || data.ddrval != DD_OK)
|
|
{
|
|
DPF_ERR("HAL failed to handle TextureCreate");
|
|
LEAVE_WIN16LOCK();
|
|
hr = data.ddrval;
|
|
goto CreateErrorCleanup;
|
|
}
|
|
|
|
pSurf->dwCookie = data.dwHandle;
|
|
pSurf->dwFlags |= DDSURFACE_DX6HANDLE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LEAVE_WIN16LOCK();
|
|
}
|
|
|
|
// Now insert this into our linked list
|
|
// If re-using, then we are already on the list so don't do anything
|
|
if (!pCreateSurface->bReUse)
|
|
{
|
|
for (i = 0; i < dwNumToCreate; i++)
|
|
{
|
|
((PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle))->pNext =
|
|
pDevice->pSurfList;
|
|
((PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle))->pPrevious =
|
|
NULL;
|
|
if (pDevice->pSurfList != NULL)
|
|
{
|
|
pDevice->pSurfList->pPrevious = (PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle);
|
|
}
|
|
pDevice->pSurfList = (PDDSURFACE)(pCreateSurface->pSList[i].hKernelHandle);
|
|
}
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
return DD_OK;
|
|
|
|
CreateErrorCleanup:
|
|
for (i = 0; i < pCreateSurface->dwSCnt; i++)
|
|
{
|
|
pSurf = (PDDSURFACE)pCreateSurface->pSList[i].hKernelHandle;
|
|
if (pSurf != NULL)
|
|
{
|
|
FreeSurfaceObject(pSurf, TRUE);
|
|
// If we are reusing, then we need to keep the pSurf around
|
|
// for a retry
|
|
if (!pCreateSurface->bReUse)
|
|
{
|
|
MemFree(pSurf);
|
|
}
|
|
}
|
|
pCreateSurface->pSList[i].hKernelHandle = NULL;
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
return MapLegacyResult(hr);
|
|
}
|
|
|
|
|
|
DWORD APIENTRY DdDestroySurface( PD3D8_DESTROYSURFACEDATA pDestroySurface )
|
|
{
|
|
DWORD i;
|
|
PDDSURFACE pSurf = (PDDSURFACE) pDestroySurface->hSurface;
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pDestroySurface->hDD;
|
|
PDEFERREDCREATE pDefCreate = pDevice->pDeferList;
|
|
|
|
ENTER_DDRAW();
|
|
FreeSurfaceObject(pSurf, TRUE);
|
|
|
|
if (pSurf != NULL)
|
|
{
|
|
// Free fpVidMem if we allocated it
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_SYSMEMALLOCATED)
|
|
{
|
|
MemFree (pSurf->fpVidMem);
|
|
}
|
|
|
|
// Remove the surface from the linked list
|
|
|
|
if (pDevice->pSurfList == pSurf)
|
|
{
|
|
pDevice->pSurfList = pSurf->pNext;
|
|
if (pSurf->pNext != NULL)
|
|
{
|
|
pSurf->pNext->pPrevious = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pSurf->pNext != NULL)
|
|
{
|
|
pSurf->pNext->pPrevious = pSurf->pPrevious;
|
|
}
|
|
pSurf->pPrevious->pNext = pSurf->pNext;
|
|
}
|
|
|
|
MemFree(pSurf);
|
|
}
|
|
|
|
// We look in the defer list to see if any referenced surface
|
|
// is being destroyed. If this is the case, then we need to
|
|
// update the defer list and mark the surfaces as freed so
|
|
// that we don't try and resurrect destroyed surfaces. Although
|
|
// this appears slow, it is not too bad because a deferred list
|
|
// will be present only if a mode switch happened. In this case,
|
|
// it doesn't hurt if things are a little slow.
|
|
|
|
while (pDefCreate != NULL)
|
|
{
|
|
for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
|
|
{
|
|
if (pSurf == (PDDSURFACE) pDefCreate->CreateData.pSList[i].hKernelHandle)
|
|
{
|
|
pDefCreate->CreateData.pSList[i].hKernelHandle = 0;
|
|
break;
|
|
}
|
|
}
|
|
pDefCreate = pDefCreate->pNext;
|
|
}
|
|
|
|
LEAVE_DDRAW();
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
DWORD APIENTRY DdGetScanLine( PD3D8_GETSCANLINEDATA pGetScanLine )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pGetScanLine->hDD;
|
|
DWORD dwRet = DDHAL_DRIVER_HANDLED;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pDevice))
|
|
{
|
|
static int LostScanLine;
|
|
|
|
// When lost, we want to mix up the return values in case somebody
|
|
// calling us is waiting for these values to change
|
|
|
|
pGetScanLine->ddRVal = DD_OK;
|
|
if (LostScanLine == 0)
|
|
{
|
|
pGetScanLine->dwScanLine = 0;
|
|
pGetScanLine->bInVerticalBlank = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pGetScanLine->dwScanLine = LostScanLine;
|
|
pGetScanLine->bInVerticalBlank = FALSE;
|
|
}
|
|
if ((LostScanLine += 10) > 100)
|
|
{
|
|
LostScanLine = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LPDDHAL_GETSCANLINE gslhalfn;
|
|
LPDDHAL_GETSCANLINE gslfn;
|
|
|
|
gslfn = pDevice->pDD->lpLcl->lpDDCB->HALDD.GetScanLine;
|
|
gslhalfn = pDevice->pDD->lpLcl->lpDDCB->cbDDCallbacks.GetScanLine;
|
|
if( gslhalfn != NULL )
|
|
{
|
|
DDHAL_GETSCANLINEDATA gsld;
|
|
|
|
gsld.GetScanLine = gslhalfn;
|
|
gsld.lpDD = pDevice->pDD->lpLcl->lpGbl;
|
|
DOHALCALL( GetScanLine, gslfn, gsld, dwRet, FALSE );
|
|
if( dwRet == DDHAL_DRIVER_HANDLED )
|
|
{
|
|
pGetScanLine->dwScanLine = gsld.dwScanLine;
|
|
if (gsld.ddRVal == DDERR_VERTICALBLANKINPROGRESS)
|
|
{
|
|
gsld.ddRVal = DD_OK;
|
|
pGetScanLine->bInVerticalBlank = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pGetScanLine->bInVerticalBlank = FALSE;
|
|
}
|
|
pGetScanLine->ddRVal = MapLegacyResult(gsld.ddRVal);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwRet = DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
}
|
|
|
|
LEAVE_BOTH();
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY DdSetExclusiveMode( PD3D8_SETEXCLUSIVEMODEDATA pSetExclusiveMode )
|
|
{
|
|
DPF_ERR("DdSetExclusiveMode");
|
|
#if 0
|
|
LPDDRAWI_DIRECTDRAW_LCL lpDX7;
|
|
|
|
// Tell DDraw that we've grabbed exclusive mode
|
|
|
|
ENTER_DDRAW();
|
|
lpDX7 = ((LPDDRAWI_DIRECTDRAW_INT)(pSetExclusiveMode->lpDD->hDD))->lpLcl;
|
|
|
|
if( pSetExclusiveMode->dwEnterExcl )
|
|
{
|
|
lpDX7->dwLocalFlags |= DDRAWILCL_SETCOOPCALLED | DDRAWILCL_ISFULLSCREEN;
|
|
lpDX7->lpGbl->lpExclusiveOwner = lpDX7;
|
|
lpDX7->lpGbl->dwFlags |= DDRAWI_FULLSCREEN;
|
|
}
|
|
else
|
|
{
|
|
lpDX7->dwLocalFlags &= ~(DDRAWILCL_SETCOOPCALLED | DDRAWILCL_ISFULLSCREEN);
|
|
lpDX7->lpGbl->lpExclusiveOwner = NULL;
|
|
lpDX7->lpGbl->dwFlags &= ~DDRAWI_FULLSCREEN;
|
|
}
|
|
LEAVE_DDRAW();
|
|
#endif
|
|
pSetExclusiveMode->ddRVal = DD_OK;
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdFlipToGDISurface( PD3D8_FLIPTOGDISURFACEDATA pFlipToGDISurface )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pFlipToGDISurface->hDD;
|
|
LPDDRAWI_DIRECTDRAW_INT lpDD = pDevice->pDD;
|
|
|
|
pFlipToGDISurface->ddRVal = MapLegacyResult(DD_FlipToGDISurface((LPDIRECTDRAW)lpDD));
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdSetColorkey( PD3D8_SETCOLORKEYDATA pSetColorkey)
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pSetColorkey->hDD;
|
|
PDDSURFACE pSurf = (PDDSURFACE) pSetColorkey->hSurface;
|
|
|
|
ENTER_BOTH();
|
|
pSetColorkey->ddRVal = DD_OK;
|
|
if (CheckForDeviceLost(pSetColorkey->hDD))
|
|
{
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
if (pSurf->Surface.pHeavy != NULL)
|
|
{
|
|
DDCOLORKEY DDColorKey;
|
|
|
|
// Since this will only be called with DX6 drivers, we know that
|
|
// it will only be heavyweight surfaces and we can use the legacy
|
|
// entry point.
|
|
|
|
DDColorKey.dwColorSpaceLowValue = pSetColorkey->ColorValue;
|
|
pSetColorkey->ddRVal = MapLegacyResult(DD_Surface_SetColorKey((LPDIRECTDRAWSURFACE)pSurf->Surface.pHeavy,
|
|
DDCKEY_SRCBLT,
|
|
&DDColorKey));
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD APIENTRY DdGetAvailDriverMemory( PD3D8_GETAVAILDRIVERMEMORYDATA pGetAvailDriverMemory )
|
|
{
|
|
DWORD dwTotal;
|
|
DWORD dwFree;
|
|
DDSCAPS ddscaps;
|
|
LPDDRAWI_DIRECTDRAW_INT pdrv_int = ((PDDDEVICEHANDLE)pGetAvailDriverMemory->hDD)->pDD;
|
|
|
|
ddscaps.dwCaps = DDSCAPS_TEXTURE;
|
|
|
|
pGetAvailDriverMemory->ddRVal = MapLegacyResult(DD_GetAvailableVidMem( (LPDIRECTDRAW)pdrv_int, &ddscaps, &dwTotal, &dwFree ));
|
|
|
|
pGetAvailDriverMemory->dwFree = dwFree;
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
HRESULT CalcDDSurfInfo( PDDCONTEXT pCtx, LPDDRAWI_DDRAWSURFACE_LCL pSLcl,
|
|
LPDDRAWI_DDRAWSURFACE_LCL pZLcl )
|
|
{
|
|
HRESULT ddrval;
|
|
DWORD dwWidth, dwHeight;
|
|
unsigned long m;
|
|
int s;
|
|
LPDDPIXELFORMAT pSPixFmt = NULL;
|
|
LPDDPIXELFORMAT pZPixFmt = NULL;
|
|
|
|
if( pSLcl == NULL ) return S_OK;
|
|
|
|
// Get info from the surface
|
|
dwWidth = pSLcl->lpGbl->wWidth;
|
|
dwHeight = pSLcl->lpGbl->wHeight;
|
|
GET_PIXEL_FORMAT( pSLcl, pSLcl->lpGbl, pSPixFmt );
|
|
|
|
if( ( pSPixFmt->dwFlags & ( DDPF_PALETTEINDEXED4 |
|
|
DDPF_PALETTEINDEXED8 ) ) == 0 )
|
|
{
|
|
// palettized pixfmts will not have valid RGB Bitmasks, so avoid
|
|
// computing this for them
|
|
|
|
pCtx->red_mask = pSPixFmt->dwRBitMask;
|
|
pCtx->green_mask = pSPixFmt->dwGBitMask;
|
|
pCtx->blue_mask = pSPixFmt->dwBBitMask;
|
|
|
|
if( (pCtx->red_mask == 0x0) || (pCtx->green_mask == 0x0) ||
|
|
(pCtx->blue_mask == 0x0) )
|
|
{
|
|
D3D_ERR("All the color masks in the Render target's pixel-format "
|
|
"must be non-zero");
|
|
return DDERR_INVALIDPIXELFORMAT;
|
|
}
|
|
|
|
// these are used by Clear
|
|
for( s = 0, m = pCtx->red_mask; !(m & 1); s++, m >>= 1 );
|
|
pCtx->red_shift = s;
|
|
pCtx->red_scale = 255 / (pCtx->red_mask >> s);
|
|
for( s = 0, m = pCtx->green_mask; !(m & 1); s++, m >>= 1 );
|
|
pCtx->green_shift = s;
|
|
pCtx->green_scale = 255 / (pCtx->green_mask >> s);
|
|
for( s = 0, m = pCtx->blue_mask; !(m & 1); s++, m >>= 1 );
|
|
pCtx->blue_shift = s;
|
|
pCtx->blue_scale = 255 / (pCtx->blue_mask >> s);
|
|
|
|
if( (pCtx->red_scale==0) || (pCtx->green_scale==0) ||
|
|
(pCtx->blue_scale==0) )
|
|
return DDERR_INVALIDPIXELFORMAT;
|
|
|
|
pCtx->bDDSTargetIsPalettized=FALSE;
|
|
}
|
|
else
|
|
{
|
|
pCtx->bDDSTargetIsPalettized=TRUE;
|
|
}
|
|
|
|
if( pZLcl )
|
|
{
|
|
// Get info from the surface
|
|
GET_PIXEL_FORMAT( pZLcl, pZLcl->lpGbl, pZPixFmt );
|
|
if( pZPixFmt->dwZBitMask!=0x0)
|
|
{
|
|
for(s = 0, m = pZPixFmt->dwZBitMask; !(m & 0x1); s++, m >>= 1);
|
|
pCtx->zmask_shift = s;
|
|
}
|
|
else
|
|
{
|
|
// if ZBitMask isn't being set, then Clear2 will never be used,
|
|
// so zbuf_shift/stencil_shift wont be needed anyway
|
|
pCtx->zmask_shift=0;
|
|
}
|
|
|
|
if( pZPixFmt->dwStencilBitMask != 0x0 )
|
|
{
|
|
for(s = 0, m = pZPixFmt->dwStencilBitMask; !(m & 0x1);
|
|
s++, m >>= 1) ;
|
|
pCtx->stencilmask_shift = s;
|
|
}
|
|
else
|
|
{
|
|
pCtx->stencilmask_shift=0;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
DWORD WINAPI D3dContextCreate(PD3D8_CONTEXTCREATEDATA pCreateContext)
|
|
{
|
|
D3DHAL_CONTEXTCREATEDATA data;
|
|
DWORD ret;
|
|
HRESULT hr = S_OK;
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) pCreateContext->hDD;
|
|
LPDDRAWI_DIRECTDRAW_INT lpDD = pDevice->pDD;
|
|
PDDSURFACE lpDDSTarget = (PDDSURFACE)pCreateContext->hSurface;
|
|
PDDSURFACE lpDDSZBuffer = (PDDSURFACE)pCreateContext->hDDSZ;
|
|
PDDCONTEXT pContext;
|
|
ULONG cjBuffer = 0;
|
|
|
|
// Do the allocation first, since if it fails we don't have to do any real cleanup
|
|
|
|
ENTER_BOTH();
|
|
pDevice->pContext = NULL;
|
|
pContext = (PDDCONTEXT) MemAlloc(sizeof(DDCONTEXT));
|
|
if (pContext == NULL)
|
|
{
|
|
pCreateContext->ddrval = DDERR_OUTOFMEMORY;
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Now allocate the memory for the DPBuffer.
|
|
pContext->pDPBuffer = NULL;
|
|
|
|
cjBuffer = pCreateContext->cjBuffer;
|
|
if( cjBuffer == 0)
|
|
{
|
|
cjBuffer = DEF_PRIM_BUFFER_SIZE;
|
|
}
|
|
else if (cjBuffer < MIN_PRIM_BUFFER_SIZE ||
|
|
cjBuffer > MAX_PRIM_BUFFER_SIZE)
|
|
{
|
|
D3D_ERR("Illegal buffer size");
|
|
pCreateContext->ddrval = D3DERR_DRIVERINTERNALERROR;
|
|
MemFree( pContext );
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
pContext->pDPBuffer = (LPVOID)MemAlloc( cjBuffer );
|
|
if( pContext->pDPBuffer == NULL )
|
|
{
|
|
pCreateContext->ddrval = DDERR_OUTOFMEMORY;
|
|
MemFree( pContext );
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
pCreateContext->pvBuffer = (LPVOID)(((DWORD)pContext->pDPBuffer+31)&(~31));
|
|
pCreateContext->cjBuffer = cjBuffer;
|
|
|
|
// We need to check for a lost device before mucking around with the surfaces
|
|
|
|
if (CheckForDeviceLost(pDevice))
|
|
{
|
|
pContext->Context = 0;
|
|
pContext->pDevice = pDevice;
|
|
pDevice->pContext = pContext;
|
|
pCreateContext->dwhContext = (ULONG_PTR) pContext;
|
|
|
|
// Remember data required to create the context later
|
|
|
|
pContext->dwFlags = DDCONTEXT_DEFER;
|
|
pContext->dwTempContext = pCreateContext->dwhContext;
|
|
pContext->dwPID = pCreateContext->dwPID;
|
|
pContext->ddrval = pCreateContext->ddrval;
|
|
|
|
pCreateContext->ddrval = DD_OK;
|
|
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Calculate the surface info for Clear emulation if needed
|
|
hr = CalcDDSurfInfo( pContext,
|
|
(lpDDSTarget) ? lpDDSTarget->Surface.pHeavy->lpLcl
|
|
: NULL,
|
|
(lpDDSZBuffer) ? lpDDSZBuffer->Surface.pHeavy->lpLcl
|
|
: NULL );
|
|
if( FAILED( hr ) )
|
|
{
|
|
pCreateContext->ddrval = MapLegacyResult(hr);
|
|
MemFree(pContext->pDPBuffer);
|
|
pCreateContext->pvBuffer = NULL;
|
|
pCreateContext->cjBuffer = 0;
|
|
MemFree(pContext);
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
memset(&data, 0, sizeof(D3DHAL_CONTEXTCREATEDATA));
|
|
|
|
pDevice->pContext = NULL;
|
|
if (pDevice->DriverLevel >= 7)
|
|
{
|
|
if (lpDD)
|
|
data.lpDDLcl = lpDD->lpLcl;
|
|
else
|
|
data.lpDDLcl = NULL;
|
|
|
|
if (lpDDSTarget)
|
|
data.lpDDSLcl = lpDDSTarget->Surface.pHeavy->lpLcl;
|
|
else
|
|
data.lpDDSLcl = NULL;
|
|
|
|
if (lpDDSZBuffer)
|
|
data.lpDDSZLcl = lpDDSZBuffer->Surface.pHeavy->lpLcl;
|
|
else
|
|
data.lpDDSZLcl = NULL;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (lpDD)
|
|
data.lpDDGbl = lpDD->lpLcl->lpGbl;
|
|
else
|
|
data.lpDDLcl = NULL;
|
|
|
|
if (lpDDSTarget)
|
|
data.lpDDS = (LPDIRECTDRAWSURFACE)lpDDSTarget->Surface.pHeavy;
|
|
else
|
|
data.lpDDS = NULL;
|
|
|
|
if (lpDDSZBuffer)
|
|
data.lpDDSZ = (LPDIRECTDRAWSURFACE)lpDDSZBuffer->Surface.pHeavy;
|
|
else
|
|
data.lpDDSZ = NULL;
|
|
}
|
|
|
|
// Hack Alert!! dwhContext is used to inform the driver which version
|
|
// of the D3D interface is calling it.
|
|
data.dwhContext = pCreateContext->dwhContext;
|
|
data.dwPID = pCreateContext->dwPID;
|
|
data.ddrval = pCreateContext->ddrval;
|
|
|
|
/* 0 for pre-DX5 devices.
|
|
* 1 for DX5 devices.
|
|
* 2 for DX6 devices.
|
|
* 3 for DX7 devices.
|
|
*/
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pDevice,
|
|
lpDD->lpLcl->lpGbl->lpD3DHALCallbacks->ContextCreate,
|
|
&data);
|
|
|
|
if (ret != DDHAL_DRIVER_HANDLED || data.ddrval != DD_OK)
|
|
{
|
|
D3D_ERR( "Driver did not handle ContextCreate" );
|
|
MemFree(pContext->pDPBuffer);
|
|
pCreateContext->pvBuffer = NULL;
|
|
pCreateContext->cjBuffer = 0;
|
|
MemFree(pContext);
|
|
pCreateContext->dwhContext = 0;
|
|
pCreateContext->ddrval = D3DERR_DRIVERINTERNALERROR;
|
|
}
|
|
else
|
|
{
|
|
pContext->Context = data.dwhContext;
|
|
pContext->pDevice = pDevice;
|
|
pDevice->pContext = pContext;
|
|
|
|
pCreateContext->dwhContext = (ULONG_PTR) pContext;
|
|
pCreateContext->ddrval = data.ddrval;
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
HRESULT WINAPI D3dContextDestroy(PD3D8_CONTEXTDESTROYDATA pDestroyContext)
|
|
{
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pDestroyContext->dwhContext;
|
|
|
|
ENTER_BOTH();
|
|
CheckForDeviceLost(pContext->pDevice);
|
|
|
|
pDestroyContext->ddrval = DD_OK;
|
|
if (pContext->Context)
|
|
{
|
|
D3DHAL_CONTEXTDESTROYDATA data;
|
|
DWORD ret;
|
|
DDSURFACE* pSurf;
|
|
|
|
// If there are any DX6 texture handles created w/ this context,
|
|
// we should destroy them now.
|
|
|
|
pSurf = pContext->pDevice->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if ((pSurf->dwFlags & DDSURFACE_DX6HANDLE) &&
|
|
(pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy != NULL))
|
|
{
|
|
D3DHAL_TEXTUREDESTROYDATA data;
|
|
DWORD ret;
|
|
|
|
data.dwhContext = (ULONG_PTR) pContext->Context;
|
|
data.dwHandle = pSurf->dwCookie;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pSurf->pDevice,
|
|
pSurf->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy,
|
|
&data);
|
|
pSurf->dwFlags &= ~DDSURFACE_DX6HANDLE;
|
|
pSurf->dwCookie = 0;
|
|
}
|
|
pSurf = pSurf->pNext;
|
|
}
|
|
|
|
data.dwhContext = (ULONG_PTR) pContext->Context;
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pContext->pDevice,
|
|
pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->ContextDestroy,
|
|
&data);
|
|
|
|
pDestroyContext->ddrval = MapLegacyResult(data.ddrval);
|
|
}
|
|
|
|
if( pContext->pDPBuffer ) MemFree( pContext->pDPBuffer );
|
|
pContext->pDevice->pContext = NULL;
|
|
MemFree(pContext);
|
|
LEAVE_BOTH();
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
void BltFillRects( PDDCONTEXT pCtx, PDDSURFACE pDDS, DWORD count,
|
|
LPD3DRECT rect, D3DCOLOR dwFillColor)
|
|
{
|
|
HRESULT ddrval;
|
|
DDBLTFX bltfx;
|
|
RECT tr;
|
|
DWORD i;
|
|
DWORD r, g, b;
|
|
|
|
// Fill with background color
|
|
|
|
memset(&bltfx, 0, sizeof(bltfx));
|
|
bltfx.dwSize = sizeof(bltfx);
|
|
|
|
// unlike clear callback, which just takes pure 32-bit ARGB word and forces the driver to scale it for
|
|
// the pixelformat, here we need to compute the exact fill word, depending on surface's R,G,B bitmasks
|
|
|
|
if( pCtx->bDDSTargetIsPalettized )
|
|
{
|
|
// Palettized render targets are not supported
|
|
DDASSERT( TRUE );
|
|
}
|
|
else
|
|
{
|
|
DDASSERT((pCtx->red_scale!=0)&&(pCtx->green_scale!=0)&&(pCtx->blue_scale!=0));
|
|
r = RGB_GETRED(dwFillColor) / pCtx->red_scale;
|
|
g = RGB_GETGREEN(dwFillColor) / pCtx->green_scale;
|
|
b = RGB_GETBLUE(dwFillColor) / pCtx->blue_scale;
|
|
bltfx.dwFillColor = (r << pCtx->red_shift) | (g << pCtx->green_shift) |
|
|
(b << pCtx->blue_shift);
|
|
}
|
|
|
|
for (i = 0; i < count; i++,rect++)
|
|
{
|
|
tr.left = rect->x1;
|
|
tr.right = rect->x2;
|
|
tr.top = rect->y1;
|
|
tr.bottom = rect->y2;
|
|
do
|
|
{
|
|
ddrval = DD_Surface_Blt( (LPDIRECTDRAWSURFACE)pDDS->Surface.pHeavy,
|
|
&tr, NULL, NULL, DDBLT_COLORFILL, &bltfx);
|
|
} while (ddrval == DDERR_WASSTILLDRAWING);
|
|
}
|
|
}
|
|
|
|
void BltFillZRects( PDDCONTEXT pCtx, PDDSURFACE pDDSZ, unsigned long Zpixel,
|
|
DWORD count, LPD3DRECT rect, DWORD dwWriteMask)
|
|
{
|
|
HRESULT ddrval;
|
|
DDBLTFX bltfx;
|
|
DWORD i;
|
|
RECT tr;
|
|
DWORD dwExtraFlags=0;
|
|
|
|
memset(&bltfx, 0, sizeof(DDBLTFX));
|
|
bltfx.dwSize = sizeof(DDBLTFX);
|
|
bltfx.dwFillDepth = Zpixel;
|
|
|
|
// hack to pass DepthBlt WriteMask through ddraw/ddhel to blitlib
|
|
if( dwWriteMask != 0 )
|
|
{
|
|
bltfx.dwZDestConstBitDepth = dwWriteMask;
|
|
dwExtraFlags = DDBLT_DEPTHFILLWRITEMASK;
|
|
}
|
|
|
|
for(i=0; i<count ; i++, rect++)
|
|
{
|
|
tr.left = rect->x1;
|
|
tr.right = rect->x2;
|
|
tr.top = rect->y1;
|
|
tr.bottom = rect->y2;
|
|
do
|
|
{
|
|
ddrval = DD_Surface_Blt(
|
|
(LPDIRECTDRAWSURFACE)pDDSZ->Surface.pHeavy,
|
|
&tr, NULL, NULL,
|
|
DDBLT_DEPTHFILL |
|
|
dwExtraFlags, &bltfx );
|
|
} while (ddrval == DDERR_WASSTILLDRAWING);
|
|
}
|
|
}
|
|
|
|
DWORD WINAPI D3dClear( PD3D8_CLEAR2DATA pData )
|
|
{
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pData->dwhContext;
|
|
LPDDRAWI_DIRECTDRAW_GBL pGbl = NULL;
|
|
DWORD ret = DDHAL_DRIVER_HANDLED;
|
|
DWORD dwFlags = pData->dwFlags;
|
|
BOOL bDoRGBClear = ((dwFlags & D3DCLEAR_TARGET)!=0);
|
|
BOOL bDoZClear = ((dwFlags & D3DCLEAR_ZBUFFER)!=0);
|
|
BOOL bDoStencilClear = ((dwFlags & D3DCLEAR_STENCIL)!=0);
|
|
D3DVALUE dvZ = pData->dvFillDepth;
|
|
PDDSURFACE pZBuffer = NULL;
|
|
LPDDRAWI_DDRAWSURFACE_GBL pZGbl = NULL;
|
|
LPDDRAWI_DDRAWSURFACE_LCL pZLcl = NULL;
|
|
LPDDPIXELFORMAT pZPixFmt = NULL;
|
|
|
|
pData->ddrval = S_OK;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pContext->pDevice))
|
|
{
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
|
|
pGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
|
|
if( pGbl->lpD3DHALCallbacks3->Clear2 )
|
|
{
|
|
D3DHAL_CLEAR2DATA Clear2Data;
|
|
memcpy( &Clear2Data, pData, sizeof( Clear2Data ) );
|
|
Clear2Data.dwhContext = pContext->Context;
|
|
Clear2Data.ddrval = S_OK;
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
|
|
pContext->pDevice,
|
|
pGbl->lpD3DHALCallbacks3->Clear2,
|
|
(D3DHAL_CLEAR2DATA *)&Clear2Data);
|
|
|
|
LEAVE_BOTH();
|
|
pData->ddrval = MapLegacyResult(Clear2Data.ddrval);
|
|
return ret;
|
|
}
|
|
|
|
if( pGbl->lpD3DGlobalDriverData->hwCaps.dpcTriCaps.dwRasterCaps &
|
|
D3DPRASTERCAPS_ZBUFFERLESSHSR )
|
|
{
|
|
if( bDoStencilClear )
|
|
{
|
|
D3D_ERR( "Invalid flag D3DCLEAR_STENCIL: this ZBUFFERLESSHSR "
|
|
"device doesn't support Stencil Clears");
|
|
pData->ddrval = D3DERR_DRIVERINTERNALERROR;
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
|
|
if( bDoZClear )
|
|
{
|
|
if( !(pGbl->lpD3DHALCallbacks2->Clear) || (dvZ != 1.0f) )
|
|
{
|
|
D3D_WARN(3,"Ignoring D3DCLEAR_ZBUFFER since this "
|
|
"ZBUFFERLESSHSR device doesn't even support Clear "
|
|
"or Z!=1");
|
|
dwFlags &= ~(D3DCLEAR_ZBUFFER);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pData->hDDSZ )
|
|
{
|
|
pZBuffer = (PDDSURFACE)pData->hDDSZ;
|
|
pZLcl = pZBuffer->Surface.pHeavy->lpLcl;
|
|
pZGbl = pZLcl->lpGbl;
|
|
pZPixFmt = &pZGbl->ddpfSurface;
|
|
}
|
|
|
|
if( pGbl->lpD3DHALCallbacks2->Clear )
|
|
{
|
|
D3DHAL_CLEARDATA ClearData;
|
|
|
|
if( bDoZClear || bDoStencilClear )
|
|
{
|
|
if( (pZPixFmt != NULL) && //PowerVR need no Zbuffer
|
|
(DDPF_STENCILBUFFER & pZPixFmt->dwFlags))
|
|
{
|
|
// if surface has stencil bits, must verify either Clear2
|
|
// callback exists or we're using SW rasterizers
|
|
// (which require the special WriteMask DDHEL blt)
|
|
// This case should not be hit since we check right at the
|
|
// driver initialization time if the driver doesnt report
|
|
// Clear2 yet it supports stencils
|
|
if( pZLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY )
|
|
{
|
|
goto Emulateclear;
|
|
}
|
|
else
|
|
{
|
|
LEAVE_BOTH();
|
|
D3D_ERR( "Driver doesn't support StencilBuffer Clears");
|
|
pData->ddrval = D3DERR_DRIVERINTERNALERROR;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
}
|
|
// if Clear2 callback doesnt exist and it's a z-only surface and
|
|
// not doing zclear to non-max value then Clear2 is attempting to
|
|
// do no more than Clear could do, so it's safe to call Clear()
|
|
// instead of Clear2(), which will take advantage of older
|
|
// drivers that implement Clear but not Clear2
|
|
|
|
dwFlags &= ~D3DCLEAR_STENCIL; // Device cannot do stencil
|
|
}
|
|
|
|
if( bDoZClear && (dvZ != 1.0) )
|
|
{
|
|
ClearData.dwFlags = dwFlags & ~D3DCLEAR_ZBUFFER;
|
|
dwFlags = D3DCLEAR_ZBUFFER;
|
|
}
|
|
else
|
|
{
|
|
ClearData.dwFlags = dwFlags;
|
|
dwFlags = 0;
|
|
}
|
|
|
|
if (ClearData.dwFlags)
|
|
{
|
|
ClearData.dwhContext = pContext->Context;
|
|
// Here I will follow the ClearData.dwFillColor convention that
|
|
// color word is raw 32bit ARGB, unadjusted for surface bit depth
|
|
ClearData.dwFillColor = pData->dwFillColor;
|
|
// must clear to 0xffffffff because legacy drivers expect this
|
|
ClearData.dwFillDepth = 0xffffffff;
|
|
ClearData.lpRects = pData->lpRects;
|
|
ClearData.dwNumRects = pData->dwNumRects;
|
|
ClearData.ddrval = S_OK;
|
|
|
|
// if((err = CheckContextSurface(this)) != D3D_OK)
|
|
// {
|
|
// throw err;
|
|
// }
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
|
|
pContext->pDevice,
|
|
pGbl->lpD3DHALCallbacks2->Clear,
|
|
(D3DHAL_CLEARDATA *)&ClearData);
|
|
|
|
pData->ddrval = MapLegacyResult(ClearData.ddrval);
|
|
LEAVE_BOTH();
|
|
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
Emulateclear: // Fall back to Emulation using Blt
|
|
{
|
|
PDDSURFACE pTarget = (PDDSURFACE)pData->hDDS;
|
|
LPDDRAWI_DDRAWSURFACE_GBL pTargetGbl =
|
|
pTarget->Surface.pHeavy->lpLcl->lpGbl;
|
|
DWORD dwStencil = pData->dwFillStencil;
|
|
|
|
if(bDoRGBClear)
|
|
{
|
|
BltFillRects( pContext, (PDDSURFACE)pData->hDDS, pData->dwNumRects,
|
|
pData->lpRects, pData->dwFillColor );
|
|
//ok to not return possible errors from Blt?
|
|
}
|
|
if( (bDoZClear || bDoStencilClear) && NULL != pZPixFmt)
|
|
{
|
|
DWORD dwZbufferClearValue=0;
|
|
DWORD dwZbufferClearMask=0;
|
|
DDASSERT(pZPixFmt->dwZBufferBitDepth<=32);
|
|
DDASSERT(pZPixFmt->dwStencilBitDepth<32);
|
|
DDASSERT(pZPixFmt->dwZBitMask!=0x0);
|
|
DDASSERT((0xFFFFFFFF == (pZPixFmt->dwZBitMask |
|
|
pZPixFmt->dwStencilBitMask)) |
|
|
((DWORD)((1<<pZPixFmt->dwZBufferBitDepth)-1) ==
|
|
(pZPixFmt->dwZBitMask | pZPixFmt->dwStencilBitMask)));
|
|
DDASSERT(0==(pZPixFmt->dwZBitMask & pZPixFmt->dwStencilBitMask));
|
|
if(bDoZClear)
|
|
{
|
|
dwZbufferClearMask = pZPixFmt->dwZBitMask;
|
|
// special case the common cases
|
|
if( dvZ==1.0f )
|
|
{
|
|
dwZbufferClearValue = pZPixFmt->dwZBitMask;
|
|
}
|
|
else if( dvZ > 0.0f )
|
|
{
|
|
dwZbufferClearValue =
|
|
((DWORD)((dvZ*(pZPixFmt->dwZBitMask >>
|
|
pContext->zmask_shift)) + 0.5)) <<
|
|
pContext->zmask_shift;
|
|
}
|
|
}
|
|
|
|
if( bDoStencilClear )
|
|
{
|
|
DDASSERT(pZPixFmt->dwStencilBitMask!=0x0);
|
|
DDASSERT(pZPixFmt->dwFlags & DDPF_STENCILBUFFER);
|
|
dwZbufferClearMask |= pZPixFmt->dwStencilBitMask;
|
|
// special case the common case
|
|
if( dwStencil != 0 )
|
|
{
|
|
dwZbufferClearValue |= (dwStencil <<
|
|
pContext->stencilmask_shift) &
|
|
pZPixFmt->dwStencilBitMask;
|
|
}
|
|
}
|
|
if( dwZbufferClearMask == (pZPixFmt->dwStencilBitMask |
|
|
pZPixFmt->dwZBitMask) )
|
|
{
|
|
// do Stencil & Z Blt together, using regular DepthFill blt
|
|
// which will be faster than the writemask blt because its
|
|
// write-only, instead of read-modify-write
|
|
dwZbufferClearMask = 0;
|
|
}
|
|
BltFillZRects( pContext, (PDDSURFACE)pData->hDDSZ,
|
|
dwZbufferClearValue, pData->dwNumRects,
|
|
pData->lpRects, dwZbufferClearMask );
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return ret;
|
|
}
|
|
|
|
DWORD WINAPI D3dSetRenderTarget( PD3D8_SETRENDERTARGETDATA pData )
|
|
{
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pData->dwhContext;
|
|
LPDDRAWI_DIRECTDRAW_GBL pGbl = NULL;
|
|
DWORD ret = DDHAL_DRIVER_HANDLED;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pContext->pDevice))
|
|
{
|
|
LEAVE_BOTH();
|
|
pData->ddrval = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
pGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
|
|
if( pGbl->lpD3DHALCallbacks2->SetRenderTarget )
|
|
{
|
|
D3DHAL_SETRENDERTARGETDATA srtData;
|
|
|
|
// If creation of the render target was defered, create it now
|
|
|
|
if (pContext->dwFlags & DDCONTEXT_DEFER)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pTarget = NULL;
|
|
LPDDRAWI_DDRAWSURFACE_INT pZ = NULL;
|
|
HRESULT hr;
|
|
D3DHAL_CONTEXTCREATEDATA data;
|
|
DWORD ret;
|
|
|
|
if (pData->hDDS)
|
|
{
|
|
pTarget = ((PDDSURFACE)pData->hDDS)->Surface.pHeavy;
|
|
}
|
|
if (pData->hDDSZ)
|
|
{
|
|
pZ = ((PDDSURFACE)pData->hDDSZ)->Surface.pHeavy;
|
|
}
|
|
|
|
// Calculate the surface info for Clear emulation if needed
|
|
CalcDDSurfInfo(pContext,
|
|
(pTarget) ? pTarget->lpLcl : NULL,
|
|
(pZ) ? pZ->lpLcl : NULL);
|
|
|
|
memset(&data, 0, sizeof(D3DHAL_CONTEXTCREATEDATA));
|
|
if (pContext->pDevice->DriverLevel >= 7)
|
|
{
|
|
if (pContext->pDevice->pDD != NULL)
|
|
{
|
|
data.lpDDLcl = pContext->pDevice->pDD->lpLcl;
|
|
}
|
|
|
|
if (pTarget != NULL)
|
|
{
|
|
data.lpDDSLcl = pTarget->lpLcl;
|
|
}
|
|
else
|
|
{
|
|
data.lpDDSLcl = NULL;
|
|
}
|
|
if (pZ != NULL)
|
|
{
|
|
data.lpDDSZLcl = pZ->lpLcl;
|
|
}
|
|
else
|
|
{
|
|
data.lpDDSZLcl = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pContext->pDevice->pDD != NULL)
|
|
{
|
|
data.lpDDGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
|
|
}
|
|
|
|
data.lpDDS = (LPDIRECTDRAWSURFACE)pTarget;
|
|
data.lpDDSZ = (LPDIRECTDRAWSURFACE) pZ;
|
|
}
|
|
|
|
// Hack Alert!! dwhContext is used to inform the driver which version
|
|
// of the D3D interface is calling it.
|
|
data.dwhContext = pContext->dwTempContext;
|
|
data.dwPID = pContext->dwPID;
|
|
data.ddrval = pContext->ddrval;
|
|
|
|
/* 0 for pre-DX5 devices.
|
|
* 1 for DX5 devices.
|
|
* 2 for DX6 devices.
|
|
* 3 for DX7 devices.
|
|
*/
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pContext->pDevice,
|
|
pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->ContextCreate,
|
|
&data);
|
|
|
|
if (ret == DDHAL_DRIVER_HANDLED && data.ddrval == DD_OK)
|
|
{
|
|
pContext->Context = data.dwhContext;
|
|
}
|
|
pContext->dwFlags &= ~DDCONTEXT_DEFER;
|
|
}
|
|
|
|
pData->bNeedUpdate = FALSE;
|
|
memset( &srtData, 0, sizeof( srtData ) );
|
|
srtData.dwhContext = pContext->Context;
|
|
if( pData->hDDS )
|
|
srtData.lpDDS =
|
|
(LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDS)->Surface.pHeavy;
|
|
if( pData->hDDSZ )
|
|
srtData.lpDDSZ =
|
|
(LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDSZ)->Surface.pHeavy;
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
|
|
pContext->pDevice,
|
|
pGbl->lpD3DHALCallbacks2->SetRenderTarget,
|
|
(D3DHAL_SETRENDERTARGETDATA *)&srtData );
|
|
pData->ddrval = MapLegacyResult(srtData.ddrval);
|
|
|
|
// If we need to create any defered texture handles, we will do so now
|
|
|
|
if (pContext->dwFlags & DDCONTEXT_DEFEREDTEXTUREHANDLES)
|
|
{
|
|
DDSURFACE* pSurf;
|
|
|
|
pContext->dwFlags &= ~ DDCONTEXT_DEFEREDTEXTUREHANDLES;
|
|
pSurf = pContext->pDevice->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_DEFERCREATETEXHANDLE)
|
|
{
|
|
D3DHAL_TEXTURECREATEDATA data;
|
|
DWORD ret;
|
|
|
|
memset(&data, 0, sizeof(D3DHAL_TEXTURECREATEDATA));
|
|
data.dwhContext = pContext->Context;
|
|
data.lpDDS = (LPDIRECTDRAWSURFACE) pSurf->Surface.pHeavy;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pContext->pDevice,
|
|
pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate,
|
|
&data);
|
|
|
|
pSurf->dwCookie = data.dwHandle;
|
|
pSurf->dwFlags |= DDSURFACE_DX6HANDLE;
|
|
pSurf->dwFlags &= ~DDSURFACE_DEFERCREATETEXHANDLE;
|
|
}
|
|
pSurf = pSurf->pNext;
|
|
}
|
|
}
|
|
|
|
LEAVE_BOTH();
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
D3DHAL_CONTEXTCREATEDATA cdata;
|
|
D3DHAL_CONTEXTDESTROYDATA ddata;
|
|
DDSURFACE* pTemp;
|
|
|
|
// If we have allocated any texture handles, we need to free them now
|
|
|
|
pTemp = pContext->pDevice->pSurfList;
|
|
while (pTemp != NULL)
|
|
{
|
|
if ((pTemp->dwFlags & DDSURFACE_DX6HANDLE) &&
|
|
(pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy != NULL))
|
|
{
|
|
D3DHAL_TEXTUREDESTROYDATA data;
|
|
DWORD ret;
|
|
|
|
data.dwhContext = (ULONG_PTR) pContext->Context;
|
|
data.dwHandle = pTemp->dwCookie;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pTemp->pDevice,
|
|
pTemp->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureDestroy,
|
|
&data);
|
|
}
|
|
pTemp = pTemp->pNext;
|
|
}
|
|
|
|
pData->bNeedUpdate = TRUE;
|
|
memset( &ddata, 0, sizeof(D3DHAL_CONTEXTDESTROYDATA) );
|
|
|
|
// Destroy Old Context
|
|
ddata.dwhContext = pContext->Context;
|
|
if (pContext->Context != 0)
|
|
{
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
|
|
pContext->pDevice,
|
|
pGbl->lpD3DHALCallbacks->ContextDestroy,
|
|
&ddata );
|
|
|
|
if (ret != DDHAL_DRIVER_HANDLED || ddata.ddrval != DD_OK)
|
|
{
|
|
D3D_ERR( "SRT emulation, ContextDestroy failed." );
|
|
LEAVE_BOTH();
|
|
pData->ddrval = MapLegacyResult(ddata.ddrval);
|
|
return ret;
|
|
}
|
|
}
|
|
pContext->dwFlags &= ~(DDCONTEXT_DEFER | DDCONTEXT_DEFEREDTEXTUREHANDLES);
|
|
|
|
// Create a new Context
|
|
memset( &cdata, 0, sizeof(D3DHAL_CONTEXTCREATEDATA) );
|
|
cdata.lpDDGbl = pGbl;
|
|
if( pData->hDDS )
|
|
cdata.lpDDS =
|
|
(LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDS)->Surface.pHeavy;;
|
|
if( pData->hDDSZ )
|
|
cdata.lpDDSZ =
|
|
(LPDIRECTDRAWSURFACE)((PDDSURFACE)pData->hDDSZ)->Surface.pHeavy;
|
|
// Hack Alert!! dwhContext is used to inform the driver which version
|
|
// of the D3D interface is calling it.
|
|
// We don't want DX6 drivers to know that we are DX8 because
|
|
// we found at least one driver that starts behaving differently when
|
|
// it sees anything other than 3. (the driver was TNT2 and it turned
|
|
// off multitexturing thinking that anything other than 3 means DX5
|
|
// or below)
|
|
cdata.dwhContext = 3;
|
|
DDASSERT(pContext->pDevice->DriverLevel < 7); // should never get here for DX7 or above drivers
|
|
cdata.dwPID = GetCurrentProcessId();
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
|
|
pContext->pDevice,
|
|
pGbl->lpD3DHALCallbacks->ContextCreate,
|
|
&cdata );
|
|
if (ret != DDHAL_DRIVER_HANDLED || cdata.ddrval != DD_OK)
|
|
{
|
|
D3D_ERR( "SRT emulation, ContextCreate failed" );
|
|
LEAVE_BOTH();
|
|
pData->dwhContext = 0;
|
|
pData->ddrval = MapLegacyResult(cdata.ddrval);
|
|
return ret;
|
|
}
|
|
pContext->Context = cdata.dwhContext;
|
|
pData->ddrval = MapLegacyResult(cdata.ddrval);
|
|
|
|
// Now we need to re-create any texture handles that we destroyed
|
|
|
|
if (pData->ddrval == DD_OK)
|
|
{
|
|
pTemp = pContext->pDevice->pSurfList;
|
|
while (pTemp != NULL)
|
|
{
|
|
if ((pTemp->dwFlags & DDSURFACE_DX6HANDLE) ||
|
|
(pTemp->dwFlags & DDSURFACE_DEFERCREATETEXHANDLE))
|
|
{
|
|
D3DHAL_TEXTURECREATEDATA data;
|
|
DWORD ret;
|
|
|
|
memset(&data, 0, sizeof(D3DHAL_TEXTURECREATEDATA));
|
|
data.dwhContext = pContext->Context;
|
|
data.lpDDS = (LPDIRECTDRAWSURFACE) pTemp->Surface.pHeavy;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(ret,
|
|
pTemp->pDevice,
|
|
pTemp->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks->TextureCreate,
|
|
&data);
|
|
pTemp->dwCookie = data.dwHandle;
|
|
pTemp->dwFlags |= DDSURFACE_DX6HANDLE;
|
|
pTemp->dwFlags &= ~DDSURFACE_DEFERCREATETEXHANDLE;
|
|
}
|
|
pTemp = pTemp->pNext;
|
|
}
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
return ret;
|
|
}
|
|
|
|
|
|
HRESULT WINAPI D3dContextDestroyAll(PD3D8_CONTEXTDESTROYALLDATA pDestroyAllContext)
|
|
{
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
|
|
HRESULT WINAPI D3dGetDriverState(PD3D8_GETDRIVERSTATEDATA pGetDriverState)
|
|
{
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pGetDriverState->dwhContext;
|
|
DWORD dwRet = DDHAL_DRIVER_HANDLED;
|
|
ULONG_PTR pTemp;
|
|
|
|
pGetDriverState->ddRVal = D3DERR_DRIVERINTERNALERROR;
|
|
ENTER_BOTH();
|
|
if (!CheckForDeviceLost(pContext->pDevice))
|
|
{
|
|
pTemp = pGetDriverState->dwhContext;
|
|
pGetDriverState->dwhContext = (ULONG_PTR) pContext->Context;
|
|
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(dwRet,
|
|
pContext->pDevice,
|
|
pContext->pDevice->pDD->lpLcl->lpGbl->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState,
|
|
(LPDDHAL_GETDRIVERSTATEDATA)pGetDriverState);
|
|
pGetDriverState->dwhContext = pTemp;
|
|
|
|
pGetDriverState->ddRVal = MapLegacyResult(pGetDriverState->ddRVal);
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
HRESULT WINAPI D3dValidateTextureStageState(PD3D8_VALIDATETEXTURESTAGESTATEDATA pValidate)
|
|
{
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pValidate->dwhContext;
|
|
DWORD dwRet = DDHAL_DRIVER_HANDLED;
|
|
ULONG_PTR pTemp;
|
|
|
|
pValidate->ddrval = D3DERR_DEVICELOST;
|
|
pValidate->dwNumPasses = 0;
|
|
ENTER_BOTH();
|
|
if (!CheckForDeviceLost(pContext->pDevice))
|
|
{
|
|
pTemp = pValidate->dwhContext;
|
|
pValidate->dwhContext = (ULONG_PTR) pContext->Context;
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(dwRet,
|
|
pContext->pDevice,
|
|
pContext->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks3->ValidateTextureStageState,
|
|
(D3DHAL_VALIDATETEXTURESTAGESTATEDATA*) pValidate);
|
|
pValidate->dwhContext = pTemp;
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
DWORD WINAPI D3dDrawPrimitives2(PD3D8_DRAWPRIMITIVES2DATA pdp2data)
|
|
{
|
|
D3DHAL_DRAWPRIMITIVES2DATA dp2data;
|
|
DWORD ret = 0;
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pdp2data->dwhContext;
|
|
DDSURFACE* pSurfCommand;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavyCommand;
|
|
DDSURFACE* pSurfVertex = NULL;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavyVertex = NULL;
|
|
|
|
// Copy the data into our structure for easy access
|
|
memcpy (&dp2data, pdp2data, sizeof(dp2data));
|
|
|
|
// Start processing
|
|
ENTER_BOTH();
|
|
|
|
// Handle loss
|
|
if (CheckForDeviceLost(((PDDSURFACE)pdp2data->hDDCommands)->pDevice))
|
|
{
|
|
pdp2data->ddrval = DD_OK;
|
|
pdp2data->dwErrorOffset = 0;
|
|
|
|
// Need to set these values to their original
|
|
// state so that the FE doesn't get confused.
|
|
pdp2data->fpVidMem_CB = 0;
|
|
pdp2data->dwLinearSize_CB = 0;
|
|
pdp2data->fpVidMem_VB = 0;
|
|
pdp2data->dwLinearSize_VB = 0;
|
|
|
|
// May need to return a pointer here
|
|
if ((dp2data.dwFlags & D3DHALDP2_SWAPVERTEXBUFFER) &&
|
|
!(dp2data.dwFlags & D3DHALDP2_USERMEMVERTICES))
|
|
{
|
|
DDSURFACE* pVertex = (PDDSURFACE)pdp2data->hDDVertex;
|
|
|
|
if (pVertex->Pool == D3DPOOL_SYSTEMMEM)
|
|
{
|
|
if (pVertex->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
pdp2data->fpVidMem_VB = pVertex->Surface.pLight->fpGblVidMem;
|
|
pdp2data->dwLinearSize_VB = pVertex->Surface.pLight->GblPitch;
|
|
}
|
|
else
|
|
{
|
|
pdp2data->fpVidMem_VB = pVertex->Surface.pHeavy->lpLcl->lpGbl->fpVidMem;
|
|
pdp2data->dwLinearSize_VB = pVertex->Surface.pHeavy->lpLcl->lpGbl->dwLinearSize;
|
|
}
|
|
}
|
|
else if (pVertex->dwFlags & DDSURFACE_HEAVYWEIGHT)
|
|
{
|
|
if ((pVertex->fpVidMem == NULL) ||
|
|
!(pVertex->dwFlags & DDSURFACE_SYSMEMALLOCATED))
|
|
{
|
|
pVertex->fpVidMem = (char*) MemAlloc(pVertex->Pitch);
|
|
if (pVertex->fpVidMem != NULL)
|
|
{
|
|
pVertex->dwFlags |= DDSURFACE_SYSMEMALLOCATED;
|
|
}
|
|
}
|
|
if (pVertex->dwFlags & DDSURFACE_SYSMEMALLOCATED)
|
|
{
|
|
pdp2data->fpVidMem_VB = (ULONG_PTR) pVertex->fpVidMem;
|
|
pdp2data->dwLinearSize_VB = pVertex->Pitch;
|
|
}
|
|
else
|
|
{
|
|
pdp2data->ddrval = DDERR_GENERIC;
|
|
}
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
pSurfCommand = (PDDSURFACE)pdp2data->hDDCommands;
|
|
pHeavyCommand = GetHeavyweightSurf(pSurfCommand);
|
|
if (pHeavyCommand != NULL)
|
|
{
|
|
dp2data.lpDDCommands = pHeavyCommand->lpLcl;
|
|
}
|
|
else
|
|
{
|
|
pdp2data->ddrval = DDERR_OUTOFMEMORY;
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
if (!(pdp2data->dwFlags & D3DHALDP2_USERMEMVERTICES))
|
|
{
|
|
pSurfVertex = (PDDSURFACE)pdp2data->hDDVertex;
|
|
pHeavyVertex = GetHeavyweightSurf(pSurfVertex);
|
|
dp2data.lpDDVertex = pHeavyVertex->lpLcl;
|
|
}
|
|
dp2data.dwhContext = ((PDDCONTEXT)dp2data.dwhContext)->Context;
|
|
|
|
if (((PDDSURFACE)pdp2data->hDDCommands)->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks3->DrawPrimitives2)
|
|
{
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16(
|
|
ret,
|
|
((PDDSURFACE)pdp2data->hDDCommands)->pDevice,
|
|
((PDDSURFACE)pdp2data->hDDCommands)->pDevice->pDD->lpLcl->lpGbl->lpD3DHALCallbacks3->DrawPrimitives2,
|
|
&dp2data);
|
|
if ((ret == DDHAL_DRIVER_HANDLED) && (dp2data.ddrval != DD_OK)
|
|
&& (DDERR_WASSTILLDRAWING != dp2data.ddrval))
|
|
{
|
|
((PDDSURFACE)pdp2data->hDDCommands)->pDevice->bDP2Error = TRUE;
|
|
}
|
|
}
|
|
|
|
// If the call to the driver succeded, swap the buffers if needed and
|
|
// perform GetAliasVidmem
|
|
if (ret == DDHAL_DRIVER_HANDLED && (dp2data.ddrval == DD_OK))
|
|
{
|
|
pdp2data->fpVidMem_CB = 0;
|
|
pdp2data->dwLinearSize_CB = 0;
|
|
pdp2data->fpVidMem_VB = 0;
|
|
pdp2data->dwLinearSize_VB = 0;
|
|
|
|
if (dp2data.dwFlags & D3DHALDP2_SWAPCOMMANDBUFFER)
|
|
{
|
|
// CONSIDER: Implement VidMem command buffer
|
|
}
|
|
|
|
if ((dp2data.dwFlags & D3DHALDP2_SWAPVERTEXBUFFER) && !(dp2data.dwFlags & D3DHALDP2_USERMEMVERTICES))
|
|
{
|
|
FLATPTR paliasbits;
|
|
DWORD dwLinearSize = dp2data.lpDDVertex->lpGbl->dwLinearSize;
|
|
if (dp2data.dwFlags & D3DHALDP2_VIDMEMVERTEXBUF)
|
|
{
|
|
paliasbits = GetAliasedVidMem( dp2data.lpDDVertex->lpSurfMore->lpDD_lcl,
|
|
dp2data.lpDDVertex,
|
|
(FLATPTR) dp2data.lpDDVertex->lpGbl->fpVidMem );
|
|
if (paliasbits == 0)
|
|
{
|
|
D3D_ERR( "Could not get Aliased pointer for vid mem vertex buffer" );
|
|
// Since we can't use this pointer, set it's size to 0
|
|
// That way next time around we will try and allocate a new one
|
|
dwLinearSize = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
paliasbits = dp2data.lpDDVertex->lpGbl->fpVidMem;
|
|
}
|
|
|
|
pdp2data->fpVidMem_VB = paliasbits;
|
|
pdp2data->dwLinearSize_VB = dwLinearSize;
|
|
}
|
|
}
|
|
if ((pSurfCommand->dwFlags & DDSURFACE_LIGHTWEIGHT) &&
|
|
(pHeavyCommand != NULL))
|
|
{
|
|
UnmapLightweightSurface (pSurfCommand);
|
|
}
|
|
if ((pSurfVertex != NULL ) &&
|
|
(pSurfVertex->dwFlags & DDSURFACE_LIGHTWEIGHT) &&
|
|
(pHeavyVertex != NULL))
|
|
{
|
|
UnmapLightweightSurface (pSurfVertex);
|
|
}
|
|
|
|
pdp2data->ddrval = dp2data.ddrval;
|
|
pdp2data->dwErrorOffset = dp2data.dwErrorOffset;
|
|
LEAVE_BOTH();
|
|
|
|
// We don't map the errors to the new ones because the runtime still needs
|
|
// to deal with WASSTILLDRAWING, so it does the mapping instead of us.
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
PALETTEINFO* GetPaletteInfo (PDDDEVICEHANDLE pDevice, DWORD PaletteID)
|
|
{
|
|
PALETTEINFO* pPaletteInfo;
|
|
HRESULT hr;
|
|
DWORD i;
|
|
|
|
// The palette IDs are app defined and can range from 0 - 65500. We don't
|
|
// want to always allocate a table with 65500 entries, and we don't want
|
|
// to walk a list on every palette call, so we will grow the table to the
|
|
// desired whenever we need to. This works well if we assume that most
|
|
// apps will start with low numbers and then work up.
|
|
|
|
if (PaletteID >= pDevice->NumPaletteHandleEntries)
|
|
{
|
|
// We need to grow the table
|
|
|
|
DWORD NewTableSize;
|
|
PALETTEINFO** pNewTable;
|
|
|
|
if (((DWORD)-1) - PaletteID <= EXTRA_PALETTE_PADDING)
|
|
{
|
|
NewTableSize = PaletteID + 1;
|
|
}
|
|
else
|
|
{
|
|
NewTableSize = PaletteID + EXTRA_PALETTE_PADDING + 1;
|
|
}
|
|
pNewTable = MemAlloc(NewTableSize * sizeof(PALETTEINFO*));
|
|
if (pNewTable == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
if ((pDevice->pPaletteHandleTable) &&
|
|
(pDevice->NumPaletteHandleEntries > 0))
|
|
{
|
|
memcpy(pNewTable,
|
|
pDevice->pPaletteHandleTable,
|
|
pDevice->NumPaletteHandleEntries * sizeof(PALETTEINFO*));
|
|
MemFree(pDevice->pPaletteHandleTable);
|
|
}
|
|
pDevice->pPaletteHandleTable = pNewTable;
|
|
pDevice->NumPaletteHandleEntries = NewTableSize;
|
|
}
|
|
|
|
// If we already have info for this palette, we just return it now
|
|
|
|
if (pDevice->pPaletteHandleTable[PaletteID] != NULL)
|
|
{
|
|
return pDevice->pPaletteHandleTable[PaletteID];
|
|
}
|
|
|
|
// Otherwise, we allocate a structure and initialize it
|
|
|
|
pPaletteInfo = MemAlloc(sizeof(PALETTEINFO));
|
|
if (pPaletteInfo == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
pPaletteInfo->ColorTable[i].peRed = (UCHAR) i;
|
|
pPaletteInfo->ColorTable[i].peGreen = (UCHAR) i;
|
|
pPaletteInfo->ColorTable[i].peBlue = (UCHAR) i;
|
|
pPaletteInfo->ColorTable[i].peFlags = (UCHAR) 0;
|
|
}
|
|
hr = DD_CreatePalette ((LPDIRECTDRAW) pDevice->pDD,
|
|
DDPCAPS_8BIT,
|
|
pPaletteInfo->ColorTable,
|
|
&pPaletteInfo->pDDPalette,
|
|
NULL);
|
|
if (hr != DD_OK)
|
|
{
|
|
MemFree(pPaletteInfo);
|
|
return NULL;
|
|
}
|
|
|
|
pDevice->pPaletteHandleTable[PaletteID] = pPaletteInfo;
|
|
return pPaletteInfo;
|
|
}
|
|
|
|
|
|
DWORD WINAPI DdSetPalette (PD3D8_SETPALETTEDATA pSetPalette)
|
|
{
|
|
PALETTEINFO* pPalette;
|
|
|
|
DDASSERT (((PDDDEVICEHANDLE)pSetPalette->hDD)->DriverLevel == 6);
|
|
|
|
ENTER_BOTH();
|
|
CheckForDeviceLost(pSetPalette->hDD);
|
|
|
|
pSetPalette->ddRVal = D3DERR_DRIVERINTERNALERROR;
|
|
pPalette = GetPaletteInfo (pSetPalette->hDD,
|
|
pSetPalette->Palette);
|
|
if (pPalette != NULL)
|
|
{
|
|
pSetPalette->ddRVal = DD_OK;
|
|
if ((((DDSURFACE*)pSetPalette->hSurface)->Surface.pHeavy != NULL) &&
|
|
(((DDSURFACE*)pSetPalette->hSurface)->Surface.pHeavy->lpLcl->lpDDPalette !=
|
|
(LPDDRAWI_DDRAWPALETTE_INT)pPalette->pDDPalette))
|
|
{
|
|
pSetPalette->ddRVal = MapLegacyResult(DD_Surface_SetPalette(
|
|
(LPDIRECTDRAWSURFACE)((DDSURFACE*)pSetPalette->hSurface)->Surface.pHeavy,
|
|
pPalette->pDDPalette));
|
|
}
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD WINAPI DdUpdatePalette (PD3D8_UPDATEPALETTEDATA pUpdatePalette)
|
|
{
|
|
PALETTEINFO* pPalette;
|
|
|
|
DDASSERT (((PDDDEVICEHANDLE)pUpdatePalette->hDD)->DriverLevel == 6);
|
|
|
|
ENTER_BOTH();
|
|
CheckForDeviceLost(pUpdatePalette->hDD);
|
|
|
|
pUpdatePalette->ddRVal = D3DERR_DRIVERINTERNALERROR;
|
|
pPalette = GetPaletteInfo (pUpdatePalette->hDD,
|
|
pUpdatePalette->Palette);
|
|
if (pPalette != NULL)
|
|
{
|
|
pUpdatePalette->ddRVal = MapLegacyResult(DD_Palette_SetEntries(
|
|
pPalette->pDDPalette,
|
|
0,
|
|
0,
|
|
256,
|
|
pUpdatePalette->ColorTable));
|
|
}
|
|
LEAVE_BOTH();
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
DWORD WINAPI D3dSceneCapture (PD3D8_SCENECAPTUREDATA pData)
|
|
{
|
|
PDDCONTEXT pContext = (PDDCONTEXT) pData->dwhContext;
|
|
LPDDRAWI_DIRECTDRAW_GBL pGbl = NULL;
|
|
DWORD ret = DDHAL_DRIVER_HANDLED;
|
|
|
|
pData->ddrval = S_OK;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(pContext->pDevice))
|
|
{
|
|
LEAVE_BOTH();
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
pGbl = pContext->pDevice->pDD->lpLcl->lpGbl;
|
|
if( pGbl->lpD3DHALCallbacks->SceneCapture )
|
|
{
|
|
D3DHAL_SCENECAPTUREDATA SceneCaptureData;
|
|
memcpy( &SceneCaptureData, pData, sizeof( SceneCaptureData ) );
|
|
SceneCaptureData.dwhContext = pContext->Context;
|
|
SceneCaptureData.ddrval = S_OK;
|
|
CALL_D3DHAL_TAKEBUSY_NOWIN16( ret,
|
|
pContext->pDevice,
|
|
pGbl->lpD3DHALCallbacks->SceneCapture,
|
|
(D3DHAL_SCENECAPTUREDATA *)&SceneCaptureData);
|
|
|
|
LEAVE_BOTH();
|
|
pData->ddrval = MapLegacyResult(SceneCaptureData.ddrval);
|
|
return ret;
|
|
}
|
|
|
|
LEAVE_BOTH();
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
//
|
|
// D3D8CreateDirectDrawObject
|
|
//
|
|
// Creates a DirectDraw object in DDRAW.DLL. By mainting a full representation of
|
|
// this object in DDRAW.DLL, it will automatically update the HAL info after mode
|
|
// changes, etc.
|
|
|
|
VOID APIENTRY D3D8CreateDirectDrawObject( LPGUID lpGuid,
|
|
char *szDeviceName,
|
|
HANDLE* phDD,
|
|
D3DDEVTYPE Type,
|
|
HINSTANCE* phLibrary,
|
|
VOID* pInitFunction)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECTDRAW lpDD1;
|
|
PD3D8GetSWInfo pfnHookCreate;
|
|
DDDEVICEHANDLE* pDeviceHandle;
|
|
HKEY hKey = (HKEY) NULL;
|
|
|
|
ENTER_DDRAW();
|
|
*phDD = NULL;
|
|
*phLibrary = NULL;
|
|
pDeviceHandle = (PDDDEVICEHANDLE) MemAlloc(sizeof(DDDEVICEHANDLE));
|
|
if (pDeviceHandle == NULL)
|
|
{
|
|
LEAVE_DDRAW();
|
|
return;
|
|
}
|
|
lstrcpy(pDeviceHandle->szDeviceName, szDeviceName);
|
|
pDeviceHandle->PID = GetCurrentProcessId();
|
|
|
|
hr = InternalDirectDrawCreate (NULL, &lpDD1, NULL,
|
|
DDRAWILCL_DIRECTDRAW7 | DDRAWILCL_DIRECTDRAW8, szDeviceName);
|
|
if( DD_OK == hr )
|
|
{
|
|
// Make it point to the DX7 vtbl. Do this rather than a QI since
|
|
// a QI for a DX7 object has some extra overhead.
|
|
|
|
lpDD1->lpVtbl = (LPVOID) &dd7Callbacks;
|
|
pDeviceHandle->pDD = (HANDLE) (LPDDRAWI_DIRECTDRAW_INT)lpDD1;
|
|
pDeviceHandle->DeviceType = Type;
|
|
|
|
if (Type == D3DDEVTYPE_REF)
|
|
{
|
|
// Load the refrast and let them take things over
|
|
*phLibrary = LoadLibrary (D3D8_REFRASTNAME);
|
|
pDeviceHandle->pSwDD = SwDDICreateDirectDraw();
|
|
if (pDeviceHandle->pSwDD != NULL)
|
|
{
|
|
*phDD = (HANDLE*) pDeviceHandle;
|
|
}
|
|
else
|
|
{
|
|
lpDD1->lpVtbl->Release(lpDD1);
|
|
}
|
|
}
|
|
else if (Type == D3DDEVTYPE_SW)
|
|
{
|
|
pDeviceHandle->pSwDD = SwDDICreateDirectDraw();
|
|
if (pDeviceHandle->pSwDD != NULL)
|
|
{
|
|
*phDD = (HANDLE*) pDeviceHandle;
|
|
pDeviceHandle->pSwInitFunction = pInitFunction;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*phDD = (HANDLE*) pDeviceHandle;
|
|
}
|
|
}
|
|
|
|
if (*phDD == NULL)
|
|
{
|
|
MemFree(pDeviceHandle);
|
|
}
|
|
else
|
|
{
|
|
pDeviceHandle->pLink = pDeviceList;
|
|
pDeviceList = pDeviceHandle;
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
// See if they want to explicitly enable/disable lightweight surfaces
|
|
|
|
if ((*phDD != NULL) && (!RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3D, &hKey)))
|
|
{
|
|
DWORD type;
|
|
DWORD value;
|
|
DWORD cb = sizeof(value);
|
|
|
|
pDeviceHandle->ForceFlagsOn = 0;
|
|
pDeviceHandle->ForceFlagsOff = 0;
|
|
#ifdef DEBUG
|
|
if (!RegQueryValueEx(hKey, "ForceDriverFlagsOn", NULL, &type, (CONST LPBYTE)&value, &cb))
|
|
{
|
|
pDeviceHandle->ForceFlagsOn = value;
|
|
}
|
|
cb = sizeof(value);
|
|
#endif
|
|
if (!RegQueryValueEx(hKey, "ForceDriverFlagsOff", NULL, &type, (CONST LPBYTE)&value, &cb))
|
|
{
|
|
pDeviceHandle->ForceFlagsOff = value;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
//
|
|
// D3D8ReenableDirectDrawObject
|
|
//
|
|
// On Win9X, this function doesn't do anything, but we have it since Win2K
|
|
// requires it and keeping it keeps the code bases more similar between the
|
|
// two platforms.
|
|
|
|
BOOL WINAPI D3D8ReenableDirectDrawObject( HANDLE hDD, LPBOOL pbNewMode )
|
|
{
|
|
*pbNewMode = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
SWCursorForced()
|
|
{
|
|
if (0 != GetPrivateProfileInt("Display", "SwCursor", 0, "SYSTEM.INI"))
|
|
{
|
|
// ini setting always takes precedence
|
|
DPF(2,"System.ini says SwCursor is ON");
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
HKEY key;
|
|
|
|
if (RegOpenKey(HKEY_CURRENT_CONFIG, "Display\\Settings", &key) == ERROR_SUCCESS)
|
|
{
|
|
char temp[10];
|
|
DWORD len = sizeof(temp);
|
|
DWORD type;
|
|
DWORD i;
|
|
if ((RegQueryValueEx(key, "SwCursor", NULL, (LPDWORD)&type,
|
|
(LPBYTE)(LPSTR)temp, (LPDWORD)&len) == ERROR_SUCCESS) &&
|
|
(type == REG_SZ))
|
|
{
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if ( 0 == temp[i] )
|
|
break;
|
|
if ( '0' != temp[i] )
|
|
{
|
|
RegCloseKey(key);
|
|
DPF(2,"Regkey SwCursor is ON");
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
RegCloseKey(key);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// D3D8QueryDirectDrawObject
|
|
//
|
|
// This gets all of the actual HAL info. It will typically be called twice,
|
|
// the first time to get the basic info (some of the input pointers will be
|
|
// NULL), and again to get all of the info.
|
|
|
|
BOOL WINAPI D3D8QueryDirectDrawObject (HANDLE hDD,
|
|
PD3D8_DRIVERCAPS pDriverCaps,
|
|
PD3D8_CALLBACKS pCallbacks,
|
|
char *pDeviceName,
|
|
HINSTANCE hLibrary,
|
|
D3D8_GLOBALDRIVERDATA* pGblDriverData,
|
|
D3DHAL_D3DEXTENDEDCAPS* pExtendedCaps,
|
|
LPDDSURFACEDESC pTextureFormats,
|
|
LPDDPIXELFORMAT pZStencilFormats,
|
|
UINT* pcTextureFormats,
|
|
UINT* pcZStencilFormats
|
|
)
|
|
{
|
|
LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl;
|
|
LPDDRAWI_DIRECTDRAW_GBL pdrv;
|
|
DDSCAPSEX SurfCapsEx;
|
|
DWORD dwRet;
|
|
DWORD i;
|
|
HDC hdc;
|
|
D3DFORMAT* pTempZStencil;
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
DDHAL_GETDRIVERINFODATA GetDriverInfoData;
|
|
BOOL GotDX8Formats;
|
|
|
|
ENTER_DDRAW();
|
|
|
|
pdrv_lcl = pDevice->pDD->lpLcl;
|
|
pdrv = pdrv_lcl->lpGbl;
|
|
|
|
// Get all of the neccesary caps
|
|
|
|
memset(pDriverCaps, 0, sizeof(D3D8_DRIVERCAPS));
|
|
|
|
pDriverCaps->D3DCaps.Caps = pdrv->ddCaps.dwCaps;
|
|
pDriverCaps->D3DCaps.Caps2 = pdrv->ddCaps.dwCaps2;
|
|
pDriverCaps->D3DCaps.Caps3 = pdrv->ddCaps.dwSVCaps;
|
|
pDriverCaps->SVBCaps = pdrv->ddCaps.dwSVBCaps;
|
|
pDriverCaps->VSBCaps = pdrv->ddCaps.dwVSBCaps;
|
|
pDriverCaps->SVBCaps2 = pdrv->ddCaps.dwSVBCaps2;
|
|
|
|
SurfCapsEx.dwCaps2 = pdrv->ddsCapsMore.dwCaps2;
|
|
SurfCapsEx.dwCaps3 = pdrv->ddsCapsMore.dwCaps3;
|
|
SurfCapsEx.dwCaps4 = pdrv->ddsCapsMore.dwCaps4;
|
|
|
|
if (!IS_SOFTWARE_DRIVER(pDevice))
|
|
{
|
|
GotDX8Formats = FALSE;
|
|
|
|
// See if we can get the DX8 caps directly
|
|
if ((pdrv->dwFlags & DDRAWI_DRIVERINFO2) &&
|
|
(pdrv->pGetDriverInfo != NULL))
|
|
{
|
|
D3DCAPS8 caps8;
|
|
DD_GETDRIVERINFO2DATA* pgdi2;
|
|
|
|
memset(&caps8, 0, sizeof(caps8));
|
|
|
|
pgdi2 = (DD_GETDRIVERINFO2DATA*)&caps8;
|
|
|
|
// sizeof(DD_STEREOMODE)? The GUID for GetDriverInfo2 is shared with
|
|
// the stereo mode querying stuff. Therefore we need to pass down
|
|
// the structure size (and the expected data size) as
|
|
// sizeof(DD_STEREOMODE) even though we actually have a buffer (and
|
|
// expect a size of sizeof(D3DCAPS8).
|
|
pgdi2->dwReserved = sizeof(D3DCAPS8);
|
|
pgdi2->dwMagic = D3DGDI2_MAGIC;
|
|
pgdi2->dwType = D3DGDI2_TYPE_GETD3DCAPS8;
|
|
pgdi2->dwExpectedSize = sizeof(D3DCAPS8);
|
|
|
|
memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
|
|
GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
|
|
GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
|
|
GetDriverInfoData.lpvData = &caps8;
|
|
GetDriverInfoData.dwExpectedSize = sizeof(D3DCAPS8);
|
|
|
|
// Pass a context variable so that the driver
|
|
// knows which instance of itself to use
|
|
// w.r.t. this function. These are different
|
|
// values on Win95 and NT.
|
|
GetDriverInfoData.dwContext = pdrv->dwReserved3;
|
|
|
|
if ((pdrv->pGetDriverInfo(&GetDriverInfoData) == DDHAL_DRIVER_HANDLED) &&
|
|
(GetDriverInfoData.ddRVal == DD_OK ))
|
|
{
|
|
// Looks like we got D3DCAPS8 back from the driver. Verify by means
|
|
// of the dwActualSize field in GetDriverInfoData.
|
|
if (sizeof(D3DCAPS8) != GetDriverInfoData.dwActualSize)
|
|
{
|
|
DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(D3DCAPS8))");
|
|
LEAVE_DDRAW();
|
|
return(FALSE);
|
|
}
|
|
|
|
// All went well. Copy the caps data across
|
|
memcpy(&pDriverCaps->D3DCaps, &caps8, sizeof(caps8));
|
|
|
|
// Display drivers can all render windowed
|
|
if (pdrv->ddCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED)
|
|
{
|
|
pDriverCaps->D3DCaps.Caps2 |= DDCAPS2_CANRENDERWINDOWED;
|
|
}
|
|
|
|
// Set the flag indicating that the DDI successfully reported DX8
|
|
// style caps
|
|
pDriverCaps->dwFlags |= DDIFLAG_D3DCAPS8;
|
|
}
|
|
}
|
|
|
|
// If this driver supports the DX8 DDI then use the new surface format reporting
|
|
// mechanism rather than the texture formats reported in the global driver data
|
|
if (pDriverCaps->dwFlags & DDIFLAG_D3DCAPS8)
|
|
{
|
|
DD_GETDRIVERINFO2DATA* pgdi2;
|
|
DD_GETFORMATCOUNTDATA gfcd;
|
|
DD_GETFORMATDATA gfd;
|
|
|
|
// If DDIFLAG_D3DCAPS8 got set we have a driver info 2 support
|
|
DDASSERT(pdrv->dwFlags & DDRAWI_DRIVERINFO2);
|
|
DDASSERT(pdrv->pGetDriverInfo != NULL);
|
|
|
|
// Step 1: Get the number of supported formats
|
|
// Please see the description comments above for a description of why the
|
|
// reserved field is set to sizeof(DD_STEREOMODE)
|
|
memset(&gfcd, 0, sizeof(gfcd));
|
|
|
|
gfcd.gdi2.dwReserved = sizeof(DD_GETFORMATCOUNTDATA);
|
|
gfcd.gdi2.dwMagic = D3DGDI2_MAGIC;
|
|
gfcd.gdi2.dwType = D3DGDI2_TYPE_GETFORMATCOUNT;
|
|
gfcd.gdi2.dwExpectedSize = sizeof(DD_GETFORMATCOUNTDATA);
|
|
|
|
#if DBG
|
|
// Ensure the driver actually sets the format count if it succeeds this call
|
|
gfcd.dwFormatCount = BOGUS_FIELD_VALUE;
|
|
#endif // DBG
|
|
|
|
memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
|
|
GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
|
|
GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
|
|
GetDriverInfoData.lpvData = &gfcd;
|
|
GetDriverInfoData.dwExpectedSize = sizeof(DD_GETFORMATCOUNTDATA);
|
|
GetDriverInfoData.dwContext = pdrv->dwReserved3;
|
|
|
|
if ((pdrv->pGetDriverInfo(&GetDriverInfoData) == DDHAL_DRIVER_HANDLED) &&
|
|
(GetDriverInfoData.ddRVal == DD_OK ))
|
|
{
|
|
// Looks like we got a DD_GETFORMATCOUNTDATA back from the driver. Verify by means
|
|
// of the dwActualSize field in GetDriverInfoData.
|
|
if (sizeof(DD_GETFORMATCOUNTDATA) != GetDriverInfoData.dwActualSize)
|
|
{
|
|
DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(DD_GETFORMATCOUNTDATA))");
|
|
LEAVE_DDRAW();
|
|
return(FALSE);
|
|
}
|
|
|
|
#ifdef DBG
|
|
if (BOGUS_FIELD_VALUE == gfcd.dwFormatCount)
|
|
{
|
|
DPF_ERR( "Driver succeeded GETFORMATCOUNT request but didn't set dwFormatCount" );
|
|
LEAVE_DDRAW();
|
|
return(FALSE);
|
|
}
|
|
#endif // DBG
|
|
|
|
// All went well. Replace the number of supported texture formats the driver
|
|
// reported to us with this new number. We don't use the legacy texture format
|
|
// list if this new mechanism is supported
|
|
|
|
*pcTextureFormats = gfcd.dwFormatCount;
|
|
|
|
// Flag the fact that we got DX8 style formats from the driver.
|
|
GotDX8Formats = TRUE;
|
|
|
|
// Step2: Query for each of the surface formats in turn.
|
|
// We only do this if the caller requested that we do by means of a non-NULL
|
|
// texture format buffer
|
|
if (NULL != pTextureFormats)
|
|
{
|
|
DWORD c;
|
|
DDSURFACEDESC* pOutFormat;
|
|
|
|
// For simplicities sake we ask for a single format at a time. Not exactly
|
|
// high-performance but this should not matter at this stage of the code.
|
|
pOutFormat = pTextureFormats;
|
|
for (c = 0; c < (*pcTextureFormats); ++c)
|
|
{
|
|
// We reinitialize the entire request each time. We could probably
|
|
// optimize this but it doesn't seem worth it.
|
|
memset(&gfd, 0, sizeof(DD_GETFORMATDATA));
|
|
|
|
gfd.gdi2.dwReserved = sizeof(DD_GETFORMATDATA);
|
|
gfd.gdi2.dwMagic = D3DGDI2_MAGIC;
|
|
gfd.gdi2.dwType = D3DGDI2_TYPE_GETFORMAT;
|
|
gfd.gdi2.dwExpectedSize = sizeof(DD_GETFORMATDATA);
|
|
gfd.dwFormatIndex = c;
|
|
#if DBG
|
|
// Ensure the driver actually sets the format count if it succeeds this call
|
|
gfd.format.dwSize = BOGUS_FIELD_VALUE;
|
|
#endif // DBG
|
|
|
|
memset(&GetDriverInfoData, 0, sizeof(GetDriverInfoData));
|
|
GetDriverInfoData.dwSize = sizeof(GetDriverInfoData);
|
|
GetDriverInfoData.guidInfo = GUID_GetDriverInfo2;
|
|
GetDriverInfoData.lpvData = &gfd;
|
|
GetDriverInfoData.dwExpectedSize = sizeof(DD_GETFORMATDATA);
|
|
GetDriverInfoData.dwContext = pdrv->dwReserved3;
|
|
|
|
if ((pdrv->pGetDriverInfo(&GetDriverInfoData) == DDHAL_DRIVER_HANDLED) &&
|
|
(GetDriverInfoData.ddRVal == DD_OK ))
|
|
{
|
|
// Looks like we got a DD_GETFORMATDATA back from the driver. Verify by means
|
|
// of the dwActualSize field in GetDriverInfoData.
|
|
if (sizeof(DD_GETFORMATDATA) != GetDriverInfoData.dwActualSize)
|
|
{
|
|
DPF(0, "Driver returned an data structure of incorrect size (!= sizeof(DD_GETFORMATDATA))");
|
|
LEAVE_DDRAW();
|
|
return(FALSE);
|
|
}
|
|
|
|
DDASSERT(c == gfd.dwFormatIndex);
|
|
|
|
#ifdef DBG
|
|
if (BOGUS_FIELD_VALUE == gfd.format.dwSize)
|
|
{
|
|
DPF_ERR( "Driver succeeded GETFORMAT request but didn't set format" );
|
|
LEAVE_DDRAW();
|
|
return(FALSE);
|
|
}
|
|
#endif // DBG
|
|
|
|
// Looks like all went well so initialize the surface description
|
|
// part of the output format and copy the pixel format we got from
|
|
// the driver across
|
|
memset(pOutFormat, 0, sizeof(DDSURFACEDESC));
|
|
pOutFormat->dwSize = sizeof(DDSURFACEDESC);
|
|
pOutFormat->dwFlags = DDSD_PIXELFORMAT;
|
|
memcpy(&pOutFormat->ddpfPixelFormat, &(gfd.format), sizeof(DDPIXELFORMAT));
|
|
|
|
++pOutFormat;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPF(0, "Driver claims DX8 but fails call to GETFORMATCOUNT" );
|
|
DPF(0, "DX7 texture format list will be used but this will change soon" );
|
|
DPF(0, "Fix driver to support DX8 style surface format reporting now" );
|
|
}
|
|
}
|
|
|
|
// The driver does not support the DX8 DDI so simply use the existing DX7
|
|
// style texture format list.
|
|
if (pdrv->lpD3DGlobalDriverData != NULL)
|
|
{
|
|
// Wackiness to get around type checking
|
|
*pGblDriverData = *(D3D8_GLOBALDRIVERDATA*) pdrv_lcl->lpGbl->lpD3DGlobalDriverData;
|
|
|
|
// If we alreay have DX8 style formats from the driver don't bother using the DX7
|
|
// style texture format list
|
|
if (!GotDX8Formats)
|
|
{
|
|
*pcTextureFormats = pdrv_lcl->lpGbl->lpD3DGlobalDriverData->dwNumTextureFormats;
|
|
|
|
if (pTextureFormats != NULL)
|
|
{
|
|
memcpy(
|
|
pTextureFormats,
|
|
pdrv_lcl->lpGbl->lpD3DGlobalDriverData->lpTextureFormats,
|
|
pdrv_lcl->lpGbl->lpD3DGlobalDriverData->dwNumTextureFormats*sizeof(*pTextureFormats));
|
|
}
|
|
}
|
|
|
|
// Get the D3D extended caps
|
|
|
|
if (pdrv->lpD3DExtendedCaps)
|
|
{
|
|
*pExtendedCaps = *(pdrv->lpD3DExtendedCaps);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If we alreay have DX8 style formats from the driver don't bother using the DX7
|
|
// style texture format list
|
|
if (!GotDX8Formats)
|
|
{
|
|
*pcTextureFormats = 0;
|
|
}
|
|
}
|
|
|
|
|
|
// Get the supported Z formats. We only do this if we are not using a
|
|
// software driver
|
|
|
|
*pcZStencilFormats = pdrv->dwNumZPixelFormats;
|
|
if (pdrv->dwNumZPixelFormats > 0)
|
|
{
|
|
if (pZStencilFormats)
|
|
{
|
|
memcpy(pZStencilFormats,
|
|
pdrv->lpZPixelFormats,
|
|
pdrv->dwNumZPixelFormats * sizeof( *pZStencilFormats ));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pGblDriverData->hwCaps.dwDeviceZBufferBitDepth & DDBD_16)
|
|
{
|
|
(*pcZStencilFormats)++;
|
|
if (pZStencilFormats)
|
|
{
|
|
pZStencilFormats->dwSize = sizeof(DDPIXELFORMAT);
|
|
pZStencilFormats->dwFlags = DDPF_ZBUFFER;
|
|
pZStencilFormats->dwZBufferBitDepth = 16;
|
|
pZStencilFormats->dwStencilBitDepth = 0;
|
|
pZStencilFormats->dwZBitMask = 0xffff;
|
|
pZStencilFormats->dwStencilBitMask = 0x0000;
|
|
pZStencilFormats++;
|
|
}
|
|
}
|
|
if (pGblDriverData->hwCaps.dwDeviceZBufferBitDepth & DDBD_32)
|
|
{
|
|
(*pcZStencilFormats)++;
|
|
if (pZStencilFormats)
|
|
{
|
|
pZStencilFormats->dwSize = sizeof(DDPIXELFORMAT);
|
|
pZStencilFormats->dwFlags = DDPF_ZBUFFER;
|
|
pZStencilFormats->dwZBufferBitDepth = 32;
|
|
pZStencilFormats->dwStencilBitDepth = 0;
|
|
pZStencilFormats->dwZBitMask = 0xffffffff;
|
|
pZStencilFormats->dwStencilBitMask = 0x00000000;
|
|
pZStencilFormats++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get info about the current mode
|
|
|
|
pDriverCaps->DisplayWidth = pdrv->vmiData.dwDisplayWidth;
|
|
pDriverCaps->DisplayHeight = pdrv->vmiData.dwDisplayHeight;
|
|
pDriverCaps->DisplayFrequency = pdrv->dwMonitorFrequency;
|
|
switch (pdrv->vmiData.ddpfDisplay.dwRGBBitCount)
|
|
{
|
|
case 8:
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_P8;
|
|
pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_P8;
|
|
break;
|
|
|
|
case 15:
|
|
case 16:
|
|
if (pdrv->vmiData.ddpfDisplay.dwGBitMask == 0x7e0)
|
|
{
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_R5G6B5;
|
|
pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_R5G6B5;
|
|
}
|
|
else
|
|
{
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_X1R5G5B5;
|
|
pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_X1R5G5B5;
|
|
if (pdrv->vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS)
|
|
{
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_A1R5G5B5;
|
|
}
|
|
//pdrv->vmiData.ddpfDisplay.dwRGBAlphaBitMask = 0;
|
|
//pdrv->vmiData.ddpfDisplay.dwFlags &= ~DDPF_ALPHAPIXELS;
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_R8G8B8;
|
|
pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_R8G8B8;
|
|
break;
|
|
|
|
case 32:
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_X8R8G8B8;
|
|
pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_X8R8G8B8;
|
|
if (pdrv->vmiData.ddpfDisplay.dwFlags & DDPF_ALPHAPIXELS)
|
|
{
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_A8R8G8B8;
|
|
}
|
|
//pdrv->vmiData.ddpfDisplay.dwRGBAlphaBitMask = 0;
|
|
//pdrv->vmiData.ddpfDisplay.dwFlags &= ~DDPF_ALPHAPIXELS;
|
|
break;
|
|
|
|
default:
|
|
pDriverCaps->DisplayFormatWithAlpha = D3DFMT_UNKNOWN;
|
|
pDriverCaps->DisplayFormatWithoutAlpha = D3DFMT_UNKNOWN;
|
|
break;
|
|
}
|
|
|
|
pDevice->DisplayFormatWithAlpha = pDriverCaps->DisplayFormatWithAlpha;
|
|
pDevice->DisplayFormatWithoutAlpha = pDriverCaps->DisplayFormatWithoutAlpha;
|
|
|
|
// Fill in the D3D8 Callback table
|
|
RtlZeroMemory(pCallbacks, sizeof(*pCallbacks));
|
|
pCallbacks->CreateSurface = DdCreateSurface;
|
|
pCallbacks->DestroySurface = DdDestroySurface;
|
|
pCallbacks->Lock = DdLock;
|
|
pCallbacks->Unlock = DdUnlock;
|
|
pCallbacks->Blt = DdBlt;
|
|
pCallbacks->GetScanLine = DdGetScanLine;
|
|
pCallbacks->Flip = DdFlip;
|
|
pCallbacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
|
|
pCallbacks->GetBltStatus = DdGetBltStatus;
|
|
pCallbacks->GetFlipStatus = DdGetFlipStatus;
|
|
pCallbacks->SetMode = DdSetMode;
|
|
pCallbacks->FlipToGDISurface = DdFlipToGDISurface;
|
|
pCallbacks->SetExclusiveMode = DdSetExclusiveMode;
|
|
pCallbacks->GetAvailDriverMemory = DdGetAvailDriverMemory;
|
|
pCallbacks->Clear2 = D3dClear;
|
|
pCallbacks->SetRenderTarget = D3dSetRenderTarget;
|
|
pCallbacks->SetColorkey = DdSetColorkey;
|
|
pCallbacks->SetPalette = DdSetPalette;
|
|
pCallbacks->UpdatePalette = DdUpdatePalette;
|
|
pCallbacks->SceneCapture = D3dSceneCapture;
|
|
|
|
if ((pdrv->lpD3DHALCallbacks != NULL) &&
|
|
(pdrv->lpD3DHALCallbacks->ContextCreate != NULL))
|
|
{
|
|
pCallbacks->CreateContext = D3dContextCreate;
|
|
}
|
|
if ((pdrv->lpD3DHALCallbacks != NULL) &&
|
|
(pdrv->lpD3DHALCallbacks->ContextDestroy != NULL))
|
|
{
|
|
pCallbacks->ContextDestroy = D3dContextDestroy;
|
|
}
|
|
if ((pdrv->lpD3DHALCallbacks != NULL) &&
|
|
(pdrv->lpD3DHALCallbacks->ContextDestroyAll != NULL))
|
|
{
|
|
pCallbacks->ContextDestroyAll = D3dContextDestroyAll;
|
|
}
|
|
if (pdrv->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState != NULL)
|
|
{
|
|
pCallbacks->GetDriverState = D3dGetDriverState;
|
|
}
|
|
if ((pdrv->lpD3DHALCallbacks3 != NULL) &&
|
|
(pdrv->lpD3DHALCallbacks3->ValidateTextureStageState != NULL))
|
|
{
|
|
pCallbacks->ValidateTextureStageState = D3dValidateTextureStageState;
|
|
}
|
|
if ((pdrv->lpD3DHALCallbacks3 != NULL) &&
|
|
(pdrv->lpD3DHALCallbacks3->DrawPrimitives2 != NULL))
|
|
{
|
|
pCallbacks->DrawPrimitives2 = D3dDrawPrimitives2;
|
|
}
|
|
|
|
// If Refrast or the HEL has a hook, call it to let it change whatever it wants
|
|
|
|
if (IS_SOFTWARE_DRIVER(pDevice))
|
|
{
|
|
*pcZStencilFormats = 0;
|
|
|
|
SwDDIMungeCaps (
|
|
hLibrary,
|
|
hDD,
|
|
pDriverCaps,
|
|
pCallbacks,
|
|
pTextureFormats,
|
|
pcTextureFormats,
|
|
pDevice->pSwInitFunction
|
|
);
|
|
}
|
|
|
|
// Now we need to determine what level of DX support the driver supports
|
|
|
|
pDevice->DriverLevel = 0;
|
|
if (pDriverCaps->D3DCaps.MaxStreams != 0)
|
|
{
|
|
pDevice->DriverLevel = 8;
|
|
}
|
|
else if (pCallbacks->GetDriverState != 0)
|
|
{
|
|
pDevice->DriverLevel = 7;
|
|
}
|
|
else if (pCallbacks->DrawPrimitives2 != 0)
|
|
{
|
|
pDevice->DriverLevel = 6;
|
|
if (pDevice->pDefaultPalette == NULL)
|
|
{
|
|
PALETTEENTRY ColorTable[256];
|
|
int i;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
ColorTable[i].peRed = (UCHAR) i;
|
|
ColorTable[i].peGreen = (UCHAR) i;
|
|
ColorTable[i].peBlue = (UCHAR) i;
|
|
}
|
|
DPF_MUTE();
|
|
DD_CreatePalette ((LPDIRECTDRAW) pDevice->pDD,
|
|
DDPCAPS_8BIT,
|
|
ColorTable,
|
|
&pDevice->pDefaultPalette,
|
|
NULL);
|
|
DPF_UNMUTE();
|
|
}
|
|
}
|
|
|
|
if (pGblDriverData->hwCaps.dwDevCaps & D3DDEVCAPS_TEXTURESYSTEMMEMORY)
|
|
{
|
|
pDevice->bCanTextureSysmem = TRUE;
|
|
}
|
|
|
|
|
|
// Can this driver handle lightweight surfaces?
|
|
|
|
pDriverCaps->KnownDriverFlags = 0;
|
|
if (pDevice->DriverLevel < 7)
|
|
{
|
|
pDevice->bLightweight = FALSE;
|
|
}
|
|
else if (pDevice->DriverLevel == 7)
|
|
{
|
|
pDevice->bLightweight = CanKnownDriverDoThis(pDevice, KNOWN_LIGHTWEIGHT);
|
|
}
|
|
else
|
|
{
|
|
pDevice->bLightweight = TRUE;
|
|
}
|
|
|
|
// What about HW cursor support?
|
|
// The check below needs to know the hardware driver level so it cannot use
|
|
// pDevice->DriverLevel since it may be set due to ref.
|
|
|
|
if (SWCursorForced())
|
|
{
|
|
pDriverCaps->D3DCaps.CursorCaps = 0;
|
|
}
|
|
else if (((0 == pdrv->lpD3DExtendedCaps) ||
|
|
(0 == pDriverCaps->D3DCaps.MaxStreams)) &&
|
|
(NULL != pdrv->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState))
|
|
{
|
|
// The hardware driver is DX7
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_HWCURSOR))
|
|
{
|
|
pDriverCaps->D3DCaps.CursorCaps = D3DCURSORCAPS_COLOR;
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_HWCURSOR;
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_HWCURSORLOWRES))
|
|
{
|
|
pDriverCaps->D3DCaps.CursorCaps |= D3DCURSORCAPS_LOWRES;
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_HWCURSORLOWRES;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If it's a pre-dx8 driver and they support cubemaps, we need to
|
|
// specify whether they support mipped cubemaps or not.
|
|
|
|
if (pDevice->DriverLevel < 8)
|
|
{
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_MIPPEDCUBEMAPS))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_MIPPEDCUBEMAPS;
|
|
}
|
|
|
|
// Does this driver have a Z/Stencil depth restriction?
|
|
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_ZSTENCILDEPTH))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_ZSTENCILDEPTH;
|
|
}
|
|
|
|
// Does device have no driver known to over-queue windowed presentation blts?
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_NOTAWINDOWEDBLTQUEUER))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_NOTAWINDOWEDBLTQUEUER;
|
|
}
|
|
|
|
// Does device support D3DFMT_D16_LOCKABLE
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_D16_LOCKABLE))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_D16_LOCKABLE;
|
|
}
|
|
|
|
// Figure out what RT/Texture formats it supports
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_CANMISMATCHRT))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_CANMISMATCHRT;
|
|
}
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_X1R5G5B5))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_X1R5G5B5;
|
|
}
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_R5G6B5))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_R5G6B5;
|
|
}
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_X8R8G8B8))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_X8R8G8B8;
|
|
}
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A8R8G8B8))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A8R8G8B8;
|
|
}
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A1R5G5B5))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A1R5G5B5;
|
|
}
|
|
if (CanKnownDriverDoThis(pDevice, KNOWN_RTTEXTURE_A4R4G4B4))
|
|
{
|
|
pDriverCaps->KnownDriverFlags |= KNOWN_RTTEXTURE_A4R4G4B4;
|
|
}
|
|
}
|
|
|
|
// ATI drivers don't handle palettes correctly, so we will delete
|
|
// all palettized textures from their list.
|
|
|
|
if (pDevice->DriverLevel < 8)
|
|
{
|
|
if (((pDevice->PCIID >> 16) == 0x1002) &&
|
|
(pTextureFormats != NULL))
|
|
{
|
|
i = 0;
|
|
while (i < *pcTextureFormats)
|
|
{
|
|
if (pTextureFormats[i].ddpfPixelFormat.dwFlags &
|
|
(DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8))
|
|
{
|
|
UINT j;
|
|
|
|
(*pcTextureFormats)--;
|
|
for (j = i; j < *pcTextureFormats; j++)
|
|
{
|
|
pTextureFormats[j] = pTextureFormats[j+1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// We assume that a software driver will always support at least DX7
|
|
|
|
if ((pDevice->DriverLevel < 7) &&
|
|
IS_SOFTWARE_DRIVER(pDevice))
|
|
{
|
|
LEAVE_DDRAW();
|
|
DPF_ERR("A Software rasterizer must contain at least DX7 driver level support");
|
|
return FALSE;
|
|
}
|
|
LEAVE_DDRAW();
|
|
return TRUE;
|
|
}
|
|
|
|
VOID CleanupDevice (PDDDEVICEHANDLE pDevice)
|
|
{
|
|
DWORD i;
|
|
DDSURFACE* pSurf;
|
|
DDSURFACE* pSurfTemp;
|
|
|
|
// Cleanup the palette allocations
|
|
|
|
if (pDevice->pDefaultPalette != NULL)
|
|
{
|
|
InternalPaletteRelease((LPDDRAWI_DDRAWPALETTE_INT)
|
|
pDevice->pDefaultPalette);
|
|
pDevice->pDefaultPalette = NULL;
|
|
}
|
|
if (pDevice->NumPaletteHandleEntries > 0)
|
|
{
|
|
for (i = 0; i < pDevice->NumPaletteHandleEntries; i++)
|
|
{
|
|
if (pDevice->pPaletteHandleTable[i] != NULL)
|
|
{
|
|
InternalPaletteRelease((LPDDRAWI_DDRAWPALETTE_INT)
|
|
pDevice->pPaletteHandleTable[i]->pDDPalette);
|
|
MemFree(pDevice->pPaletteHandleTable[i]);
|
|
pDevice->pPaletteHandleTable[i] = NULL;
|
|
}
|
|
}
|
|
MemFree(pDevice->pPaletteHandleTable);
|
|
pDevice->pPaletteHandleTable = NULL;
|
|
pDevice->NumPaletteHandleEntries = 0;
|
|
}
|
|
|
|
if (pDevice->pContext)
|
|
{
|
|
D3D8_CONTEXTDESTROYDATA data;
|
|
|
|
data.dwhContext = (ULONG_PTR) pDevice->pContext;
|
|
D3dContextDestroy(&data);
|
|
pDevice->pContext = NULL;
|
|
}
|
|
|
|
pSurf = pDevice->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if (!IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
|
|
pHeavy = MapLightweightSurface(pSurf);
|
|
if (pHeavy != NULL)
|
|
{
|
|
pHeavy->dwIntRefCnt = 1;
|
|
pHeavy->lpLcl->dwLocalRefCnt = 1;
|
|
pHeavy->lpLcl->lpGbl->dwRefCnt = 1;
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_ROOT)
|
|
{
|
|
pHeavy->lpLcl->lpSurfMore->pAddrefedThisOwner = (IUnknown*) pSurf->pDevice->pDD;
|
|
}
|
|
|
|
InternalSurfaceRelease(pHeavy, TRUE, TRUE);
|
|
|
|
pHeavy->dwReserved1 = (ULONG_PTR) NULL;
|
|
pHeavy->dwReserved2 = 0;
|
|
}
|
|
MemFree (pSurf->Surface.pLight);
|
|
pSurf->Surface.pLight = NULL;
|
|
}
|
|
else if (pSurf->dwFlags & DDSURFACE_HEAVYWEIGHT)
|
|
{
|
|
if ((pSurf->dwFlags & DDSURFACE_ROOT) &&
|
|
(pSurf->Surface.pHeavy != NULL))
|
|
{
|
|
InternalSurfaceRelease(pSurf->Surface.pHeavy, FALSE, TRUE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MemFree(pSurf->Surface.pHeavy);
|
|
}
|
|
pSurfTemp = pSurf;
|
|
pSurf = pSurf->pNext;
|
|
MemFree(pSurfTemp);
|
|
}
|
|
|
|
if (pDevice->pSwDD)
|
|
{
|
|
if (pDevice->pSwDD->lpLcl->lpGbl->lpDDCBtmp)
|
|
{
|
|
MemFree(pDevice->pSwDD->lpLcl->lpGbl->lpDDCBtmp);
|
|
}
|
|
MemFree(pDevice->pSwDD);
|
|
}
|
|
|
|
if (pDevice->NumCachedSurfaces > 0)
|
|
{
|
|
for (i = 0; i < (DWORD) pDevice->NumCachedSurfaces; i++)
|
|
{
|
|
MemFree(pDevice->pCachedSurfaceTable[i].pSurface);
|
|
}
|
|
MemFree(pDevice->pCachedSurfaceTable);
|
|
pDevice->pCachedSurfaceTable = NULL;
|
|
pDevice->NumCachedSurfaces = 0;
|
|
}
|
|
|
|
if (pDevice->SurfaceHandleList.dwList != NULL)
|
|
{
|
|
MemFree(pDevice->SurfaceHandleList.dwList);
|
|
}
|
|
}
|
|
|
|
|
|
VOID APIENTRY D3D8DeleteDirectDrawObject( HANDLE hDD )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
LPDIRECTDRAW lpDD;
|
|
|
|
// hDD can be NULL in some error paths
|
|
|
|
if (pDevice == NULL)
|
|
return;
|
|
|
|
ENTER_DDRAW();
|
|
CleanupDevice(pDevice);
|
|
|
|
lpDD = (LPDIRECTDRAW) pDevice->pDD;
|
|
if (lpDD != NULL)
|
|
{
|
|
lpDD->lpVtbl->Release(lpDD);
|
|
}
|
|
|
|
if (pDeviceList == pDevice)
|
|
{
|
|
// If we're first, then update global list
|
|
// pointer
|
|
pDeviceList = pDevice->pLink;
|
|
}
|
|
else
|
|
{
|
|
// Find ourselves in the list
|
|
PDDDEVICEHANDLE pDevicePrev = pDeviceList;
|
|
while (pDevicePrev->pLink != pDevice)
|
|
{
|
|
pDevicePrev = pDevicePrev->pLink;
|
|
}
|
|
|
|
// Skip past our current node
|
|
pDevicePrev->pLink = pDevice->pLink;
|
|
}
|
|
MemFree(pDevice);
|
|
|
|
LEAVE_DDRAW();
|
|
}
|
|
|
|
HDC APIENTRY D3D8GetDC( HANDLE hSurface, LPPALETTEENTRY pPalette )
|
|
{
|
|
HDC hdc = NULL;
|
|
PDDSURFACE pSurf = (PDDSURFACE) hSurface;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
DDSURFACEDESC ddsd;
|
|
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
|
|
pHeavy = GetHeavyweightSurf(pSurf);
|
|
if (pHeavy == NULL)
|
|
{
|
|
hdc = NULL;
|
|
DPF_ERR("Out of memory error mapping lightweight surface");
|
|
}
|
|
else
|
|
{
|
|
FillDDSurfaceDesc(pHeavy->lpLcl, &ddsd);
|
|
ddsd.lpSurface = (void*)pHeavy->lpLcl->lpGbl->fpVidMem;
|
|
|
|
hdc = DD16_GetDC((HDC)(pSurf->pDevice->pDD->lpLcl->hDC),
|
|
&ddsd,
|
|
NULL);
|
|
|
|
if (hdc == NULL)
|
|
{
|
|
DPF_ERR("Failure to GetDC for non-heavyweight surface?");
|
|
}
|
|
DONE_HEAVYWEIGHT_SURF (pSurf);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pHeavy = GetHeavyweightSurf(pSurf);
|
|
if (pHeavy == NULL)
|
|
{
|
|
DPF_ERR("Unable to map lightweight surface - out of memory");
|
|
hdc = NULL;
|
|
}
|
|
else
|
|
{
|
|
HRESULT hr = InternalGetDC(pHeavy, &hdc, FALSE);
|
|
if (FAILED(hr))
|
|
{
|
|
DPF_ERR("Could not get DC for surface");
|
|
hdc = NULL;
|
|
}
|
|
}
|
|
}
|
|
return hdc;
|
|
}
|
|
|
|
BOOL APIENTRY D3D8ReleaseDC(HANDLE hSurface, HDC hdc)
|
|
{
|
|
PDDSURFACE pSurf = (PDDSURFACE) hSurface;
|
|
DDASSERT(hdc != NULL);
|
|
|
|
if (IS_SOFTWARE_DRIVER_SURFACE(pSurf))
|
|
{
|
|
DD16_ReleaseDC(hdc);
|
|
}
|
|
|
|
else
|
|
{
|
|
HRESULT hr;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
|
|
if (pSurf->dwFlags & DDSURFACE_LIGHTWEIGHT)
|
|
{
|
|
pHeavy = GET_CACHED_LIGHTWEIGHT_INT(pSurf);
|
|
DDASSERT(pHeavy != NULL);
|
|
}
|
|
else
|
|
{
|
|
pHeavy = pSurf->Surface.pHeavy;
|
|
}
|
|
|
|
hr = InternalReleaseDC(pHeavy->lpLcl, hdc, FALSE);
|
|
if (FAILED(hr))
|
|
{
|
|
DPF_ERR("Could not release DC?");
|
|
}
|
|
DONE_HEAVYWEIGHT_SURF(pSurf);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL APIENTRY D3D8SetGammaRamp( HANDLE hDD, HDC hdc, LPVOID lpGammaRamp )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
ENTER_BOTH();
|
|
if (CheckForDeviceLost(hDD))
|
|
{
|
|
LEAVE_BOTH();
|
|
return TRUE;
|
|
}
|
|
|
|
if (pDevice->pDD->lpLcl->lpPrimary != NULL)
|
|
{
|
|
hr = DD_Gamma_SetGammaRamp((LPDIRECTDRAWGAMMACONTROL) pDevice->pDD->lpLcl->lpPrimary,
|
|
0, lpGammaRamp);
|
|
}
|
|
LEAVE_BOTH();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// D3D8BuildModeTable
|
|
//
|
|
|
|
VOID APIENTRY D3D8BuildModeTable( char* pDeviceName,
|
|
D3DDISPLAYMODE* pTable,
|
|
DWORD* pNumEntries,
|
|
D3DFORMAT Unknown16,
|
|
HANDLE hProfile,
|
|
BOOL b16bppSupported,
|
|
BOOL b32bppSupported
|
|
)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hProfile;
|
|
LPDDRAWI_DIRECTDRAW_GBL pdrv;
|
|
DWORD NumModes = 0;
|
|
|
|
DWORD i;
|
|
DWORD j;
|
|
D3DFORMAT format;
|
|
|
|
if ((pDeviceHandle == NULL) ||
|
|
(pDeviceHandle->pDD == NULL))
|
|
{
|
|
*pNumEntries = NumModes;
|
|
return;
|
|
}
|
|
|
|
ENTER_DDRAW();
|
|
pdrv = pDeviceHandle->pDD->lpLcl->lpGbl;
|
|
|
|
NumModes = 0;
|
|
for (i = 0; i < pdrv->dwNumModes; i++)
|
|
{
|
|
// Filter out all modes other than 15, 16 and 32bpp
|
|
if ((pdrv->lpModeInfo[i].dwBPP != 15) &&
|
|
(pdrv->lpModeInfo[i].dwBPP != 16) &&
|
|
(pdrv->lpModeInfo[i].dwBPP != 32))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (((pdrv->lpModeInfo[i].dwBPP == 15) ||
|
|
(pdrv->lpModeInfo[i].dwBPP == 16)) &&
|
|
!b16bppSupported)
|
|
{
|
|
continue;
|
|
}
|
|
else if ((pdrv->lpModeInfo[i].dwBPP == 32) &&
|
|
!b32bppSupported)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Can GDI and the monitor handle this mode/refresh rate?
|
|
if(pdrv->dwFlags & DDRAWI_DISPLAYDRV)
|
|
{
|
|
DWORD cds_flags;
|
|
DEVMODE dm;
|
|
int cds_rc;
|
|
BOOL bUseRefresh;
|
|
|
|
bUseRefresh = (pdrv->lpModeInfo[i].wRefreshRate > 0);
|
|
makeDEVMODE( pdrv, &pdrv->lpModeInfo[i], FALSE, bUseRefresh, &cds_flags, &dm );
|
|
|
|
cds_flags |= CDS_TEST;
|
|
cds_rc = xxxChangeDisplaySettingsExA(pdrv->cDriverName, &dm, NULL, cds_flags, 0);
|
|
if( cds_rc != 0 )
|
|
{
|
|
continue;
|
|
}
|
|
if (!MonitorCanHandleMode (pdrv,
|
|
pdrv->lpModeInfo[i].dwWidth,
|
|
pdrv->lpModeInfo[i].dwHeight,
|
|
pdrv->lpModeInfo[i].wRefreshRate))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Make sure that we understand the format.
|
|
|
|
if ((pdrv->lpModeInfo[i].dwBPP == 16) ||
|
|
(pdrv->lpModeInfo[i].dwBPP == 15))
|
|
{
|
|
format = Unknown16;
|
|
}
|
|
else
|
|
{
|
|
DDASSERT(pdrv->lpModeInfo[i].dwBPP == 32);
|
|
format = D3DFMT_X8R8G8B8;
|
|
}
|
|
|
|
// Add the new mode.
|
|
if (pTable != NULL)
|
|
{
|
|
///The caller must pass us a number
|
|
DDASSERT( (*pNumEntries) );
|
|
if ( NumModes >= *pNumEntries )
|
|
{
|
|
//we exceeded the number of entries allocated for us.
|
|
//tell the caller to re-query and try again.
|
|
NumModes = 0;
|
|
break;
|
|
}
|
|
|
|
pTable[NumModes].Width = pdrv->lpModeInfo[i].dwWidth;
|
|
pTable[NumModes].Height = pdrv->lpModeInfo[i].dwHeight;
|
|
pTable[NumModes].RefreshRate = pdrv->lpModeInfo[i].wRefreshRate;
|
|
pTable[NumModes].Format = format;
|
|
}
|
|
NumModes++;
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
*pNumEntries = NumModes;
|
|
}
|
|
|
|
|
|
BOOL APIENTRY D3D8IsDeviceLost( HANDLE hDD)
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
|
|
return pDevice->bDeviceLost;
|
|
}
|
|
|
|
BOOL APIENTRY D3D8CanRestoreNow( HANDLE hDD)
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
LPDDRAWI_DIRECTDRAW_GBL pGbl;
|
|
BOOL bSupported = FALSE;
|
|
HRESULT hr;
|
|
|
|
// If we aren't lost, then it's an easy call
|
|
ENTER_DDRAW();
|
|
|
|
if (!(pDevice->bDeviceLost))
|
|
{
|
|
LEAVE_DDRAW();
|
|
return TRUE;
|
|
}
|
|
hr = DD_TestCooperativeLevel((LPDIRECTDRAW)pDevice->pDD);
|
|
if ( DD_OK == hr || DDERR_WRONGMODE == hr)
|
|
{
|
|
// Are we in a mode in which D3D is supported?
|
|
|
|
pGbl = pDevice->pDD->lpLcl->lpGbl;
|
|
if (IS_SOFTWARE_DRIVER(hDD))
|
|
{
|
|
// Assume that any software driver can render in modes > 8bpp
|
|
|
|
if (pGbl->vmiData.ddpfDisplay.dwRGBBitCount > 8)
|
|
{
|
|
bSupported = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
if (pGbl->lpD3DGlobalDriverData != NULL)
|
|
{
|
|
switch (pGbl->vmiData.ddpfDisplay.dwRGBBitCount)
|
|
{
|
|
case 15:
|
|
case 16:
|
|
if (pGbl->lpD3DGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & DDBD_16)
|
|
{
|
|
bSupported = TRUE;
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
if (pGbl->lpD3DGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & DDBD_24)
|
|
{
|
|
bSupported = TRUE;
|
|
}
|
|
break;
|
|
|
|
case 32:
|
|
if (pGbl->lpD3DGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & DDBD_32)
|
|
{
|
|
bSupported = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
return bSupported;
|
|
}
|
|
|
|
VOID APIENTRY D3D8RestoreDevice( HANDLE hDD)
|
|
{
|
|
HRESULT hr;
|
|
DWORD i, j, k;
|
|
DWORD Width, Height, Depth;
|
|
BYTE *SliceSrc, *SliceDst, *RowSrc, *RowDst;
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
PDDSURFACE pSurf;
|
|
LPDDRAWI_DDRAWSURFACE_INT pHeavy;
|
|
PDEFERREDCREATE pDefCreate = pDevice->pDeferList;
|
|
PDEFERREDCREATE *ppNext = &pDevice->pDeferList;
|
|
PDEFERREDCREATE pTemp;
|
|
D3D8_LOCKDATA LockData;
|
|
D3D8_UNLOCKDATA UnlockData;
|
|
|
|
ENTER_BOTH();
|
|
if (!D3D8CanRestoreNow(hDD))
|
|
{
|
|
LEAVE_BOTH();
|
|
return;
|
|
}
|
|
|
|
pDevice->bDeviceLost = FALSE;
|
|
pDevice->bDP2Error = FALSE;
|
|
|
|
// If a context was created while lost, we will not re-create it now since
|
|
// we don't have a render target or Z Buffer (the vidmem surfaces would have
|
|
// already been destroyed. Therefore, we won't attempt to create the context
|
|
// until they create the new surfaces and call SetRenderTarget. We also
|
|
// won't try to create any defered texture handles at this time since we may
|
|
// not have a valid context. We will also do that in the SetRenderTarget call.
|
|
|
|
// Walk the list of surfaces and create any SurfaceEx surfaces that we may
|
|
// have pending.
|
|
|
|
pSurf = pDevice->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if ((pSurf->dwFlags & DDSURFACE_DEFERCREATEEX) &&
|
|
!(pSurf->dwFlags & DDSURFACE_DUMMY))
|
|
{
|
|
pHeavy = GetHeavyweightSurf(pSurf);
|
|
if (pHeavy != NULL)
|
|
{
|
|
createsurfaceEx(pHeavy->lpLcl);
|
|
DONE_HEAVYWEIGHT_SURF(pSurf);
|
|
}
|
|
|
|
pSurf->dwFlags &= ~DDSURFACE_DEFERCREATEEX;
|
|
}
|
|
pSurf = pSurf->pNext;
|
|
}
|
|
|
|
// Finally resurrect our deferred driver managed surfaces (Gulp!)
|
|
|
|
while (pDefCreate != NULL)
|
|
{
|
|
// First check if the deferred surface exists at all. The problem
|
|
// is that DdDestroySurface could have been called. We could have
|
|
// removed the surface from the deferred list in DdDestroySurface
|
|
// but since DdDestroySurface is called piecemeal, it gets
|
|
// very annoying. The removal is best done here.
|
|
// ASSUMPTION: if pSList[0].hKernelHandle is NULL then
|
|
// pSList[1,2,etc].hKernelHandle are also NULL. There is no
|
|
// reason for this to be not the case as of 3/2001.
|
|
|
|
if (pDefCreate->CreateData.pSList[0].hKernelHandle == NULL)
|
|
{
|
|
pTemp = pDefCreate->pNext;
|
|
*ppNext = pTemp;
|
|
MemFree(pDefCreate->CreateData.pSList);
|
|
MemFree(pDefCreate);
|
|
pDefCreate = pTemp;
|
|
continue;
|
|
}
|
|
|
|
// Attempt to resurrect
|
|
|
|
pDefCreate->CreateData.bReUse = TRUE;
|
|
hr = DdCreateSurface(&pDefCreate->CreateData);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
for (i = 0; i < pDefCreate->CreateData.dwSCnt; i++)
|
|
{
|
|
pSurf = (PDDSURFACE) pDefCreate->CreateData.pSList[i].hKernelHandle;
|
|
|
|
// Reset DDSURF_SYSMEMALLOCATED to keep DdLock below happy
|
|
|
|
pSurf->dwFlags &= ~DDSURFACE_SYSMEMALLOCATED;
|
|
|
|
// Lock and copy
|
|
|
|
ZeroMemory(&LockData, sizeof(LockData));
|
|
LockData.hDD = hDD;
|
|
LockData.hSurface = pSurf;
|
|
hr = DdLock(&LockData);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
SliceSrc = (BYTE*)pSurf->fpVidMem;
|
|
SliceDst = (BYTE*)LockData.lpSurfData;
|
|
Width = pDefCreate->CreateData.pSList[i].cpWidth;
|
|
Height = pDefCreate->CreateData.pSList[i].cpHeight;
|
|
Depth = pDefCreate->CreateData.pSList[i].cpDepth;
|
|
if (!(pDefCreate->CreateData.Type == D3DRTYPE_VOLUME ||
|
|
pDefCreate->CreateData.Type == D3DRTYPE_VOLUMETEXTURE))
|
|
{
|
|
Depth = 1;
|
|
}
|
|
for (j = 0; j < Depth; ++j)
|
|
{
|
|
RowSrc = SliceSrc;
|
|
RowDst = SliceDst;
|
|
for (k = 0; k < Height; ++k)
|
|
{
|
|
CopyMemory(RowDst, RowSrc, min(LockData.lPitch, (LONG)Width * 8));
|
|
RowSrc += Width * 8;
|
|
RowDst += LockData.lPitch;
|
|
}
|
|
SliceSrc += Width * Height * 8;
|
|
SliceDst += LockData.lSlicePitch;
|
|
}
|
|
|
|
ZeroMemory(&UnlockData, sizeof(UnlockData));
|
|
UnlockData.hDD = hDD;
|
|
UnlockData.hSurface = pSurf;
|
|
hr = DdUnlock(&UnlockData);
|
|
if (FAILED(hr))
|
|
{
|
|
// TODO: Handle/(ignore?) failure
|
|
DPF(0,"Unlock failed when resurrecting driver managed surface.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// TODO: Handle/(ignore?) failure
|
|
DPF(0,"Lock failed when resurrecting driver managed surface. Texture may go missing.");
|
|
}
|
|
|
|
// Free the temporary fpVidmem that we allocated in CreateVidmemSurface
|
|
|
|
MemFree(pSurf->fpVidMem);
|
|
pSurf->fpVidMem = 0;
|
|
}
|
|
|
|
// Remove from list and freeup all memory
|
|
|
|
pTemp = pDefCreate->pNext;
|
|
*ppNext = pTemp;
|
|
MemFree(pDefCreate->CreateData.pSList);
|
|
MemFree(pDefCreate);
|
|
pDefCreate = pTemp;
|
|
}
|
|
else
|
|
{
|
|
// We set ReUse to FALSE to indicate that we were not able to resurrect
|
|
pDefCreate->CreateData.bReUse = FALSE;
|
|
|
|
ppNext = &(pDefCreate->pNext);
|
|
pDefCreate = pDefCreate->pNext;
|
|
}
|
|
}
|
|
|
|
if (pDevice->pDeferList != NULL)
|
|
{
|
|
// TODO:
|
|
// Ummm, we were not able to resurrect. This may be due to out of memory
|
|
// which probably needs to be reported to the app.
|
|
DPF(0,"Unable to resurrect all driver managed surfaces.");
|
|
}
|
|
|
|
LEAVE_BOTH();
|
|
}
|
|
|
|
|
|
BOOL APIENTRY D3D8DoVidmemSurfacesExist( HANDLE hDD)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) hDD;
|
|
PDDSURFACE pSurf;
|
|
|
|
// Walk the list and return TRUE is we find any surfaces that are either
|
|
// local or nonlocal vidmem.
|
|
|
|
ENTER_DDRAW();
|
|
pSurf = pDeviceHandle->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if ((pSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
|
|
(pSurf->Pool == D3DPOOL_NONLOCALVIDMEM) ||
|
|
(pSurf->dwFlags & DDSURFACE_TREATASVIDMEM))
|
|
{
|
|
#if DBG
|
|
DPF(0,"The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist");
|
|
pSurf = pDeviceHandle->pSurfList;
|
|
while (pSurf != NULL)
|
|
{
|
|
if ((pSurf->Pool == D3DPOOL_LOCALVIDMEM) ||
|
|
(pSurf->Pool == D3DPOOL_NONLOCALVIDMEM) ||
|
|
(pSurf->dwFlags & DDSURFACE_TREATASVIDMEM))
|
|
{
|
|
switch (pSurf->Type)
|
|
{
|
|
case D3DRTYPE_SURFACE:
|
|
DPF(0," D3DRTYPE_SURFACE");
|
|
break;
|
|
case D3DRTYPE_VOLUME:
|
|
DPF(0," D3DRTYPE_VOLUME");
|
|
break;
|
|
case D3DRTYPE_TEXTURE:
|
|
DPF(0," D3DRTYPE_TEXTURE");
|
|
break;
|
|
case D3DRTYPE_VOLUMETEXTURE:
|
|
DPF(0," D3DRTYPE_VOLUMETEXTURE");
|
|
break;
|
|
case D3DRTYPE_CUBETEXTURE:
|
|
DPF(0," D3DRTYPE_CUBETEXTURE");
|
|
break;
|
|
case D3DRTYPE_VERTEXBUFFER:
|
|
DPF(0," D3DRTYPE_VERTEXBUFFER");
|
|
break;
|
|
case D3DRTYPE_INDEXBUFFER:
|
|
DPF(0," D3DRTYPE_INDEXBUFFER");
|
|
break;
|
|
case D3DRTYPE_COMMANDBUFFER:
|
|
DPF(0," D3DRTYPE_COMMANDBUFFER");
|
|
break;
|
|
default:
|
|
DPF(0," UNKNOWN SURFACE TYPE");
|
|
break;
|
|
}
|
|
}
|
|
pSurf = pSurf->pNext;
|
|
}
|
|
#endif
|
|
LEAVE_DDRAW();
|
|
|
|
return TRUE;
|
|
}
|
|
pSurf = pSurf->pNext;
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD APIENTRY D3D8GetMode( HANDLE Handle,
|
|
char* pDeviceName,
|
|
D3DDISPLAYMODE* pMode,
|
|
D3DFORMAT Unknown16)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) Handle;
|
|
LPDDRAWI_DIRECTDRAW_GBL pdrv;
|
|
|
|
ENTER_DDRAW();
|
|
memset(pMode, 0, sizeof(D3DDISPLAYMODE));
|
|
|
|
if (pDeviceHandle != NULL)
|
|
{
|
|
pdrv = pDeviceHandle->pDD->lpLcl->lpGbl;
|
|
|
|
pMode->Width = pdrv->vmiData.dwDisplayWidth;
|
|
pMode->Height = pdrv->vmiData.dwDisplayHeight;
|
|
pMode->RefreshRate = pdrv->dwMonitorFrequency;
|
|
switch (pdrv->vmiData.ddpfDisplay.dwRGBBitCount)
|
|
{
|
|
case 8:
|
|
pMode->Format = D3DFMT_P8;
|
|
break;
|
|
|
|
case 15:
|
|
case 16:
|
|
if (pdrv->vmiData.ddpfDisplay.dwGBitMask == 0x7e0)
|
|
{
|
|
pMode->Format = D3DFMT_R5G6B5;
|
|
}
|
|
else
|
|
{
|
|
pMode->Format = D3DFMT_X1R5G5B5;
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
pMode->Format = D3DFMT_R8G8B8;
|
|
break;
|
|
|
|
case 32:
|
|
pMode->Format = D3DFMT_X8R8G8B8;
|
|
break;
|
|
|
|
default:
|
|
pMode->Format = D3DFMT_UNKNOWN;
|
|
break;
|
|
}
|
|
LEAVE_DDRAW();
|
|
return DD_OK;
|
|
}
|
|
else
|
|
{
|
|
DEVMODE dm;
|
|
HDC hdc;
|
|
|
|
memset (&dm, 0, sizeof(dm));
|
|
dm.dmSize = sizeof(dm);
|
|
|
|
// For pre-Win98 systems, we use GetDeviceCaps
|
|
// because ENUM_CURRENT_SETTINGS is not
|
|
// supported on these legacy systems.
|
|
if (!IsWindows98())
|
|
{
|
|
DWORD bpp;
|
|
|
|
hdc = GetDC(NULL);
|
|
|
|
pMode->Width = GetDeviceCaps(hdc, HORZRES);
|
|
pMode->Height = GetDeviceCaps(hdc, VERTRES);
|
|
pMode->RefreshRate = 0;
|
|
|
|
bpp = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
|
|
ReleaseDC(NULL, hdc);
|
|
|
|
switch (bpp)
|
|
{
|
|
case 8:
|
|
pMode->Format = D3DFMT_P8;
|
|
break;
|
|
|
|
case 24:
|
|
pMode->Format = D3DFMT_R8G8B8;
|
|
break;
|
|
|
|
case 32:
|
|
pMode->Format = D3DFMT_X8R8G8B8;
|
|
break;
|
|
|
|
case 15:
|
|
case 16:
|
|
pMode->Format = Unknown16;
|
|
break;
|
|
|
|
default:
|
|
DPF(0, "Unknown desktop format");
|
|
pMode->Format = D3DFMT_UNKNOWN;
|
|
break;
|
|
}
|
|
}
|
|
else if (EnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &dm))
|
|
{
|
|
pMode->Width = dm.dmPelsWidth;
|
|
pMode->Height = dm.dmPelsHeight;
|
|
pMode->RefreshRate = dm.dmDisplayFrequency;
|
|
|
|
switch (dm.dmBitsPerPel)
|
|
{
|
|
case 8:
|
|
pMode->Format = D3DFMT_P8;
|
|
break;
|
|
|
|
case 24:
|
|
pMode->Format = D3DFMT_R8G8B8;
|
|
break;
|
|
|
|
case 32:
|
|
pMode->Format = D3DFMT_X8R8G8B8;
|
|
break;
|
|
|
|
case 15:
|
|
case 16:
|
|
pMode->Format = Unknown16;
|
|
break;
|
|
|
|
default:
|
|
pMode->Format = D3DFMT_UNKNOWN;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LEAVE_DDRAW();
|
|
DPF_ERR("EnumDisplaySettings failed?");
|
|
DPF(0, "display is %s", pDeviceName);
|
|
return D3DERR_DRIVERINTERNALERROR;
|
|
}
|
|
LEAVE_DDRAW();
|
|
return DD_OK;
|
|
}
|
|
|
|
LEAVE_DDRAW();
|
|
return D3DERR_DRIVERINTERNALERROR;
|
|
}
|
|
|
|
|
|
DWORD APIENTRY D3D8SetMode( HANDLE Handle,
|
|
char* pDeviceName,
|
|
UINT Width,
|
|
UINT Height,
|
|
UINT BPP,
|
|
UINT RefreshRate,
|
|
BOOL bRestore)
|
|
{
|
|
PDDDEVICEHANDLE pDeviceHandle = (PDDDEVICEHANDLE) Handle;
|
|
LPDDRAWI_DIRECTDRAW_GBL pdrv;
|
|
HRESULT hr = DDERR_GENERIC;
|
|
DWORD i;
|
|
|
|
ENTER_DDRAW();
|
|
if ((pDeviceHandle != NULL) &&
|
|
(pDeviceHandle->pDD != NULL))
|
|
{
|
|
// We will call DDraw to do the mode change because it is able to
|
|
// cleanup the mode change when the app exits and because we don't
|
|
// want to treat external mode changes and DDraw mode changes the
|
|
// same way.
|
|
|
|
pdrv = pDeviceHandle->pDD->lpLcl->lpGbl;
|
|
for (i = 0; i < pdrv->dwNumModes; i++)
|
|
{
|
|
if ((pdrv->lpModeInfo[i].dwWidth == Width) &&
|
|
(pdrv->lpModeInfo[i].dwHeight == Height) &&
|
|
(pdrv->lpModeInfo[i].dwBPP == BPP))
|
|
{
|
|
if ((RefreshRate == 0) ||
|
|
(RefreshRate == pdrv->lpModeInfo[i].wRefreshRate))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (i < pdrv->dwNumModes)
|
|
{
|
|
BOOL bExists;
|
|
BOOL bOwn;
|
|
LPDDRAWI_DIRECTDRAW_LCL lcl = pDeviceHandle->pDD->lpLcl;
|
|
|
|
// When profiling, we will be doing mode changes w/o holding
|
|
// exlusive mode, but we need ddraw to think that we have it in
|
|
// order to change bit depth.
|
|
|
|
CheckExclusiveMode(lcl, &bExists, &bOwn, FALSE, NULL, FALSE);
|
|
if (!bOwn)
|
|
{
|
|
if (bExists)
|
|
{
|
|
LEAVE_DDRAW();
|
|
return D3DERR_DRIVERINTERNALERROR;
|
|
}
|
|
lcl->lpGbl->lpExclusiveOwner = lcl;
|
|
}
|
|
|
|
if (bRestore)
|
|
{
|
|
hr = MapLegacyResult(RestoreDisplayMode (lcl, TRUE));
|
|
}
|
|
else
|
|
{
|
|
hr = MapLegacyResult(SetDisplayMode (lcl,
|
|
i,
|
|
TRUE,
|
|
RefreshRate != 0));
|
|
}
|
|
if (!bOwn)
|
|
{
|
|
// This check shouldn't be needed, but it's safe since just
|
|
// about anything can happen during a mode change.
|
|
|
|
if (lcl->lpGbl->lpExclusiveOwner == lcl)
|
|
{
|
|
lcl->lpGbl->lpExclusiveOwner = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LEAVE_DDRAW();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
DWORD APIENTRY D3D8SetCooperativeLevel(
|
|
HANDLE hDD,
|
|
HWND hWnd,
|
|
DWORD dwFlags )
|
|
{
|
|
PDDDEVICEHANDLE pDevice = (PDDDEVICEHANDLE) hDD;
|
|
LPDDRAWI_DIRECTDRAW_INT pdrv_int = pDevice->pDD;
|
|
return MapLegacyResult(DD_SetCooperativeLevel((LPDIRECTDRAW)pdrv_int, hWnd, dwFlags|DDSCL_DX8APP));
|
|
}
|
|
|
|
BOOL APIENTRY D3D8IsDummySurface(
|
|
HANDLE hSurface )
|
|
{
|
|
PDDSURFACE pSurf = (PDDSURFACE) hSurface;
|
|
|
|
return ((pSurf->dwFlags & DDSURFACE_DUMMY) != 0);
|
|
}
|
|
|
|
void CleanupD3D8( LPDDRAWI_DIRECTDRAW_GBL pdrv,
|
|
BOOL bDestroyAll,
|
|
DWORD PID)
|
|
{
|
|
DDDEVICEHANDLE* pDevice;
|
|
DDDEVICEHANDLE* pTemp;
|
|
|
|
ENTER_DDRAW();
|
|
pDevice = pDeviceList;
|
|
|
|
if (bDestroyAll)
|
|
{
|
|
// The process has died, so clean everything up. We don't need to call
|
|
// the software driver for anything since it's already unloaded.
|
|
|
|
while (pDevice != NULL)
|
|
{
|
|
if (pDevice->PID == PID)
|
|
{
|
|
CleanupDevice(pDevice);
|
|
|
|
// Remove this device from the list
|
|
|
|
if (pDeviceList == pDevice)
|
|
{
|
|
pDeviceList = pDevice->pLink;
|
|
}
|
|
else
|
|
{
|
|
pTemp = pDeviceList;
|
|
while (pTemp->pLink != pDevice)
|
|
{
|
|
pTemp = pTemp->pLink;
|
|
}
|
|
pTemp->pLink = pDevice->pLink;
|
|
}
|
|
|
|
// Now free the device
|
|
|
|
pTemp = pDevice;
|
|
pDevice = pDevice->pLink;
|
|
MemFree(pTemp);
|
|
}
|
|
else
|
|
{
|
|
pDevice = pDevice->pLink;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// The device is getting lost, so we will mark it as lost and free up
|
|
// any resources that will get lost.
|
|
|
|
while (pDevice != NULL)
|
|
{
|
|
if (pDevice->pDD->lpLcl->lpGbl == pdrv)
|
|
{
|
|
LoseDevice (pDevice);
|
|
}
|
|
pDevice = pDevice->pLink;
|
|
}
|
|
}
|
|
LEAVE_DDRAW();
|
|
}
|
|
|
|
|
|
VOID APIENTRY D3D8LoseDevice(
|
|
HANDLE hDD )
|
|
{
|
|
ENTER_DDRAW();
|
|
LoseDevice (hDD);
|
|
LEAVE_DDRAW();
|
|
}
|
|
|
|
|
|
|
|
VOID APIENTRY D3D8GetHALName(
|
|
char* pDisplayName,
|
|
char* pHALName)
|
|
{
|
|
LPDDRAWI_DIRECTDRAW_INT lpDD_int = NULL;
|
|
|
|
ENTER_DDRAW();
|
|
InternalDirectDrawCreate( NULL,
|
|
(LPDIRECTDRAW*) &lpDD_int,
|
|
NULL,
|
|
DDRAWILCL_DIRECTDRAW7 | DDRAWILCL_DIRECTDRAW8,
|
|
pDisplayName);
|
|
if (lpDD_int != NULL)
|
|
{
|
|
lstrcpy(pHALName, lpDD_int->lpLcl->lpGbl->dd32BitDriverData.szName);
|
|
DD_Release((LPDIRECTDRAW)lpDD_int);
|
|
}
|
|
LEAVE_DDRAW();
|
|
}
|
|
|
|
|