Skip to content

Commit

Permalink
ShaderAST: Added ast::ShaderAllocator
Browse files Browse the repository at this point in the history
  • Loading branch information
DragonJoker committed Sep 29, 2023
1 parent 8b101ec commit 9a15195
Show file tree
Hide file tree
Showing 107 changed files with 2,146 additions and 1,319 deletions.
1 change: 1 addition & 0 deletions include/CompilerGlsl/compileGlsl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ namespace glsl
bool hasShaderStorageBuffers{ false };
bool hasDescriptorSets{ false };
bool hasBaseInstance{ false };
ast::ShaderAllocator * allocator{};
// Filled by writeSpirv/serialiseSpirv
uint32_t requiredVersion{ vUnk };
GlslExtensionSet requiredExtensions{};
Expand Down
1 change: 1 addition & 0 deletions include/CompilerHlsl/compileHlsl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace hlsl
uint32_t shaderModel{ v5_0 };
ast::ShaderStage shaderStage;
bool flipVertY{ false };
ast::ShaderAllocator * allocator{};
};

SDWHLSL_API std::string compileHlsl( ast::Shader const & shader
Expand Down
14 changes: 14 additions & 0 deletions include/CompilerSpirV/compileSpirV.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,25 @@ namespace spirv
{
uint32_t specVersion{ v1_1 };
SpirVExtensionSet * availableExtensions{};
ast::ShaderAllocator * allocator{};
// Filled by writeSpirv/serialiseSpirv
uint32_t requiredVersion{ vUnk };
SpirVExtensionSet requiredExtensions{};
};

class Module;
struct ModuleDeleter
{
SDWSPIRV_API void operator()( Module * module );
};
using ModulePtr = std::unique_ptr< Module, ModuleDeleter >;

SDWSPIRV_API ModulePtr compileSpirV( ast::Shader const & shader
, SpirVConfig & config );
SDWSPIRV_API std::string writeModule( Module const & module
, bool writeHeader = true );
SDWSPIRV_API std::vector< uint32_t > serialiseModule( Module const & module );

SDWSPIRV_API std::string writeSpirv( ast::Shader const & shader
, SpirVConfig & config
, bool writeHeader = true );
Expand Down
32 changes: 5 additions & 27 deletions include/ShaderAST/Expr/ExprCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ See LICENSE file in root folder
#define ___AST_ExprCache_H___
#pragma once

#include "ShaderAST/ShaderAllocator.hpp"
#include "ShaderAST/Type/TypeCache.hpp"
#include "ShaderAST/Expr/EnumCombinedImageAccess.hpp"
#include "ShaderAST/Expr/EnumIntrinsic.hpp"
Expand All @@ -16,21 +17,12 @@ See LICENSE file in root folder
#include <unordered_map>
#include <vector>

namespace ast
{
enum class CacheMode
{
eNone,
eArena
};
}

namespace ast::expr
{
class ExprCache
{
public:
SDAST_API ExprCache( CacheMode cacheMode = CacheMode::eArena );
SDAST_API ExprCache( ShaderAllocatorBlock & allocator );
SDAST_API ~ExprCache() = default;

SDAST_API AddPtr makeAdd( type::TypePtr type, ExprPtr lhs, ExprPtr rhs );
Expand Down Expand Up @@ -158,31 +150,17 @@ namespace ast::expr
, typename ... ParamsT >
std::unique_ptr< ExprT, DeleteExpr > makeExpr( ParamsT && ... params )
{
auto mem = allocExpr( sizeof( ExprT ) );
auto mem = m_allocator.allocate( sizeof( ExprT ) );
return std::unique_ptr< ExprT, DeleteExpr >{ new ( mem )ExprT{ *this, std::forward< ParamsT >( params )... } };
}

private:
friend struct DeleteExpr;

SDAST_API void * allocExpr( size_t size );
void freeExpr( Expr * expr );
void freeExpr( Expr * expr )noexcept;

private:
CacheMode m_cacheMode{};

struct Memory
{
Memory()
: data{ std::make_unique< std::vector< std::byte > >( 1024 * 1024 ) }
{
}

std::unique_ptr< std::vector< std::byte > > data;
size_t index{};
};
std::vector< Memory > m_memory;
Memory * m_currentMemory{};
ShaderAllocatorBlock & m_allocator;
};
}

Expand Down
10 changes: 9 additions & 1 deletion include/ShaderAST/Shader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ namespace ast
class Shader
{
public:
SDAST_API explicit Shader( ast::ShaderStage type );
SDAST_API explicit Shader( ast::ShaderStage type
, ShaderAllocator * allocator = nullptr );
SDAST_API void push( stmt::Container * container
, ast::var::VariableList vars );
SDAST_API void pop();
Expand Down Expand Up @@ -304,6 +305,11 @@ namespace ast
return *m_stmtCache;
}

ShaderAllocatorBlock & getAllocator()const
{
return *m_allocator;
}

ShaderData const & getData()const
{
return m_data;
Expand All @@ -319,6 +325,8 @@ namespace ast
stmt::Container * container;
};
ast::ShaderStage m_type;
std::unique_ptr< ShaderAllocator > m_ownAllocator;
ShaderAllocatorBlockPtr m_allocator;
std::unique_ptr< ast::type::TypesCache > m_typesCache;
std::unique_ptr< ast::stmt::StmtCache > m_stmtCache;
std::unique_ptr< ast::expr::ExprCache > m_exprCache;
Expand Down
5 changes: 5 additions & 0 deletions include/ShaderAST/ShaderASTPrerequisites.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ See LICENSE file in root folder

namespace ast
{
class ShaderAllocator;
class ShaderAllocatorBlock;

using ShaderAllocatorBlockPtr = std::unique_ptr< ShaderAllocatorBlock >;

enum class ShaderStage
{
eVertex,
Expand Down
167 changes: 167 additions & 0 deletions include/ShaderAST/ShaderAllocator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
See LICENSE file in root folder
*/
#ifndef ___AST_ShaderAllocator_H___
#define ___AST_ShaderAllocator_H___
#pragma once

#include "ShaderASTPrerequisites.hpp"

#include <memory>
#include <vector>

namespace ast
{
class BuddyAllocator
{
private:
using PointerType = std::byte *;

public:
/**
* Constructor.
*\param[in] numLevels
* The allocator maximum tree size.
*\param[in] minBlockSize
* The minimum size for a block.
*/
BuddyAllocator( uint32_t numLevels
, uint32_t minBlockSize );
/**
* Reports memory leaks.
*/
~BuddyAllocator();
/**
*\param[in] size
* The requested memory size.
*\return
* \p true if there is enough remaining memory for given size.
*/
bool hasAvailable( size_t size )const;
/**
* Allocates memory.
*\param[in] size
* The requested memory size.
*\return
* The memory chunk.
*/
PointerType allocate( size_t size );
/**
* Deallocates memory.
*\param[in] pointer
* The memory chunk.
*/
bool deallocate( PointerType pointer );
/**
*\return
* The pool total size.
*/
size_t getTotalSize()const;

size_t getAlignSize()const;
PointerType getPointer( uint32_t offset );
size_t getOffset( PointerType pointer )const;

private:
uint32_t doGetLevel( size_t size )const;
size_t doGetLevelSize( uint32_t level )const;
PointerType doAllocate( uint32_t level );
void doMergeLevel( PointerType const & block
, uint32_t index
, uint32_t level );

private:
using FreeList = std::list< PointerType >;
using PointerLevel = std::pair< size_t, uint32_t >;

private:
std::vector< std::byte > m_memory;
uint32_t m_numLevels;
uint32_t m_minBlockSize;
std::vector< FreeList > m_freeLists;
std::vector< PointerLevel > m_allocated;
};

class ShaderAllocator;

enum class AllocationMode
{
eNone,
eIncremental,
eFragmented
};

struct MemoryCursor
{
ptrdiff_t index{};
size_t offset{};
};

class ShaderAllocatorBlock
{
public:
SDAST_API explicit ShaderAllocatorBlock( ShaderAllocator & allocator )noexcept;
SDAST_API ShaderAllocatorBlock( ShaderAllocatorBlock const & rhs ) = delete;
SDAST_API ShaderAllocatorBlock & operator=( ShaderAllocatorBlock const & rhs ) = delete;
SDAST_API ShaderAllocatorBlock( ShaderAllocatorBlock && rhs )noexcept;
SDAST_API ShaderAllocatorBlock & operator=( ShaderAllocatorBlock && rhs )noexcept;
SDAST_API ~ShaderAllocatorBlock()noexcept;

SDAST_API void * allocate( size_t size );
SDAST_API void deallocate( void * mem, size_t size )noexcept;

SDAST_API size_t report()const;

private:
ShaderAllocator * m_allocator;
MemoryCursor m_savedCursor{};
};

class ShaderAllocator
{
friend class ShaderAllocatorBlock;

public:
SDAST_API ShaderAllocator( AllocationMode allocationMode = AllocationMode::eFragmented );
SDAST_API ~ShaderAllocator() = default;

SDAST_API void * allocate( size_t size );
SDAST_API void deallocate( void * mem, size_t size )noexcept;

SDAST_API MemoryCursor getCursor()const noexcept;
SDAST_API size_t getMemDiff( MemoryCursor const & cursor )const noexcept;
SDAST_API size_t report()const;

SDAST_API ShaderAllocatorBlockPtr getBlock()
{
return std::make_unique< ShaderAllocatorBlock >( *this );
}

private:
struct Memory
{
static size_t constexpr BlockAllocSize = 1024 * 1024;

Memory()
: data{ std::make_unique< std::vector< std::byte > >( BlockAllocSize ) }
{
}

std::unique_ptr< std::vector< std::byte > > data;
size_t offset{};
};

private:
void flushTo( MemoryCursor const & cursor );

private:
AllocationMode m_allocationMode{};
std::unordered_map< size_t, std::unique_ptr< BuddyAllocator > > m_buddies;
std::vector< Memory > m_memory;
std::vector< Memory > m_pending;
Memory * m_currentMemory{};
size_t m_maxAllocated{};
};
}

#endif
23 changes: 5 additions & 18 deletions include/ShaderAST/Stmt/StmtCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ See LICENSE file in root folder
#define ___AST_StmtCache_H___
#pragma once

#include "ShaderAST/ShaderAllocator.hpp"
#include "ShaderAST/Expr/ExprCache.hpp"
#include "ShaderAST/Stmt/PreprocExtension.hpp"
#include "ShaderAST/Stmt/StmtFunctionDecl.hpp"
Expand All @@ -18,7 +19,7 @@ namespace ast::stmt
class StmtCache
{
public:
SDAST_API StmtCache( CacheMode cacheMode = CacheMode::eArena );
SDAST_API StmtCache( ShaderAllocatorBlock & allocator );
SDAST_API ~StmtCache() = default;

SDAST_API PreprocDefinePtr makePreprocDefine( EntityName nameId, std::string name, expr::ExprPtr expr );
Expand Down Expand Up @@ -88,31 +89,17 @@ namespace ast::stmt
template< typename StmtT, typename ... ParamsT >
std::unique_ptr< StmtT, DeleteStmt > makeStmt( ParamsT && ... params )
{
auto mem = allocStmt( sizeof( StmtT ) );
auto mem = m_allocator.allocate( sizeof( StmtT ) );
return std::unique_ptr< StmtT, DeleteStmt >{ new ( mem )StmtT{ *this, std::forward< ParamsT >( params )... } };
}

private:
friend struct DeleteStmt;

SDAST_API void * allocStmt( size_t size );
void freeStmt( Stmt * stmt );
void freeStmt( Stmt * stmt )noexcept;

private:
CacheMode m_cacheMode{};

struct Memory
{
Memory()
: data{ std::make_unique< std::vector< std::byte > >( 1024 * 1024 ) }
{
}

std::unique_ptr< std::vector< std::byte > > data;
size_t index{};
};
std::vector< Memory > m_memory;
Memory * m_currentMemory{};
ShaderAllocatorBlock & m_allocator;
};
}

Expand Down
2 changes: 2 additions & 0 deletions include/ShaderWriter/BaseTypes/AccelerationStructure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace sdw
SDW_API ~AccelerationStructure()override = default;
SDW_API AccelerationStructure( AccelerationStructure && rhs ) = default;
SDW_API AccelerationStructure( AccelerationStructure const & rhs ) = default;
SDW_API AccelerationStructure & operator=( AccelerationStructure && rhs ) = default;
SDW_API AccelerationStructure & operator=( AccelerationStructure const & rhs ) = default;

SDW_API static ast::type::TypePtr makeType( ast::type::TypesCache & cache );
};
Expand Down
2 changes: 1 addition & 1 deletion include/ShaderWriter/CallableWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace sdw
: public ShaderWriter
{
public:
SDW_API CallableWriter();
SDW_API explicit CallableWriter( ShaderAllocator * allocator = nullptr );

template< typename ValueT >
void implementMainT( uint32_t dataLocation
Expand Down
2 changes: 1 addition & 1 deletion include/ShaderWriter/ComputeWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ namespace sdw
: public ShaderWriter
{
public:
SDW_API ComputeWriter();
SDW_API explicit ComputeWriter( ShaderAllocator * allocator = nullptr );

SDW_API void implementMain( uint32_t localSizeX
, ComputeMainFuncT< VoidT > const & function );
Expand Down
Loading

0 comments on commit 9a15195

Please sign in to comment.