|
|
//----------------------------------------------------------------------------
//
// refrastfn.cpp
//
// Reference rasterizer callback functions for D3DIM.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
// The DDI refrast is emulating
RDDDITYPE g_RefDDI;
// All the supported texture formats
DDSURFACEDESC g_ddsdTex[RD_MAX_NUM_TEXTURE_FORMATS];
// The current caps8 for newly created devices
static D3DCAPS8 g_RefCaps8;
// Maps D3DMULTISAMPLE_TYPE into the bit to use for the flags.
// Maps each of the multisampling values (2 to 16) to the bits[1] to bits[15]
// of wBltMSTypes and wFlipMSTypes
#define DDI_MULTISAMPLE_TYPE(x) (1 << ((x)-1))
//----------------------------------------------------------------------------
//
// RefRastUpdatePalettes
//
//----------------------------------------------------------------------------
HRESULT RefRastUpdatePalettes(RefDev *pRefDev) { INT i, j, k; RDSurface2D* pRDTex[D3DHAL_TSS_MAXSTAGES]; D3DTEXTUREHANDLE phTex[D3DHAL_TSS_MAXSTAGES]; HRESULT hr; int cActTex;
if ((cActTex = pRefDev->GetCurrentTextureMaps(phTex, pRDTex)) == 0) { return D3D_OK; }
for (j = 0; j < cActTex; j++) { // stages may not have texture bound
if ( NULL == pRDTex[j] ) continue; pRDTex[j]->UpdatePalette(); }
return D3D_OK;
}
//----------------------------------------------------------------------------
//
// RDRenderTarget::Initialize
//
// Converts color and Z surface information into refrast form.
//
//----------------------------------------------------------------------------
HRESULT RDRenderTarget::Initialize( LPDDRAWI_DDRAWSURFACE_LCL pLclColor, LPDDRAWI_DDRAWSURFACE_LCL pLclZ ) { HRESULT hr; RDSurfaceFormat ColorFmt; RDSurfaceFormat ZFmt; RDSurface2D* pOldColor = m_pColor; RDSurface2D* pOldDepth = m_pDepth;
if( m_pColor ) { m_pColor = NULL; } if( m_pDepth ) { m_pDepth = NULL; }
// Find the surfaces from the global surface manager
// We are assuming that CreateSurfaceEx has been called on these
// surfaces before this.
RDSurface2D* pColor = m_pColor = new RDSurface2D; if( pColor == NULL ) { DPFERR( "Color surface could not be allocated" ); m_pColor = pOldColor; m_pDepth = pOldDepth; return DDERR_OUTOFMEMORY; } if( FAILED( hr = pColor->Initialize( pLclColor ) ) ) { DPFERR( "Unable to initialize the color buffer" ); delete pColor; m_pColor = pOldColor; m_pDepth = pOldDepth; return hr; }
if (NULL != pLclZ) { RDSurface2D* pDepth = m_pDepth = new RDSurface2D; if( pDepth == NULL ) { DPFERR( "Depth surface could not be allocated" ); delete pColor; m_pColor = pOldColor; m_pDepth = pOldDepth; return DDERR_OUTOFMEMORY; } if( FAILED( hr = pDepth->Initialize( pLclZ ) ) ) { DPFERR("Unable to initialize the Depth buffer"); delete pColor; delete pDepth; m_pColor = pOldColor; m_pDepth = pOldDepth; return hr; } }
m_Clip.left = 0; m_Clip.top = 0; m_Clip.bottom = pColor->GetHeight() - 1; m_Clip.right = pColor->GetWidth() - 1;
m_bPreDX7DDI = TRUE; delete pOldColor; delete pOldDepth; return D3D_OK; }
//----------------------------------------------------------------------------
//
// RDRenderTarget::Initialize
//
// Converts color and Z surface information into refrast form.
//
//----------------------------------------------------------------------------
HRESULT RDRenderTarget::Initialize( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, LPDDRAWI_DDRAWSURFACE_LCL pLclColor, LPDDRAWI_DDRAWSURFACE_LCL pLclZ ) { HRESULT hr; RDSurfaceFormat ColorFmt; RDSurfaceFormat ZFmt; RDSurface2D* pOldColor = m_pColor; RDSurface2D* pOldDepth = m_pDepth;
if( m_pColor ) { m_pColor = NULL; } if( m_pDepth ) { m_pDepth = NULL; }
// Find the surfaces from the global surface manager
// We are assuming that CreateSurfaceEx has been called on these
// surfaces before this.
DWORD dwColorHandle = pLclColor->lpSurfMore->dwSurfaceHandle; RDSurface2D* pColor = m_pColor = (RDSurface2D *)g_SurfMgr.GetSurfFromList( pDDLcl, dwColorHandle); if( pColor == NULL ) { DPFERR("Color surface not found"); m_pColor = pOldColor; m_pDepth = pOldDepth; return DDERR_INVALIDPARAMS; }
if (NULL != pLclZ) { DWORD dwDepthHandle = pLclZ->lpSurfMore->dwSurfaceHandle; RDSurface2D* pDepth = m_pDepth = (RDSurface2D *)g_SurfMgr.GetSurfFromList( pDDLcl, dwDepthHandle); if( pDepth == NULL ) { DPFERR("Depth surface not found"); m_pColor = pOldColor; m_pDepth = pOldDepth; return DDERR_INVALIDPARAMS; } }
m_Clip.left = 0; m_Clip.top = 0; m_Clip.bottom = pColor->GetHeight() - 1; m_Clip.right = pColor->GetWidth() - 1;
return D3D_OK; }
//----------------------------------------------------------------------------
//
// RDRenderTarget::Initialize
//
// Converts color and Z surface information into refrast form.
//
//----------------------------------------------------------------------------
HRESULT RDRenderTarget::Initialize( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, DWORD dwColorHandle, DWORD dwDepthHandle ) { HRESULT hr; RDSurfaceFormat ColorFmt; RDSurfaceFormat ZFmt; RDSurface2D* pOldColor = m_pColor; RDSurface2D* pOldDepth = m_pDepth;
// Release objects we hold pointers to
if( m_pColor ) { m_pColor = NULL; } if( m_pDepth ) { m_pDepth = NULL; }
// Find the surfaces from the global surface manager
// We are assuming that CreateSurfaceEx has been called on these
// surfaces before this.
RDSurface2D* pColor = m_pColor = (RDSurface2D *)g_SurfMgr.GetSurfFromList( pDDLcl, dwColorHandle); if( pColor == NULL ) { DPFERR("Color surface not found"); m_pColor = pOldColor; m_pDepth = pOldDepth; return DDERR_INVALIDPARAMS; }
if (0 != dwDepthHandle) { RDSurface2D* pDepth = m_pDepth = (RDSurface2D *)g_SurfMgr.GetSurfFromList( pDDLcl, dwDepthHandle); if( pDepth == NULL ) { DPFERR("Depth surface not found"); m_pColor = pOldColor; m_pDepth = pOldDepth; return DDERR_INVALIDPARAMS; } }
m_Clip.left = 0; m_Clip.top = 0; m_Clip.bottom = pColor->GetHeight() - 1; m_Clip.right = pColor->GetWidth() - 1;
return D3D_OK; }
//----------------------------------------------------------------------------
//
// RefRastContextCreate
//
// Creates a RefDev and initializes it with the info passed in.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastContextCreate(LPD3DHAL_CONTEXTCREATEDATA pCtxData) { RefDev *pRefDev; RDRenderTarget *pRendTgt; INT i;
// 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 RDRenderTarget()) == NULL) { pCtxData->ddrval = DDERR_OUTOFMEMORY; return DDHAL_DRIVER_HANDLED; }
// If it is expected to be a DX7+ driver
if (g_RefDDI < RDDDI_DX7HAL) { if (pCtxData->lpDDS) pColorLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pCtxData->lpDDS))->lpLcl; if (pCtxData->lpDDSZ) pZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pCtxData->lpDDSZ))->lpLcl;
// Collect surface information where the failures are easy to handle.
pCtxData->ddrval = pRendTgt->Initialize( pColorLcl, pZLcl ); } else { pColorLcl = pCtxData->lpDDSLcl; pZLcl = pCtxData->lpDDSZLcl;
// Collect surface information where the failures are easy to handle.
pCtxData->ddrval = pRendTgt->Initialize( pCtxData->lpDDLcl, pColorLcl, pZLcl ); }
if (pCtxData->ddrval != D3D_OK) { delete pRendTgt; return DDHAL_DRIVER_HANDLED; }
// Note:
// dwhContext is used by the runtime to inform the driver, which
// d3d interface is calling the driver.
if ( ( pRefDev = new RefDev( pCtxData->lpDDLcl, (DWORD)(pCtxData->dwhContext), g_RefDDI, &g_RefCaps8 ) ) == NULL ) { pCtxData->ddrval = DDERR_OUTOFMEMORY; return DDHAL_DRIVER_HANDLED; }
pRefDev->SetRenderTarget( pRendTgt );
// return RR object pointer as context handle
pCtxData->dwhContext = (ULONG_PTR)pRefDev;
pCtxData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastContextDestroy
//
// Destroy a RefDev.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastContextDestroy(LPD3DHAL_CONTEXTDESTROYDATA pCtxDestroyData) { RefDev *pRefDev;
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastContextDestroy", pCtxDestroyData);
// Clean up override bits
RDRenderTarget *pRendTgt = pRefDev->GetRenderTarget(); if ( NULL != pRendTgt ) { delete pRendTgt; }
delete pRefDev;
pCtxDestroyData->ddrval = D3D_OK; return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastSceneCapture
//
// Pass scene capture callback to ref rast.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastSceneCapture(LPD3DHAL_SCENECAPTUREDATA pData) { RefDev *pRefDev;
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastSceneCapture", pData);
pRefDev->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) { RefDev *pRefDev; LPDDRAWI_DDRAWSURFACE_LCL pZLcl = NULL; LPDDRAWI_DDRAWSURFACE_LCL pColorLcl = NULL; HRESULT ret;
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastSetRenderTarget", pTgtData);
_ASSERT( pRefDev->IsDriverDX6AndBefore(), "This callback should" "never be called on DDIs DX7 and beyond" )
_ASSERT( pRefDev->IsInterfaceDX6AndBefore(), "An older interface should" "never call this DLL" )
RDRenderTarget *pRendTgt = pRefDev->GetRenderTarget(); if ( NULL == pRendTgt ) { return DDHAL_DRIVER_HANDLED; }
if( pTgtData->lpDDS ) pColorLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pTgtData->lpDDS))->lpLcl; if( pTgtData->lpDDSZ ) pZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)(pTgtData->lpDDSZ))->lpLcl;
// Collect surface information.
pTgtData->ddrval = pRendTgt->Initialize( pColorLcl, pZLcl); if (pTgtData->ddrval != D3D_OK) { return DDHAL_DRIVER_HANDLED; }
pRefDev->SetRenderTarget(pRendTgt);
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastValidateTextureStageState
//
// Validate current blend operations. RefRast does everything.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastValidateTextureStageState(LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA pData) { RefDev *pRefDev;
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastValidateTextureStageState", pData);
pData->dwNumPasses = 1; pData->ddrval = D3D_OK;
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastTextureCreate
//
// Creates a RefRast texture and initializes it with the info passed in.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastTextureCreate(LPD3DHAL_TEXTURECREATEDATA pTexData) { RefDev *pRefDev; RDSurface2D* pRDTex; HRESULT hr; LPDDRAWI_DDRAWSURFACE_LCL pLcl;
if (pTexData->lpDDS) { pLcl = ((LPDDRAWI_DDRAWSURFACE_INT)pTexData->lpDDS)->lpLcl; }
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastTextureCreate", pTexData);
// Runtime shouldnt be calling TextureCreate for DX7 and newer
// driver models
_ASSERT( pRefDev->IsDriverDX6AndBefore(), "This DDI should not" "be called from DDIs previous to DX7" );
// assume OKness
pTexData->ddrval = D3D_OK;
// Allocate RDSurface2D
if ( !(pRefDev->TextureCreate( (LPD3DTEXTUREHANDLE)&(pTexData->dwHandle), &pRDTex ) ) ) { pTexData->ddrval = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; }
// Init texturemap.
hr = pRDTex->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) { RefDev *pRefDev;
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastTextureDestroy", pTexDestroyData);
// Runtime shouldnt be Calling TextureCreate for DX7 and newer
// driver models
_ASSERT( pRefDev->IsDriverDX6AndBefore(), "This DDI should not" "be called from DDIs previous to DX7" );
if (!(pRefDev->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) { RefDev *pRefDev;
// Check RefDev
VALIDATE_REFRAST_CONTEXT("RefRastTextureGetSurf", pTexGetSurf);
pTexGetSurf->lpDDS = pRefDev->TextureGetSurf(pTexGetSurf->dwHandle); pTexGetSurf->ddrval = D3D_OK;
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastGetDriverState
//
// Called by the runtime to get any kind of driver information
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastGetDriverState(LPDDHAL_GETDRIVERSTATEDATA pGDSData) { RefDev *pRefDev;
// Check RefDev
#if DBG
if ((pGDSData) == NULL) { DPFERR("in %s, data pointer = NULL", "RefRastGetDriverState"); return DDHAL_DRIVER_HANDLED; } pRefDev = (RefDev *)ULongToPtr((pGDSData)->dwhContext); if (!pRefDev) { DPFERR("in %s, dwhContext = NULL", "RefRastGetDriverState"); pGDSData->ddRVal = D3DHAL_CONTEXT_BAD; return DDHAL_DRIVER_HANDLED; } #else // !DBG
pRefDev = (RefDev *)ULongToPtr((pGDSData)->dwhContext); #endif // !DBG
//
// No implementation yet, so nothing is understood yet
//
pGDSData->ddRVal = S_FALSE;
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// FindAttachedSurfaceCaps2
//
// Walks the attachment list for the surface, looking for an attachment
// that has any of the dwCaps2 bits (or ignores if zero) and none of the
// FindAttachedSurfaceCaps2NotPresent bits.
//
//----------------------------------------------------------------------------
LPDDRAWI_DDRAWSURFACE_LCL FindAttachedSurfaceCaps2( LPDDRAWI_DDRAWSURFACE_LCL pLcl, DWORD dwCaps2) { LPATTACHLIST lpAttachStruct = pLcl->lpAttachList; while(lpAttachStruct) { if ((dwCaps2 == 0) || (lpAttachStruct->lpAttached->lpSurfMore->ddsCapsEx.dwCaps2 & dwCaps2)) return lpAttachStruct->lpAttached; lpAttachStruct = lpAttachStruct->lpLink; }
return 0; }
//----------------------------------------------------------------------------
//
// ProcessPossibleMipMap
//
// Record private data structure for this surface and all attached mip
// sublevels.
//
//----------------------------------------------------------------------------
void ProcessPossibleMipMap( LPDDHAL_CREATESURFACEEXDATA p, LPDDRAWI_DDRAWSURFACE_LCL lpDDSMipLcl ) { do { // This function should not deal with deletions. Assert this.
_ASSERT( SURFACE_MEMORY(lpDDSMipLcl), "Delete should have already taken place" );
p->ddRVal = g_SurfMgr.AddSurfToList( p->lpDDLcl, lpDDSMipLcl, NULL ); if (FAILED(p->ddRVal)) return;
// Now search down the 2nd+ order attachment: the chain
// of mip sublevels.
lpDDSMipLcl = FindAttachedSurfaceCaps2(lpDDSMipLcl, DDSCAPS2_MIPMAPSUBLEVEL); } while (lpDDSMipLcl); }
//----------------------------------------------------------------------------
//
// RefRastCreateSurfaceEx
//
// Refrast implementation of CreateSurfaceEx. g_SurfMgr is the object
// that does the real job.
//
// CreateSurfaceEx is also used to inform the driver to create and destroy
// surface representations for a given handle. The way the driver can tell
// the difference between create and destroy is by looking at the fpVidmem
// pointer of the passed local. If it is null, it is a destroy.
//
// Create: This call is atomic. i.e. the attachments are all done by the
// runtime. The driver is expected to walk through the attachment and
// form its internal picture as described below.
// For complex surfaces (mipped textures, cubemaps), we need to record an
// internal representation for the top-level surface that includes all
// sub-surfaces. This is because the handle associated with the top-level
// surface is what's passed to SetTextureStage.
// However, we also need entries in our list that allow us to set any
// of the sublevels as render targets. Thus this top-level routine iterates
// across the entire attachment graph (to accomodate SRT on any subsurface)
// and the lower-level routine (RDSurface2D::Initialize) also iterates across
// the whole graph (to accomodate SetTexture on the top-level).
// A flipping chain is another structure that needs SRT to work on all
// contained surfaces.
//
// Destroy: The destruction unfortunately is not atomic. The driver gets
// the call to destroy per sub-level. The attachment has no meaning
// at this time, so the driver should only delete the level being
// referred to.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastCreateSurfaceEx(LPDDHAL_CREATESURFACEEXDATA p) { #if DBG
if( p == NULL ) { DPFERR("CreateSurfaceExData ptr is NULL"); return DDHAL_DRIVER_HANDLED; } if( p->lpDDLcl == NULL || p->lpDDSLcl == NULL ) { DPFERR("DDLcl or the DDSLcl ptr is NULL"); return DDHAL_DRIVER_HANDLED; } #endif
LPDDRAWI_DDRAWSURFACE_LCL lpDDSLcl = p->lpDDSLcl; p->ddRVal = DD_OK;
//
// Is it a Delete call ? If so simply delete the surface-rep associated
// with this local and dont walk the local chain.
//
if( 0 == SURFACE_MEMORY(lpDDSLcl) ) { g_SurfMgr.RemoveSurfFromList( p->lpDDLcl, lpDDSLcl ); return DDHAL_DRIVER_HANDLED; }
ProcessPossibleMipMap(p, lpDDSLcl);
//Now we have two possibilities: cubemap or flipping chain.
// Check cube map first:
//+ve X is always the first face
// (Note a DX7 driver would have to handle cubes w/o the +X face (since DX7
// cubes may have any set of faces missing).)
if (lpDDSLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX) { //Go find each attached cubemap face and process it as a mipmap
for (int i=1;i<6;i++) { DWORD dwCaps2=0; switch(i) { case 1: dwCaps2 = DDSCAPS2_CUBEMAP_NEGATIVEX; break; case 2: dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEY; break; case 3: dwCaps2 = DDSCAPS2_CUBEMAP_NEGATIVEY; break; case 4: dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEZ; break; case 5: dwCaps2 = DDSCAPS2_CUBEMAP_NEGATIVEZ; break; }
//Find the top-level faces attached to the root
//(there will be no mip sublevel of any of these five types
//attached to the root).
lpDDSLcl = FindAttachedSurfaceCaps2(p->lpDDSLcl, dwCaps2); if (lpDDSLcl) ProcessPossibleMipMap(p, lpDDSLcl); } } else if ( 0==(lpDDSLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP) && 0 != lpDDSLcl->lpAttachList) { //just assert that we're not handling some of the other types
//we know are passed to CSEx.
_ASSERT(0==(lpDDSLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE), "CSEx for an attached texture?"); _ASSERT(0==(lpDDSLcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER), "CSEx for an attached execute buffer?");
// We processed mipmaps above, so either there will be no
// more attachments (aside from the mipsublevels), or it's
// a flipping chain.
// The first member of the chain was processed above.
// Npw we look around the ring, terminating when we hit the first surface
// again.
//
// NOTE: DX8 software drivers will only ever see a chain, not a ring.
// This code terminates at the end of the chain.
//
// A real driver may have to check for attached Z surfaces
// here, as well as stereo left surfaces.
lpDDSLcl = lpDDSLcl->lpAttachList->lpAttached; _ASSERT(lpDDSLcl, "Bad attachment List");
while (lpDDSLcl && lpDDSLcl != p->lpDDSLcl) //i.e. not the first surface again
{ //We just reuse the "ProcessPossibleMipmap" function, and
//assert that it will not have to traverse a mipmap here.
_ASSERT(0==(lpDDSLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP), "Flipping chains should not be mipmaps");
ProcessPossibleMipMap(p, lpDDSLcl);
//This is the termination condition we expect for DX8 software
//drivers.
if (0 == lpDDSLcl->lpAttachList) { lpDDSLcl = 0; break; }
lpDDSLcl = lpDDSLcl->lpAttachList->lpAttached;
_ASSERT(lpDDSLcl, "Bad attachment List"); } } // else we drop through and do no further attachment list processing
// (typically on mipmaps or execute buffers).
return DDHAL_DRIVER_HANDLED; }
extern HRESULT FASTCALL FindOutSurfFormat(LPDDPIXELFORMAT pDdPixFmt, RDSurfaceFormat* pFmt, BOOL* pbIsDepth);
//----------------------------------------------------------------------------
//
// RefRastCreateSurface
//
// Create a requested surface. Fake VIDMEM allocation.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastCreateSurface(LPDDHAL_CREATESURFACEDATA pData) { LPDDRAWI_DDRAWSURFACE_LCL pSLcl = NULL; LPDDRAWI_DDRAWSURFACE_GBL pSGbl = NULL; LPDDRAWI_DDRAWSURFACE_MORE pSMore = NULL; DWORD dwBytesPerPixel = 0; DWORD dwBytesInVB = 0; DWORD dwNumBytes = 0; DWORD dwPitch = 0; DWORD dwSlicePitch = 0; DWORD i = 0, j = 0; BYTE* pBits = NULL; BOOL isDXT = FALSE; UINT MultiSampleCount; DWORD dwMultiSamplePitch = 0; BYTE* pMultiSampleBits = NULL; DWORD dwNumMultiSampleBytes = 0; HRESULT hr = S_OK;
pData->ddRVal = DD_OK;
//
// Validation
//
// The surface count
if( pData->dwSCnt < 1 ) { DPFERR("At least one surface should be created"); pData->ddRVal = E_FAIL; return DDHAL_DRIVER_HANDLED; }
// Primary surface cannot be handled here
if( pData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE ) { DPFERR("Refrast cannot allocate Primary surface"); pData->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; }
// Only Vidmem or Driver Managed allocations are handled here
if(((pData->lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM)) == 0) && ((pData->lplpSList[0]->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE) == 0)) { DPFERR("Refrast can only allocate Vidmem or DriverManaged surfaces"); pData->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; }
// Dont allocate if the width or the height is not provided
if( (pData->lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT )) != (DDSD_WIDTH | DDSD_HEIGHT ) ) { DPFERR("No size provided for the surface"); pData->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; }
// Currently, allocation takes place only if a pixel format is provided
if( pData->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT ) { dwBytesPerPixel = (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount >> 3);
// For FourCCs, we need to explicitly indicate the bytes per pixel
if ((dwBytesPerPixel == 0) && (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)) { if( IsYUV( pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC ) ) { dwBytesPerPixel = 2; } else if( IsDXTn( pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC ) ) { dwBytesPerPixel = 1; isDXT = TRUE; } // All the new surface formats (introduced after DX7) are marked as
// 4CC. Technically they are not 4CC, that field is overloaded to
// mean the new DX8 style format ID.
else if( (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == 0xFF000004) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_Q8W8V8U8) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_V16U16) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD) D3DFMT_W11V11U10) || // Formats introduced in DX8.1
(pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_A2B10G10R10) || #if 0
(pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_A8B8G8R8) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_X8B8G8R8) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_W10V11U11) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_A8X8V8U8) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_L8X8V8U8) || #endif
(pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_G16R16) || (pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC == (DWORD)D3DFMT_A2W10V10U10) ) { // Private new format
dwBytesPerPixel = 4; } } } else if( pData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER ) { dwBytesInVB = ((LPDDSURFACEDESC2)(pData->lpDDSurfaceDesc))->dwWidth; } else { // Note: for DX8 drivers, this case should never be encountered.
// In the future, if RefDev is revamped to work with legacy interfaces
// then this case needs to something real instead of failing:
// If the pixel-formats are not provided, then the current primary
// format should be assumed.
DPFERR( "Refrast can only allocate if PixelFormat is provided" ); pData->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; }
//
// Allocate the memory and compute the Pitch for every surface on the
// list.
//
// We should be guaranteed that this is the same for all surfaces in the
// list
MultiSampleCount = 0xf & (pData->lplpSList[0]->lpSurfMore->ddsCapsEx.dwCaps3);
//This will be the case on older than DX8 runtimes
if (MultiSampleCount == 0) { MultiSampleCount = 1; }
for( i = 0; i < pData->dwSCnt; i++ ) { RDCREATESURFPRIVATE* pPriv = NULL;
pSLcl = pData->lplpSList[i]; pSGbl = pSLcl->lpGbl; pSMore = pSLcl->lpSurfMore; DWORD dwHeight = pSGbl->wHeight;
// If already allocated, just return
if( pSGbl->fpVidMem || pSGbl->dwReserved1 ) { DPFERR("Surface has already been allocated"); pData->ddRVal = E_FAIL; break; }
// Figure out if it is a vertex buffer
if( dwBytesInVB ) { dwNumBytes = dwBytesInVB; dwPitch = dwBytesInVB; } else { // Figure out the pitch and allocate
switch( pData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC ) { case MAKEFOURCC('D', 'X', 'T', '1'): dwMultiSamplePitch = (MultiSampleCount * ((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[0] + 7) & ~7; dwPitch = (((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[0] + 7) & ~7; dwHeight = ((pSGbl->wHeight+3)>>2); break; case MAKEFOURCC('D', 'X', 'T', '2'): dwMultiSamplePitch = (MultiSampleCount * ((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[1] + 7) & ~7; dwPitch = (((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[1] + 7) & ~7; dwHeight = ((pSGbl->wHeight+3)>>2); break; case MAKEFOURCC('D', 'X', 'T', '3'): dwMultiSamplePitch = (MultiSampleCount * ((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[2] + 7) & ~7; dwPitch = (((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[2] + 7) & ~7; dwHeight = ((pSGbl->wHeight+3)>>2); break; case MAKEFOURCC('D', 'X', 'T', '4'): dwMultiSamplePitch = (MultiSampleCount * ((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[3] + 7) & ~7; dwPitch = (((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[3] + 7) & ~7; dwHeight = ((pSGbl->wHeight+3)>>2); break; case MAKEFOURCC('D', 'X', 'T', '5'): dwMultiSamplePitch = (MultiSampleCount * ((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[4] + 7) & ~7; dwPitch = (((pSGbl->wWidth+3)>>2) * g_DXTBlkSize[4] + 7) & ~7; dwHeight = ((pSGbl->wHeight+3)>>2); break; default: dwMultiSamplePitch = (MultiSampleCount * dwBytesPerPixel * pSGbl->wWidth + 7) & ~7; dwPitch = (dwBytesPerPixel * pSGbl->wWidth + 7) & ~7; break; }
if (!(pSMore->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME)) { dwNumBytes = dwPitch * dwHeight; if( MultiSampleCount > 1 ) dwNumMultiSampleBytes = dwMultiSamplePitch * pSGbl->wHeight; } else { _ASSERT( dwMultiSamplePitch == dwPitch, "Cant have multisample for volume textures\n" ); dwSlicePitch = dwPitch * dwHeight;
// low word of ddsCaps.ddsCapsEx.dwCaps4 has depth
// (volume texture only).
dwNumBytes = dwSlicePitch * LOWORD(pSMore->ddsCapsEx.dwCaps4); } }
pPriv = new RDCREATESURFPRIVATE; if( pPriv == NULL ) { DPFERR("Allocation failed"); pData->ddRVal = DDERR_OUTOFMEMORY; break; }
pPriv->pBits = new BYTE[dwNumBytes]; if( pPriv->pBits == NULL) { DPFERR("Allocation failed"); delete pPriv; pData->ddRVal = DDERR_OUTOFMEMORY; break; } pPriv->dwPitch = dwPitch;
// Allocate the private MultiSample buffer
if( dwNumMultiSampleBytes ) { pPriv->pMultiSampleBits = new BYTE[dwNumMultiSampleBytes]; if( pPriv->pMultiSampleBits == NULL) { DPFERR("Multisample allocation failed"); delete pPriv; pData->ddRVal = DDERR_OUTOFMEMORY; break; } pPriv->dwMultiSamplePitch = dwMultiSamplePitch; pPriv->wSamples = (WORD)MultiSampleCount; HR_RET(FindOutSurfFormat(&(DDSurf_PixFmt(pSLcl)), &pPriv->SurfaceFormat, NULL)); }
// Save the stuff on the surface
pSGbl->fpVidMem = (FLATPTR)pPriv->pBits; if ( isDXT ) { pSGbl->lPitch = dwNumBytes; if (pSMore->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME) { // set slice pitch (volume texture only).
pSGbl->lSlicePitch = dwSlicePitch; } } else { pSGbl->lPitch = pPriv->dwPitch; if (pSMore->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME) { // set slice pitch (volume texture only).
pSGbl->lSlicePitch = dwSlicePitch; } } pSGbl->dwReserved1 = (ULONG_PTR)pPriv; }
// The loop completed successfully
if( i == pData->dwSCnt ) return DDHAL_DRIVER_HANDLED;
// Else the loop terminated abnormally,
// Free up allocated memory and quit with the error
for( j = 0; j < i; j++ ) { pData->lplpSList[j]->lpGbl->lPitch = 0; if (pSMore->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME) { pData->lplpSList[j]->lpGbl->lSlicePitch = 0; } delete (RDCREATESURFPRIVATE *)pData->lplpSList[j]->lpGbl->dwReserved1; pData->lplpSList[j]->lpGbl->dwReserved1 = 0; } return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastDestroySurface
//
// Destroy a requested surface.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastDestroySurface(LPDDHAL_DESTROYSURFACEDATA pData) { pData->ddRVal = DD_OK;
//
// Validation
//
if( pData->lpDDSurface->lpGbl->dwReserved1 == NULL ) { DPFERR("This surface was not created by refrast"); pData->ddRVal = E_FAIL; return DDHAL_DRIVER_HANDLED; }
delete (RDCREATESURFPRIVATE *)pData->lpDDSurface->lpGbl->dwReserved1; pData->lpDDSurface->lpGbl->dwReserved1 = 0;
// For vid-mem surfaces, runtime calls this DDI once per entire mip-chain
// so this needs to be removed.
// Now free the handle if it has been allocated for this surface
pData->ddRVal = g_SurfMgr.RemoveSurfFromList( pData->lpDDSurface->lpSurfMore->lpDD_lcl, pData->lpDDSurface );
return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastLock
//
// Locks the given surface.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastLock(LPDDHAL_LOCKDATA pData) { DWORD dwBytesPerPixel = 0; LPDDRAWI_DDRAWSURFACE_LCL pSLcl = pData->lpDDSurface; LPDDRAWI_DDRAWSURFACE_GBL pSGbl = pSLcl->lpGbl; pData->ddRVal = DD_OK;
//
// Validation
//
if( pSGbl->dwReserved1 == NULL ) { DPFERR("This surface was not created by refrast"); pData->ddRVal = E_FAIL; return DDHAL_DRIVER_HANDLED; }
//
// Obtain the private data
//
RDCREATESURFPRIVATE* pPriv = (RDCREATESURFPRIVATE *)pSGbl->dwReserved1;
if (g_RefDDI > RDDDI_DX7HAL) { // Figure out the device it is being used with.
// If this is a Multisampled Rendertarget, need to filter down for
// the runtime.
if( pPriv->pMultiSampleBits ) { BYTE* pBits = pPriv->pBits; DWORD dwPitch = pPriv->dwPitch;
BYTE* pMSBits = pPriv->pMultiSampleBits; DWORD dwMSPitch = pPriv->dwMultiSamplePitch;
RDSurfaceFormat sf = pPriv->SurfaceFormat; FLOAT fSampleScale = 1.F/((FLOAT)pPriv->wSamples);
int width = (int)DDSurf_Width(pSLcl); int height = (int)DDSurf_Height(pSLcl); for (int iY = 0; iY < height; iY++) { for (int iX = 0; iX < width; iX++) { RDColor Color((UINT32)0); for (UINT iS=0; iS<pPriv->wSamples; iS++) { RDColor SampleColor; SampleColor.ConvertFrom( sf, PixelAddress( iX, iY, 0, iS, pMSBits, dwMSPitch, 0, pPriv->wSamples, sf ) ); Color.R += (SampleColor.R * fSampleScale); Color.G += (SampleColor.G * fSampleScale); Color.B += (SampleColor.B * fSampleScale); Color.A += (SampleColor.A * fSampleScale); } Color.ConvertTo( sf, 0., PixelAddress( iX, iY, 0, pBits, dwPitch, 0, sf ) ); } } } }
if( pData->bHasRect ) { // If it is either a 1) VB, 2) IB or 3) CB then the
// rect has a special meaning. rect.top - rect.bottom
// gives the range of memory desired.
// Note: it rect.bottom is the higher address and it is exclusive.
if( pSLcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER ) { pData->lpSurfData = (LPVOID)(pPriv->pBits + pData->rArea.top); } else if( pSLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_VOLUME ) { // If it is a volume texture, then the front and back are
// or'd into the high word of rect->left and rect->right
// respectively.
DWORD front = (pData->rArea.left >> 16); DWORD left = pData->rArea.left & 0x0000ffff; DWORD top = pData->rArea.top; DWORD slicePitch = pSGbl->lSlicePitch; if( IsDXTn( pSGbl->ddpfSurface.dwFourCC ) ) { _ASSERT( FALSE, "Should not be reached without driver " "managed support" );
} else { dwBytesPerPixel = pSGbl->ddpfSurface.dwRGBBitCount >> 3; pData->lpSurfData = (LPVOID)(pPriv->pBits + front * slicePitch + top * pPriv->dwPitch + left * dwBytesPerPixel); } } else { if( IsDXTn( pSGbl->ddpfSurface.dwFourCC ) ) { _ASSERT( FALSE, "Should not be reached without driver " "managed support" );
} else { dwBytesPerPixel = pSGbl->ddpfSurface.dwRGBBitCount >> 3; pData->lpSurfData = (LPVOID)(pPriv->pBits + pData->rArea.top*pPriv->dwPitch + pData->rArea.left*dwBytesPerPixel); } } } else { pData->lpSurfData = (LPVOID)pPriv->pBits; }
pPriv->Lock(); return DDHAL_DRIVER_HANDLED; }
//----------------------------------------------------------------------------
//
// RefRastUnlock
//
// Unlocks the given surface.
//
//----------------------------------------------------------------------------
DWORD __stdcall RefRastUnlock(LPDDHAL_UNLOCKDATA pData) { pData->ddRVal = DD_OK;
//
// Validation
//
if( pData->lpDDSurface->lpGbl->dwReserved1 == NULL ) { DPFERR("This surface was not created by refrast"); pData->ddRVal = E_FAIL; return DDHAL_DRIVER_HANDLED; }
//
// Obtain the private data
//
RDCREATESURFPRIVATE* pPriv = (RDCREATESURFPRIVATE *)pData->lpDDSurface->lpGbl->dwReserved1;
pPriv->Unlock(); return DDHAL_DRIVER_HANDLED; }
//////////////////////////////////////////////////////////////////////////////
//
// Software DDI interface implementation
//
//////////////////////////////////////////////////////////////////////////////
//
// DX8 DDI caps
//
#define RESPATH_D3DREF RESPATH_D3D "\\ReferenceDevice"
static void ModifyDeviceCaps8( void ) { HKEY hKey = (HKEY) NULL; if( ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3DREF, &hKey) ) { DWORD dwType; DWORD dwValue; char dwString[128]; DWORD dwSize;
dwSize = sizeof(dwValue); if ( (ERROR_SUCCESS == RegQueryValueEx( hKey, "PixelShaderVersion", NULL, &dwType, (LPBYTE)&dwValue, &dwSize )) && (dwType == REG_DWORD) ) { g_RefCaps8.PixelShaderVersion = dwValue; } dwSize = sizeof(dwString); if ( (ERROR_SUCCESS == RegQueryValueEx( hKey, "MaxPixelShaderValue", NULL, &dwType, (LPBYTE)dwString, &dwSize )) && (dwType == REG_SZ) ) { sscanf( dwString, "%f", &g_RefCaps8.MaxPixelShaderValue ); }
RegCloseKey(hKey); }
}
static void FillOutDeviceCaps8( RDDDITYPE ddi ) { g_RefCaps8.DevCaps= D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | 0;
g_RefCaps8.PrimitiveMiscCaps = D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_COLORWRITEENABLE | D3DPMISCCAPS_CLIPTLVERTS | D3DPMISCCAPS_TSSARGTEMP | D3DPMISCCAPS_FOGINFVF | D3DPMISCCAPS_BLENDOP ;
#ifdef __D3D_NULL_REF
g_RefCaps8.PrimitiveMiscCaps |= D3DPMISCCAPS_NULLREFERENCE; #endif //__D3D_NULL_REF
g_RefCaps8.RasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_PAT | // D3DPRASTERCAPS_ZBIAS |
D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE ;
g_RefCaps8.ZCmpCaps = D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS ;
g_RefCaps8.SrcBlendCaps = 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 ;
g_RefCaps8.DestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT ;
g_RefCaps8.AlphaCmpCaps = D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS ;
g_RefCaps8.ShadeCaps = D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGGOURAUD ;
g_RefCaps8.TextureCaps = D3DPTEXTURECAPS_PERSPECTIVE | // D3DPTEXTURECAPS_POW2 |
D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2 ;
g_RefCaps8.TextureFilterCaps = D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MAGFANISOTROPIC ;
g_RefCaps8.CubeTextureFilterCaps = D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR ;
g_RefCaps8.VolumeTextureFilterCaps = D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MAGFLINEAR ;
g_RefCaps8.TextureAddressCaps = D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV | D3DPTADDRESSCAPS_MIRRORONCE ;
g_RefCaps8.VolumeTextureAddressCaps = D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV | D3DPTADDRESSCAPS_MIRRORONCE ;
g_RefCaps8.LineCaps = D3DLINECAPS_TEXTURE | D3DLINECAPS_ZTEST | D3DLINECAPS_BLEND | D3DLINECAPS_ALPHACMP | D3DLINECAPS_FOG ;
g_RefCaps8.MaxTextureWidth = 4096; g_RefCaps8.MaxTextureHeight = 4096; g_RefCaps8.MaxVolumeExtent = 4096;
g_RefCaps8.MaxTextureRepeat = 32768; g_RefCaps8.MaxTextureAspectRatio = 0; g_RefCaps8.MaxAnisotropy = 16; g_RefCaps8.MaxVertexW = 1.0e10;
g_RefCaps8.GuardBandLeft = -32768.f; g_RefCaps8.GuardBandTop = -32768.f; g_RefCaps8.GuardBandRight = 32767.f; g_RefCaps8.GuardBandBottom = 32767.f;
g_RefCaps8.ExtentsAdjust = 0.; g_RefCaps8.StencilCaps = D3DSTENCILCAPS_KEEP | D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE| D3DSTENCILCAPS_INCRSAT| D3DSTENCILCAPS_DECRSAT| D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
g_RefCaps8.FVFCaps = 8 | D3DFVFCAPS_PSIZE;
g_RefCaps8.TextureOpCaps = 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 | D3DTEXOPCAPS_MULTIPLYADD | D3DTEXOPCAPS_LERP ;
g_RefCaps8.MaxTextureBlendStages = 8; g_RefCaps8.MaxSimultaneousTextures = 8;
g_RefCaps8.VertexProcessingCaps = 0; g_RefCaps8.MaxActiveLights = 0; g_RefCaps8.MaxUserClipPlanes = 0; g_RefCaps8.MaxVertexBlendMatrices = 0; g_RefCaps8.MaxVertexBlendMatrixIndex = 0;
g_RefCaps8.MaxPointSize = RD_MAX_POINT_SIZE;
g_RefCaps8.MaxPrimitiveCount = 0x001fffff; g_RefCaps8.MaxVertexIndex = 0x00ffffff; g_RefCaps8.MaxStreams = 1; g_RefCaps8.MaxStreamStride = 256;
g_RefCaps8.VertexShaderVersion = D3DVS_VERSION(0,0); g_RefCaps8.MaxVertexShaderConst = 0;
g_RefCaps8.PixelShaderVersion = D3DPS_VERSION(1,4); g_RefCaps8.MaxPixelShaderValue = FLT_MAX;
// Non 3D Caps
g_RefCaps8.Caps = 0; g_RefCaps8.Caps2 = DDCAPS2_CANMANAGERESOURCE | DDCAPS2_CANRENDERWINDOWED | DDCAPS2_DYNAMICTEXTURES;
switch( ddi ) { case RDDDI_DX8TLHAL: g_RefCaps8.DevCaps |= D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO | D3DDEVCAPS_NPATCHES | D3DDEVCAPS_QUINTICRTPATCHES | 0; g_RefCaps8.VertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_TWEENING | D3DVTXPCAPS_LOCALVIEWER ; g_RefCaps8.MaxActiveLights = 0xffffffff; g_RefCaps8.MaxUserClipPlanes = RD_MAX_USER_CLIPPLANES; g_RefCaps8.MaxVertexBlendMatrices = RD_MAX_BLEND_WEIGHTS; g_RefCaps8.MaxVertexBlendMatrixIndex = RD_MAX_WORLD_MATRICES - 1; g_RefCaps8.MaxStreams = RD_MAX_NUMSTREAMS; g_RefCaps8.VertexShaderVersion = D3DVS_VERSION(1,1); g_RefCaps8.MaxVertexShaderConst = RD_MAX_NUMCONSTREG; break; } }
//
// pre-DX8 DDI caps
//
static D3DHAL_GLOBALDRIVERDATA RefGDD = { 0 }; static D3DHAL_D3DEXTENDEDCAPS RefExtCaps = { 0 };
static void FillOutDeviceCaps( BOOL bIsNullDevice, RDDDITYPE ddi ) { //
// set device description
//
RefGDD.dwSize = sizeof(RefGDD); RefGDD.hwCaps.dwDevCaps = D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY | D3DDEVCAPS_DRAWPRIMTLVERTEX;
RefGDD.dwNumVertices = (RD_MAX_VERTEX_COUNT - RD_MAX_CLIP_VERTICES); RefGDD.dwNumClipVertices = RD_MAX_CLIP_VERTICES;
RefGDD.hwCaps.dpcTriCaps.dwSize = sizeof(D3DPRIMCAPS); RefGDD.hwCaps.dpcTriCaps.dwMiscCaps = D3DPMISCCAPS_MASKZ | D3DPMISCCAPS_CULLNONE | D3DPMISCCAPS_CULLCW | D3DPMISCCAPS_CULLCCW ; RefGDD.hwCaps.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; RefGDD.hwCaps.dpcTriCaps.dwZCmpCaps = D3DPCMPCAPS_NEVER | D3DPCMPCAPS_LESS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_NOTEQUAL | D3DPCMPCAPS_GREATEREQUAL | D3DPCMPCAPS_ALWAYS ; RefGDD.hwCaps.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 ; RefGDD.hwCaps.dpcTriCaps.dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR | D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR | D3DPBLENDCAPS_SRCALPHASAT ; RefGDD.hwCaps.dpcTriCaps.dwAlphaCmpCaps = RefGDD.hwCaps.dpcTriCaps.dwZCmpCaps; RefGDD.hwCaps.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB | D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD ; RefGDD.hwCaps.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_COLORKEYBLEND; RefGDD.hwCaps.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 ; RefGDD.hwCaps.dpcTriCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_MODULATEALPHA | // D3DPTBLENDCAPS_DECALMASK |
// D3DPTBLENDCAPS_MODULATEMASK |
D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_ADD ; RefGDD.hwCaps.dpcTriCaps.dwTextureAddressCaps = D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV ; RefGDD.hwCaps.dpcTriCaps.dwStippleWidth = 0; RefGDD.hwCaps.dpcTriCaps.dwStippleHeight = 0;
// line caps - copy tricaps and modify
memcpy( &RefGDD.hwCaps.dpcLineCaps, &RefGDD.hwCaps.dpcTriCaps, sizeof(D3DPRIMCAPS) );
// disable antialias cap
RefGDD.hwCaps.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;
RefGDD.hwCaps.dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32; RefGDD.hwCaps.dwDeviceZBufferBitDepth = DDBD_16 | DDBD_32;
//
// 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;
switch( ddi ) { case RDDDI_DX7TLHAL: RefGDD.hwCaps.dwDevCaps |= D3DDEVCAPS_HWTRANSFORMANDLIGHT; RefExtCaps.dwVertexProcessingCaps = (D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER); RefExtCaps.wMaxUserClipPlanes = RD_MAX_USER_CLIPPLANES; RefExtCaps.wMaxVertexBlendMatrices = RD_MAX_BLEND_WEIGHTS; // Fall throug
case RDDDI_DX7HAL: RefGDD.hwCaps.dwDevCaps |= D3DDEVCAPS_DRAWPRIMITIVES2EX; } }
//----------------------------------------------------------------------------
//
// Pixel formats
//
// Returns all the pixel formats supported by our rasterizer, and what we
// can do with them.
// Called at device creation time.
//
//----------------------------------------------------------------------------
DWORD GetRefFormatOperations( LPDDSURFACEDESC* lplpddsd ) { int i = 0;
DDSURFACEDESC* ddsd = g_ddsdTex;
// Here we list our DX8 texture formats.
// A driver wishing to run against DX7 or earlier runtimes would duplicate
// entries, placing a list of DDSURFACEDESCs before this list that contain
// old-style DDPIXELFORMAT structures. Example of old style:
// /* 888 */
// ddsd[i].dwSize = sizeof(ddsd[0]);
// ddsd[i].dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
// ddsd[i].ddsCaps.dwCaps = DDSCAPS_TEXTURE;
// ddsd[i].ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
// ddsd[i].ddpfPixelFormat.dwFlags = DDPF_RGB;
// ddsd[i].ddpfPixelFormat.dwRGBBitCount = 32;
// ddsd[i].ddpfPixelFormat.dwRBitMask = 0xff0000;
// ddsd[i].ddpfPixelFormat.dwGBitMask = 0x00ff00;
// ddsd[i].ddpfPixelFormat.dwBBitMask = 0x0000ff;
//-------------------------- (A)RGB Formats -----------------------------------------
/* 888 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_R8G8B8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_3DACCELERATION | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* x888 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8R8G8B8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_3DACCELERATION | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* 8888 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8R8G8B8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* 565 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_R5G6B5; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_3DACCELERATION | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* x555 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X1R5G5B5; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_3DACCELERATION | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* 1555 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A1R5G5B5; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
// A formats for PC98 consistency
// 4444 ARGB (it is already supported by S3 Virge)
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A4R4G4B4; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
// 4444 XRGB
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X4R4G4B4; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
// 332 8-bit RGB
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_R3G3B2; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
// 8332 16-bit ARGB
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8R3G3B2; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
//---------------------------- Palettized formats ------------------------------------
#if 0
/* pal4 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES); i++; #endif
/* A8P8 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8P8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
/* pal8 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_P8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
//-------------------------- alpha/luminance formats -----------------------------------
/* 8 bit luminance-only */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_L8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
/* 16 bit alpha-luminance */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8L8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
/* 8 bit alpha-luminance */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A4L4; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
/* A8 */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
//-------------------------- YUV formats -----------------------------------
// UYVY
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_UYVY; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// YUY2
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_YUY2; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
//-------------------------- DXT formats -----------------------------------
// DXT compressed texture format 1
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_DXT1; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// DXT compressed texture format 2
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_DXT2; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// DXT compressed texture format 3
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_DXT3; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// DXT compressed texture format 4
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_DXT4; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// DXT compressed texture format 5
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_DXT5; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
//-------------------------- Bump/luminance formats / Signed formats -----------------
// V8U8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_V8U8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// L6V5U5
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_L6V5U5; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// X8L8V8U8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8L8V8U8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// V16U16
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_V16U16; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// Q8W8V8U8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_Q8W8V8U8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// W11V11U10
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_W11V11U10; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
//-------------- Formats introduced in DX8.1 -------------------------
#if 0
// A8B8G8R8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8B8G8R8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// W10V11U11
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_W10V11U11; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// A8X8V8U8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A8X8V8U8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// L8X8V8U8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_L8X8V8U8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// X8B8G8R8
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8B8G8R8; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++; #endif
// A2W10V10U10
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A2W10V10U10; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// A2B10G10R10
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_A2B10G10R10; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE | D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET | D3DFORMAT_OP_OFFSCREEN_RENDERTARGET; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
// G16R16
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_G16R16; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_VOLUMETEXTURE | D3DFORMAT_OP_CUBETEXTURE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
//-------------------------- Z/Stencil buffer formats -----------------------------------
/* 8 bit stencil; 24 bit Z */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_S8D24; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* 1 bit stencil; 15 bit Z */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_S1D15; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* 4 bit stencil; 24 bit Z */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_D24X4S4; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
//-------------------------- Z/Stencil/texture + shadow buffer formats -----------------------------------
// Z16S0
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_D16_LOCKABLE; ddsd[i].ddpfPixelFormat.dwOperations = #if 0
// for Shadow Buffer prototype API
D3DFORMAT_OP_TEXTURE | #endif
D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
// Z32S0
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_D32; ddsd[i].ddpfPixelFormat.dwOperations = #if 0
// for Shadow Buffer prototype API
D3DFORMAT_OP_TEXTURE | #endif
D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
/* 24 bit Z */ ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) D3DFMT_X8D24; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 0; //not required for known formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_4_SAMPLES) | DDI_MULTISAMPLE_TYPE(D3DMULTISAMPLE_9_SAMPLES); i++;
//
// This is an example of a IHV-specific format
// The HIWORD must be the PCI-ID of the IHV
// and the third byte must be zero.
// In this case, we're using a sample PCI-ID of
// FF00, and we're denoting the 4th format
// by that PCI-ID.
//
// In this case, we're exposing a non-standard Z-buffer format
// that can be used as a texture and depth-stencil at
// in the same format.(We are also choosing to
// disallow it as valid for cubemaps and volumes.)
//
ddsd[i].ddpfPixelFormat.dwFlags = DDPF_D3DFORMAT; ddsd[i].ddpfPixelFormat.dwFourCC = (DWORD) 0xFF000004; ddsd[i].ddpfPixelFormat.dwOperations = D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH | D3DFORMAT_OP_ZSTENCIL | D3DFORMAT_OP_TEXTURE | D3DFORMAT_OP_PIXELSIZE; ddsd[i].ddpfPixelFormat.dwPrivateFormatBitCount = 32; // required for IHV formats
ddsd[i].ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes = 0; ddsd[i].ddpfPixelFormat.MultiSampleCaps.wBltMSTypes = 0; i++;
*lplpddsd = ddsd;
_ASSERT(i<=RD_MAX_NUM_TEXTURE_FORMATS, "Not enough space in static texture list");
return i; }
#include <d3d8sddi.h>
HRESULT WINAPI D3D8GetSWInfo( D3DCAPS8* pCaps, PD3D8_SWCALLBACKS pCallbacks, DWORD* pNumTextures, DDSURFACEDESC** ppTexList ) { #define RESPATH_D3D "Software\\Microsoft\\Direct3D"
// First query the registry to check if we were asked to
// emulate any particular DDI.
g_RefDDI = RDDDI_DX8TLHAL; HKEY hKey = (HKEY) NULL; if( ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_D3D, &hKey) ) { DWORD dwType; DWORD dwValue; DWORD dwSize = sizeof(dwValue); if ( ERROR_SUCCESS == RegQueryValueEx( hKey, "DriverStyle", NULL, &dwType, (LPBYTE) &dwValue, &dwSize ) && dwType == REG_DWORD && dwValue > 0 ) { g_RefDDI = (RDDDITYPE)dwValue;
// NOTE: RefDev's DDI emulation is currently restricted to
// DX8 TL and Non-TL HALs only.
if( g_RefDDI > RDDDI_DX8TLHAL ) { DPFERR( "Bad Driver style set. Assuming DX8TLHAL" ); g_RefDDI = RDDDI_DX8TLHAL; } if( g_RefDDI < RDDDI_DX8HAL ) { DPFERR( "Bad Driver style set. Assuming DX8HAL" ); g_RefDDI = RDDDI_DX8HAL; } } RegCloseKey(hKey); }
// NULL out all the callbacks first
memset( pCallbacks, 0, sizeof(PD3D8_SWCALLBACKS) );
// These callbacks are needed by everyone
pCallbacks->CreateContext = RefRastContextCreate; pCallbacks->ContextDestroy = RefRastContextDestroy; pCallbacks->ContextDestroyAll = NULL; pCallbacks->SceneCapture = RefRastSceneCapture; pCallbacks->CreateSurface = RefRastCreateSurface; pCallbacks->Lock = RefRastLock; pCallbacks->DestroySurface = RefRastDestroySurface; pCallbacks->Unlock = RefRastUnlock;
switch( g_RefDDI ) { case RDDDI_DX8TLHAL: case RDDDI_DX8HAL: case RDDDI_DX7TLHAL: case RDDDI_DX7HAL: pCallbacks->GetDriverState = RefRastGetDriverState; pCallbacks->CreateSurfaceEx = RefRastCreateSurfaceEx; // Fall through
case RDDDI_DP2HAL: pCallbacks->ValidateTextureStageState = RefRastValidateTextureStageState; pCallbacks->DrawPrimitives2 = RefRastDrawPrimitives2; pCallbacks->Clear2 = NULL; // Fall through
case RDDDI_DPHAL: pCallbacks->DrawOnePrimitive = NULL; pCallbacks->DrawOneIndexedPrimitive = NULL; pCallbacks->DrawPrimitives = NULL; pCallbacks->Clear = NULL; pCallbacks->SetRenderTarget = RefRastSetRenderTarget; // Fall through
case RDDDI_OLDHAL: pCallbacks->RenderState = NULL; pCallbacks->RenderPrimitive = NULL; pCallbacks->TextureCreate = RefRastTextureCreate; pCallbacks->TextureDestroy = RefRastTextureDestroy; pCallbacks->TextureSwap = NULL; pCallbacks->TextureGetSurf = RefRastTextureGetSurf; break; default: DPFERR( "Unknown DDI style set" ); return E_FAIL; }
// Now deal with the caps
FillOutDeviceCaps(FALSE, g_RefDDI);
// Fill in the supported pixel format operations
// In DX8 these operations are expressed through the texture
// format list.
*pNumTextures = GetRefFormatOperations( ppTexList );
FillOutDeviceCaps8( g_RefDDI ); ModifyDeviceCaps8(); *pCaps = g_RefCaps8;
return DD_OK; }
|