From d7c48d28c7c8bedb09f3c3187015b0e4159da156 Mon Sep 17 00:00:00 2001 From: Anish Bhobe Date: Mon, 7 Jul 2025 19:36:54 +0200 Subject: [PATCH] Uniform Buffers. --- Blaze/Source/Blaze.cpp | 10 ++--- Blaze/Source/BufferManager.cpp | 71 +++++++++++++++++++++++++++++++++- Blaze/Source/BufferManager.h | 18 +++++++-- Blaze/Source/MiscData.cpp | 50 ++++-------------------- Blaze/Source/MiscData.h | 5 +-- Blaze/Source/ModelLoader.cpp | 4 +- 6 files changed, 97 insertions(+), 61 deletions(-) diff --git a/Blaze/Source/Blaze.cpp b/Blaze/Source/Blaze.cpp index fbe2077..abd22e6 100644 --- a/Blaze/Source/Blaze.cpp +++ b/Blaze/Source/Blaze.cpp @@ -74,7 +74,7 @@ SDL_AppResult SDL_AppInit( void** appstate, int, char** ) app_state.miscData->lightData.pointLightCount = _countof( point_light ); - app_state.renderDevice->bufferManager->WriteToBuffer( app_state.miscData->pointLights, point_light ); + app_state.renderDevice->bufferManager->WriteRangeToBuffer( app_state.miscData->pointLights, point_light ); Blaze::MiscData::DirectionalLight dir_light[] = { { @@ -85,12 +85,10 @@ SDL_AppResult SDL_AppInit( void** appstate, int, char** ) app_state.miscData->lightData.dirLightCount = _countof( dir_light ); - app_state.renderDevice->bufferManager->WriteToBuffer( app_state.miscData->directionalLights, dir_light ); + app_state.renderDevice->bufferManager->WriteRangeToBuffer( app_state.miscData->directionalLights, dir_light ); - memcpy( - app_state.miscData->cameraUniformBufferPtr + sizeof( Blaze::MiscData::CameraData ), - &app_state.miscData->lightData, - sizeof app_state.miscData->lightData ); + app_state.renderDevice->bufferManager->WriteObjectToBuffer( + app_state.miscData->uniformBuffer, sizeof( Blaze::MiscData::CameraData ), app_state.miscData->lightData ); return SDL_APP_CONTINUE; } diff --git a/Blaze/Source/BufferManager.cpp b/Blaze/Source/BufferManager.cpp index f23b2f4..0c5baa4 100644 --- a/Blaze/Source/BufferManager.cpp +++ b/Blaze/Source/BufferManager.cpp @@ -40,7 +40,7 @@ Blaze::Buffer& BufferManager::FetchBufferUnchecked( BufferID const& rid ) return m_buffers[inner_index]; } -void BufferManager::WriteToBufferImpl( BufferID const& rid, void const* data, size_t const size ) +void BufferManager::WriteToBuffer( BufferID const& rid, void const* data, size_t const size, size_t const offset ) { ASSERT( IsValidID( rid ) ); @@ -48,7 +48,7 @@ void BufferManager::WriteToBufferImpl( BufferID const& rid, void const* data, si ASSERT( size <= buffer.size ); - memcpy( buffer.mappedData, data, size ); + memcpy( buffer.mappedData + offset, data, size ); } bool BufferManager::IsValidID( BufferID const& rid ) const @@ -248,6 +248,73 @@ Blaze::BufferID BufferManager::CreateStorageBuffer( size_t const size ) return *reinterpret_cast( &index ); } +Blaze::BufferID BufferManager::CreateUniformBuffer( size_t const size ) +{ + ASSERT( not m_freeList.Empty() ); + + Buffer* buffer_slot = reinterpret_cast( m_freeList.PopFront() ); + ++m_count; + + ASSERT( m_renderDevice ); + RenderDevice const& render_device = *m_renderDevice; + + VkBufferCreateInfo const buffer_create_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = size, + .usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + }; + + VmaAllocationCreateInfo constexpr allocation_create_info = { + .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 allocation_info; + VkBuffer storage_buffer; + VmaAllocation storage_buffer_allocation; + + VK_CHECK( vmaCreateBuffer( + render_device.gpuAllocator, + &buffer_create_info, + &allocation_create_info, + &storage_buffer, + &storage_buffer_allocation, + &allocation_info ) ); + + VkBufferDeviceAddressInfo const device_address_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + .pNext = nullptr, + .buffer = storage_buffer, + }; + + VkDeviceAddress const device_address = vkGetBufferDeviceAddress( render_device.device, &device_address_info ); + + // NOTE: bufferSlot preserves index between uses. + uint32_t index = buffer_slot->index; + new ( buffer_slot ) Buffer{ + .buffer = storage_buffer, + .allocation = storage_buffer_allocation, + .mappedData = static_cast( allocation_info.pMappedData ), + .deviceAddress = device_address, + .size = size, + .index = index, + }; + + // NOTE: Memory hackery to create BufferID; + return *reinterpret_cast( &index ); +} + void BufferManager::FreeBuffer( BufferID* rid ) { if ( not IsValidID( *rid ) ) return; diff --git a/Blaze/Source/BufferManager.h b/Blaze/Source/BufferManager.h index 694d812..acce3e7 100644 --- a/Blaze/Source/BufferManager.h +++ b/Blaze/Source/BufferManager.h @@ -52,7 +52,6 @@ private: void DestroyBuffer( Buffer& buf ); Buffer& FetchBufferUnchecked( BufferID const& rid ); - void WriteToBufferImpl( BufferID const& rid, void const* data, size_t size ); public: [[nodiscard]] bool IsValidID( BufferID const& rid ) const; @@ -60,6 +59,7 @@ public: BufferID CreateVertexBuffer( size_t size ); BufferID CreateIndexBuffer( size_t size ); BufferID CreateStorageBuffer( size_t size ); + BufferID CreateUniformBuffer( size_t size ); void FreeBuffer( BufferID* rid ); @@ -67,13 +67,23 @@ public: std::optional FetchBuffer( BufferID const& rid ); std::optional FetchDeviceAddress( BufferID const& rid ); + void WriteToBuffer( BufferID const& rid, void const* data, size_t size, size_t offset ); + // Utility to directly muck the data - void WriteToBuffer( BufferID const& rid, std::ranges::contiguous_range auto const& data ) + void WriteRangeToBuffer( BufferID const& rid, std::ranges::contiguous_range auto const& data ) { - WriteToBufferImpl( + WriteToBuffer( rid, std::ranges::data( data ), - std::ranges::size( data ) * sizeof( std::ranges::range_value_t ) ); + std::ranges::size( data ) * sizeof( std::ranges::range_value_t ), + 0 ); + } + + // Utility to directly muck the data + void WriteObjectToBuffer( BufferID const& rid, size_t const offset, auto const& data ) + requires not std::ranges::range + { + WriteToBuffer( rid, &data, sizeof data, offset ); } static BufferManager* Create( GlobalMemory* mem, RenderDevice* render_device, uint32_t max_count ); diff --git a/Blaze/Source/MiscData.cpp b/Blaze/Source/MiscData.cpp index c1b31c0..bed7ac3 100644 --- a/Blaze/Source/MiscData.cpp +++ b/Blaze/Source/MiscData.cpp @@ -274,8 +274,6 @@ bool MiscData::Init( RenderDevice const& render_device ) cameraData.viewMatrix = DirectX::XMMatrixLookAtRH( cameraData.cameraPosition, cameraTarget, cameraUp ); cameraData.projectionMatrix = DirectX::XMMatrixPerspectiveFovRH( DirectX::XMConvertToRadians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f ); - - cameraUniformBufferSize = sizeof( CameraData ) + sizeof( LightData ); } @@ -295,45 +293,10 @@ bool MiscData::Init( RenderDevice const& render_device ) // Uniform Buffer { + uniformBuffer = render_device.bufferManager->CreateUniformBuffer( sizeof( CameraData ) + sizeof( LightData ) ); - VkBufferCreateInfo const buffer_create_info = { - .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 allocation_create_info = { - .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 allocation_info; - - VK_CHECK( vmaCreateBuffer( - render_device.gpuAllocator, - &buffer_create_info, - &allocation_create_info, - &cameraUniformBuffer, - &cameraUniformBufferAllocation, - &allocation_info ) ); - - if ( allocation_info.pMappedData ) - { - cameraUniformBufferPtr = static_cast( allocation_info.pMappedData ); - memcpy( cameraUniformBufferPtr, &cameraData, sizeof cameraData ); - memcpy( cameraUniformBufferPtr + sizeof cameraData, &lightData, sizeof lightData ); - } + render_device.bufferManager->WriteObjectToBuffer( uniformBuffer, 0, cameraData ); + render_device.bufferManager->WriteObjectToBuffer( uniformBuffer, sizeof CameraData, lightData ); } // Descriptors @@ -364,9 +327,9 @@ bool MiscData::Init( RenderDevice const& render_device ) VK_CHECK( vkAllocateDescriptorSets( device, &descriptor_set_allocate_info, &descriptorSet ) ); VkDescriptorBufferInfo const descriptor_buffer_info = { - .buffer = cameraUniformBuffer, + .buffer = render_device.bufferManager->FetchBuffer( uniformBuffer ).value(), .offset = 0, - .range = cameraUniformBufferSize, + .range = sizeof( CameraData ) + sizeof( LightData ), }; VkWriteDescriptorSet write_descriptor_sets[] = { @@ -464,7 +427,8 @@ void MiscData::Destroy( Blaze::RenderDevice const& render_device ) VkDevice const device = render_device.device; vkDestroyDescriptorPool( device, Take( descriptorPool ), nullptr ); - vmaDestroyBuffer( render_device.gpuAllocator, Take( cameraUniformBuffer ), Take( cameraUniformBufferAllocation ) ); + + render_device.bufferManager->FreeBuffer( &uniformBuffer ); render_device.bufferManager->FreeBuffer( &pointLights ); render_device.bufferManager->FreeBuffer( &directionalLights ); diff --git a/Blaze/Source/MiscData.h b/Blaze/Source/MiscData.h index beff216..de9f157 100644 --- a/Blaze/Source/MiscData.h +++ b/Blaze/Source/MiscData.h @@ -58,10 +58,7 @@ struct MiscData BufferID directionalLights; LightData lightData; - VkBuffer cameraUniformBuffer; - VmaAllocation cameraUniformBufferAllocation; - size_t cameraUniformBufferSize; - uint8_t* cameraUniformBufferPtr; + BufferID uniformBuffer; VkDescriptorPool descriptorPool; VkDescriptorSet descriptorSet; diff --git a/Blaze/Source/ModelLoader.cpp b/Blaze/Source/ModelLoader.cpp index c8b86f3..c5a8328 100644 --- a/Blaze/Source/ModelLoader.cpp +++ b/Blaze/Source/ModelLoader.cpp @@ -793,12 +793,12 @@ Entity* LoadModel( Blaze::RenderDevice* render_device, EntityManager* entity_man entity->model.vertexBuffer = render_device->bufferManager->CreateVertexBuffer( vertices.size() * sizeof vertices[0] ); if ( not entity->model.vertexBuffer ) return nullptr; - render_device->bufferManager->WriteToBuffer( entity->model.vertexBuffer, vertices ); + render_device->bufferManager->WriteRangeToBuffer( entity->model.vertexBuffer, vertices ); entity->model.indexBuffer = render_device->bufferManager->CreateIndexBuffer( indices.size() * sizeof indices[0] ); if ( not entity->model.indexBuffer ) return nullptr; - render_device->bufferManager->WriteToBuffer( entity->model.indexBuffer, std::span{ indices } ); + render_device->bufferManager->WriteRangeToBuffer( entity->model.indexBuffer, indices ); cgltf_free( gltf_model ); return entity;