Reformatted + Frame_Create.

This commit is contained in:
Anish Bhobe 2025-06-14 00:29:22 +02:00
parent fd9ceae67d
commit d09f725803
17 changed files with 754 additions and 669 deletions

72
.clang-format Normal file
View File

@ -0,0 +1,72 @@
---
BasedOnStyle: Microsoft
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AlignFunctionPointers: true
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: true
AlignCompound: true
AlignFunctionPointers: true
PadOperators: true
AlignOperands: true
AlignTrailingComments:
OverEmptyLines: 2
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: true
BeforeWhile: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakConstructorInitializers: BeforeComma
ConstructorInitializerIndentWidth: 2
Cpp11BracedListStyle: false
IncludeCategories:
- Regex: ^<.*
Priority: 1
- Regex: ^".*
Priority: 2
- Regex: .*
Priority: 3
IncludeIsMainRegex: ([-_](test|unittest))?$
IndentCaseLabels: true
IndentWidth: 2
InsertNewlineAtEOF: true
MaxEmptyLinesToKeep: 2
PointerAlignment: Left
SpaceBeforeParensOptions:
AfterOverloadedOperator: true
SpacesInAngles: false
SpacesInParens: Custom
SpacesInParensOptions:
InConditionalStatements: true
InCStyleCasts: true
Other: true
TabWidth: 2
Language: Cpp
ConstructorInitializerAllOnOneLineOrOnePerLine: true
SpaceInEmptyParentheses: false
SpacesInConditionalStatement: true
SpacesInCStyleCastParentheses: false
AlignArrayOfStructures: Right

View File

@ -24,39 +24,34 @@ void AppState::destroy()
} }
AppState::AppState( SDL_Window* window, RenderDevice* renderDevice, MiscData* miscData ) AppState::AppState( SDL_Window* window, RenderDevice* renderDevice, MiscData* miscData )
: window{ window } : window{ window }, renderDevice{ renderDevice }, miscData{ miscData }, sprintfBuffer{ 0 }
, renderDevice{ renderDevice } {}
, miscData{ miscData } {}
AppState* CreateAppState( GlobalMemory* memory, uint32_t const width, uint32_t const height ) AppState* AppState_Create( GlobalMemory* memory, uint32_t const width, uint32_t const height )
{ {
SDL_Window* window = SDL_CreateWindow( SDL_Window* window =
"Blaze Test", SDL_CreateWindow( "Blaze Test", static_cast<int>( width ), static_cast<int>( height ), SDL_WINDOW_VULKAN );
static_cast<int>(width),
static_cast<int>(height),
SDL_WINDOW_VULKAN );
if ( !window ) if ( !window )
{ {
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "%s", SDL_GetError() ); SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "%s", SDL_GetError() );
return nullptr; return nullptr;
} }
auto state = memory->getState(); RenderDevice* renderDevice = RenderDevice_Create( memory, { .window = window } );
RenderDevice* renderDevice = CreateRenderDevice( memory, { .window = window } );
if ( !renderDevice->isInit() ) if ( !renderDevice->isInit() )
{ {
SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "RenderDevice failed to init" ); SDL_LogError( SDL_LOG_CATEGORY_APPLICATION, "RenderDevice failed to init" );
SDL_DestroyWindow( window );
return nullptr; return nullptr;
} }
(void)state;
auto* miscDataAllocation = memory->allocate( sizeof( MiscData ) ); auto* miscDataAllocation = memory->allocate( sizeof( MiscData ) );
MiscData* miscData = new( miscDataAllocation ) MiscData{}; MiscData* miscData = new ( miscDataAllocation ) MiscData{};
miscData->init( *renderDevice ); miscData->init( *renderDevice );
auto* allocation = memory->allocate( sizeof( AppState ) ); auto* allocation = memory->allocate( sizeof( AppState ) );
AppState* appState = new( allocation ) AppState{ window, renderDevice, miscData }; AppState* appState = new ( allocation ) AppState{ window, renderDevice, miscData };
return appState; return appState;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <memory> #include <cstdint>
struct SDL_Window; struct SDL_Window;
@ -10,18 +10,18 @@ struct MiscData;
struct AppState struct AppState
{ {
SDL_Window* window; SDL_Window* window;
RenderDevice* renderDevice; RenderDevice* renderDevice;
MiscData* miscData; MiscData* miscData;
char sprintfBuffer[256];
[[nodiscard]] [[nodiscard]] bool isInit() const;
bool isInit() const; void destroy();
void destroy();
AppState( SDL_Window* window, RenderDevice* renderDevice, MiscData* miscData ); AppState( SDL_Window* window, RenderDevice* renderDevice, MiscData* miscData );
AppState( AppState const& other ) = delete; AppState( AppState const& other ) = delete;
AppState( AppState&& other ) noexcept = delete; AppState( AppState&& other ) noexcept = delete;
AppState& operator=( AppState const& other ) = delete; AppState& operator=( AppState const& other ) = delete;
AppState& operator=( AppState&& other ) noexcept = delete; AppState& operator=( AppState&& other ) noexcept = delete;
@ -29,4 +29,4 @@ struct AppState
~AppState(); ~AppState();
}; };
AppState* CreateAppState( GlobalMemory* memory, uint32_t const width, uint32_t const height ); AppState* AppState_Create( GlobalMemory* memory, uint32_t width, uint32_t height );

195
Blaze.cpp
View File

