Skip to content

Commit

Permalink
adding a pool for command pools and descriptor pools
Browse files Browse the repository at this point in the history
  • Loading branch information
beaumanvienna committed Sep 7, 2024
1 parent 83ab5cf commit 57b3133
Show file tree
Hide file tree
Showing 20 changed files with 1,423 additions and 1,132 deletions.
56 changes: 10 additions & 46 deletions application/lucre/gameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,15 +256,8 @@ namespace LucreApp
GetScene(state)->Start();
SetLoaded(state);
};
if (Engine::m_Engine->MultiThreadingSupport())
{
std::thread loadMainSceneThread(lambda);
loadMainSceneThread.detach();
}
else
{
lambda();
}
ThreadPool& threadPool = Engine::m_Engine->m_PoolPrimary;
std::future<void> future = threadPool.SubmitTask(lambda);
break;
}
case State::BEACH:
Expand All @@ -278,18 +271,10 @@ namespace LucreApp
GetScene(state)->Start();
SetLoaded(state);
};
if (Engine::m_Engine->MultiThreadingSupport())
{
std::thread loadBeachSceneThread(lambda);
loadBeachSceneThread.detach();
}
else
{
lambda();
}
ThreadPool& threadPool = Engine::m_Engine->m_PoolPrimary;
std::future<void> future = threadPool.SubmitTask(lambda);
break;
}

case State::NIGHT:
{
auto lambda = [this, state]()
Expand All @@ -301,15 +286,8 @@ namespace LucreApp
GetScene(state)->Start();
SetLoaded(state);
};
if (Engine::m_Engine->MultiThreadingSupport())
{
std::thread loadNightSceneThread(lambda);
loadNightSceneThread.detach();
}
else
{
lambda();
}
ThreadPool& threadPool = Engine::m_Engine->m_PoolPrimary;
std::future<void> future = threadPool.SubmitTask(lambda);
break;
}
case State::DESSERT:
Expand All @@ -323,15 +301,8 @@ namespace LucreApp
GetScene(state)->Start();
SetLoaded(state);
};
if (Engine::m_Engine->MultiThreadingSupport())
{
std::thread loadDessertSceneThread(lambda);
loadDessertSceneThread.detach();
}
else
{
lambda();
}
ThreadPool& threadPool = Engine::m_Engine->m_PoolPrimary;
std::future<void> future = threadPool.SubmitTask(lambda);
break;
}
case State::TERRAIN:
Expand All @@ -346,15 +317,8 @@ namespace LucreApp
GetScene(state)->Start();
SetLoaded(state);
};
if (Engine::m_Engine->MultiThreadingSupport())
{
ThreadPool& threadPool = Engine::m_Engine->m_Pool;
std::future<void> future = threadPool.SubmitTask(lambda);
}
else
{
lambda();
}
ThreadPool& threadPool = Engine::m_Engine->m_PoolPrimary;
std::future<void> future = threadPool.SubmitTask(lambda);
break;
}
case State::CUTSCENE:
Expand Down
1 change: 1 addition & 0 deletions engine/auxiliary/threadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ namespace GfxRenderEngine
ThreadPool::ThreadPool(const BS::concurrency_t numThreads) : m_Pool{numThreads} {}

void ThreadPool::Wait() { m_Pool.wait(); }
[[nodiscard]] BS::concurrency_t ThreadPool::Size() const { return m_Pool.get_thread_count(); }

} // namespace GfxRenderEngine
2 changes: 2 additions & 0 deletions engine/auxiliary/threadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ namespace GfxRenderEngine
ThreadPool(const BS::concurrency_t numThreads);

void Wait();
[[nodiscard]] BS::concurrency_t Size() const;

template <typename FunctionType, typename ReturnType = std::invoke_result_t<std::decay_t<FunctionType>>>
[[nodiscard]] std::future<ReturnType> SubmitTask(FunctionType&& task)
{
std::lock_guard<std::mutex> guard(m_Mutex);
return m_Pool.submit_task(task);
}
[[nodiscard]] std::vector<std::thread::id> GetThreadIDs() const { return m_Pool.get_thread_ids(); }

private:
BS::thread_pool m_Pool;
Expand Down
2 changes: 1 addition & 1 deletion engine/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace GfxRenderEngine
return false;
}
m_Window->SetEventCallback([this](Event& event) { return this->OnEvent(event); });
m_GraphicsContext = GraphicsContext::Create(m_Window.get());
m_GraphicsContext = GraphicsContext::Create(m_Window.get(), m_PoolPrimary, m_PoolSecondary);

// init audio
m_Audio = Audio::Create();
Expand Down
3 changes: 2 additions & 1 deletion engine/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ namespace GfxRenderEngine
static Engine* m_Engine;
static SettingsManager m_SettingsManager;
CoreSettings m_CoreSettings{&m_SettingsManager};
ThreadPool m_Pool;
ThreadPool m_PoolPrimary;
ThreadPool m_PoolSecondary;

