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.
272 lines
7.6 KiB
272 lines
7.6 KiB
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
|
|
#ifndef IMATERIALSYSTEMINTERNAL_H
|
|
#define IMATERIALSYSTEMINTERNAL_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "materialsystem/imaterialsystem.h"
|
|
#include "tier1/callqueue.h"
|
|
#include "tier1/memstack.h"
|
|
#include "tier1/fmtstr.h"
|
|
|
|
#include "tier0/vprof_telemetry.h"
|
|
#include "tier0/perfstats.h"
|
|
|
|
class IMaterialInternal;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Special call queue that knows (a) single threaded access, and (b) all
|
|
// functions called after last function added
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CMatCallQueue
|
|
{
|
|
public:
|
|
CMatCallQueue()
|
|
{
|
|
static int nStackCount = 0;
|
|
CFmtStr stackName( "CMatCallQueue.m_Allocator[%d]", nStackCount++ );
|
|
#ifdef DEDICATED
|
|
m_Allocator.Init( (const char *)stackName, 2*1024, 0, 0, 4 );
|
|
#else
|
|
m_Allocator.Init( (const char *)stackName, ( IsGameConsole() || IsPlatformPosix() ) ? 2*1024*1024 : 8*1024*1024, 64*1024, 256*1024, 4 );
|
|
#endif
|
|
m_FunctorFactory.SetAllocator( &m_Allocator );
|
|
m_pHead = m_pTail = NULL;
|
|
}
|
|
|
|
size_t GetMemoryUsed()
|
|
{
|
|
return m_Allocator.GetUsed();
|
|
}
|
|
|
|
int Count()
|
|
{
|
|
int i = 0;
|
|
Elem_t *pCurrent = m_pHead;
|
|
while ( pCurrent )
|
|
{
|
|
i++;
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
template <typename T>
|
|
T &Copy( T &item )
|
|
{
|
|
T *pCopy = (T *)m_Allocator.Alloc( sizeof(T) );
|
|
memcpy( pCopy, &item, sizeof(T) );
|
|
return *pCopy;
|
|
}
|
|
|
|
template <typename T>
|
|
T *CopyArray( T *p, int n )
|
|
{
|
|
T *pCopy = (T *)m_Allocator.Alloc( sizeof(T) * n );
|
|
memcpy( (void *)pCopy, p, sizeof(T) * n );
|
|
return pCopy;
|
|
}
|
|
|
|
template <const char *>
|
|
const char *Copy( const char *psz )
|
|
{
|
|
int len = V_strlen( psz );
|
|
char *pCopy = (char *)m_Allocator.Alloc( len + 1 );
|
|
memcpy( pCopy, psz, len + 1 );
|
|
return pCopy;
|
|
|
|
}
|
|
|
|
void CallQueued()
|
|
{
|
|
TM_ZONE_PLOT( TELEMETRY_LEVEL1, "RenderThread", TELEMETRY_ZONE_PLOT_SLOT_2 );
|
|
PERF_STATS_BLOCK( "RenderThread", PERF_STATS_SLOT_RENDERTHREAD );
|
|
if ( !m_pHead )
|
|
{
|
|
return;
|
|
}
|
|
|
|
CFunctor *pFunctor;
|
|
|
|
Elem_t *pCurrent = m_pHead;
|
|
while ( pCurrent )
|
|
{
|
|
pFunctor = pCurrent->GetFunctor();
|
|
#ifdef _DEBUG
|
|
if ( pFunctor->m_nUserID == m_nBreakSerialNumber)
|
|
{
|
|
m_nBreakSerialNumber = (unsigned)-1;
|
|
}
|
|
#endif
|
|
if ( pCurrent->pNext )
|
|
{
|
|
PREFETCH360( pCurrent->pNext, 0 );
|
|
PREFETCH360( pCurrent->pNext, 128 );
|
|
}
|
|
(*pFunctor)();
|
|
pFunctor->~CFunctor(); // no need to ref count, we're alone here...
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
#ifdef DEBUG_MATCALLQUEUE
|
|
static int prevHigh = 0;
|
|
if ( m_Allocator.GetUsed() > prevHigh )
|
|
{
|
|
Msg( "***%d\n", m_Allocator.GetUsed() );
|
|
prevHigh = m_Allocator.GetUsed();
|
|
}
|
|
#endif
|
|
m_Allocator.FreeAll( false );
|
|
m_pHead = m_pTail = NULL;
|
|
}
|
|
|
|
void QueueFunctor( CFunctor *pFunctor )
|
|
{
|
|
Assert( pFunctor );
|
|
m_Allocator.Alloc( sizeof(Elem_t) );
|
|
QueueFunctorInternal( m_FunctorFactory.CreateRefCountingFunctor( pFunctor, &CFunctor::operator() ) );
|
|
}
|
|
|
|
void Flush()
|
|
{
|
|
if ( !m_pHead )
|
|
{
|
|
return;
|
|
}
|
|
|
|
CFunctor *pFunctor;
|
|
|
|
Elem_t *pCurrent = m_pHead;
|
|
while ( pCurrent )
|
|
{
|
|
pFunctor = pCurrent->GetFunctor();
|
|
pFunctor->Release();
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
|
|
m_Allocator.FreeAll( false );
|
|
m_pHead = m_pTail = NULL;
|
|
}
|
|
|
|
#define DEFINE_MATCALLQUEUE_NONMEMBER_QUEUE_CALL(N) \
|
|
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
|
|
void QueueCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
|
|
{ \
|
|
m_Allocator.Alloc( sizeof(Elem_t) ); \
|
|
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
|
|
}
|
|
|
|
//-------------------------------------
|
|
|
|
#define DEFINE_MATCALLQUEUE_MEMBER_QUEUE_CALL(N) \
|
|
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
|
|
void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
|
|
{ \
|
|
m_Allocator.Alloc( sizeof(Elem_t) ); \
|
|
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
|
|
}
|
|
|
|
//-------------------------------------
|
|
|
|
#define DEFINE_MATCALLQUEUE_CONST_MEMBER_QUEUE_CALL(N) \
|
|
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
|
|
void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
|
|
{ \
|
|
m_Allocator.Alloc( sizeof(Elem_t) ); \
|
|
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
|
|
}
|
|
|
|
//-------------------------------------
|
|
|
|
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_NONMEMBER_QUEUE_CALL );
|
|
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_MEMBER_QUEUE_CALL );
|
|
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_CONST_MEMBER_QUEUE_CALL );
|
|
|
|
private:
|
|
void QueueFunctorInternal( CFunctor *pFunctor )
|
|
{
|
|
#ifdef _DEBUG
|
|
pFunctor->m_nUserID = m_nCurSerialNumber++;
|
|
#endif
|
|
MEM_ALLOC_CREDIT_( "CMatCallQueue.m_Allocator" );
|
|
// Caller is expected to have preallocated Elem_t entry immediately prior to functor
|
|
Elem_t *pNew = ((Elem_t *)pFunctor) - 1;
|
|
if ( m_pTail )
|
|
{
|
|
m_pTail->pNext = pNew;
|
|
m_pTail = pNew;
|
|
}
|
|
else
|
|
{
|
|
m_pHead = m_pTail = pNew;
|
|
}
|
|
pNew->pNext = NULL;
|
|
}
|
|
|
|
struct Elem_t
|
|
{
|
|
Elem_t *pNext;
|
|
CFunctor *GetFunctor() { return (CFunctor *)(this + 1 ); }
|
|
};
|
|
|
|
Elem_t *m_pHead;
|
|
Elem_t *m_pTail;
|
|
|
|
CMemoryStack m_Allocator;
|
|
CCustomizedFunctorFactory<CMemoryStack, CRefCounted1<CFunctor, CRefCountServiceDestruct< CRefST > > > m_FunctorFactory;
|
|
unsigned m_nCurSerialNumber;
|
|
unsigned m_nBreakSerialNumber;
|
|
};
|
|
|
|
#define MATCONFIG_FLAGS_SUPPORT_EDITOR ( 1 << 0 )
|
|
#define MATCONFIG_FLAGS_SUPPORT_GBUFFER ( 1 << 1 )
|
|
//-----------------------------------------------------------------------------
|
|
// Additional interfaces used internally to the library
|
|
//-----------------------------------------------------------------------------
|
|
abstract_class IMaterialSystemInternal : public IMaterialSystem
|
|
{
|
|
public:
|
|
// Returns the current material
|
|
virtual IMaterial* GetCurrentMaterial() = 0;
|
|
|
|
virtual int GetLightmapPage( void ) = 0;
|
|
|
|
// Gets the maximum lightmap page size...
|
|
virtual int GetLightmapWidth( int lightmap ) const = 0;
|
|
virtual int GetLightmapHeight( int lightmap ) const = 0;
|
|
|
|
virtual ITexture *GetLocalCubemap( void ) = 0;
|
|
|
|
// virtual bool RenderZOnlyWithHeightClipEnabled( void ) = 0;
|
|
virtual void ForceDepthFuncEquals( bool bEnable ) = 0;
|
|
virtual enum MaterialHeightClipMode_t GetHeightClipMode( void ) = 0;
|
|
|
|
// FIXME: Remove? Here for debugging shaders in CShaderSystem
|
|
virtual void AddMaterialToMaterialList( IMaterialInternal *pMaterial ) = 0;
|
|
virtual void RemoveMaterial( IMaterialInternal *pMaterial ) = 0;
|
|
virtual void RemoveMaterialSubRect( IMaterialInternal *pMaterial ) = 0;
|
|
virtual bool InFlashlightMode() const = 0;
|
|
virtual bool IsCascadedShadowMapping() const = 0;
|
|
|
|
// Can we use editor materials?
|
|
virtual bool CanUseEditorMaterials() const = 0;
|
|
virtual int GetConfigurationFlags( void ) const = 0;
|
|
virtual const char *GetForcedTextureLoadPathID() = 0;
|
|
|
|
virtual CMatCallQueue *GetRenderCallQueue() = 0;
|
|
|
|
virtual void UnbindMaterial( IMaterial *pMaterial ) = 0;
|
|
virtual uint GetRenderThreadId() const = 0 ;
|
|
};
|
|
|
|
|
|
#endif // IMATERIALSYSTEMINTERNAL_H
|