diff --git a/lsfg-vk-backend/src/helpers/managed_shader.cpp b/lsfg-vk-backend/src/helpers/managed_shader.cpp index 577511c..9d66762 100644 --- a/lsfg-vk-backend/src/helpers/managed_shader.cpp +++ b/lsfg-vk-backend/src/helpers/managed_shader.cpp @@ -110,9 +110,9 @@ ManagedShader ManagedShaderBuilder::build(const vk::Vulkan& vk, }; } -void ManagedShader::dispatch(const vk::CommandBuffer& cmd, +void ManagedShader::dispatch(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, VkExtent2D extent) const { - cmd.dispatch(this->shader, + cmd.dispatch(vk, this->shader, this->descriptorSet, this->barriers, extent.width, extent.height, 1 diff --git a/lsfg-vk-backend/src/helpers/managed_shader.hpp b/lsfg-vk-backend/src/helpers/managed_shader.hpp index 0e2a2db..1618af9 100644 --- a/lsfg-vk-backend/src/helpers/managed_shader.hpp +++ b/lsfg-vk-backend/src/helpers/managed_shader.hpp @@ -18,10 +18,12 @@ namespace ls { friend class ManagedShaderBuilder; public: /// dispatch the managed shader + /// @param vk the vulkan instance /// @param cmd command buffer to use /// @param extent dispatch size /// @throws ls::vulkan_error on failure - void dispatch(const vk::CommandBuffer& cmd, VkExtent2D extent) const; + void dispatch(const vk::Vulkan& vk, + const vk::CommandBuffer& cmd, VkExtent2D extent) const; private: ls::R shader; diff --git a/lsfg-vk-backend/src/lsfgvk.cpp b/lsfg-vk-backend/src/lsfgvk.cpp index a19cb23..a85c2cf 100644 --- a/lsfg-vk-backend/src/lsfgvk.cpp +++ b/lsfg-vk-backend/src/lsfgvk.cpp @@ -122,10 +122,11 @@ Instance::Instance( const std::function& devicePicker, const std::filesystem::path& shaderDllPath, bool allowLowPrecision) { - const auto selectFunc = [&devicePicker](const std::vector& devices) { + const auto selectFunc = [&devicePicker](const vk::VulkanInstanceFuncs funcs, + const std::vector& devices) { for (const auto& device : devices) { VkPhysicalDeviceProperties props; - vkGetPhysicalDeviceProperties(device, &props); + funcs.GetPhysicalDeviceProperties(device, &props); std::array devname = std::to_array(props.deviceName); devname[255] = '\0'; // ensure null-termination @@ -440,22 +441,22 @@ ContextImpl::ContextImpl(const InstanceImpl& instance, // initialize all images const vk::CommandBuffer cmdbuf{ctx.vk}; - cmdbuf.prepareImage(this->blackImage); - mipmaps.prepare(cmdbuf); + cmdbuf.prepareImage(ctx.vk, this->blackImage); + mipmaps.prepare(ctx.vk, cmdbuf); for (size_t i = 0; i < 7; ++i) { - alpha0.at(i).prepare(cmdbuf); - alpha1.at(i).prepare(cmdbuf); + alpha0.at(i).prepare(ctx.vk, cmdbuf); + alpha1.at(i).prepare(ctx.vk, cmdbuf); } - beta0.prepare(cmdbuf); - beta1.prepare(cmdbuf); + beta0.prepare(ctx.vk, cmdbuf); + beta1.prepare(ctx.vk, cmdbuf); for (const auto& pass : this->passes) { for (size_t i = 0; i < 7; ++i) { - pass.gamma0.at(i).prepare(cmdbuf); - pass.gamma1.at(i).prepare(cmdbuf); + pass.gamma0.at(i).prepare(ctx.vk, cmdbuf); + pass.gamma1.at(i).prepare(ctx.vk, cmdbuf); if (i < 4) continue; - pass.delta0.at(i - 4).prepare(cmdbuf); - pass.delta1.at(i - 4).prepare(cmdbuf); + pass.delta0.at(i - 4).prepare(ctx.vk, cmdbuf); + pass.delta1.at(i - 4).prepare(ctx.vk, cmdbuf); } } cmdbuf.submit(ctx.vk); // wait for completion @@ -477,7 +478,7 @@ void Instance::scheduleFrames(Context& context) { } #ifdef LSFGVK__RENDERDOC_INTEGRATION if (impl->getRenderDocAPI()) { - vkDeviceWaitIdle(impl->getVulkan().dev()); + impl->getVulkan().df().DeviceWaitIdle(impl->getVulkan().dev()); impl->getRenderDocAPI()->EndFrameCapture( RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(impl->getVulkan().inst()), nullptr); @@ -490,13 +491,13 @@ void Context::scheduleFrames() { vk::CommandBuffer& cmdbuf = this->cmdbufs.at(this->cmdbuf_idx++ % this->cmdbufs.size()); cmdbuf = vk::CommandBuffer(this->ctx.vk); - this->mipmaps.render(cmdbuf, this->fidx); + this->mipmaps.render(ctx.vk, cmdbuf, this->fidx); for (size_t i = 0; i < 7; ++i) { - this->alpha0.at(6 - i).render(cmdbuf); - this->alpha1.at(6 - i).render(cmdbuf, this->fidx); + this->alpha0.at(6 - i).render(ctx.vk, cmdbuf); + this->alpha1.at(6 - i).render(ctx.vk, cmdbuf, this->fidx); } - this->beta0.render(cmdbuf, this->fidx); - this->beta1.render(cmdbuf); + this->beta0.render(ctx.vk, cmdbuf, this->fidx); + this->beta1.render(ctx.vk, cmdbuf); cmdbuf.submit(this->ctx.vk, this->syncSemaphore, this->idx, @@ -512,14 +513,14 @@ void Context::scheduleFrames() { const auto& pass = this->passes.at(i); for (size_t j = 0; j < 7; j++) { - pass.gamma0.at(j).render(cmdbuf, this->fidx); - pass.gamma1.at(j).render(cmdbuf); + pass.gamma0.at(j).render(ctx.vk, cmdbuf, this->fidx); + pass.gamma1.at(j).render(ctx.vk, cmdbuf); if (j < 4) continue; - pass.delta0.at(j - 4).render(cmdbuf, this->fidx); - pass.delta1.at(j - 4).render(cmdbuf); + pass.delta0.at(j - 4).render(ctx.vk, cmdbuf, this->fidx); + pass.delta1.at(j - 4).render(ctx.vk, cmdbuf); } - pass.generate->render(cmdbuf, this->fidx); + pass.generate->render(ctx.vk, cmdbuf, this->fidx); cmdbuf.submit(this->ctx.vk, this->prepassSemaphore, this->idx - 1, @@ -540,7 +541,9 @@ void Instance::closeContext(const Context& context) { throw lsfgvk::error("attempted to close unknown context", std::runtime_error("no such context")); - vkDeviceWaitIdle(this->m_impl->getVulkan().dev()); + const auto& vk = this->m_impl->getVulkan(); + vk.df().DeviceWaitIdle(vk.dev()); + this->m_contexts.erase(it); } diff --git a/lsfg-vk-backend/src/shaderchains/alpha0.cpp b/lsfg-vk-backend/src/shaderchains/alpha0.cpp index 8306bbd..0240273 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha0.cpp +++ b/lsfg-vk-backend/src/shaderchains/alpha0.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -53,20 +54,20 @@ Alpha0::Alpha0(const ls::Ctx& ctx, this->dispatchExtent1 = ls::add_shift_extent(quarterExtent, 7, 3); } -void Alpha0::prepare(const vk::CommandBuffer& cmd) const { +void Alpha0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { // TODO: find a way to batch prepare for (size_t i = 0; i < this->tempImages0.size(); i++) { - cmd.prepareImage(this->tempImages0.at(i)); - cmd.prepareImage(this->tempImages1.at(i)); + cmd.prepareImage(vk, this->tempImages0.at(i)); + cmd.prepareImage(vk, this->tempImages1.at(i)); } for (const auto& image : this->images) - cmd.prepareImage(image); + cmd.prepareImage(vk, image); } -void Alpha0::render(const vk::CommandBuffer& cmd) const { - this->sets[0].dispatch(cmd, this->dispatchExtent0); - this->sets[1].dispatch(cmd, this->dispatchExtent0); - this->sets[2].dispatch(cmd, this->dispatchExtent1); +void Alpha0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { + this->sets[0].dispatch(vk, cmd, this->dispatchExtent0); + this->sets[1].dispatch(vk, cmd, this->dispatchExtent0); + this->sets[2].dispatch(vk, cmd, this->dispatchExtent1); } diff --git a/lsfg-vk-backend/src/shaderchains/alpha0.hpp b/lsfg-vk-backend/src/shaderchains/alpha0.hpp index 9bc17d0..70edbf0 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha0.hpp +++ b/lsfg-vk-backend/src/shaderchains/alpha0.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -22,12 +23,14 @@ namespace chains { const vk::Image& sourceImage); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the pre-alpha shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer - void render(const vk::CommandBuffer& cmd) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// get the generated images /// @return vector of images diff --git a/lsfg-vk-backend/src/shaderchains/alpha1.cpp b/lsfg-vk-backend/src/shaderchains/alpha1.cpp index 604cf53..0d40948 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha1.cpp +++ b/lsfg-vk-backend/src/shaderchains/alpha1.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -40,13 +41,13 @@ Alpha1::Alpha1(const ls::Ctx& ctx, this->dispatchExtent = ls::add_shift_extent(quarterExtent, 7, 3); } -void Alpha1::prepare(const vk::CommandBuffer& cmd) const { +void Alpha1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& vec : this->images) for (const auto& img : vec) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); } -void Alpha1::render(const vk::CommandBuffer& cmd, size_t idx) const { +void Alpha1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { // FIXME: iirc only one of the 7 instances of alpha1 requires 3 temporal images - this->sets[idx % 3].dispatch(cmd, dispatchExtent); + this->sets[idx % 3].dispatch(vk, cmd, dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/alpha1.hpp b/lsfg-vk-backend/src/shaderchains/alpha1.hpp index f24e0fa..6c4dba6 100644 --- a/lsfg-vk-backend/src/shaderchains/alpha1.hpp +++ b/lsfg-vk-backend/src/shaderchains/alpha1.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -22,13 +23,15 @@ namespace chains { const std::vector& sourceImages); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the alpha shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer /// @param idx frame index - void render(const vk::CommandBuffer& cmd, size_t idx) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const; /// get the generated images /// @return vector of images diff --git a/lsfg-vk-backend/src/shaderchains/beta0.cpp b/lsfg-vk-backend/src/shaderchains/beta0.cpp index 5691720..08b8c1e 100644 --- a/lsfg-vk-backend/src/shaderchains/beta0.cpp +++ b/lsfg-vk-backend/src/shaderchains/beta0.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -37,11 +38,11 @@ Beta0::Beta0(const ls::Ctx& ctx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Beta0::prepare(const vk::CommandBuffer& cmd) const { +void Beta0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& img : this->images) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); } -void Beta0::render(const vk::CommandBuffer& cmd, size_t idx) const { - this->sets[idx % 3].dispatch(cmd, dispatchExtent); +void Beta0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { + this->sets[idx % 3].dispatch(vk, cmd, dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/beta0.hpp b/lsfg-vk-backend/src/shaderchains/beta0.hpp index 9c551dc..7eaf2ca 100644 --- a/lsfg-vk-backend/src/shaderchains/beta0.hpp +++ b/lsfg-vk-backend/src/shaderchains/beta0.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -22,13 +23,15 @@ namespace chains { const std::vector>& sourceImages); /// prepare the shaderchain initially + /// @param vk vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the beta shaderchain + /// @param vk vulkan instance /// @param cmd command buffer /// @param idx frame index - void render(const vk::CommandBuffer& cmd, size_t idx) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const; /// get the generated images /// @return vector of images diff --git a/lsfg-vk-backend/src/shaderchains/beta1.cpp b/lsfg-vk-backend/src/shaderchains/beta1.cpp index 838f828..9591a62 100644 --- a/lsfg-vk-backend/src/shaderchains/beta1.cpp +++ b/lsfg-vk-backend/src/shaderchains/beta1.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -61,18 +62,18 @@ Beta1::Beta1(const ls::Ctx& ctx, this->dispatchExtent1 = ls::add_shift_extent(extent, 31, 5); } -void Beta1::prepare(const vk::CommandBuffer& cmd) const { +void Beta1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (size_t i = 0; i < 2; i++) { - cmd.prepareImage(this->tempImages0.at(i)); - cmd.prepareImage(this->tempImages1.at(i)); + cmd.prepareImage(vk, this->tempImages0.at(i)); + cmd.prepareImage(vk, this->tempImages1.at(i)); } for (const auto& img : this->images) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); } -void Beta1::render(const vk::CommandBuffer& cmd) const { - this->sets[0].dispatch(cmd, this->dispatchExtent0); - this->sets[1].dispatch(cmd, this->dispatchExtent0); - this->sets[2].dispatch(cmd, this->dispatchExtent0); - this->sets[3].dispatch(cmd, this->dispatchExtent1); +void Beta1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { + this->sets[0].dispatch(vk, cmd, this->dispatchExtent0); + this->sets[1].dispatch(vk, cmd, this->dispatchExtent0); + this->sets[2].dispatch(vk, cmd, this->dispatchExtent0); + this->sets[3].dispatch(vk, cmd, this->dispatchExtent1); } diff --git a/lsfg-vk-backend/src/shaderchains/beta1.hpp b/lsfg-vk-backend/src/shaderchains/beta1.hpp index 263ae67..157258f 100644 --- a/lsfg-vk-backend/src/shaderchains/beta1.hpp +++ b/lsfg-vk-backend/src/shaderchains/beta1.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -22,12 +23,14 @@ namespace chains { const std::vector& sourceImages); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the beta shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer - void render(const vk::CommandBuffer& cmd) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// get the generated images /// @return vector of images diff --git a/lsfg-vk-backend/src/shaderchains/delta0.cpp b/lsfg-vk-backend/src/shaderchains/delta0.cpp index 25cb0b3..5e3ff0f 100644 --- a/lsfg-vk-backend/src/shaderchains/delta0.cpp +++ b/lsfg-vk-backend/src/shaderchains/delta0.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -59,14 +60,14 @@ Delta0::Delta0(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Delta0::prepare(const vk::CommandBuffer& cmd) const { +void Delta0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& img : this->images0) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); for (const auto& img : this->images1) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); } -void Delta0::render(const vk::CommandBuffer& cmd, size_t idx) const { - this->sets0[idx % 3].dispatch(cmd, dispatchExtent); - this->sets1[idx % 3].dispatch(cmd, dispatchExtent); +void Delta0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { + this->sets0[idx % 3].dispatch(vk, cmd, dispatchExtent); + this->sets1[idx % 3].dispatch(vk, cmd, dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/delta0.hpp b/lsfg-vk-backend/src/shaderchains/delta0.hpp index 1371b9d..544e7ea 100644 --- a/lsfg-vk-backend/src/shaderchains/delta0.hpp +++ b/lsfg-vk-backend/src/shaderchains/delta0.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -27,13 +28,15 @@ namespace chains { const vk::Image& additionalInput1); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the delta shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer /// @param idx frame index - void render(const vk::CommandBuffer& cmd, size_t idx) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const; /// get the generated images /// @return vector of images diff --git a/lsfg-vk-backend/src/shaderchains/delta1.cpp b/lsfg-vk-backend/src/shaderchains/delta1.cpp index e6aa596..e9cf418 100644 --- a/lsfg-vk-backend/src/shaderchains/delta1.cpp +++ b/lsfg-vk-backend/src/shaderchains/delta1.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -92,16 +93,16 @@ Delta1::Delta1(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Delta1::prepare(const vk::CommandBuffer& cmd) const { +void Delta1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (size_t i = 0; i < this->tempImages0.size(); i++) { - cmd.prepareImage(this->tempImages0.at(i)); - cmd.prepareImage(this->tempImages1.at(i)); + cmd.prepareImage(vk, this->tempImages0.at(i)); + cmd.prepareImage(vk, this->tempImages1.at(i)); } - cmd.prepareImage(*this->image0); - cmd.prepareImage(*this->image1); + cmd.prepareImage(vk, *this->image0); + cmd.prepareImage(vk, *this->image1); } -void Delta1::render(const vk::CommandBuffer& cmd) const { +void Delta1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& set : this->sets) - set.dispatch(cmd, dispatchExtent); + set.dispatch(vk, cmd, dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/delta1.hpp b/lsfg-vk-backend/src/shaderchains/delta1.hpp index 475e8a5..5354d3b 100644 --- a/lsfg-vk-backend/src/shaderchains/delta1.hpp +++ b/lsfg-vk-backend/src/shaderchains/delta1.hpp @@ -5,6 +5,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -32,12 +33,14 @@ namespace chains { const vk::Image& additionalInput2); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the gamma shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer - void render(const vk::CommandBuffer& cmd) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// get the first generated image /// @return image diff --git a/lsfg-vk-backend/src/shaderchains/gamma0.cpp b/lsfg-vk-backend/src/shaderchains/gamma0.cpp index f2724ed..77c4e8e 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma0.cpp +++ b/lsfg-vk-backend/src/shaderchains/gamma0.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -40,11 +41,11 @@ Gamma0::Gamma0(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Gamma0::prepare(const vk::CommandBuffer& cmd) const { +void Gamma0::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& img : this->images) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); } -void Gamma0::render(const vk::CommandBuffer& cmd, size_t idx) const { - this->sets[idx % 3].dispatch(cmd, dispatchExtent); +void Gamma0::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { + this->sets[idx % 3].dispatch(vk, cmd, dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/gamma0.hpp b/lsfg-vk-backend/src/shaderchains/gamma0.hpp index 5d9a9ae..a57ab69 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma0.hpp +++ b/lsfg-vk-backend/src/shaderchains/gamma0.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -25,13 +26,15 @@ namespace chains { const vk::Image& additionalInput); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the gamma shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer /// @param idx frame index - void render(const vk::CommandBuffer& cmd, size_t idx) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const; /// get the generated images /// @return vector of images diff --git a/lsfg-vk-backend/src/shaderchains/gamma1.cpp b/lsfg-vk-backend/src/shaderchains/gamma1.cpp index 4322d07..ca89446 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma1.cpp +++ b/lsfg-vk-backend/src/shaderchains/gamma1.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -61,15 +62,15 @@ Gamma1::Gamma1(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(extent, 7, 3); } -void Gamma1::prepare(const vk::CommandBuffer& cmd) const { +void Gamma1::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (size_t i = 0; i < this->tempImages0.size(); i++) { - cmd.prepareImage(this->tempImages0.at(i)); - cmd.prepareImage(this->tempImages1.at(i)); + cmd.prepareImage(vk, this->tempImages0.at(i)); + cmd.prepareImage(vk, this->tempImages1.at(i)); } - cmd.prepareImage(*this->image); + cmd.prepareImage(vk, *this->image); } -void Gamma1::render(const vk::CommandBuffer& cmd) const { +void Gamma1::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& set : this->sets) - set.dispatch(cmd, dispatchExtent); + set.dispatch(vk, cmd, dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/gamma1.hpp b/lsfg-vk-backend/src/shaderchains/gamma1.hpp index 182c256..cd039ff 100644 --- a/lsfg-vk-backend/src/shaderchains/gamma1.hpp +++ b/lsfg-vk-backend/src/shaderchains/gamma1.hpp @@ -5,6 +5,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include @@ -28,12 +29,14 @@ namespace chains { const vk::Image& additionalInput1); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the gamma shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer - void render(const vk::CommandBuffer& cmd) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// get the generated image /// @return image diff --git a/lsfg-vk-backend/src/shaderchains/generate.cpp b/lsfg-vk-backend/src/shaderchains/generate.cpp index f586f03..a677d03 100644 --- a/lsfg-vk-backend/src/shaderchains/generate.cpp +++ b/lsfg-vk-backend/src/shaderchains/generate.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -47,6 +48,6 @@ Generate::Generate(const ls::Ctx& ctx, size_t idx, this->dispatchExtent = ls::add_shift_extent(ctx.sourceExtent, 15, 4); } -void Generate::render(const vk::CommandBuffer& cmd, size_t idx) const { - this->sets[idx % 2].dispatch(cmd, this->dispatchExtent); +void Generate::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { + this->sets[idx % 2].dispatch(vk, cmd, this->dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/generate.hpp b/lsfg-vk-backend/src/shaderchains/generate.hpp index 537f155..777c387 100644 --- a/lsfg-vk-backend/src/shaderchains/generate.hpp +++ b/lsfg-vk-backend/src/shaderchains/generate.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -31,9 +32,10 @@ namespace chains { const vk::Image& outputImage); /// render the generate shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer /// @param idx frame index - void render(const vk::CommandBuffer& cmd, size_t idx) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const; private: std::vector sets; VkExtent2D dispatchExtent{}; diff --git a/lsfg-vk-backend/src/shaderchains/mipmaps.cpp b/lsfg-vk-backend/src/shaderchains/mipmaps.cpp index cb09854..5d151b4 100644 --- a/lsfg-vk-backend/src/shaderchains/mipmaps.cpp +++ b/lsfg-vk-backend/src/shaderchains/mipmaps.cpp @@ -3,6 +3,7 @@ #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -40,11 +41,11 @@ Mipmaps::Mipmaps(const ls::Ctx& ctx, this->dispatchExtent = ls::add_shift_extent(ctx.flowExtent, 63, 6); } -void Mipmaps::prepare(const vk::CommandBuffer& cmd) const { +void Mipmaps::prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const { for (const auto& img : this->images) - cmd.prepareImage(img); + cmd.prepareImage(vk, img); } -void Mipmaps::render(const vk::CommandBuffer& cmd, size_t idx) const { - this->sets[idx % 2].dispatch(cmd, this->dispatchExtent); +void Mipmaps::render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const { + this->sets[idx % 2].dispatch(vk, cmd, this->dispatchExtent); } diff --git a/lsfg-vk-backend/src/shaderchains/mipmaps.hpp b/lsfg-vk-backend/src/shaderchains/mipmaps.hpp index d7416d8..a665f24 100644 --- a/lsfg-vk-backend/src/shaderchains/mipmaps.hpp +++ b/lsfg-vk-backend/src/shaderchains/mipmaps.hpp @@ -4,6 +4,7 @@ #include "../helpers/utils.hpp" #include "lsfg-vk-common/vulkan/command_buffer.hpp" #include "lsfg-vk-common/vulkan/image.hpp" +#include "lsfg-vk-common/vulkan/vulkan.hpp" #include #include @@ -23,13 +24,15 @@ namespace chains { const std::pair& sourceImages); /// prepare the shaderchain initially + /// @param vk the vulkan instance /// @param cmd command buffer - void prepare(const vk::CommandBuffer& cmd) const; + void prepare(const vk::Vulkan& vk, const vk::CommandBuffer& cmd) const; /// render the mipmaps shaderchain + /// @param vk the vulkan instance /// @param cmd command buffer /// @param idx frame index - void render(const vk::CommandBuffer& cmd, size_t idx) const; + void render(const vk::Vulkan& vk, const vk::CommandBuffer& cmd, size_t idx) const; /// get the generated mipmap images /// @return vector of images diff --git a/lsfg-vk-common/CMakeLists.txt b/lsfg-vk-common/CMakeLists.txt index 5ae6514..ec59a0d 100644 --- a/lsfg-vk-common/CMakeLists.txt +++ b/lsfg-vk-common/CMakeLists.txt @@ -15,5 +15,3 @@ add_library(lsfg-vk-common STATIC ${COMMON_SOURCES}) target_include_directories(lsfg-vk-common PUBLIC include) -target_link_libraries(lsfg-vk-common - vulkan) diff --git a/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp b/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp index f49a894..01426a3 100644 --- a/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp +++ b/lsfg-vk-common/include/lsfg-vk-common/vulkan/command_buffer.hpp @@ -27,22 +27,32 @@ namespace vk { CommandBuffer(const vk::Vulkan& vk); /// initialize an image + /// @param vk the vulkan instance /// @param image the image to initialize /// @param clearColor optional clear color - void prepareImage(const vk::Image& image, + void prepareImage(const vk::Vulkan& vk, + const vk::Image& image, const std::optional& clearColor = std::nullopt) const; /// dispatch a compute shader + /// @param vk the vulkan instance /// @param shader the compute shader /// @param set the descriptor set /// @param barriers image memory barriers to apply /// @param x dispatch size in X /// @param y dispatch size in Y /// @param z dispatch size in Z - void dispatch(const vk::Shader& shader, const vk::DescriptorSet& set, + void dispatch(const vk::Vulkan& vk, const vk::Shader& shader, const vk::DescriptorSet& set, const std::vector& barriers, uint32_t x, uint32_t y, uint32_t z) const; + /// copy buffer to image + /// @param vk the vulkan instance + /// @param buffer the source buffer + /// @param image the destination image + void copyBufferToImage(const vk::Vulkan& vk, + const vk::Buffer& buffer, const vk::Image& image) const; + /// submit the command buffer /// @param vk the vulkan instance /// @param waitSemaphore the semaphore to wait on @@ -58,11 +68,6 @@ namespace vk { /// @param vk the vulkan instance /// @throws ls::vulkan_error on failure void submit(const vk::Vulkan& vk) const; - - /// copy buffer to image - /// @param buffer the source buffer - /// @param image the destination image - void copyBufferToImage(const vk::Buffer& buffer, const vk::Image& image) const; private: ls::owned_ptr commandBuffer; }; diff --git a/lsfg-vk-common/include/lsfg-vk-common/vulkan/shader.hpp b/lsfg-vk-common/include/lsfg-vk-common/vulkan/shader.hpp index 844b931..5eb72f2 100644 --- a/lsfg-vk-common/include/lsfg-vk-common/vulkan/shader.hpp +++ b/lsfg-vk-common/include/lsfg-vk-common/vulkan/shader.hpp @@ -4,6 +4,7 @@ #include "vulkan.hpp" #include +#include #include #include diff --git a/lsfg-vk-common/include/lsfg-vk-common/vulkan/vulkan.hpp b/lsfg-vk-common/include/lsfg-vk-common/vulkan/vulkan.hpp index 6ead6ec..05c8b2a 100644 --- a/lsfg-vk-common/include/lsfg-vk-common/vulkan/vulkan.hpp +++ b/lsfg-vk-common/include/lsfg-vk-common/vulkan/vulkan.hpp @@ -12,10 +12,87 @@ #include namespace vk { + + /// vulkan instance function pointers + struct VulkanInstanceFuncs { + PFN_vkDestroyInstance DestroyInstance; + PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; + PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties; + PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties; + PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties; + PFN_vkCreateDevice CreateDevice; + PFN_vkGetDeviceProcAddr GetDeviceProcAddr; + }; + using PhysicalDeviceSelector = const std::function< - VkPhysicalDevice(const std::vector&) + VkPhysicalDevice( + const VulkanInstanceFuncs&, + const std::vector& + ) >&; + /// vulkan device function pointers + struct VulkanDeviceFuncs { + PFN_vkGetDeviceQueue GetDeviceQueue; + PFN_vkDeviceWaitIdle DeviceWaitIdle; + PFN_vkCreateCommandPool CreateCommandPool; + PFN_vkDestroyCommandPool DestroyCommandPool; + PFN_vkCreateDescriptorPool CreateDescriptorPool; + PFN_vkDestroyDescriptorPool DestroyDescriptorPool; + PFN_vkCreateBuffer CreateBuffer; + PFN_vkDestroyBuffer DestroyBuffer; + PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements; + PFN_vkAllocateMemory AllocateMemory; + PFN_vkFreeMemory FreeMemory; + PFN_vkBindBufferMemory BindBufferMemory; + PFN_vkMapMemory MapMemory; + PFN_vkUnmapMemory UnmapMemory; + PFN_vkAllocateCommandBuffers AllocateCommandBuffers; + PFN_vkFreeCommandBuffers FreeCommandBuffers; + PFN_vkBeginCommandBuffer BeginCommandBuffer; + PFN_vkEndCommandBuffer EndCommandBuffer; + PFN_vkCmdPipelineBarrier CmdPipelineBarrier; + PFN_vkCmdClearColorImage CmdClearColorImage; + PFN_vkCmdBindPipeline CmdBindPipeline; + PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets; + PFN_vkCmdDispatch CmdDispatch; + PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage; + PFN_vkQueueSubmit QueueSubmit; + PFN_vkAllocateDescriptorSets AllocateDescriptorSets; + PFN_vkFreeDescriptorSets FreeDescriptorSets; + PFN_vkUpdateDescriptorSets UpdateDescriptorSets; + PFN_vkCreateFence CreateFence; + PFN_vkDestroyFence DestroyFence; + PFN_vkResetFences ResetFences; + PFN_vkWaitForFences WaitForFences; + PFN_vkCreateImage CreateImage; + PFN_vkDestroyImage DestroyImage; + PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements; + PFN_vkBindImageMemory BindImageMemory; + PFN_vkCreateImageView CreateImageView; + PFN_vkDestroyImageView DestroyImageView; + PFN_vkCreateSampler CreateSampler; + PFN_vkDestroySampler DestroySampler; + PFN_vkCreateSemaphore CreateSemaphore; + PFN_vkDestroySemaphore DestroySemaphore; + PFN_vkCreateShaderModule CreateShaderModule; + PFN_vkDestroyShaderModule DestroyShaderModule; + PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout; + PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout; + PFN_vkCreatePipelineLayout CreatePipelineLayout; + PFN_vkDestroyPipelineLayout DestroyPipelineLayout; + PFN_vkCreateComputePipelines CreateComputePipelines; + PFN_vkDestroyPipeline DestroyPipeline; + PFN_vkSignalSemaphore SignalSemaphore; + PFN_vkWaitSemaphores WaitSemaphores; + + // extension functions + PFN_vkGetMemoryFdKHR GetMemoryFdKHR; + PFN_vkImportSemaphoreFdKHR ImportSemaphoreFdKHR; + PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR; + }; + /// vulkan version wrapper class version { public: @@ -73,14 +150,21 @@ namespace vk { /// check if fp16 is supported /// @return true if fp16 is supported [[nodiscard]] bool supportsFP16() const { return this->fp16; } + + /// get device-level function pointers + /// @return the device function pointers + [[nodiscard]] const auto& df() const { return this->device_funcs; } private: ls::owned_ptr instance; + VulkanInstanceFuncs instance_funcs; VkPhysicalDevice physdev; uint32_t computeFamilyIdx; bool fp16; ls::owned_ptr device; + VulkanDeviceFuncs device_funcs; + VkQueue computeQueue; ls::owned_ptr cmdPool; diff --git a/lsfg-vk-common/src/vulkan/buffer.cpp b/lsfg-vk-common/src/vulkan/buffer.cpp index e2c1a05..cf96af9 100644 --- a/lsfg-vk-common/src/vulkan/buffer.cpp +++ b/lsfg-vk-common/src/vulkan/buffer.cpp @@ -25,14 +25,14 @@ namespace { .usage = usage, .sharingMode = VK_SHARING_MODE_EXCLUSIVE }; - auto res = vkCreateBuffer(vk.dev(), &bufferInfo, nullptr, &handle); + auto res = vk.df().CreateBuffer(vk.dev(), &bufferInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateBuffer() failed"); return ls::owned_ptr( new VkBuffer(handle), - [dev = vk.dev()](VkBuffer& buffer) { - vkDestroyBuffer(dev, buffer, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyBuffer](VkBuffer& buffer) { + defunc(dev, buffer, nullptr); } ); } @@ -41,7 +41,7 @@ namespace { VkDeviceMemory handle{}; VkMemoryRequirements reqs{}; - vkGetBufferMemoryRequirements(vk.dev(), buffer, &reqs); + vk.df().GetBufferMemoryRequirements(vk.dev(), buffer, &reqs); auto mti = vk.findMemoryTypeIndex( reqs.memoryTypeBits, @@ -55,18 +55,18 @@ namespace { .allocationSize = reqs.size, .memoryTypeIndex = *mti }; - auto res = vkAllocateMemory(vk.dev(), &memoryInfo, nullptr, &handle); + auto res = vk.df().AllocateMemory(vk.dev(), &memoryInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkAllocateMemory() failed"); - res = vkBindBufferMemory(vk.dev(), buffer, handle, 0); + res = vk.df().BindBufferMemory(vk.dev(), buffer, handle, 0); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkBindBufferMemory() failed"); return ls::owned_ptr( new VkDeviceMemory(handle), - [dev = vk.dev()](VkDeviceMemory& memory) { - vkFreeMemory(dev, memory, nullptr); + [dev = vk.dev(), defunc = vk.df().FreeMemory](VkDeviceMemory& memory) { + defunc(dev, memory, nullptr); } ); } @@ -75,7 +75,7 @@ namespace { VkDeviceMemory memory, const void* data, size_t size) { void* buf{}; - auto res = vkMapMemory(vk.dev(), memory, 0, size, 0, &buf); + auto res = vk.df().MapMemory(vk.dev(), memory, 0, size, 0, &buf); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkMapMemory() failed"); @@ -85,7 +85,7 @@ namespace { reinterpret_cast(buf) ); - vkUnmapMemory(vk.dev(), memory); + vk.df().UnmapMemory(vk.dev(), memory); } } diff --git a/lsfg-vk-common/src/vulkan/command_buffer.cpp b/lsfg-vk-common/src/vulkan/command_buffer.cpp index b679ac2..b9af775 100644 --- a/lsfg-vk-common/src/vulkan/command_buffer.cpp +++ b/lsfg-vk-common/src/vulkan/command_buffer.cpp @@ -28,14 +28,16 @@ namespace { .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .commandBufferCount = 1 }; - auto res = vkAllocateCommandBuffers(vk.dev(), &commandBufferInfo, &handle); + auto res = vk.df().AllocateCommandBuffers(vk.dev(), &commandBufferInfo, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkAllocateCommandBuffers() failed"); return ls::owned_ptr( new VkCommandBuffer(handle), - [dev = vk.dev(), pool = vk.cmdpool()](VkCommandBuffer& commandBufferModule) { - vkFreeCommandBuffers(dev, pool, 1, &commandBufferModule); + [dev = vk.dev(), pool = vk.cmdpool(), defunc = vk.df().FreeCommandBuffers]( + VkCommandBuffer& commandBufferModule + ) { + defunc(dev, pool, 1, &commandBufferModule); } ); } @@ -48,12 +50,13 @@ CommandBuffer::CommandBuffer(const vk::Vulkan& vk) .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - auto res = vkBeginCommandBuffer(*this->commandBuffer, &beginInfo); + auto res = vk.df().BeginCommandBuffer(*this->commandBuffer, &beginInfo); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkBeginCommandBuffer() failed"); } -void CommandBuffer::prepareImage(const vk::Image& image, +void CommandBuffer::prepareImage(const vk::Vulkan& vk, + const vk::Image& image, const std::optional& clearColor) const { const VkImageMemoryBarrier barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -68,7 +71,7 @@ void CommandBuffer::prepareImage(const vk::Image& image, .layerCount = 1 } }; - vkCmdPipelineBarrier(*this->commandBuffer, + vk.df().CmdPipelineBarrier(*this->commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, @@ -77,7 +80,7 @@ void CommandBuffer::prepareImage(const vk::Image& image, ); if (clearColor.has_value()) { - vkCmdClearColorImage(*this->commandBuffer, + vk.df().CmdClearColorImage(*this->commandBuffer, image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clearColor.value(), @@ -86,11 +89,12 @@ void CommandBuffer::prepareImage(const vk::Image& image, } } -void CommandBuffer::dispatch(const vk::Shader& shader, +void CommandBuffer::dispatch(const vk::Vulkan& vk, + const vk::Shader& shader, const vk::DescriptorSet& set, const std::vector& barriers, uint32_t x, uint32_t y, uint32_t z) const { - vkCmdPipelineBarrier(*this->commandBuffer, + vk.df().CmdPipelineBarrier(*this->commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, @@ -98,23 +102,65 @@ void CommandBuffer::dispatch(const vk::Shader& shader, 0, nullptr, static_cast(barriers.size()), barriers.data() ); - vkCmdBindPipeline(*this->commandBuffer, + vk.df().CmdBindPipeline(*this->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader.pipeline() ); - vkCmdBindDescriptorSets(*this->commandBuffer, + vk.df().CmdBindDescriptorSets(*this->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader.pipelinelayout(), 0, 1, &set.handle(), 0, nullptr ); - vkCmdDispatch(*this->commandBuffer, x, y, z); + vk.df().CmdDispatch(*this->commandBuffer, x, y, z); } +void CommandBuffer::copyBufferToImage(const vk::Vulkan& vk, + const vk::Buffer& buffer, const vk::Image& image) const { + const VkImageMemoryBarrier barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_NONE, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .image = image.handle(), + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .levelCount = 1, + .layerCount = 1 + } + }; + vk.df().CmdPipelineBarrier(*this->commandBuffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, + 0, nullptr, + 0, nullptr, + 1, &barrier + ); + + const VkBufferImageCopy region{ + .bufferImageHeight = 0, + .imageSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .layerCount = 1 + }, + .imageExtent = { + .width = image.getExtent().width, + .height = image.getExtent().height, + .depth = 1 + } + }; + vk.df().CmdCopyBufferToImage(*this->commandBuffer, + buffer.handle(), image.handle(), + VK_IMAGE_LAYOUT_GENERAL, 1, ®ion + ); +} + + void CommandBuffer::submit(const vk::Vulkan& vk, const vk::TimelineSemaphore& waitSemaphore, uint64_t waitValue, const vk::TimelineSemaphore& signalSemaphore, uint64_t signalValue) const { - auto res = vkEndCommandBuffer(*this->commandBuffer); + auto res = vk.df().EndCommandBuffer(*this->commandBuffer); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkEndCommandBuffer() failed"); @@ -138,13 +184,13 @@ void CommandBuffer::submit(const vk::Vulkan& vk, .signalSemaphoreCount = 1, .pSignalSemaphores = &signalSemaphore.handle() }; - res = vkQueueSubmit(vk.queue(), 1, &submitInfo, VK_NULL_HANDLE); + res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, VK_NULL_HANDLE); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkQueueSubmit() failed"); } void CommandBuffer::submit(const vk::Vulkan& vk) const { - auto res = vkEndCommandBuffer(*this->commandBuffer); + auto res = vk.df().EndCommandBuffer(*this->commandBuffer); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkEndCommandBuffer() failed"); @@ -154,50 +200,10 @@ void CommandBuffer::submit(const vk::Vulkan& vk) const { .pCommandBuffers = &*this->commandBuffer }; const vk::Fence fence{vk}; - res = vkQueueSubmit(vk.queue(), 1, &submitInfo, fence.handle()); + res = vk.df().QueueSubmit(vk.queue(), 1, &submitInfo, fence.handle()); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkQueueSubmit() failed"); if (!fence.wait(vk)) throw ls::vulkan_error(VK_TIMEOUT, "Fence::wait() timed out"); } - -void CommandBuffer::copyBufferToImage(const vk::Buffer& buffer, const vk::Image& image) const { - const VkImageMemoryBarrier barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = VK_ACCESS_NONE, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .image = image.handle(), - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .levelCount = 1, - .layerCount = 1 - } - }; - vkCmdPipelineBarrier(*this->commandBuffer, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, nullptr, - 0, nullptr, - 1, &barrier - ); - - const VkBufferImageCopy region{ - .bufferImageHeight = 0, - .imageSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .layerCount = 1 - }, - .imageExtent = { - .width = image.getExtent().width, - .height = image.getExtent().height, - .depth = 1 - } - }; - vkCmdCopyBufferToImage(*this->commandBuffer, - buffer.handle(), image.handle(), - VK_IMAGE_LAYOUT_GENERAL, 1, ®ion - ); -} diff --git a/lsfg-vk-common/src/vulkan/descriptor_set.cpp b/lsfg-vk-common/src/vulkan/descriptor_set.cpp index 5988267..ecef74b 100644 --- a/lsfg-vk-common/src/vulkan/descriptor_set.cpp +++ b/lsfg-vk-common/src/vulkan/descriptor_set.cpp @@ -28,14 +28,16 @@ namespace { .descriptorSetCount = 1, .pSetLayouts = &layout }; - auto res = vkAllocateDescriptorSets(vk.dev(), &setInfo, &handle); + auto res = vk.df().AllocateDescriptorSets(vk.dev(), &setInfo, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkAllocateDescriptorSets() failed"); return ls::owned_ptr( new VkDescriptorSet(handle), - [dev = vk.dev(), pool = vk.descpool()](VkDescriptorSet& commandBufferModule) { - vkFreeDescriptorSets(dev, pool, 1, &commandBufferModule); + [dev = vk.dev(), pool = vk.descpool(), defunc = vk.df().FreeDescriptorSets]( + VkDescriptorSet& commandBufferModule + ) { + defunc(dev, pool, 1, &commandBufferModule); } ); } @@ -120,6 +122,6 @@ DescriptorSet::DescriptorSet(const vk::Vulkan& vk, })) }); - vkUpdateDescriptorSets(vk.dev(), + vk.df().UpdateDescriptorSets(vk.dev(), static_cast(entries.size()), entries.data(), 0, nullptr); } diff --git a/lsfg-vk-common/src/vulkan/fence.cpp b/lsfg-vk-common/src/vulkan/fence.cpp index 2397fa9..c4421fa 100644 --- a/lsfg-vk-common/src/vulkan/fence.cpp +++ b/lsfg-vk-common/src/vulkan/fence.cpp @@ -17,14 +17,14 @@ namespace { const VkFenceCreateInfo fenceInfo{ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; - auto res = vkCreateFence(vk.dev(), &fenceInfo, nullptr, &handle); + auto res = vk.df().CreateFence(vk.dev(), &fenceInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateFence() failed"); return ls::owned_ptr( new VkFence(handle), - [dev = vk.dev()](VkFence& fence) { - vkDestroyFence(dev, fence, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyFence](VkFence& fence) { + defunc(dev, fence, nullptr); } ); } @@ -35,14 +35,14 @@ Fence::Fence(const vk::Vulkan& vk) void Fence::reset(const vk::Vulkan& vk) const { VkFence fence = *this->fence; - auto res = vkResetFences(vk.dev(), 1, &fence); + auto res = vk.df().ResetFences(vk.dev(), 1, &fence); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkResetFences() failed"); } bool Fence::wait(const vk::Vulkan& vk, uint64_t timeout) const { VkFence fence = *this->fence; - auto res = vkWaitForFences(vk.dev(), 1, &fence, VK_TRUE, timeout); + auto res = vk.df().WaitForFences(vk.dev(), 1, &fence, VK_TRUE, timeout); if (res != VK_SUCCESS && res != VK_TIMEOUT) throw ls::vulkan_error(res, "vkWaitForFences() failed"); diff --git a/lsfg-vk-common/src/vulkan/image.cpp b/lsfg-vk-common/src/vulkan/image.cpp index f04acbe..3acf1b4 100644 --- a/lsfg-vk-common/src/vulkan/image.cpp +++ b/lsfg-vk-common/src/vulkan/image.cpp @@ -37,14 +37,14 @@ namespace { .usage = usage, .sharingMode = VK_SHARING_MODE_EXCLUSIVE }; - auto res = vkCreateImage(vk.dev(), &imageInfo, nullptr, &handle); + auto res = vk.df().CreateImage(vk.dev(), &imageInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateImage() failed"); return ls::owned_ptr( new VkImage(handle), - [dev = vk.dev()](VkImage& image) { - vkDestroyImage(dev, image, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyImage](VkImage& image) { + defunc(dev, image, nullptr); } ); } @@ -54,7 +54,7 @@ namespace { VkDeviceMemory handle{}; VkMemoryRequirements reqs{}; - vkGetImageMemoryRequirements(vk.dev(), image, &reqs); + vk.df().GetImageMemoryRequirements(vk.dev(), image, &reqs); auto mti = vk.findMemoryTypeIndex( reqs.memoryTypeBits, @@ -89,25 +89,22 @@ namespace { .allocationSize = reqs.size, .memoryTypeIndex = *mti }; - auto res = vkAllocateMemory(vk.dev(), &memoryInfo, nullptr, &handle); + auto res = vk.df().AllocateMemory(vk.dev(), &memoryInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkAllocateMemory() failed"); - res = vkBindImageMemory(vk.dev(), image, handle, 0); + res = vk.df().BindImageMemory(vk.dev(), image, handle, 0); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkBindImageMemory() failed"); if (exportFd.has_value()) { - auto vkGetMemoryFdKHR = reinterpret_cast( - vkGetDeviceProcAddr(vk.dev(), "vkGetMemoryFdKHR")); // TODO: cache - const VkMemoryGetFdInfoKHR fdInfo{ .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, .memory = handle, .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR }; int fd{}; - res = vkGetMemoryFdKHR(vk.dev(), &fdInfo, &fd); + res = vk.df().GetMemoryFdKHR(vk.dev(), &fdInfo, &fd); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkGetMemoryFdKHR() failed"); **exportFd = fd; @@ -115,8 +112,8 @@ namespace { return ls::owned_ptr( new VkDeviceMemory(handle), - [dev = vk.dev()](VkDeviceMemory& memory) { - vkFreeMemory(dev, memory, nullptr); + [dev = vk.dev(), defunc = vk.df().FreeMemory](VkDeviceMemory& memory) { + defunc(dev, memory, nullptr); } ); } @@ -138,14 +135,14 @@ namespace { .layerCount = 1 } }; - auto res = vkCreateImageView(vk.dev(), &viewInfo, nullptr, &handle); + auto res = vk.df().CreateImageView(vk.dev(), &viewInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateImageView() failed"); return ls::owned_ptr( new VkImageView(handle), - [dev = vk.dev()](VkImageView& view) { - vkDestroyImageView(dev, view, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyImageView](VkImageView& view) { + defunc(dev, view, nullptr); } ); } diff --git a/lsfg-vk-common/src/vulkan/sampler.cpp b/lsfg-vk-common/src/vulkan/sampler.cpp index 99711ae..3646cbe 100644 --- a/lsfg-vk-common/src/vulkan/sampler.cpp +++ b/lsfg-vk-common/src/vulkan/sampler.cpp @@ -27,14 +27,14 @@ namespace { white ? VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK }; - auto res = vkCreateSampler(vk.dev(), &samplerInfo, nullptr, &handle); + auto res = vk.df().CreateSampler(vk.dev(), &samplerInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateSampler() failed"); return ls::owned_ptr( new VkSampler(handle), - [dev = vk.dev()](VkSampler& sampler) { - vkDestroySampler(dev, sampler, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroySampler](VkSampler& sampler) { + defunc(dev, sampler, nullptr); } ); } diff --git a/lsfg-vk-common/src/vulkan/semaphore.cpp b/lsfg-vk-common/src/vulkan/semaphore.cpp index 59c1e92..54674fd 100644 --- a/lsfg-vk-common/src/vulkan/semaphore.cpp +++ b/lsfg-vk-common/src/vulkan/semaphore.cpp @@ -22,30 +22,27 @@ namespace { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .pNext = fd.has_value() ? &exportInfo : nullptr }; - auto res = vkCreateSemaphore(vk.dev(), &semaphoreInfo, nullptr, &handle); + auto res = vk.df().CreateSemaphore(vk.dev(), &semaphoreInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateSemaphore() failed"); if (fd.has_value()) { // import semaphore from fd - auto vkImportSemaphoreFdKHR = reinterpret_cast( - vkGetDeviceProcAddr(vk.dev(), "vkImportSemaphoreFdKHR")); // TODO: cache - const VkImportSemaphoreFdInfoKHR importInfo{ .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, .semaphore = handle, .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, .fd = *fd // closes the fd }; - res = vkImportSemaphoreFdKHR(vk.dev(), &importInfo); + res = vk.df().ImportSemaphoreFdKHR(vk.dev(), &importInfo); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkImportSemaphoreFdKHR() failed"); } return ls::owned_ptr( new VkSemaphore(handle), - [dev = vk.dev()](VkSemaphore& semaphore) { - vkDestroySemaphore(dev, semaphore, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroySemaphore](VkSemaphore& semaphore) { + defunc(dev, semaphore, nullptr); } ); } diff --git a/lsfg-vk-common/src/vulkan/shader.cpp b/lsfg-vk-common/src/vulkan/shader.cpp index e30444e..9fb7563 100644 --- a/lsfg-vk-common/src/vulkan/shader.cpp +++ b/lsfg-vk-common/src/vulkan/shader.cpp @@ -23,14 +23,14 @@ namespace { .codeSize = data_len, .pCode = reinterpret_cast(data) }; - auto res = vkCreateShaderModule(vk.dev(), &shaderModuleInfo, nullptr, &handle); + auto res = vk.df().CreateShaderModule(vk.dev(), &shaderModuleInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateShaderModule() failed"); return ls::owned_ptr( new VkShaderModule(handle), - [dev = vk.dev()](VkShaderModule& shaderModule) { - vkDestroyShaderModule(dev, shaderModule, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyShaderModule](VkShaderModule& shaderModule) { + defunc(dev, shaderModule, nullptr); } ); } @@ -73,19 +73,21 @@ namespace { .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT }); - const VkDescriptorSetLayoutCreateInfo descriptorLayoutInfo{ + const VkDescriptorSetLayoutCreateInfo info{ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .bindingCount = static_cast(bindings.size()), .pBindings = bindings.data() }; - auto res = vkCreateDescriptorSetLayout(vk.dev(), &descriptorLayoutInfo, nullptr, &handle); + auto res = vk.df().CreateDescriptorSetLayout(vk.dev(), &info, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateDescriptorSetLayout() failed"); return ls::owned_ptr( new VkDescriptorSetLayout(handle), - [dev = vk.dev()](VkDescriptorSetLayout& layout) { - vkDestroyDescriptorSetLayout(dev, layout, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyDescriptorSetLayout]( + VkDescriptorSetLayout& layout + ) { + defunc(dev, layout, nullptr); } ); } @@ -100,14 +102,14 @@ namespace { .setLayoutCount = 1, .pSetLayouts = &descriptorLayout }; - auto res = vkCreatePipelineLayout(vk.dev(), &layoutInfo, nullptr, &handle); + auto res = vk.df().CreatePipelineLayout(vk.dev(), &layoutInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreatePipelineLayout() failed"); return ls::owned_ptr( new VkPipelineLayout(handle), - [dev = vk.dev()](VkPipelineLayout& layout) { - vkDestroyPipelineLayout(dev, layout, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyPipelineLayout](VkPipelineLayout& layout) { + defunc(dev, layout, nullptr); } ); } @@ -129,7 +131,7 @@ namespace { .stage = shaderStageInfo, .layout = pipelineLayout }; - auto res = vkCreateComputePipelines(vk.dev(), + auto res = vk.df().CreateComputePipelines(vk.dev(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateComputePipelines() failed"); @@ -138,8 +140,8 @@ namespace { return ls::owned_ptr( new VkPipeline(handle), - [dev = vk.dev()](VkPipeline& pipeline) { - vkDestroyPipeline(dev, pipeline, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroyPipeline](VkPipeline& pipeline) { + defunc(dev, pipeline, nullptr); } ); } diff --git a/lsfg-vk-common/src/vulkan/timeline_semaphore.cpp b/lsfg-vk-common/src/vulkan/timeline_semaphore.cpp index 05ae0b0..3114080 100644 --- a/lsfg-vk-common/src/vulkan/timeline_semaphore.cpp +++ b/lsfg-vk-common/src/vulkan/timeline_semaphore.cpp @@ -30,38 +30,32 @@ namespace { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .pNext = &typeInfo, }; - auto res = vkCreateSemaphore(vk.dev(), &semaphoreInfo, nullptr, &handle); + auto res = vk.df().CreateSemaphore(vk.dev(), &semaphoreInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateSemaphore() failed"); if (importFd.has_value()) { // import semaphore from fd - auto vkImportSemaphoreFdKHR = reinterpret_cast( - vkGetDeviceProcAddr(vk.dev(), "vkImportSemaphoreFdKHR")); // TODO: cache - const VkImportSemaphoreFdInfoKHR importInfo{ .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, .semaphore = handle, .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, .fd = *importFd // closes the fd }; - res = vkImportSemaphoreFdKHR(vk.dev(), &importInfo); + res = vk.df().ImportSemaphoreFdKHR(vk.dev(), &importInfo); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkImportSemaphoreFdKHR() failed"); } if (exportFd.has_value()) { // export semaphore to fd - auto vkGetSemaphoreFdKHR = reinterpret_cast( - vkGetDeviceProcAddr(vk.dev(), "vkGetSemaphoreFdKHR")); // TODO: cache - const VkSemaphoreGetFdInfoKHR getFdInfo{ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, .semaphore = handle, .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT }; int fd{}; - res = vkGetSemaphoreFdKHR(vk.dev(), &getFdInfo, &fd); + res = vk.df().GetSemaphoreFdKHR(vk.dev(), &getFdInfo, &fd); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkGetSemaphoreFdKHR() failed"); @@ -70,8 +64,8 @@ namespace { return ls::owned_ptr( new VkSemaphore(handle), - [dev = vk.dev()](VkSemaphore& semaphore) { - vkDestroySemaphore(dev, semaphore, nullptr); + [dev = vk.dev(), defunc = vk.df().DestroySemaphore](VkSemaphore& semaphore) { + defunc(dev, semaphore, nullptr); } ); } @@ -87,7 +81,7 @@ void TimelineSemaphore::signal(const vk::Vulkan& vk, uint64_t value) const { .semaphore = *this->semaphore, .value = value }; - auto res = vkSignalSemaphore(vk.dev(), &signalInfo); + auto res = vk.df().SignalSemaphore(vk.dev(), &signalInfo); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkSignalSemaphore() failed"); } @@ -100,7 +94,7 @@ bool TimelineSemaphore::wait(const vk::Vulkan& vk, uint64_t value, uint64_t time .pSemaphores = &semaphore, .pValues = &value }; - auto res = vkWaitSemaphores(vk.dev(), &waitInfo, timeout); + auto res = vk.df().WaitSemaphores(vk.dev(), &waitInfo, timeout); if (res != VK_SUCCESS && res != VK_TIMEOUT) throw ls::vulkan_error(res, "vkWaitSemaphores() failed"); diff --git a/lsfg-vk-common/src/vulkan/vulkan.cpp b/lsfg-vk-common/src/vulkan/vulkan.cpp index 31dacfd..3d5c26a 100644 --- a/lsfg-vk-common/src/vulkan/vulkan.cpp +++ b/lsfg-vk-common/src/vulkan/vulkan.cpp @@ -9,24 +9,66 @@ #include #include +#include #include using namespace vk; namespace { + /// load libvulkan.so.1 and return its handle + void* get_vulkan_handle() { + static void* handle{nullptr}; // NOLINT + if (handle) return handle; + + handle = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL); + if (!handle) + throw ls::vulkan_error("failed to load libvulkan.so.1"); + + return handle; + } + + /// get the main proc addr function + PFN_vkGetInstanceProcAddr get_mpa() { + static PFN_vkGetInstanceProcAddr mpa{nullptr}; // NOLINT + if (mpa) return mpa; + + mpa = reinterpret_cast( + dlsym(get_vulkan_handle(), "vkGetInstanceProcAddr")); + if (!mpa) + throw ls::vulkan_error("failed to get vkGetInstanceProcAddr symbol"); + + return mpa; + } +} + +namespace { + template + T ipa(PFN_vkGetInstanceProcAddr mpa, VkInstance instance, const char* name) { + T func = reinterpret_cast( + mpa(instance, name)); + if (!func) + throw ls::vulkan_error("failed to get instance proc addr for " + std::string(name)); + return func; + } + /// create a vulkan instance ls::owned_ptr createInstance( const std::string& appName, version appVersion, const std::string& engineName, version engineVersion) { VkInstance handle{}; + auto vkCreateInstance = + ipa(get_mpa(), nullptr, "vkCreateInstance"); + if (!vkCreateInstance) + throw ls::vulkan_error("failed to get vkCreateInstance symbol"); + const VkApplicationInfo appInfo{ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pApplicationName = appName.c_str(), .applicationVersion = appVersion.into(), .pEngineName = engineName.c_str(), .engineVersion = engineVersion.into(), - .apiVersion = VK_API_VERSION_1_2 // seems Vulkan 1.2 is supported on all Vulkan-capable GPUs + .apiVersion = VK_API_VERSION_1_2 // seems 1.2 is supported on all Vulkan-capable GPUs }; const VkInstanceCreateInfo instanceInfo{ .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, @@ -36,29 +78,55 @@ namespace { if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateInstance() failed"); + auto defunc = + ipa(get_mpa(), handle, "vkDestroyInstance"); + if (!defunc) + throw ls::vulkan_error("failed to get vkDestroyInstance symbol"); return ls::owned_ptr( new VkInstance(handle), - [](VkInstance& instance) { - vkDestroyInstance(instance, nullptr); + [defunc](VkInstance& instance) { + defunc(instance, nullptr); } ); } + /// initialize vulkan instance function pointers + VulkanInstanceFuncs initVulkanInstanceFuncs(VkInstance i) { + const auto& mpa = get_mpa(); + + return { + .DestroyInstance = ipa(mpa, i, "vkDestroyInstance"), + .EnumeratePhysicalDevices = ipa(mpa, i, + "vkEnumeratePhysicalDevices"), + .GetPhysicalDeviceProperties = ipa(mpa, i, + "vkGetPhysicalDeviceProperties"), + .GetPhysicalDeviceQueueFamilyProperties = + ipa(mpa, i, + "vkGetPhysicalDeviceQueueFamilyProperties"), + .GetPhysicalDeviceFeatures2 = ipa(mpa, i, + "vkGetPhysicalDeviceFeatures2"), + .GetPhysicalDeviceMemoryProperties = ipa(mpa, i, + "vkGetPhysicalDeviceMemoryProperties"), + .CreateDevice = ipa(mpa, i, "vkCreateDevice"), + .GetDeviceProcAddr = ipa(mpa, i, "vkGetDeviceProcAddr"), + }; + } + /// filter for a physical device - VkPhysicalDevice findPhysicalDevice( + VkPhysicalDevice findPhysicalDevice(const VulkanInstanceFuncs& fi, VkInstance instance, PhysicalDeviceSelector filter) { uint32_t phydevCount{}; - auto res = vkEnumeratePhysicalDevices(instance, &phydevCount, nullptr); + auto res = fi.EnumeratePhysicalDevices(instance, &phydevCount, nullptr); if (res != VK_SUCCESS || phydevCount == 0) throw ls::vulkan_error(res, "vkEnumeratePhysicalDevices() failed"); std::vector phydevs(phydevCount); - res = vkEnumeratePhysicalDevices(instance, &phydevCount, phydevs.data()); + res = fi.EnumeratePhysicalDevices(instance, &phydevCount, phydevs.data()); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkEnumeratePhysicalDevices() failed"); - VkPhysicalDevice selected = filter(phydevs); + VkPhysicalDevice selected = filter(fi, phydevs); if (!selected) throw ls::vulkan_error("no suitable physical device found"); @@ -66,12 +134,13 @@ namespace { } /// find the queue family index with given flags - uint32_t findQFI(VkPhysicalDevice physdev, VkQueueFlags flags) { + uint32_t findQFI(const VulkanInstanceFuncs& fi, + VkPhysicalDevice physdev, VkQueueFlags flags) { uint32_t queueCount{}; - vkGetPhysicalDeviceQueueFamilyProperties(physdev, &queueCount, nullptr); + fi.GetPhysicalDeviceQueueFamilyProperties(physdev, &queueCount, nullptr); std::vector queues(queueCount); - vkGetPhysicalDeviceQueueFamilyProperties(physdev, &queueCount, queues.data()); + fi.GetPhysicalDeviceQueueFamilyProperties(physdev, &queueCount, queues.data()); for (uint32_t i = 0; i < queueCount; ++i) { if ((queues[i].queueFlags & flags) == flags) @@ -82,7 +151,7 @@ namespace { } /// check for fp16 support - bool checkFP16(VkPhysicalDevice physdev) { + bool checkFP16(const VulkanInstanceFuncs& fi, VkPhysicalDevice physdev) { VkPhysicalDeviceVulkan12Features supportedFeaturesVulkan12{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES }; @@ -90,12 +159,22 @@ namespace { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, .pNext = &supportedFeaturesVulkan12 }; - vkGetPhysicalDeviceFeatures2(physdev, &supportedFeatures); + fi.GetPhysicalDeviceFeatures2(physdev, &supportedFeatures); return supportedFeaturesVulkan12.shaderFloat16 == VK_TRUE; } + template + T dpa(const VulkanInstanceFuncs& funcs, VkDevice device, const char* name) { + T func = reinterpret_cast( + funcs.GetDeviceProcAddr(device, name)); + if (!func) + throw ls::vulkan_error("failed to get device proc addr for " + std::string(name)); + return func; + } + /// create a logical device - ls::owned_ptr createLogicalDevice(VkPhysicalDevice physdev, uint32_t cfi, bool fp16) { + ls::owned_ptr createLogicalDevice(const VulkanInstanceFuncs& fi, + VkPhysicalDevice physdev, uint32_t cfi, bool fp16) { VkDevice handle{}; const float queuePriority{1.0F}; // highest priority @@ -124,48 +203,124 @@ namespace { .enabledExtensionCount = static_cast(requestedExtensions.size()), .ppEnabledExtensionNames = requestedExtensions.data() }; - auto res = vkCreateDevice(physdev, &deviceInfo, nullptr, &handle); + auto res = fi.CreateDevice(physdev, &deviceInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateDevice() failed"); + auto defunc = + dpa(fi, handle, "vkDestroyDevice"); + if (!defunc) + throw ls::vulkan_error("failed to get vkDestroyDevice symbol"); return ls::owned_ptr( new VkDevice(handle), - [](VkDevice& device) { - vkDestroyDevice(device, nullptr); + [defunc](VkDevice& device) { + defunc(device, nullptr); } ); } + /// initialize vulkan device function pointers + VulkanDeviceFuncs initVulkanDeviceFuncs(const VulkanInstanceFuncs& f, VkDevice d) { + return { + .GetDeviceQueue = dpa(f, d, "vkGetDeviceQueue"), + .DeviceWaitIdle = dpa(f, d, "vkDeviceWaitIdle"), + .CreateCommandPool = dpa(f, d, "vkCreateCommandPool"), + .DestroyCommandPool = dpa(f, d, "vkDestroyCommandPool"), + .CreateDescriptorPool = dpa(f, d, "vkCreateDescriptorPool"), + .DestroyDescriptorPool = dpa(f, d, "vkDestroyDescriptorPool"), + .CreateBuffer = dpa(f, d, "vkCreateBuffer"), + .DestroyBuffer = dpa(f, d, "vkDestroyBuffer"), + .GetBufferMemoryRequirements = dpa(f, d, + "vkGetBufferMemoryRequirements"), + .AllocateMemory = dpa(f, d, "vkAllocateMemory"), + .FreeMemory = dpa(f, d, "vkFreeMemory"), + .BindBufferMemory = dpa(f, d, "vkBindBufferMemory"), + .MapMemory = dpa(f, d, "vkMapMemory"), + .UnmapMemory = dpa(f, d, "vkUnmapMemory"), + .AllocateCommandBuffers = dpa(f, d, + "vkAllocateCommandBuffers"), + .FreeCommandBuffers = dpa(f, d, "vkFreeCommandBuffers"), + .BeginCommandBuffer = dpa(f, d, "vkBeginCommandBuffer"), + .EndCommandBuffer = dpa(f, d, "vkEndCommandBuffer"), + .CmdPipelineBarrier = dpa(f, d, "vkCmdPipelineBarrier"), + .CmdClearColorImage = dpa(f, d, "vkCmdClearColorImage"), + .CmdBindPipeline = dpa(f, d, "vkCmdBindPipeline"), + .CmdBindDescriptorSets = dpa(f, d, "vkCmdBindDescriptorSets"), + .CmdDispatch = dpa(f, d, "vkCmdDispatch"), + .CmdCopyBufferToImage = dpa(f, d, "vkCmdCopyBufferToImage"), + .QueueSubmit = dpa(f, d, "vkQueueSubmit"), + .AllocateDescriptorSets = dpa(f, d, + "vkAllocateDescriptorSets"), + .FreeDescriptorSets = dpa(f, d, "vkFreeDescriptorSets"), + .UpdateDescriptorSets = dpa(f, d, "vkUpdateDescriptorSets"), + .CreateFence = dpa(f, d, "vkCreateFence"), + .DestroyFence = dpa(f, d, "vkDestroyFence"), + .ResetFences = dpa(f, d, "vkResetFences"), + .WaitForFences = dpa(f, d, "vkWaitForFences"), + .CreateImage = dpa(f, d, "vkCreateImage"), + .DestroyImage = dpa(f, d, "vkDestroyImage"), + .GetImageMemoryRequirements = dpa(f, d, + "vkGetImageMemoryRequirements"), + .BindImageMemory = dpa(f, d, "vkBindImageMemory"), + .CreateImageView = dpa(f, d, "vkCreateImageView"), + .DestroyImageView = dpa(f, d, "vkDestroyImageView"), + .CreateSampler = dpa(f, d, "vkCreateSampler"), + .DestroySampler = dpa(f, d, "vkDestroySampler"), + .CreateSemaphore = dpa(f, d, "vkCreateSemaphore"), + .DestroySemaphore = dpa(f, d, "vkDestroySemaphore"), + .CreateShaderModule = dpa(f, d, "vkCreateShaderModule"), + .DestroyShaderModule = dpa(f, d, "vkDestroyShaderModule"), + .CreateDescriptorSetLayout = dpa(f, d, + "vkCreateDescriptorSetLayout"), + .DestroyDescriptorSetLayout = dpa(f, d, + "vkDestroyDescriptorSetLayout"), + .CreatePipelineLayout = dpa(f, d, "vkCreatePipelineLayout"), + .DestroyPipelineLayout = dpa(f, d, "vkDestroyPipelineLayout"), + .CreateComputePipelines = dpa(f, d, + "vkCreateComputePipelines"), + .DestroyPipeline = dpa(f, d, "vkDestroyPipeline"), + .SignalSemaphore = dpa(f, d, "vkSignalSemaphore"), + .WaitSemaphores = dpa(f, d, "vkWaitSemaphores"), + + .GetMemoryFdKHR = dpa(f, d, "vkGetMemoryFdKHR"), + .ImportSemaphoreFdKHR = dpa(f, d, "vkImportSemaphoreFdKHR"), + .GetSemaphoreFdKHR = dpa(f, d, "vkGetSemaphoreFdKHR"), + }; + } + /// get a queue from the logical device - VkQueue getQueue(VkDevice device, uint32_t cfi) { + VkQueue getQueue(const VulkanDeviceFuncs& fd, + VkDevice device, uint32_t cfi) { VkQueue queue{}; - vkGetDeviceQueue(device, cfi, 0, &queue); + fd.GetDeviceQueue(device, cfi, 0, &queue); return queue; } /// create a command pool - ls::owned_ptr createCommandPool(VkDevice device, uint32_t cfi) { + ls::owned_ptr createCommandPool(const VulkanDeviceFuncs& fd, + VkDevice device, uint32_t cfi) { VkCommandPool handle{}; const VkCommandPoolCreateInfo cmdpoolInfo{ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .queueFamilyIndex = cfi }; - auto res = vkCreateCommandPool(device, &cmdpoolInfo, nullptr, &handle); + auto res = fd.CreateCommandPool(device, &cmdpoolInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateCommandPool() failed"); return ls::owned_ptr( new VkCommandPool(handle), - [dev = device](VkCommandPool& pool) { - vkDestroyCommandPool(dev, pool, nullptr); + [dev = device, defunc = fd.DestroyCommandPool](VkCommandPool& pool) { + defunc(dev, pool, nullptr); } ); } /// create a descriptor pool - ls::owned_ptr createDescriptorPool(VkDevice device) { + ls::owned_ptr createDescriptorPool(const VulkanDeviceFuncs& fd, + VkDevice device) { VkDescriptorPool handle{}; const std::array poolCounts{{ // FIXME: arbitrary limits @@ -181,14 +336,14 @@ namespace { .poolSizeCount = static_cast(poolCounts.size()), .pPoolSizes = poolCounts.data() }; - auto res = vkCreateDescriptorPool(device, &descpoolInfo, nullptr, &handle); + auto res = fd.CreateDescriptorPool(device, &descpoolInfo, nullptr, &handle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkCreateDescriptorPool() failed"); return ls::owned_ptr( new VkDescriptorPool(handle), - [dev = device](VkDescriptorPool& pool) { - vkDestroyDescriptorPool(dev, pool, nullptr); + [dev = device, defunc = fd.DestroyDescriptorPool](VkDescriptorPool& pool) { + defunc(dev, pool, nullptr); } ); } @@ -201,23 +356,28 @@ Vulkan::Vulkan(const std::string& appName, version appVersion, appName, appVersion, engineName, engineVersion )), - physdev(findPhysicalDevice( + instance_funcs(initVulkanInstanceFuncs(*this->instance)), + physdev(findPhysicalDevice(this->instance_funcs, *this->instance, selectPhysicalDevice )), - computeFamilyIdx(findQFI(this->physdev, VK_QUEUE_COMPUTE_BIT)), - fp16(checkFP16(this->physdev)), - device(createLogicalDevice( + computeFamilyIdx(findQFI(this->instance_funcs, this->physdev, VK_QUEUE_COMPUTE_BIT)), + fp16(checkFP16(this->instance_funcs, this->physdev)), + device(createLogicalDevice(this->instance_funcs, this->physdev, this->computeFamilyIdx, this->fp16 )), - computeQueue(getQueue(*this->device, this->computeFamilyIdx)), - cmdPool(createCommandPool( + device_funcs(initVulkanDeviceFuncs( + this->instance_funcs, + *this->device + )), + computeQueue(getQueue(this->device_funcs, *this->device, this->computeFamilyIdx)), + cmdPool(createCommandPool(this->device_funcs, *this->device, this->computeFamilyIdx )), - descPool(createDescriptorPool( + descPool(createDescriptorPool(this->device_funcs, *this->device )) { } @@ -229,7 +389,7 @@ std::optional Vulkan::findMemoryTypeIndex( VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VkPhysicalDeviceMemoryProperties props; - vkGetPhysicalDeviceMemoryProperties(this->physdev, &props); + this->instance_funcs.GetPhysicalDeviceMemoryProperties(this->physdev, &props); std::array memTypes = std::to_array(props.memoryTypes); for (uint32_t i = 0; i < props.memoryTypeCount; ++i) diff --git a/lsfg-vk-debug/src/debug.cpp b/lsfg-vk-debug/src/debug.cpp index c6e9986..9e87af2 100644 --- a/lsfg-vk-debug/src/debug.cpp +++ b/lsfg-vk-debug/src/debug.cpp @@ -60,7 +60,7 @@ namespace { VK_BUFFER_USAGE_TRANSFER_SRC_BIT}; const vk::CommandBuffer cmdbuf{vk}; - cmdbuf.copyBufferToImage(stagingbuf, image); + cmdbuf.copyBufferToImage(vk, stagingbuf, image); const vk::TimelineSemaphore sema{vk, 0}; cmdbuf.submit(vk, sema, 1, sema, 2); @@ -77,7 +77,8 @@ int main() { const vk::Vulkan vk{ "lsfg-vk-debug", vk::version{1, 1, 0}, "lsfg-vk-debug-engine", vk::version{1, 0, 0}, - [](const std::vector& devices) { + [](const vk::VulkanInstanceFuncs, + const std::vector& devices) { return devices.front(); } };