Source code of Windows XP (NT5)
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.
|
|
/*==========================================================================;
* * Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved. * * File: texture.cpp * Content: Implementation of the CBaseTexture class. * * ***************************************************************************/ #include "ddrawpr.h"
#include "texture.hpp"
#include "d3di.hpp"
#include "ddi.h"
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::CanTexBlt"
BOOL CBaseTexture::CanTexBlt(CBaseTexture *pDstTexture) const { const D3D8_DRIVERCAPS* pDriverCaps = Device()->GetCoreCaps(); D3DPOOL SrcPool = GetBufferDesc()->Pool; D3DPOOL DstPool = pDstTexture->GetBufferDesc()->Pool;
// Real pools should not be default
DXGASSERT(SrcPool != D3DPOOL_DEFAULT); DXGASSERT(DstPool != D3DPOOL_DEFAULT); DXGASSERT(VALID_INTERNAL_POOL(SrcPool)); DXGASSERT(VALID_INTERNAL_POOL(DstPool));
// Check if the device can do TexBlt
if (Device()->CanTexBlt() == FALSE) return FALSE;
// Check that source and dest formats match
DXGASSERT(GetBufferDesc()->Format == pDstTexture->GetBufferDesc()->Format);
// FourCC may not be copy-able
if (CPixel::IsFourCC(GetBufferDesc()->Format)) { if (!(pDriverCaps->D3DCaps.Caps2 & DDCAPS2_COPYFOURCC)) { return FALSE; } }
// Note that we do not support TexBlt to anything
// that is persistent across Reset; because TexBlt is
// asynchronous and may not succeed if we get lost.
//
// This can break apps that expect the blt to have
// succeeded.
if (pDriverCaps->D3DCaps.Caps2 & DDCAPS2_NONLOCALVIDMEMCAPS) { if (SrcPool == D3DPOOL_SYSTEMMEM) { if ((DstPool == D3DPOOL_NONLOCALVIDMEM) && (pDriverCaps->D3DCaps.DevCaps & D3DDEVCAPS_CANBLTSYSTONONLOCAL)) { return TRUE; } else if ((DstPool == D3DPOOL_LOCALVIDMEM) && (pDriverCaps->SVBCaps & DDCAPS_BLT)) { return TRUE; } } else if (SrcPool == D3DPOOL_NONLOCALVIDMEM) { if ((DstPool == D3DPOOL_LOCALVIDMEM) && (pDriverCaps->NLVCaps & DDCAPS_BLT)) { return TRUE; } } else if ((SrcPool == D3DPOOL_LOCALVIDMEM) || (SrcPool == D3DPOOL_MANAGED)) { if ((DstPool == D3DPOOL_LOCALVIDMEM) && (pDriverCaps->D3DCaps.Caps & DDCAPS_BLT)) { return TRUE; } } } else { if (SrcPool == D3DPOOL_SYSTEMMEM) { if ((DstPool == D3DPOOL_LOCALVIDMEM) && (pDriverCaps->SVBCaps & DDCAPS_BLT)) { return TRUE; } } else if ((SrcPool == D3DPOOL_LOCALVIDMEM) || (SrcPool == D3DPOOL_MANAGED)) { if ((DstPool == D3DPOOL_LOCALVIDMEM) && (pDriverCaps->D3DCaps.Caps & DDCAPS_BLT)) { return TRUE; } } }
return FALSE; } // CBaseTexture::CanTexBlt
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::VerifyFormat"
HRESULT CBaseTexture::Validate(CBaseDevice *pDevice, D3DRESOURCETYPE Type, D3DPOOL Pool, DWORD Usage, D3DFORMAT Format) { DXGASSERT(pDevice); DXGASSERT(Type == D3DRTYPE_TEXTURE || Type == D3DRTYPE_CUBETEXTURE || Type == D3DRTYPE_VOLUMETEXTURE);
// Check pool
if (!VALID_POOL(Pool)) { DPF_ERR("Invalid Pool specified for texture"); return D3DERR_INVALIDCALL; }
//pool scratch doesn't allow any usages
if (Pool == D3DPOOL_SCRATCH) { if (Usage) { DPF_ERR("D3DPOOL_SCRATCH resources aren't allowed to have any usage flags"); return D3DERR_INVALIDCALL; } }
// Check usage flags
if (Usage & ~D3DUSAGE_TEXTURE_VALID) { DPF_ERR("Invalid usage flag specified for texture."); return D3DERR_INVALIDCALL; }
// Check if USAGE_DYNAMIC is allowed
if (Usage & D3DUSAGE_DYNAMIC) { if (Pool == D3DPOOL_MANAGED) { DPF_ERR("Managed textures cannot be dynamic."); return D3DERR_INVALIDCALL; } }
// Check is load-once is supported
if (Usage & D3DUSAGE_LOADONCE) { // Only SysMem and Managed are load-once-able
if (Pool != D3DPOOL_SYSTEMMEM && Pool != D3DPOOL_MANAGED) { DPF_ERR("Only SysMem and Managed textures support D3DUSAGE_LOADONCE"); return D3DERR_INVALIDCALL; }
// Only D16_LOCKABLE is a lockable depth; doesn't
// make sense to have a non-lockable LOAD_ONCE texture
if (CPixel::IsNonLockableZ(Format)) { DPF_ERR("Depth formats other than D3DFMT_D16_LOCKABLE are not lockable."); return D3DERR_INVALIDCALL; } }
// Check that only POOL_DEFAULT is supported for
// RT or DS textures
if (Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) { if (Pool != D3DPOOL_DEFAULT) { DPF_ERR("Pool must be D3DPOOL_DEFAULT for RenderTarget and" " DepthStencil Usages"); return D3DERR_INVALIDCALL; } }
// Sys scratch or Managed must have a format that we can use directly
if (Pool == D3DPOOL_SYSTEMMEM || Pool == D3DPOOL_MANAGED || Pool == D3DPOOL_SCRATCH) { // Can't create format unless it is supported
if (!CPixel::IsSupported(Type, Format)) { DPF_ERR("SystemMem, Scratch and Managed textures do not support this" " format."); return D3DERR_INVALIDCALL; } if (CPixel::IsNonLockableZ(Format)) { DPF_ERR("This format is not supported for SystemMem, Scratch or Managed textures"); return D3DERR_INVALIDCALL; } }
if (Pool != D3DPOOL_SCRATCH) { HRESULT hr = pDevice->CheckDeviceFormat(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_DYNAMIC), Type, Format); if (FAILED(hr)) { DPF_ERR("Invalid format specified for texture"); return D3DERR_INVALIDCALL; } }
return S_OK; }; // CBaseTexture::Validate
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::InferUsageFlags"
// Infer usage flags based on external parameters
DWORD CBaseTexture::InferUsageFlags(D3DPOOL Pool, DWORD Usage, D3DFORMAT Format) { //scratch textures have only usage lock
if (Pool == D3DPOOL_SCRATCH) return D3DUSAGE_LOCK;
// All textures have this usage set
DWORD UsageInferred = D3DUSAGE_TEXTURE;
DXGASSERT(!(Usage & D3DUSAGE_LOCK)); DXGASSERT(!(Usage & D3DUSAGE_TEXTURE));
// Infer Lock
if ((Pool != D3DPOOL_DEFAULT) && !(CPixel::IsNonLockableZ(Format)) && !(Usage & D3DUSAGE_LOADONCE)) { // Pool Default is not lockable
// Usage Load Once implies absence of USAGE_LOCK
// Z formats (other than D16_LOCKABLE) are not lockable
// Otherwise, locking is support by default
UsageInferred |= D3DUSAGE_LOCK; } else if (CPixel::IsIHVFormat(Format)) { // IHV formats are lockable
UsageInferred |= D3DUSAGE_LOCK; } else if (Usage & D3DUSAGE_DYNAMIC) { DXGASSERT(Pool != D3DPOOL_MANAGED); // Dynamic textures are lockable
UsageInferred |= D3DUSAGE_LOCK; }
return (UsageInferred | Usage);
} // CBaseTexture::InferUsageFlags
#ifdef DEBUG
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::ReportWhyLockFailed"
// DPF why Lock failed as clearly as possible
void CBaseTexture::ReportWhyLockFailed(void) const { // If there are multiple reasons that lock failed; we report
// them all to minimize user confusion
if (GetUserPool() == D3DPOOL_DEFAULT) { DPF_ERR("Lock is not supported for textures allocated with" " POOL_DEFAULT unless they are marked D3DUSAGE_DYNAMIC."); } if (CPixel::IsNonLockableZ(GetUserFormat())) { DPF_ERR("Lock is not supported for depth formats other than D3DFMT_D16_LOCKABLE"); } if (GetBufferDesc()->Usage & D3DUSAGE_LOADONCE) { DPF_ERR("For textures created with D3DUSAGE_LOADONCE," " each level can only be locked once."); }
// If we got here; then USAGE_LOCK should not have been set
DXGASSERT(!(GetBufferDesc()->Usage & D3DUSAGE_LOCK));
return; } // CBaseTexture::ReportWhyLockFailed
#endif // DEBUG
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::OnDestroy"
// Textures overload this to call OnTextureDestroy on the
// Device before calling Sync.
void CBaseTexture::OnDestroy(void) { if (GetUserPool() != D3DPOOL_SCRATCH) { // we need to call this before freeing the texture so
// that currently set textures get unset.
if (BaseKernelHandle()) { // m_hKernelHandle might not be available if Create fails early
CD3DBase *pDev = static_cast<CD3DBase *>(Device()); pDev->OnTextureDestroy(this); }
// After FE has been notified, then we need
// to sync; so call our base class
CResource::OnDestroy(); }
return; } // CBaseTexture::OnDestroy
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::SetLODImpl"
DWORD CBaseTexture::SetLODImpl(DWORD LOD) { // Clamp to max lod since we can't return errors
if (LOD >= GetLevelCountImpl()) { DPF_ERR("Invalid dwLOD passed to SetLOD; clamping to number-of-levels-minus-one."); LOD = GetLevelCountImpl() - 1; }
DWORD oldLOD = 0; if (IsD3DManaged()) { oldLOD = Device()->ResourceManager()->SetLOD(RMHandle(), LOD); } // If IsD3DManaged() is FALSE and if the actual pool
// is found to be D3DPOOL_MANAGED then the resource
// MUST be driver managed.
else if (GetBufferDesc()->Pool == D3DPOOL_MANAGED) { CD3DBase *pDev = static_cast<CD3DBase*>(Device()); DXGASSERT(IS_DX8HAL_DEVICE(pDev)); oldLOD = SetLODI(LOD); pDev->SetTexLOD(this, LOD); } // If above two conditions are false, then we must
// check if we have fallen back to sysmem for some
// reason even if the app requested managed. THIS
// IS IMPOSSIBLE, so ASSERT.
else if (GetUserPool() == D3DPOOL_MANAGED) { // We assert because sysmem fallback is not possible
// for textures (and hence SetLOD)
DXGASSERT(FALSE); } else { DPF_ERR("LOD set on non-managed object"); } return oldLOD; }; // SetLODImpl
#undef DPF_MODNAME
#define DPF_MODNAME "CBaseTexture::GetLODImpl"
DWORD CBaseTexture::GetLODImpl() { if (!IsD3DManaged() && GetBufferDesc()->Pool != D3DPOOL_MANAGED) { DPF_ERR("LOD accessed on non-managed object"); return 0; } return GetLODI(); }; // GetLODImpl
// End of file : texture.cpp
|