@ -9,118 +9,96 @@
#include <volk.h> #include <volk.h>
#define SDL_MAIN_USE_CALLBACKS 1 #define SDL_MAIN_USE_CALLBACKS 1
#include <memory>
#include <glm/ext/matrix_transform.hpp>
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_filesystem.h> #include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_vulkan.h> #include <SDL3/SDL_vulkan.h>
#include <glm/ext/matrix_transform.hpp>
#include <memory>
#include "AppState.h" #include "AppState.h"
#include "Frame.h" #include "Frame.h"
#include "GlobalMemory.h" #include "GlobalMemory.h"
#include "MacroUtils.h" #include "MacroUtils.h"
#include "MathUtil.h" #include "MathUtil.h"
#include "RenderDevice.h"
#include "MiscData.h" #include "MiscData.h"
#include "RenderDevice.h"
constexpr uint32_t WIDTH = 1280; constexpr uint32_t WIDTH = 1280;
constexpr uint32_t HEIGHT = 720; constexpr uint32_t HEIGHT = 720;
constexpr uint32_t NUM_FRAMES = 3; constexpr uint32_t NUM_FRAMES = 3;
using Byte = uint8_t;
constexpr size_t operator ""_KiB( size_t const value )
{
return value * 1024;
}
constexpr size_t operator ""_MiB( size_t const value )
{
return value * 1024_KiB;
}
constexpr size_t operator ""_GiB( size_t const value )
{
return value * 1024_MiB;
}
namespace Blaze::Global namespace Blaze::Global
{ {
GlobalMemory g_Memory; GlobalMemory g_Memory;
} }
SDL_AppResult SDL_AppInit( void** pAppState, 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 ); Blaze::Global::g_Memory.init( 128_MiB );
*pAppState = CreateAppState( &Blaze::Global::g_Memory, WIDTH, HEIGHT ); *appstate = AppState_Create( &Blaze::Global::g_Memory, WIDTH, HEIGHT );
if ( !*pAppState ) return SDL_APP_FAILURE; if ( !*appstate ) return SDL_APP_FAILURE;
AppState& appState = *static_cast<AppState*>(*pAppState);
if ( !appState.isInit() )
{
return SDL_APP_FAILURE;
}
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
char g_buf[1000];
SDL_AppResult SDL_AppIterate( void* appstate ) SDL_AppResult SDL_AppIterate( void* appstate )
{ {
AppState& appState = *static_cast<AppState*>(appstate); AppState& appState = *static_cast<AppState*>( appstate );
RenderDevice& renderDevice = *appState.renderDevice; RenderDevice& renderDevice = *appState.renderDevice;
MiscData& misc = *appState.miscData; MiscData& misc = *appState.miscData;
Frame& currentFrame = renderDevice.frames[renderDevice.frameIndex]; Frame& currentFrame = renderDevice.frames[renderDevice.frameIndex];
VK_CHECK( VK_CHECK( vkWaitForFences(
vkWaitForFences(renderDevice.device, renderDevice.device, 1, &currentFrame.frameReadyToReuse, VK_TRUE, std::numeric_limits<uint32_t>::max() ) );
1,
&currentFrame.frameReadyToReuse,
VK_TRUE,
std::numeric_limits<uint32_t>::max()) );
// All resources of frame 'frameIndex' are free. // All resources of frame 'frameIndex' are free.
// time calc
uint64_t const previousCounter = misc.previousCounter; uint64_t const previousCounter = misc.previousCounter;
uint64_t const currentCounter = SDL_GetPerformanceCounter(); uint64_t const currentCounter = SDL_GetPerformanceCounter();
uint64_t const deltaCount = currentCounter - previousCounter; uint64_t const deltaCount = currentCounter - previousCounter;
uint64_t const perfFreq = SDL_GetPerformanceFrequency(); uint64_t const perfFreq = SDL_GetPerformanceFrequency();
double const deltaTime = static_cast<double>(deltaCount) / static_cast<double>(perfFreq); double const deltaTime = static_cast<double>( deltaCount ) / static_cast<double>( perfFreq );
misc.previousCounter = currentCounter; misc.previousCounter = currentCounter;
double deltaTimeMs = deltaTime * 1000.0; {
double fps = 1.0 / deltaTime; double deltaTimeMs = deltaTime * 1000.0;
auto _ = sprintf_s<1000>( g_buf, "%.2f fps %.5fms %llu -> %llu", fps, deltaTimeMs, previousCounter, currentCounter ); double fps = 1.0 / deltaTime;
SDL_SetWindowTitle( appState.window, g_buf ); ( void )sprintf_s<256>(
appState.sprintfBuffer, "%.2f fps %.5fms %llu -> %llu", fps, deltaTimeMs, previousCounter, currentCounter );
SDL_SetWindowTitle( appState.window, appState.sprintfBuffer );
}
misc.cameraData.modelMatrix = glm::rotate( misc.cameraData.modelMatrix = glm::rotate(
misc.cameraData.modelMatrix, misc.cameraData.modelMatrix,
glm::radians( 60.0f ) * static_cast<float>(deltaTime), glm::radians( 60.0f ) * static_cast<float>( deltaTime ),
glm::vec3{ 0.0f, 1.0f, 0.0f } ); glm::vec3{ 0.0f, 1.0f, 0.0f } );
memcpy( misc.cameraUniformBufferPtr, &misc.cameraData, sizeof misc.cameraData ); memcpy( misc.cameraUniformBufferPtr, &misc.cameraData, sizeof misc.cameraData );
uint32_t currentImageIndex; uint32_t currentImageIndex;
VK_CHECK( VK_CHECK( vkAcquireNextImageKHR(
vkAcquireNextImageKHR(renderDevice.device, renderDevice.swapchain, std::numeric_limits<uint32_t>::max(), renderDevice.device,
currentFrame.imageAcquiredSemaphore, nullptr, &currentImageIndex) ); renderDevice.swapchain,
std::numeric_limits<uint32_t>::max(),
currentFrame.imageAcquiredSemaphore,
nullptr,
&currentImageIndex ) );
VK_CHECK( vkResetFences(renderDevice.device, 1, &currentFrame.frameReadyToReuse) ); VK_CHECK( vkResetFences( renderDevice.device, 1, &currentFrame.frameReadyToReuse ) );
VK_CHECK( vkResetCommandPool(renderDevice.device, currentFrame.commandPool, 0) ); VK_CHECK( vkResetCommandPool( renderDevice.device, currentFrame.commandPool, 0 ) );
misc.acquireToRenderBarrier.image = renderDevice.swapchainImages[currentImageIndex]; misc.acquireToRenderBarrier.image = renderDevice.swapchainImages[currentImageIndex];
misc.renderToPresentBarrier.image = renderDevice.swapchainImages[currentImageIndex]; misc.renderToPresentBarrier.image = renderDevice.swapchainImages[currentImageIndex];
VkCommandBuffer cmd = currentFrame.commandBuffer; VkCommandBuffer cmd = currentFrame.commandBuffer;
VkCommandBufferBeginInfo constexpr beginInfo = { VkCommandBufferBeginInfo constexpr beginInfo = {
.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,
}; };
@ -128,42 +106,42 @@ SDL_AppResult SDL_AppIterate( void* appstate )
.float32 = { 0.0f, 0.0f, 0.0f, 1.0f }, .float32 = { 0.0f, 0.0f, 0.0f, 1.0f },
}; };
VK_CHECK( vkBeginCommandBuffer(cmd, &beginInfo) ); VK_CHECK( vkBeginCommandBuffer( cmd, &beginInfo ) );
{ {
VkRenderingAttachmentInfo const attachmentInfo = { VkRenderingAttachmentInfo const attachmentInfo = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.pNext = nullptr, .pNext = nullptr,
.imageView = renderDevice.swapchainViews[currentImageIndex], .imageView = renderDevice.swapchainViews[currentImageIndex],
.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 = BLACK_CLEAR },
}; };
VkRenderingInfo renderingInfo = { VkRenderingInfo renderingInfo = {
.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 = renderDevice.swapchainExtent },
.layerCount = 1, .layerCount = 1,
.viewMask = 0, .viewMask = 0,
.colorAttachmentCount = 1, .colorAttachmentCount = 1,
.pColorAttachments = &attachmentInfo, .pColorAttachments = &attachmentInfo,
.pDepthAttachment = nullptr, .pDepthAttachment = nullptr,
.pStencilAttachment = nullptr, .pStencilAttachment = nullptr,
}; };
vkCmdPipelineBarrier2( cmd, &misc.acquireToRenderDependency ); vkCmdPipelineBarrier2( cmd, &misc.acquireToRenderDependency );
vkCmdBeginRendering( cmd, &renderingInfo ); vkCmdBeginRendering( cmd, &renderingInfo );
{ {
VkViewport viewport = { VkViewport viewport = {
.x = 0, .x = 0,
.y = static_cast<float>(renderDevice.swapchainExtent.height), .y = static_cast<float>( renderDevice.swapchainExtent.height ),
.width = static_cast<float>(renderDevice.swapchainExtent.width), .width = static_cast<float>( renderDevice.swapchainExtent.width ),
.height = -static_cast<float>(renderDevice.swapchainExtent.height), .height = -static_cast<float>( renderDevice.swapchainExtent.height ),
.minDepth = 0.0f, .minDepth = 0.0f,
.maxDepth = 1.0f, .maxDepth = 1.0f,
}; };
@ -179,49 +157,42 @@ SDL_AppResult SDL_AppIterate( void* appstate )
VkDeviceSize constexpr offset = 0; VkDeviceSize constexpr offset = 0;
vkCmdBindVertexBuffers( cmd, 0, 1, &misc.vertexBuffer, &offset ); vkCmdBindVertexBuffers( cmd, 0, 1, &misc.vertexBuffer, &offset );
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
cmd, cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.pipelineLayout, 0, 1, &misc.descriptorSet, 0, nullptr );
VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdDraw( cmd, static_cast<uint32_t>( misc.vertices.size() ), 1, 0, 0 );
misc.pipelineLayout,
0,
1,
&misc.descriptorSet,
0,
nullptr );
vkCmdDraw( cmd, static_cast<uint32_t>(misc.vertices.size()), 1, 0, 0 );
} }
vkCmdEndRendering( cmd ); vkCmdEndRendering( cmd );
vkCmdPipelineBarrier2( cmd, &misc.renderToPresentDependency ); vkCmdPipelineBarrier2( cmd, &misc.renderToPresentDependency );
} }
VK_CHECK( vkEndCommandBuffer(cmd) ); VK_CHECK( vkEndCommandBuffer( cmd ) );
VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo const submitInfo = { VkSubmitInfo const submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr, .pNext = nullptr,
.waitSemaphoreCount = 1, .waitSemaphoreCount = 1,
.pWaitSemaphores = &currentFrame.imageAcquiredSemaphore, .pWaitSemaphores = &currentFrame.imageAcquiredSemaphore,
.pWaitDstStageMask = &stageMask, .pWaitDstStageMask = &stageMask,
.commandBufferCount = 1, .commandBufferCount = 1,
.pCommandBuffers = &cmd, .pCommandBuffers = &cmd,
.signalSemaphoreCount = 1, .signalSemaphoreCount = 1,
.pSignalSemaphores = &currentFrame.renderFinishedSemaphore, .pSignalSemaphores = &currentFrame.renderFinishedSemaphore,
}; };
VK_CHECK( vkQueueSubmit(renderDevice.directQueue, 1, &submitInfo, currentFrame.frameReadyToReuse) ); VK_CHECK( vkQueueSubmit( renderDevice.directQueue, 1, &submitInfo, currentFrame.frameReadyToReuse ) );
VkPresentInfoKHR const presentInfo = { VkPresentInfoKHR const presentInfo = {
.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 = &currentFrame.renderFinishedSemaphore,
.swapchainCount = 1, .swapchainCount = 1,
.pSwapchains = &renderDevice.swapchain, .pSwapchains = &renderDevice.swapchain,
.pImageIndices = &currentImageIndex, .pImageIndices = &currentImageIndex,
.pResults = nullptr, .pResults = nullptr,
}; };
VK_CHECK( vkQueuePresentKHR(renderDevice.directQueue, &presentInfo) ); VK_CHECK( vkQueuePresentKHR( renderDevice.directQueue, &presentInfo ) );
renderDevice.frameIndex = (renderDevice.frameIndex + 1) % NUM_FRAMES; renderDevice.frameIndex = ( renderDevice.frameIndex + 1 ) % NUM_FRAMES;
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
@ -238,7 +209,7 @@ SDL_AppResult SDL_AppEvent( void*, SDL_Event* event )
void SDL_AppQuit( void* appstate, SDL_AppResult ) void SDL_AppQuit( void* appstate, SDL_AppResult )
{ {
AppState* appState = static_cast<AppState*>(appstate); AppState* appState = static_cast<AppState*>( appstate );
appState->destroy(); appState->destroy();

View File

@ -157,6 +157,7 @@
<ClCompile Include="VmaImpl.cpp" /> <ClCompile Include="VmaImpl.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include=".clang-format" />
<None Include=".gitignore" /> <None Include=".gitignore" />
<None Include="PLAN.md"> <None Include="PLAN.md">
<SubType> <SubType>

View File

@ -56,6 +56,9 @@
<None Include="PLAN.md"> <None Include="PLAN.md">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
<None Include=".clang-format">
<Filter>Resource Files</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="Mesh.slang"> <CustomBuild Include="Mesh.slang">

View File

@ -7,43 +7,21 @@
bool Frame::isInit() const bool Frame::isInit() const
{ {
return static_cast<bool>(commandPool); return static_cast<bool>( commandPool );
} }
Frame::Frame( VkDevice const device, uint32_t const directQueueFamilyIndex ) Frame::Frame(
{ VkCommandPool const commandPool,
VkCommandPoolCreateInfo const commandPoolCreateInfo = { VkCommandBuffer const commandBuffer,
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, VkSemaphore const imageAcquiredSemaphore,
.pNext = nullptr, VkSemaphore const renderFinishedSemaphore,
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, VkFence const frameReadyToReuse )
.queueFamilyIndex = directQueueFamilyIndex, : commandPool{ commandPool }
}; , commandBuffer{ commandBuffer }
VK_CHECK( vkCreateCommandPool(device, &commandPoolCreateInfo, nullptr, &commandPool) ); , imageAcquiredSemaphore{ imageAcquiredSemaphore }
, renderFinishedSemaphore{ renderFinishedSemaphore }
VkCommandBufferAllocateInfo const commandBufferAllocateInfo = { , frameReadyToReuse{ frameReadyToReuse }
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, {}
.pNext = nullptr,
.commandPool = commandPool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1,
};
VK_CHECK( vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer) );
VkSemaphoreCreateInfo constexpr semaphoreCreateInfo = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = nullptr,
.flags = 0
};
VK_CHECK( vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &imageAcquiredSemaphore) );
VK_CHECK( vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphore) );
VkFenceCreateInfo constexpr fenceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.pNext = nullptr,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
};
VK_CHECK( vkCreateFence(device, &fenceCreateInfo, nullptr, &frameReadyToReuse) );
}
void Frame::destroy( RenderDevice const& renderDevice ) void Frame::destroy( RenderDevice const& renderDevice )
{ {
@ -60,5 +38,54 @@ void Frame::destroy( RenderDevice const& renderDevice )
Frame::~Frame() Frame::~Frame()
{ {
// Manual Cleanup Required. // Manual Cleanup Required.
ASSERT( not isInit() ); ASSERT( !isInit() );
}
void Frame_Create( Frame* frame, VkDevice const device, uint32_t const directQueueFamilyIndex )
{
VkCommandPool commandPool;
VkCommandBuffer commandBuffer;
VkSemaphore imageAcquiredSemaphore;
VkSemaphore renderFinishedSemaphore;
VkFence frameReadyToReuse;
{
VkCommandPoolCreateInfo const commandPoolCreateInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
.queueFamilyIndex = directQueueFamilyIndex,
};
VK_CHECK( vkCreateCommandPool( device, &commandPoolCreateInfo, nullptr, &commandPool ) );
VkCommandBufferAllocateInfo const commandBufferAllocateInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
.commandPool = commandPool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1,
};
VK_CHECK( vkAllocateCommandBuffers( device, &commandBufferAllocateInfo, &commandBuffer ) );
VkSemaphoreCreateInfo constexpr semaphoreCreateInfo = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
};
VK_CHECK( vkCreateSemaphore( device, &semaphoreCreateInfo, nullptr, &imageAcquiredSemaphore ) );
VK_CHECK( vkCreateSemaphore( device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphore ) );
VkFenceCreateInfo constexpr fenceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.pNext = nullptr,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
};
VK_CHECK( vkCreateFence( device, &fenceCreateInfo, nullptr, &frameReadyToReuse ) );
}
frame->commandPool = commandPool;
frame->commandBuffer = commandBuffer;
frame->imageAcquiredSemaphore = imageAcquiredSemaphore;
frame->renderFinishedSemaphore = renderFinishedSemaphore;
frame->frameReadyToReuse = frameReadyToReuse;
} }

