clean: Mass renames, format, fixed scheme.

This commit is contained in:
Anish Bhobe 2025-07-02 15:45:56 +02:00
parent 6d19360f3f
commit d6907f0503
28 changed files with 1585 additions and 1543 deletions

View File

@ -21,6 +21,7 @@ AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false BinPackArguments: false
BinPackParameters: false BinPackParameters: false
PackConstructorInitializers: CurrentLine
BraceWrapping: BraceWrapping:
AfterCaseLabel: true AfterCaseLabel: true
AfterClass: true AfterClass: true
@ -42,7 +43,8 @@ BraceWrapping:
SplitEmptyNamespace: false SplitEmptyNamespace: false
BreakConstructorInitializers: BeforeComma BreakConstructorInitializers: BeforeComma
ConstructorInitializerIndentWidth: 2 ConstructorInitializerIndentWidth: 2
Cpp11BracedListStyle: false ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
IncludeCategories: IncludeCategories:
- Regex: ^<.* - Regex: ^<.*
Priority: 1 Priority: 1
@ -70,4 +72,4 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesInConditionalStatement: true SpacesInConditionalStatement: true
SpacesInCStyleCastParentheses: false SpacesInCStyleCastParentheses: false
AlignArrayOfStructures: Right AlignArrayOfStructures: Left

View File

@ -1,4 +1,27 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020methods/@EntryIndexedValue">&lt;NamingElement Priority="10"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="member function" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aa_bb" /&gt;&lt;/Policy&gt;&lt;/NamingElement&gt;</s:String> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Local_0020variables/@EntryIndexedValue">&lt;NamingElement Priority="7"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="local variable" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String> <s:String x:Key="/Default/CodeStyle/CodeFormatting/CppClangFormat/ExecutableToUse/@EntryValue">FromPath</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Parameters/@EntryIndexedValue">&lt;NamingElement Priority="6"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="function parameter" /&gt;&lt;type Name="lambda parameter" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020fields/@EntryIndexedValue">&lt;NamingElement Priority="11"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="class field" /&gt;&lt;type Name="struct field" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="m_" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020methods/@EntryIndexedValue">&lt;NamingElement Priority="10"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="member function" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aa_bb" /&gt;&lt;/Policy&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020public_0020fields/@EntryIndexedValue">&lt;NamingElement Priority="12"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="PUBLIC"&gt;&lt;type Name="class field" /&gt;&lt;type Name="struct field" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Classes_0020and_0020structs/@EntryIndexedValue">&lt;NamingElement Priority="1"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="__interface" /&gt;&lt;type Name="class" /&gt;&lt;type Name="enum" /&gt;&lt;type Name="struct" /&gt;&lt;type Name="union" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Concepts/@EntryIndexedValue">&lt;NamingElement Priority="2"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE" /&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Enum_0020members/@EntryIndexedValue">&lt;NamingElement Priority="14"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="scoped enumerator" /&gt;&lt;type Name="unscoped enumerator" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="k" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Enums/@EntryIndexedValue">&lt;NamingElement Priority="3"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="enum" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Global_0020constants/@EntryIndexedValue">&lt;NamingElement Priority="16"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="global variable" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Global_0020functions/@EntryIndexedValue">&lt;NamingElement Priority="9"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="global function" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Global_0020variables/@EntryIndexedValue">&lt;NamingElement Priority="8"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="global variable" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="g_" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Macros/@EntryIndexedValue">&lt;NamingElement Priority="19"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="macro" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Namespaces/@EntryIndexedValue">&lt;NamingElement Priority="17"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="namespace" /&gt;&lt;type Name="namespace alias" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Other_0020constants/@EntryIndexedValue">&lt;NamingElement Priority="15"&gt;&lt;Descriptor Static="True" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="class field" /&gt;&lt;type Name="local variable" /&gt;&lt;type Name="struct field" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="k" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Typedefs/@EntryIndexedValue">&lt;NamingElement Priority="18"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="type alias" /&gt;&lt;type Name="typedef" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aa_bb" /&gt;&lt;/Policy&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Union_0020members/@EntryIndexedValue">&lt;NamingElement Priority="13"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="union member" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Unions/@EntryIndexedValue">&lt;NamingElement Priority="4"&gt;&lt;Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"&gt;&lt;type Name="union" /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/NamingElement&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=BE90B2EAA41A844C846175EA311A0E8C/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=BE90B2EAA41A844C846175EA311A0E8C/AbsolutePath/@EntryValue">C:\Users\Eon\source\repos\Blaze\Blaze.sln.DotSettings</s:String>
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=BE90B2EAA41A844C846175EA311A0E8C/RelativePath/@EntryValue"></s:String>
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileBE90B2EAA41A844C846175EA311A0E8C/@KeyIndexDefined">True</s:Boolean>
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileBE90B2EAA41A844C846175EA311A0E8C/RelativePriority/@EntryValue">1</s:Double></wpf:ResourceDictionary>

View File

@ -202,7 +202,6 @@
<ClCompile Include="Source\MiscData.cpp" /> <ClCompile Include="Source\MiscData.cpp" />
<ClCompile Include="Source\ModelLoader.cpp" /> <ClCompile Include="Source\ModelLoader.cpp" />
<ClCompile Include="Source\RenderDevice.cpp" /> <ClCompile Include="Source\RenderDevice.cpp" />
<ClCompile Include="Source\RID.cpp" />
<ClCompile Include="Source\StbImpl.cpp" /> <ClCompile Include="Source\StbImpl.cpp" />
<ClCompile Include="Source\TextureManager.cpp" /> <ClCompile Include="Source\TextureManager.cpp" />
<ClCompile Include="Source\VmaImpl.cpp" /> <ClCompile Include="Source\VmaImpl.cpp" />
@ -219,7 +218,6 @@
<ClInclude Include="Source\FreeList.h" /> <ClInclude Include="Source\FreeList.h" />
<ClInclude Include="Source\GlobalMemory.h" /> <ClInclude Include="Source\GlobalMemory.h" />
<ClInclude Include="Source\MacroUtils.h" /> <ClInclude Include="Source\MacroUtils.h" />
<ClInclude Include="Source\MathUtil.h" />
<ClInclude Include="Source\MiscData.h" /> <ClInclude Include="Source\MiscData.h" />
<ClInclude Include="Source\ModelLoader.h" /> <ClInclude Include="Source\ModelLoader.h" />
<ClInclude Include="Source\RenderDevice.h" /> <ClInclude Include="Source\RenderDevice.h" />

View File

@ -8,80 +8,73 @@
#include "RenderDevice.h" #include "RenderDevice.h"
#include "TextureManager.h" #include "TextureManager.h"
bool AppState::isInit() const namespace Blaze
{ {
return window and renderDevice and renderDevice->isInit();
bool AppState::IsInit() const
{
return window and renderDevice and renderDevice->IsInit();
} }
void AppState::destroy() void AppState::Destroy()
{ {
if ( !isInit() ) return; if ( !IsInit() ) return;
renderDevice->waitIdle(); renderDevice->WaitIdle();
Take( miscData )->destroy( *renderDevice ); Take( miscData )->Destroy( *renderDevice );
Take( entityManager )->destroy(); Take( entityManager )->Destroy();
Take( renderDevice )->destroy(); Take( renderDevice )->Destroy();
SDL_DestroyWindow( Take( window ) ); SDL_DestroyWindow( Take( window ) );
} }
AppState::AppState( SDL_Window* window, RenderDevice* renderDevice, EntityManager* entityManager, MiscData* miscData ) AppState::AppState(
SDL_Window* window, RenderDevice* render_device, EntityManager* entity_manager, MiscData* misc_data )
: window{ window } : window{ window }
, renderDevice{ renderDevice } , renderDevice{ render_device }
, entityManager{ entityManager } , entityManager{ entity_manager }
, miscData{ miscData } , miscData{ misc_data }
, sprintfBuffer{ 0 } , sprintfBuffer{ 0 }
{} {}
AppState* AppState_Create( GlobalMemory* memory, uint32_t const width, uint32_t const height ) AppState* AppState::Create( GlobalMemory* memory, uint32_t width, uint32_t height )
{ {
SDL_Window* window = SDL_Window* window =
SDL_CreateWindow( "Blaze Test", static_cast<int>( width ), static_cast<int>( height ), SDL_WINDOW_VULKAN ); SDL_CreateWindow( "Blaze Test", static_cast<int>( width ), static_cast<int>( height ), SDL_WINDOW_VULKAN );
if ( !window ) ASSERT( window );
{
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "%s", SDL_GetError() );
return nullptr;
}
RenderDevice* renderDevice = RenderDevice_Create( memory, { .window = window } ); RenderDevice* render_device = RenderDevice::Create( memory, { .window = window } );
if ( !renderDevice or !renderDevice->isInit() ) ASSERT( render_device );
{
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "RenderDevice failed to init" );
SDL_DestroyWindow( window );
return nullptr;
}
EntityManager* entityManager = EntityManager_Create( memory, renderDevice, 1000 ); EntityManager* entity_manager = EntityManager::Create( memory, render_device, 1000 );
if ( !entityManager ) ASSERT( entity_manager );
{
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "EntityManager failed to init" );
renderDevice->destroy();
SDL_DestroyWindow( window );
return nullptr;
}
auto* miscDataAllocation = memory->allocate( sizeof( MiscData ) ); byte* misc_data_allocation = memory->Allocate( sizeof( MiscData ) );
MiscData* miscData = new ( miscDataAllocation ) MiscData{}; MiscData* misc_data = new ( misc_data_allocation ) MiscData{};
if ( !miscData->init( *renderDevice ) ) if ( !misc_data->Init( *render_device ) )
{ {
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "MiscData failed to init" ); SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "MiscData failed to init" );
entityManager->destroy(); entity_manager->Destroy();
renderDevice->destroy(); render_device->Destroy();
SDL_DestroyWindow( window ); SDL_DestroyWindow( window );
ASSERT( false );
return nullptr; return nullptr;
} }
auto* allocation = memory->allocate( sizeof( AppState ) ); byte* allocation = memory->Allocate( sizeof( AppState ) );
AppState* appState = new ( allocation ) AppState{ window, renderDevice, entityManager, miscData }; AppState* app_state = new ( allocation ) AppState{ window, render_device, entity_manager, misc_data };
return appState; return app_state;
} }
#if defined( DTOR_TEST )
AppState::~AppState() AppState::~AppState()
{ {
ASSERT( not isInit() ); ASSERT( not IsInit() );
} }
#endif
} // namespace Blaze

View File

@ -2,14 +2,16 @@
#include <cstdint> #include <cstdint>
// ReSharper disable once CppInconsistentNaming
struct SDL_Window; struct SDL_Window;
namespace Blaze
{
struct GlobalMemory; struct GlobalMemory;
struct MiscData;
struct RenderDevice; struct RenderDevice;
struct EntityManager; struct EntityManager;
struct TextureManager;
struct MiscData;
struct AppState struct AppState
{ {
@ -19,18 +21,16 @@ struct AppState
MiscData* miscData; MiscData* miscData;
char sprintfBuffer[256]; char sprintfBuffer[256];
[[nodiscard]] bool isInit() const; [[nodiscard]] bool IsInit() const;
void destroy();
AppState( SDL_Window* window, RenderDevice* renderDevice, EntityManager* entityManager, MiscData* miscData ); static AppState* Create( GlobalMemory* memory, uint32_t width, uint32_t height );
void Destroy();
AppState( AppState const& other ) = delete; AppState( SDL_Window* window, RenderDevice* render_device, EntityManager* entity_manager, MiscData* misc_data );
AppState( AppState&& other ) noexcept = delete;
AppState& operator=( AppState const& other ) = delete;
AppState& operator=( AppState&& other ) noexcept = delete;
#if defined( DTOR_TEST )
~AppState(); ~AppState();
#endif
}; };
AppState* AppState_Create( GlobalMemory* memory, uint32_t width, uint32_t height ); } // namespace Blaze

View File

