diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /materialsystem/shaderapidx9/gpubufferallocator.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'materialsystem/shaderapidx9/gpubufferallocator.h')
| -rw-r--r-- | materialsystem/shaderapidx9/gpubufferallocator.h | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/materialsystem/shaderapidx9/gpubufferallocator.h b/materialsystem/shaderapidx9/gpubufferallocator.h new file mode 100644 index 0000000..cffd96d --- /dev/null +++ b/materialsystem/shaderapidx9/gpubufferallocator.h @@ -0,0 +1,146 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: CGPUBufferAllocator manages allocation of VBs/IBs from shared memory pools. +// Avoids 4KB physical alloc alignment overhead per VB/IB. +// +// $NoKeywords: $ +// +//===========================================================================// + + +#ifndef GPUBUFFERALLOCATOR_H +#define GPUBUFFERALLOCATOR_H + +#ifdef _WIN32 +#pragma once +#endif + +#ifdef _X360 + +#include "tier1/utlvector.h" +#include "tier1/convar.h" + +class CVertexBuffer; +class CIndexBuffer; + + +// Only active on X360 atm +#define USE_GPU_BUFFER_ALLOCATOR ( IsX360() ) + + +//----------------------------------------------------------------------------- +// A handle to a buffer pool allocation, held by the allocated VB/IB +//----------------------------------------------------------------------------- +struct GPUBufferHandle_t +{ + GPUBufferHandle_t( void ) : nPoolNum( -1 ), pMemory( NULL ), nPoolEntry( -1 ) {} + bool IsValid( void ) { return ( pMemory != NULL ); } + byte * pMemory; // Physical address of the allocation + int nPoolNum; // Identifies the pool + int nPoolEntry; // Identifies this allocation within the pool +}; + +//----------------------------------------------------------------------------- +// Describes an entry in a CGPUBufferPool +//----------------------------------------------------------------------------- +struct GPUBufferPoolEntry_t +{ + int nOffset; + int nSize; + bool bIsVertexBuffer; + union + { + // These are set to NULL by CGPUBufferPool::Free() (called when the VB/IB is destroyed) + CVertexBuffer *pVertexBuffer; + CIndexBuffer *pIndexBuffer; + }; +}; + +//----------------------------------------------------------------------------- +// A single memory block out of which individual VBs/IBs are allocated +//----------------------------------------------------------------------------- +class CGPUBufferPool +{ +public: + CGPUBufferPool( int nSize ); + virtual ~CGPUBufferPool( void ); + + // Returns the index (-1 on failure) of a new allocation in the pool, for a buffer of the given size. + int Allocate( int nSize, bool bIsVertexBuffer, void *pObject ); + // Frees a given entry (just marks it as freed, the memory will not be reused by Allocate() until CGPUBufferAllocator::Defrag() is called ) + void Deallocate( const GPUBufferHandle_t *pHandle ); + +private: + // NOTE: these values are specialized for X360 and should be #ifdef'd for other target platforms + static const int POOL_ENTRIES_INIT_SIZE = 256; + static const int POOL_ENTRIES_GROW_SIZE = 256; + static const int POOL_ENTRY_ALIGNMENT = 4; // 4-byte alignment required for VB/IB data on XBox360 + + byte * m_pMemory; // Pointer to the (physical) address of the pool's memory + int m_nSize; // Total size of the pool + int m_nBytesUsed; // High watermark of used memory in the pool + CUtlVector<GPUBufferPoolEntry_t>m_PoolEntries; // Memory-order array of items allocated in the pool + + // CGPUBufferAllocator is a friend so that CGPUBufferAllocator::Defrag() can shuffle allocations around + friend class CGPUBufferAllocator; +}; + +//----------------------------------------------------------------------------- +// Manages a set of memory blocks out of which individual VBs/IBs are allocated +//----------------------------------------------------------------------------- +class CGPUBufferAllocator +{ +public: + CGPUBufferAllocator( void ); + virtual ~CGPUBufferAllocator( void ); + + // (De)Allocates memory for a vertex/index buffer: + bool AllocateVertexBuffer( CVertexBuffer *pVertexBuffer, int nBufferSize ); + bool AllocateIndexBuffer( CIndexBuffer *pIndexBuffer, int nBufferSize ); + void DeallocateVertexBuffer( CVertexBuffer *pVertexBuffer ); + void DeallocateIndexBuffer( CIndexBuffer *pIndexBuffer ); + + // Compact memory to account for freed buffers + // NOTE: this must only be called during map transitions, no rendering must be in flight and everything must be single-threaded! + void Compact(); + + // Spew statistics about pooled buffer allocations + void SpewStats( bool bBrief = false ); + + +private: + // NOTE: these values are specialized for X360 and should be #ifdef'd for other target platforms + static const int INITIAL_POOL_SIZE = 57*1024*1024 + 256*1024; + static const int ADDITIONAL_POOL_SIZE = 2*1024*1024; + static const int MAX_POOLS = 8; + static const int MAX_BUFFER_SIZE = ADDITIONAL_POOL_SIZE; // 256*1024; + + + // Allocate a new CGPUBufferPool + bool AllocatePool( int nPoolSize ); + // Allocate/deallocate a buffer (type-agnostic) + bool AllocateBuffer( GPUBufferHandle_t *pHandle, int nBufferSize, void *pObject, bool bIsVertexBuffer ); + void DeallocateBuffer( const GPUBufferHandle_t *pHandle ); + // Make a handle for a given allocation + GPUBufferHandle_t MakeGPUBufferHandle( int nPoolNum, int nPoolEntry ); + // Helper for Compact + void MoveBufferMemory( int nDstPool, int *pnDstEntry, int *pnDstOffset, CGPUBufferPool &srcPool, GPUBufferPoolEntry_t &srcEntry ); + + + CGPUBufferPool *m_BufferPools[ MAX_POOLS ]; + int m_nBufferPools; + bool m_bEnabled; + + CThreadFastMutex m_mutex; +}; + + +// Track non-pooled physallocs, to help tune CGPUBufferAllocator usage: +extern CInterlockedInt g_NumIndividualIBPhysAllocs; +extern CInterlockedInt g_SizeIndividualIBPhysAllocs; +extern CInterlockedInt g_NumIndividualVBPhysAllocs; +extern CInterlockedInt g_SizeIndividualVBPhysAllocs; + +#endif // _X360 + +#endif // GPUBUFFERALLOCATOR_H |