24
Frame.h
View File

@ -7,17 +7,29 @@ struct RenderDevice;
struct Frame struct Frame
{ {
VkCommandPool commandPool; VkCommandPool commandPool;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
VkSemaphore imageAcquiredSemaphore; VkSemaphore imageAcquiredSemaphore;
VkSemaphore renderFinishedSemaphore; VkSemaphore renderFinishedSemaphore;
VkFence frameReadyToReuse; VkFence frameReadyToReuse;
[[nodiscard]] bool isInit() const; [[nodiscard]] bool isInit() const;
Frame( VkDevice device, uint32_t directQueueFamilyIndex ); Frame(
VkCommandPool commandPool,
VkCommandBuffer commandBuffer,
VkSemaphore imageAcquiredSemaphore,
VkSemaphore renderFinishedSemaphore,
VkFence frameReadyToReuse );
void destroy( RenderDevice const& renderDevice ); void destroy( RenderDevice const& renderDevice );
Frame( Frame const& other ) = delete;
Frame( Frame&& other ) noexcept = delete;
Frame& operator=( Frame const& other ) = delete;
Frame& operator=( Frame&& other ) noexcept = delete;
~Frame(); ~Frame();
}; };
void Frame_Create( Frame* frame, VkDevice device, uint32_t directQueueFamilyIndex );

View File

@ -4,41 +4,42 @@
void GlobalMemory::init( size_t const size ) void GlobalMemory::init( size_t const size )
{ {
memory = new Byte[size]; memory = new std::byte[size];
capacity = size; capacity = size;
available = size; available = size;
} }
void GlobalMemory::destroy() void GlobalMemory::destroy()
{ {
Byte const* originalMemory = memory - (capacity - available); std::byte const* originalMemory = memory - ( capacity - available );
delete[] originalMemory; delete[] originalMemory;
memory = nullptr; memory = nullptr;
available = 0; available = 0;
capacity = 0; capacity = 0;
} }
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" );
Byte* retVal = memory; std::byte* retVal = memory;
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*>( retVal ),
reinterpret_cast<void*>(memory), reinterpret_cast<void*>( memory ),
size, size,
available ); available );
return retVal; return retVal;
} }
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 foundOffset = addr % alignment;
if ( foundOffset == 0 ) if ( foundOffset == 0 )
@ -54,18 +55,18 @@ Byte* GlobalMemory::allocate( size_t const size, size_t const alignment )
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 {
.memory = memory, .memory = memory,
.available = available, .available = available,
}; };
} }
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
SDL_LogInfo( SDL_LOG_CATEGORY_SYSTEM, "RESTORE: %p %llu", reinterpret_cast<void*>(memory), available ); SDL_LogInfo( SDL_LOG_CATEGORY_SYSTEM, "RESTORE: %p %llu", reinterpret_cast<void*>( memory ), available );
memory = state.memory; memory = state.memory;
available = state.available; available = state.available;
} }

View File

@ -4,31 +4,42 @@
#include "MacroUtils.h" #include "MacroUtils.h"
using Byte = uint8_t; consteval size_t operator""_KiB( size_t const value )
{
return value * 1024;
}
consteval size_t operator""_MiB( size_t const value )
{
return value * 1024_KiB;
}
consteval size_t operator""_GiB( size_t const value )
{
return value * 1024_MiB;
}
struct GlobalMemory struct GlobalMemory
{ {
struct State struct State
{ {
Byte* memory; std::byte* memory;
size_t available; size_t available;
}; };
Byte* memory; std::byte* memory;
size_t available; size_t available;
size_t capacity; size_t capacity;
void init( size_t size ); void init( size_t size );
void destroy();
void destroy(); [[nodiscard]]
std::byte* allocate( size_t size );
[[nodiscard]]
std::byte* allocate( size_t size, size_t alignment );
Byte* allocate( size_t size ); [[nodiscard]]
State getState() const; //< Do not do any permanent allocations after calling this.
Byte* allocate( size_t size, size_t alignment ); void restoreState( State const& state ); //< Call this before permanent allocations.
// Do not do any permanent allocations after calling this.
[[nodiscard]] State getState() const;
// Call this before permanent allocations.
void restoreState( State const& state );
}; };