@ -9,7 +9,6 @@
#define SDL_MAIN_USE_CALLBACKS 1 #define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_main.h> #include <SDL3/SDL_main.h>
#include <SDL3/SDL_vulkan.h> #include <SDL3/SDL_vulkan.h>
@ -20,7 +19,6 @@
#include "Frame.h" #include "Frame.h"
#include "GlobalMemory.h" #include "GlobalMemory.h"
#include "MacroUtils.h" #include "MacroUtils.h"
#include "MathUtil.h"
#include "MiscData.h" #include "MiscData.h"
#include "RenderDevice.h" #include "RenderDevice.h"
@ -35,189 +33,193 @@ namespace Blaze::Global
GlobalMemory g_Memory; GlobalMemory g_Memory;
} }
// ReSharper disable once CppInconsistentNaming
SDL_AppResult SDL_AppInit( void** appstate, int, char** ) SDL_AppResult SDL_AppInit( void** appstate, int, char** )
{ {
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS ); SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS );
Blaze::Global::g_Memory.init( 128_MiB ); using Blaze::operator""_MiB;
*appstate = AppState_Create( &Blaze::Global::g_Memory, WIDTH, HEIGHT ); Blaze::Global::g_Memory.Initialize( 128_MiB );
*appstate = Blaze::AppState::Create( &Blaze::Global::g_Memory, WIDTH, HEIGHT );
if ( !*appstate ) return SDL_APP_FAILURE; if ( !*appstate ) return SDL_APP_FAILURE;
AppState& appState = *static_cast<AppState*>( *appstate ); Blaze::AppState const& app_state = *static_cast<Blaze::AppState*>( *appstate );
Entity const* entity = LoadModel( appState.renderDevice, appState.entityManager, "Assets/Models/DamagedHelmet.glb" ); Blaze::Entity const* entity =
LoadModel( app_state.renderDevice, app_state.entityManager, "Assets/Models/DamagedHelmet.glb" );
ASSERT( entity ); ASSERT( entity );
std::array pointLight = { Blaze::MiscData::PointLight point_light[] = {
MiscData::PointLight{ {
.position = { 12.0f, 0.0f, 0.0f }, .position = { 12.0f, 0.0f, 0.0f },
.range = 12, .range = 12,
.color = { 1.0f, 0.0f, 0.0f }, .color = { 1.0f, 0.0f, 0.0f },
.attenuation = 1.0f, .attenuation = 1.0f,
}, },
MiscData::PointLight{ {
.position = { 0.0f, 3.0f, 0.0f }, .position = { 0.0f, 3.0f, 0.0f },
.range = 12, .range = 12,
.color = { 12.0f, 12.0f, 12.0f }, .color = { 12.0f, 12.0f, 12.0f },
.attenuation = 1.0f, .attenuation = 1.0f,
}, },
MiscData::PointLight{ {
.position = { 0.0f, 0.0f, -12.0f }, .position = { 0.0f, 0.0f, -12.0f },
.range = 6, .range = 6,
.color = { 0.0f, 0.0f, 1.0f }, .color = { 0.0f, 0.0f, 1.0f },
.attenuation = 1.0f, .attenuation = 1.0f,
}, },
}; };
appState.miscData->lightData.pointLightCount = static_cast<uint32_t>( pointLight.size() ); app_state.miscData->lightData.pointLightCount = _countof( point_light );
appState.renderDevice->bufferManager->writeToBuffer( app_state.renderDevice->bufferManager->WriteToBuffer( app_state.miscData->pointLights, point_light );
appState.miscData->pointLights, std::span{ pointLight.begin(), pointLight.end() } );
memcpy( memcpy(
appState.miscData->cameraUniformBufferPtr + sizeof( MiscData::CameraData ), app_state.miscData->cameraUniformBufferPtr + sizeof( Blaze::MiscData::CameraData ),
&appState.miscData->lightData, &app_state.miscData->lightData,
sizeof appState.miscData->lightData ); sizeof app_state.miscData->lightData );
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
// ReSharper disable once CppInconsistentNaming
SDL_AppResult SDL_AppIterate( void* appstate ) SDL_AppResult SDL_AppIterate( void* appstate )
{ {
AppState& appState = *static_cast<AppState*>( appstate ); Blaze::AppState& app_state = *static_cast<Blaze::AppState*>( appstate );
RenderDevice& renderDevice = *appState.renderDevice; Blaze::RenderDevice& render_device = *app_state.renderDevice;
EntityManager& entityManager = *appState.entityManager; Blaze::EntityManager& entity_manager = *app_state.entityManager;
MiscData& misc = *appState.miscData; Blaze::MiscData& misc = *app_state.miscData;
Frame& currentFrame = renderDevice.frames[renderDevice.frameIndex]; Blaze::Frame& current_frame = render_device.frames[render_device.frameIndex];
VK_CHECK( vkWaitForFences( renderDevice.device, 1, &currentFrame.frameReadyToReuse, VK_TRUE, UINT32_MAX ) ); VK_CHECK( vkWaitForFences( render_device.device, 1, &current_frame.frameReadyToReuse, VK_TRUE, UINT32_MAX ) );
// All resources of frame 'frameIndex' are free. // All resources of frame 'frameIndex' are free.
// time calc // time calc
uint64_t const previousCounter = misc.previousCounter; uint64_t const previous_counter = misc.previousCounter;
uint64_t const currentCounter = SDL_GetPerformanceCounter(); uint64_t const current_counter = SDL_GetPerformanceCounter();
uint64_t const deltaCount = currentCounter - previousCounter; uint64_t const delta_count = current_counter - previous_counter;
uint64_t const perfFreq = SDL_GetPerformanceFrequency(); uint64_t const perf_freq = SDL_GetPerformanceFrequency();
double const deltaTime = static_cast<double>( deltaCount ) / static_cast<double>( perfFreq ); double const delta_time = static_cast<double>( delta_count ) / static_cast<double>( perf_freq );
misc.previousCounter = currentCounter; misc.previousCounter = current_counter;
{ {
misc.frameTimeSum -= misc.frameTime[misc.frameTimeWriteHead]; misc.frameTimeSum -= misc.frameTime[misc.frameTimeWriteHead];
misc.frameTime[misc.frameTimeWriteHead] = deltaTime; misc.frameTime[misc.frameTimeWriteHead] = delta_time;
misc.frameTimeSum += deltaTime; misc.frameTimeSum += delta_time;
misc.frameTimeWriteHead = ( misc.frameTimeWriteHead + 1 ) % misc.frameTimeEntryCount; misc.frameTimeWriteHead = ( misc.frameTimeWriteHead + 1 ) % misc.frameTimeEntryCount;
double avgDeltaTime = ( misc.frameTimeSum / misc.frameTimeEntryCount ); double avg_delta_time = ( misc.frameTimeSum / misc.frameTimeEntryCount );
double fps = 1.0 / avgDeltaTime; double fps = 1.0 / avg_delta_time;
double avgDeltaTimeMs = 1000.0 * avgDeltaTime; double avg_delta_time_ms = 1000.0 * avg_delta_time;
( void )sprintf_s<256>( appState.sprintfBuffer, "%.2f fps %.2f ms", fps, avgDeltaTimeMs ); ( void )sprintf_s<256>( app_state.sprintfBuffer, "%.2f fps %.2f ms", fps, avg_delta_time_ms );
SDL_SetWindowTitle( appState.window, appState.sprintfBuffer ); SDL_SetWindowTitle( app_state.window, app_state.sprintfBuffer );
} }
for ( Entity& entity : entityManager.iter() ) for ( Blaze::Entity& entity : entity_manager.Iterate() )
{ {
if ( not entity.isRoot() ) continue; if ( not entity.IsRoot() ) continue;
entity.transform.rotation = DirectX::XMQuaternionMultiply( entity.transform.rotation = DirectX::XMQuaternionMultiply(
DirectX::XMQuaternionRotationAxis( DirectX::XMQuaternionRotationAxis(
DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ), DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ),
DirectX::XMConvertToRadians( 60.0f ) * static_cast<float>( deltaTime ) ), DirectX::XMConvertToRadians( 60.0f ) * static_cast<float>( delta_time ) ),
entity.transform.rotation ); entity.transform.rotation );
} }
uint32_t currentImageIndex; uint32_t current_image_index;
VK_CHECK( vkAcquireNextImageKHR( VK_CHECK( vkAcquireNextImageKHR(
renderDevice.device, render_device.device,
renderDevice.swapchain, render_device.swapchain,
std::numeric_limits<uint32_t>::max(), std::numeric_limits<uint32_t>::max(),
currentFrame.imageAcquiredSemaphore, current_frame.imageAcquiredSemaphore,
nullptr, nullptr,
&currentImageIndex ) ); &current_image_index ) );
// TODO: Resize Swapchain if required. // TODO: Resize Swapchain if required.
VK_CHECK( vkResetFences( renderDevice.device, 1, &currentFrame.frameReadyToReuse ) ); VK_CHECK( vkResetFences( render_device.device, 1, &current_frame.frameReadyToReuse ) );
VK_CHECK( vkResetCommandPool( renderDevice.device, currentFrame.commandPool, 0 ) ); VK_CHECK( vkResetCommandPool( render_device.device, current_frame.commandPool, 0 ) );
misc.acquireToRenderBarrier.image = renderDevice.swapchainImages[currentImageIndex]; misc.acquireToRenderBarrier.image = render_device.swapchainImages[current_image_index];
misc.renderToPresentBarrier.image = renderDevice.swapchainImages[currentImageIndex]; misc.renderToPresentBarrier.image = render_device.swapchainImages[current_image_index];
VkCommandBuffer cmd = currentFrame.commandBuffer; VkCommandBuffer cmd = current_frame.commandBuffer;
VkCommandBufferBeginInfo constexpr beginInfo = { VkCommandBufferBeginInfo constexpr begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.pInheritanceInfo = nullptr, .pInheritanceInfo = nullptr,
}; };
VkClearColorValue constexpr static BLACK_CLEAR = { VkClearColorValue constexpr static kBlackClear = {
.float32 = { 0.0f, 0.0f, 0.0f, 1.0f }, .float32 = { 0.0f, 0.0f, 0.0f, 1.0f },
}; };
VkClearDepthStencilValue constexpr static DEPTH_STENCIL_CLEAR = { VkClearDepthStencilValue constexpr static kDepthStencilClear = {
.depth = 1.0f, .depth = 1.0f,
.stencil = 0, .stencil = 0,
}; };
VK_CHECK( vkBeginCommandBuffer( cmd, &beginInfo ) ); VK_CHECK( vkBeginCommandBuffer( cmd, &begin_info ) );
{ {
VkRenderingAttachmentInfo const depthAttachmentInfo = { VkRenderingAttachmentInfo const depth_attachment_info = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.pNext = nullptr, .pNext = nullptr,
.imageView = currentFrame.depthView, .imageView = current_frame.depthView,
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, .imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
.resolveMode = VK_RESOLVE_MODE_NONE, .resolveMode = VK_RESOLVE_MODE_NONE,
.resolveImageView = nullptr, .resolveImageView = nullptr,
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, .resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = { .depthStencil = DEPTH_STENCIL_CLEAR }, .clearValue = { .depthStencil = kDepthStencilClear },
}; };
VkRenderingAttachmentInfo const attachmentInfo = { VkRenderingAttachmentInfo const attachment_info = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.pNext = nullptr, .pNext = nullptr,
.imageView = renderDevice.swapchainViews[currentImageIndex], .imageView = render_device.swapchainViews[current_image_index],
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.resolveMode = VK_RESOLVE_MODE_NONE, .resolveMode = VK_RESOLVE_MODE_NONE,
.resolveImageView = nullptr, .resolveImageView = nullptr,
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, .resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = { .color = BLACK_CLEAR }, .clearValue = { .color = kBlackClear },
}; };
VkRenderingInfo renderingInfo = { VkRenderingInfo rendering_info = {
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.renderArea = { .offset = { 0, 0 }, .extent = renderDevice.swapchainExtent }, .renderArea = { .offset = { 0, 0 }, .extent = render_device.swapchainExtent },
.layerCount = 1, .layerCount = 1,
.viewMask = 0, .viewMask = 0,
.colorAttachmentCount = 1, .colorAttachmentCount = 1,
.pColorAttachments = &attachmentInfo, .pColorAttachments = &attachment_info,
.pDepthAttachment = &depthAttachmentInfo, .pDepthAttachment = &depth_attachment_info,
.pStencilAttachment = nullptr, .pStencilAttachment = nullptr,
}; };
vkCmdPipelineBarrier2( cmd, &misc.acquireToRenderDependency ); vkCmdPipelineBarrier2( cmd, &misc.acquireToRenderDependency );
vkCmdBeginRendering( cmd, &renderingInfo ); vkCmdBeginRendering( cmd, &rendering_info );
{ {
VkViewport viewport = { VkViewport viewport = {
.x = 0, .x = 0,
.y = static_cast<float>( renderDevice.swapchainExtent.height ), .y = static_cast<float>( render_device.swapchainExtent.height ),
.width = static_cast<float>( renderDevice.swapchainExtent.width ), .width = static_cast<float>( render_device.swapchainExtent.width ),
.height = -static_cast<float>( renderDevice.swapchainExtent.height ), .height = -static_cast<float>( render_device.swapchainExtent.height ),
.minDepth = 0.0f, .minDepth = 0.0f,
.maxDepth = 1.0f, .maxDepth = 1.0f,
}; };
vkCmdSetViewport( cmd, 0, 1, &viewport ); vkCmdSetViewport( cmd, 0, 1, &viewport );
VkRect2D scissor = { VkRect2D scissor = {
.offset = { 0, 0 }, .offset = { 0, 0 },
.extent = renderDevice.swapchainExtent, .extent = render_device.swapchainExtent,
}; };
vkCmdSetScissor( cmd, 0, 1, &scissor ); vkCmdSetScissor( cmd, 0, 1, &scissor );
@ -225,98 +227,98 @@ SDL_AppResult SDL_AppIterate( void* appstate )
vkCmdBindPipeline( cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.meshPipeline ); vkCmdBindPipeline( cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.meshPipeline );
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
cmd, cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
misc.pipelineLayout, misc.pipelineLayout,
0, 0,
1, 1,
&renderDevice.textureManager->descriptorSet(), &render_device.textureManager->DescriptorSet(),
0, 0,
nullptr ); nullptr );
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.pipelineLayout, 1, 1, &misc.descriptorSet, 0, nullptr ); cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.pipelineLayout, 1, 1, &misc.descriptorSet, 0, nullptr );
std::function<void( Entity const&, DirectX::XMMATRIX const&, Model const* )> drawEntity = std::function<void( Blaze::Entity const&, DirectX::XMMATRIX const&, Blaze::Model const* )> draw_entity =
[&]( Entity const& entity, DirectX::XMMATRIX const& parent, Model const* current ) [&]( Blaze::Entity const& entity, DirectX::XMMATRIX const& parent, Blaze::Model const* current )
{ {
Transform const& localTransform = entity.transform; Blaze::Transform const& local_transform = entity.transform;
DirectX::XMMATRIX worldTransform; DirectX::XMMATRIX world_transform;
{ {
worldTransform = world_transform =
DirectX::XMMatrixAffineTransformation( DirectX::XMMatrixAffineTransformation(
localTransform.scale, DirectX::XMVectorZero(), localTransform.rotation, localTransform.translation ) * local_transform.scale, DirectX::XMVectorZero(), local_transform.rotation, local_transform.translation ) *
parent; parent;
} }
if ( not entity.model.isNull() ) if ( not entity.model.IsNull() )
{ {
VkBuffer const vertexBuffer = renderDevice.bufferManager->fetchBuffer( entity.model.vertexBuffer ).value(); VkBuffer const vertex_buffer = render_device.bufferManager->FetchBuffer( entity.model.vertexBuffer ).value();
VkBuffer const indexBuffer = renderDevice.bufferManager->fetchBuffer( entity.model.indexBuffer ).value(); VkBuffer const index_buffer = render_device.bufferManager->FetchBuffer( entity.model.indexBuffer ).value();
VkDeviceSize constexpr offset = 0; VkDeviceSize constexpr offset = 0;
vkCmdBindVertexBuffers( cmd, 0, 1, &vertexBuffer, &offset ); vkCmdBindVertexBuffers( cmd, 0, 1, &vertex_buffer, &offset );
vkCmdBindIndexBuffer( cmd, indexBuffer, offset, VK_INDEX_TYPE_UINT32 ); vkCmdBindIndexBuffer( cmd, index_buffer, offset, VK_INDEX_TYPE_UINT32 );
} }
vkCmdPushConstants( vkCmdPushConstants(
cmd, misc.pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, sizeof worldTransform, &worldTransform ); cmd, misc.pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, sizeof world_transform, &world_transform );
DirectX::XMMATRIX const inverseTransform = XMMatrixInverse( nullptr, worldTransform ); DirectX::XMMATRIX const inverse_transform = XMMatrixInverse( nullptr, world_transform );
vkCmdPushConstants( vkCmdPushConstants(
cmd, cmd,
misc.pipelineLayout, misc.pipelineLayout,
VK_SHADER_STAGE_ALL_GRAPHICS, VK_SHADER_STAGE_ALL_GRAPHICS,
sizeof worldTransform, sizeof world_transform,
sizeof inverseTransform, sizeof inverse_transform,
&inverseTransform ); &inverse_transform );
if ( not entity.modelMesh.isNull() ) if ( not entity.modelMesh.IsNull() )
{ {
ASSERT( current ); ASSERT( current );
for ( Primitive const& primitive : std::span{ current->primitives.data() + entity.modelMesh.primitiveStart, for ( Blaze::Primitive const& primitive : std::span{
entity.modelMesh.primitiveCount } ) current->primitives.data() + entity.modelMesh.primitiveStart, entity.modelMesh.primitiveCount } )
{ {
byte const* materialData = nullptr; Blaze::byte const* material_data;
if ( primitive.material != UINT32_MAX ) if ( primitive.material != UINT32_MAX )
{ {
Material const* mat = &current->materials[primitive.material]; Blaze::Material const* mat = &current->materials[primitive.material];
materialData = reinterpret_cast<byte const*>( mat ); material_data = reinterpret_cast<Blaze::byte const*>( mat );
materialData += Material::GPU_DATA_OFFSET; material_data += Blaze::Material::kGPUDataOffset;
} }
else else
{ {
materialData = reinterpret_cast<byte const*>( &DEFAULT_MATERIAL ); material_data = reinterpret_cast<Blaze::byte const*>( &Blaze::DEFAULT_MATERIAL );
materialData += Material::GPU_DATA_OFFSET; material_data += Blaze::Material::kGPUDataOffset;
} }
vkCmdPushConstants( vkCmdPushConstants(
cmd, cmd,
misc.pipelineLayout, misc.pipelineLayout,
VK_SHADER_STAGE_ALL_GRAPHICS, VK_SHADER_STAGE_ALL_GRAPHICS,
2 * sizeof worldTransform, 2 * sizeof world_transform,
Material::GPU_DATA_SIZE, Blaze::Material::kGPUDataSize,
materialData ); material_data );
vkCmdDrawIndexed( cmd, primitive.indexCount, 1, primitive.indexStart, primitive.vertexOffset, 0 ); vkCmdDrawIndexed( cmd, primitive.indexCount, 1, primitive.indexStart, primitive.vertexOffset, 0 );
} }
} }
for ( Entity& child : entity.children() ) for ( Blaze::Entity& child : entity.IterChildren() )
{ {
drawEntity( child, worldTransform, entity.model.isNull() ? current : &entity.model ); draw_entity( child, world_transform, entity.model.IsNull() ? current : &entity.model );
} }
}; };
for ( Entity const& entity : entityManager.iter() ) for ( Blaze::Entity const& entity : entity_manager.Iterate() )
{ {
if ( not entity.isRoot() ) if ( not entity.IsRoot() )
{ {
continue; continue;
} }
drawEntity( entity, DirectX::XMMatrixIdentity(), nullptr ); draw_entity( entity, DirectX::XMMatrixIdentity(), nullptr );
} }
} }
vkCmdEndRendering( cmd ); vkCmdEndRendering( cmd );
@ -324,38 +326,39 @@ SDL_AppResult SDL_AppIterate( void* appstate )
} }
VK_CHECK( vkEndCommandBuffer( cmd ) ); VK_CHECK( vkEndCommandBuffer( cmd ) );
VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPipelineStageFlags stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo const submitInfo = { VkSubmitInfo const submit_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr, .pNext = nullptr,
.waitSemaphoreCount = 1, .waitSemaphoreCount = 1,
.pWaitSemaphores = &currentFrame.imageAcquiredSemaphore, .pWaitSemaphores = &current_frame.imageAcquiredSemaphore,
.pWaitDstStageMask = &stageMask, .pWaitDstStageMask = &stage_mask,
.commandBufferCount = 1, .commandBufferCount = 1,
.pCommandBuffers = &cmd, .pCommandBuffers = &cmd,
.signalSemaphoreCount = 1, .signalSemaphoreCount = 1,
.pSignalSemaphores = &currentFrame.renderFinishedSemaphore, .pSignalSemaphores = &current_frame.renderFinishedSemaphore,
}; };
VK_CHECK( vkQueueSubmit( renderDevice.directQueue, 1, &submitInfo, currentFrame.frameReadyToReuse ) ); VK_CHECK( vkQueueSubmit( render_device.directQueue, 1, &submit_info, current_frame.frameReadyToReuse ) );
VkPresentInfoKHR const presentInfo = { VkPresentInfoKHR const present_info = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = nullptr, .pNext = nullptr,
.waitSemaphoreCount = 1, .waitSemaphoreCount = 1,
.pWaitSemaphores = &currentFrame.renderFinishedSemaphore, .pWaitSemaphores = &current_frame.renderFinishedSemaphore,
.swapchainCount = 1, .swapchainCount = 1,
.pSwapchains = &renderDevice.swapchain, .pSwapchains = &render_device.swapchain,
.pImageIndices = &currentImageIndex, .pImageIndices = &current_image_index,
.pResults = nullptr, .pResults = nullptr,
}; };
VK_CHECK( vkQueuePresentKHR( renderDevice.directQueue, &presentInfo ) ); VK_CHECK( vkQueuePresentKHR( render_device.directQueue, &present_info ) );
renderDevice.frameIndex = ( renderDevice.frameIndex + 1 ) % NUM_FRAMES; render_device.frameIndex = ( render_device.frameIndex + 1 ) % NUM_FRAMES;
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
// ReSharper disable once CppInconsistentNaming
SDL_AppResult SDL_AppEvent( void*, SDL_Event* event ) SDL_AppResult SDL_AppEvent( void*, SDL_Event* event )
{ {
if ( event->type == SDL_EVENT_QUIT ) if ( event->type == SDL_EVENT_QUIT )
@ -366,11 +369,12 @@ SDL_AppResult SDL_AppEvent( void*, SDL_Event* event )
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
// ReSharper disable once CppInconsistentNaming
void SDL_AppQuit( void* appstate, SDL_AppResult ) void SDL_AppQuit( void* appstate, SDL_AppResult )
{ {
AppState* appState = static_cast<AppState*>( appstate ); auto* app_state = static_cast<Blaze::AppState*>( appstate );
if ( appState ) appState->destroy(); if ( app_state ) app_state->Destroy();
Blaze::Global::g_Memory.destroy(); Blaze::Global::g_Memory.Destroy();
} }

View File

@ -3,75 +3,75 @@
#include "GlobalMemory.h" #include "GlobalMemory.h"
template struct RID<Buffer>; using Blaze::BufferManager;
void BufferManager::destroyBuffer( Buffer& buf ) void BufferManager::DestroyBuffer( Buffer& buf )
{ {
if ( not buf.buffer ) return; if ( not buf.buffer ) return;
ASSERT( m_pRenderDevice ); ASSERT( m_renderDevice );
uint32_t const index = buf.index; uint32_t const index = buf.index;
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
uint32_t const generation = ( index & GENERATION_MASK ) >> GENERATION_OFFSET; uint32_t const generation = ( index & kGenerationMask ) >> kGenerationOffset;
RenderDevice const& renderDevice = *m_pRenderDevice; RenderDevice const& render_device = *m_renderDevice;
vmaDestroyBuffer( renderDevice.gpuAllocator, Take( buf.buffer ), Take( buf.allocation ) ); vmaDestroyBuffer( render_device.gpuAllocator, Take( buf.buffer ), Take( buf.allocation ) );
buf.size = 0; buf.size = 0;
buf.mappedData = nullptr; buf.mappedData = nullptr;
buf.index = innerIndex | ( generation + 1 ) << GENERATION_OFFSET; buf.index = inner_index | ( generation + 1 ) << kGenerationOffset;
// NOTE: DO NOT EDIT INNER INDEX. // NOTE: DO NOT EDIT INNER INDEX.
ASSERT( innerIndex == ( buf.index & INDEX_MASK ) and "Index should not be modified" ); ASSERT( inner_index == ( buf.index & kIndexMask ) and "Index should not be modified" );
ASSERT( buf.index > index and "Generation should increase." ); ASSERT( buf.index > index and "Generation should increase." );
m_freeList.pushBack( reinterpret_cast<FreeList::Node*>( &buf ) ); m_freeList.PushBack( reinterpret_cast<Util::FreeList::Node*>( &buf ) );
--m_count; --m_count;
} }
Buffer& BufferManager::fetchBufferUnchecked( BufferID const& rid ) Blaze::Buffer& BufferManager::FetchBufferUnchecked( BufferID const& rid )
{ {
uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid ); uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid );
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
return m_aBuffers[innerIndex]; return m_buffers[inner_index];
} }
void BufferManager::writeToBufferImpl( BufferID const& rid, void const* data, size_t const size ) void BufferManager::WriteToBufferImpl( BufferID const& rid, void const* data, size_t const size )
{ {
ASSERT( isValidID( rid ) ); ASSERT( IsValidID( rid ) );
Buffer const& buffer = fetchBufferUnchecked( rid ); Buffer const& buffer = FetchBufferUnchecked( rid );
ASSERT( size <= buffer.size ); ASSERT( size <= buffer.size );
memcpy( buffer.mappedData, data, size ); memcpy( buffer.mappedData, data, size );
} }
bool BufferManager::isValidID( BufferID const& rid ) const bool BufferManager::IsValidID( BufferID const& rid ) const
{ {
uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid ); uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid );
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
if ( innerIndex > m_capacity ) return false; if ( inner_index > m_capacity ) return false;
return m_aBuffers[innerIndex].index == index; return m_buffers[inner_index].index == index;
} }
BufferID BufferManager::createVertexBuffer( size_t const size ) Blaze::BufferID BufferManager::CreateVertexBuffer( size_t const size )
{ {
ASSERT( not m_freeList.empty() ); ASSERT( not m_freeList.Empty() );
Buffer* bufferSlot = reinterpret_cast<Buffer*>( m_freeList.popFront() ); Buffer* buffer_slot = reinterpret_cast<Buffer*>( m_freeList.PopFront() );
++m_count; ++m_count;
ASSERT( m_pRenderDevice ); ASSERT( m_renderDevice );
RenderDevice const& renderDevice = *m_pRenderDevice; RenderDevice const& render_device = *m_renderDevice;
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const buffer_create_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -82,7 +82,7 @@ BufferID BufferManager::createVertexBuffer( size_t const size )
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocation_create_info = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
@ -93,24 +93,24 @@ BufferID BufferManager::createVertexBuffer( size_t const size )
.priority = 1.0f, .priority = 1.0f,
}; };
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocation_info;
VkBuffer vertexBuffer; VkBuffer vertex_buffer;
VmaAllocation vertexBufferAllocation; VmaAllocation vertex_buffer_allocation;
VK_CHECK( vmaCreateBuffer( VK_CHECK( vmaCreateBuffer(
renderDevice.gpuAllocator, render_device.gpuAllocator,
&bufferCreateInfo, &buffer_create_info,
&allocationCreateInfo, &allocation_create_info,
&vertexBuffer, &vertex_buffer,
&vertexBufferAllocation, &vertex_buffer_allocation,
&allocationInfo ) ); &allocation_info ) );
// NOTE: textureSlot preserves index between uses. // NOTE: textureSlot preserves index between uses.
uint32_t index = bufferSlot->index; uint32_t index = buffer_slot->index;
new ( bufferSlot ) Buffer{ new ( buffer_slot ) Buffer{
.buffer = vertexBuffer, .buffer = vertex_buffer,
.allocation = vertexBufferAllocation, .allocation = vertex_buffer_allocation,
.mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ), .mappedData = static_cast<std::byte*>( allocation_info.pMappedData ),
.deviceAddress = 0, .deviceAddress = 0,
.size = size, .size = size,
.index = index, .index = index,
@ -120,18 +120,18 @@ BufferID BufferManager::createVertexBuffer( size_t const size )
return *reinterpret_cast<BufferID*>( &index ); return *reinterpret_cast<BufferID*>( &index );
} }
BufferID BufferManager::createIndexBuffer( size_t const size ) Blaze::BufferID BufferManager::CreateIndexBuffer( size_t const size )
{ {
ASSERT( not m_freeList.empty() ); ASSERT( not m_freeList.Empty() );
Buffer* bufferSlot = reinterpret_cast<Buffer*>( m_freeList.popFront() ); Buffer* buffer_slot = reinterpret_cast<Buffer*>( m_freeList.PopFront() );
++m_count; ++m_count;
ASSERT( m_pRenderDevice ); ASSERT( m_renderDevice );
RenderDevice const& renderDevice = *m_pRenderDevice; RenderDevice const& render_device = *m_renderDevice;
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const buffer_create_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -142,7 +142,7 @@ BufferID BufferManager::createIndexBuffer( size_t const size )
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocation_create_info = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
@ -153,24 +153,24 @@ BufferID BufferManager::createIndexBuffer( size_t const size )
.priority = 1.0f, .priority = 1.0f,
}; };
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocation_info;
VkBuffer indexBuffer; VkBuffer index_buffer;
VmaAllocation indexBufferAllocation; VmaAllocation index_buffer_allocation;
VK_CHECK( vmaCreateBuffer( VK_CHECK( vmaCreateBuffer(
renderDevice.gpuAllocator, render_device.gpuAllocator,
&bufferCreateInfo, &buffer_create_info,
&allocationCreateInfo, &allocation_create_info,
&indexBuffer, &index_buffer,
&indexBufferAllocation, &index_buffer_allocation,
&allocationInfo ) ); &allocation_info ) );
// NOTE: bufferSlot preserves index between uses. // NOTE: bufferSlot preserves index between uses.
uint32_t index = bufferSlot->index; uint32_t index = buffer_slot->index;
new ( bufferSlot ) Buffer{ new ( buffer_slot ) Buffer{
.buffer = indexBuffer, .buffer = index_buffer,
.allocation = indexBufferAllocation, .allocation = index_buffer_allocation,
.mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ), .mappedData = static_cast<std::byte*>( allocation_info.pMappedData ),
.deviceAddress = 0, .deviceAddress = 0,
.size = size, .size = size,
.index = index, .index = index,
@ -180,18 +180,18 @@ BufferID BufferManager::createIndexBuffer( size_t const size )
return *reinterpret_cast<BufferID*>( &index ); return *reinterpret_cast<BufferID*>( &index );
} }
BufferID BufferManager::createStorageBuffer( size_t const size ) Blaze::BufferID BufferManager::CreateStorageBuffer( size_t const size )
{ {
ASSERT( not m_freeList.empty() ); ASSERT( not m_freeList.Empty() );
Buffer* bufferSlot = reinterpret_cast<Buffer*>( m_freeList.popFront() ); Buffer* buffer_slot = reinterpret_cast<Buffer*>( m_freeList.PopFront() );
++m_count; ++m_count;
ASSERT( m_pRenderDevice ); ASSERT( m_renderDevice );
RenderDevice const& renderDevice = *m_pRenderDevice; RenderDevice const& render_device = *m_renderDevice;
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const buffer_create_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -202,7 +202,7 @@ BufferID BufferManager::createStorageBuffer( size_t const size )
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocation_create_info = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
@ -213,33 +213,33 @@ BufferID BufferManager::createStorageBuffer( size_t const size )
.priority = 1.0f, .priority = 1.0f,
}; };
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocation_info;
VkBuffer storageBuffer; VkBuffer storage_buffer;
VmaAllocation storageBufferAllocation; VmaAllocation storage_buffer_allocation;
VK_CHECK( vmaCreateBuffer( VK_CHECK( vmaCreateBuffer(
renderDevice.gpuAllocator, render_device.gpuAllocator,
&bufferCreateInfo, &buffer_create_info,
&allocationCreateInfo, &allocation_create_info,
&storageBuffer, &storage_buffer,
&storageBufferAllocation, &storage_buffer_allocation,
&allocationInfo ) ); &allocation_info ) );
VkBufferDeviceAddressInfo const deviceAddressInfo = { VkBufferDeviceAddressInfo const device_address_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.pNext = nullptr, .pNext = nullptr,
.buffer = storageBuffer, .buffer = storage_buffer,
}; };
VkDeviceAddress const deviceAddress = vkGetBufferDeviceAddress( renderDevice.device, &deviceAddressInfo ); VkDeviceAddress const device_address = vkGetBufferDeviceAddress( render_device.device, &device_address_info );
// NOTE: bufferSlot preserves index between uses. // NOTE: bufferSlot preserves index between uses.
uint32_t index = bufferSlot->index; uint32_t index = buffer_slot->index;
new ( bufferSlot ) Buffer{ new ( buffer_slot ) Buffer{
.buffer = storageBuffer, .buffer = storage_buffer,
.allocation = storageBufferAllocation, .allocation = storage_buffer_allocation,
.mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ), .mappedData = static_cast<std::byte*>( allocation_info.pMappedData ),
.deviceAddress = deviceAddress, .deviceAddress = device_address,
.size = size, .size = size,
.index = index, .index = index,
}; };
@ -248,47 +248,50 @@ BufferID BufferManager::createStorageBuffer( size_t const size )
return *reinterpret_cast<BufferID*>( &index ); return *reinterpret_cast<BufferID*>( &index );
} }
void BufferManager::freeBuffer( BufferID* rid ) void BufferManager::FreeBuffer( BufferID* rid )
{ {
if ( not isValidID( *rid ) ) return; if ( not IsValidID( *rid ) ) return;
Buffer& buffer = fetchBufferUnchecked( *rid ); Buffer& buffer = FetchBufferUnchecked( *rid );
destroyBuffer( buffer ); DestroyBuffer( buffer );
*rid = {}; *rid = {};
} }
std::optional<VkBuffer> BufferManager::fetchBuffer( BufferID const& rid ) std::optional<VkBuffer> BufferManager::FetchBuffer( BufferID const& rid )
{ {
if ( not isValidID( rid ) ) return std::nullopt; if ( not IsValidID( rid ) ) return std::nullopt;
return fetchBufferUnchecked( rid ).buffer; return FetchBufferUnchecked( rid ).buffer;
} }
std::optional<VkDeviceAddress> BufferManager::fetchDeviceAddress( BufferID const& rid ) std::optional<VkDeviceAddress> BufferManager::FetchDeviceAddress( BufferID const& rid )
{ {
if ( not isValidID( rid ) ) return std::nullopt; if ( not IsValidID( rid ) ) return std::nullopt;
Buffer const& buffer = fetchBufferUnchecked( rid ); Buffer const& buffer = FetchBufferUnchecked( rid );
if ( buffer.deviceAddress == 0 ) return std::nullopt; if ( buffer.deviceAddress == 0 ) return std::nullopt;
return buffer.deviceAddress; return buffer.deviceAddress;
} }
BufferManager::BufferManager( RenderDevice* pRenderDevice, Buffer* aBuffers, uint32_t const capacity ) BufferManager::BufferManager( RenderDevice* render_device, Buffer* buffers, uint32_t const capacity )
: m_pRenderDevice{ pRenderDevice }, m_aBuffers{ aBuffers }, m_count{ 0 }, m_capacity{ capacity } : m_renderDevice{ render_device }
, m_buffers{ buffers }
, m_count{ 0 }
, m_capacity{ capacity }
{ {
uint32_t i = 0; uint32_t i = 0;
for ( Buffer& tex : std::span{ m_aBuffers, m_capacity } ) for ( Buffer& tex : std::span{ m_buffers, m_capacity } )
{ {
// Default Generation is 1 // Default Generation is 1
tex.index = i++ | ( 1 << GENERATION_OFFSET ); tex.index = i++ | ( 1 << kGenerationOffset );
m_freeList.pushFront( reinterpret_cast<FreeList::Node*>( &tex ) ); m_freeList.PushFront( reinterpret_cast<Util::FreeList::Node*>( &tex ) );
} }
} }
void BufferManager::destroy() void BufferManager::Destroy()
{ {
#if defined( _DEBUG ) #if defined( _DEBUG )
@ -298,30 +301,31 @@ void BufferManager::destroy()
} }
#endif #endif
while ( not m_freeList.empty() ) while ( not m_freeList.Empty() )
{ {
Buffer* buf = reinterpret_cast<Buffer*>( m_freeList.popFront() ); Buffer* buf = reinterpret_cast<Buffer*>( m_freeList.PopFront() );
memset( buf, 0, sizeof *buf ); memset( buf, 0, sizeof *buf );
} }
for ( Buffer& buf : std::span{ m_aBuffers, m_count } ) for ( Buffer& buf : std::span{ m_buffers, m_count } )
{ {
destroyBuffer( buf ); DestroyBuffer( buf );
} }
} }
BufferManager::~BufferManager() BufferManager::~BufferManager()
{ {
ASSERT( not m_aBuffers ); ASSERT( not m_buffers );
} }
BufferManager* BufferManager_Create( GlobalMemory* mem, RenderDevice* renderDevice, uint32_t maxCount )
BufferManager* BufferManager::Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t const max_count )
{ {
Buffer* buffers = reinterpret_cast<Buffer*>( mem->allocate( maxCount * sizeof( Buffer ), alignof( Buffer ) ) ); Buffer* buffers = reinterpret_cast<Buffer*>( mem->Allocate( max_count * sizeof( Buffer ), alignof( Buffer ) ) );
if ( not buffers ) return nullptr; if ( not buffers ) return nullptr;
std::byte* allocation = mem->allocate( sizeof( BufferManager ), alignof( BufferManager ) ); std::byte* allocation = mem->Allocate( sizeof( BufferManager ), alignof( BufferManager ) );
if ( not allocation ) return nullptr; if ( not allocation ) return nullptr;
return new ( allocation ) BufferManager{ renderDevice, buffers, maxCount }; return new ( allocation ) BufferManager{ render_device, buffers, max_count };
} }

