|
|
//----------------------------------------------------------------------------
//
// refrastfn.cpp
//
// Reference rasterizer callback functions for D3DIM.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
// Primitive functions
#include "primfns.hpp"
#define MAX_CLIPPING_PLANES 12
#define MAX_CLIP_VERTICES (( 2 * MAX_CLIPPING_PLANES ) + 3 )
#define MAX_VERTEX_COUNT 2048
#define BASE_VERTEX_COUNT (MAX_VERTEX_COUNT - MAX_CLIP_VERTICES)
HRESULT RefRastLockTarget(ReferenceRasterizer *pRefRast); void RefRastUnlockTarget(ReferenceRasterizer *pRefRast); HRESULT RefRastLockTexture(ReferenceRasterizer *pRefRast); void RefRastUnlockTexture(ReferenceRasterizer *pRefRast);
//----------------------------------------------------------------------------
//
// Stiches together device descs
//
//----------------------------------------------------------------------------
void D3DDeviceDescConvert(LPD3DDEVICEDESC7 lpOut, LPD3DDEVICEDESC_V1 lpV1, LPD3DHAL_D3DEXTENDEDCAPS lpExt) { if(lpV1!=NULL) { lpOut->dwDevCaps = lpV1->dwDevCaps; lpOut->dpcLineCaps = lpV1->dpcLineCaps; lpOut->dpcTriCaps = lpV1->dpcTriCaps; lpOut->dwDeviceRenderBitDepth = lpV1->dwDeviceRenderBitDepth; lpOut->dwDeviceZBufferBitDepth = lpV1->dwDeviceZBufferBitDepth; }
if (lpExt) { // DX5
lpOut->dwMinTextureWidth = lpExt->dwMinTextureWidth; lpOut->dwMaxTextureWidth = lpExt->dwMaxTextureWidth; lpOut->dwMinTextureHeight = lpExt->dwMinTextureHeight; lpOut->dwMaxTextureHeight = lpExt->dwMaxTextureHeight;
// DX6
lpOut->dwMaxTextureRepeat = lpExt->dwMaxTextureRepeat; lpOut->dwMaxTextureAspectRatio = lpExt->dwMaxTextureAspectRatio; lpOut->dwMaxAnisotropy = lpExt->dwMaxAnisotropy; lpOut->dvGuardBandLeft = lpExt->dvGuardBandLeft; lpOut->dvGuardBandTop = lpExt->dvGuardBandTop; lpOut->dvGuardBandRight = lpExt->dvGuardBandRight; lpOut->dvGuardBandBottom = lpExt->dvGuardBandBottom; lpOut->dvExtentsAdjust = lpExt->dvExtentsAdjust; lpOut->dwStencilCaps = lpExt->dwStencilCaps; lpOut->dwFVFCaps = lpExt->dwFVFCaps; lpOut->dwTextureOpCaps = lpExt->dwTextureOpCaps; lpOut->wMaxTextureBlendStages = lpExt->wMaxTextureBlendStages; lpOut->wMaxSimultaneousTextures = lpExt->wMaxSimultaneousTextures;
// DX7
lpOut->dwMaxActiveLights = lpExt->dwMaxActiveLights; lpOut->dvMaxVertexW = lpExt->dvMaxVertexW; lpOut->wMaxUserClipPlanes = lpExt->wMaxUserClipPlanes; lpOut->wMaxVertexBlendMatrices = lpExt->wMaxVertexBlendMatrices; lpOut->dwVertexProcessingCaps = lpExt->dwVertexProcessingCaps; lpOut->dwReserved1 = lpExt->dwReserved1; lpOut->dwReserved2 = lpExt->dwReserved2; lpOut->dwReserved3 = lpExt->dwReserved3; lpOut->dwReserved4 = lpExt->dwReserved4; } }
//----------------------------------------------------------------------------
//
// FindOutSurfFormat
//
// Converts a DDPIXELFORMAT to RRSurfaceType.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL FindOutSurfFormat(LPDDPIXELFORMAT pDdPixFmt, RRSurfaceType *pFmt) { if (pDdPixFmt->dwFlags & DDPF_ZBUFFER) { switch(pDdPixFmt->dwZBitMask) { default: case 0x0000FFFF: *pFmt = RR_STYPE_Z16S0; break; case 0xFFFFFF00: if (pDdPixFmt->dwStencilBitMask == 0x000000FF) { *pFmt = RR_STYPE_Z24S8; } else { *pFmt = RR_STYPE_Z24S4; } break; case 0x00FFFFFF: if (pDdPixFmt->dwStencilBitMask == 0xFF000000) { *pFmt = RR_STYPE_S8Z24; } else { *pFmt = RR_STYPE_S4Z24; } break; case 0x0000FFFE: *pFmt = RR_STYPE_Z15S1; break; case 0x00007FFF: *pFmt = RR_STYPE_S1Z15; break; case 0xFFFFFFFF: *pFmt = RR_STYPE_Z32S0; break; } } else if (pDdPixFmt->dwFlags & DDPF_BUMPDUDV) { UINT uFmt = pDdPixFmt->dwBumpDvBitMask; switch (uFmt) { case 0x0000ff00: switch (pDdPixFmt->dwRGBBitCount) { case 24: *pFmt = RR_STYPE_U8V8L8; break; case 16: *pFmt = RR_STYPE_U8V8; break; } break;
case 0x000003e0: *pFmt = RR_STYPE_U5V5L6; break; } } else if (pDdPixFmt->dwFlags & DDPF_PALETTEINDEXED8) { *pFmt = RR_STYPE_PALETTE8; } else if (pDdPixFmt->dwFlags & DDPF_PALETTEINDEXED4) { *pFmt = RR_STYPE_PALETTE4; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('U', 'Y', 'V', 'Y')) { *pFmt = RR_STYPE_UYVY; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('Y', 'U', 'Y', '2')) { *pFmt = RR_STYPE_YUY2; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('D', 'X', 'T', '1')) { *pFmt = RR_STYPE_DXT1; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('D', 'X', 'T', '2')) { *pFmt = RR_STYPE_DXT2; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('D', 'X', 'T', '3')) { *pFmt = RR_STYPE_DXT3; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('D', 'X', 'T', '4')) { *pFmt = RR_STYPE_DXT4; } else if (pDdPixFmt->dwFourCC == MAKEFOURCC('D', 'X', 'T', '5')) { *pFmt = RR_STYPE_DXT5; } else { UINT uFmt = pDdPixFmt->dwGBitMask | pDdPixFmt->dwRBitMask;
if (pDdPixFmt->dwFlags & DDPF_ALPHAPIXELS) { uFmt |= pDdPixFmt->dwRGBAlphaBitMask; }
switch (uFmt) { case 0x00ffff00: switch (pDdPixFmt->dwRGBBitCount) { case 32: *pFmt = RR_STYPE_B8G8R8X8; break; case 24: *pFmt = RR_STYPE_B8G8R8; break; } break; case 0xffffff00: *pFmt = RR_STYPE_B8G8R8A8; break; case 0xffe0: if (pDdPixFmt->dwFlags & DDPF_ALPHAPIXELS) { *pFmt = RR_STYPE_B5G5R5A1; } else { *pFmt = RR_STYPE_B5G6R5; } break; case 0x07fe0: *pFmt = RR_STYPE_B5G5R5; break; case 0xff0: *pFmt = RR_STYPE_B4G4R4; break; case 0xfff0: *pFmt = RR_STYPE_B4G4R4A4; break; case 0xff: if (pDdPixFmt->dwFlags & DDPF_ALPHAPIXELS) { *pFmt = RR_STYPE_L4A4; } else { *pFmt = RR_STYPE_L8; } break; case 0xffff: *pFmt = RR_STYPE_L8A8; break; case 0xfc: *pFmt = RR_STYPE_B2G3R3; break; case 0xfffc: *pFmt = RR_STYPE_B2G3R3A8; break; default: *pFmt = RR_STYPE_NULL; break; } }
return D3D_OK; }
//----------------------------------------------------------------------------
//
// ValidTextureSize
//
// checks for power of two texture size
//
//----------------------------------------------------------------------------
BOOL FASTCALL ValidTextureSize(INT16 iuSize, INT16 iuShift, INT16 ivSize, INT16 ivShift) { if (iuSize == 1) { if (ivSize == 1) { return TRUE; } else { return !(ivSize & (~(1 << ivShift))); } } else { if (ivSize == 1) { return !(iuSize & (~(1 << iuShift))); } else { return (!(iuSize & (~(1 << iuShift))) && !(iuSize & (~(1 << iuShift)))); } } }
//----------------------------------------------------------------------------
//
// ValidMipmapSize
//
// Computes size of next smallest mipmap level, clamping at 1
//
//----------------------------------------------------------------------------
BOOL FASTCALL ValidMipmapSize(INT16 iPreSize, INT16 iSize) { if (iPreSize == 1) { if (iSize == 1) { return TRUE; } else { return FALSE; } } else { return ((iPreSize >> 1) == iSize); } }
//----------------------------------------------------------------------------
//
// RefRastLockTarget
//
// Lock current RenderTarget.
//
//----------------------------------------------------------------------------
HRESULT RefRastLockTarget(ReferenceRasterizer *pRefRast) { HRESULT hr; RRRenderTarget *pRrTarget;
pRrTarget = pRefRast->GetRenderTarget();
HR_RET(LockSurface(pRrTarget->m_pDDSLcl, (LPVOID*)&(pRrTarget->m_pColorBufBits))); if (pRrTarget->m_pDDSZLcl) { HR_RET(LockSurface(pRrTarget->m_pDDSZLcl, (LPVOID*)&(pRrTarget->m_pDepthBufBits))); } else { pRrTarget->m_pDepthBufBits = NULL; }
return D3D_OK; }
//----------------------------------------------------------------------------
//
// RefRastUnlockTexture
//
// Unlock current RenderTarget.
//
//----------------------------------------------------------------------------
void RefRastUnlockTarget(ReferenceRasterizer *pRefRast) { RRRenderTarget *pRrTarget;
pRrTarget = pRefRast->GetRenderTarget();
UnlockSurface(pRrTarget->m_pDDSLcl); if (pRrTarget->m_pDDSZLcl) { UnlockSurface(pRrTarget->m_pDDSZLcl); } }
//----------------------------------------------------------------------------
//
// RRTextureMapSetSizes
//
// Sets sizes, pitches, etc, based on the current iFirstSurf.
//
//----------------------------------------------------------------------------
static HRESULT RRTextureMapSetSizes( RRTexture *pRRTex, INT iFirstSurf, INT cEnvMap ) { LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl = pRRTex->m_pDDSLcl[iFirstSurf]; RRSurfaceType SurfType = pRRTex->m_SurfType; INT i, j;
// Init texturemap.
pRRTex->m_iWidth = DDSurf_Width( pDDSLcl ); pRRTex->m_iHeight = DDSurf_Height( pDDSLcl );
for ( j = 0; j < cEnvMap; j++ ) { if ((SurfType == RR_STYPE_DXT1) || (SurfType == RR_STYPE_DXT2) || (SurfType == RR_STYPE_DXT3) || (SurfType == RR_STYPE_DXT4) || (SurfType == RR_STYPE_DXT5)) { // Note, here is the assumption that:
// 1) width and height are reported correctly by the driver that
// created the surface
// 2) The allocation of the memory is contiguous (as done by hel)
pRRTex->m_iPitch[j] = ((pRRTex->m_iWidth+3)>>2) * g_DXTBlkSize[(int)SurfType - (int)RR_STYPE_DXT1]; } else { pRRTex->m_iPitch[j] = DDSurf_Pitch( pDDSLcl ); } }
// Check if the texture size is power of 2
if (!ValidTextureSize((INT16)pRRTex->m_iWidth, (INT16)IntLog2(pRRTex->m_iWidth), (INT16)pRRTex->m_iHeight, (INT16)IntLog2(pRRTex->m_iHeight))) { return DDERR_INVALIDPARAMS; }
// Check for mipmap if any.
// iPreSizeU and iPreSizeV store the size(u and v) of the previous level
// mipmap. They are init'ed with the first texture size.
INT16 iPreSizeU = (INT16)pRRTex->m_iWidth, iPreSizeV = (INT16)pRRTex->m_iHeight; for ( i = iFirstSurf + cEnvMap; i <= pRRTex->m_cLOD*cEnvMap; i += cEnvMap) { for ( j = 0; j < cEnvMap; j++ ) { pDDSLcl = pRRTex->m_pDDSLcl[i+j]; if (NULL == pDDSLcl) continue; if ((SurfType == RR_STYPE_DXT1) || (SurfType == RR_STYPE_DXT2) || (SurfType == RR_STYPE_DXT3) || (SurfType == RR_STYPE_DXT4) || (SurfType == RR_STYPE_DXT5)) { // Note, here is the assumption that:
// 1) width and height are reported correctly by the driver that
// created the surface
// 2) The allocation of the memory is contiguous (as done by hel)
pRRTex->m_iPitch[i-iFirstSurf+j] = ((DDSurf_Width( pDDSLcl )+3)>>2) * g_DXTBlkSize[(int)SurfType - (int)RR_STYPE_DXT1]; } else { pRRTex->m_iPitch[i-iFirstSurf+j] = DDSurf_Pitch( pDDSLcl ); }
if (j == 0) { // Check for invalid mipmap texture size
if (!ValidMipmapSize(iPreSizeU, (INT16)DDSurf_Width( pDDSLcl )) || !ValidMipmapSize(iPreSizeV, (INT16)DDSurf_Height( pDDSLcl ))) { return DDERR_INVALIDPARAMS; } } iPreSizeU = (INT16)DDSurf_Width( pDDSLcl ); iPreSizeV = (INT16)DDSurf_Height( pDDSLcl ); } }
return D3D_OK; }
//----------------------------------------------------------------------------
//
// RefRastLockTexture
//
// Lock current texture surface before the texture bits are accessed.
//
//----------------------------------------------------------------------------
HRESULT RefRastLockTexture(ReferenceRasterizer *pRefRast) { INT i, j, k; RRTexture* pRRTex[D3DHAL_TSS_MAXSTAGES]; D3DTEXTUREHANDLE phTex[D3DHAL_TSS_MAXSTAGES]; HRESULT hr; int cActTex;
if ((cActTex = pRefRast->GetCurrentTextureMaps(phTex, pRRTex)) == 0) { return D3D_OK; }
for (j = 0; j < cActTex; j++) { // stages may not have texture bound
if ( NULL == pRRTex[j] ) continue;
// Don't lock anything that is currently locked
if ((pRRTex[j]->m_uFlags & RR_TEXTURE_LOCKED) == 0) { INT32 iMaxMipLevels = 0; if ( NULL != pRRTex[j]->m_pStageState ) { iMaxMipLevels = pRRTex[j]->m_pStageState->m_dwVal[D3DTSS_MAXMIPLEVEL]; } INT iFirstSurf = min(iMaxMipLevels, pRRTex[j]->m_cLODDDS); INT cEnvMap = (pRRTex[j]->m_uFlags & RR_TEXTURE_ENVMAP) ? (6) : (1); iFirstSurf *= cEnvMap;
HR_RET(RRTextureMapSetSizes(pRRTex[j], iFirstSurf, cEnvMap));
for (i = iFirstSurf; i <= pRRTex[j]->m_cLODDDS*cEnvMap; i += cEnvMap) { for ( k = 0; k < cEnvMap; k++ ) { hr = LockSurface(pRRTex[j]->m_pDDSLcl[i+k], (LPVOID*)&(pRRTex[j]->m_pTextureBits[i-iFirstSurf+k]));
if (hr != D3D_OK) { // Unlock any partial mipmap locks we've taken, as
// RastUnlock can only handle entire textures being
// locked or unlocked.
while (--i + k >= 0) { UnlockSurface(pRRTex[j]->m_pDDSLcl[i+k]); }
// Make sure that i is signed and that the above
// loop exited properly.
_ASSERT(i+k < 0, "Unlock of partial mipmap locks failed" );
goto EH_Unlock; } } }
// Set the transparent bit and the transparent color with pDDS[0]
LPDDRAWI_DDRAWSURFACE_LCL pLcl; pLcl = pRRTex[j]->m_pDDSLcl[0]; if ((pLcl->dwFlags & DDRAWISURF_HASCKEYSRCBLT) != 0) { pRRTex[j]->m_uFlags |= RR_TEXTURE_HAS_CK; pRRTex[j]->m_dwColorKey = pLcl->ddckCKSrcBlt.dwColorSpaceLowValue; } else { pRRTex[j]->m_uFlags &= ~RR_TEXTURE_HAS_CK; }
// set the empty face color with pDDS[0]
// note that ddckCKDestOverlay is unioned with dwEmptyFaceColor, but
// not in the internal structure
pRRTex[j]->m_dwEmptyFaceColor = pLcl->ddckCKDestOverlay.dwColorSpaceLowValue;
// Update palette
if (pRRTex[j]->m_SurfType == RR_STYPE_PALETTE8 || pRRTex[j]->m_SurfType == RR_STYPE_PALETTE4) { if (pLcl->lpDDPalette) { LPDDRAWI_DDRAWPALETTE_GBL pPal = pLcl->lpDDPalette->lpLcl->lpGbl; pRRTex[j]->m_pPalette = (DWORD*)pPal->lpColorTable; if (pPal->dwFlags & DDRAWIPAL_ALPHA) { pRRTex[j]->m_uFlags |= RR_TEXTURE_ALPHAINPALETTE; } } }
pRRTex[j]->m_uFlags |= RR_TEXTURE_LOCKED; } }
// validate texture internals
for (j = 0; j < cActTex; j++) { // stages may not have texture bound
if ( NULL == pRRTex[j] ) continue;
if ( !(pRRTex[j]->Validate()) ) { hr = DDERR_INVALIDPARAMS; goto EH_Unlock; } }
return D3D_OK;
EH_Unlock: // Unlock complete textures we've already locked.
// RastUnlock will check the flags to figure
// out which ones to unlock.
RefRastUnlockTexture(pRefRast);
return hr; }
//----------------------------------------------------------------------------
//
// RefRastUnlockTexture
//
// Unlock texture surface after the texture bits are accessed.
//
//----------------------------------------------------------------------------
void RefRastUnlockTexture(ReferenceRasterizer *pRefRast) { INT i, j, k; RRTexture* pRRTex[D3DHAL_TSS_MAXSTAGES]; D3DTEXTUREHANDLE phTex[D3DHAL_TSS_MAXSTAGES]; int cActTex;
if ((cActTex = pRefRast->GetCurrentTextureMaps(phTex, pRRTex)) == 0) { return ; }
for (j = 0; j < cActTex; j++) { // stages may not have texture bound
if ( NULL == pRRTex[j] ) continue;
// RastUnlock is used for cleanup in RastLock so it needs to
// be able to handle partially locked mipmap chains.
if (pRRTex[j]->m_uFlags & RR_TEXTURE_LOCKED) { INT32 iMaxMipLevels = 0; if ( NULL != pRRTex[j]->m_pStageState ) { iMaxMipLevels = pRRTex[j]->m_pStageState->m_dwVal[D3DTSS_MAXMIPLEVEL]; } INT iFirstSurf = min(iMaxMipLevels, pRRTex[j]->m_cLODDDS); INT cEnvMap = (pRRTex[j]->m_uFlags & RR_TEXTURE_ENVMAP) ? (6) : (1); iFirstSurf *= cEnvMap;
for (i = iFirstSurf; i <= pRRTex[j]->m_cLODDDS*cEnvMap; i += cEnvMap) { for ( k = 0; k < cEnvMap; k++ ) { UnlockSurface(pRRTex[j]->m_pDDSLcl[i+k]); pRRTex[j]->m_pTextureBits[i-iFirstSurf+k] = NULL; } }
// Reset the flags
pRRTex[j]->m_uFlags &= ~RR_TEXTURE_LOCKED; pRRTex[j]->m_uFlags &= ~RR_TEXTURE_HAS_CK;
pRRTex[j]->Validate(); } } }
//----------------------------------------------------------------------------
//
// FillRRRenderTarget
//
// Converts color and Z surface information into refrast form.
//
//----------------------------------------------------------------------------
HRESULT FillRRRenderTarget(LPDDRAWI_DDRAWSURFACE_LCL pLclColor, LPDDRAWI_DDRAWSURFACE_LCL pLclZ, RRRenderTarget *pRrTarget) { HRESULT hr; RRSurfaceType ColorFmt; RRSurfaceType ZFmt = RR_STYPE_NULL;
// Release objects we hold pointers to
if (pRrTarget->m_pDDSLcl) { pRrTarget->m_pDDSLcl = NULL; } if (pRrTarget->m_pDDSZLcl) { pRrTarget->m_pDDSZLcl = NULL; }
HR_RET(FindOutSurfFormat(&DDSurf_PixFmt(pLclColor), &ColorFmt));
if (NULL != pLclZ) { HR_RET(FindOutSurfFormat(&(DDSurf_PixFmt(pLclZ)), &ZFmt)); pRrTarget->m_pDepthBufBits = (char *)SURFACE_MEMORY(pLclZ); pRrTarget->m_iDepthBufPitch = DDSurf_Pitch(pLclZ); pRrTarget->m_pDDSZLcl = pLclZ; } else { pRrTarget->m_pDepthBufBits = NULL; pRrTarget->m_iDepthBufPitch = 0; pRrTarget->m_pDDSZLcl = NULL; }
pRrTarget->m_Clip.left = 0; pRrTarget->m_Clip.top = 0; pRrTarget->m_Clip.bottom = DDSurf_Height(pLclColor) - 1; pRrTarget->m_Clip.right = DDSurf_Width(pLclColor) - 1; pRrTarget->m_iWidth = DDSurf_Width(pLclColor); pRrTarget->m_iHeight = DDSurf_Height(pLclColor); pRrTarget->m_pColorBufBits = (char *)SURFACE_MEMORY(pLclColor); pRrTarget->m_iColorBufPitch = DDSurf_Pitch(pLclColor); pRrTarget->m_ColorSType = (RRSurfaceType)ColorFmt; pRrTarget->m_DepthSType = (RRSurfaceType)ZFmt; pRrTarget->m_pDDSLcl = pLclColor;
return D3D_OK; }
//----------------------------------------------------------------------------
//
// RefRastContextCreate
//
// Creates a ReferenceRasterizer and initializes it with the info passed in.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastContextCreate(LPD3DHAL_CONTEXTCREATEDATA pCtxData) { ReferenceRasterizer *pRefRast; RRRenderTarget *pRendTgt; INT i; RRDEVICETYPE dwDriverType;
// Surface7 pointers for QI
LPDDRAWI_DDRAWSURFACE_LCL pZLcl = NULL; LPDDRAWI_DDRAWSURFACE_LCL pColorLcl = NULL; HRESULT ret;
DPFM(0, DRV, ("In the new RefRast Dll\n"));
// this only needs to be called once, but once per context won't hurt
RefRastSetMemif(&malloc, &free, &realloc);
if ((pRendTgt = new RRRenderTarget()) == NULL) { pCtxData->ddrval = DDERR_OUTOFMEMORY; return DDHAL_DRIVER_HANDLED; }
// If it is expected to be a DX7+ driver
if (pCtxData->ddrval < (DWORD)RRTYPE_DX7HAL) { if (pCtxData->lpDDS) pColorLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pCtxData->lpDDS))->lpLcl; if (pCtxData->lpDDSZ) pZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pCtxData->lpDDSZ))->lpLcl; } else { pColorLcl = pCtxData->lpDDSLcl; pZLcl = pCtxData->lpDDSZLcl; }
// save the ddrval that is being sent down to communicate the driver
// type that the runtime expects it to be.
dwDriverType = (RRDEVICETYPE) pCtxData->ddrval;
// Collect surface information where the failures are easy to handle.
pCtxData->ddrval = FillRRRenderTarget(pColorLcl, pZLcl, pRendTgt); if (pCtxData->ddrval != D3D_OK) { return DDHAL_DRIVER_HANDLED; }
// Note (Hacks):
// dwhContext is used by the runtime to inform the driver, which
// d3d interface is calling the driver.
// ddrval is used by the runtime to inform the driver the DriverStyle
// value it read. This is a RefRast specific hack.
if ((pRefRast = new ReferenceRasterizer( pCtxData->lpDDLcl, (DWORD)(pCtxData->dwhContext), dwDriverType)) == NULL) { pCtxData->ddrval = DDERR_OUTOFMEMORY; return DDHAL_DRIVER_HANDLED; }
pRefRast->SetRenderTarget(pRendTgt);
// return RR object pointer as context handle
pCtxData->dwhContext = (ULONG_PTR)pRefRast;
pCtxData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastContextDestroy
//
// Destroy a ReferenceRasterizer.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastContextDestroy(LPD3DHAL_CONTEXTDESTROYDATA pCtxDestroyData) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastContextDestroy", pCtxDestroyData);
// Clean up override bits
RRRenderTarget *pRendTgt = pRefRast->GetRenderTarget(); if ( NULL != pRendTgt ) { delete pRendTgt; }
delete pRefRast;
pCtxDestroyData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastSceneCapture
//
// Pass scene capture callback to ref rast.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastSceneCapture(LPD3DHAL_SCENECAPTUREDATA pData) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastSceneCapture", pData);
pRefRast->SceneCapture( pData->dwFlag );
pData->ddrval = D3D_OK; // Should this be changed to a QI ?
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastSetRenderTarget
//
// Update a RefRast context with the info from a new render target.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastSetRenderTarget(LPD3DHAL_SETRENDERTARGETDATA pTgtData) { ReferenceRasterizer *pRefRast; LPDDRAWI_DDRAWSURFACE_LCL pZLcl = NULL; LPDDRAWI_DDRAWSURFACE_LCL pColorLcl = NULL; HRESULT ret;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastSetRenderTarget", pTgtData);
RRRenderTarget *pRendTgt = pRefRast->GetRenderTarget(); if ( NULL == pRendTgt ) { return DDHAL_DRIVER_HANDLED; }
if (pRefRast->IsInterfaceDX6AndBefore() || pRefRast->IsDriverDX6AndBefore()) { if( pTgtData->lpDDS ) pColorLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pTgtData->lpDDS))->lpLcl; if( pTgtData->lpDDSZ ) pZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pTgtData->lpDDSZ))->lpLcl; } else { pColorLcl = pTgtData->lpDDSLcl; pZLcl = pTgtData->lpDDSZLcl; }
// Collect surface information.
pTgtData->ddrval = FillRRRenderTarget(pColorLcl, pZLcl, pRendTgt); if (pTgtData->ddrval != D3D_OK) { return DDHAL_DRIVER_HANDLED; }
pRefRast->SetRenderTarget(pRendTgt);
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastValidateTextureStageState
//
// Validate current blend operations. RefRast does everything.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastValidateTextureStageState(LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA pData) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastValidateTextureStageState", pData);
pData->dwNumPasses = 1; pData->ddrval = D3D_OK;
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastDrawOneIndexedPrimitive
//
// Draw one list of primitives. This is called by D3DIM for API
// DrawIndexedPrimitive.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastDrawOneIndexedPrimitive(LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA pOneIdxPrimData) { ReferenceRasterizer *pRefRast; HRESULT hr; DWORD dwVStride;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastDrawOneIndexedPrimitive", pOneIdxPrimData);
if ((pOneIdxPrimData->ddrval=RRFVFCheckAndStride(pOneIdxPrimData->dwFVFControl, &dwVStride)) != D3D_OK) { return DDHAL_DRIVER_HANDLED; } if ((pOneIdxPrimData->ddrval= RefRastLockTarget(pRefRast)) != D3D_OK) { return DDHAL_DRIVER_HANDLED; } if ((pOneIdxPrimData->ddrval=RefRastLockTexture(pRefRast)) != D3D_OK) { RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } if ((pOneIdxPrimData->ddrval= pRefRast->BeginRendering((DWORD)pOneIdxPrimData->dwFVFControl)) != D3D_OK) { RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; }
pOneIdxPrimData->ddrval = DoDrawOneIndexedPrimitive(pRefRast, (UINT16)dwVStride, (PUINT8)pOneIdxPrimData->lpvVertices, pOneIdxPrimData->lpwIndices, pOneIdxPrimData->PrimitiveType, pOneIdxPrimData->dwNumIndices); hr = pRefRast->EndRendering(); RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); if (pOneIdxPrimData->ddrval == D3D_OK) { pOneIdxPrimData->ddrval = hr; } return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastDrawOnePrimitive
//
// Draw one list of primitives. This is called by D3DIM for API DrawPrimitive.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastDrawOnePrimitive(LPD3DHAL_DRAWONEPRIMITIVEDATA pOnePrimData) { ReferenceRasterizer *pRefRast; HRESULT hr; DWORD dwVStride;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastDrawOnePrimitive", pOnePrimData);
if ((pOnePrimData->ddrval=RRFVFCheckAndStride(pOnePrimData->dwFVFControl, &dwVStride)) != D3D_OK) { return DDHAL_DRIVER_HANDLED; } if ((pOnePrimData->ddrval=RefRastLockTarget(pRefRast)) != D3D_OK) { return DDHAL_DRIVER_HANDLED; } if ((pOnePrimData->ddrval=RefRastLockTexture(pRefRast)) != D3D_OK) { RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } if ((pOnePrimData->ddrval= pRefRast->BeginRendering(pOnePrimData->dwFVFControl)) != D3D_OK) { RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } pOnePrimData->ddrval = DoDrawOnePrimitive(pRefRast, (UINT16)dwVStride, (PUINT8)pOnePrimData->lpvVertices, pOnePrimData->PrimitiveType, pOnePrimData->dwNumVertices); hr = pRefRast->EndRendering(); // Unlock texture/rendertarget
RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); if (pOnePrimData->ddrval == D3D_OK) { pOnePrimData->ddrval = hr; }
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastDrawPrimitives
//
// This is called by D3DIM for a list of batched API DrawPrimitive calls.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastDrawPrimitives(LPD3DHAL_DRAWPRIMITIVESDATA pDrawPrimData) { ReferenceRasterizer *pRefRast; PUINT8 pData = (PUINT8)pDrawPrimData->lpvData; LPD3DHAL_DRAWPRIMCOUNTS pDrawPrimitiveCounts; HRESULT hr; DWORD dwVStride;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastDrawPrimitives", pDrawPrimData);
pDrawPrimitiveCounts = (LPD3DHAL_DRAWPRIMCOUNTS)pData; // Check for FVF only if there is something to be drawn
if (pDrawPrimitiveCounts->wNumVertices > 0) { // Unconditionally get the vertex stride, since it can not change
if ((pDrawPrimData->ddrval = RRFVFCheckAndStride(pDrawPrimData->dwFVFControl, &dwVStride)) != D3D_OK) { return DDHAL_DRIVER_HANDLED; } }
if ((pDrawPrimData->ddrval=RefRastLockTarget(pRefRast)) != D3D_OK) { return DDHAL_DRIVER_HANDLED; }
// Skip BeginRendering & RefRastLockTexture if first thing is state change
if (pDrawPrimitiveCounts->wNumStateChanges <= 0) { if ((pDrawPrimData->ddrval=RefRastLockTexture(pRefRast)) != D3D_OK) { RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } if ((pDrawPrimData->ddrval = pRefRast->BeginRendering(pDrawPrimData->dwFVFControl)) != D3D_OK) { RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } } // Loop through the data, update render states
// and then draw the primitive
for (;;) { pDrawPrimitiveCounts = (LPD3DHAL_DRAWPRIMCOUNTS)pData; pData += sizeof(D3DHAL_DRAWPRIMCOUNTS);
// Update render states
if (pDrawPrimitiveCounts->wNumStateChanges > 0) { UINT32 StateType,StateValue; LPDWORD pStateChange = (LPDWORD)pData; INT i; for (i = 0; i < pDrawPrimitiveCounts->wNumStateChanges; i++) { StateType = *pStateChange; pStateChange ++; StateValue = *pStateChange; pStateChange ++; pRefRast->SetRenderState(StateType, StateValue); }
pData += pDrawPrimitiveCounts->wNumStateChanges * sizeof(DWORD) * 2; }
// Check for exit
if (pDrawPrimitiveCounts->wNumVertices == 0) { break; }
// Align pointer to vertex data
pData = (PUINT8) ((ULONG_PTR)(pData + (DP_VTX_ALIGN - 1)) & ~(DP_VTX_ALIGN - 1));
// The texture might changed
if (pDrawPrimitiveCounts->wNumStateChanges > 0) { RefRastUnlockTexture(pRefRast); if ((pDrawPrimData->ddrval=pRefRast->EndRendering()) != D3D_OK) { RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } if ((pDrawPrimData->ddrval=RefRastLockTexture(pRefRast)) != D3D_OK) { RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } if ((pDrawPrimData->ddrval = pRefRast->BeginRendering(pDrawPrimData->dwFVFControl)) != D3D_OK) { RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); return DDHAL_DRIVER_HANDLED; } }
// Draw primitives
pDrawPrimData->ddrval = DoDrawOnePrimitive(pRefRast, (UINT16)dwVStride, (PUINT8)pData, (D3DPRIMITIVETYPE) pDrawPrimitiveCounts->wPrimitiveType, pDrawPrimitiveCounts->wNumVertices); if (pDrawPrimData->ddrval != DD_OK) { goto EH_exit; }
pData += pDrawPrimitiveCounts->wNumVertices * dwVStride; }
EH_exit: hr = pRefRast->EndRendering(); RefRastUnlockTexture(pRefRast); RefRastUnlockTarget(pRefRast); if (pDrawPrimData->ddrval == D3D_OK) { pDrawPrimData->ddrval = hr; }
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastTextureCreate
//
// Creates a RefRast texture and initializes it with the info passed in.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastTextureCreate(LPD3DHAL_TEXTURECREATEDATA pTexData) { ReferenceRasterizer *pRefRast; RRTexture* pRRTex; HRESULT hr; LPDDRAWI_DDRAWSURFACE_LCL pLcl;
if (pTexData->lpDDS) { pLcl = ((LPDDRAWI_DDRAWSURFACE_INT)pTexData->lpDDS)->lpLcl; }
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastTextureCreate", pTexData);
// Runtime shouldnt be calling TextureCreate for DX7 and newer
// driver models
if ((pRefRast->IsInterfaceDX6AndBefore() == FALSE) && (pRefRast->IsDriverDX6AndBefore() == FALSE)) { pTexData->ddrval = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; }
// assume OKness
pTexData->ddrval = D3D_OK;
// Allocate RRTexture
if ( !(pRefRast->TextureCreate( (LPD3DTEXTUREHANDLE)&(pTexData->dwHandle), &pRRTex ) ) ) { pTexData->ddrval = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; }
// Init texturemap.
hr = pRRTex->Initialize( pLcl ); if (hr != D3D_OK) { pTexData->ddrval = hr; return DDHAL_DRIVER_HANDLED; }
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastTextureDestroy
//
// Destroy a RefRast texture.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastTextureDestroy(LPD3DHAL_TEXTUREDESTROYDATA pTexDestroyData) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastTextureDestroy", pTexDestroyData);
// Runtime shouldnt be Calling TextureCreate for DX7 and newer
// driver models
if ((pRefRast->IsInterfaceDX6AndBefore() == FALSE) && (pRefRast->IsDriverDX6AndBefore() == FALSE)) { pTexDestroyData->ddrval = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; }
if (!(pRefRast->TextureDestroy(pTexDestroyData->dwHandle))) { pTexDestroyData->ddrval = DDERR_GENERIC; } else { pTexDestroyData->ddrval = D3D_OK; }
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastTextureGetSurf
//
// Returns the surface pointer associate with a texture handle.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastTextureGetSurf(LPD3DHAL_TEXTUREGETSURFDATA pTexGetSurf) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastTextureGetSurf", pTexGetSurf);
pTexGetSurf->lpDDS = pRefRast->TextureGetSurf(pTexGetSurf->dwHandle); pTexGetSurf->ddrval = D3D_OK;
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastRenderPrimitive
//
// Called by Execute() for drawing primitives.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastRenderPrimitive(LPD3DHAL_RENDERPRIMITIVEDATA pRenderData) { ReferenceRasterizer *pRefRast; LPD3DINSTRUCTION pIns; LPD3DTLVERTEX pVtx; PUINT8 pData, pPrim;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastRenderPrimitive", pRenderData);
if (pRefRast->GetRenderState()[D3DRENDERSTATE_ZVISIBLE]) { pRenderData->dwStatus &= ~D3DSTATUS_ZNOTVISIBLE; pRenderData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
// Find out necessary data
pData = (PUINT8)(((LPDDRAWI_DDRAWSURFACE_INT) (pRenderData->lpExeBuf))->lpLcl->lpGbl->fpVidMem); pIns = &pRenderData->diInstruction; pPrim = pData + pRenderData->dwOffset; pVtx = (LPD3DTLVERTEX)((PUINT8)((LPDDRAWI_DDRAWSURFACE_INT) (pRenderData->lpTLBuf))->lpLcl->lpGbl->fpVidMem + pRenderData->dwTLOffset);
if ( (pRenderData->ddrval=RefRastLockTarget(pRefRast)) != D3D_OK ) { return DDHAL_DRIVER_HANDLED; } if ( (pRenderData->ddrval=RefRastLockTexture(pRefRast)) != D3D_OK ) { return DDHAL_DRIVER_HANDLED; } if ( (pRenderData->ddrval=pRefRast->BeginRendering(D3DFVF_TLVERTEX)) != D3D_OK ) { return DDHAL_DRIVER_HANDLED; }
// Render
switch (pIns->bOpcode) { case D3DOP_POINT: pRenderData->ddrval = DoRendPoints(pRefRast, pIns, pVtx, (LPD3DPOINT)pPrim); break; case D3DOP_LINE: pRenderData->ddrval = DoRendLines(pRefRast, pIns, pVtx, (LPD3DLINE)pPrim); break; case D3DOP_TRIANGLE: pRenderData->ddrval = DoRendTriangles(pRefRast, pIns, pVtx, (LPD3DTRIANGLE)pPrim); break; default: DPFM(0, DRV, ("(RefRast) Wrong Opcode passed to the new rasterizer.")); pRenderData->ddrval = DDERR_INVALIDPARAMS; break; }
HRESULT hr = pRefRast->EndRendering(); RefRastUnlockTarget(pRefRast); RefRastUnlockTexture(pRefRast); if (pRenderData->ddrval == D3D_OK) { pRenderData->ddrval = hr; }
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastRenderState
//
// Called by Execute() for setting render states.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastRenderState(LPD3DHAL_RENDERSTATEDATA pStateData) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
VALIDATE_REFRAST_CONTEXT("RefRastRenderState", pStateData);
PUINT8 pData; LPD3DSTATE pState; INT i; pData = (PUINT8) (((LPDDRAWI_DDRAWSURFACE_INT) (pStateData->lpExeBuf))->lpLcl->lpGbl->fpVidMem);
// Updates states
for (i = 0, pState = (LPD3DSTATE) (pData + pStateData->dwOffset); i < (INT)pStateData->dwCount; i ++, pState ++) { UINT32 type = (UINT32) pState->drstRenderStateType;
// Set the state
pRefRast->SetRenderState(type, pState->dwArg[0]); } return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastGetDriverState
//
// Called by the runtime to get any kind of driver information
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastGetDriverState(LPDDHAL_GETDRIVERSTATEDATA pGDSData) { ReferenceRasterizer *pRefRast;
// Check ReferenceRasterizer
#if DBG
if ((pGDSData) == NULL) { DPFM(0, DRV, ("in %s, data pointer = NULL", "RefRastGetDriverState")); return DDHAL_DRIVER_HANDLED; } pRefRast = (ReferenceRasterizer *)((pGDSData)->dwhContext); if (!pRefRast) { DPFM(0, DRV, ("in %s, dwhContext = NULL", "RefRastGetDriverState")); pGDSData->ddRVal = D3DHAL_CONTEXT_BAD; return DDHAL_DRIVER_HANDLED; } #else // !DBG
pRefRast = (ReferenceRasterizer *)((pGDSData)->dwhContext); #endif // !DBG
//
// No implementation yet, so nothing is understood yet
//
pGDSData->ddRVal = S_FALSE;
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastHalProvider::GetCaps/GetInterface
//
// Returns the reference rasterizer's HAL interface.
//
//----------------------------------------------------------------------------
extern D3DDEVICEDESC7 g_nullDevDesc;
static D3DHAL_CALLBACKS Callbacks = { sizeof(D3DHAL_CALLBACKS), RefRastContextCreate, RefRastContextDestroy, NULL, RefRastSceneCapture, NULL, NULL, RefRastRenderState, RefRastRenderPrimitive, NULL, RefRastTextureCreate, RefRastTextureDestroy, NULL, RefRastTextureGetSurf, // All others NULL.
};
static D3DHAL_CALLBACKS2 Callbacks2 = { sizeof(D3DHAL_CALLBACKS2), D3DHAL2_CB32_SETRENDERTARGET | D3DHAL2_CB32_DRAWONEPRIMITIVE | D3DHAL2_CB32_DRAWONEINDEXEDPRIMITIVE | D3DHAL2_CB32_DRAWPRIMITIVES, RefRastSetRenderTarget, NULL, RefRastDrawOnePrimitive, RefRastDrawOneIndexedPrimitive, RefRastDrawPrimitives };
static D3DHAL_CALLBACKS3 Callbacks3 = { sizeof(D3DHAL_CALLBACKS3), D3DHAL3_CB32_VALIDATETEXTURESTAGESTATE | D3DHAL3_CB32_DRAWPRIMITIVES2, NULL, // Clear2
NULL, // lpvReserved
RefRastValidateTextureStageState, RefRastDrawPrimitives2, // DrawVB
};
static D3DDEVICEDESC7 RefDevDesc = { 0 }; static D3DHAL_D3DEXTENDEDCAPS RefExtCaps;
static void FillOutDeviceCaps( BOOL bIsNullDevice ) { //
// set device description
//
RefDevDesc.dwDevCaps = D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT ;
RefDevDesc.dpcTriCaps.dwSize = sizeof(D3DPRIMCAPS); RefDevDesc.dpcTriCaps.dwMiscCaps = D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW ; RefDevDesc.dpcTriCaps.dwRasterCaps = D3DPRASTERCAPS_DITHER | // D3DPRASTERCAPS_ROP2 |
// D3DPRASTERCAPS_XOR |
// D3DPRASTERCAPS_PAT |
D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_SUBPIXELX | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | // D3DPRASTERCAPS_STIPPLE |
// D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT |
D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT | // D3DPRASTERCAPS_ANTIALIASEDGES |
D3DPRASTERCAPS_MIPMAPLODBIAS | // D3DPRASTERCAPS_ZBIAS |
// D3DPRASTERCAPS_ZBUFFERLESSHSR |
D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG; RefDevDesc.dpcTriCaps.dwZCmpCaps = D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS ; RefDevDesc.dpcTriCaps.dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT | D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA ; RefDevDesc.dpcTriCaps.dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT ; RefDevDesc.dpcTriCaps.dwAlphaCmpCaps = RefDevDesc.dpcTriCaps.dwZCmpCaps; RefDevDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD ; RefDevDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_COLORKEYBLEND; RefDevDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_NEAREST | D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFANISOTROPIC ; RefDevDesc.dpcTriCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_MODULATEALPHA | // D3DPTBLENDCAPS_DECALMASK |
// D3DPTBLENDCAPS_MODULATEMASK |
D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_ADD ; RefDevDesc.dpcTriCaps.dwTextureAddressCaps = D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV ; RefDevDesc.dpcTriCaps.dwStippleWidth = 0; RefDevDesc.dpcTriCaps.dwStippleHeight = 0;
// line caps - copy tricaps and modify
memcpy( &RefDevDesc.dpcLineCaps, &RefDevDesc.dpcTriCaps, sizeof(D3DPRIMCAPS) );
// disable antialias cap
RefDevDesc.dpcLineCaps.dwRasterCaps = D3DPRASTERCAPS_DITHER | // D3DPRASTERCAPS_ROP2 |
// D3DPRASTERCAPS_XOR |
// D3DPRASTERCAPS_PAT |
D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_SUBPIXELX | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | // D3DPRASTERCAPS_STIPPLE |
// D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT |
// D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT |
// D3DPRASTERCAPS_ANTIALIASEDGES |
D3DPRASTERCAPS_MIPMAPLODBIAS | // D3DPRASTERCAPS_ZBIAS |
// D3DPRASTERCAPS_ZBUFFERLESSHSR |
D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | // D3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT |
D3DPRASTERCAPS_WFOG;
RefDevDesc.dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32; RefDevDesc.dwDeviceZBufferBitDepth = DDBD_16 | DDBD_32;
// DX5 stuff (should be in sync with the extended caps reported below)
RefDevDesc.dwMinTextureWidth = 1; RefDevDesc.dwMaxTextureWidth = 4096; RefDevDesc.dwMinTextureHeight = 1; RefDevDesc.dwMaxTextureHeight = 4096;
//
// set extended caps
//
RefExtCaps.dwSize = sizeof(RefExtCaps);
RefExtCaps.dwMinTextureWidth = 1; RefExtCaps.dwMaxTextureWidth = 4096; RefExtCaps.dwMinTextureHeight = 1; RefExtCaps.dwMaxTextureHeight = 4096; RefExtCaps.dwMinStippleWidth = 0; // stipple unsupported
RefExtCaps.dwMaxStippleWidth = 0; RefExtCaps.dwMinStippleHeight = 0; RefExtCaps.dwMaxStippleHeight = 0;
RefExtCaps.dwMaxTextureRepeat = 32768; RefExtCaps.dwMaxTextureAspectRatio = 0; // no limit
RefExtCaps.dwMaxAnisotropy = 16;
RefExtCaps.dvGuardBandLeft = (bIsNullDevice) ? (-2048.f) : (-32768.f); RefExtCaps.dvGuardBandTop = (bIsNullDevice) ? (-2048.f) : (-32768.f); RefExtCaps.dvGuardBandRight = (bIsNullDevice) ? ( 2047.f) : ( 32767.f); RefExtCaps.dvGuardBandBottom = (bIsNullDevice) ? ( 2047.f) : ( 32767.f); RefExtCaps.dvExtentsAdjust = 0.; // AA kernel is 1.0 x 1.0
RefExtCaps.dwStencilCaps = D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE| D3DSTENCILCAPS_INCRSAT| D3DSTENCILCAPS_DECRSAT| D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR; RefExtCaps.dwFVFCaps = 8; // max number of tex coord sets
RefExtCaps.dwTextureOpCaps = D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2 | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X | D3DTEXOPCAPS_MODULATE4X | D3DTEXOPCAPS_ADD | D3DTEXOPCAPS_ADDSIGNED | D3DTEXOPCAPS_ADDSIGNED2X | D3DTEXOPCAPS_SUBTRACT | D3DTEXOPCAPS_ADDSMOOTH | D3DTEXOPCAPS_BLENDDIFFUSEALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHA | D3DTEXOPCAPS_BLENDFACTORALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHAPM | D3DTEXOPCAPS_BLENDCURRENTALPHA | D3DTEXOPCAPS_PREMODULATE | D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA | D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR | D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_BUMPENVMAPLUMINANCE | D3DTEXOPCAPS_DOTPRODUCT3 ; RefExtCaps.wMaxTextureBlendStages = 8; RefExtCaps.wMaxSimultaneousTextures = 8; RefExtCaps.dwMaxActiveLights = 0xffffffff; RefExtCaps.dvMaxVertexW = 1.0e10;
RefExtCaps.wMaxUserClipPlanes = RRMAX_USER_CLIPPLANES; RefExtCaps.wMaxVertexBlendMatrices = RRMAX_WORLD_MATRICES;
RefExtCaps.dwVertexProcessingCaps = (D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER); RefExtCaps.dwReserved1 = 0; RefExtCaps.dwReserved2 = 0; RefExtCaps.dwReserved3 = 0; RefExtCaps.dwReserved4 = 0; }
static D3DHAL_GLOBALDRIVERDATA RefDriverData;
static void DevDesc7ToDevDescV1( D3DDEVICEDESC_V1 *pOut, D3DDEVICEDESC7 *pIn ) {
// These fields are not available in D3DDEVICEDESC7.
// Zeroing them out, the front-end should not be using them
// DWORD dwFlags
// D3DCOLORMODEL dcmColorModel
// D3DTRANSFORMCAPS dtcTransformCaps
// BOOL bClipping
// D3DLIGHTINGCAPS dlcLightingCaps
// DWORD dwMaxBufferSize
// DWORD dwMaxVertexCount
// DWORD dwMinStippleWidth, dwMaxStippleWidth
// DWORD dwMinStippleHeight, dwMaxStippleHeight;
//
ZeroMemory( pOut, sizeof( D3DDEVICEDESC_V1 ) ); pOut->dwSize = sizeof( D3DDEVICEDESC_V1 );
// These are available in D3DDEVICEDESC7 so copy field by field
// to avoid any future problems based on the assumptions of size
pOut->dwDevCaps = pIn->dwDevCaps; pOut->dpcLineCaps = pIn->dpcLineCaps; pOut->dpcTriCaps = pIn->dpcTriCaps; pOut->dwDeviceRenderBitDepth = pIn->dwDeviceRenderBitDepth; pOut->dwDeviceZBufferBitDepth = pIn->dwDeviceZBufferBitDepth; }
static void DevDesc7ToDevDesc( D3DDEVICEDESC *pOut, D3DDEVICEDESC7 *pIn ) {
pOut->dwSize = sizeof( D3DDEVICEDESC );
// These fields are not available in D3DDEVICEDESC7.
// Setting them to some sensible values
pOut->dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS | D3DDD_LIGHTINGCAPS | D3DDD_BCLIPPING | D3DDD_LINECAPS | D3DDD_TRICAPS | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT ; pOut->dcmColorModel = D3DCOLOR_RGB; pOut->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS); pOut->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP; pOut->bClipping = TRUE; pOut->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS); pOut->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT | D3DLIGHTCAPS_DIRECTIONAL ; pOut->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB; pOut->dlcLightingCaps.dwNumLights = 0; pOut->dwMaxBufferSize = 0; pOut->dwMaxVertexCount = BASE_VERTEX_COUNT; pOut->dwMinStippleWidth = 0; pOut->dwMaxStippleWidth = 0; pOut->dwMinStippleHeight = 0; pOut->dwMaxStippleHeight = 0;
// These are available in D3DDEVICEDESC7 so copy field by field
// to avoid any future problems based on the assumptions of size
pOut->dwDevCaps = pIn->dwDevCaps; pOut->dpcLineCaps = pIn->dpcLineCaps; pOut->dpcTriCaps = pIn->dpcTriCaps; pOut->dwDeviceRenderBitDepth = pIn->dwDeviceRenderBitDepth; pOut->dwDeviceZBufferBitDepth = pIn->dwDeviceZBufferBitDepth; pOut->dwMinTextureWidth = pIn->dwMinTextureWidth; pOut->dwMinTextureHeight = pIn->dwMinTextureHeight; pOut->dwMaxTextureWidth = pIn->dwMaxTextureWidth; pOut->dwMaxTextureHeight = pIn->dwMaxTextureHeight; pOut->dwMaxTextureRepeat = pIn->dwMaxTextureRepeat; pOut->dwMaxTextureAspectRatio = pIn->dwMaxTextureAspectRatio; pOut->dwMaxAnisotropy = pIn->dwMaxAnisotropy; pOut->dvGuardBandLeft = pIn->dvGuardBandLeft; pOut->dvGuardBandTop = pIn->dvGuardBandTop; pOut->dvGuardBandRight = pIn->dvGuardBandRight; pOut->dvGuardBandBottom = pIn->dvGuardBandBottom; pOut->dvExtentsAdjust = pIn->dvExtentsAdjust; pOut->dwStencilCaps = pIn->dwStencilCaps; pOut->dwFVFCaps = pIn->dwFVFCaps; pOut->dwTextureOpCaps = pIn->dwTextureOpCaps; pOut->wMaxTextureBlendStages = pIn->wMaxTextureBlendStages; pOut->wMaxSimultaneousTextures = pIn->wMaxSimultaneousTextures; }
STDMETHODIMP RefRastHalProvider::GetInterface(THIS_ LPDDRAWI_DIRECTDRAW_GBL pDdGbl, LPD3DHALPROVIDER_INTERFACEDATA pInterfaceData, DWORD dwVersion) { // fill out device description & extended caps
FillOutDeviceCaps(FALSE); // add extended caps to RefDevDesc
D3DDeviceDescConvert(&RefDevDesc,NULL,&RefExtCaps);
// fill out GLOBALDRIVERDATA (initially zero)
RefDriverData.dwSize = sizeof(RefDriverData);
//
// Need to fix up RefDriverData.hwCaps (D3DDEVICEDESC) from
// rgbDevDesc (D3DDEVICEDESC7)
//
DevDesc7ToDevDescV1( &RefDriverData.hwCaps, &RefDevDesc );
RefDriverData.dwNumVertices = BASE_VERTEX_COUNT; RefDriverData.dwNumClipVertices = MAX_CLIP_VERTICES; RefDriverData.dwNumTextureFormats = GetRefTextureFormats(IID_IDirect3DRefDevice, &RefDriverData.lpTextureFormats, dwVersion);
// set interface data for return
pInterfaceData->pGlobalData = &RefDriverData; pInterfaceData->pExtCaps = &RefExtCaps; pInterfaceData->pCallbacks = &Callbacks; pInterfaceData->pCallbacks2 = &Callbacks2; pInterfaceData->pCallbacks3 = &Callbacks3;
//
// This dwVersion==4 corresponds to DX7+
// This HalProvider interface is a hack to enable sw-drivers to
// behave like hw-hals hence this mysteriousness!
//
if( dwVersion >= 4 ) { pInterfaceData->pfnGetDriverState = RefRastGetDriverState; }
return S_OK; }
STDMETHODIMP RefRastHalProvider::GetCaps(THIS_ LPDDRAWI_DIRECTDRAW_GBL pDdGbl, LPD3DDEVICEDESC7 pHwDesc, LPD3DDEVICEDESC7 pHelDesc, DWORD dwVersion) { // fill out device description & extended caps
FillOutDeviceCaps(FALSE); // add extended caps to RefDevDesc
D3DDeviceDescConvert(&RefDevDesc,NULL,&RefExtCaps);
//
// This dwVersion==4 corresponds to DX7+
// This HalProvider interface is a hack to enable sw-drivers to
// behave like hw-hals hence this mysteriousness!
//
if (dwVersion < 4) { ZeroMemory( pHwDesc, sizeof( D3DDEVICEDESC )); ((D3DDEVICEDESC *)pHwDesc)->dwSize = sizeof( D3DDEVICEDESC ); DevDesc7ToDevDesc( (D3DDEVICEDESC *)pHelDesc, &RefDevDesc ); } else { memcpy(pHwDesc, &g_nullDevDesc, sizeof(D3DDEVICEDESC7)); memcpy(pHelDesc, &RefDevDesc, sizeof(D3DDEVICEDESC7)); } return D3D_OK; }
//----------------------------------------------------------------------------
//
// Null Device implementation section
//
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// NullDeviceContextCreate
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceContextCreate(LPD3DHAL_CONTEXTCREATEDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceContextDestroy
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceContextDestroy(LPD3DHAL_CONTEXTDESTROYDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceSceneCapture
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceSceneCapture(LPD3DHAL_SCENECAPTUREDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceSetRenderTarget
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceSetRenderTarget(LPD3DHAL_SETRENDERTARGETDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceDrawOneIndexedPrimitive
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceDrawOneIndexedPrimitive(LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceDrawOnePrimitive
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceDrawOnePrimitive(LPD3DHAL_DRAWONEPRIMITIVEDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceDrawPrimitives
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceDrawPrimitives(LPD3DHAL_DRAWPRIMITIVESDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceDrawPrimitives2
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceDrawPrimitives2(LPD3DHAL_DRAWPRIMITIVES2DATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceTextureCreate
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceTextureCreate(LPD3DHAL_TEXTURECREATEDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceTextureDestroy
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceTextureDestroy(LPD3DHAL_TEXTUREDESTROYDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceTextureGetSurf
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceTextureGetSurf(LPD3DHAL_TEXTUREGETSURFDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceRenderPrimitive
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceRenderPrimitive(LPD3DHAL_RENDERPRIMITIVEDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceRenderState
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceRenderState(LPD3DHAL_RENDERSTATEDATA pData) { pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
// NullDeviceValidateTextureStageState
//----------------------------------------------------------------------------
DWORD __stdcall NullDeviceValidateTextureStageState(LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA pData) { pData->dwNumPasses = 1; pData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// NullDeviceHalProvider::GetCaps/GetInterface
//
// Returns the null device's HAL interface.
// RefRast's caps are reflected by this device. Only the actual callbacks
// are different.
//----------------------------------------------------------------------------
static D3DHAL_CALLBACKS NullCallbacks = { sizeof(D3DHAL_CALLBACKS), NullDeviceContextCreate, NullDeviceContextDestroy, NULL, NullDeviceSceneCapture, NULL, NULL, NullDeviceRenderState, NullDeviceRenderPrimitive, NULL, NullDeviceTextureCreate, NullDeviceTextureDestroy, NULL, NullDeviceTextureGetSurf, // All others NULL.
};
static D3DHAL_CALLBACKS2 NullCallbacks2 = { sizeof(D3DHAL_CALLBACKS2), D3DHAL2_CB32_SETRENDERTARGET | D3DHAL2_CB32_DRAWONEPRIMITIVE | D3DHAL2_CB32_DRAWONEINDEXEDPRIMITIVE | D3DHAL2_CB32_DRAWPRIMITIVES, NullDeviceSetRenderTarget, NULL, NullDeviceDrawOnePrimitive, NullDeviceDrawOneIndexedPrimitive, NullDeviceDrawPrimitives };
static D3DHAL_CALLBACKS3 NullCallbacks3 = { sizeof(D3DHAL_CALLBACKS3), D3DHAL3_CB32_VALIDATETEXTURESTAGESTATE | D3DHAL3_CB32_DRAWPRIMITIVES2, NULL, // Clear2
NULL, // lpvReserved
NullDeviceValidateTextureStageState, NullDeviceDrawPrimitives2, };
STDMETHODIMP NullDeviceHalProvider::GetInterface(THIS_ LPDDRAWI_DIRECTDRAW_GBL pDdGbl, LPD3DHALPROVIDER_INTERFACEDATA pInterfaceData, DWORD dwVersion) { // fill out device description & extended caps
FillOutDeviceCaps(TRUE); // add extended caps to RefDevDesc
D3DDeviceDescConvert(&RefDevDesc,NULL,&RefExtCaps);
// fill out GLOBALDRIVERDATA (initially zero)
RefDriverData.dwSize = sizeof(RefDriverData);
DevDesc7ToDevDescV1( &RefDriverData.hwCaps, &RefDevDesc );
RefDriverData.dwNumVertices = BASE_VERTEX_COUNT; RefDriverData.dwNumClipVertices = MAX_CLIP_VERTICES; RefDriverData.dwNumTextureFormats = GetRefTextureFormats(IID_IDirect3DNullDevice, &RefDriverData.lpTextureFormats, dwVersion);
// set interface data for return
pInterfaceData->pGlobalData = &RefDriverData; pInterfaceData->pExtCaps = &RefExtCaps; pInterfaceData->pCallbacks = &NullCallbacks; pInterfaceData->pCallbacks2 = &NullCallbacks2; pInterfaceData->pCallbacks3 = &NullCallbacks3;
return S_OK; }
STDMETHODIMP NullDeviceHalProvider::GetCaps(THIS_ LPDDRAWI_DIRECTDRAW_GBL pDdGbl, LPD3DDEVICEDESC7 pHwDesc, LPD3DDEVICEDESC7 pHelDesc, DWORD dwVersion) { *pHwDesc = g_nullDevDesc;
// fill out device description & extended caps
FillOutDeviceCaps(TRUE); // add extended caps to RefDevDesc
D3DDeviceDescConvert(&RefDevDesc,NULL,&RefExtCaps);
//
// This dwVersion==4 corresponds to DX7+
// This HalProvider interface is a hack to enable sw-drivers to
// behave like hw-hals hence this mysteriousness!
//
if (dwVersion < 4) { ZeroMemory( pHwDesc, sizeof( D3DDEVICEDESC )); ((D3DDEVICEDESC *)pHwDesc)->dwSize = sizeof( D3DDEVICEDESC ); DevDesc7ToDevDesc( (D3DDEVICEDESC *)pHelDesc, &RefDevDesc ); } else { memcpy(pHwDesc, &g_nullDevDesc, sizeof(D3DDEVICEDESC7)); memcpy(pHelDesc, &RefDevDesc, sizeof(D3DDEVICEDESC7)); } return D3D_OK; }
|