View File

@ -1,29 +1,34 @@
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <cstdlib>
#include <utility> #include <utility>
#define G_ASSERT(COND) \ #define G_ASSERT( COND ) \
do { \ do \
auto _result = (COND); \ { \
if (not _result) { \ auto _result = ( COND ); \
__debugbreak(); \ if ( not _result ) \
assert(_result && #COND); \ { \
} \ __debugbreak(); \
} while(false) assert( _result&& #COND ); \
} \
} \
while ( false )
#define ASSERT(COND) G_ASSERT(COND) #define ASSERT( COND ) G_ASSERT( COND )
#define VK_CHECK(RESULT) \ #define VK_CHECK( RESULT ) \
do { \ do \
auto _result = (RESULT); \ { \
if (_result != VK_SUCCESS) { \ auto _result = ( RESULT ); \
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, \ if ( _result != VK_SUCCESS ) \
"" #RESULT " failed with %d at %s:%d", \ { \
_result, __FILE__, __LINE__); \ SDL_LogError( SDL_LOG_CATEGORY_SYSTEM, "" #RESULT " failed with %d at %s:%d", _result, __FILE__, __LINE__ ); \
__debugbreak(); \ __debugbreak(); \
assert(_result == VK_SUCCESS); \ exit( _result ); \
} \ } \
} while(false) } \
while ( false )
#define Take(OBJ) std::exchange(OBJ, {}) #define Take( OBJ ) std::exchange( OBJ, {} )

View File