View File

@ -9,6 +9,8 @@
#include "RenderDevice.h" #include "RenderDevice.h"
#include "VulkanHeader.h" #include "VulkanHeader.h"
namespace Blaze
{
struct GlobalMemory; struct GlobalMemory;
struct RenderDevice; struct RenderDevice;
@ -22,60 +24,62 @@ struct Buffer
uint32_t index; uint32_t index;
}; };
static_assert( sizeof( Buffer ) > sizeof( FreeList::Node ) and "Buffer is used intrusively by FreeList" ); static_assert( sizeof( Buffer ) > sizeof( Util::FreeList::Node ) and "Buffer is used intrusively by FreeList" );
static_assert( static_assert(
offsetof( Buffer, index ) >= sizeof( FreeList::Node ) and "Index should not be overwritten even in invalid state" ); offsetof( Buffer, index ) >= sizeof( Util::FreeList::Node ) and
"Index should not be overwritten even in invalid state" );
extern template struct RID<Buffer>;
using BufferID = RID<Buffer>; using BufferID = RID<Buffer>;
struct BufferManager struct BufferManager
{ {
private: private:
constexpr static uint32_t INDEX_MASK = 0x0007FFFF; constexpr static uint32_t kIndexMask = 0x0007FFFF;
constexpr static uint32_t GENERATION_MASK = ~INDEX_MASK; constexpr static uint32_t kGenerationMask = ~kIndexMask;
constexpr static uint32_t GENERATION_OFFSET = 19; constexpr static uint32_t kGenerationOffset = 19;
static_assert( static_assert(
( ( GENERATION_MASK >> GENERATION_OFFSET & 0x1 ) == 0x1 ) and ( ( kGenerationMask >> kGenerationOffset & 0x1 ) == 0x1 ) and
( ( GENERATION_MASK >> ( GENERATION_OFFSET - 1 ) & 0x1 ) != 0x1 ) and "Checks boundary" ); ( ( kGenerationMask >> ( kGenerationOffset - 1 ) & 0x1 ) != 0x1 ) and "Checks boundary" );
RenderDevice* m_pRenderDevice; RenderDevice* m_renderDevice;
// Buffer Manager // Buffer Manager
Buffer* m_aBuffers; Buffer* m_buffers;
uint32_t m_count; uint32_t m_count;
uint32_t m_capacity; uint32_t m_capacity;
FreeList m_freeList; Util::FreeList m_freeList;
void destroyBuffer( Buffer& buf ); void DestroyBuffer( Buffer& buf );
Buffer& fetchBufferUnchecked( BufferID const& rid ); Buffer& FetchBufferUnchecked( BufferID const& rid );
void writeToBufferImpl( BufferID const& rid, void const* data, size_t size ); void WriteToBufferImpl( BufferID const& rid, void const* data, size_t size );
public: public:
[[nodiscard]] bool isValidID( BufferID const& rid ) const; [[nodiscard]] bool IsValidID( BufferID const& rid ) const;
BufferID createVertexBuffer( size_t size ); BufferID CreateVertexBuffer( size_t size );
BufferID createIndexBuffer( size_t size ); BufferID CreateIndexBuffer( size_t size );
BufferID createStorageBuffer( size_t size ); BufferID CreateStorageBuffer( size_t size );
void freeBuffer( BufferID* rid ); void FreeBuffer( BufferID* rid );
DEPRECATE_JULY_2025 DEPRECATE_JULY_2025
std::optional<VkBuffer> fetchBuffer( BufferID const& rid ); std::optional<VkBuffer> FetchBuffer( BufferID const& rid );
std::optional<VkDeviceAddress> fetchDeviceAddress( BufferID const& rid ); std::optional<VkDeviceAddress> FetchDeviceAddress( BufferID const& rid );
void writeToBuffer( BufferID const& rid, std::ranges::contiguous_range auto const& data ) // Utility to directly muck the data
void WriteToBuffer( BufferID const& rid, std::ranges::contiguous_range auto const& data )
{ {
writeToBufferImpl( WriteToBufferImpl(
rid, rid,
std::ranges::data( data ), std::ranges::data( data ),
std::ranges::size( data ) * sizeof( std::ranges::range_value_t<decltype( data )> ) ); std::ranges::size( data ) * sizeof( std::ranges::range_value_t<decltype( data )> ) );
} }
// static BufferManager* Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t max_count );
BufferManager( RenderDevice* pRenderDevice, Buffer* aBuffers, uint32_t capacity ); void Destroy();
void destroy();
BufferManager( RenderDevice* render_device, Buffer* buffers, uint32_t capacity );
BufferManager( BufferManager const& other ) = delete; BufferManager( BufferManager const& other ) = delete;
BufferManager( BufferManager&& other ) noexcept = delete; BufferManager( BufferManager&& other ) noexcept = delete;
@ -84,4 +88,5 @@ public:
~BufferManager(); ~BufferManager();
}; };
BufferManager* BufferManager_Create( GlobalMemory* mem, RenderDevice* renderDevice, uint32_t maxCount );
} // namespace Blaze

View File

@ -8,9 +8,12 @@
#include "Frame.h" #include "Frame.h"
#include "TextureManager.h" #include "TextureManager.h"
namespace Blaze
{
Entity& EntitySiblingIterable::Iterator::operator++() Entity& EntitySiblingIterable::Iterator::operator++()
{ {
current = current->nextSibling(); current = current->NextSibling();
return *current; return *current;
} }
@ -34,43 +37,42 @@ EntitySiblingIterable::Iterator EntitySiblingIterable::end()
return {}; return {};
} }
void Entity::SetParent( Entity* parent )
void Entity::setParent( Entity* parent )
{ {
ASSERT( parent ); ASSERT( parent );
if ( m_parent == parent ) return; if ( m_parent == parent ) return;
removeParent(); RemoveParent();
// Insert self into parent. // Insert self into GetParent.
m_parent = parent; m_parent = parent;
Entity* oldHead = parent->m_firstChild; Entity* old_head = parent->m_firstChild;
if ( oldHead ) if ( old_head )
{ {
// Old head is next after this // Old head is next after this
this->m_nextSibling = oldHead; this->m_nextSibling = old_head;
// This is prev to old head // This is prev to old head
oldHead->m_prevSibling = this; old_head->m_prevSibling = this;
} }
// We are the head now. // We are the head now.
m_parent->m_firstChild = this; m_parent->m_firstChild = this;
} }
void Entity::addChild( Entity* child ) void Entity::AddChild( Entity* child )
{ {
child->setParent( this ); child->SetParent( this );
} }
void Entity::removeChild( Entity* child ) void Entity::RemoveChild( Entity* child )
{ {
ASSERT( child ); ASSERT( child );
child->removeParent(); child->RemoveParent();
} }
void Entity::removeParent() void Entity::RemoveParent()
{ {
if ( m_parent ) if ( m_parent )
{ {
@ -95,7 +97,7 @@ void Entity::removeParent()
} }
} }
EntitySiblingIterable Entity::children() const EntitySiblingIterable Entity::IterChildren() const
{ {
return { m_firstChild }; return { m_firstChild };
} }
@ -111,35 +113,47 @@ Entity::Entity( Transform const& transform )
, m_flags{ 0 } , m_flags{ 0 }
{} {}
Entity* EntityManager::createEntity( Transform const& transform ) EntityManager::EntityManager( RenderDevice* render_device, Entity* data, uint32_t const capacity )
{ : m_renderDevice{ render_device }
ASSERT( count < capacity ); , m_entities{ data }
, m_count{ 0 }
, m_capacity{ capacity }
{}
Entity& entity = entities[count++]; EntityManager::Iterable EntityManager::Iterate() const
{
return Iterable{ m_entities, m_count };
}
Entity* EntityManager::CreateEntity( Transform const& transform )
{
ASSERT( m_count < m_capacity );
Entity& entity = m_entities[m_count++];
new ( &entity ) Entity{ transform }; new ( &entity ) Entity{ transform };
return &entity; return &entity;
} }
void EntityManager::destroyEntity( Entity* entity ) void EntityManager::DestroyEntity( Entity* entity )
{ {
ASSERT( entity ); ASSERT( entity );
VkDevice const device = pRenderDevice->device; VkDevice const device = m_renderDevice->device;
if ( not entity->model.isNull() ) if ( not entity->model.IsNull() )
{ {
for ( auto& material : entity->model.materials ) for ( Material& material : entity->model.materials )
{ {
vkDestroySampler( device, Take( material.sampler ), nullptr ); vkDestroySampler( device, Take( material.sampler ), nullptr );
pRenderDevice->textureManager->freeTexture( &material.albedoTextureID ); m_renderDevice->textureManager->FreeTexture( &material.albedoTextureID );
pRenderDevice->textureManager->freeTexture( &material.normalTextureID ); m_renderDevice->textureManager->FreeTexture( &material.normalTextureID );
pRenderDevice->textureManager->freeTexture( &material.metalRoughTextureID ); m_renderDevice->textureManager->FreeTexture( &material.metalRoughTextureID );
pRenderDevice->textureManager->freeTexture( &material.emissiveTextureID ); m_renderDevice->textureManager->FreeTexture( &material.emissiveTextureID );
} }
pRenderDevice->bufferManager->freeBuffer( &entity->model.vertexBuffer ); m_renderDevice->bufferManager->FreeBuffer( &entity->model.vertexBuffer );
pRenderDevice->bufferManager->freeBuffer( &entity->model.indexBuffer ); m_renderDevice->bufferManager->FreeBuffer( &entity->model.indexBuffer );
entity->model.primitives.clear(); entity->model.primitives.clear();
entity->model.materials.clear(); entity->model.materials.clear();
} }
@ -147,29 +161,32 @@ void EntityManager::destroyEntity( Entity* entity )
entity->modelMesh = { 0, 0 }; entity->modelMesh = { 0, 0 };
} }
void EntityManager::destroy() void EntityManager::Destroy()
{ {
Entity const* end = entities + capacity; Entity const* end = m_entities + m_capacity;
for ( Entity* iter = entities; iter != end; ++iter ) for ( Entity* iter = m_entities; iter != end; ++iter )
{ {
destroyEntity( iter ); DestroyEntity( iter );
} }
entities = nullptr; m_entities = nullptr;
capacity = 0; m_capacity = 0;
count = 0; m_count = 0;
} }
EntityManager::~EntityManager() EntityManager::~EntityManager()
{ {
assert( !entities ); assert( !m_entities );
} }
EntityManager* EntityManager_Create( GlobalMemory* mem, RenderDevice* renderDevice, uint32_t const capacity )
EntityManager* EntityManager::Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t const capacity )
{ {
Entity* data = reinterpret_cast<Entity*>( mem->allocate( capacity * sizeof( Entity ), alignof( Entity ) ) ); Entity* data = reinterpret_cast<Entity*>( mem->Allocate( capacity * sizeof( Entity ), alignof( Entity ) ) );
memset( data, 0, capacity * sizeof( Entity ) ); memset( data, 0, capacity * sizeof( Entity ) );
std::byte* alloc = mem->allocate( sizeof( EntityManager ), alignof( EntityManager ) ); std::byte* alloc = mem->Allocate( sizeof( EntityManager ), alignof( EntityManager ) );
return new ( alloc ) EntityManager{ renderDevice, data, capacity }; return new ( alloc ) EntityManager{ render_device, data, capacity };
} }
} // namespace Blaze

View File

