VertexBuffer ingestion and Camera.

This commit is contained in:
Anish Bhobe 2025-06-13 22:48:31 +02:00
parent 9115b97bc2
commit fd9ceae67d
11 changed files with 438 additions and 128 deletions

1
.gitignore vendored
View File

@ -613,3 +613,4 @@ $RECYCLE.BIN/
# Windows shortcuts # Windows shortcuts
*.lnk *.lnk
*.spv

View File

@ -8,61 +8,60 @@
bool AppState::isInit() const bool AppState::isInit() const
{ {
return window and renderDevice and renderDevice->isInit(); 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)->cleanup(*renderDevice); Take( miscData )->destroy( *renderDevice );
Take(renderDevice)->destroy(); Take( renderDevice )->destroy();
SDL_DestroyWindow(Take(window)); SDL_DestroyWindow( Take( window ) );
} }
AppState::AppState(SDL_Window* window, RenderDevice* renderDevice, MiscData* miscData) AppState::AppState( SDL_Window* window, RenderDevice* renderDevice, MiscData* miscData )
: window{ window } : window{ window }
, renderDevice{ renderDevice } , renderDevice{ renderDevice }
, miscData{ miscData } { , miscData{ miscData } {}
}
AppState* CreateAppState(GlobalMemory* memory, uint32_t const width, uint32_t const height) AppState* CreateAppState( GlobalMemory* memory, uint32_t const width, uint32_t const height )
{ {
SDL_Window* window = SDL_CreateWindow( SDL_Window* window = SDL_CreateWindow(
"Blaze Test", "Blaze Test",
static_cast<int>(width), static_cast<int>(width),
static_cast<int>(height), static_cast<int>(height),
SDL_WINDOW_VULKAN); 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(); auto state = memory->getState();
RenderDevice* renderDevice = CreateRenderDevice(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" );
return nullptr; return nullptr;
} }
(void)state; (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;
} }
AppState::~AppState() AppState::~AppState()
{ {
ASSERT(!isInit()); ASSERT( !isInit() );
} }

View File

@ -10,6 +10,7 @@
#define SDL_MAIN_USE_CALLBACKS 1 #define SDL_MAIN_USE_CALLBACKS 1
#include <memory> #include <memory>
#include <glm/ext/matrix_transform.hpp>
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3/SDL_main.h> #include <SDL3/SDL_main.h>
#include <SDL3/SDL_filesystem.h> #include <SDL3/SDL_filesystem.h>
@ -68,6 +69,8 @@ SDL_AppResult SDL_AppInit( void** pAppState, int, char** )
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);
@ -76,10 +79,31 @@ SDL_AppResult SDL_AppIterate( void* appstate )
Frame& currentFrame = renderDevice.frames[renderDevice.frameIndex]; Frame& currentFrame = renderDevice.frames[renderDevice.frameIndex];
VK_CHECK( VK_CHECK(
vkWaitForFences(renderDevice.device, 1, &currentFrame.frameReadyToReuse, VK_TRUE, std::numeric_limits<uint32_t>::max vkWaitForFences(renderDevice.device,
()) ); 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.
uint64_t const previousCounter = misc.previousCounter;
uint64_t const currentCounter = SDL_GetPerformanceCounter();
uint64_t const deltaCount = currentCounter - previousCounter;
uint64_t const perfFreq = SDL_GetPerformanceFrequency();
double const deltaTime = static_cast<double>(deltaCount) / static_cast<double>(perfFreq);
misc.previousCounter = currentCounter;
double deltaTimeMs = deltaTime * 1000.0;
double fps = 1.0 / deltaTime;
auto _ = sprintf_s<1000>( g_buf, "%.2f fps %.5fms %llu -> %llu", fps, deltaTimeMs, previousCounter, currentCounter );
SDL_SetWindowTitle( appState.window, g_buf );
misc.cameraData.modelMatrix = glm::rotate(
misc.cameraData.modelMatrix,
glm::radians( 60.0f ) * static_cast<float>(deltaTime),
glm::vec3{ 0.0f, 1.0f, 0.0f } );
memcpy( misc.cameraUniformBufferPtr, &misc.cameraData, sizeof misc.cameraData );
uint32_t currentImageIndex; uint32_t currentImageIndex;
VK_CHECK( VK_CHECK(
vkAcquireNextImageKHR(renderDevice.device, renderDevice.swapchain, std::numeric_limits<uint32_t>::max(), vkAcquireNextImageKHR(renderDevice.device, renderDevice.swapchain, std::numeric_limits<uint32_t>::max(),
@ -151,8 +175,19 @@ SDL_AppResult SDL_AppIterate( void* appstate )
vkCmdSetScissor( cmd, 0, 1, &scissor ); vkCmdSetScissor( cmd, 0, 1, &scissor );
// Render Something? // Render Something?
vkCmdBindPipeline( cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.trianglePipeline ); vkCmdBindPipeline( cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.meshPipeline );
vkCmdDraw( cmd, 3, 1, 0, 0 ); VkDeviceSize constexpr offset = 0;
vkCmdBindVertexBuffers( cmd, 0, 1, &misc.vertexBuffer, &offset );
vkCmdBindDescriptorSets(
cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS,
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 );

View File

@ -163,7 +163,7 @@
</SubType> </SubType>
</None> </None>
<None Include="README.md" /> <None Include="README.md" />
<CustomBuild Include="Triangle.slang"> <CustomBuild Include="Mesh.slang">
<FileType>Document</FileType> <FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">slangc %(FullPath) -profile sm_6_6 -target spirv -o %(Filename).spv</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">slangc %(FullPath) -profile sm_6_6 -target spirv -o %(Filename).spv</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).spv</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).spv</Outputs>

View File

@ -58,7 +58,7 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="Triangle.slang"> <CustomBuild Include="Mesh.slang">
<Filter>Shader Files</Filter> <Filter>Shader Files</Filter>
</CustomBuild> </CustomBuild>
</ItemGroup> </ItemGroup>

View File

@ -15,13 +15,23 @@ struct VertexOut {
float4 vertexColor : CoarseColor; float4 vertexColor : CoarseColor;
}; };
struct CameraData {
float4x4 model;
float4x4 view;
float4x4 proj;
};
ParameterBlock<CameraData> camera;
[shader("vertex")] [shader("vertex")]
VertexOut VertexMain( VertexOut VertexMain(
uint vertexId: SV_VertexID uint vertexId: SV_VertexID,
float4 position,
float4 color,
) { ) {
VertexOut output; VertexOut output;
output.outPosition = vertexPos[vertexId]; output.outPosition = mul(camera.proj, mul(camera.view, mul(camera.model, position)));
output.vertexColor = vertexColors[vertexId]; output.vertexColor = color;
return output; return output;
} }

View File

@ -6,13 +6,18 @@
#include "MacroUtils.h" #include "MacroUtils.h"
#include "RenderDevice.h" #include "RenderDevice.h"
#include <glm/gtc/matrix_transform.hpp>
void MiscData::init( RenderDevice const& renderDevice ) void MiscData::init( RenderDevice const& renderDevice )
{ {
VkDevice const device = renderDevice.device; VkDevice const device = renderDevice.device;
previousCounter = 0;
// Pipeline Creation
{ {
size_t dataSize; size_t dataSize;
void* rawData = SDL_LoadFile( "Triangle.spv", &dataSize ); void* rawData = SDL_LoadFile( "Mesh.spv", &dataSize );
ASSERT( dataSize % 4 == 0 ); ASSERT( dataSize % 4 == 0 );
if ( !rawData ) if ( !rawData )
@ -34,12 +39,29 @@ void MiscData::init( RenderDevice const& renderDevice )
VkShaderModule shaderModule; VkShaderModule shaderModule;
VK_CHECK( vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule) ); VK_CHECK( vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule) );
VkPipelineLayoutCreateInfo constexpr pipelineLayoutCreateInfo = { VkDescriptorSetLayoutBinding constexpr descriptorSetLayoutBinding = {
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.pImmutableSamplers = nullptr,
};
VkDescriptorSetLayoutCreateInfo const descriptorSetLayoutCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.bindingCount = 1,
.pBindings = &descriptorSetLayoutBinding,
};
VK_CHECK( vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout) );
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 = 0, .setLayoutCount = 1,
.pSetLayouts = nullptr, .pSetLayouts = &descriptorSetLayout,
.pushConstantRangeCount = 0, .pushConstantRangeCount = 0,
.pPushConstantRanges = nullptr, .pPushConstantRanges = nullptr,
}; };
@ -66,21 +88,42 @@ void MiscData::init( RenderDevice const& renderDevice )
} }
}; };
VkPipelineVertexInputStateCreateInfo constexpr vertexInputState = { VkVertexInputBindingDescription constexpr bindingDescription = {
.binding = 0,
.stride = sizeof( Vertex ),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
};
std::array attributeDescriptions = {
VkVertexInputAttributeDescription{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof( Vertex, position ),
},
VkVertexInputAttributeDescription{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof( Vertex, color ),
},
};
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 = 0, .vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = nullptr, .pVertexBindingDescriptions = &bindingDescription,
.vertexAttributeDescriptionCount = 0, .vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size()),
.pVertexAttributeDescriptions = nullptr, .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_LIST, .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
.primitiveRestartEnable = VK_FALSE, .primitiveRestartEnable = VK_FALSE,
}; };
@ -210,80 +253,264 @@ void MiscData::init( RenderDevice const& renderDevice )
.basePipelineIndex = 0, .basePipelineIndex = 0,
}; };
VK_CHECK( vkCreateGraphicsPipelines(device, nullptr, 1, &graphicsPipelineCreateInfo, nullptr, &trianglePipeline) ); VK_CHECK( vkCreateGraphicsPipelines(device, nullptr, 1, &graphicsPipelineCreateInfo, nullptr, &meshPipeline) );
vkDestroyShaderModule( device, shaderModule, nullptr ); vkDestroyShaderModule( device, shaderModule, nullptr );
SDL_free( rawData ); SDL_free( rawData );
} }
acquireToRenderBarrier = { // Vertex Buffer Creation
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, {
.pNext = nullptr, vertexBufferSize = sizeof vertices[0] * vertices.size();
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
};
acquireToRenderDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr,
.dependencyFlags = 0,
.memoryBarrierCount = 0,
.pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &acquireToRenderBarrier,
};
renderToPresentBarrier = { // TL----TR
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, // | \ |
.pNext = nullptr, // | \ |
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, // | \ |
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, // BL----BR
.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, //
.dstAccessMask = VK_ACCESS_2_NONE, // BL -> BR -> TL
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // TL -> BR -> TR
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, vertices = std::array{
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, // Bottom Left
.subresourceRange = { Vertex{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .position = { -1.0f, -1.0f, 0.0f, 1.0f },
.baseMipLevel = 0, .color = { 0.0f, 0.0f, 1.0f, 1.0f },
.levelCount = 1, },
.baseArrayLayer = 0, // Bottom Right
.layerCount = 1, Vertex{
.position = { 1.0f, -1.0f, 0.0f, 1.0f },
.color = { 1.0f, 0.0f, 0.0f, 1.0f },
},
// Top Left
Vertex{
.position = { -1.0f, 1.0f, 0.0f, 1.0f },
.color = { 0.0f, 1.0f, 0.0f, 1.0f },
},
// Top Right
Vertex{
.position = { 1.0f, 1.0f, 0.0f, 1.0f },
.color = { 1.0f, 1.0f, 0.0f, 1.0f },
}
};
VkBufferCreateInfo const bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = vertexBufferSize,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
};
VmaAllocationCreateInfo constexpr allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.preferredFlags = 0,
.memoryTypeBits = 0,
.pool = nullptr,
.pUserData = nullptr,
.priority = 1.0f,
};
VmaAllocationInfo allocationInfo;
VK_CHECK(
vmaCreateBuffer(
renderDevice.gpuAllocator,
&bufferCreateInfo,
&allocationCreateInfo,
&vertexBuffer,
&vertexBufferAllocation,
&allocationInfo) );
if ( allocationInfo.pMappedData )
{
memcpy( allocationInfo.pMappedData, vertices.data(), vertices.size() * sizeof vertices[0] );
} }
}; }
renderToPresentDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // Camera
.pNext = nullptr, {
.dependencyFlags = 0, cameraPosition = glm::vec3{ 0.0f, 0.0f, -5.0f };
.memoryBarrierCount = 0, cameraTarget = glm::vec3{ 0.0f, 0.0f, 0.0f };
.pMemoryBarriers = nullptr, cameraData.modelMatrix = glm::mat4{ 1.0f };
.bufferMemoryBarrierCount = 0, cameraData.viewMatrix = glm::lookAt( cameraPosition, cameraTarget, glm::vec3{ 0.0f, 1.0f, 0.0f } );
.pBufferMemoryBarriers = nullptr, cameraData.projectionMatrix = glm::perspective( glm::radians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f );
.imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &renderToPresentBarrier, cameraUniformBufferSize = sizeof( CameraData );
};
VkBufferCreateInfo const bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = cameraUniformBufferSize,
.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
};
VmaAllocationCreateInfo constexpr allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.preferredFlags = 0,
.memoryTypeBits = 0,
.pool = nullptr,
.pUserData = nullptr,
.priority = 1.0f,
};
VmaAllocationInfo allocationInfo;
VK_CHECK(
vmaCreateBuffer(
renderDevice.gpuAllocator,
&bufferCreateInfo,
&allocationCreateInfo,
&cameraUniformBuffer,
&cameraUniformBufferAllocation,
&allocationInfo) );
if ( allocationInfo.pMappedData )
{
memcpy( allocationInfo.pMappedData, &cameraData, sizeof cameraData );
cameraUniformBufferPtr = static_cast<uint8_t*>(allocationInfo.pMappedData);
}
}
// Descriptors
{
VkDescriptorPoolSize const poolSize = {
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = renderDevice.getNumFrames(),
};
VkDescriptorPoolCreateInfo const descriptorPoolCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.maxSets = renderDevice.getNumFrames(),
.poolSizeCount = 1,
.pPoolSizes = &poolSize,
};
VK_CHECK( vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool) );
VkDescriptorSetAllocateInfo const descriptorSetAllocateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = descriptorPool,
.descriptorSetCount = 1,
.pSetLayouts = &descriptorSetLayout,
};
VK_CHECK( vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet) );
VkDescriptorBufferInfo const descriptorBufferInfo = {
.buffer = cameraUniformBuffer,
.offset = 0,
.range = sizeof CameraData,
};
VkWriteDescriptorSet writeDescriptorSet = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = descriptorSet,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pImageInfo = nullptr,
.pBufferInfo = &descriptorBufferInfo,
.pTexelBufferView = nullptr,
};
vkUpdateDescriptorSets( device, 1, &writeDescriptorSet, 0, nullptr );
}
// Barrier Creation
{
acquireToRenderBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
};
acquireToRenderDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr,
.dependencyFlags = 0,
.memoryBarrierCount = 0,
.pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &acquireToRenderBarrier,
};
renderToPresentBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
.dstAccessMask = VK_ACCESS_2_NONE,
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
};
renderToPresentDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr,
.dependencyFlags = 0,
.memoryBarrierCount = 0,
.pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = 1,
.pImageMemoryBarriers = &renderToPresentBarrier,
};
}
} }
void MiscData::cleanup( RenderDevice const& renderDevice ) void MiscData::destroy( RenderDevice const& renderDevice )
{ {
VkDevice const device = renderDevice.device; VkDevice const device = renderDevice.device;
vkDestroyPipeline( device, trianglePipeline, nullptr ); vkDestroyDescriptorPool( device, Take( descriptorPool ), nullptr );
vkDestroyPipelineLayout( device, pipelineLayout, nullptr ); vmaDestroyBuffer( renderDevice.gpuAllocator, Take( cameraUniformBuffer ), Take( cameraUniformBufferAllocation ) );
vmaDestroyBuffer( renderDevice.gpuAllocator, Take( vertexBuffer ), Take( vertexBufferAllocation ) );
vkDestroyPipeline( device, Take( meshPipeline ), nullptr );
vkDestroyPipelineLayout( device, Take( pipelineLayout ), nullptr );
vkDestroyDescriptorSetLayout( device, Take( descriptorSetLayout ), nullptr );
} }

