Allocate command buffers from pools

This commit is contained in:
Jérôme Leclercq
2020-08-27 18:31:26 +02:00
parent cbdac32f5f
commit 7c9dcdfbe4
18 changed files with 333 additions and 23 deletions

View File

@@ -22,12 +22,14 @@
namespace Nz
{
class OpenGLCommandPool;
class OpenGLFramebuffer;
class NAZARA_OPENGLRENDERER_API OpenGLCommandBuffer final : public CommandBuffer
{
public:
OpenGLCommandBuffer() = default;
inline OpenGLCommandBuffer();
inline OpenGLCommandBuffer(OpenGLCommandPool& owner, std::size_t poolIndex, std::size_t bindingIndex);
OpenGLCommandBuffer(const OpenGLCommandBuffer&) = delete;
OpenGLCommandBuffer(OpenGLCommandBuffer&&) noexcept = default;
~OpenGLCommandBuffer() = default;
@@ -49,6 +51,10 @@ namespace Nz
void Execute();
inline std::size_t GetBindingIndex() const;
inline std::size_t GetPoolIndex() const;
inline const OpenGLCommandPool& GetOwner() const;
inline void SetFramebuffer(const OpenGLFramebuffer& framebuffer, const RenderPass& renderPass, std::initializer_list<CommandBufferBuilder::ClearValues> clearValues);
inline void SetScissor(Nz::Recti scissorRegion);
inline void SetViewport(Nz::Recti viewportRegion);
@@ -60,6 +66,7 @@ namespace Nz
struct DrawStates;
void ApplyStates(const GL::Context& context, const DrawStates& states);
void Release();
struct BeginDebugRegionData
{
@@ -139,7 +146,10 @@ namespace Nz
>;
DrawStates m_currentStates;
std::size_t m_bindingIndex;
std::size_t m_poolIndex;
std::vector<CommandData> m_commands;
OpenGLCommandPool* m_owner;
};
}

View File

@@ -4,11 +4,24 @@
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLFramebuffer.hpp>
#include <cassert>
#include <stdexcept>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
{
inline OpenGLCommandBuffer::OpenGLCommandBuffer() :
m_owner(nullptr)
{
}
inline OpenGLCommandBuffer::OpenGLCommandBuffer(OpenGLCommandPool& owner, std::size_t poolIndex, std::size_t bindingIndex) :
m_bindingIndex(bindingIndex),
m_poolIndex(poolIndex),
m_owner(&owner)
{
}
inline void OpenGLCommandBuffer::BeginDebugRegion(const std::string_view& regionName, const Nz::Color& color)
{
BeginDebugRegionData beginDebugRegion;
@@ -104,6 +117,22 @@ namespace Nz
m_commands.emplace_back(EndDebugRegionData{});
}
inline std::size_t Nz::OpenGLCommandBuffer::GetBindingIndex() const
{
return m_bindingIndex;
}
inline std::size_t Nz::OpenGLCommandBuffer::GetPoolIndex() const
{
return m_poolIndex;
}
inline const OpenGLCommandPool& OpenGLCommandBuffer::GetOwner() const
{
assert(m_owner);
return *m_owner;
}
inline void OpenGLCommandBuffer::SetFramebuffer(const OpenGLFramebuffer& framebuffer, const RenderPass& /*renderPass*/, std::initializer_list<CommandBufferBuilder::ClearValues> clearValues)
{
SetFrameBufferData setFramebuffer;

View File

@@ -8,23 +8,45 @@
#define NAZARA_OPENGLRENDERER_OPENGLCOMMANDPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Renderer/CommandPool.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
namespace Nz
{
class NAZARA_OPENGLRENDERER_API OpenGLCommandPool final : public CommandPool
{
friend OpenGLCommandBuffer;
public:
OpenGLCommandPool() = default;
OpenGLCommandPool(const OpenGLCommandPool&) = delete;
OpenGLCommandPool(OpenGLCommandPool&&) noexcept = default;
~OpenGLCommandPool() = default;
std::unique_ptr<CommandBuffer> BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) override;
CommandBufferPtr BuildCommandBuffer(const std::function<void(CommandBufferBuilder& builder)>& callback) override;
OpenGLCommandPool& operator=(const OpenGLCommandPool&) = delete;
OpenGLCommandPool& operator=(OpenGLCommandPool&&) = delete;
private:
struct CommandPool;
CommandPool& AllocatePool();
CommandBufferPtr AllocateFromPool(std::size_t poolIndex);
void Release(CommandBuffer& commandBuffer);
inline void TryToShrink();
struct CommandPool
{
using BindingStorage = std::aligned_storage_t<sizeof(OpenGLCommandBuffer), alignof(OpenGLCommandBuffer)>;
Bitset<UInt64> freeCommands;
std::unique_ptr<BindingStorage[]> storage;
};
std::vector<CommandPool> m_commandPools;
};
}

View File

@@ -8,6 +8,22 @@
namespace Nz
{
inline void OpenGLCommandPool::TryToShrink()
{
std::size_t poolCount = m_commandPools.size();
if (poolCount >= 2 && m_commandPools.back().freeCommands.TestAll())
{
for (std::size_t i = poolCount - 1; i > 0; --i)
{
if (!m_commandPools[i].freeCommands.TestAll())
break;
poolCount--;
}
m_commandPools.resize(poolCount);
}
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@@ -17,6 +17,7 @@ namespace Nz
case PixelFormat_A8: return GLTextureFormat { GL_R8, GL_RED, GL_UNSIGNED_BYTE, GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
case PixelFormat_RGB8: return GLTextureFormat { GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ZERO };
case PixelFormat_RGBA8: return GLTextureFormat { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
default: break;
}
NazaraError("Unhandled PixelFormat 0x" + String::Number(UnderlyingCast(pixelFormat), 16));