@ -3,14 +3,15 @@
#include <cstdint> #include <cstdint>
#include <DirectXMath.h> #include <DirectXMath.h>
#include <span>
#include "VulkanHeader.h"
#include "ModelLoader.h" #include "ModelLoader.h"
namespace Blaze
{
struct GlobalMemory;
struct Entity; struct Entity;
struct RenderDevice; struct RenderDevice;
struct GlobalMemory;
struct Transform struct Transform
{ {
@ -50,31 +51,31 @@ private:
uint64_t m_flags; // FIXME: Wasting space. uint64_t m_flags; // FIXME: Wasting space.
public: public:
[[nodiscard]] bool isRoot() const [[nodiscard]] bool IsRoot() const
{ {
return not m_parent; return not m_parent;
} }
[[nodiscard]] Entity* parent() const [[nodiscard]] Entity* GetParent() const
{ {
return m_parent; return m_parent;
} }
[[nodiscard]] Entity* nextSibling() const [[nodiscard]] Entity* NextSibling() const
{ {
return m_nextSibling; return m_nextSibling;
} }
void setParent( Entity* parent ); void SetParent( Entity* parent );
void addChild( Entity* child ); void AddChild( Entity* child );
void removeChild( Entity* child ); void RemoveChild( Entity* child );
// Remove self from parent // Remove self from GetParent
void removeParent(); void RemoveParent();
[[nodiscard]] EntitySiblingIterable children() const; [[nodiscard]] EntitySiblingIterable IterChildren() const;
explicit Entity( Transform const& transform ); explicit Entity( Transform const& transform );
}; };
@ -102,28 +103,26 @@ struct EntityManager
} }
}; };
RenderDevice* pRenderDevice; private:
Entity* entities; RenderDevice* m_renderDevice;
uint32_t count; Entity* m_entities;
uint32_t capacity; uint32_t m_count;
uint32_t m_capacity;
EntityManager( RenderDevice* renderDevice, Entity* data, uint32_t const capacity ) public:
: pRenderDevice{ renderDevice }, entities{ data }, count{ 0 }, capacity{ capacity } EntityManager( RenderDevice* render_device, Entity* data, uint32_t capacity );
{}
[[nodiscard]] Iterable iter() const [[nodiscard]] Iterable Iterate() const;
{
return Iterable{ entities, count };
}
// Make Entities return ID, make it a sparse indexing system. // Make Entities return ID, make it a sparse indexing system.
Entity* createEntity( Transform const& transform ); Entity* CreateEntity( Transform const& transform );
void destroyEntity( Entity* entity ); void DestroyEntity( Entity* entity );
void destroy(); static EntityManager* Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t capacity );
void Destroy();
~EntityManager(); ~EntityManager();
}; };
EntityManager* EntityManager_Create( GlobalMemory* mem, RenderDevice* renderDevice, uint32_t capacity ); } // namespace Blaze

View File

@ -5,38 +5,40 @@
#include "MacroUtils.h" #include "MacroUtils.h"
#include "RenderDevice.h" #include "RenderDevice.h"
bool Frame::isInit() const using Blaze::Frame;
bool Blaze::Frame::IsInit() const
{ {
return static_cast<bool>( commandPool ); return static_cast<bool>( commandPool );
} }
Frame::Frame( Frame::Frame(
VkCommandPool const commandPool, VkCommandPool const command_pool,
VkCommandBuffer const commandBuffer, VkCommandBuffer const command_buffer,
VkSemaphore const imageAcquiredSemaphore, VkSemaphore const image_acquired_semaphore,
VkSemaphore const renderFinishedSemaphore, VkSemaphore const render_finished_semaphore,
VkFence const frameReadyToReuse, VkFence const frame_ready_to_reuse,
VkImage const depthImage, VkImage const depth_image,
VmaAllocation const depthAllocation, VmaAllocation const depth_allocation,
VkImageView const depthView ) VkImageView const depth_view )
: commandPool{ commandPool } : commandPool{ command_pool }
, commandBuffer{ commandBuffer } , commandBuffer{ command_buffer }
, imageAcquiredSemaphore{ imageAcquiredSemaphore } , imageAcquiredSemaphore{ image_acquired_semaphore }
, renderFinishedSemaphore{ renderFinishedSemaphore } , renderFinishedSemaphore{ render_finished_semaphore }
, frameReadyToReuse{ frameReadyToReuse } , frameReadyToReuse{ frame_ready_to_reuse }
, depthImage{ depthImage } , depthImage{ depth_image }
, depthAllocation{ depthAllocation } , depthAllocation{ depth_allocation }
, depthView{ depthView } , depthView{ depth_view }
{} {}
void Frame::destroy( RenderDevice const& renderDevice ) void Frame::Destroy( RenderDevice const& render_device )
{ {
if ( !isInit() ) return; if ( !IsInit() ) return;
VkDevice const device = renderDevice.device; VkDevice const device = render_device.device;
vkDestroyImageView( device, Take( depthView ), nullptr ); vkDestroyImageView( device, Take( depthView ), nullptr );
vmaDestroyImage( renderDevice.gpuAllocator, Take( depthImage ), Take( depthAllocation ) ); vmaDestroyImage( render_device.gpuAllocator, Take( depthImage ), Take( depthAllocation ) );
vkDestroyCommandPool( device, Take( commandPool ), nullptr ); vkDestroyCommandPool( device, Take( commandPool ), nullptr );
vkDestroyFence( device, Take( frameReadyToReuse ), nullptr ); vkDestroyFence( device, Take( frameReadyToReuse ), nullptr );
@ -44,71 +46,64 @@ void Frame::destroy( RenderDevice const& renderDevice )
vkDestroySemaphore( device, Take( renderFinishedSemaphore ), nullptr ); vkDestroySemaphore( device, Take( renderFinishedSemaphore ), nullptr );
} }
Frame::~Frame() Frame Frame::Create(
VkDevice const device,
VmaAllocator const gpu_allocator,
uint32_t const direct_queue_family_index,
VkExtent2D const swapchain_extent )
{ {
// Manual Cleanup Required. VkCommandPool command_pool;
ASSERT( !isInit() ); VkCommandBuffer command_buffer;
} VkSemaphore image_acquired_semaphore;
VkSemaphore render_finished_semaphore;
VkFence frame_ready_to_reuse;
void Frame_Create( VkImage depth_image;
Frame* frame, VmaAllocation depth_allocation;
VkDevice const device, VkImageView depth_view;
VmaAllocator const gpuAllocator,
uint32_t const directQueueFamilyIndex,
VkExtent2D const swapchainExtent )
{
VkCommandPool commandPool;
VkCommandBuffer commandBuffer;
VkSemaphore imageAcquiredSemaphore;
VkSemaphore renderFinishedSemaphore;
VkFence frameReadyToReuse;
VkImage depthImage;
VmaAllocation depthAllocation;
VkImageView depthView;
{ {
VkCommandPoolCreateInfo const commandPoolCreateInfo = { VkCommandPoolCreateInfo const command_pool_create_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
.queueFamilyIndex = directQueueFamilyIndex, .queueFamilyIndex = direct_queue_family_index,
}; };
VK_CHECK( vkCreateCommandPool( device, &commandPoolCreateInfo, nullptr, &commandPool ) ); VK_CHECK( vkCreateCommandPool( device, &command_pool_create_info, nullptr, &command_pool ) );
VkCommandBufferAllocateInfo const commandBufferAllocateInfo = { VkCommandBufferAllocateInfo const command_buffer_allocate_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.commandPool = commandPool, .commandPool = command_pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1, .commandBufferCount = 1,
}; };
VK_CHECK( vkAllocateCommandBuffers( device, &commandBufferAllocateInfo, &commandBuffer ) ); VK_CHECK( vkAllocateCommandBuffers( device, &command_buffer_allocate_info, &command_buffer ) );
VkSemaphoreCreateInfo constexpr semaphoreCreateInfo = { VkSemaphoreCreateInfo constexpr semaphore_create_info = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
}; };
VK_CHECK( vkCreateSemaphore( device, &semaphoreCreateInfo, nullptr, &imageAcquiredSemaphore ) ); VK_CHECK( vkCreateSemaphore( device, &semaphore_create_info, nullptr, &image_acquired_semaphore ) );
VK_CHECK( vkCreateSemaphore( device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphore ) ); VK_CHECK( vkCreateSemaphore( device, &semaphore_create_info, nullptr, &render_finished_semaphore ) );
VkFenceCreateInfo constexpr fenceCreateInfo = { VkFenceCreateInfo constexpr fence_create_info = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = VK_FENCE_CREATE_SIGNALED_BIT, .flags = VK_FENCE_CREATE_SIGNALED_BIT,
}; };
VK_CHECK( vkCreateFence( device, &fenceCreateInfo, nullptr, &frameReadyToReuse ) ); VK_CHECK( vkCreateFence( device, &fence_create_info, nullptr, &frame_ready_to_reuse ) );
} }
{ {
VkImageCreateInfo const depthImageCreateInfo = { VkImageCreateInfo const depth_image_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.imageType = VK_IMAGE_TYPE_2D, .imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_D32_SFLOAT, .format = VK_FORMAT_D32_SFLOAT,
.extent = { swapchainExtent.width, swapchainExtent.height, 1 }, .extent = { swapchain_extent.width, swapchain_extent.height, 1 },
.mipLevels = 1, .mipLevels = 1,
.arrayLayers = 1, .arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
@ -120,7 +115,7 @@ void Frame_Create(
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
}; };
VmaAllocationCreateInfo constexpr depthAllocationCreateInfo = { VmaAllocationCreateInfo constexpr depth_allocation_create_info = {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, .flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
.usage = VMA_MEMORY_USAGE_GPU_ONLY, .usage = VMA_MEMORY_USAGE_GPU_ONLY,
.requiredFlags = 0, .requiredFlags = 0,
@ -132,9 +127,14 @@ void Frame_Create(
}; };
VK_CHECK( vmaCreateImage( VK_CHECK( vmaCreateImage(
gpuAllocator, &depthImageCreateInfo, &depthAllocationCreateInfo, &depthImage, &depthAllocation, nullptr ) ); gpu_allocator,
&depth_image_create_info,
&depth_allocation_create_info,
&depth_image,
&depth_allocation,
nullptr ) );
VkImageSubresourceRange constexpr subresourceRange = { VkImageSubresourceRange constexpr subresource_range = {
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = 1,
@ -142,33 +142,35 @@ void Frame_Create(
.layerCount = 1, .layerCount = 1,
}; };
VkComponentMapping constexpr componentMapping = { VkComponentMapping constexpr component_mapping = {
.r = VK_COMPONENT_SWIZZLE_IDENTITY, .r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY, .g = VK_COMPONENT_SWIZZLE_IDENTITY,
.b = VK_COMPONENT_SWIZZLE_IDENTITY, .b = VK_COMPONENT_SWIZZLE_IDENTITY,
.a = VK_COMPONENT_SWIZZLE_IDENTITY, .a = VK_COMPONENT_SWIZZLE_IDENTITY,
}; };
VkImageViewCreateInfo const imageViewCreateInfo = { VkImageViewCreateInfo const image_view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.image = depthImage, .image = depth_image,
.viewType = VK_IMAGE_VIEW_TYPE_2D, .viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = depthImageCreateInfo.format, .format = depth_image_create_info.format,
.components = componentMapping, .components = component_mapping,
.subresourceRange = subresourceRange, .subresourceRange = subresource_range,
}; };
VK_CHECK( vkCreateImageView( device, &imageViewCreateInfo, nullptr, &depthView ) ); VK_CHECK( vkCreateImageView( device, &image_view_create_info, nullptr, &depth_view ) );
} }
frame->commandPool = commandPool; return Frame{
frame->commandBuffer = commandBuffer; command_pool,
frame->imageAcquiredSemaphore = imageAcquiredSemaphore; command_buffer,
frame->renderFinishedSemaphore = renderFinishedSemaphore; image_acquired_semaphore,
frame->frameReadyToReuse = frameReadyToReuse; render_finished_semaphore,
frame->depthImage = depthImage; frame_ready_to_reuse,
frame->depthView = depthView; depth_image,
frame->depthAllocation = depthAllocation; depth_allocation,
depth_view,
};
} }

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <utility>
#include "VulkanHeader.h" #include "VulkanHeader.h"
namespace Blaze
{
struct RenderDevice; struct RenderDevice;
struct Frame struct Frame
@ -18,31 +18,22 @@ struct Frame
VmaAllocation depthAllocation; VmaAllocation depthAllocation;
VkImageView depthView; VkImageView depthView;
[[nodiscard]] bool isInit() const; [[nodiscard]] bool IsInit() const;
Frame( Frame(
VkCommandPool commandPool, VkCommandPool command_pool,
VkCommandBuffer commandBuffer, VkCommandBuffer command_buffer,
VkSemaphore imageAcquiredSemaphore, VkSemaphore image_acquired_semaphore,
VkSemaphore renderFinishedSemaphore, VkSemaphore render_finished_semaphore,
VkFence frameReadyToReuse, VkFence frame_ready_to_reuse,
VkImage depthImage, VkImage depth_image,
VmaAllocation depthAllocation, VmaAllocation depth_allocation,
VkImageView depthView ); VkImageView depth_view );
void destroy( RenderDevice const& renderDevice ); static Frame Create(
VkDevice device, VmaAllocator gpu_allocator, uint32_t direct_queue_family_index, VkExtent2D swapchain_extent );
Frame( Frame const& other ) = delete; void Destroy( RenderDevice const& render_device );
Frame( Frame&& other ) noexcept = delete;
Frame& operator=( Frame const& other ) = delete;
Frame& operator=( Frame&& other ) noexcept = delete;
~Frame();
}; };
void Frame_Create( } // namespace Blaze
Frame* frame,
VkDevice device,
VmaAllocator gpuAllocator,
uint32_t directQueueFamilyIndex,
VkExtent2D swapchainExtent );

View File

@ -1,72 +1,79 @@
#include "FreeList.h" #include "FreeList.h"
#include "MacroUtils.h"
namespace Blaze::Util
{
FreeList::Iterator& FreeList::Iterator::operator++() FreeList::Iterator& FreeList::Iterator::operator++()
{ {
pIter = pIter->pNext; iter = iter->next;
return *this; return *this;
} }
bool FreeList::Iterator::operator==( Iterator const& other ) const bool FreeList::Iterator::operator==( Iterator const& other ) const
{ {
return this->pIter == other.pIter; return this->iter == other.iter;
} }
FreeList::Node& FreeList::Iterator::operator*() FreeList::Node& FreeList::Iterator::operator*() const
{ {
return *pIter; return *iter;
} }
FreeList::FreeList() : m_head{ .pNext = &m_tail, .pPrev = nullptr }, m_tail{ .pNext = nullptr, .pPrev = &m_head } FreeList::FreeList() : m_head{ .next = &m_tail, .prev = nullptr }, m_tail{ .next = nullptr, .prev = &m_head }
{} {}
void FreeList::pushBack( Node* pNode ) void FreeList::PushBack( Node* node )
{ {
Node* prev = m_tail.pPrev; Node* prev = m_tail.prev;
// Set prev as previous of pNode // Set prev as previous of node
prev->pNext = pNode; prev->next = node;
pNode->pPrev = prev; node->prev = prev;
// Set tail as next of pNode // Set tail as next of node
pNode->pNext = &m_tail; node->next = &m_tail;
m_tail.pPrev = pNode; m_tail.prev = node;
} }
void FreeList::pushFront( Node* pNode ) void FreeList::PushFront( Node* node )
{ {
Node* next = m_head.pNext; Node* next = m_head.next;
// Set next as next of pNode // Set next as next of node
next->pPrev = pNode; next->prev = node;
pNode->pNext = next; node->next = next;
// Set head as prev of pNode // Set head as prev of node
pNode->pPrev = &m_head; node->prev = &m_head;
m_head.pNext = pNode; m_head.next = node;
} }
FreeList::Node* FreeList::popFront() FreeList::Node* FreeList::PopFront()
{ {
ASSERT( not empty() ); ASSERT( not Empty() );
Node* element = m_head.pNext; Node* element = m_head.next;
element->pPrev->pNext = element->pNext; m_head.next = element->next;
element->pNext->pPrev = element->pPrev; element->next->prev = &m_head;
return element; return element;
} }
bool FreeList::empty() const bool FreeList::Empty() const
{ {
return m_head.pNext == &m_tail; return m_head.next == &m_tail;
} }
FreeList::Iterator FreeList::begin() FreeList::Iterator FreeList::begin()
{ {
return { m_head.pNext }; return { m_head.next };
} }
FreeList::Iterator FreeList::end() FreeList::Iterator FreeList::end()
{ {
return { &m_tail }; return { &m_tail };
} }
} // namespace Blaze::Util

View File

@ -1,21 +1,23 @@
#pragma once #pragma once
#include "MacroUtils.h"
namespace Blaze::Util
{
struct FreeList struct FreeList
{ {
struct Node struct Node
{ {
Node* pNext; Node* next;
Node* pPrev; Node* prev;
}; };
struct Iterator struct Iterator
{ {
Node* pIter; Node* iter;
Iterator& operator++(); Iterator& operator++();
bool operator==( Iterator const& other ) const; bool operator==( Iterator const& other ) const;
Node& operator*(); Node& operator*() const;
}; };
private: private:
@ -25,10 +27,10 @@ private:
public: public:
FreeList(); FreeList();
void pushBack( Node* pNode ); void PushBack( Node* node );
void pushFront( Node* pNode ); void PushFront( Node* node );
Node* popFront(); Node* PopFront();
[[nodiscard]] bool empty() const; [[nodiscard]] bool Empty() const;
Iterator begin(); Iterator begin();
Iterator end(); Iterator end();
@ -40,3 +42,5 @@ public:
~FreeList() = default; ~FreeList() = default;
}; };
} // namespace Blaze::Util

View File

@ -2,59 +2,62 @@
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
void GlobalMemory::init( size_t const size ) namespace Blaze
{
void GlobalMemory::Initialize( size_t const size )
{ {
memory = new std::byte[size]; memory = new std::byte[size];
capacity = size; capacity = size;
available = size; available = size;
} }
void GlobalMemory::destroy() void GlobalMemory::Destroy()
{ {
std::byte const* originalMemory = memory - ( capacity - available ); std::byte const* original_memory = memory - ( capacity - available );
delete[] originalMemory; delete[] original_memory;
memory = nullptr; memory = nullptr;
available = 0; available = 0;
capacity = 0; capacity = 0;
} }
std::byte* GlobalMemory::allocate( size_t const size ) std::byte* GlobalMemory::Allocate( size_t const size )
{ {
assert( size <= available && "No enough space available" ); assert( size <= available && "No enough space available" );
std::byte* retVal = memory; std::byte* ret_val = memory;
memset( retVal, 0, size ); memset( ret_val, 0, size );
memory += size; memory += size;
available -= size; available -= size;
SDL_LogInfo( SDL_LogInfo(
SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_CATEGORY_SYSTEM,
"ALLOC: %p -> %p (%llu) (avail: %llu)", "ALLOC: %p -> %p (%llu) (avail: %llu)",
reinterpret_cast<void*>( retVal ), reinterpret_cast<void*>( ret_val ),
reinterpret_cast<void*>( memory ), reinterpret_cast<void*>( memory ),
size, size,
available ); available );
return retVal; return ret_val;
} }
std::byte* GlobalMemory::allocate( size_t const size, size_t const alignment ) std::byte* GlobalMemory::Allocate( size_t const size, size_t const alignment )
{ {
uintptr_t const addr = reinterpret_cast<uintptr_t>( memory ); uintptr_t const addr = reinterpret_cast<uintptr_t>( memory );
uintptr_t const foundOffset = addr % alignment; uintptr_t const found_offset = addr % alignment;
if ( foundOffset == 0 ) if ( found_offset == 0 )
{ {
return allocate( size ); return Allocate( size );
} }
uintptr_t const offset = alignment - foundOffset; uintptr_t const offset = alignment - found_offset;
size_t const allocationSize = size + offset; size_t const allocation_size = size + offset;
return offset + allocate( allocationSize ); return offset + Allocate( allocation_size );
} }
GlobalMemory::State GlobalMemory::getState() const GlobalMemory::State GlobalMemory::GetState() const
{ {
SDL_LogInfo( SDL_LOG_CATEGORY_SYSTEM, "TEMP: %p %llu", reinterpret_cast<void*>( memory ), available ); SDL_LogInfo( SDL_LOG_CATEGORY_SYSTEM, "TEMP: %p %llu", reinterpret_cast<void*>( memory ), available );
return { return {
@ -63,7 +66,7 @@ GlobalMemory::State GlobalMemory::getState() const
}; };
} }
void GlobalMemory::restoreState( State const& state ) void GlobalMemory::RestoreState( State const& state )
{ {
ASSERT( memory >= state.memory ); //< Behind top of allocator ASSERT( memory >= state.memory ); //< Behind top of allocator
ASSERT( memory - ( capacity - available ) <= state.memory ); //< Ahead of start of allocator ASSERT( memory - ( capacity - available ) <= state.memory ); //< Ahead of start of allocator
@ -71,3 +74,5 @@ void GlobalMemory::restoreState( State const& state )
memory = state.memory; memory = state.memory;
available = state.available; available = state.available;
} }
} // namespace Blaze

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <cstdint>
#include "MacroUtils.h" #include "MacroUtils.h"
namespace Blaze
{
consteval size_t operator""_KiB( size_t const value ) consteval size_t operator""_KiB( size_t const value )
{ {
return value * 1024; return value * 1024;
@ -19,27 +19,30 @@ consteval size_t operator""_GiB( size_t const value )
return value * 1024_MiB; return value * 1024_MiB;
} }
using byte = std::byte;
struct GlobalMemory struct GlobalMemory
{ {
struct State struct State
{ {
std::byte* memory; byte* memory;
size_t available; size_t available;
}; };
std::byte* memory; byte* memory;
size_t available; size_t available;
size_t capacity; size_t capacity;
void init( size_t size ); void Initialize( size_t size );
void destroy(); void Destroy();
[[nodiscard]] [[nodiscard]]
std::byte* allocate( size_t size ); byte* Allocate( size_t size );
[[nodiscard]] [[nodiscard]]
std::byte* allocate( size_t size, size_t alignment ); byte* Allocate( size_t size, size_t alignment );
[[nodiscard]] [[nodiscard]]
State getState() const; //< Do not do any permanent allocations after calling this. State GetState() const; //< Do not do any permanent allocations after calling this.
void restoreState( State const& state ); //< Call this before permanent allocations. void RestoreState( State const& state ); //< Call this before permanent allocations.
}; };
} // namespace Blaze