@ -2,7 +2,7 @@
#include <utility> #include <utility>
template < std::totally_ordered T > template <std::totally_ordered T>
T Clamp( T const val, T const minVal, T const maxVal ) T Clamp( T const val, T const minVal, T const maxVal )
{ {
return std::min( maxVal, std::max( val, minVal ) ); return std::min( maxVal, std::max( val, minVal ) );

View File

@ -1,7 +1,7 @@
#include "MiscData.h" #include "MiscData.h"
#include <array>
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
#include <array>
#include "MacroUtils.h" #include "MacroUtils.h"
#include "RenderDevice.h" #include "RenderDevice.h"
@ -12,7 +12,7 @@ void MiscData::init( RenderDevice const& renderDevice )
{ {
VkDevice const device = renderDevice.device; VkDevice const device = renderDevice.device;
previousCounter = 0; previousCounter = 0;
// Pipeline Creation // Pipeline Creation
{ {
@ -25,235 +25,231 @@ void MiscData::init( RenderDevice const& renderDevice )
SDL_LogError( SDL_LOG_CATEGORY_SYSTEM, "%s", SDL_GetError() ); SDL_LogError( SDL_LOG_CATEGORY_SYSTEM, "%s", SDL_GetError() );
abort(); abort();
} }
uint32_t const* data = static_cast<uint32_t const*>( rawData );
auto data = static_cast<uint32_t const*>(rawData); // Create Shader Module
VkShaderModuleCreateInfo const shaderModuleCreateInfo = { VkShaderModuleCreateInfo const shaderModuleCreateInfo = {
.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 = dataSize,
.pCode = data, .pCode = data,
}; };
VkShaderModule shaderModule; VkShaderModule shaderModule;
VK_CHECK( vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule) ); VK_CHECK( vkCreateShaderModule( device, &shaderModuleCreateInfo, nullptr, &shaderModule ) );
VkDescriptorSetLayoutBinding constexpr descriptorSetLayoutBinding = { VkDescriptorSetLayoutBinding constexpr descriptorSetLayoutBinding = {
.binding = 0, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.pImmutableSamplers = nullptr, .pImmutableSamplers = nullptr,
}; };
VkDescriptorSetLayoutCreateInfo const descriptorSetLayoutCreateInfo = { VkDescriptorSetLayoutCreateInfo const descriptorSetLayoutCreateInfo = {
.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 = &descriptorSetLayoutBinding, .pBindings = &descriptorSetLayoutBinding,
}; };
VK_CHECK( vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout) ); VK_CHECK( vkCreateDescriptorSetLayout( device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout ) );
VkPipelineLayoutCreateInfo const pipelineLayoutCreateInfo = { VkPipelineLayoutCreateInfo const pipelineLayoutCreateInfo = {
.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 = 1, .setLayoutCount = 1,
.pSetLayouts = &descriptorSetLayout, .pSetLayouts = &descriptorSetLayout,
.pushConstantRangeCount = 0, .pushConstantRangeCount = 0,
.pPushConstantRanges = nullptr, .pPushConstantRanges = nullptr,
}; };
VK_CHECK( vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout) ); VK_CHECK( vkCreatePipelineLayout( device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout ) );
std::array stages = { std::array stages = {
VkPipelineShaderStageCreateInfo{ 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 = shaderModule,
.pName = "VertexMain", .pName = "VertexMain",
.pSpecializationInfo = nullptr, .pSpecializationInfo = nullptr,
}, },
VkPipelineShaderStageCreateInfo{ 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 = shaderModule,
.pName = "FragmentMain", .pName = "FragmentMain",
.pSpecializationInfo = nullptr, .pSpecializationInfo = nullptr,
} }
}; };
// Bindings
VkVertexInputBindingDescription constexpr bindingDescription = { VkVertexInputBindingDescription constexpr bindingDescription = {
.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 = { std::array attributeDescriptions = {
VkVertexInputAttributeDescription{ VkVertexInputAttributeDescription{
.location = 0, .location = 0,
.binding = 0, .binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT, .format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof( Vertex, position ), .offset = offsetof( Vertex, position ),
}, },
VkVertexInputAttributeDescription{ VkVertexInputAttributeDescription{
.location = 1, .location = 1,
.binding = 0, .binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT, .format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof( Vertex, color ), .offset = offsetof( Vertex, color ),
}, },
}; };
VkPipelineVertexInputStateCreateInfo const vertexInputState = { VkPipelineVertexInputStateCreateInfo const vertexInputState = {
.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 = &bindingDescription,
.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size()), .vertexAttributeDescriptionCount = static_cast<uint32_t>( attributeDescriptions.size() ),
.pVertexAttributeDescriptions = attributeDescriptions.data(), .pVertexAttributeDescriptions = attributeDescriptions.data(),
}; };
VkPipelineInputAssemblyStateCreateInfo constexpr inputAssembly = { VkPipelineInputAssemblyStateCreateInfo constexpr inputAssembly = {
.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,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
.primitiveRestartEnable = VK_FALSE, .primitiveRestartEnable = VK_FALSE,
}; };
VkPipelineTessellationStateCreateInfo constexpr tessellationState = { VkPipelineTessellationStateCreateInfo constexpr tessellationState = {
.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 viewportState = {
.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,
.viewportCount = 1, .viewportCount = 1,
.pViewports = nullptr, .pViewports = nullptr,
.scissorCount = 1, .scissorCount = 1,
.pScissors = nullptr, .pScissors = nullptr,
}; };
VkPipelineRasterizationStateCreateInfo constexpr rasterizationState = { VkPipelineRasterizationStateCreateInfo constexpr rasterizationState = {
.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,
.depthClampEnable = VK_TRUE, .depthClampEnable = VK_TRUE,
.rasterizerDiscardEnable = VK_FALSE, .rasterizerDiscardEnable = VK_FALSE,
.polygonMode = VK_POLYGON_MODE_FILL, .polygonMode = VK_POLYGON_MODE_FILL,
.cullMode = VK_CULL_MODE_NONE, .cullMode = VK_CULL_MODE_NONE,
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
.depthBiasEnable = VK_FALSE, .depthBiasEnable = VK_FALSE,
.depthBiasConstantFactor = 0.0f, .depthBiasConstantFactor = 0.0f,
.depthBiasClamp = 0.0f, .depthBiasClamp = 0.0f,
.depthBiasSlopeFactor = 0.0f, .depthBiasSlopeFactor = 0.0f,
.lineWidth = 1.0f, .lineWidth = 1.0f,
}; };
VkPipelineMultisampleStateCreateInfo constexpr multisampleState = { VkPipelineMultisampleStateCreateInfo constexpr multisampleState = {
.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,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
.sampleShadingEnable = VK_FALSE, .sampleShadingEnable = VK_FALSE,
.minSampleShading = 0.0f, .minSampleShading = 0.0f,
.pSampleMask = nullptr, .pSampleMask = nullptr,
.alphaToCoverageEnable = VK_FALSE, .alphaToCoverageEnable = VK_FALSE,
.alphaToOneEnable = VK_FALSE, .alphaToOneEnable = VK_FALSE,
}; };
VkPipelineDepthStencilStateCreateInfo constexpr depthStencilState = { VkPipelineDepthStencilStateCreateInfo constexpr depthStencilState = {
.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,
.depthTestEnable = VK_FALSE, .depthTestEnable = VK_FALSE,
.depthWriteEnable = VK_FALSE, .depthWriteEnable = VK_FALSE,
.depthCompareOp = VK_COMPARE_OP_ALWAYS, .depthCompareOp = VK_COMPARE_OP_ALWAYS,
.depthBoundsTestEnable = VK_FALSE, .depthBoundsTestEnable = VK_FALSE,
.stencilTestEnable = VK_FALSE, .stencilTestEnable = VK_FALSE,
.front = {}, .front = {},
.back = {}, .back = {},
.minDepthBounds = 0.0f, .minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f, .maxDepthBounds = 1.0f,
}; };
VkPipelineColorBlendAttachmentState constexpr colorBlendAttachmentState = { VkPipelineColorBlendAttachmentState constexpr colorBlendAttachmentState = {
.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,
.colorBlendOp = VK_BLEND_OP_ADD, .colorBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.alphaBlendOp = VK_BLEND_OP_ADD, .alphaBlendOp = VK_BLEND_OP_ADD,
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT .colorWriteMask =
| VK_COLOR_COMPONENT_G_BIT VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
| VK_COLOR_COMPONENT_B_BIT
| VK_COLOR_COMPONENT_A_BIT,
}; };
VkPipelineColorBlendStateCreateInfo const colorBlendState = { VkPipelineColorBlendStateCreateInfo const colorBlendState = {
.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 = &colorBlendAttachmentState,
.blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }, .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
}; };
std::array constexpr dynamicStates = { std::array constexpr dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo const dynamicStateCreateInfo = { VkPipelineDynamicStateCreateInfo const dynamicStateCreateInfo = {
.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 = static_cast<uint32_t>( dynamicStates.size() ),
.pDynamicStates = dynamicStates.data() .pDynamicStates = dynamicStates.data()
}; };
VkPipelineRenderingCreateInfoKHR const renderingCreateInfo = { VkPipelineRenderingCreateInfoKHR const renderingCreateInfo = {
.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 = &renderDevice.swapchainFormat,
}; };
VkGraphicsPipelineCreateInfo const graphicsPipelineCreateInfo = { VkGraphicsPipelineCreateInfo const graphicsPipelineCreateInfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &renderingCreateInfo, .pNext = &renderingCreateInfo,
.flags = 0, .flags = 0,
.stageCount = static_cast<uint32_t>(stages.size()), .stageCount = static_cast<uint32_t>( stages.size() ),
.pStages = stages.data(), .pStages = stages.data(),
.pVertexInputState = &vertexInputState, .pVertexInputState = &vertexInputState,
.pInputAssemblyState = &inputAssembly, .pInputAssemblyState = &inputAssembly,
.pTessellationState = &tessellationState, .pTessellationState = &tessellationState,
.pViewportState = &viewportState, .pViewportState = &viewportState,
.pRasterizationState = &rasterizationState, .pRasterizationState = &rasterizationState,
.pMultisampleState = &multisampleState, .pMultisampleState = &multisampleState,
.pDepthStencilState = &depthStencilState, .pDepthStencilState = &depthStencilState,
.pColorBlendState = &colorBlendState, .pColorBlendState = &colorBlendState,
.pDynamicState = &dynamicStateCreateInfo, .pDynamicState = &dynamicStateCreateInfo,
.layout = pipelineLayout, .layout = pipelineLayout,
.renderPass = nullptr, .renderPass = nullptr,
.subpass = 0, .subpass = 0,
.basePipelineHandle = nullptr, .basePipelineHandle = nullptr,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}; };
VK_CHECK( vkCreateGraphicsPipelines(device, nullptr, 1, &graphicsPipelineCreateInfo, nullptr, &meshPipeline) ); VK_CHECK( vkCreateGraphicsPipelines( device, nullptr, 1, &graphicsPipelineCreateInfo, nullptr, &meshPipeline ) );
vkDestroyShaderModule( device, shaderModule, nullptr ); vkDestroyShaderModule( device, shaderModule, nullptr );
@ -276,59 +272,57 @@ void MiscData::init( RenderDevice const& renderDevice )
vertices = std::array{ vertices = std::array{
// Bottom Left // Bottom Left
Vertex{ Vertex{
.position = { -1.0f, -1.0f, 0.0f, 1.0f }, .position = { -1.0f, -1.0f, 0.0f, 1.0f },
.color = { 0.0f, 0.0f, 1.0f, 1.0f }, .color = { 0.0f, 0.0f, 1.0f, 1.0f },
}, },
// Bottom Right // Bottom Right
Vertex{ Vertex{
.position = { 1.0f, -1.0f, 0.0f, 1.0f }, .position = { 1.0f, -1.0f, 0.0f, 1.0f },
.color = { 1.0f, 0.0f, 0.0f, 1.0f }, .color = { 1.0f, 0.0f, 0.0f, 1.0f },
}, },
// Top Left // Top Left
Vertex{ Vertex{
.position = { -1.0f, 1.0f, 0.0f, 1.0f }, .position = { -1.0f, 1.0f, 0.0f, 1.0f },
.color = { 0.0f, 1.0f, 0.0f, 1.0f }, .color = { 0.0f, 1.0f, 0.0f, 1.0f },
}, },
// Top Right // Top Right
Vertex{ Vertex{
.position = { 1.0f, 1.0f, 0.0f, 1.0f }, .position = { 1.0f, 1.0f, 0.0f, 1.0f },
.color = { 1.0f, 1.0f, 0.0f, 1.0f }, .color = { 1.0f, 1.0f, 0.0f, 1.0f },
} }
}; };
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.size = vertexBufferSize, .size = vertexBufferSize,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0, .queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_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,
.preferredFlags = 0, .preferredFlags = 0,
.memoryTypeBits = 0, .memoryTypeBits = 0,
.pool = nullptr, .pool = nullptr,
.pUserData = nullptr, .pUserData = nullptr,
.priority = 1.0f, .priority = 1.0f,
}; };
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocationInfo;
VK_CHECK( VK_CHECK( vmaCreateBuffer(
vmaCreateBuffer(
renderDevice.gpuAllocator, renderDevice.gpuAllocator,
&bufferCreateInfo, &bufferCreateInfo,
&allocationCreateInfo, &allocationCreateInfo,
&vertexBuffer, &vertexBuffer,
&vertexBufferAllocation, &vertexBufferAllocation,
&allocationInfo) ); &allocationInfo ) );
if ( allocationInfo.pMappedData ) if ( allocationInfo.pMappedData )
{ {
@ -344,92 +338,90 @@ void MiscData::init( RenderDevice const& renderDevice )
cameraData.viewMatrix = glm::lookAt( cameraPosition, cameraTarget, glm::vec3{ 0.0f, 1.0f, 0.0f } ); cameraData.viewMatrix = glm::lookAt( cameraPosition, cameraTarget, glm::vec3{ 0.0f, 1.0f, 0.0f } );
cameraData.projectionMatrix = glm::perspective( glm::radians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f ); cameraData.projectionMatrix = glm::perspective( glm::radians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f );
cameraUniformBufferSize = sizeof( CameraData ); cameraUniformBufferSize = sizeof( CameraData );
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.size = cameraUniformBufferSize, .size = cameraUniformBufferSize,
.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, .usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0, .queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
}; };
VmaAllocationCreateInfo constexpr allocationCreateInfo = { VmaAllocationCreateInfo constexpr allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_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,
.preferredFlags = 0, .preferredFlags = 0,
.memoryTypeBits = 0, .memoryTypeBits = 0,
.pool = nullptr, .pool = nullptr,
.pUserData = nullptr, .pUserData = nullptr,
.priority = 1.0f, .priority = 1.0f,
}; };
VmaAllocationInfo allocationInfo; VmaAllocationInfo allocationInfo;
VK_CHECK( VK_CHECK( vmaCreateBuffer(
vmaCreateBuffer(
renderDevice.gpuAllocator, renderDevice.gpuAllocator,
&bufferCreateInfo, &bufferCreateInfo,
&allocationCreateInfo, &allocationCreateInfo,
&cameraUniformBuffer, &cameraUniformBuffer,
&cameraUniformBufferAllocation, &cameraUniformBufferAllocation,
&allocationInfo) ); &allocationInfo ) );
if ( allocationInfo.pMappedData ) if ( allocationInfo.pMappedData )
{ {
memcpy( allocationInfo.pMappedData, &cameraData, sizeof cameraData ); memcpy( allocationInfo.pMappedData, &cameraData, sizeof cameraData );
cameraUniformBufferPtr = static_cast<uint8_t*>(allocationInfo.pMappedData); cameraUniformBufferPtr = static_cast<uint8_t*>( allocationInfo.pMappedData );
} }
} }
// Descriptors // Descriptors
{ {
VkDescriptorPoolSize const poolSize = { VkDescriptorPoolSize const poolSize = {
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = renderDevice.getNumFrames(), .descriptorCount = renderDevice.getNumFrames(),
}; };
VkDescriptorPoolCreateInfo const descriptorPoolCreateInfo = { VkDescriptorPoolCreateInfo const descriptorPoolCreateInfo = {
.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 = renderDevice.getNumFrames(), .maxSets = renderDevice.getNumFrames(),
.poolSizeCount = 1, .poolSizeCount = 1,
.pPoolSizes = &poolSize, .pPoolSizes = &poolSize,
}; };
VK_CHECK( vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool) ); VK_CHECK( vkCreateDescriptorPool( device, &descriptorPoolCreateInfo, nullptr, &descriptorPool ) );
VkDescriptorSetAllocateInfo const descriptorSetAllocateInfo = { VkDescriptorSetAllocateInfo const descriptorSetAllocateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.descriptorPool = descriptorPool, .descriptorPool = descriptorPool,
.descriptorSetCount = 1, .descriptorSetCount = 1,
.pSetLayouts = &descriptorSetLayout, .pSetLayouts = &descriptorSetLayout,
}; };
VK_CHECK( vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet) ); VK_CHECK( vkAllocateDescriptorSets( device, &descriptorSetAllocateInfo, &descriptorSet ) );
VkDescriptorBufferInfo const descriptorBufferInfo = { VkDescriptorBufferInfo const descriptorBufferInfo = {
.buffer = cameraUniformBuffer, .buffer = cameraUniformBuffer,
.offset = 0, .offset = 0,
.range = sizeof CameraData, .range = sizeof CameraData,
}; };
VkWriteDescriptorSet writeDescriptorSet = { VkWriteDescriptorSet writeDescriptorSet = {
.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 = &descriptorBufferInfo,
.pTexelBufferView = nullptr, .pTexelBufferView = nullptr,
}; };
@ -438,66 +430,64 @@ void MiscData::init( RenderDevice const& renderDevice )
// Barrier Creation // Barrier Creation
{ {
VkImageSubresourceRange subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
acquireToRenderBarrier = { acquireToRenderBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, .dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.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,
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
}; };
acquireToRenderDependency = { acquireToRenderDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr, .pNext = nullptr,
.dependencyFlags = 0, .dependencyFlags = 0,
.memoryBarrierCount = 0, .memoryBarrierCount = 0,
.pMemoryBarriers = nullptr, .pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0, .bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr, .pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = 1, .imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &acquireToRenderBarrier, .pImageMemoryBarriers = &acquireToRenderBarrier,
}; };
renderToPresentBarrier = { renderToPresentBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, .srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, .dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
.dstAccessMask = VK_ACCESS_2_NONE, .dstAccessMask = VK_ACCESS_2_NONE,
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.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,
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
}; };
renderToPresentDependency = { renderToPresentDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr, .pNext = nullptr,
.dependencyFlags = 0, .dependencyFlags = 0,
.memoryBarrierCount = 0, .memoryBarrierCount = 0,
.pMemoryBarriers = nullptr, .pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0, .bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr, .pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = 1, .imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &renderToPresentBarrier, .pImageMemoryBarriers = &renderToPresentBarrier,
}; };
} }
} }