View File

@ -1,13 +1,49 @@
#pragma once #pragma once
#include <array>
#include <volk.h> #include <volk.h>
#include <vma/vk_mem_alloc.h>
#include <glm/glm.hpp>
struct RenderDevice; struct RenderDevice;
struct Vertex
{
float position[4];
float color[4];
};
struct MiscData struct MiscData
{ {
VkPipelineLayout pipelineLayout; struct CameraData
VkPipeline trianglePipeline; {
glm::mat4x4 modelMatrix;
glm::mat4x4 viewMatrix;
glm::mat4x4 projectionMatrix;
};
uint64_t previousCounter;
VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout;
VkPipeline meshPipeline;
VkBuffer vertexBuffer;
VmaAllocation vertexBufferAllocation;
size_t vertexBufferSize;
std::array<Vertex, 4> vertices;
glm::vec3 cameraPosition;
glm::vec3 cameraTarget;
CameraData cameraData;
VkBuffer cameraUniformBuffer;
VmaAllocation cameraUniformBufferAllocation;
size_t cameraUniformBufferSize;
uint8_t* cameraUniformBufferPtr;
VkDescriptorPool descriptorPool;
VkDescriptorSet descriptorSet;
VkImageMemoryBarrier2 acquireToRenderBarrier; VkImageMemoryBarrier2 acquireToRenderBarrier;
VkDependencyInfo acquireToRenderDependency; VkDependencyInfo acquireToRenderDependency;
@ -15,5 +51,5 @@ struct MiscData
VkDependencyInfo renderToPresentDependency; VkDependencyInfo renderToPresentDependency;
void init( RenderDevice const& renderDevice ); void init( RenderDevice const& renderDevice );
void cleanup( RenderDevice const& renderDevice ); void destroy( RenderDevice const& renderDevice );
}; };

