Skip to content

Commit

Permalink
Better memory allocation (#32)
Browse files Browse the repository at this point in the history
* vulkanGlobal: add BufferInfo struct, and deprecate CreateBuffer

* vulkanGlobal: add missing VK_EXT_ROBUSTNESS_2_EXTENSION_NAME

* Context: add createBuffer()
Diff with old CreateBuffer():
- VmaAllocationCreateFlags flags in argument for better control
- Return an optional std::optional<BufferInfo>, (don't throw)
- Set usage as VMA_MEMORY_USAGE_AUTO instead of unknown

* VertexBuffer: use Context::createBuffer() in LOCAL mode
- This also remove the unneeded VMA_ALLOCATION_CREATE_MAPPED_BIT flag (a small boost in FPS remarked)
- VMA_ALLOCATION_CREATE_MAPPED_BIT: permanent mapping, but code is "mapping -> copy -> unmapping"

* GarbageCollector: add GarbageBuffer constructor with BufferInfo

* VertexBuffer: use Context::createBuffer() for DEVICE mode, use INDIRECT_EXECUTION for submit type

* TextureImage: remove usage of CreateBuffer()

* Shaders: add missing "readonly" decoration
- This mute validation error : "vertexPipelineStoresAndAtomics was not enabled."

* ObjSpriteBatches: avoid passing by requestGlobalTransform()

* UniformBuffer: apply Context::createBuffer()

* IndexBuffer: apply Context::createBuffer()

* remove deprecated

* Context: add createImage()

* vulkanGlobal: add ImageInfo, apply Context::createImage to TextureImage

* vulkanGlobal: move CreateImageView() to LogicalDevice
  • Loading branch information
JonathSpirit authored Dec 27, 2024
1 parent de3e50a commit e0b8518
Show file tree
Hide file tree
Showing 19 changed files with 368 additions and 425 deletions.
13 changes: 13 additions & 0 deletions includes/FastEngine/vulkan/C_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,19 @@ class FGE_API Context
*/
[[nodiscard]] VmaAllocator getAllocator() const;

[[nodiscard]] std::optional<BufferInfo> createBuffer(VkDeviceSize size,
VkBufferUsageFlags usage,
VmaAllocationCreateFlags flags,
VkMemoryPropertyFlags requiredProperties = 0) const;
[[nodiscard]] std::optional<ImageInfo> createImage(uint32_t width,
uint32_t height,
VkFormat format,
VkImageTiling tiling,
uint32_t mipLevels,
VkImageUsageFlags usage,
VmaAllocationCreateFlags flags,
VkMemoryPropertyFlags requiredProperties = 0) const;

/**
* \brief Push a graphics command buffer to a list
*
Expand Down
8 changes: 3 additions & 5 deletions includes/FastEngine/vulkan/C_garbageCollector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,14 @@ struct GarbageDescriptorSet
};
struct GarbageBuffer
{
constexpr GarbageBuffer(VkBuffer buffer, VmaAllocation bufferAllocation, VmaAllocator allocator) :
constexpr GarbageBuffer(BufferInfo bufferInfo, VmaAllocator allocator) :
_type(GarbageType::GARBAGE_VERTEX_BUFFER),
_buffer(buffer),
_bufferAllocation(bufferAllocation),
_bufferInfo(bufferInfo),
_allocator(allocator)
{}

GarbageType _type;
VkBuffer _buffer;
VmaAllocation _bufferAllocation;
BufferInfo _bufferInfo;
VmaAllocator _allocator;
};
struct GarbageGraphicPipeline
Expand Down
2 changes: 2 additions & 0 deletions includes/FastEngine/vulkan/C_logicalDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class FGE_API LogicalDevice
[[nodiscard]] VkQueue getPresentQueue() const;
[[nodiscard]] VkPhysicalDeviceFeatures getEnabledFeatures() const;

[[nodiscard]] VkImageView createImageView(VkImage image, VkFormat format, uint32_t mipLevels) const;

private:
VkDevice g_device;
VkQueue g_graphicQueue;
Expand Down
3 changes: 1 addition & 2 deletions includes/FastEngine/vulkan/C_textureImage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ class FGE_API TextureImage : public ContextAware
private:
void createTextureSampler(float mipLodBias, float mipLodMin, float mipLodMax);

VkImage g_textureImage;
VmaAllocation g_textureImageAllocation;
ImageInfo g_imageInfo;

VkImageView g_textureImageView;
VkSampler g_textureSampler;
Expand Down
5 changes: 2 additions & 3 deletions includes/FastEngine/vulkan/C_uniformBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ class FGE_API UniformBuffer : public ContextAware

private:
#ifndef FGE_DEF_SERVER
void createBuffer(VkDeviceSize bufferSize, VkBuffer& buffer, VmaAllocation& bufferAllocation);
[[nodiscard]] BufferInfo createBuffer(VkDeviceSize bufferSize) const;

VkBuffer g_uniformBuffer;
VmaAllocation g_uniformBufferAllocation;
BufferInfo g_uniformBufferInfo;
void* g_uniformBufferMapped;
VkDeviceSize g_bufferSize;
VkDeviceSize g_bufferCapacity;
Expand Down
12 changes: 4 additions & 8 deletions includes/FastEngine/vulkan/C_vertexBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,8 @@ class FGE_API VertexBuffer : public ContextAware

std::vector<Vertex> g_vertices;

mutable VkBuffer g_buffer;
mutable VkBuffer g_stagingBuffer;
mutable VmaAllocation g_bufferAllocation;
mutable VmaAllocation g_stagingBufferAllocation;
mutable BufferInfo g_bufferInfo;
mutable BufferInfo g_stagingBufferInfo;
mutable std::size_t g_bufferCapacity;

mutable bool g_needUpdate;
Expand Down Expand Up @@ -141,10 +139,8 @@ class FGE_API IndexBuffer : public ContextAware

std::vector<uint16_t> g_indices;

mutable VkBuffer g_buffer;
mutable VkBuffer g_stagingBuffer;
mutable VmaAllocation g_bufferAllocation;
mutable VmaAllocation g_stagingBufferAllocation;
mutable BufferInfo g_bufferInfo;
mutable BufferInfo g_stagingBufferInfo;
mutable std::size_t g_bufferCapacity;

mutable bool g_needUpdate;
Expand Down
57 changes: 32 additions & 25 deletions includes/FastEngine/vulkan/vulkanGlobal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,40 @@
namespace fge::vulkan
{

class LogicalDevice;
class PhysicalDevice;
class Context;

struct BufferInfo
{
VkBuffer _buffer{VK_NULL_HANDLE};
VmaAllocation _allocation{VK_NULL_HANDLE};

[[nodiscard]] inline constexpr bool valid() const
{
return this->_buffer != VK_NULL_HANDLE && this->_allocation != VK_NULL_HANDLE;
}
inline constexpr void clear()
{
this->_buffer = VK_NULL_HANDLE;
this->_allocation = VK_NULL_HANDLE;
}
};

struct ImageInfo
{
VkImage _image{VK_NULL_HANDLE};
VmaAllocation _allocation{VK_NULL_HANDLE};

[[nodiscard]] inline constexpr bool valid() const
{
return this->_image != VK_NULL_HANDLE && this->_allocation != VK_NULL_HANDLE;
}
inline constexpr void clear()
{
this->_image = VK_NULL_HANDLE;
this->_allocation = VK_NULL_HANDLE;
}
};

FGE_API extern std::vector<char const*> InstanceLayers;
FGE_API extern std::vector<char const*> DeviceExtensions;
FGE_API extern std::vector<char const*> InstanceExtensions;
Expand All @@ -51,29 +81,6 @@ FGE_API extern void SetActiveContext(Context& context);

FGE_API bool CheckInstanceLayerSupport(char const* layerName);

FGE_API void CreateBuffer(Context const& context,
VkDeviceSize size,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties,
VkBuffer& buffer,
VmaAllocation& allocation);

FGE_API void CreateImage(Context const& context,
uint32_t width,
uint32_t height,
VkFormat format,
VkImageTiling tiling,
VkImageUsageFlags usage,
VkMemoryPropertyFlags properties,
uint32_t mipLevels,
VkImage& image,
VmaAllocation& allocation);

FGE_API VkImageView CreateImageView(LogicalDevice const& logicalDevice,
VkImage image,
VkFormat format,
uint32_t mipLevels);

} // namespace fge::vulkan

#endif //_FGE_VULKAN_VULKANGLOBAL_HPP_INCLUDED
4 changes: 2 additions & 2 deletions resources/shaders/objShapeInstances_vertex.vert
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ struct TransformsData {
mat4 modelTransform;
mat4 viewTransform;
};
layout(set = 0, binding = 0) buffer GlobalTransformsData {
layout(set = 0, binding = 0) buffer readonly GlobalTransformsData {
TransformsData data[];
} globalTransforms;

struct InstanceData {
uvec4 color[2];
vec2 offset;
};
layout(set = 1, binding = 0) buffer BufferInstanceData {
layout(set = 1, binding = 0) buffer readonly BufferInstanceData {
InstanceData data[];
} instances;

Expand Down
2 changes: 1 addition & 1 deletion resources/shaders/objSpriteBatches_vertex.vert
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct InstanceData {
uint textureIndex;
};

layout(set = 0, binding = 0) buffer BufferInstanceData {
layout(set = 0, binding = 0) buffer readonly BufferInstanceData {
InstanceData data[];
} instances;

Expand Down
2 changes: 1 addition & 1 deletion sources/graphic/shaderResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct InstanceData {
mat4 viewTransform;
};
layout(set = 0, binding = 0) buffer BufferInstanceData {
layout(set = 0, binding = 0) buffer readonly BufferInstanceData {
InstanceData data[];
} instances;
Expand Down
14 changes: 10 additions & 4 deletions sources/object/C_objSpriteBatches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,17 +201,23 @@ FGE_OBJ_DRAW_BODY(ObjSpriteBatches)
auto* view = static_cast<InstanceDataBuffer*>(this->g_instancesTransform.getBufferMapped());
view->_transform = target.getView().getProjection() * target.getView().getTransform();

auto globalTransformIndex = target.requestGlobalTransform(*this, states._resTransform);
fge::TransformUboData const* parentTransform = target.getContext().getGlobalTransform(globalTransformIndex);
fge::TransformUboData const* parentTransform = target.getGlobalTransform(states._resTransform);

//Update all model matrices
for (std::size_t i = 0; i < this->g_instancesData.size(); ++i)
{
auto* instance = static_cast<InstanceDataBuffer*>(this->g_instancesTransform.getBufferMapped()) + i + 1;

instance->_textureIndex = this->g_instancesData[i]._textureIndex;
instance->_transform =
parentTransform->_modelTransform * this->g_instancesData[i]._transformable.getTransform();
if (parentTransform != nullptr)
{
instance->_transform = parentTransform->_modelTransform * this->getTransform() *
this->g_instancesData[i]._transformable.getTransform();
}
else
{
instance->_transform = this->getTransform() * this->g_instancesData[i]._transformable.getTransform();
}
}

auto copyStates = states.copy();
Expand Down
68 changes: 68 additions & 0 deletions sources/vulkan/C_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,74 @@ VmaAllocator Context::getAllocator() const
{
return this->g_allocator;
}
std::optional<BufferInfo> Context::createBuffer(VkDeviceSize size,
VkBufferUsageFlags usage,
VmaAllocationCreateFlags flags,
VkMemoryPropertyFlags requiredProperties) const
{
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

VmaAllocationCreateInfo allocationCreateInfo{};
allocationCreateInfo.flags = flags;
allocationCreateInfo.requiredFlags = requiredProperties;
allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;

BufferInfo info{};
auto result = vmaCreateBuffer(this->getAllocator(), &bufferInfo, &allocationCreateInfo, &info._buffer,
&info._allocation, nullptr);
if (result != VK_SUCCESS)
{
return std::nullopt;
}
return info;
}
std::optional<ImageInfo> Context::createImage(uint32_t width,
uint32_t height,
VkFormat format,
VkImageTiling tiling,
uint32_t mipLevels,
VkImageUsageFlags usage,
VmaAllocationCreateFlags flags,
VkMemoryPropertyFlags requiredProperties) const
{
VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = width;
imageInfo.extent.height = height;
imageInfo.extent.depth = 1;
imageInfo.mipLevels = mipLevels;
imageInfo.arrayLayers = 1;

imageInfo.format = format;
imageInfo.tiling = tiling;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = usage;

imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.flags = 0; // Optional

imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

VmaAllocationCreateInfo allocationCreateInfo{};
allocationCreateInfo.flags = flags;
allocationCreateInfo.requiredFlags = requiredProperties;
allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;

ImageInfo info{};
auto result = vmaCreateImage(this->getAllocator(), &imageInfo, &allocationCreateInfo, &info._image,
&info._allocation, nullptr);

if (result != VK_SUCCESS)
{
return std::nullopt;
}
return info;
}

void Context::pushGraphicsCommandBuffer(VkCommandBuffer commandBuffer) const
{
Expand Down
4 changes: 2 additions & 2 deletions sources/vulkan/C_garbageCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ Garbage::~Garbage()
&this->g_data._descriptorSet._descriptorSet);
break;
case GarbageType::GARBAGE_VERTEX_BUFFER:
vmaDestroyBuffer(this->g_data._buffer._allocator, this->g_data._buffer._buffer,
this->g_data._buffer._bufferAllocation);
vmaDestroyBuffer(this->g_data._buffer._allocator, this->g_data._buffer._bufferInfo._buffer,
this->g_data._buffer._bufferInfo._allocation);
break;
case GarbageType::GARBAGE_GRAPHIC_PIPELINE:
vkDestroyPipeline(this->g_data._graphicPipeline._logicalDevice, this->g_data._graphicPipeline._pipeline,
Expand Down
21 changes: 21 additions & 0 deletions sources/vulkan/C_logicalDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,25 @@ VkPhysicalDeviceFeatures LogicalDevice::getEnabledFeatures() const
return this->g_enabledFeatures;
}

VkImageView LogicalDevice::createImageView(VkImage image, VkFormat format, uint32_t mipLevels) const
{
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = format;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = mipLevels;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;

VkImageView imageView = VK_NULL_HANDLE;
if (vkCreateImageView(this->g_device, &viewInfo, nullptr, &imageView) != VK_SUCCESS)
{
return VK_NULL_HANDLE;
}
return imageView;
}

} // namespace fge::vulkan
2 changes: 1 addition & 1 deletion sources/vulkan/C_swapChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void SwapChain::createImageViews()
for (size_t i = 0; i < this->g_swapChainImages.size(); i++)
{
this->g_swapChainImageViews[i] =
CreateImageView(*this->g_logicalDevice, this->g_swapChainImages[i], this->g_swapChainImageFormat, 1);
this->g_logicalDevice->createImageView(this->g_swapChainImages[i], this->g_swapChainImageFormat, 1);
}
}

Expand Down
Loading

0 comments on commit e0b8518

Please sign in to comment.