View File

@ -1,11 +0,0 @@
#pragma once
#include <utility>
using byte = std::byte;
template <std::totally_ordered T>
T Clamp( T const val, T const minVal, T const maxVal )
{
return std::min( maxVal, std::max( val, minVal ) );
}

View File

@ -1,7 +1,6 @@
#include "MiscData.h" #include "MiscData.h"
#include <array> #include <array>
#include <iso646.h>
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
@ -9,38 +8,41 @@
#include "MacroUtils.h" #include "MacroUtils.h"
#include "RenderDevice.h" #include "RenderDevice.h"
bool MiscData::init( RenderDevice const& renderDevice ) namespace Blaze
{ {
VkDevice const device = renderDevice.device;
bool MiscData::Init( RenderDevice const& render_device )
{
VkDevice const device = render_device.device;
previousCounter = 0; previousCounter = 0;
// Pipeline Creation // Pipeline Creation
{ {
size_t dataSize; size_t data_size;
void* rawData = SDL_LoadFile( "Mesh.spv", &dataSize ); void* raw_data = SDL_LoadFile( "Mesh.spv", &data_size );
ASSERT( dataSize % 4 == 0 ); ASSERT( data_size % 4 == 0 );
if ( !rawData ) if ( !raw_data )
{ {
SDL_LogError( SDL_LOG_CATEGORY_SYSTEM, "%s", SDL_GetError() ); SDL_LogError( SDL_LOG_CATEGORY_SYSTEM, "%s", SDL_GetError() );
return false; return false;
} }
uint32_t const* data = static_cast<uint32_t const*>( rawData ); uint32_t const* data = static_cast<uint32_t const*>( raw_data );
// Create Shader Module // Create Shader Module
VkShaderModuleCreateInfo const shaderModuleCreateInfo = { VkShaderModuleCreateInfo const shader_module_create_info = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.codeSize = dataSize, .codeSize = data_size,
.pCode = data, .pCode = data,
}; };
VkShaderModule shaderModule; VkShaderModule shader_module;
VK_CHECK( vkCreateShaderModule( device, &shaderModuleCreateInfo, nullptr, &shaderModule ) ); VK_CHECK( vkCreateShaderModule( device, &shader_module_create_info, nullptr, &shader_module ) );
VkDescriptorSetLayoutBinding constexpr perFrameDescriptorBinding{ VkDescriptorSetLayoutBinding constexpr per_frame_descriptor_binding{
.binding = 0, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
@ -48,116 +50,86 @@ bool MiscData::init( RenderDevice const& renderDevice )
.pImmutableSamplers = nullptr, .pImmutableSamplers = nullptr,
}; };
VkDescriptorSetLayoutCreateInfo perFrameDescriptorSetLayoutCreateInfo = { VkDescriptorSetLayoutCreateInfo per_frame_descriptor_set_layout_create_info{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.bindingCount = 1, .bindingCount = 1,
.pBindings = &perFrameDescriptorBinding, .pBindings = &per_frame_descriptor_binding,
}; };
VK_CHECK( VK_CHECK( vkCreateDescriptorSetLayout(
vkCreateDescriptorSetLayout( device, &perFrameDescriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout ) ); device, &per_frame_descriptor_set_layout_create_info, nullptr, &descriptorSetLayout ) );
VkPushConstantRange const pushConstantRange = { VkPushConstantRange constexpr push_constant_range{
.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS, .stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS,
.offset = 0, .offset = 0,
.size = 2 * sizeof( DirectX::XMMATRIX ) + Material::GPU_DATA_SIZE, .size = 2 * sizeof( DirectX::XMMATRIX ) + Material::kGPUDataSize,
}; };
std::array const descriptorSetLayouts = { VkDescriptorSetLayout const descriptor_set_layouts[] = {
renderDevice.textureManager->descriptorLayout(), render_device.textureManager->DescriptorLayout(),
descriptorSetLayout, descriptorSetLayout,
}; };
VkPipelineLayoutCreateInfo const pipelineLayoutCreateInfo = { VkPipelineLayoutCreateInfo const pipeline_layout_create_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.setLayoutCount = static_cast<uint32_t>( descriptorSetLayouts.size() ), .setLayoutCount = _countof( descriptor_set_layouts ),
.pSetLayouts = descriptorSetLayouts.data(), .pSetLayouts = descriptor_set_layouts,
.pushConstantRangeCount = 1, .pushConstantRangeCount = 1,
.pPushConstantRanges = &pushConstantRange, .pPushConstantRanges = &push_constant_range,
}; };
VK_CHECK( vkCreatePipelineLayout( device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout ) ); VK_CHECK( vkCreatePipelineLayout( device, &pipeline_layout_create_info, nullptr, &pipelineLayout ) );
std::array stages = { VkPipelineShaderStageCreateInfo stages[] = {
VkPipelineShaderStageCreateInfo{ {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.stage = VK_SHADER_STAGE_VERTEX_BIT, .stage = VK_SHADER_STAGE_VERTEX_BIT,
.module = shaderModule, .module = shader_module,
.pName = "VertexMain", .pName = "VertexMain",
.pSpecializationInfo = nullptr, .pSpecializationInfo = nullptr,
}, },
VkPipelineShaderStageCreateInfo{ {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT, .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = shaderModule, .module = shader_module,
.pName = "FragmentMain", .pName = "FragmentMain",
.pSpecializationInfo = nullptr, .pSpecializationInfo = nullptr,
} }
}; };
// Bindings // Bindings
VkVertexInputBindingDescription constexpr bindingDescription = { VkVertexInputBindingDescription constexpr binding_description = {
.binding = 0, .binding = 0,
.stride = sizeof( Vertex ), .stride = sizeof( Vertex ),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX, .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
}; };
std::array attributeDescriptions = { VkVertexInputAttributeDescription attribute_descriptions[] = {
VkVertexInputAttributeDescription{ {.location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof( Vertex, position ) },
.location = 0, {.location = 1, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof( Vertex, normal ) },
.binding = 0, {.location = 2, .binding = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof( Vertex, tangent ) },
.format = VK_FORMAT_R32G32B32_SFLOAT, {.location = 3, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof( Vertex, texCoord0 )},
.offset = offsetof( Vertex, position ), {.location = 4, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof( Vertex, texCoord1 )},
}, {.location = 5, .binding = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof( Vertex, color0 ) },
VkVertexInputAttributeDescription{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof( Vertex, normal ),
},
VkVertexInputAttributeDescription{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof( Vertex, tangent ),
},
VkVertexInputAttributeDescription{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof( Vertex, texCoord0 ),
},
VkVertexInputAttributeDescription{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof( Vertex, texCoord1 ),
},
VkVertexInputAttributeDescription{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof( Vertex, color0 ),
},
}; };
VkPipelineVertexInputStateCreateInfo const vertexInputState = { VkPipelineVertexInputStateCreateInfo const vertex_input_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.vertexBindingDescriptionCount = 1, .vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = &bindingDescription, .pVertexBindingDescriptions = &binding_description,
.vertexAttributeDescriptionCount = static_cast<uint32_t>( attributeDescriptions.size() ), .vertexAttributeDescriptionCount = _countof( attribute_descriptions ),
.pVertexAttributeDescriptions = attributeDescriptions.data(), .pVertexAttributeDescriptions = attribute_descriptions,
}; };
VkPipelineInputAssemblyStateCreateInfo constexpr inputAssembly = { VkPipelineInputAssemblyStateCreateInfo const input_assembly = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -165,14 +137,14 @@ bool MiscData::init( RenderDevice const& renderDevice )
.primitiveRestartEnable = VK_FALSE, .primitiveRestartEnable = VK_FALSE,
}; };
VkPipelineTessellationStateCreateInfo constexpr tessellationState = { VkPipelineTessellationStateCreateInfo constexpr tessellation_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.patchControlPoints = 0, .patchControlPoints = 0,
}; };
VkPipelineViewportStateCreateInfo constexpr viewportState = { VkPipelineViewportStateCreateInfo constexpr viewport_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -182,7 +154,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.pScissors = nullptr, .pScissors = nullptr,
}; };
VkPipelineRasterizationStateCreateInfo constexpr rasterizationState = { VkPipelineRasterizationStateCreateInfo constexpr rasterization_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -198,7 +170,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.lineWidth = 1.0f, .lineWidth = 1.0f,
}; };
VkPipelineMultisampleStateCreateInfo constexpr multisampleState = { VkPipelineMultisampleStateCreateInfo constexpr multisample_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -210,7 +182,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.alphaToOneEnable = VK_FALSE, .alphaToOneEnable = VK_FALSE,
}; };
VkPipelineDepthStencilStateCreateInfo constexpr depthStencilState = { VkPipelineDepthStencilStateCreateInfo constexpr depth_stencil_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -225,7 +197,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.maxDepthBounds = 1.0f, .maxDepthBounds = 1.0f,
}; };
VkPipelineColorBlendAttachmentState constexpr colorBlendAttachmentState = { VkPipelineColorBlendAttachmentState constexpr color_blend_attachment_state = {
.blendEnable = VK_FALSE, .blendEnable = VK_FALSE,
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
@ -234,52 +206,52 @@ bool MiscData::init( RenderDevice const& renderDevice )
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.alphaBlendOp = VK_BLEND_OP_ADD, .alphaBlendOp = VK_BLEND_OP_ADD,
.colorWriteMask = .colorWriteMask =
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
}; };
VkPipelineColorBlendStateCreateInfo const colorBlendState = { VkPipelineColorBlendStateCreateInfo const color_blend_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.logicOpEnable = VK_FALSE, .logicOpEnable = VK_FALSE,
.logicOp = VK_LOGIC_OP_COPY, .logicOp = VK_LOGIC_OP_COPY,
.attachmentCount = 1, .attachmentCount = 1,
.pAttachments = &colorBlendAttachmentState, .pAttachments = &color_blend_attachment_state,
.blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }, .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
}; };
std::array constexpr dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkDynamicState constexpr dynamic_states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo const dynamicStateCreateInfo = { VkPipelineDynamicStateCreateInfo const dynamic_state_create_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.dynamicStateCount = static_cast<uint32_t>( dynamicStates.size() ), .dynamicStateCount = _countof( dynamic_states ),
.pDynamicStates = dynamicStates.data() .pDynamicStates = dynamic_states,
}; };
VkPipelineRenderingCreateInfoKHR const renderingCreateInfo = { VkPipelineRenderingCreateInfoKHR const rendering_create_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
.colorAttachmentCount = 1, .colorAttachmentCount = 1,
.pColorAttachmentFormats = &renderDevice.swapchainFormat, .pColorAttachmentFormats = &render_device.swapchainFormat,
.depthAttachmentFormat = VK_FORMAT_D32_SFLOAT, .depthAttachmentFormat = VK_FORMAT_D32_SFLOAT,
}; };
VkGraphicsPipelineCreateInfo const graphicsPipelineCreateInfo = { VkGraphicsPipelineCreateInfo const graphics_pipeline_create_info = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &renderingCreateInfo, .pNext = &rendering_create_info,
.flags = 0, .flags = 0,
.stageCount = static_cast<uint32_t>( stages.size() ), .stageCount = _countof( stages ),
.pStages = stages.data(), .pStages = stages,
.pVertexInputState = &vertexInputState, .pVertexInputState = &vertex_input_state,
.pInputAssemblyState = &inputAssembly, .pInputAssemblyState = &input_assembly,
.pTessellationState = &tessellationState, .pTessellationState = &tessellation_state,
.pViewportState = &viewportState, .pViewportState = &viewport_state,
.pRasterizationState = &rasterizationState, .pRasterizationState = &rasterization_state,
.pMultisampleState = &multisampleState, .pMultisampleState = &multisample_state,
.pDepthStencilState = &depthStencilState, .pDepthStencilState = &depth_stencil_state,
.pColorBlendState = &colorBlendState, .pColorBlendState = &color_blend_state,
.pDynamicState = &dynamicStateCreateInfo, .pDynamicState = &dynamic_state_create_info,
.layout = pipelineLayout, .layout = pipelineLayout,
.renderPass = nullptr, .renderPass = nullptr,
.subpass = 0, .subpass = 0,
@ -287,11 +259,11 @@ bool MiscData::init( RenderDevice const& renderDevice )
.basePipelineIndex = 0, .basePipelineIndex = 0,
}; };
VK_CHECK( vkCreateGraphicsPipelines( device, nullptr, 1, &graphicsPipelineCreateInfo, nullptr, &meshPipeline ) ); VK_CHECK( vkCreateGraphicsPipelines( device, nullptr, 1, &graphics_pipeline_create_info, nullptr, &meshPipeline ) );
vkDestroyShaderModule( device, shaderModule, nullptr ); vkDestroyShaderModule( device, shader_module, nullptr );
SDL_free( rawData ); SDL_free( raw_data );
} }
// Camera // Camera
@ -301,7 +273,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
cameraUp = DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 1.0f ); cameraUp = DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 1.0f );
cameraData.viewMatrix = DirectX::XMMatrixLookAtLH( cameraData.cameraPosition, cameraTarget, cameraUp ); cameraData.viewMatrix = DirectX::XMMatrixLookAtLH( cameraData.cameraPosition, cameraTarget, cameraUp );
cameraData.projectionMatrix = cameraData.projectionMatrix =
DirectX::XMMatrixPerspectiveFovLH( DirectX::XMConvertToRadians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f ); DirectX::XMMatrixPerspectiveFovLH( DirectX::XMConvertToRadians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f );
cameraUniformBufferSize = sizeof( CameraData ) + sizeof( LightData ); cameraUniformBufferSize = sizeof( CameraData ) + sizeof( LightData );
} }
@ -309,14 +281,14 @@ bool MiscData::init( RenderDevice const& renderDevice )
// Lights // Lights
{ {
pointLights = renderDevice.bufferManager->createStorageBuffer( 10 * sizeof( PointLight ) ); pointLights = render_device.bufferManager->CreateStorageBuffer( 10 * sizeof( PointLight ) );
if ( not pointLights ) return false; if ( not pointLights ) return false;
directionalLights = renderDevice.bufferManager->createStorageBuffer( 10 * sizeof( DirectionalLight ) ); directionalLights = render_device.bufferManager->CreateStorageBuffer( 10 * sizeof( DirectionalLight ) );
if ( not directionalLights ) return false; if ( not directionalLights ) return false;
lightData.pointLights = renderDevice.bufferManager->fetchDeviceAddress( pointLights ).value(); lightData.pointLights = render_device.bufferManager->FetchDeviceAddress( pointLights ).value();
lightData.directionalLights = renderDevice.bufferManager->fetchDeviceAddress( directionalLights ).value(); lightData.directionalLights = render_device.bufferManager->FetchDeviceAddress( directionalLights ).value();
lightData.dirLightCount = 0; lightData.dirLightCount = 0;
lightData.pointLightCount = 0; lightData.pointLightCount = 0;
} }
@ -324,7 +296,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
// Uniform Buffer // Uniform Buffer
{ {
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const buffer_create_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
@ -335,7 +307,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocation_create_info = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
@ -346,19 +318,19 @@ bool MiscData::init( RenderDevice const& renderDevice )
.priority = 1.0f, .priority = 1.0f,
}; };
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocation_info;
VK_CHECK( vmaCreateBuffer( VK_CHECK( vmaCreateBuffer(
renderDevice.gpuAllocator, render_device.gpuAllocator,
&bufferCreateInfo, &buffer_create_info,
&allocationCreateInfo, &allocation_create_info,
&cameraUniformBuffer, &cameraUniformBuffer,
&cameraUniformBufferAllocation, &cameraUniformBufferAllocation,
&allocationInfo ) ); &allocation_info ) );
if ( allocationInfo.pMappedData ) if ( allocation_info.pMappedData )
{ {
cameraUniformBufferPtr = static_cast<uint8_t*>( allocationInfo.pMappedData ); cameraUniformBufferPtr = static_cast<uint8_t*>( allocation_info.pMappedData );
memcpy( cameraUniformBufferPtr, &cameraData, sizeof cameraData ); memcpy( cameraUniformBufferPtr, &cameraData, sizeof cameraData );
memcpy( cameraUniformBufferPtr + sizeof cameraData, &lightData, sizeof lightData ); memcpy( cameraUniformBufferPtr + sizeof cameraData, &lightData, sizeof lightData );
} }
@ -366,28 +338,22 @@ bool MiscData::init( RenderDevice const& renderDevice )
// Descriptors // Descriptors
{ {
std::array poolSizes = { VkDescriptorPoolSize pool_sizes[] = {
VkDescriptorPoolSize{ {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3 },
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 100},
.descriptorCount = 3,
},
VkDescriptorPoolSize{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 100,
},
}; };
VkDescriptorPoolCreateInfo const descriptorPoolCreateInfo = { VkDescriptorPoolCreateInfo const descriptor_pool_create_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.maxSets = 101, .maxSets = 101,
.poolSizeCount = static_cast<uint32_t>( poolSizes.size() ), .poolSizeCount = _countof( pool_sizes ),
.pPoolSizes = poolSizes.data(), .pPoolSizes = pool_sizes,
}; };
VK_CHECK( vkCreateDescriptorPool( device, &descriptorPoolCreateInfo, nullptr, &descriptorPool ) ); VK_CHECK( vkCreateDescriptorPool( device, &descriptor_pool_create_info, nullptr, &descriptorPool ) );
VkDescriptorSetAllocateInfo const descriptorSetAllocateInfo = { VkDescriptorSetAllocateInfo const descriptor_set_allocate_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.descriptorPool = descriptorPool, .descriptorPool = descriptorPool,
@ -395,36 +361,35 @@ bool MiscData::init( RenderDevice const& renderDevice )
.pSetLayouts = &descriptorSetLayout, .pSetLayouts = &descriptorSetLayout,
}; };
VK_CHECK( vkAllocateDescriptorSets( device, &descriptorSetAllocateInfo, &descriptorSet ) ); VK_CHECK( vkAllocateDescriptorSets( device, &descriptor_set_allocate_info, &descriptorSet ) );
VkDescriptorBufferInfo const descriptorBufferInfo = { VkDescriptorBufferInfo const descriptor_buffer_info = {
.buffer = cameraUniformBuffer, .buffer = cameraUniformBuffer,
.offset = 0, .offset = 0,
.range = cameraUniformBufferSize, .range = cameraUniformBufferSize,
}; };
std::array writeDescriptorSets = { VkWriteDescriptorSet write_descriptor_sets[] = {
VkWriteDescriptorSet{ {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr, .pNext = nullptr,
.dstSet = descriptorSet, .dstSet = descriptorSet,
.dstBinding = 0, .dstBinding = 0,
.dstArrayElement = 0, .dstArrayElement = 0,
.descriptorCount = 1, .descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pImageInfo = nullptr, .pImageInfo = nullptr,
.pBufferInfo = &descriptorBufferInfo, .pBufferInfo = &descriptor_buffer_info,
.pTexelBufferView = nullptr, .pTexelBufferView = nullptr,
}, },
}; };
vkUpdateDescriptorSets( vkUpdateDescriptorSets( device, _countof( write_descriptor_sets ), write_descriptor_sets, 0, nullptr );
device, static_cast<uint32_t>( writeDescriptorSets.size() ), writeDescriptorSets.data(), 0, nullptr );
} }
// Barrier Creation // Barrier Creation
{ {
VkImageSubresourceRange subresourceRange = { VkImageSubresourceRange subresource_range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = 1,
@ -443,7 +408,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = subresourceRange, .subresourceRange = subresource_range,
}; };
acquireToRenderDependency = { acquireToRenderDependency = {
@ -469,7 +434,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = subresourceRange, .subresourceRange = subresource_range,
}; };
renderToPresentDependency = { renderToPresentDependency = {
@ -494,17 +459,18 @@ bool MiscData::init( RenderDevice const& renderDevice )
return true; return true;
} }
void MiscData::destroy( RenderDevice const& renderDevice ) void MiscData::Destroy( Blaze::RenderDevice const& render_device )
{ {
VkDevice const device = renderDevice.device; VkDevice const device = render_device.device;
vkDestroyDescriptorPool( device, Take( descriptorPool ), nullptr ); vkDestroyDescriptorPool( device, Take( descriptorPool ), nullptr );
vmaDestroyBuffer( renderDevice.gpuAllocator, Take( cameraUniformBuffer ), Take( cameraUniformBufferAllocation ) ); vmaDestroyBuffer( render_device.gpuAllocator, Take( cameraUniformBuffer ), Take( cameraUniformBufferAllocation ) );
renderDevice.bufferManager->freeBuffer( &pointLights ); render_device.bufferManager->FreeBuffer( &pointLights );
renderDevice.bufferManager->freeBuffer( &directionalLights ); render_device.bufferManager->FreeBuffer( &directionalLights );
vkDestroyPipeline( device, Take( meshPipeline ), nullptr ); vkDestroyPipeline( device, Take( meshPipeline ), nullptr );
vkDestroyPipelineLayout( device, Take( pipelineLayout ), nullptr ); vkDestroyPipelineLayout( device, Take( pipelineLayout ), nullptr );
vkDestroyDescriptorSetLayout( device, Take( descriptorSetLayout ), nullptr ); vkDestroyDescriptorSetLayout( device, Take( descriptorSetLayout ), nullptr );
} }
} // namespace Blaze

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <array>
#include "VulkanHeader.h" #include "VulkanHeader.h"
#include <DirectXMath.h> #include <DirectXMath.h>
#include "BufferManager.h" #include "BufferManager.h"
namespace Blaze
{
struct GlobalMemory; struct GlobalMemory;
struct RenderDevice; struct RenderDevice;
@ -31,9 +31,9 @@ struct MiscData
struct DirectionalLight struct DirectionalLight
{ {
DirectX::XMFLOAT3 direction; DirectX::XMFLOAT3 direction;
float _padding0; float padding0;
DirectX::XMFLOAT3 color; DirectX::XMFLOAT3 color;
float _padding1; float padding1;
}; };
struct LightData struct LightData
@ -75,6 +75,7 @@ struct MiscData
uint8_t frameTimeWriteHead; uint8_t frameTimeWriteHead;
uint8_t frameTimeEntryCount; uint8_t frameTimeEntryCount;
bool init( RenderDevice const& renderDevice ); bool Init( RenderDevice const& render_device );
void destroy( RenderDevice const& renderDevice ); void Destroy( RenderDevice const& render_device );
}; };
} // namespace Blaze

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,13 @@
#include "BufferManager.h" #include "BufferManager.h"
#include "TextureManager.h" #include "TextureManager.h"
namespace Blaze
{
struct GlobalMemory;
struct RenderDevice; struct RenderDevice;
struct EntityManager; struct EntityManager;
struct Entity; struct Entity;
struct GlobalMemory;
struct Vertex struct Vertex
{ {
@ -35,7 +38,7 @@ struct ModelMesh
uint32_t primitiveStart = 0; uint32_t primitiveStart = 0;
uint32_t primitiveCount = 0; uint32_t primitiveCount = 0;
[[nodiscard]] bool isNull() const [[nodiscard]] bool IsNull() const
{ {
return primitiveCount == 0; return primitiveCount == 0;
} }
@ -43,8 +46,8 @@ struct ModelMesh
struct Material struct Material
{ {
size_t constexpr static GPU_DATA_OFFSET = sizeof( VkSampler ); size_t constexpr static kGPUDataOffset = sizeof( VkSampler );
size_t constexpr static GPU_DATA_SIZE = 56; size_t constexpr static kGPUDataSize = 56;
VkSampler sampler; // TODO: Reuse VkSampler sampler; // TODO: Reuse
// To copy directly. // To copy directly.
@ -57,29 +60,29 @@ struct Material
float roughness = 1.0f; float roughness = 1.0f;
float metallic = 1.0f; float metallic = 1.0f;
[[nodiscard]] bool isNull() const [[nodiscard]] bool IsNull() const
{ {
return not( albedoTextureID and normalTextureID and metalRoughTextureID and emissiveTextureID and sampler ); return not( albedoTextureID and normalTextureID and metalRoughTextureID and emissiveTextureID and sampler );
} }
}; };
static_assert( sizeof( Material ) == Material::GPU_DATA_OFFSET + Material::GPU_DATA_SIZE ); static_assert( sizeof( Material ) == Material::kGPUDataOffset + Material::kGPUDataSize );
static constexpr Material DEFAULT_MATERIAL = {}; static constexpr Material DEFAULT_MATERIAL = {};
struct Model struct Model
{ {
std::pmr::monotonic_buffer_resource mem; BufferID vertexBuffer;
BufferID indexBuffer;
std::vector<Material> materials;
std::vector<Primitive> primitives;
BufferID vertexBuffer; [[nodiscard]] bool IsNull() const
BufferID indexBuffer;
std::pmr::vector<Material> materials;
std::pmr::vector<Primitive> primitives;
[[nodiscard]] bool isNull() const
{ {
return vertexBuffer.isNull(); return vertexBuffer.IsNull();
} }
}; };
Entity* LoadModel( RenderDevice* renderDevice, EntityManager* entityManager, const char* filename ); Entity* LoadModel( RenderDevice* render_device, EntityManager* entity_manager, const char* filename );
} // namespace Blaze

View File

View File

@ -2,6 +2,9 @@
#include <cstdint> #include <cstdint>
namespace Blaze
{
template <typename T> template <typename T>
struct RID struct RID
{ {
@ -14,7 +17,7 @@ private:
public: public:
RID() = default; RID() = default;
[[nodiscard]] bool isNull() const [[nodiscard]] bool IsNull() const
{ {
return m_index == 0; return m_index == 0;
} }
@ -29,3 +32,5 @@ public:
return m_index != 0; return m_index != 0;
} }
}; };
} // namespace Blaze