View File

@ -24,7 +24,7 @@ struct MiscData
glm::mat4x4 projectionMatrix; glm::mat4x4 projectionMatrix;
}; };
uint64_t previousCounter; uint64_t previousCounter;
VkDescriptorSetLayout descriptorSetLayout; VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
@ -35,21 +35,21 @@ struct MiscData
size_t vertexBufferSize; size_t vertexBufferSize;
std::array<Vertex, 4> vertices; std::array<Vertex, 4> vertices;
glm::vec3 cameraPosition; glm::vec3 cameraPosition;
glm::vec3 cameraTarget; glm::vec3 cameraTarget;
CameraData cameraData; CameraData cameraData;
VkBuffer cameraUniformBuffer; VkBuffer cameraUniformBuffer;
VmaAllocation cameraUniformBufferAllocation; VmaAllocation cameraUniformBufferAllocation;
size_t cameraUniformBufferSize; size_t cameraUniformBufferSize;
uint8_t* cameraUniformBufferPtr; uint8_t* cameraUniformBufferPtr;
VkDescriptorPool descriptorPool; VkDescriptorPool descriptorPool;
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet;
VkImageMemoryBarrier2 acquireToRenderBarrier; VkImageMemoryBarrier2 acquireToRenderBarrier;
VkDependencyInfo acquireToRenderDependency; VkDependencyInfo acquireToRenderDependency;
VkImageMemoryBarrier2 renderToPresentBarrier; VkImageMemoryBarrier2 renderToPresentBarrier;
VkDependencyInfo renderToPresentDependency; VkDependencyInfo renderToPresentDependency;
void init( RenderDevice const& renderDevice ); void init( RenderDevice const& renderDevice );
void destroy( RenderDevice const& renderDevice ); void destroy( RenderDevice const& renderDevice );
}; };

View File