private:
static void SignalHandler(int signal);
Expand Down
12 changes: 7 additions & 5 deletions engine/platform/Vulkan/VKdescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ namespace GfxRenderEngine
}

// *************** Descriptor Pool Builder *********************
VK_DescriptorPool::Builder::Builder(VkDevice device) : m_Device{device} {}

VK_DescriptorPool::Builder& VK_DescriptorPool::Builder::AddPoolSize(VkDescriptorType descriptorType, uint count)
{
Expand All @@ -102,13 +103,14 @@ namespace GfxRenderEngine

std::unique_ptr<VK_DescriptorPool> VK_DescriptorPool::Builder::Build() const
{
return std::make_unique<VK_DescriptorPool>(m_MaxSets, m_PoolFlags, m_PoolSizes);
return std::make_unique<VK_DescriptorPool>(m_Device, m_MaxSets, m_PoolFlags, m_PoolSizes);
}

// *************** Descriptor Pool *********************

VK_DescriptorPool::VK_DescriptorPool(uint maxSets, VkDescriptorPoolCreateFlags poolFlags,
VK_DescriptorPool::VK_DescriptorPool(VkDevice device, uint maxSets, VkDescriptorPoolCreateFlags poolFlags,
const std::vector<VkDescriptorPoolSize>& poolSizes)
: m_Device{device}
{
VkDescriptorPoolCreateInfo descriptorPoolInfo{};
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
Expand All @@ -117,7 +119,7 @@ namespace GfxRenderEngine
descriptorPoolInfo.maxSets = maxSets;
descriptorPoolInfo.flags = poolFlags;

auto result = vkCreateDescriptorPool(VK_Core::m_Device->Device(), &descriptorPoolInfo, nullptr, &m_DescriptorPool);
auto result = vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &m_DescriptorPool);
if (result != VK_SUCCESS)
{
LOG_CORE_CRITICAL("failed to create descriptor pool!");
Expand All @@ -126,8 +128,8 @@ namespace GfxRenderEngine

VK_DescriptorPool::~VK_DescriptorPool()
{
vkDeviceWaitIdle(VK_Core::m_Device->Device());
vkDestroyDescriptorPool(VK_Core::m_Device->Device(), m_DescriptorPool, nullptr);
vkDeviceWaitIdle(m_Device);
vkDestroyDescriptorPool(m_Device, m_DescriptorPool, nullptr);
}

bool VK_DescriptorPool::AllocateDescriptorSet(const VkDescriptorSetLayout descriptorSetLayout,
Expand Down
8 changes: 4 additions & 4 deletions engine/platform/Vulkan/VKdescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@

#include "engine.h"

#include "VKdevice.h"

namespace GfxRenderEngine
{
class VK_DescriptorSetLayout
Expand Down Expand Up @@ -90,22 +88,23 @@ namespace GfxRenderEngine
{

public:
Builder() {}
Builder(VkDevice device);

Builder& AddPoolSize(VkDescriptorType descriptorType, uint count);
Builder& SetPoolFlags(VkDescriptorPoolCreateFlags flags);
Builder& SetMaxSets(uint count);
std::unique_ptr<VK_DescriptorPool> Build() const;

private:
VkDevice m_Device;
std::vector<VkDescriptorPoolSize> m_PoolSizes;

uint m_MaxSets = 1000;
VkDescriptorPoolCreateFlags m_PoolFlags = 0;
};

public:
VK_DescriptorPool(uint maxSets, VkDescriptorPoolCreateFlags poolFlags,
VK_DescriptorPool(VkDevice device, uint maxSets, VkDescriptorPoolCreateFlags poolFlags,
const std::vector<VkDescriptorPoolSize>& poolSizes);
~VK_DescriptorPool();

Expand All @@ -117,6 +116,7 @@ namespace GfxRenderEngine
void ResetPool();

private:
VkDevice m_Device;
VkDescriptorPool m_DescriptorPool;

friend class VK_DescriptorWriter;
Expand Down
40 changes: 7 additions & 33 deletions engine/platform/Vulkan/VKdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,21 @@ namespace GfxRenderEngine
}
}

VK_Device::VK_Device(VK_Window* window) : m_Window{window}
VK_Device::VK_Device(VK_Window* window, ThreadPool& threadPoolPrimary, ThreadPool& threadPoolSecondary)
: m_Window{window}
{
CreateInstance();
SetupDebugMessenger();
CreateSurface();
PickPhysicalDevice();
CreateLogicalDevice();
CreateCommandPool();
m_LoadPool = std::make_shared<VK_Pool>(m_Device, m_QueueFamilyIndices, threadPoolPrimary, threadPoolSecondary);
}

VK_Device::~VK_Device()
{
vkDestroyCommandPool(m_Device, m_GraphicsCommandPool, nullptr);
vkDestroyCommandPool(m_Device, m_LoadCommandPool, nullptr);
vkDestroyDevice(m_Device, nullptr);

if (m_EnableValidationLayers)
Expand Down Expand Up @@ -302,13 +303,6 @@ namespace GfxRenderEngine
{
LOG_CORE_CRITICAL("failed to create graphics command pool!");
}

poolInfo.queueFamilyIndex = m_QueueFamilyIndices.m_TransferFamily;

if (vkCreateCommandPool(m_Device, &poolInfo, nullptr, &m_LoadCommandPool) != VK_SUCCESS)
{
LOG_CORE_CRITICAL("failed to create load command pool!");
}
}

void VK_Device::CreateSurface() { m_Window->CreateWindowSurface(m_Instance, &m_Surface); }
Expand Down Expand Up @@ -713,19 +707,7 @@ namespace GfxRenderEngine
VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
// single time commands are transfer commands
// however, commands like vkCmdBlitImage require graphics support on transfer queues
// --> if the transfer queue is of the same queue family as the graphics queue,
// the load command pool can be used, multithreading enabled, "type" be ignored
// otherwise the graphics queue has to be used, if requested by "type"
if (m_TransferQueueSupportsGraphics)
{
allocInfo.commandPool = m_LoadCommandPool;
}
else
{
allocInfo.commandPool = type == QueueTypes::TRANSFER ? m_LoadCommandPool : m_GraphicsCommandPool;
}
allocInfo.commandPool = m_LoadPool->GetCommandPool();
allocInfo.commandBufferCount = 1;

VkCommandBuffer commandBuffer;
Expand All @@ -742,27 +724,19 @@ namespace GfxRenderEngine

void VK_Device::EndSingleTimeCommands(VkCommandBuffer commandBuffer, QueueTypes type)
{
ZoneScopedN("EndSingleTimeCommands");
vkEndCommandBuffer(commandBuffer);

VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
std::lock_guard<std::mutex> guard(m_QueueAccessMutex);

// see BeginSingleTimeCommands
if ((type == QueueTypes::TRANSFER) || m_TransferQueueSupportsGraphics)
{
ZoneScopedN("EndSingleTimeCommands");
vkQueueSubmit(TransferQueue(), 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(TransferQueue());
vkFreeCommandBuffers(m_Device, m_LoadCommandPool, 1, &commandBuffer);
}
else
{
ZoneScopedN("EndSingleTimeCommands");
vkQueueSubmit(GraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(GraphicsQueue());
vkFreeCommandBuffers(m_Device, m_GraphicsCommandPool, 1, &commandBuffer);
vkFreeCommandBuffers(m_Device, m_LoadPool->GetCommandPool(), 1, &commandBuffer);
}
}

Expand Down
39 changes: 8 additions & 31 deletions engine/platform/Vulkan/VKdevice.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Engine Copyright (c) 2022 Engine Development Team
/* Engine Copyright (c) 2024 Engine Development Team
https://github.com/beaumanvienna/vulkan
Permission is hereby granted, free of charge, to any person
Expand All @@ -22,38 +22,15 @@

#pragma once

#include <string>
#include <vector>
#include <vulkan/vulkan.h>

#include "VKpool.h"
#include "VKdeviceStructs.h"
#include "auxiliary/threadPool.h"

namespace GfxRenderEngine
{
struct SwapChainSupportDetails
{
VkSurfaceCapabilitiesKHR capabilities;
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> presentModes;
};

enum QueueTypes
{
GRAPHICS = 0,
PRESENT,
TRANSFER,
NUMBER_OF_QUEUE_TYPES
};

struct QueueFamilyIndices
{
int m_GraphicsFamily = -1;
int m_PresentFamily = -1;
int m_TransferFamily = -1;
int m_NumberOfQueues = 0;
std::vector<int> m_UniqueFamilyIndices;
int m_QueueIndices[QueueTypes::NUMBER_OF_QUEUE_TYPES] = {};
bool IsComplete() { return (m_GraphicsFamily >= 0) && (m_PresentFamily >= 0) && (m_TransferFamily >= 0); }
};

class VK_Window;

class VK_Device
Expand All @@ -66,7 +43,7 @@ namespace GfxRenderEngine
const bool m_EnableValidationLayers = true;
#endif

VK_Device(VK_Window* window);
VK_Device(VK_Window* window, ThreadPool& threadPoolPrimary, ThreadPool& threadPoolSecondary);
~VK_Device();

// Not copyable or movable
Expand Down Expand Up @@ -148,8 +125,8 @@ namespace GfxRenderEngine
VkPhysicalDevice m_PhysicalDevice = VK_NULL_HANDLE;
VK_Window* m_Window;
VkCommandPool m_GraphicsCommandPool;
VkCommandPool m_LoadCommandPool;

std::shared_ptr<VK_Pool> m_LoadPool;
std::mutex m_QueueAccessMutex;
VkDevice m_Device;
VkSurfaceKHR m_Surface;

Expand Down
Loading

0 comments on commit 57b3133

Please sign in to comment.