View File

@ -1,5 +1,7 @@
#include "RenderDevice.h" #include "RenderDevice.h"
#include <algorithm>
#include "MacroUtils.h" #include "MacroUtils.h"
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
@ -11,26 +13,28 @@
#include "BufferManager.h" #include "BufferManager.h"
#include "Frame.h" #include "Frame.h"
#include "GlobalMemory.h" #include "GlobalMemory.h"
#include "MathUtil.h"
#include "TextureManager.h" #include "TextureManager.h"
using Blaze::RenderDevice;
#if defined( DTOR_TEST )
RenderDevice::~RenderDevice() RenderDevice::~RenderDevice()
{ {
ASSERT( !isInit() ); ASSERT( !IsInit() );
} }
#endif
// TODO: Failure Handling RenderDevice* RenderDevice::Create( GlobalMemory* mem, CreateInfo const& create_info )
RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo const& createInfo )
{ {
ASSERT( mem ); ASSERT( mem );
ASSERT( createInfo.window ); ASSERT( create_info.window );
volkInitialize(); volkInitialize();
VkInstance instance; VkInstance instance;
// Create Instance // Create Instance
{ {
VkApplicationInfo constexpr applicationInfo = { VkApplicationInfo constexpr application_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr, .pNext = nullptr,
.pApplicationName = "Test", .pApplicationName = "Test",
@ -40,63 +44,63 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
.apiVersion = VK_API_VERSION_1_3, .apiVersion = VK_API_VERSION_1_3,
}; };
uint32_t instanceExtensionCount; uint32_t instance_extension_count;
char const* const* instanceExtensions = SDL_Vulkan_GetInstanceExtensions( &instanceExtensionCount ); char const* const* instance_extensions = SDL_Vulkan_GetInstanceExtensions( &instance_extension_count );
VkInstanceCreateInfo const instanceCreateInfo = { VkInstanceCreateInfo const instance_create_info = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.pApplicationInfo = &applicationInfo, .pApplicationInfo = &application_info,
.enabledLayerCount = 0, .enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr, .ppEnabledLayerNames = nullptr,
.enabledExtensionCount = instanceExtensionCount, .enabledExtensionCount = instance_extension_count,
.ppEnabledExtensionNames = instanceExtensions, .ppEnabledExtensionNames = instance_extensions,
}; };
VK_CHECK( vkCreateInstance( &instanceCreateInfo, nullptr, &instance ) ); VK_CHECK( vkCreateInstance( &instance_create_info, nullptr, &instance ) );
volkLoadInstance( instance ); volkLoadInstance( instance );
} }
VkSurfaceKHR surface; VkSurfaceKHR surface;
// Create Surface // Create Surface
ASSERT( SDL_Vulkan_CreateSurface( createInfo.window, instance, nullptr, &surface ) ); ASSERT( SDL_Vulkan_CreateSurface( create_info.window, instance, nullptr, &surface ) );
VkPhysicalDevice physicalDeviceInUse = nullptr; VkPhysicalDevice physical_device_in_use = nullptr;
VkDevice device = nullptr; VkDevice device = nullptr;
VmaAllocator gpuAllocator = nullptr; VmaAllocator allocator = nullptr;
std::optional<uint32_t> directQueueFamilyIndex = std::nullopt; std::optional<uint32_t> direct_queue_family_index = std::nullopt;
VkQueue directQueue = nullptr; VkQueue direct_queue = nullptr;
// Create Device and Queue // Create Device and Queue
{ {
auto tempAllocStart = mem->getState(); auto temp_alloc_start = mem->GetState();
uint32_t physicalDeviceCount; uint32_t physical_device_count;
VK_CHECK( vkEnumeratePhysicalDevices( instance, &physicalDeviceCount, nullptr ) ); VK_CHECK( vkEnumeratePhysicalDevices( instance, &physical_device_count, nullptr ) );
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Found %u GPUs", physicalDeviceCount ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Found %u GPUs", physical_device_count );
VkPhysicalDevice* physicalDevices = VkPhysicalDevice* physical_devices =
reinterpret_cast<VkPhysicalDevice*>( mem->allocate( sizeof( VkPhysicalDevice ) * physicalDeviceCount ) ); reinterpret_cast<VkPhysicalDevice*>( mem->Allocate( sizeof( VkPhysicalDevice ) * physical_device_count ) );
VK_CHECK( vkEnumeratePhysicalDevices( instance, &physicalDeviceCount, physicalDevices ) ); VK_CHECK( vkEnumeratePhysicalDevices( instance, &physical_device_count, physical_devices ) );
for ( VkPhysicalDevice const physicalDevice : std::span{ physicalDevices, physicalDeviceCount } ) for ( VkPhysicalDevice const physical_device : std::span{ physical_devices, physical_device_count } )
{ {
auto tempAllocQueueProperties = mem->getState(); auto temp_alloc_queue_properties = mem->GetState();
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties( physicalDevice, &properties ); vkGetPhysicalDeviceProperties( physical_device, &properties );
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "GPU: %s", properties.deviceName ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "GPU: %s", properties.deviceName );
SDL_LogInfo( SDL_LogInfo(
SDL_LOG_CATEGORY_GPU, SDL_LOG_CATEGORY_GPU,
"- API Version %d.%d.%d", "- API Version %d.%d.%d",
VK_API_VERSION_MAJOR( properties.apiVersion ), VK_API_VERSION_MAJOR( properties.apiVersion ),
VK_API_VERSION_MINOR( properties.apiVersion ), VK_API_VERSION_MINOR( properties.apiVersion ),
VK_API_VERSION_PATCH( properties.apiVersion ) ); VK_API_VERSION_PATCH( properties.apiVersion ) );
constexpr static uint32_t API_PATCH_BITS = 0xFFF; constexpr static uint32_t kApiPatchBits = 0xFFF;
if ( ( properties.apiVersion & ( ~API_PATCH_BITS ) ) < VK_API_VERSION_1_3 ) if ( ( properties.apiVersion & ( ~kApiPatchBits ) ) < VK_API_VERSION_1_3 )
{ {
continue; continue;
} }
@ -106,68 +110,68 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
continue; continue;
} }
uint32_t queueFamilyCount; uint32_t queue_family_count;
vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamilyCount, nullptr ); vkGetPhysicalDeviceQueueFamilyProperties( physical_device, &queue_family_count, nullptr );
VkQueueFamilyProperties* queueFamilyProperties = reinterpret_cast<VkQueueFamilyProperties*>( VkQueueFamilyProperties* queue_family_properties = reinterpret_cast<VkQueueFamilyProperties*>(
mem->allocate( sizeof( VkQueueFamilyProperties ) * queueFamilyCount ) ); mem->Allocate( sizeof( VkQueueFamilyProperties ) * queue_family_count ) );
vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamilyCount, queueFamilyProperties ); vkGetPhysicalDeviceQueueFamilyProperties( physical_device, &queue_family_count, queue_family_properties );
for ( uint32_t queueFamilyIndex = 0; queueFamilyIndex != queueFamilyCount; ++queueFamilyIndex ) for ( uint32_t queue_family_index = 0; queue_family_index != queue_family_count; ++queue_family_index )
{ {
VkQueueFamilyProperties const& qfp = queueFamilyProperties[queueFamilyIndex]; VkQueueFamilyProperties const& qfp = queue_family_properties[queue_family_index];
bool hasGraphicsSupport = false; bool has_graphics_support = false;
bool hasComputeSupport = false; bool has_compute_support = false;
bool hasTransferSupport = false; bool has_transfer_support = false;
bool hasPresentSupport = false; bool has_present_support = false;
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "- Queue [%d]", queueFamilyIndex ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "- Queue [%d]", queue_family_index );
if ( qfp.queueFlags & VK_QUEUE_GRAPHICS_BIT ) if ( qfp.queueFlags & VK_QUEUE_GRAPHICS_BIT )
{ {
hasGraphicsSupport = true; has_graphics_support = true;
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Graphic" ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Graphic" );
} }
if ( qfp.queueFlags & VK_QUEUE_COMPUTE_BIT ) if ( qfp.queueFlags & VK_QUEUE_COMPUTE_BIT )
{ {
hasComputeSupport = true; has_compute_support = true;
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Compute" ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Compute" );
} }
if ( qfp.queueFlags & VK_QUEUE_TRANSFER_BIT ) if ( qfp.queueFlags & VK_QUEUE_TRANSFER_BIT )
{ {
hasTransferSupport = true; has_transfer_support = true;
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Transfer" ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Transfer" );
} }
VkBool32 isSurfaceSupported; VkBool32 is_surface_supported;
VK_CHECK( VK_CHECK(
vkGetPhysicalDeviceSurfaceSupportKHR( physicalDevice, queueFamilyIndex, surface, &isSurfaceSupported ) ); vkGetPhysicalDeviceSurfaceSupportKHR( physical_device, queue_family_index, surface, &is_surface_supported ) );
if ( isSurfaceSupported ) if ( is_surface_supported )
{ {
hasPresentSupport = true; has_present_support = true;
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Present" ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "-- Present" );
} }
if ( hasGraphicsSupport and hasComputeSupport and hasTransferSupport and hasPresentSupport ) if ( has_graphics_support and has_compute_support and has_transfer_support and has_present_support )
{ {
physicalDeviceInUse = physicalDevice; physical_device_in_use = physical_device;
directQueueFamilyIndex = queueFamilyIndex; direct_queue_family_index = queue_family_index;
break; break;
} }
} }
mem->restoreState( tempAllocQueueProperties ); mem->RestoreState( temp_alloc_queue_properties );
} }
ASSERT( physicalDeviceInUse ); ASSERT( physical_device_in_use );
ASSERT( directQueueFamilyIndex.has_value() ); ASSERT( direct_queue_family_index.has_value() );
float priority = 1.0f; float priority = 1.0f;
VkDeviceQueueCreateInfo queueCreateInfo = { VkDeviceQueueCreateInfo queue_create_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.queueFamilyIndex = directQueueFamilyIndex.value(), .queueFamilyIndex = direct_queue_family_index.value(),
.queueCount = 1, .queueCount = 1,
.pQueuePriorities = &priority, .pQueuePriorities = &priority,
}; };
@ -200,27 +204,27 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
.samplerAnisotropy = true, .samplerAnisotropy = true,
}; };
std::array enabledDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; std::array enabled_device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
VkDeviceCreateInfo const deviceCreateInfo = { VkDeviceCreateInfo const device_create_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &features12, .pNext = &features12,
.flags = 0, .flags = 0,
.queueCreateInfoCount = 1, .queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueCreateInfo, .pQueueCreateInfos = &queue_create_info,
.enabledLayerCount = 0, .enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr, .ppEnabledLayerNames = nullptr,
.enabledExtensionCount = static_cast<uint32_t>( enabledDeviceExtensions.size() ), .enabledExtensionCount = static_cast<uint32_t>( enabled_device_extensions.size() ),
.ppEnabledExtensionNames = enabledDeviceExtensions.data(), .ppEnabledExtensionNames = enabled_device_extensions.data(),
.pEnabledFeatures = &features, .pEnabledFeatures = &features,
}; };
VK_CHECK( vkCreateDevice( physicalDeviceInUse, &deviceCreateInfo, nullptr, &device ) ); VK_CHECK( vkCreateDevice( physical_device_in_use, &device_create_info, nullptr, &device ) );
volkLoadDevice( device ); volkLoadDevice( device );
VmaAllocatorCreateInfo allocatorCreateInfo = { VmaAllocatorCreateInfo allocator_create_info = {
.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
.physicalDevice = physicalDeviceInUse, .physicalDevice = physical_device_in_use,
.device = device, .device = device,
.preferredLargeHeapBlockSize = 0, .preferredLargeHeapBlockSize = 0,
.pAllocationCallbacks = nullptr, .pAllocationCallbacks = nullptr,
@ -232,112 +236,115 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
.pTypeExternalMemoryHandleTypes = nullptr, .pTypeExternalMemoryHandleTypes = nullptr,
}; };
VmaVulkanFunctions vkFunctions; VmaVulkanFunctions vk_functions;
VK_CHECK( vmaImportVulkanFunctionsFromVolk( &allocatorCreateInfo, &vkFunctions ) ); VK_CHECK( vmaImportVulkanFunctionsFromVolk( &allocator_create_info, &vk_functions ) );
allocatorCreateInfo.pVulkanFunctions = &vkFunctions; allocator_create_info.pVulkanFunctions = &vk_functions;
VK_CHECK( vmaCreateAllocator( &allocatorCreateInfo, &gpuAllocator ) ); VK_CHECK( vmaCreateAllocator( &allocator_create_info, &allocator ) );
vkGetDeviceQueue( device, directQueueFamilyIndex.value(), 0, &directQueue ); vkGetDeviceQueue( device, direct_queue_family_index.value(), 0, &direct_queue );
mem->restoreState( tempAllocStart ); mem->RestoreState( temp_alloc_start );
} }
// Swapchain creation // Swapchain creation
VkExtent2D swapchainExtent = { createInfo.width, createInfo.height }; VkExtent2D swapchain_extent = { create_info.width, create_info.height };
VkFormat swapchainFormat = VK_FORMAT_UNDEFINED; VkFormat swapchain_format = VK_FORMAT_UNDEFINED;
VkSwapchainKHR swapchain; VkSwapchainKHR swapchain;
VkImage* swapchainImages; VkImage* swapchain_images;
VkImageView* swapchainViews; VkImageView* swapchain_views;
uint32_t swapchainImageCount; uint32_t swapchain_image_count;
{ {
auto tempAllocStart = mem->getState(); auto temp_alloc_start = mem->GetState();
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
VK_CHECK( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physicalDeviceInUse, surface, &capabilities ) ); VK_CHECK( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physical_device_in_use, surface, &capabilities ) );
// Image Count Calculation // Image Count Calculation
swapchainImageCount = 3; swapchain_image_count = 3;
if ( capabilities.maxImageCount > 0 ) if ( capabilities.maxImageCount > 0 )
{ {
swapchainImageCount = std::min( swapchainImageCount, capabilities.maxImageCount ); swapchain_image_count = std::min( swapchain_image_count, capabilities.maxImageCount );
} }
swapchainImageCount = std::max( swapchainImageCount, capabilities.minImageCount + 1 ); swapchain_image_count = std::max( swapchain_image_count, capabilities.minImageCount + 1 );
// Image Size calculation // Image Size calculation
{ {
auto [minWidth, minHeight] = capabilities.minImageExtent; auto [minWidth, minHeight] = capabilities.minImageExtent;
auto [maxWidth, maxHeight] = capabilities.maxImageExtent; auto [maxWidth, maxHeight] = capabilities.maxImageExtent;
swapchainExtent.width = Clamp( swapchainExtent.width, minWidth, maxWidth ); swapchain_extent.width = std::clamp( swapchain_extent.width, minWidth, maxWidth );
swapchainExtent.height = Clamp( swapchainExtent.height, minHeight, maxHeight ); swapchain_extent.height = std::clamp( swapchain_extent.height, minHeight, maxHeight );
} }
uint32_t surfaceFormatCount; uint32_t surface_format_count;
vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDeviceInUse, surface, &surfaceFormatCount, nullptr ); vkGetPhysicalDeviceSurfaceFormatsKHR( physical_device_in_use, surface, &surface_format_count, nullptr );
VkSurfaceFormatKHR* surfaceFormats = VkSurfaceFormatKHR* surface_formats =
reinterpret_cast<VkSurfaceFormatKHR*>( mem->allocate( sizeof( VkSurfaceFormatKHR ) * surfaceFormatCount ) ); reinterpret_cast<VkSurfaceFormatKHR*>( mem->Allocate( sizeof( VkSurfaceFormatKHR ) * surface_format_count ) );
vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDeviceInUse, surface, &surfaceFormatCount, surfaceFormats ); vkGetPhysicalDeviceSurfaceFormatsKHR( physical_device_in_use, surface, &surface_format_count, surface_formats );
VkSurfaceFormatKHR format = { VkSurfaceFormatKHR format = {
.format = VK_FORMAT_UNDEFINED, .format = VK_FORMAT_UNDEFINED,
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, .colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
}; };
for ( auto& surfaceFormat : std::span{ surfaceFormats, surfaceFormatCount } ) for ( uint32_t i = 0; i < surface_format_count; ++i )
{ {
if ( surfaceFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR ) VkSurfaceFormatKHR surface_format = surface_formats[i];
if ( surface_format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR )
{ {
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Color Space SRGB Found %d", surfaceFormat.format ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Color Space SRGB Found %d", surface_format.format );
if ( surfaceFormat.format == VK_FORMAT_R8G8B8A8_SRGB ) if ( surface_format.format == VK_FORMAT_R8G8B8A8_SRGB )
{ {
format = surfaceFormat; format = surface_format;
break; break;
} }
if ( surfaceFormat.format == VK_FORMAT_B8G8R8A8_SRGB ) if ( surface_format.format == VK_FORMAT_B8G8R8A8_SRGB )
{ {
format = surfaceFormat; format = surface_format;
break; break;
} }
if ( surfaceFormat.format == VK_FORMAT_R8G8B8A8_UNORM ) if ( surface_format.format == VK_FORMAT_R8G8B8A8_UNORM )
{ {
format = surfaceFormat; format = surface_format;
} }
} }
} }
ASSERT( format.format != VK_FORMAT_UNDEFINED ); ASSERT( format.format != VK_FORMAT_UNDEFINED );
swapchainFormat = format.format; swapchain_format = format.format;
uint32_t presentModeCount; uint32_t present_mode_count;
vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDeviceInUse, surface, &presentModeCount, nullptr ); vkGetPhysicalDeviceSurfacePresentModesKHR( physical_device_in_use, surface, &present_mode_count, nullptr );
VkPresentModeKHR* presentModes = VkPresentModeKHR* present_modes =
reinterpret_cast<VkPresentModeKHR*>( mem->allocate( sizeof( VkPresentModeKHR ) * presentModeCount ) ); reinterpret_cast<VkPresentModeKHR*>( mem->Allocate( sizeof( VkPresentModeKHR ) * present_mode_count ) );
vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDeviceInUse, surface, &presentModeCount, presentModes ); vkGetPhysicalDeviceSurfacePresentModesKHR( physical_device_in_use, surface, &present_mode_count, present_modes );
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
for ( VkPresentModeKHR presentModeIter : std::span{ presentModes, presentModeCount } ) for ( uint32_t i = 0; i < present_mode_count; ++i )
{ {
if ( presentModeIter == VK_PRESENT_MODE_FIFO_RELAXED_KHR ) VkPresentModeKHR present_mode_iter = present_modes[i];
if ( present_mode_iter == VK_PRESENT_MODE_FIFO_RELAXED_KHR )
{ {
presentMode = presentModeIter; present_mode = present_mode_iter;
break; break;
} }
if ( presentModeIter == VK_PRESENT_MODE_MAILBOX_KHR ) if ( present_mode_iter == VK_PRESENT_MODE_MAILBOX_KHR )
{ {
presentMode = presentModeIter; present_mode = present_mode_iter;
} }
} }
mem->restoreState( tempAllocStart ); mem->RestoreState( temp_alloc_start );
VkSwapchainCreateInfoKHR const swapchainCreateInfo = { VkSwapchainCreateInfoKHR const swapchain_create_info = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.surface = surface, .surface = surface,
.minImageCount = swapchainImageCount, .minImageCount = swapchain_image_count,
.imageFormat = format.format, .imageFormat = format.format,
.imageColorSpace = format.colorSpace, .imageColorSpace = format.colorSpace,
.imageExtent = swapchainExtent, .imageExtent = swapchain_extent,
.imageArrayLayers = 1, .imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
@ -345,117 +352,119 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = presentMode, .presentMode = present_mode,
.clipped = false, .clipped = false,
.oldSwapchain = nullptr, .oldSwapchain = nullptr,
}; };
VK_CHECK( vkCreateSwapchainKHR( device, &swapchainCreateInfo, nullptr, &swapchain ) ); VK_CHECK( vkCreateSwapchainKHR( device, &swapchain_create_info, nullptr, &swapchain ) );
swapchainImageCount = 0; swapchain_image_count = 0;
vkGetSwapchainImagesKHR( device, swapchain, &swapchainImageCount, nullptr ); vkGetSwapchainImagesKHR( device, swapchain, &swapchain_image_count, nullptr );
swapchainImages = reinterpret_cast<VkImage*>( mem->allocate( sizeof( VkImage ) * swapchainImageCount ) ); swapchain_images = reinterpret_cast<VkImage*>( mem->Allocate( sizeof( VkImage ) * swapchain_image_count ) );
vkGetSwapchainImagesKHR( device, swapchain, &swapchainImageCount, swapchainImages ); vkGetSwapchainImagesKHR( device, swapchain, &swapchain_image_count, swapchain_images );
swapchainViews = reinterpret_cast<VkImageView*>( mem->allocate( sizeof( VkImageView ) * swapchainImageCount ) ); swapchain_views = reinterpret_cast<VkImageView*>( mem->Allocate( sizeof( VkImageView ) * swapchain_image_count ) );
for ( uint32_t i = 0; i != swapchainImageCount; ++i ) for ( uint32_t i = 0; i != swapchain_image_count; ++i )
{ {
VkImageViewCreateInfo const viewCreateInfo = { VkComponentMapping constexpr component_mapping = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, VK_COMPONENT_SWIZZLE_IDENTITY,
.pNext = nullptr, VK_COMPONENT_SWIZZLE_IDENTITY,
.flags = 0, VK_COMPONENT_SWIZZLE_IDENTITY,
.image = swapchainImages[i], VK_COMPONENT_SWIZZLE_IDENTITY,
.viewType = VK_IMAGE_VIEW_TYPE_2D, };
.format = format.format, VkImageSubresourceRange constexpr subresource_range = {
.components = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
VK_COMPONENT_SWIZZLE_IDENTITY, .baseMipLevel = 0,
VK_COMPONENT_SWIZZLE_IDENTITY, .levelCount = 1,
VK_COMPONENT_SWIZZLE_IDENTITY, .baseArrayLayer = 0,
VK_COMPONENT_SWIZZLE_IDENTITY .layerCount = 1,
}, };
.subresourceRange = { VkImageViewCreateInfo const view_create_info = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.baseMipLevel = 0, .pNext = nullptr,
.levelCount = 1, .flags = 0,
.baseArrayLayer = 0, .image = swapchain_images[i],
.layerCount = 1, .viewType = VK_IMAGE_VIEW_TYPE_2D,
} .format = format.format,
.components = component_mapping,
.subresourceRange = subresource_range,
}; };
VK_CHECK( vkCreateImageView( device, &viewCreateInfo, nullptr, &swapchainViews[i] ) ); VK_CHECK( vkCreateImageView( device, &view_create_info, nullptr, &swapchain_views[i] ) );
} }
} }
// Init frames. // Init frames.
Frame* frames = reinterpret_cast<Frame*>( mem->allocate( sizeof( Frame ) * swapchainImageCount ) ); Frame* frames = reinterpret_cast<Frame*>( mem->Allocate( sizeof( Frame ) * swapchain_image_count ) );
for ( uint32_t i = 0; i != swapchainImageCount; ++i ) for ( uint32_t i = 0; i != swapchain_image_count; ++i )
{ {
Frame_Create( frames + i, device, gpuAllocator, directQueueFamilyIndex.value(), swapchainExtent ); frames[i] = Frame::Create( device, allocator, direct_queue_family_index.value(), swapchain_extent );
} }
std::byte* allocation = mem->allocate( sizeof( RenderDevice ), alignof( RenderDevice ) ); std::byte* allocation = mem->Allocate( sizeof( RenderDevice ), alignof( RenderDevice ) );
if ( not allocation ) return nullptr; if ( not allocation ) return nullptr;
RenderDevice* renderDevice = new ( allocation ) RenderDevice{ RenderDevice* render_device = new ( allocation ) RenderDevice{
instance, instance,
surface, surface,
physicalDeviceInUse, physical_device_in_use,
device, device,
gpuAllocator, allocator,
directQueue, direct_queue,
directQueueFamilyIndex.value(), direct_queue_family_index.value(),
swapchainFormat, swapchain_format,
swapchainExtent, swapchain_extent,
swapchain, swapchain,
swapchainImages, swapchain_images,
swapchainViews, swapchain_views,
frames, frames,
swapchainImageCount, swapchain_image_count,
}; };
TextureManager* textureManager = TextureManager_Create( mem, renderDevice, 10000 ); TextureManager* texture_manager = TextureManager::Create( mem, render_device, 10000 );
if ( !textureManager ) if ( !texture_manager )
{ {
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "TextureManager failed to init" ); SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "TextureManager failed to init" );
renderDevice->destroy(); render_device->Destroy();
return nullptr; return nullptr;
} }
renderDevice->textureManager = textureManager; render_device->textureManager = texture_manager;
ASSERT( renderDevice->textureManager ); ASSERT( render_device->textureManager );
BufferManager* bufferManager = BufferManager_Create( mem, renderDevice, 10000 ); BufferManager* buffer_manager = BufferManager::Create( mem, render_device, 10000 );
if ( !bufferManager ) if ( !buffer_manager )
{ {
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "BufferManager failed to init" ); SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "BufferManager failed to init" );
renderDevice->destroy(); render_device->Destroy();
return nullptr; return nullptr;
} }
renderDevice->bufferManager = bufferManager; render_device->bufferManager = buffer_manager;
ASSERT( renderDevice->bufferManager ); ASSERT( render_device->bufferManager );
return renderDevice; return render_device;
} }
inline bool RenderDevice::isInit() const inline bool RenderDevice::IsInit() const
{ {
return instance and device and textureManager; return instance and device and textureManager;
} }
void RenderDevice::destroy() void RenderDevice::Destroy()
{ {
if ( not isInit() ) return; if ( not IsInit() ) return;
Take( bufferManager )->destroy(); Take( bufferManager )->Destroy();
Take( textureManager )->destroy(); Take( textureManager )->Destroy();
for ( Frame& frame : std::span{ Take( frames ), swapchainImageCount } ) for ( size_t i = 0; i < swapchainImageCount; ++i )
{ {
frame.destroy( *this ); frames[i].Destroy( *this );
} }
for ( auto const& view : std::span{ Take( swapchainViews ), swapchainImageCount } ) for ( auto const& view : std::span{ Take( swapchainViews ), swapchainImageCount } )
@ -475,44 +484,45 @@ void RenderDevice::destroy()
volkFinalize(); volkFinalize();
} }
void RenderDevice::waitIdle() const void RenderDevice::WaitIdle() const
{ {
VK_CHECK( vkDeviceWaitIdle( device ) ); VK_CHECK( vkDeviceWaitIdle( device ) );
} }
uint32_t RenderDevice::getNumFrames() const uint32_t RenderDevice::GetNumFrames() const
{ {
return swapchainImageCount; return swapchainImageCount;
} }
RenderDevice::RenderDevice( RenderDevice::RenderDevice(
VkInstance const instance, VkInstance const instance,
VkSurfaceKHR const surface, VkSurfaceKHR const surface,
VkPhysicalDevice const physicalDeviceInUse, VkPhysicalDevice const physical_device_in_use,
VkDevice const device, VkDevice const device,
VmaAllocator const gpuAllocator, VmaAllocator const allocator,
VkQueue const directQueue, VkQueue const direct_queue,
uint32_t const directQueueFamilyIndex, uint32_t const direct_queue_family_index,
VkFormat const swapchainFormat, VkFormat const swapchain_format,
VkExtent2D const swapchainExtent, VkExtent2D const swapchain_extent,
VkSwapchainKHR const swapchain, VkSwapchainKHR const swapchain,
VkImage* swapchainImages, VkImage* swapchain_images,
VkImageView* swapchainViews, VkImageView* swapchain_views,
Frame* frames, Frame* frames,
uint32_t const swapchainImageCount ) uint32_t const swapchain_image_count )
: instance{ instance } : instance{ instance }
, surface{ surface } , surface{ surface }
, physicalDeviceInUse{ physicalDeviceInUse } , physicalDeviceInUse{ physical_device_in_use }
, device{ device } , device{ device }
, gpuAllocator{ gpuAllocator } , gpuAllocator{ allocator }
, directQueue{ directQueue } , directQueue{ direct_queue }
, directQueueFamilyIndex{ directQueueFamilyIndex } , directQueueFamilyIndex{ direct_queue_family_index }
, swapchainFormat{ swapchainFormat } , swapchainFormat{ swapchain_format }
, swapchainExtent{ swapchainExtent } , swapchainExtent{ swapchain_extent }
, swapchain{ swapchain } , swapchain{ swapchain }
, swapchainImages{ swapchainImages } , swapchainImages{ swapchain_images }
, swapchainViews{ swapchainViews } , swapchainViews{ swapchain_views }
, frames{ frames } , frames{ frames }
, swapchainImageCount{ swapchainImageCount } , swapchainImageCount{ swapchain_image_count }
, textureManager{ nullptr } , textureManager{ nullptr }
, bufferManager{ nullptr }
{} {}

