Leaked source code of windows server 2003
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.
 
 
 
 
 
 

2159 lines
70 KiB

//----------------------------------------------------------------------------
//
// 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;
}