From eaff1ba744669fb8e0d4511d1e920ff4056c4dac Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 20 May 2018 12:37:26 -1000 Subject: [PATCH] Vulkan backend fixes --- include/boo/graphicsdev/Vulkan.hpp | 3 ++ lib/graphicsdev/Vulkan.cpp | 45 ++++++++++++++++++++++-------- lib/x11/ApplicationXlib.hpp | 5 ++++ lib/x11/WindowXlib.cpp | 13 ++++++--- 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/include/boo/graphicsdev/Vulkan.hpp b/include/boo/graphicsdev/Vulkan.hpp index 7a560a0..7e93a10 100644 --- a/include/boo/graphicsdev/Vulkan.hpp +++ b/include/boo/graphicsdev/Vulkan.hpp @@ -62,11 +62,14 @@ struct VulkanContext VkFramebuffer m_framebuffer = VK_NULL_HANDLE; VkRenderPassBeginInfo m_passBeginInfo = {}; void setImage(VulkanContext* ctx, VkImage image, uint32_t width, uint32_t height); + void destroy(VkDevice dev); }; std::vector m_bufs; uint32_t m_backBuf = 0; void destroy(VkDevice dev) { + for (Buffer& buf : m_bufs) + buf.destroy(dev); m_bufs.clear(); if (m_swapChain) { diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 84b6172..9773298 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -78,6 +78,7 @@ class VulkanDataFactoryImpl : public VulkanDataFactory, public GraphicsDataFacto IGraphicsContext* m_parent; VulkanContext* m_ctx; std::unordered_map> m_sharedShaders; + std::unordered_map m_sourceToBinary; std::vector m_texUnis; float m_gamma = 1.f; @@ -117,8 +118,16 @@ class VulkanDataFactoryImpl : public VulkanDataFactory, public GraphicsDataFacto }); } + void DestroyGammaResources() + { + m_gammaBinding.reset(); + m_gammaVFMT.reset(); + m_gammaVBO.reset(); + m_gammaLUT.reset(); + m_gammaShader.reset(); + } + public: - std::unordered_map m_sourceToBinary; VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx); Platform platform() const {return Platform::Vulkan;} @@ -141,6 +150,9 @@ public: if (gamma != 1.f) UpdateGammaLUT(m_gammaLUT.get(), gamma); } + + uint64_t CompileVert(std::vector& out, const char* vertSource, uint64_t srcKey); + uint64_t CompileFrag(std::vector& out, const char* fragSource, uint64_t srcKey); }; static inline void ThrowIfFailed(VkResult res) @@ -605,6 +617,14 @@ void VulkanContext::Window::SwapChain::Buffer::setImage m_passBeginInfo.pClearValues = nullptr; } +void VulkanContext::Window::SwapChain::Buffer::destroy(VkDevice dev) +{ + if (m_colorView) + vk::DestroyImageView(dev, m_colorView, nullptr); + if (m_framebuffer) + vk::DestroyFramebuffer(dev, m_framebuffer, nullptr); +} + void VulkanContext::initSwapChain(VulkanContext::Window& windowCtx, VkSurfaceKHR surface, VkFormat format, VkColorSpaceKHR colorspace) { @@ -2852,6 +2872,11 @@ struct VulkanCommandQueue : IGraphicsCommandQueue { m_running = false; vk::WaitForFences(m_ctx->m_dev, 1, &m_drawCompleteFence, VK_FALSE, -1); + static_cast(m_parent->getDataFactory())->DestroyGammaResources(); + m_drawResTokens[0].clear(); + m_drawResTokens[1].clear(); + m_boundTarget.reset(); + m_resolveDispSource.reset(); } ~VulkanCommandQueue() @@ -3527,8 +3552,7 @@ void VulkanTextureD::unmap() VulkanDataFactoryImpl::VulkanDataFactoryImpl(IGraphicsContext* parent, VulkanContext* ctx) : m_parent(parent), m_ctx(ctx) {} -static uint64_t CompileVert(std::vector& out, const char* vertSource, uint64_t srcKey, - VulkanDataFactoryImpl& factory) +uint64_t VulkanDataFactoryImpl::CompileVert(std::vector& out, const char* vertSource, uint64_t srcKey) { const EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules); glslang::TShader vs(EShLangVertex); @@ -3552,12 +3576,11 @@ static uint64_t CompileVert(std::vector& out, const char* vertSour XXH64_reset(&hashState, 0); XXH64_update(&hashState, out.data(), out.size() * sizeof(unsigned int)); uint64_t binKey = XXH64_digest(&hashState); - factory.m_sourceToBinary[srcKey] = binKey; + m_sourceToBinary[srcKey] = binKey; return binKey; } -static uint64_t CompileFrag(std::vector& out, const char* fragSource, uint64_t srcKey, - VulkanDataFactoryImpl& factory) +uint64_t VulkanDataFactoryImpl::CompileFrag(std::vector& out, const char* fragSource, uint64_t srcKey) { const EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules); glslang::TShader fs(EShLangFragment); @@ -3581,7 +3604,7 @@ static uint64_t CompileFrag(std::vector& out, const char* fragSour XXH64_reset(&hashState, 0); XXH64_update(&hashState, out.data(), out.size() * sizeof(unsigned int)); uint64_t binKey = XXH64_digest(&hashState); - factory.m_sourceToBinary[srcKey] = binKey; + m_sourceToBinary[srcKey] = binKey; return binKey; } @@ -3628,10 +3651,10 @@ boo::ObjToken VulkanDataFactory::Context::newShaderPipeline } if (vertBlobOut && vertBlobOut->empty()) - binHashes[0] = CompileVert(*vertBlobOut, vertSource, srcHashes[0], factory); + binHashes[0] = factory.CompileVert(*vertBlobOut, vertSource, srcHashes[0]); if (fragBlobOut && fragBlobOut->empty()) - binHashes[1] = CompileFrag(*fragBlobOut, fragSource, srcHashes[1], factory); + binHashes[1] = factory.CompileFrag(*fragBlobOut, fragSource, srcHashes[1]); VkShaderModuleCreateInfo smCreateInfo = {}; smCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; @@ -3657,7 +3680,7 @@ boo::ObjToken VulkanDataFactory::Context::newShaderPipeline else { useVertBlob = &vertBlob; - binHashes[0] = CompileVert(vertBlob, vertSource, srcHashes[0], factory); + binHashes[0] = factory.CompileVert(vertBlob, vertSource, srcHashes[0]); } VkShaderModule vertModule; @@ -3687,7 +3710,7 @@ boo::ObjToken VulkanDataFactory::Context::newShaderPipeline else { useFragBlob = &fragBlob; - binHashes[1] = CompileFrag(fragBlob, fragSource, srcHashes[1], factory); + binHashes[1] = factory.CompileFrag(fragBlob, fragSource, srcHashes[1]); } VkShaderModule fragModule; diff --git a/lib/x11/ApplicationXlib.hpp b/lib/x11/ApplicationXlib.hpp index 55f2f89..51ac368 100644 --- a/lib/x11/ApplicationXlib.hpp +++ b/lib/x11/ApplicationXlib.hpp @@ -258,6 +258,11 @@ public: tryVulkan = false; break; } + if (!arg.compare("--vulkan")) + { + tryVulkan = true; + break; + } } if (tryVulkan) diff --git a/lib/x11/WindowXlib.cpp b/lib/x11/WindowXlib.cpp index a5dab6d..450e8dc 100644 --- a/lib/x11/WindowXlib.cpp +++ b/lib/x11/WindowXlib.cpp @@ -670,12 +670,17 @@ public: VulkanContext::Window& m_windowCtx = *m_ctx->m_windows[m_parentWindow]; m_windowCtx.m_swapChains[0].destroy(m_ctx->m_dev); m_windowCtx.m_swapChains[1].destroy(m_ctx->m_dev); - //vk::DestroySurfaceKHR(m_ctx->m_instance, m_surface, nullptr); + if (m_surface) + { + vk::DestroySurfaceKHR(m_ctx->m_instance, m_surface, nullptr); + m_surface = VK_NULL_HANDLE; + } if (m_vsyncRunning) { m_vsyncRunning = false; - m_vsyncThread.join(); + if (m_vsyncThread.joinable()) + m_vsyncThread.join(); } } @@ -787,8 +792,8 @@ public: /* Get the list of VkFormats that are supported */ uint32_t formatCount; ThrowIfFailed(vk::GetPhysicalDeviceSurfaceFormatsKHR(m_ctx->m_gpus[0], m_surface, &formatCount, nullptr)); - VkSurfaceFormatKHR* surfFormats = (VkSurfaceFormatKHR*)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); - ThrowIfFailed(vk::GetPhysicalDeviceSurfaceFormatsKHR(m_ctx->m_gpus[0], m_surface, &formatCount, surfFormats)); + std::vector surfFormats(formatCount); + ThrowIfFailed(vk::GetPhysicalDeviceSurfaceFormatsKHR(m_ctx->m_gpus[0], m_surface, &formatCount, surfFormats.data())); /* If the format list includes just one entry of VK_FORMAT_UNDEFINED,