|
|
//===== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======//
//
// Purpose: Manager for texture containing subd data
//
//===========================================================================//
#include "isubdinternal.h"
#include "tier0/dbg.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/MaterialSystemUtil.h"
#include "materialsystem/itexture.h"
#include "materialsystem/imesh.h"
#include "utlsortvector.h"
#include "materialsystem_global.h"
#include "IHardwareConfigInternal.h"
#include "pixelwriter.h"
#include "itextureinternal.h"
#include "tier1/keyvalues.h"
#include "texturemanager.h"
#include "imaterialsysteminternal.h"
#include "imatrendercontextinternal.h"
#include "studio.h"
#include "tier0/vprof.h"
#include "renderparm.h"
#include "tier2/renderutils.h"
#include "bitmap/imageformat.h"
#include "materialsystem/IShader.h"
#include "imaterialinternal.h"
#include "tier0/memdbgon.h"
#define SUBD_TEXTURE_FORMAT IMAGE_FORMAT_RGBA32323232F
#define SUBD_TEXTURE_WIDTH 30
#define SUBD_TEXTURE_HEIGHT 8192 // If we need more than 8192 patches, we may be in trouble
//-----------------------------------------------------------------------------
// Subdivision surface manager class
//-----------------------------------------------------------------------------
class CSubDMgr : public ISubDMgr { public: CSubDMgr();
virtual bool ShouldAllocateTextures(); virtual void AllocateTextures(); virtual void FreeTextures(); virtual void ReacquireResources(); virtual void ReleaseResources(); virtual int GetWidth(); virtual int GetHeight(); virtual int GetOffsetGeometry(); virtual int GetOffsetTangents();
virtual float* Lock( int nNumRows ); virtual void Unlock();
virtual ShaderAPITextureHandle_t SubDTexture();
private: ShaderAPITextureHandle_t m_hSysMem; ShaderAPITextureHandle_t m_hDefaultPool; int m_nRowsLocked; int m_nOffsetGeometry; int m_nOffsetTangents; };
//-----------------------------------------------------------------------------
// Singleton
//-----------------------------------------------------------------------------
static CSubDMgr s_SubDMgr; ISubDMgr *g_pSubDMgr = &s_SubDMgr;
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CSubDMgr::CSubDMgr() { m_nRowsLocked = 0; m_nOffsetGeometry = 0; m_nOffsetTangents = 0; m_hSysMem = INVALID_SHADERAPI_TEXTURE_HANDLE; m_hDefaultPool = INVALID_SHADERAPI_TEXTURE_HANDLE; }
bool CSubDMgr::ShouldAllocateTextures() { return true; // return g_pMaterialSystemHardwareConfig->SupportsSubdivisionSurfaces();
}
int CSubDMgr::GetWidth() { return SUBD_TEXTURE_WIDTH; }
int CSubDMgr::GetHeight() { return SUBD_TEXTURE_HEIGHT; }
int CSubDMgr::GetOffsetGeometry() { return m_nOffsetGeometry; }
int CSubDMgr::GetOffsetTangents() { return m_nOffsetTangents; }
void CSubDMgr::AllocateTextures() { ReacquireResources(); }
void CSubDMgr::FreeTextures() { ReleaseResources(); }
void CSubDMgr::ReleaseResources() { if ( g_pShaderAPI->IsTexture( m_hSysMem ) ) { g_pShaderAPI->DeleteTexture( m_hSysMem ); m_hSysMem = INVALID_SHADERAPI_TEXTURE_HANDLE; }
if ( g_pShaderAPI->IsTexture( m_hDefaultPool ) ) { g_pShaderAPI->DeleteTexture( m_hDefaultPool ); m_hDefaultPool = INVALID_SHADERAPI_TEXTURE_HANDLE; } }
void CSubDMgr::ReacquireResources() { Assert( m_hSysMem == INVALID_SHADERAPI_TEXTURE_HANDLE ); Assert( m_hDefaultPool == INVALID_SHADERAPI_TEXTURE_HANDLE );
// These scratch textures are ~4mb (30*8192*16 bytes) and can
// accommodate data for 8192 patches
g_pShaderAPI->CreateTextures( &m_hSysMem, 1, SUBD_TEXTURE_WIDTH, SUBD_TEXTURE_HEIGHT, 0, SUBD_TEXTURE_FORMAT, 1, 1, TEXTURE_CREATE_SYSMEM, "_SubDSysMemTexture", "SubD Textures" );
g_pShaderAPI->CreateTextures( &m_hDefaultPool, 1, SUBD_TEXTURE_WIDTH, SUBD_TEXTURE_HEIGHT, 0, SUBD_TEXTURE_FORMAT, 1, 1, TEXTURE_CREATE_DEFAULT_POOL | TEXTURE_CREATE_VERTEXTEXTURE, "_SubDVidMemTexture", "SubD Textures" ); g_pShaderAPI->ModifyTexture( m_hDefaultPool ); g_pShaderAPI->TexMinFilter( SHADER_TEXFILTERMODE_NEAREST ); g_pShaderAPI->TexMagFilter( SHADER_TEXFILTERMODE_NEAREST ); }
float *CSubDMgr::Lock( int nRows ) { m_nRowsLocked = nRows; return (float *) g_pShaderAPI->LockTex( m_hSysMem ); }
void CSubDMgr::Unlock() { g_pShaderAPI->UnlockTex( m_hSysMem ); g_pShaderAPI->UpdateTexture( 0, 0, SUBD_TEXTURE_WIDTH, m_nRowsLocked, m_hDefaultPool, m_hSysMem ); }
ShaderAPITextureHandle_t CSubDMgr::SubDTexture() { return m_hDefaultPool; }
|