diff --git a/include/boo/graphicsdev/IGraphicsDataFactory.hpp b/include/boo/graphicsdev/IGraphicsDataFactory.hpp index a06c1f1..734dc2b 100644 --- a/include/boo/graphicsdev/IGraphicsDataFactory.hpp +++ b/include/boo/graphicsdev/IGraphicsDataFactory.hpp @@ -277,6 +277,10 @@ struct IGraphicsDataFactory { }; virtual void commitTransaction(const std::function& __BooTraceArgs) = 0; + virtual void lazyCommitTransaction(const std::function& f __BooTraceArgs) { + commitTransaction(f __BooTraceArgsUse); + } + virtual void commitPendingTransaction() {} virtual ObjToken newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs) = 0; virtual void setDisplayGamma(float gamma) = 0; virtual bool isTessellationSupported(uint32_t& maxPatchSizeOut) = 0; diff --git a/include/boo/graphicsdev/Vulkan.hpp b/include/boo/graphicsdev/Vulkan.hpp index d9fd69c..841fab2 100644 --- a/include/boo/graphicsdev/Vulkan.hpp +++ b/include/boo/graphicsdev/Vulkan.hpp @@ -130,10 +130,10 @@ public: friend class VulkanDataFactoryImpl; VulkanDataFactory& m_parent; boo::ObjToken m_data; - Context(VulkanDataFactory& parent __BooTraceArgs); - ~Context(); public: + Context(VulkanDataFactory& parent __BooTraceArgs); + ~Context(); Platform platform() const { return Platform::Vulkan; } const char* platformName() const { return "Vulkan"; } diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 9279491..11518d1 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,8 @@ class VulkanDataFactoryImpl final : public VulkanDataFactory, public GraphicsDat VulkanDescriptorPool* m_descPoolHead = nullptr; PipelineCompileQueue m_pipelineQueue; + std::optional m_lazyContext; + void flushContext(Context&); float m_gamma = 1.f; ObjToken m_gammaShader; @@ -126,21 +129,23 @@ public: VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx); ~VulkanDataFactoryImpl() { assert(m_descPoolHead == nullptr && "Dangling descriptor pools detected"); } - Platform platform() const { return Platform::Vulkan; } - const char* platformName() const { return "Vulkan"; } + Platform platform() const override { return Platform::Vulkan; } + const char* platformName() const override { return "Vulkan"; } boo::ObjToken allocateDescriptorSets(VkDescriptorSet* out); - void commitTransaction(const FactoryCommitFunc& __BooTraceArgs); + void commitTransaction(const FactoryCommitFunc& __BooTraceArgs) override; + void lazyCommitTransaction(const FactoryCommitFunc& __BooTraceArgs) override; + void commitPendingTransaction() override; - boo::ObjToken newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs); + boo::ObjToken newPoolBuffer(BufferUse use, size_t stride, size_t count __BooTraceArgs) override; - void setDisplayGamma(float gamma) { + void setDisplayGamma(float gamma) override { m_gamma = gamma; UpdateGammaLUT(m_gammaLUT.get(), gamma); } - bool isTessellationSupported(uint32_t& maxPatchSizeOut) { + bool isTessellationSupported(uint32_t& maxPatchSizeOut) override { maxPatchSizeOut = 0; if (!m_ctx->m_features.tessellationShader) return false; @@ -148,11 +153,11 @@ public: return true; } - void waitUntilShadersReady() { + void waitUntilShadersReady() override { m_pipelineQueue.waitUntilReady(); } - bool areShadersReady() { + bool areShadersReady() override { return m_pipelineQueue.isReady(); } }; @@ -3791,10 +3796,33 @@ boo::ObjToken VulkanDataFactory::Context::newShaderDataBindi void VulkanDataFactoryImpl::commitTransaction( const std::function& trans __BooTraceArgs) { - Context ctx(*this __BooTraceArgsUse); - if (!trans(ctx)) - return; + Context ctx(*this __BooTraceArgsUse); + if (!trans(ctx)) { + return; + } + commitPendingTransaction(); + flushContext(ctx); +} + +void VulkanDataFactoryImpl::lazyCommitTransaction( + const std::function& trans __BooTraceArgs) { + + if (!m_lazyContext) { + m_lazyContext.emplace(*this __BooTraceArgsUse); + } + trans(*m_lazyContext); +} + +void VulkanDataFactoryImpl::commitPendingTransaction() { + if (m_lazyContext) { + flushContext(*m_lazyContext); + m_lazyContext.reset(); + } +} + +void VulkanDataFactoryImpl::flushContext(Context& ctx) { + OPTICK_EVENT(); VulkanData* data = ctx.m_data.cast(); /* Start asynchronous shader compiles */