View File

@ -5,16 +5,16 @@
#include "VulkanHeader.h" #include "VulkanHeader.h"
namespace Blaze
struct BufferManager; {
struct GlobalMemory; struct GlobalMemory;
struct Frame; struct Frame;
struct BufferManager;
struct TextureManager; struct TextureManager;
/// The Rendering backend abstraction /// The Rendering backend abstraction
/// If this fails to initialize, we crash /// If this fails to initialize, we crash
/// ///
/// TODO: Fail elegantly.
struct RenderDevice struct RenderDevice
{ {
struct CreateInfo struct CreateInfo
@ -45,36 +45,34 @@ struct RenderDevice
TextureManager* textureManager; TextureManager* textureManager;
BufferManager* bufferManager; BufferManager* bufferManager;
[[nodiscard]] bool isInit() const; [[nodiscard]] bool IsInit() const;
void destroy(); void WaitIdle() const;
void waitIdle() const; [[nodiscard]] uint32_t GetNumFrames() const;
[[nodiscard]] uint32_t getNumFrames() const;
static RenderDevice* Create( GlobalMemory* mem, RenderDevice::CreateInfo const& create_info );
void Destroy();
RenderDevice( RenderDevice(
VkInstance instance, VkInstance instance,
VkSurfaceKHR surface, VkSurfaceKHR surface,
VkPhysicalDevice physicalDeviceInUse, VkPhysicalDevice physical_device_in_use,
VkDevice device, VkDevice device,
VmaAllocator gpuAllocator, VmaAllocator allocator,
VkQueue directQueue, VkQueue direct_queue,
uint32_t directQueueFamilyIndex, uint32_t direct_queue_family_index,
VkFormat swapchainFormat, VkFormat swapchain_format,
VkExtent2D swapchainExtent, VkExtent2D swapchain_extent,
VkSwapchainKHR swapchain, VkSwapchainKHR swapchain,
VkImage* swapchainImages, VkImage* swapchain_images,
VkImageView* swapchainViews, VkImageView* swapchain_views,
Frame* frames, Frame* frames,
uint32_t swapchainImageCount ); uint32_t swapchain_image_count );
RenderDevice( RenderDevice const& ) = delete;
RenderDevice& operator=( RenderDevice const& ) = delete;
RenderDevice( RenderDevice&& ) noexcept = delete;
RenderDevice& operator=( RenderDevice&& ) noexcept = delete;
#if defined( DTOR_TEST )
~RenderDevice(); ~RenderDevice();
#endif
}; };
RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo const& createInfo ); } // namespace Blaze

View File