View File

@ -59,11 +59,11 @@ RenderDevice* CreateRenderDevice( GlobalMemory* mem, RenderDevice::CreateInfo co
// 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;
VmaAllocator gpuAllocator = nullptr; VmaAllocator gpuAllocator = nullptr;
std::optional<uint32_t> directQueueFamilyIndex; std::optional<uint32_t> directQueueFamilyIndex = std::nullopt;
VkQueue directQueue = nullptr; VkQueue directQueue = nullptr;
// Create Device and Queue // Create Device and Queue
{ {
auto tempAllocStart = mem->getState(); auto tempAllocStart = mem->getState();
@ -418,6 +418,7 @@ void RenderDevice::destroy()
vkDestroySwapchainKHR( device, Take( swapchain ), nullptr ); vkDestroySwapchainKHR( device, Take( swapchain ), nullptr );
vmaDestroyAllocator( Take( gpuAllocator ) );
vkDestroyDevice( Take( device ), nullptr ); vkDestroyDevice( Take( device ), nullptr );
SDL_Vulkan_DestroySurface( instance, Take( surface ), nullptr ); SDL_Vulkan_DestroySurface( instance, Take( surface ), nullptr );
@ -442,7 +443,7 @@ RenderDevice::RenderDevice(
VkSurfaceKHR const surface, VkSurfaceKHR const surface,
VkPhysicalDevice const physicalDeviceInUse, VkPhysicalDevice const physicalDeviceInUse,
VkDevice const device, VkDevice const device,
VmaAllocator gpuAllocator, VmaAllocator const gpuAllocator,
VkQueue const directQueue, VkQueue const directQueue,
uint32_t const directQueueFamilyIndex, uint32_t const directQueueFamilyIndex,
VkFormat const swapchainFormat, VkFormat const swapchainFormat,

Binary file not shown.

View File

@ -3,6 +3,7 @@
"volk", "volk",
"shader-slang", "shader-slang",
"vulkan-memory-allocator", "vulkan-memory-allocator",
"glm",
{ {
"name": "sdl3", "name": "sdl3",
"features": [ "vulkan" ] "features": [ "vulkan" ]