@ -18,8 +18,9 @@ RenderDevice::~RenderDevice()
} }
// TODO: Failure Handling // TODO: Failure Handling
RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo const& createInfo ) RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo const& createInfo )
{ {
ASSERT( mem );
ASSERT( createInfo.window ); ASSERT( createInfo.window );
volkInitialize(); volkInitialize();
@ -28,36 +29,36 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
// Create Instance // Create Instance
{ {
VkApplicationInfo constexpr applicationInfo = { VkApplicationInfo constexpr applicationInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr, .pNext = nullptr,
.pApplicationName = "Test", .pApplicationName = "Test",
.applicationVersion = VK_MAKE_API_VERSION( 0, 0, 1, 0 ), .applicationVersion = VK_MAKE_API_VERSION( 0, 0, 1, 0 ),
.pEngineName = "Blaze", .pEngineName = "Blaze",
.engineVersion = VK_MAKE_API_VERSION( 0, 0, 1, 0 ), .engineVersion = VK_MAKE_API_VERSION( 0, 0, 1, 0 ),
.apiVersion = VK_API_VERSION_1_3, .apiVersion = VK_API_VERSION_1_3,
}; };
uint32_t instanceExtensionCount; uint32_t instanceExtensionCount;
char const* const* instanceExtensions = SDL_Vulkan_GetInstanceExtensions( &instanceExtensionCount ); char const* const* instanceExtensions = SDL_Vulkan_GetInstanceExtensions( &instanceExtensionCount );
VkInstanceCreateInfo const instanceCreateInfo = { VkInstanceCreateInfo const instanceCreateInfo = {
.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 = &applicationInfo,
.enabledLayerCount = 0, .enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr, .ppEnabledLayerNames = nullptr,
.enabledExtensionCount = instanceExtensionCount, .enabledExtensionCount = instanceExtensionCount,
.ppEnabledExtensionNames = instanceExtensions, .ppEnabledExtensionNames = instanceExtensions,
}; };
VK_CHECK( vkCreateInstance(&instanceCreateInfo, nullptr, &instance) ); VK_CHECK( vkCreateInstance( &instanceCreateInfo, 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( createInfo.window, instance, nullptr, &surface ) );
VkPhysicalDevice physicalDeviceInUse = nullptr; VkPhysicalDevice physicalDeviceInUse = nullptr;
VkDevice device = nullptr; VkDevice device = nullptr;
@ -66,19 +67,19 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
VkQueue directQueue = nullptr; VkQueue directQueue = nullptr;
// Create Device and Queue // Create Device and Queue
{ {
auto tempAllocStart = mem->getState(); auto tempAllocStart = mem->getState();
uint32_t physicalDeviceCount; uint32_t physicalDeviceCount;
VK_CHECK( vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr) ); VK_CHECK( vkEnumeratePhysicalDevices( instance, &physicalDeviceCount, nullptr ) );
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Found %u GPUs", physicalDeviceCount ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Found %u GPUs", physicalDeviceCount );
VkPhysicalDevice* physicalDevices = reinterpret_cast<VkPhysicalDevice*>(mem->allocate( VkPhysicalDevice* physicalDevices =
sizeof( VkPhysicalDevice ) * physicalDeviceCount )); reinterpret_cast<VkPhysicalDevice*>( mem->allocate( sizeof( VkPhysicalDevice ) * physicalDeviceCount ) );
VK_CHECK( vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices) ); VK_CHECK( vkEnumeratePhysicalDevices( instance, &physicalDeviceCount, physicalDevices ) );
for ( VkPhysicalDevice const physicalDevice : std::span{ physicalDevices, physicalDeviceCount } ) for ( VkPhysicalDevice const physicalDevice : std::span{ physicalDevices, physicalDeviceCount } )
{ {
auto tempAllocQueueProperties = mem->getState(); auto tempAllocQueueProperties = mem->getState();
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties( physicalDevice, &properties ); vkGetPhysicalDeviceProperties( physicalDevice, &properties );
@ -86,14 +87,14 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
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 API_PATCH_BITS = 0xFFF;
if ( (properties.apiVersion & (~API_PATCH_BITS)) < VK_API_VERSION_1_3 ) if ( ( properties.apiVersion & ( ~API_PATCH_BITS ) ) < VK_API_VERSION_1_3 )
{ {
continue; continue;
} }
@ -105,19 +106,18 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
uint32_t queueFamilyCount; uint32_t queueFamilyCount;
vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamilyCount, nullptr ); vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamilyCount, nullptr );
VkQueueFamilyProperties* queueFamilyProperties = reinterpret_cast<VkQueueFamilyProperties*>(mem->allocate( VkQueueFamilyProperties* queueFamilyProperties = reinterpret_cast<VkQueueFamilyProperties*>(
sizeof( VkQueueFamilyProperties ) * queueFamilyCount )); mem->allocate( sizeof( VkQueueFamilyProperties ) * queueFamilyCount ) );
vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamilyCount, queueFamilyProperties ); vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, &queueFamilyCount, queueFamilyProperties );
for ( uint32_t queueFamilyIndex = 0; queueFamilyIndex != queueFamilyCount; for ( uint32_t queueFamilyIndex = 0; queueFamilyIndex != queueFamilyCount; ++queueFamilyIndex )
++queueFamilyIndex )
{ {
VkQueueFamilyProperties const& qfp = queueFamilyProperties[queueFamilyIndex]; VkQueueFamilyProperties const& qfp = queueFamilyProperties[queueFamilyIndex];
bool hasGraphicsSupport = false; bool hasGraphicsSupport = false;
bool hasComputeSupport = false; bool hasComputeSupport = false;
bool hasTransferSupport = false; bool hasTransferSupport = false;
bool hasPresentSupport = false; bool hasPresentSupport = false;
SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "- Queue [%d]", queueFamilyIndex ); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "- Queue [%d]", queueFamilyIndex );
if ( qfp.queueFlags & VK_QUEUE_GRAPHICS_BIT ) if ( qfp.queueFlags & VK_QUEUE_GRAPHICS_BIT )
@ -138,7 +138,7 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
VkBool32 isSurfaceSupported; VkBool32 isSurfaceSupported;
VK_CHECK( VK_CHECK(
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, &isSurfaceSupported) ); vkGetPhysicalDeviceSurfaceSupportKHR( physicalDevice, queueFamilyIndex, surface, &isSurfaceSupported ) );
if ( isSurfaceSupported ) if ( isSurfaceSupported )
{ {
@ -162,65 +162,63 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
float priority = 1.0f; float priority = 1.0f;
VkDeviceQueueCreateInfo queueCreateInfo = { VkDeviceQueueCreateInfo queueCreateInfo = {
.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 = directQueueFamilyIndex.value(),
.queueCount = 1, .queueCount = 1,
.pQueuePriorities = &priority, .pQueuePriorities = &priority,
}; };
VkPhysicalDeviceVulkan13Features constexpr features13 = { VkPhysicalDeviceVulkan13Features constexpr features13 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
.pNext = nullptr, .pNext = nullptr,
.synchronization2 = true, .synchronization2 = true,
.dynamicRendering = true, .dynamicRendering = true,
}; };
VkPhysicalDeviceFeatures features = { VkPhysicalDeviceFeatures features = {
.depthClamp = true, .depthClamp = true,
.samplerAnisotropy = true, .samplerAnisotropy = true,
}; };
std::array enabledDeviceExtensions = { std::array enabledDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
VK_KHR_SWAPCHAIN_EXTENSION_NAME
VkDeviceCreateInfo const deviceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &features13,
.flags = 0,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueCreateInfo,
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
.enabledExtensionCount = static_cast<uint32_t>( enabledDeviceExtensions.size() ),
.ppEnabledExtensionNames = enabledDeviceExtensions.data(),
.pEnabledFeatures = &features,
}; };
VkDeviceCreateInfo const deviceCreateInfo = { VK_CHECK( vkCreateDevice( physicalDeviceInUse, &deviceCreateInfo, nullptr, &device ) );
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &features13,
.flags = 0,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueCreateInfo,
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
.enabledExtensionCount = static_cast<uint32_t>(enabledDeviceExtensions.size()),
.ppEnabledExtensionNames = enabledDeviceExtensions.data(),
.pEnabledFeatures = &features,
};
VK_CHECK( vkCreateDevice(physicalDeviceInUse, &deviceCreateInfo, nullptr, &device) );
volkLoadDevice( device ); volkLoadDevice( device );
VmaAllocatorCreateInfo allocatorCreateInfo = { VmaAllocatorCreateInfo allocatorCreateInfo = {
.flags = 0, .flags = 0,
.physicalDevice = physicalDeviceInUse, .physicalDevice = physicalDeviceInUse,
.device = device, .device = device,
.preferredLargeHeapBlockSize = 0, .preferredLargeHeapBlockSize = 0,
.pAllocationCallbacks = nullptr, .pAllocationCallbacks = nullptr,
.pDeviceMemoryCallbacks = nullptr, .pDeviceMemoryCallbacks = nullptr,
.pHeapSizeLimit = nullptr, .pHeapSizeLimit = nullptr,
.pVulkanFunctions = nullptr, .pVulkanFunctions = nullptr,
.instance = instance, .instance = instance,
.vulkanApiVersion = VK_API_VERSION_1_3, .vulkanApiVersion = VK_API_VERSION_1_3,
.pTypeExternalMemoryHandleTypes = nullptr, .pTypeExternalMemoryHandleTypes = nullptr,
}; };
VmaVulkanFunctions vkFunctions; VmaVulkanFunctions vkFunctions;
VK_CHECK( vmaImportVulkanFunctionsFromVolk(&allocatorCreateInfo, &vkFunctions) ); VK_CHECK( vmaImportVulkanFunctionsFromVolk( &allocatorCreateInfo, &vkFunctions ) );
allocatorCreateInfo.pVulkanFunctions = &vkFunctions; allocatorCreateInfo.pVulkanFunctions = &vkFunctions;
VK_CHECK( vmaCreateAllocator(&allocatorCreateInfo, &gpuAllocator) ); VK_CHECK( vmaCreateAllocator( &allocatorCreateInfo, &gpuAllocator ) );
vkGetDeviceQueue( device, directQueueFamilyIndex.value(), 0, &directQueue ); vkGetDeviceQueue( device, directQueueFamilyIndex.value(), 0, &directQueue );
@ -235,10 +233,10 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
VkImageView* swapchainViews; VkImageView* swapchainViews;
uint32_t swapchainImageCount; uint32_t swapchainImageCount;
{ {
auto tempAllocStart = mem->getState(); auto tempAllocStart = mem->getState();
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
VK_CHECK( vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDeviceInUse, surface, &capabilities) ); VK_CHECK( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physicalDeviceInUse, surface, &capabilities ) );
// Image Count Calculation // Image Count Calculation
swapchainImageCount = 3; swapchainImageCount = 3;
@ -258,12 +256,12 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
uint32_t surfaceFormatCount; uint32_t surfaceFormatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDeviceInUse, surface, &surfaceFormatCount, nullptr ); vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDeviceInUse, surface, &surfaceFormatCount, nullptr );
VkSurfaceFormatKHR* surfaceFormats = reinterpret_cast<VkSurfaceFormatKHR*>(mem->allocate( VkSurfaceFormatKHR* surfaceFormats =
sizeof( VkSurfaceFormatKHR ) * surfaceFormatCount )); reinterpret_cast<VkSurfaceFormatKHR*>( mem->allocate( sizeof( VkSurfaceFormatKHR ) * surfaceFormatCount ) );
vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDeviceInUse, surface, &surfaceFormatCount, surfaceFormats ); vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDeviceInUse, surface, &surfaceFormatCount, surfaceFormats );
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 ( auto& surfaceFormat : std::span{ surfaceFormats, surfaceFormatCount } )
@ -292,8 +290,8 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
uint32_t presentModeCount; uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDeviceInUse, surface, &presentModeCount, nullptr ); vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDeviceInUse, surface, &presentModeCount, nullptr );
VkPresentModeKHR* presentModes = reinterpret_cast<VkPresentModeKHR*>(mem->allocate( VkPresentModeKHR* presentModes =
sizeof( VkPresentModeKHR ) * presentModeCount )); reinterpret_cast<VkPresentModeKHR*>( mem->allocate( sizeof( VkPresentModeKHR ) * presentModeCount ) );
vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDeviceInUse, surface, &presentModeCount, presentModes ); vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDeviceInUse, surface, &presentModeCount, presentModes );
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
@ -314,34 +312,34 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
mem->restoreState( tempAllocStart ); mem->restoreState( tempAllocStart );
VkSwapchainCreateInfoKHR const swapchainCreateInfo = { VkSwapchainCreateInfoKHR const swapchainCreateInfo = {
.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 = swapchainImageCount,
.imageFormat = format.format, .imageFormat = format.format,
.imageColorSpace = format.colorSpace, .imageColorSpace = format.colorSpace,
.imageExtent = swapchainExtent, .imageExtent = swapchainExtent,
.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,
.queueFamilyIndexCount = 0, .queueFamilyIndexCount = 0,
.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 = presentMode,
.clipped = false, .clipped = false,
.oldSwapchain = nullptr, .oldSwapchain = nullptr,
}; };
VK_CHECK( vkCreateSwapchainKHR(device, &swapchainCreateInfo, nullptr, &swapchain) ); VK_CHECK( vkCreateSwapchainKHR( device, &swapchainCreateInfo, nullptr, &swapchain ) );
swapchainImageCount = 0; swapchainImageCount = 0;
vkGetSwapchainImagesKHR( device, swapchain, &swapchainImageCount, nullptr ); vkGetSwapchainImagesKHR( device, swapchain, &swapchainImageCount, nullptr );
swapchainImages = reinterpret_cast<VkImage*>(mem->allocate( sizeof( VkImage ) * swapchainImageCount )); swapchainImages = reinterpret_cast<VkImage*>( mem->allocate( sizeof( VkImage ) * swapchainImageCount ) );
vkGetSwapchainImagesKHR( device, swapchain, &swapchainImageCount, swapchainImages ); vkGetSwapchainImagesKHR( device, swapchain, &swapchainImageCount, swapchainImages );
swapchainViews = reinterpret_cast<VkImageView*>(mem->allocate( sizeof( VkImageView ) * swapchainImageCount )); swapchainViews = reinterpret_cast<VkImageView*>( mem->allocate( sizeof( VkImageView ) * swapchainImageCount ) );
for ( uint32_t i = 0; i != swapchainImageCount; ++i ) for ( uint32_t i = 0; i != swapchainImageCount; ++i )
{ {
VkImageViewCreateInfo const viewCreateInfo = { VkImageViewCreateInfo const viewCreateInfo = {
@ -366,20 +364,20 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
} }
}; };
VK_CHECK( vkCreateImageView(device, &viewCreateInfo, nullptr, &swapchainViews[i]) ); VK_CHECK( vkCreateImageView( device, &viewCreateInfo, nullptr, &swapchainViews[i] ) );
} }
} }
// Init frames. // Init frames.
Frame* frames = reinterpret_cast<Frame*>(mem->allocate( sizeof( Frame ) * swapchainImageCount )); Frame* frames = reinterpret_cast<Frame*>( mem->allocate( sizeof( Frame ) * swapchainImageCount ) );
for ( uint32_t i = 0; i != swapchainImageCount; ++i ) for ( uint32_t i = 0; i != swapchainImageCount; ++i )
{ {
new( frames + i ) Frame( device, directQueueFamilyIndex.value() ); Frame_Create( frames + i, device, directQueueFamilyIndex.value() );
} }
Byte* allocation = mem->allocate( sizeof( RenderDevice ), alignof( RenderDevice ) ); std::byte* allocation = mem->allocate( sizeof( RenderDevice ), alignof( RenderDevice ) );
return new( allocation ) RenderDevice{ return new ( allocation ) RenderDevice{
instance, instance,
surface, surface,
physicalDeviceInUse, physicalDeviceInUse,
@ -430,7 +428,7 @@ void RenderDevice::destroy()
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
@ -439,20 +437,20 @@ uint32_t RenderDevice::getNumFrames() const
} }
RenderDevice::RenderDevice( RenderDevice::RenderDevice(
VkInstance const instance, VkInstance const instance,
VkSurfaceKHR const surface, VkSurfaceKHR const surface,
VkPhysicalDevice const physicalDeviceInUse, VkPhysicalDevice const physicalDeviceInUse,
VkDevice const device, VkDevice const device,
VmaAllocator const gpuAllocator, VmaAllocator const gpuAllocator,
VkQueue const directQueue, VkQueue const directQueue,
uint32_t const directQueueFamilyIndex, uint32_t const directQueueFamilyIndex,
VkFormat const swapchainFormat, VkFormat const swapchainFormat,
VkExtent2D const swapchainExtent, VkExtent2D const swapchainExtent,
VkSwapchainKHR const swapchain, VkSwapchainKHR const swapchain,
VkImage* swapchainImages, VkImage* swapchainImages,
VkImageView* swapchainViews, VkImageView* swapchainViews,
Frame* frames, Frame* frames,
uint32_t const swapchainImageCount ) uint32_t const swapchainImageCount )
: instance{ instance } : instance{ instance }
, surface{ surface } , surface{ surface }
, physicalDeviceInUse{ physicalDeviceInUse } , physicalDeviceInUse{ physicalDeviceInUse }
@ -466,4 +464,5 @@ RenderDevice::RenderDevice(
, swapchainImages{ swapchainImages } , swapchainImages{ swapchainImages }
, swapchainViews{ swapchainViews } , swapchainViews{ swapchainViews }
, frames{ frames } , frames{ frames }
, swapchainImageCount{ swapchainImageCount } {} , swapchainImageCount{ swapchainImageCount }
{}

View File

@ -25,23 +25,23 @@ struct RenderDevice
uint32_t height = 480; uint32_t height = 480;
}; };
VkInstance instance; VkInstance instance;
VkSurfaceKHR surface; VkSurfaceKHR surface;
VkPhysicalDevice physicalDeviceInUse; VkPhysicalDevice physicalDeviceInUse;
VkDevice device; VkDevice device;
VmaAllocator gpuAllocator; VmaAllocator gpuAllocator;
VkQueue directQueue; VkQueue directQueue;
uint32_t directQueueFamilyIndex; uint32_t directQueueFamilyIndex;
VkFormat swapchainFormat; VkFormat swapchainFormat;
VkExtent2D swapchainExtent; VkExtent2D swapchainExtent;
VkSwapchainKHR swapchain; VkSwapchainKHR swapchain;
VkImage* swapchainImages; VkImage* swapchainImages;
VkImageView* swapchainViews; VkImageView* swapchainViews;
Frame* frames; Frame* frames;
uint32_t swapchainImageCount; uint32_t swapchainImageCount;
uint32_t frameIndex = 0; uint32_t frameIndex = 0;
[[nodiscard]] bool isInit() const; [[nodiscard]] bool isInit() const;
void destroy(); void destroy();
@ -49,27 +49,25 @@ struct RenderDevice
[[nodiscard]] uint32_t getNumFrames() const; [[nodiscard]] uint32_t getNumFrames() const;
RenderDevice( RenderDevice(
VkInstance instance, VkInstance instance,
VkSurfaceKHR surface, VkSurfaceKHR surface,
VkPhysicalDevice physicalDeviceInUse, VkPhysicalDevice physicalDeviceInUse,
VkDevice device, VkDevice device,
VmaAllocator gpuAllocator, VmaAllocator gpuAllocator,
VkQueue directQueue, VkQueue directQueue,
uint32_t directQueueFamilyIndex, uint32_t directQueueFamilyIndex,
// TODO: Pack?
VkFormat swapchainFormat, VkFormat swapchainFormat,
VkExtent2D swapchainExtent, VkExtent2D swapchainExtent,
VkSwapchainKHR swapchain, VkSwapchainKHR swapchain,
VkImage* swapchainImages, VkImage* swapchainImages,
VkImageView* swapchainViews, VkImageView* swapchainViews,
Frame* frames, Frame* frames,
uint32_t swapchainImageCount uint32_t swapchainImageCount );
);
RenderDevice( RenderDevice const& ) = delete; RenderDevice( RenderDevice const& ) = delete;
RenderDevice& operator=( RenderDevice const& ) = delete; RenderDevice& operator=( RenderDevice const& ) = delete;
RenderDevice( RenderDevice&& ) noexcept = delete; RenderDevice( RenderDevice&& ) noexcept = delete;
RenderDevice& operator=( RenderDevice&& ) noexcept = delete; RenderDevice& operator=( RenderDevice&& ) noexcept = delete;
@ -77,4 +75,4 @@ struct RenderDevice
~RenderDevice(); ~RenderDevice();
}; };
RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo const& createInfo ); RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo const& createInfo );

View File

@ -1,7 +1,7 @@
#include <volk.h> #include <volk.h>
#pragma warning(push, 1) #pragma warning( push, 1 )
#pragma warning(disable : 5045) #pragma warning( disable : 5045 )
#define VMA_IMPLEMENTATION #define VMA_IMPLEMENTATION
#include <vma/vk_mem_alloc.h> #include <vma/vk_mem_alloc.h>
#pragma warning(pop) #pragma warning( pop )