@ -5,32 +5,30 @@
#include "GlobalMemory.h" #include "GlobalMemory.h"
#include "RenderDevice.h" #include "RenderDevice.h"
template struct RID<Texture>; using Blaze::TextureManager;
TextureID TextureManager::createTexture( VkExtent3D const extent, VkSampler const sampler, VkFormat const format ) Blaze::TextureID TextureManager::CreateTexture(
VkExtent3D const extent, VkSampler const sampler, VkFormat const format )
{ {
ASSERT( not m_freeList.empty() ); ASSERT( not m_freeList.Empty() );
Texture* textureSlot = reinterpret_cast<Texture*>( m_freeList.popFront() ); Texture* texture_slot = reinterpret_cast<Texture*>( m_freeList.PopFront() );
++m_count; ++m_count;
ASSERT( m_pRenderDevice );
RenderDevice const& renderDevice = *m_pRenderDevice;
VkImage texture; VkImage texture;
VmaAllocation textureAllocation; VmaAllocation texture_allocation;
VkImageView textureView; VkImageView texture_view;
uint32_t const mipLevels = calculateRequiredMipLevels( extent.width, extent.height, extent.depth ); uint32_t const mip_levels = CalculateRequiredMipLevels( extent.width, extent.height, extent.depth );
VkImageCreateInfo const imageCreateInfo = { VkImageCreateInfo const image_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.imageType = VK_IMAGE_TYPE_2D, .imageType = VK_IMAGE_TYPE_2D,
.format = format, .format = format,
.extent = extent, .extent = extent,
.mipLevels = mipLevels, .mipLevels = mip_levels,
.arrayLayers = 1, .arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL, .tiling = VK_IMAGE_TILING_OPTIMAL,
@ -41,7 +39,7 @@ TextureID TextureManager::createTexture( VkExtent3D const extent, VkSampler cons
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocation_create_info = {
.flags = 0, .flags = 0,
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = 0, .requiredFlags = 0,
@ -53,121 +51,126 @@ TextureID TextureManager::createTexture( VkExtent3D const extent, VkSampler cons
}; };
VK_CHECK( vmaCreateImage( VK_CHECK( vmaCreateImage(
renderDevice.gpuAllocator, &imageCreateInfo, &allocationCreateInfo, &texture, &textureAllocation, nullptr ) ); m_renderDevice->gpuAllocator,
&image_create_info,
&allocation_create_info,
&texture,
&texture_allocation,
nullptr ) );
VkImageSubresourceRange const subresourceRange = { VkImageSubresourceRange const subresource_range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = mipLevels, .levelCount = mip_levels,
.baseArrayLayer = 0, .baseArrayLayer = 0,
.layerCount = 1, .layerCount = 1,
}; };
VkComponentMapping constexpr componentMapping = { VkComponentMapping constexpr component_mapping = {
.r = VK_COMPONENT_SWIZZLE_IDENTITY, .r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY, .g = VK_COMPONENT_SWIZZLE_IDENTITY,
.b = VK_COMPONENT_SWIZZLE_IDENTITY, .b = VK_COMPONENT_SWIZZLE_IDENTITY,
.a = VK_COMPONENT_SWIZZLE_IDENTITY, .a = VK_COMPONENT_SWIZZLE_IDENTITY,
}; };
VkImageViewCreateInfo const imageViewCreateInfo = { VkImageViewCreateInfo const image_view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.image = texture, .image = texture,
.viewType = VK_IMAGE_VIEW_TYPE_2D, .viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = imageCreateInfo.format, .format = image_create_info.format,
.components = componentMapping, .components = component_mapping,
.subresourceRange = subresourceRange, .subresourceRange = subresource_range,
}; };
VK_CHECK( vkCreateImageView( renderDevice.device, &imageViewCreateInfo, nullptr, &textureView ) ); VK_CHECK( vkCreateImageView( m_renderDevice->device, &image_view_create_info, nullptr, &texture_view ) );
// NOTE: textureSlot preserves index between uses. // NOTE: textureSlot preserves index between uses.
uint32_t index = textureSlot->index; uint32_t index = texture_slot->index;
new ( textureSlot ) Texture{ new ( texture_slot ) Texture{
.image = texture, .image = texture,
.allocation = textureAllocation, .allocation = texture_allocation,
.view = textureView, .view = texture_view,
.extent = extent, .extent = extent,
.format = format, .format = format,
.index = index, .index = index,
}; };
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
// TODO: Batch all writes. // TODO: Batch all writes.
VkDescriptorImageInfo const descriptorImageInfo = { VkDescriptorImageInfo const descriptor_image_info = {
.sampler = sampler, .sampler = sampler,
.imageView = textureView, .imageView = texture_view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
}; };
VkWriteDescriptorSet const descriptorWrite = { VkWriteDescriptorSet const descriptor_write = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr, .pNext = nullptr,
.dstSet = m_descriptorSet, .dstSet = m_descriptorSet,
.dstBinding = 0, .dstBinding = 0,
.dstArrayElement = innerIndex, .dstArrayElement = inner_index,
.descriptorCount = 1, .descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &descriptorImageInfo, .pImageInfo = &descriptor_image_info,
.pBufferInfo = nullptr, .pBufferInfo = nullptr,
.pTexelBufferView = nullptr, .pTexelBufferView = nullptr,
}; };
vkUpdateDescriptorSets( renderDevice.device, 1, &descriptorWrite, 0, nullptr ); vkUpdateDescriptorSets( m_renderDevice->device, 1, &descriptor_write, 0, nullptr );
// NOTE: Memory hackery to create TextureID; // NOTE: Memory hackery to create TextureID;
return *reinterpret_cast<TextureID*>( &index ); return *reinterpret_cast<TextureID*>( &index );
} }
bool TextureManager::isValidID( TextureID const& rid ) const bool TextureManager::IsValidID( TextureID const& rid ) const
{ {
uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid ); uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid );
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
if ( innerIndex > m_capacity ) return false; if ( inner_index > m_capacity ) return false;
return m_aTextures[innerIndex].index == index; return m_textures[inner_index].index == index;
} }
void TextureManager::freeTexture( TextureID* rid ) void TextureManager::FreeTexture( TextureID* rid )
{ {
if ( not isValidID( *rid ) ) return; if ( not IsValidID( *rid ) ) return;
Texture& texture = fetchTextureUnchecked( *rid ); Texture& texture = FetchTextureUnchecked( *rid );
destroyTexture( texture ); DestroyTexture( texture );
*rid = {}; *rid = {};
} }
std::optional<VkImage> TextureManager::fetchImage( TextureID const& rid ) std::optional<VkImage> TextureManager::FetchImage( TextureID const& rid )
{ {
if ( not isValidID( rid ) ) return std::nullopt; if ( not IsValidID( rid ) ) return std::nullopt;
return fetchTextureUnchecked( rid ).image; return FetchTextureUnchecked( rid ).image;
} }
std::optional<VkImageView> TextureManager::fetchImageView( TextureID const& rid ) std::optional<VkImageView> TextureManager::FetchImageView( TextureID const& rid )
{ {
if ( not isValidID( rid ) ) return std::nullopt; if ( not IsValidID( rid ) ) return std::nullopt;
return fetchTextureUnchecked( rid ).view; return FetchTextureUnchecked( rid ).view;
} }
VkDescriptorSetLayout const& TextureManager::descriptorLayout() const VkDescriptorSetLayout const& TextureManager::DescriptorLayout() const
{ {
return m_descriptorSetLayout; return m_descriptorSetLayout;
} }
VkDescriptorSet const& TextureManager::descriptorSet() const VkDescriptorSet const& TextureManager::DescriptorSet() const
{ {
return m_descriptorSet; return m_descriptorSet;
} }
void TextureManager::destroy() void TextureManager::Destroy()
{ {
#if defined( _DEBUG ) #if defined( _DEBUG )
if ( m_count > 0 ) if ( m_count > 0 )
@ -176,106 +179,102 @@ void TextureManager::destroy()
} }
#endif #endif
ASSERT( m_pRenderDevice ); ASSERT( m_renderDevice );
RenderDevice const& renderDevice = *m_pRenderDevice;
while ( not m_freeList.empty() ) while ( not m_freeList.Empty() )
{ {
Texture* tex = reinterpret_cast<Texture*>( m_freeList.popFront() ); Texture* tex = reinterpret_cast<Texture*>( m_freeList.PopFront() );
memset( tex, 0, sizeof *tex ); memset( tex, 0, sizeof *tex );
} }
for ( Texture& tex : std::span{ m_aTextures, m_count } ) for ( Texture& tex : std::span{ m_textures, m_count } )
{ {
destroyTexture( tex ); DestroyTexture( tex );
} }
m_descriptorSet = nullptr; m_descriptorSet = nullptr;
vkDestroyDescriptorPool( renderDevice.device, Take( m_descriptorPool ), nullptr ); vkDestroyDescriptorPool( m_renderDevice->device, Take( m_descriptorPool ), nullptr );
vkDestroyDescriptorSetLayout( renderDevice.device, Take( m_descriptorSetLayout ), nullptr ); vkDestroyDescriptorSetLayout( m_renderDevice->device, Take( m_descriptorSetLayout ), nullptr );
} }
TextureManager::~TextureManager() TextureManager::~TextureManager()
{ {
ASSERT( not m_aTextures ); ASSERT( not m_textures );
} }
void TextureManager::destroyTexture( Texture& tex ) void TextureManager::DestroyTexture( Texture& tex )
{ {
if ( not tex.image ) return; if ( not tex.image ) return;
ASSERT( m_pRenderDevice ); ASSERT( m_renderDevice );
uint32_t const index = tex.index; uint32_t const index = tex.index;
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
uint32_t const generation = ( index & GENERATION_MASK ) >> GENERATION_OFFSET; uint32_t const generation = ( index & kGenerationMask ) >> kGenerationOffset;
RenderDevice const& renderDevice = *m_pRenderDevice; vkDestroyImageView( m_renderDevice->device, Take( tex.view ), nullptr );
vkDestroyImageView( renderDevice.device, Take( tex.view ), nullptr ); vmaDestroyImage( m_renderDevice->gpuAllocator, Take( tex.image ), Take( tex.allocation ) );
vmaDestroyImage( renderDevice.gpuAllocator, Take( tex.image ), Take( tex.allocation ) );
tex.extent = {}; tex.extent = {};
tex.format = VK_FORMAT_UNDEFINED; tex.format = VK_FORMAT_UNDEFINED;
tex.index = innerIndex | ( generation + 1 ) << GENERATION_OFFSET; tex.index = inner_index | ( generation + 1 ) << kGenerationOffset;
// NOTE: DO NOT EDIT INNER INDEX. // NOTE: DO NOT EDIT INNER INDEX.
ASSERT( innerIndex == ( tex.index & INDEX_MASK ) and "Index should not be modified" ); ASSERT( inner_index == ( tex.index & kIndexMask ) and "Index should not be modified" );
ASSERT( tex.index > index and "Generation should increase." ); ASSERT( tex.index > index and "Generation should increase." );
m_freeList.pushBack( reinterpret_cast<FreeList::Node*>( &tex ) ); m_freeList.PushBack( reinterpret_cast<Util::FreeList::Node*>( &tex ) );
--m_count; --m_count;
} }
uint32_t TextureManager::calculateRequiredMipLevels( uint32_t const w, uint32_t const h, uint32_t const d ) uint32_t TextureManager::CalculateRequiredMipLevels( uint32_t const w, uint32_t const h, uint32_t const d )
{ {
uint32_t const maxDim = std::max( std::max( w, h ), d ); uint32_t const max_dim = std::max( std::max( w, h ), d );
return 1 + static_cast<uint32_t>( floorf( log2f( static_cast<float>( maxDim ) ) ) ); return 1 + static_cast<uint32_t>( floorf( log2f( static_cast<float>( max_dim ) ) ) );
} }
Texture& TextureManager::fetchTextureUnchecked( TextureID const& rid ) Blaze::Texture& TextureManager::FetchTextureUnchecked( TextureID const& rid )
{ {
uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid ); uint32_t const index = *reinterpret_cast<uint32_t const*>( &rid );
uint32_t const innerIndex = index & INDEX_MASK; uint32_t const inner_index = index & kIndexMask;
return m_aTextures[innerIndex]; return m_textures[inner_index];
} }
TextureManager::TextureManager( TextureManager::TextureManager(
RenderDevice* pRenderDevice, Blaze::RenderDevice* render_device,
Texture* aTextures, Texture* textures,
uint32_t const capacity, uint32_t const capacity,
VkDescriptorSetLayout const setLayout, VkDescriptorSetLayout const set_layout,
VkDescriptorPool const pool, VkDescriptorPool const pool,
VkDescriptorSet const descriptorSet ) VkDescriptorSet const descriptor_set )
: m_pRenderDevice{ pRenderDevice } : m_renderDevice{ render_device }
, m_aTextures{ aTextures } , m_textures{ textures }
, m_count{ 0 } , m_count{ 0 }
, m_capacity{ capacity } , m_capacity{ capacity }
, m_descriptorSetLayout{ setLayout } , m_descriptorSetLayout{ set_layout }
, m_descriptorPool{ pool } , m_descriptorPool{ pool }
, m_descriptorSet{ descriptorSet } , m_descriptorSet{ descriptor_set }
{ {
uint32_t i = 0; uint32_t i = 0;
for ( Texture& tex : std::span{ m_aTextures, m_capacity } ) for ( Texture& tex : std::span{ m_textures, m_capacity } )
{ {
// Default Generation is 1 // Default Generation is 1
tex.index = i++ | ( 1 << GENERATION_OFFSET ); tex.index = i++ | ( 1 << kGenerationOffset );
m_freeList.pushFront( reinterpret_cast<FreeList::Node*>( &tex ) ); m_freeList.PushFront( reinterpret_cast<Util::FreeList::Node*>( &tex ) );
} }
} }
TextureManager* TextureManager_Create( GlobalMemory* mem, RenderDevice* renderDevice, uint32_t const maxCount ) TextureManager* TextureManager::Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t const max_count )
{ {
Texture* textures = reinterpret_cast<Texture*>( mem->allocate( maxCount * sizeof( Texture ), alignof( Texture ) ) ); Texture* textures = reinterpret_cast<Texture*>( mem->Allocate( max_count * sizeof( Texture ), alignof( Texture ) ) );
if ( not textures ) return nullptr; if ( not textures ) return nullptr;
VkDescriptorSetLayoutBinding const descriptorSetLayoutBinding{ VkDescriptorSetLayoutBinding const descriptor_set_layout_binding{
.binding = 0, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = maxCount, .descriptorCount = max_count,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = nullptr, .pImmutableSamplers = nullptr,
}; };
@ -284,56 +283,56 @@ TextureManager* TextureManager_Create( GlobalMemory* mem, RenderDevice* renderDe
VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT |
VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT; VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT;
VkDescriptorSetLayoutBindingFlagsCreateInfo const bindlessBinding = { VkDescriptorSetLayoutBindingFlagsCreateInfo const bindless_binding = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.bindingCount = 1, .bindingCount = 1,
.pBindingFlags = &flags, .pBindingFlags = &flags,
}; };
VkDescriptorSetLayoutCreateInfo const descriptorSetLayoutCreateInfo = { VkDescriptorSetLayoutCreateInfo const descriptor_set_layout_create_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &bindlessBinding, .pNext = &bindless_binding,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.bindingCount = 1, .bindingCount = 1,
.pBindings = &descriptorSetLayoutBinding, .pBindings = &descriptor_set_layout_binding,
}; };
VkDescriptorSetLayout descriptorSetLayout; VkDescriptorSetLayout descriptor_set_layout;
VK_CHECK( vkCreateDescriptorSetLayout( VK_CHECK( vkCreateDescriptorSetLayout(
renderDevice->device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout ) ); render_device->device, &descriptor_set_layout_create_info, nullptr, &descriptor_set_layout ) );
VkDescriptorPoolSize const poolSize = { VkDescriptorPoolSize const pool_size = {
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = maxCount, .descriptorCount = max_count,
}; };
VkDescriptorPoolCreateInfo const descriptorPoolCreateInfo = { VkDescriptorPoolCreateInfo const descriptor_pool_create_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
.maxSets = 1, .maxSets = 1,
.poolSizeCount = 1, .poolSizeCount = 1,
.pPoolSizes = &poolSize, .pPoolSizes = &pool_size,
}; };
VkDescriptorPool descriptorPool; VkDescriptorPool descriptor_pool;
VK_CHECK( vkCreateDescriptorPool( renderDevice->device, &descriptorPoolCreateInfo, nullptr, &descriptorPool ) ); VK_CHECK( vkCreateDescriptorPool( render_device->device, &descriptor_pool_create_info, nullptr, &descriptor_pool ) );
VkDescriptorSetAllocateInfo const descriptorSetAllocateInfo = { VkDescriptorSetAllocateInfo const descriptor_set_allocate_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.descriptorPool = descriptorPool, .descriptorPool = descriptor_pool,
.descriptorSetCount = 1, .descriptorSetCount = 1,
.pSetLayouts = &descriptorSetLayout, .pSetLayouts = &descriptor_set_layout,
}; };
VkDescriptorSet descriptorSet; VkDescriptorSet descriptor_set;
VK_CHECK( vkAllocateDescriptorSets( renderDevice->device, &descriptorSetAllocateInfo, &descriptorSet ) ); VK_CHECK( vkAllocateDescriptorSets( render_device->device, &descriptor_set_allocate_info, &descriptor_set ) );
std::byte* allocation = mem->allocate( sizeof( TextureManager ), alignof( TextureManager ) ); std::byte* allocation = mem->Allocate( sizeof( TextureManager ), alignof( TextureManager ) );
if ( not allocation ) return nullptr; if ( not allocation ) return nullptr;
return new ( allocation ) return new ( allocation )
TextureManager{ renderDevice, textures, maxCount, descriptorSetLayout, descriptorPool, descriptorSet }; TextureManager{ render_device, textures, max_count, descriptor_set_layout, descriptor_pool, descriptor_set };
} }

View File

@ -9,6 +9,8 @@
#include "RenderDevice.h" #include "RenderDevice.h"
#include "VulkanHeader.h" #include "VulkanHeader.h"
namespace Blaze
{
struct GlobalMemory; struct GlobalMemory;
struct RenderDevice; struct RenderDevice;
@ -22,10 +24,10 @@ struct Texture
uint32_t index; uint32_t index;
}; };
static_assert( sizeof( Texture ) > sizeof( FreeList::Node ) and "Texture is used intrusively by FreeList" ); static_assert( sizeof( Texture ) > sizeof( Util::FreeList::Node ) and "Texture is used intrusively by FreeList" );
static_assert( static_assert(
offsetof( Texture, index ) >= sizeof( FreeList::Node ) and offsetof( Texture, index ) >= sizeof( Util::FreeList::Node ) and
"Index should not be overwritten even in invalid state" ); "Index should not be overwritten even in invalid state" );
extern template struct RID<Texture>; extern template struct RID<Texture>;
using TextureID = RID<Texture>; using TextureID = RID<Texture>;
@ -33,61 +35,63 @@ using TextureID = RID<Texture>;
struct TextureManager struct TextureManager
{ {
private: private:
constexpr static uint32_t INDEX_MASK = 0x0007FFFF; constexpr static uint32_t kIndexMask = 0x0007FFFF;
constexpr static uint32_t GENERATION_MASK = ~INDEX_MASK; constexpr static uint32_t kGenerationMask = ~kIndexMask;
constexpr static uint32_t GENERATION_OFFSET = 19; constexpr static uint32_t kGenerationOffset = 19;
static_assert( static_assert(
( ( GENERATION_MASK >> GENERATION_OFFSET & 0x1 ) == 0x1 ) and ( ( kGenerationMask >> kGenerationOffset & 0x1 ) == 0x1 ) and
( ( GENERATION_MASK >> ( GENERATION_OFFSET - 1 ) & 0x1 ) != 0x1 ) and "Checks boundary" ); ( ( kGenerationMask >> ( kGenerationOffset - 1 ) & 0x1 ) != 0x1 ) and "Checks boundary" );
RenderDevice* m_pRenderDevice; RenderDevice* m_renderDevice;
// Texture Manager // Texture Manager
Texture* m_aTextures; Texture* m_textures;
uint32_t m_count; uint32_t m_count;
uint32_t m_capacity; uint32_t m_capacity;
FreeList m_freeList; Util::FreeList m_freeList;
// Bindless Descriptor Info // Bindless Descriptor Info
VkDescriptorSetLayout m_descriptorSetLayout; VkDescriptorSetLayout m_descriptorSetLayout;
VkDescriptorPool m_descriptorPool; VkDescriptorPool m_descriptorPool;
VkDescriptorSet m_descriptorSet; VkDescriptorSet m_descriptorSet;
void destroyTexture( Texture& tex ); void DestroyTexture( Texture& tex );
Texture& fetchTextureUnchecked( TextureID const& rid ); Texture& FetchTextureUnchecked( TextureID const& rid );
public: public:
static uint32_t calculateRequiredMipLevels( uint32_t w, uint32_t h, uint32_t d ); static uint32_t CalculateRequiredMipLevels( uint32_t w, uint32_t h, uint32_t d );
[[nodiscard]] bool isValidID( TextureID const& rid ) const; [[nodiscard]] bool IsValidID( TextureID const& rid ) const;
// [[nodiscard]] std::optional<TextureID> createTexture( VkExtent3D extent ); // [[nodiscard]] std::optional<TextureID> createTexture( VkExtent3D extent );
void freeTexture( TextureID* rid ); void FreeTexture( TextureID* rid );
DEPRECATE_JULY_2025 DEPRECATE_JULY_2025
[[nodiscard]] TextureID createTexture( [[nodiscard]] TextureID CreateTexture(
VkExtent3D extent, VkSampler sampler, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB ); VkExtent3D extent, VkSampler sampler, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB );
DEPRECATE_JULY_2025 DEPRECATE_JULY_2025
std::optional<VkImage> fetchImage( TextureID const& rid ); std::optional<VkImage> FetchImage( TextureID const& rid );
DEPRECATE_JULY_2025 DEPRECATE_JULY_2025
std::optional<VkImageView> fetchImageView( TextureID const& rid ); std::optional<VkImageView> FetchImageView( TextureID const& rid );
[[nodiscard]] VkDescriptorSetLayout const& descriptorLayout() const; [[nodiscard]] VkDescriptorSetLayout const& DescriptorLayout() const;
[[nodiscard]] VkDescriptorSet const& descriptorSet() const; [[nodiscard]] VkDescriptorSet const& DescriptorSet() const;
// //
TextureManager( TextureManager(
RenderDevice* pRenderDevice, RenderDevice* render_device,
Texture* aTextures, Texture* textures,
uint32_t capacity, uint32_t capacity,
VkDescriptorSetLayout setLayout, VkDescriptorSetLayout set_layout,
VkDescriptorPool pool, VkDescriptorPool pool,
VkDescriptorSet descriptorSet ); VkDescriptorSet descriptor_set );
void destroy();
static TextureManager* Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t max_count );
void Destroy();
TextureManager( TextureManager const& other ) = delete; TextureManager( TextureManager const& other ) = delete;
TextureManager( TextureManager&& other ) noexcept = delete; TextureManager( TextureManager&& other ) noexcept = delete;
@ -96,4 +100,4 @@ public:
~TextureManager(); ~TextureManager();
}; };
TextureManager* TextureManager_Create( GlobalMemory* mem, RenderDevice* renderDevice, uint32_t maxCount ); } // namespace Blaze