From dc11a64c0a45d1afe463b89587fbe6a74fa034a7 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Sun, 29 Jun 2025 20:20:02 +0200 Subject: [PATCH] general cleanup --- include/core/buffer.hpp | 6 ------ include/core/commandbuffer.hpp | 7 ------- include/core/commandpool.hpp | 6 ------ include/core/descriptorpool.hpp | 6 ------ include/core/descriptorset.hpp | 10 ---------- include/core/fence.hpp | 14 +++++-------- include/core/image.hpp | 6 ------ include/core/pipeline.hpp | 8 -------- include/core/sampler.hpp | 6 ------ include/core/semaphore.hpp | 13 ++++-------- include/core/shadermodule.hpp | 6 ------ include/device.hpp | 6 ------ include/instance.hpp | 5 ----- src/core/buffer.cpp | 21 ++++++++------------ src/core/commandbuffer.cpp | 25 +++++++---------------- src/core/commandpool.cpp | 7 ++----- src/core/descriptorpool.cpp | 7 ++----- src/core/descriptorset.cpp | 35 +++++---------------------------- src/core/fence.cpp | 16 ++++++--------- src/core/image.cpp | 33 +++++++++++++------------------ src/core/pipeline.cpp | 24 ++++++++-------------- src/core/sampler.cpp | 5 +---- src/core/semaphore.cpp | 14 +++++-------- src/core/shadermodule.cpp | 19 +++++++----------- src/device.cpp | 3 --- src/main.cpp | 2 +- 26 files changed, 75 insertions(+), 235 deletions(-) diff --git a/include/core/buffer.hpp b/include/core/buffer.hpp index 5f9ac61..073bb3f 100644 --- a/include/core/buffer.hpp +++ b/include/core/buffer.hpp @@ -25,7 +25,6 @@ namespace Vulkan::Core { /// @param data Initial data for the buffer. /// @param usage Usage flags for the buffer /// - /// @throws std::invalid_argument if the device or buffer size is invalid /// @throws ls::vulkan_error if object creation fails. /// Buffer(const Device& device, size_t size, std::vector data, @@ -36,11 +35,6 @@ namespace Vulkan::Core { /// Get the size of the buffer. [[nodiscard]] size_t getSize() const { return this->size; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->buffer); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible Buffer(const Buffer&) noexcept = default; Buffer& operator=(const Buffer&) noexcept = default; diff --git a/include/core/commandbuffer.hpp b/include/core/commandbuffer.hpp index b01cf16..67f1c4e 100644 --- a/include/core/commandbuffer.hpp +++ b/include/core/commandbuffer.hpp @@ -41,7 +41,6 @@ namespace Vulkan::Core { /// @param device Vulkan device /// @param pool Vulkan command pool /// - /// @throws std::invalid_argument if the device or pool are invalid. /// @throws ls::vulkan_error if object creation fails. /// CommandBuffer(const Device& device, const CommandPool& pool); @@ -83,7 +82,6 @@ namespace Vulkan::Core { /// @param signalSemaphores Semaphores to signal after executing the command buffer /// @param signalSemaphoreValues Values for the semaphores to signal /// - /// @throws std::invalid_argument if the queue is null. /// @throws std::logic_error if the command buffer is not in Full state. /// @throws ls::vulkan_error if submission fails. /// @@ -98,11 +96,6 @@ namespace Vulkan::Core { /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->commandBuffer; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->commandBuffer); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible CommandBuffer(const CommandBuffer&) noexcept = default; CommandBuffer& operator=(const CommandBuffer&) noexcept = default; diff --git a/include/core/commandpool.hpp b/include/core/commandpool.hpp index 3936983..7470d86 100644 --- a/include/core/commandpool.hpp +++ b/include/core/commandpool.hpp @@ -21,7 +21,6 @@ namespace Vulkan::Core { /// /// @param device Vulkan device /// - /// @throws std::invalid_argument if the device is invalid. /// @throws ls::vulkan_error if object creation fails. /// CommandPool(const Device& device); @@ -29,11 +28,6 @@ namespace Vulkan::Core { /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->commandPool; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->commandPool); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible CommandPool(const CommandPool&) noexcept = default; CommandPool& operator=(const CommandPool&) noexcept = default; diff --git a/include/core/descriptorpool.hpp b/include/core/descriptorpool.hpp index 9b4d470..2227a66 100644 --- a/include/core/descriptorpool.hpp +++ b/include/core/descriptorpool.hpp @@ -21,7 +21,6 @@ namespace Vulkan::Core { /// /// @param device Vulkan device /// - /// @throws std::invalid_argument if the device is invalid. /// @throws ls::vulkan_error if object creation fails. /// DescriptorPool(const Device& device); @@ -29,11 +28,6 @@ namespace Vulkan::Core { /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->descriptorPool; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->descriptorPool); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible DescriptorPool(const DescriptorPool&) noexcept = default; DescriptorPool& operator=(const DescriptorPool&) noexcept = default; diff --git a/include/core/descriptorset.hpp b/include/core/descriptorset.hpp index 2bbb922..339ea54 100644 --- a/include/core/descriptorset.hpp +++ b/include/core/descriptorset.hpp @@ -31,7 +31,6 @@ namespace Vulkan::Core { /// @param pool Descriptor pool to allocate from /// @param shaderModule Shader module to use for the descriptor set /// - /// @throws std::invalid_argument if the device, pool or shader module is invalid. /// @throws ls::vulkan_error if object creation fails. /// DescriptorSet(const Device& device, @@ -45,8 +44,6 @@ namespace Vulkan::Core { /// @param device Vulkan device /// @param resources Resources to update the descriptor set with /// - /// @throws std::invalid_argument if the device or resources are invalid. - /// void update(const Device& device, const std::vector>& resources) const; @@ -56,18 +53,11 @@ namespace Vulkan::Core { /// @param commandBuffer Command buffer to bind the descriptor set to. /// @param pipeline Pipeline to bind the descriptor set to. /// - /// @throws std::invalid_argument if the command buffer or pipeline is invalid. - /// void bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const; /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->descriptorSet; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->descriptorSet); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible DescriptorSet(const DescriptorSet&) noexcept = default; DescriptorSet& operator=(const DescriptorSet&) noexcept = default; diff --git a/include/core/fence.hpp b/include/core/fence.hpp index 8900840..e12fe06 100644 --- a/include/core/fence.hpp +++ b/include/core/fence.hpp @@ -21,7 +21,6 @@ namespace Vulkan::Core { /// /// @param device Vulkan device /// - /// @throws std::invalid_argument if the device is invalid. /// @throws ls::vulkan_error if object creation fails. /// Fence(const Device& device); @@ -29,28 +28,26 @@ namespace Vulkan::Core { /// /// Reset the fence to an unsignaled state. /// + /// @param device Vulkan device + /// /// @throws ls::vulkan_error if resetting fails. /// - void reset() const; + void reset(const Device& device) const; /// /// Wait for the fence /// + /// @param device Vulkan device /// @param timeout The timeout in nanoseconds, or UINT64_MAX for no timeout. /// @returns true if the fence signaled, false if it timed out. /// /// @throws ls::vulkan_error if waiting fails. /// - [[nodiscard]] bool wait(uint64_t timeout = UINT64_MAX) const; + [[nodiscard]] bool wait(const Device& device, uint64_t timeout = UINT64_MAX) const; /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->fence; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->fence); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - // Trivially copyable, moveable and destructible Fence(const Fence&) noexcept = default; Fence& operator=(const Fence&) noexcept = default; @@ -59,7 +56,6 @@ namespace Vulkan::Core { ~Fence() = default; private: std::shared_ptr fence; - VkDevice device{}; }; } diff --git a/include/core/image.hpp b/include/core/image.hpp index 9fe3d52..254dd88 100644 --- a/include/core/image.hpp +++ b/include/core/image.hpp @@ -25,7 +25,6 @@ namespace Vulkan::Core { /// @param usage Usage flags for the image /// @param aspectFlags Aspect flags for the image view /// - /// @throws std::invalid_argument if the device is invalid. /// @throws ls::vulkan_error if object creation fails. /// Image(const Device& device, VkExtent2D extent, VkFormat format, @@ -40,11 +39,6 @@ namespace Vulkan::Core { /// Get the format of the image. [[nodiscard]] VkFormat getFormat() const { return this->format; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->image); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible Image(const Image&) noexcept = default; Image& operator=(const Image&) noexcept = default; diff --git a/include/core/pipeline.hpp b/include/core/pipeline.hpp index b51ec14..b90fb94 100644 --- a/include/core/pipeline.hpp +++ b/include/core/pipeline.hpp @@ -24,7 +24,6 @@ namespace Vulkan::Core { /// @param device Vulkan device /// @param shader Shader module to use for the pipeline. /// - /// @throws std::invalid_argument if the device or shader module is invalid. /// @throws ls::vulkan_error if object creation fails. /// Pipeline(const Device& device, const ShaderModule& shader); @@ -34,8 +33,6 @@ namespace Vulkan::Core { /// /// @param commandBuffer Command buffer to bind the pipeline to. /// - /// @throws std::invalid_argument if the command buffer is invalid. - /// void bind(const CommandBuffer& commandBuffer) const; /// Get the Vulkan handle. @@ -43,11 +40,6 @@ namespace Vulkan::Core { /// Get the pipeline layout. [[nodiscard]] auto getLayout() const { return *this->layout; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->pipeline); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible Pipeline(const Pipeline&) noexcept = default; Pipeline& operator=(const Pipeline&) noexcept = default; diff --git a/include/core/sampler.hpp b/include/core/sampler.hpp index 84ce43a..b1f9b55 100644 --- a/include/core/sampler.hpp +++ b/include/core/sampler.hpp @@ -22,7 +22,6 @@ namespace Vulkan::Core { /// @param device Vulkan device /// @param mode Address mode for the sampler. /// - /// @throws std::invalid_argument if the device is invalid. /// @throws ls::vulkan_error if object creation fails. /// Sampler(const Device& device, VkSamplerAddressMode mode); @@ -30,11 +29,6 @@ namespace Vulkan::Core { /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->sampler; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->sampler); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible Sampler(const Sampler&) noexcept = default; Sampler& operator=(const Sampler&) noexcept = default; diff --git a/include/core/semaphore.hpp b/include/core/semaphore.hpp index 46c3683..30168b2 100644 --- a/include/core/semaphore.hpp +++ b/include/core/semaphore.hpp @@ -23,7 +23,6 @@ namespace Vulkan::Core { /// @param device Vulkan device /// @param initial Optional initial value for creating a timeline semaphore. /// - /// @throws std::invalid_argument if the device is null. /// @throws ls::vulkan_error if object creation fails. /// Semaphore(const Device& device, std::optional initial = std::nullopt); @@ -31,16 +30,18 @@ namespace Vulkan::Core { /// /// Signal the semaphore to a specific value. /// + /// @param device Vulkan device /// @param value The value to signal the semaphore to. /// /// @throws std::logic_error if the semaphore is not a timeline semaphore. /// @throws ls::vulkan_error if signaling fails. /// - void signal(uint64_t value) const; + void signal(const Device& device, uint64_t value) const; /// /// Wait for the semaphore to reach a specific value. /// + /// @param device Vulkan device /// @param value The value to wait for. /// @param timeout The timeout in nanoseconds, or UINT64_MAX for no timeout. /// @returns true if the semaphore reached the value, false if it timed out. @@ -48,16 +49,11 @@ namespace Vulkan::Core { /// @throws std::logic_error if the semaphore is not a timeline semaphore. /// @throws ls::vulkan_error if waiting fails. /// - [[nodiscard]] bool wait(uint64_t value, uint64_t timeout = UINT64_MAX) const; + [[nodiscard]] bool wait(const Device& device, uint64_t value, uint64_t timeout = UINT64_MAX) const; /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return *this->semaphore; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->semaphore); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - // Trivially copyable, moveable and destructible Semaphore(const Semaphore&) noexcept = default; Semaphore& operator=(const Semaphore&) noexcept = default; @@ -66,7 +62,6 @@ namespace Vulkan::Core { ~Semaphore() = default; private: std::shared_ptr semaphore; - VkDevice device{}; bool isTimeline{}; }; diff --git a/include/core/shadermodule.hpp b/include/core/shadermodule.hpp index 0cce6df..fcfcf5b 100644 --- a/include/core/shadermodule.hpp +++ b/include/core/shadermodule.hpp @@ -26,7 +26,6 @@ namespace Vulkan::Core { /// @param path Path to the shader file. /// @param descriptorTypes Descriptor types used in the shader. /// - /// @throws std::invalid_argument if the device is invalid. /// @throws std::system_error if the shader file cannot be opened or read. /// @throws ls::vulkan_error if object creation fails. /// @@ -38,11 +37,6 @@ namespace Vulkan::Core { /// Get the descriptor set layout. [[nodiscard]] auto getDescriptorSetLayout() const { return *this->descriptorSetLayout; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->shaderModule); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible ShaderModule(const ShaderModule&) noexcept = default; ShaderModule& operator=(const ShaderModule&) noexcept = default; diff --git a/include/device.hpp b/include/device.hpp index 3e70c65..ef9ddcf 100644 --- a/include/device.hpp +++ b/include/device.hpp @@ -21,7 +21,6 @@ namespace Vulkan { /// /// @param instance Vulkan instance /// - /// @throws std::invalid_argument if the instance is invalid. /// @throws ls::vulkan_error if object creation fails. /// Device(const Vulkan::Instance& instance); @@ -35,11 +34,6 @@ namespace Vulkan { /// Get the compute queue. [[nodiscard]] VkQueue getComputeQueue() const { return this->computeQueue; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return static_cast(this->device); } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - // Trivially copyable, moveable and destructible Device(const Device&) noexcept = default; Device& operator=(const Device&) noexcept = default; diff --git a/include/instance.hpp b/include/instance.hpp index affd0c6..7b9d7ff 100644 --- a/include/instance.hpp +++ b/include/instance.hpp @@ -24,11 +24,6 @@ namespace Vulkan { /// Get the Vulkan handle. [[nodiscard]] auto handle() const { return this->instance ? *this->instance : VK_NULL_HANDLE; } - /// Check whether the object is valid. - [[nodiscard]] bool isValid() const { return this->handle() != VK_NULL_HANDLE; } - /// if (obj) operator. Checks if the object is valid. - explicit operator bool() const { return this->isValid(); } - /// Trivially copyable, moveable and destructible Instance(const Instance&) noexcept = default; Instance& operator=(const Instance&) noexcept = default; diff --git a/src/core/buffer.cpp b/src/core/buffer.cpp index 9ef9a78..823a765 100644 --- a/src/core/buffer.cpp +++ b/src/core/buffer.cpp @@ -8,11 +8,6 @@ using namespace Vulkan::Core; Buffer::Buffer(const Device& device, size_t size, std::vector data, VkBufferUsageFlags usage) : size(size) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - if (size < data.size()) - throw std::invalid_argument("Invalid buffer size"); - // create buffer const VkBufferCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, @@ -62,6 +57,14 @@ Buffer::Buffer(const Device& device, size_t size, std::vector data, if (res != VK_SUCCESS) throw ls::vulkan_error(res, "Failed to bind memory to Vulkan buffer"); + // upload data to buffer + uint8_t* buf{}; + res = vkMapMemory(device.handle(), memoryHandle, 0, size, 0, reinterpret_cast(&buf)); + if (res != VK_SUCCESS || buf == nullptr) + throw ls::vulkan_error(res, "Failed to map memory for Vulkan buffer"); + std::copy_n(data.data(), std::min(size, data.size()), buf); + vkUnmapMemory(device.handle(), memoryHandle); + // store buffer and memory in shared ptr this->buffer = std::shared_ptr( new VkBuffer(bufferHandle), @@ -75,12 +78,4 @@ Buffer::Buffer(const Device& device, size_t size, std::vector data, vkFreeMemory(dev, *mem, nullptr); } ); - - // upload data to buffer - uint8_t* buf{}; - res = vkMapMemory(device.handle(), memoryHandle, 0, size, 0, reinterpret_cast(&buf)); - if (res != VK_SUCCESS || buf == nullptr) - throw ls::vulkan_error(res, "Failed to map memory for Vulkan buffer"); - std::copy_n(data.data(), size, buf); - vkUnmapMemory(device.handle(), memoryHandle); } diff --git a/src/core/commandbuffer.cpp b/src/core/commandbuffer.cpp index fa50bab..5affc4e 100644 --- a/src/core/commandbuffer.cpp +++ b/src/core/commandbuffer.cpp @@ -4,11 +4,8 @@ using namespace Vulkan::Core; CommandBuffer::CommandBuffer(const Device& device, const CommandPool& pool) { - if (!device || !pool) - throw std::invalid_argument("Invalid Vulkan device or command pool"); - // create command buffer - const VkCommandBufferAllocateInfo desc = { + const VkCommandBufferAllocateInfo desc{ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .commandPool = pool.handle(), .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, @@ -67,14 +64,12 @@ void CommandBuffer::submit(VkQueue queue, std::optional fence, std::optional> waitSemaphoreValues, const std::vector& signalSemaphores, std::optional> signalSemaphoreValues) { - if (!queue) - throw std::invalid_argument("Invalid Vulkan queue"); if (*this->state != CommandBufferState::Full) throw std::logic_error("Command buffer is not in Full state"); const std::vector waitStages(waitSemaphores.size(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); - VkTimelineSemaphoreSubmitInfo timelineInfo = { + VkTimelineSemaphoreSubmitInfo timelineInfo{ .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, }; if (waitSemaphoreValues.has_value()) { @@ -88,20 +83,14 @@ void CommandBuffer::submit(VkQueue queue, std::optional fence, timelineInfo.pSignalSemaphoreValues = signalSemaphoreValues->data(); } - std::vector waitSemaphoresHandles; - for (const auto& semaphore : waitSemaphores) { - if (!semaphore) - throw std::invalid_argument("Invalid Vulkan semaphore in waitSemaphores"); + std::vector waitSemaphoresHandles(waitSemaphores.size()); + for (const auto& semaphore : waitSemaphores) waitSemaphoresHandles.push_back(semaphore.handle()); - } - std::vector signalSemaphoresHandles; - for (const auto& semaphore : signalSemaphores) { - if (!semaphore) - throw std::invalid_argument("Invalid Vulkan semaphore in signalSemaphores"); + std::vector signalSemaphoresHandles(signalSemaphores.size()); + for (const auto& semaphore : signalSemaphores) signalSemaphoresHandles.push_back(semaphore.handle()); - } - const VkSubmitInfo submitInfo = { + const VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .pNext = (waitSemaphoreValues.has_value() || signalSemaphoreValues.has_value()) ? &timelineInfo : nullptr, diff --git a/src/core/commandpool.cpp b/src/core/commandpool.cpp index 6061e37..e1fba1c 100644 --- a/src/core/commandpool.cpp +++ b/src/core/commandpool.cpp @@ -4,11 +4,8 @@ using namespace Vulkan::Core; CommandPool::CommandPool(const Device& device) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - // create command pool - const VkCommandPoolCreateInfo desc = { + const VkCommandPoolCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .queueFamilyIndex = device.getComputeFamilyIdx() }; @@ -17,7 +14,7 @@ CommandPool::CommandPool(const Device& device) { if (res != VK_SUCCESS || commandPoolHandle == VK_NULL_HANDLE) throw ls::vulkan_error(res, "Unable to create command pool"); - // store the command pool in a shared pointer + // store command pool in shared ptr this->commandPool = std::shared_ptr( new VkCommandPool(commandPoolHandle), [dev = device.handle()](VkCommandPool* commandPoolHandle) { diff --git a/src/core/descriptorpool.cpp b/src/core/descriptorpool.cpp index 340092e..fb49ecf 100644 --- a/src/core/descriptorpool.cpp +++ b/src/core/descriptorpool.cpp @@ -6,9 +6,6 @@ using namespace Vulkan::Core; DescriptorPool::DescriptorPool(const Device& device) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - // create descriptor pool const std::array pools{{ // arbitrary limits { .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 4096 }, @@ -18,7 +15,7 @@ DescriptorPool::DescriptorPool(const Device& device) { }}; const VkDescriptorPoolCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .maxSets = 16384, // arbitrary limit + .maxSets = 16384, .poolSizeCount = static_cast(pools.size()), .pPoolSizes = pools.data() }; @@ -27,7 +24,7 @@ DescriptorPool::DescriptorPool(const Device& device) { if (res != VK_SUCCESS || poolHandle == VK_NULL_HANDLE) throw ls::vulkan_error(res, "Unable to create descriptor pool"); - /// store pool in shared ptr + // store pool in shared ptr this->descriptorPool = std::shared_ptr( new VkDescriptorPool(poolHandle), [dev = device.handle()](VkDescriptorPool* poolHandle) { diff --git a/src/core/descriptorset.cpp b/src/core/descriptorset.cpp index a483b36..36b6ae6 100644 --- a/src/core/descriptorset.cpp +++ b/src/core/descriptorset.cpp @@ -5,9 +5,6 @@ using namespace Vulkan::Core; DescriptorSet::DescriptorSet(const Device& device, DescriptorPool pool, const ShaderModule& shaderModule) { - if (!device || !pool) - throw std::invalid_argument("Invalid Vulkan device"); - // create descriptor set VkDescriptorSetLayout layout = shaderModule.getDescriptorSetLayout(); const VkDescriptorSetAllocateInfo desc{ @@ -21,7 +18,7 @@ DescriptorSet::DescriptorSet(const Device& device, if (res != VK_SUCCESS || descriptorSetHandle == VK_NULL_HANDLE) throw ls::vulkan_error(res, "Unable to allocate descriptor set"); - /// store descriptor set in shared ptr + /// store set in shared ptr this->descriptorSet = std::shared_ptr( new VkDescriptorSet(descriptorSetHandle), [dev = device.handle(), pool = std::move(pool)](VkDescriptorSet* setHandle) { @@ -32,9 +29,6 @@ DescriptorSet::DescriptorSet(const Device& device, void DescriptorSet::update(const Device& device, const std::vector>& resources) const { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - std::vector writeDescriptorSets; uint32_t bindingIndex = 0; for (const auto& list : resources) { @@ -48,36 +42,23 @@ void DescriptorSet::update(const Device& device, }; if (std::holds_alternative(resource)) { - const auto& image = std::get(resource); - if (!image) - throw std::invalid_argument("Invalid image resource"); - const VkDescriptorImageInfo imageInfo{ - .imageView = image.getView(), + .imageView = std::get(resource).getView(), .imageLayout = VK_IMAGE_LAYOUT_GENERAL }; writeDesc.pImageInfo = &imageInfo; } else if (std::holds_alternative(resource)) { - const auto& sampler = std::get(resource); - if (!sampler) - throw std::invalid_argument("Invalid sampler resource"); - const VkDescriptorImageInfo imageInfo{ - .sampler = sampler.handle() + .sampler = std::get(resource).handle() }; writeDesc.pImageInfo = &imageInfo; } else if (std::holds_alternative(resource)) { const auto& buffer = std::get(resource); - if (!buffer) - throw std::invalid_argument("Invalid buffer resource"); - const VkDescriptorBufferInfo bufferInfo{ .buffer = buffer.handle(), .range = buffer.getSize() }; writeDesc.pBufferInfo = &bufferInfo; - } else { - throw std::invalid_argument("Unsupported resource type"); } writeDescriptorSets.push_back(writeDesc); @@ -86,18 +67,12 @@ void DescriptorSet::update(const Device& device, vkUpdateDescriptorSets(device.handle(), static_cast(writeDescriptorSets.size()), - writeDescriptorSets.data(), - 0, nullptr); + writeDescriptorSets.data(), 0, nullptr); } void DescriptorSet::bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const { - if (!commandBuffer) - throw std::invalid_argument("Invalid command buffer"); - - // bind descriptor set VkDescriptorSet descriptorSetHandle = this->handle(); vkCmdBindDescriptorSets(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getLayout(), - 0, 1, &descriptorSetHandle, - 0, nullptr); + 0, 1, &descriptorSetHandle, 0, nullptr); } diff --git a/src/core/fence.cpp b/src/core/fence.cpp index e864340..3108ede 100644 --- a/src/core/fence.cpp +++ b/src/core/fence.cpp @@ -4,11 +4,8 @@ using namespace Vulkan::Core; Fence::Fence(const Device& device) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - - // create fence - const VkFenceCreateInfo desc = { + // create fence + const VkFenceCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; VkFence fenceHandle{}; @@ -17,7 +14,6 @@ Fence::Fence(const Device& device) { throw ls::vulkan_error(res, "Unable to create fence"); // store fence in shared ptr - this->device = device.handle(); this->fence = std::shared_ptr( new VkFence(fenceHandle), [dev = device.handle()](VkFence* fenceHandle) { @@ -26,16 +22,16 @@ Fence::Fence(const Device& device) { ); } -void Fence::reset() const { +void Fence::reset(const Device& device) const { VkFence fenceHandle = this->handle(); - auto res = vkResetFences(this->device, 1, &fenceHandle); + auto res = vkResetFences(device.handle(), 1, &fenceHandle); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "Unable to reset fence"); } -bool Fence::wait(uint64_t timeout) const { +bool Fence::wait(const Device& device, uint64_t timeout) const { VkFence fenceHandle = this->handle(); - auto res = vkWaitForFences(this->device, 1, &fenceHandle, VK_TRUE, timeout); + auto res = vkWaitForFences(device.handle(), 1, &fenceHandle, VK_TRUE, timeout); if (res != VK_SUCCESS && res != VK_TIMEOUT) throw ls::vulkan_error(res, "Unable to wait for fence"); diff --git a/src/core/image.cpp b/src/core/image.cpp index 5c8eb38..a976f3b 100644 --- a/src/core/image.cpp +++ b/src/core/image.cpp @@ -8,9 +8,6 @@ using namespace Vulkan::Core; Image::Image(const Device& device, VkExtent2D extent, VkFormat format, VkImageUsageFlags usage, VkImageAspectFlags aspectFlags) : extent(extent), format(format) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - // create image const VkImageCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -68,24 +65,10 @@ Image::Image(const Device& device, VkExtent2D extent, VkFormat format, if (res != VK_SUCCESS) throw ls::vulkan_error(res, "Failed to bind memory to Vulkan image"); - // store image and memory in shared ptr - this->image = std::shared_ptr( - new VkImage(imageHandle), - [dev = device.handle()](VkImage* img) { - vkDestroyImage(dev, *img, nullptr); - } - ); - this->memory = std::shared_ptr( - new VkDeviceMemory(memoryHandle), - [dev = device.handle()](VkDeviceMemory* mem) { - vkFreeMemory(dev, *mem, nullptr); - } - ); - // create image view const VkImageViewCreateInfo viewDesc{ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = *this->image, + .image = imageHandle, .viewType = VK_IMAGE_VIEW_TYPE_2D, .format = format, .components = { @@ -106,7 +89,19 @@ Image::Image(const Device& device, VkExtent2D extent, VkFormat format, if (res != VK_SUCCESS || viewHandle == VK_NULL_HANDLE) throw ls::vulkan_error(res, "Failed to create image view"); - // store image view in shared ptr + // store objects in shared ptr + this->image = std::shared_ptr( + new VkImage(imageHandle), + [dev = device.handle()](VkImage* img) { + vkDestroyImage(dev, *img, nullptr); + } + ); + this->memory = std::shared_ptr( + new VkDeviceMemory(memoryHandle), + [dev = device.handle()](VkDeviceMemory* mem) { + vkFreeMemory(dev, *mem, nullptr); + } + ); this->view = std::shared_ptr( new VkImageView(viewHandle), [dev = device.handle()](VkImageView* imgView) { diff --git a/src/core/pipeline.cpp b/src/core/pipeline.cpp index ac0cc31..e20b040 100644 --- a/src/core/pipeline.cpp +++ b/src/core/pipeline.cpp @@ -4,9 +4,6 @@ using namespace Vulkan::Core; Pipeline::Pipeline(const Device& device, const ShaderModule& shader) { - if (!device || !shader) - throw std::invalid_argument("Invalid Vulkan device or shader module"); - // create pipeline layout VkDescriptorSetLayout shaderLayout = shader.getDescriptorSetLayout(); const VkPipelineLayoutCreateInfo layoutDesc{ @@ -19,14 +16,6 @@ Pipeline::Pipeline(const Device& device, const ShaderModule& shader) { if (res != VK_SUCCESS || !layoutHandle) throw ls::vulkan_error(res, "Failed to create pipeline layout"); - // store layout in shared ptr - this->layout = std::shared_ptr( - new VkPipelineLayout(layoutHandle), - [dev = device.handle()](VkPipelineLayout* layout) { - vkDestroyPipelineLayout(dev, *layout, nullptr); - } - ); - // create pipeline const VkPipelineShaderStageCreateInfo shaderStageInfo{ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, @@ -45,7 +34,13 @@ Pipeline::Pipeline(const Device& device, const ShaderModule& shader) { if (res != VK_SUCCESS || !pipelineHandle) throw ls::vulkan_error(res, "Failed to create compute pipeline"); - // store pipeline in shared ptr + // store layout and pipeline in shared ptr + this->layout = std::shared_ptr( + new VkPipelineLayout(layoutHandle), + [dev = device.handle()](VkPipelineLayout* layout) { + vkDestroyPipelineLayout(dev, *layout, nullptr); + } + ); this->pipeline = std::shared_ptr( new VkPipeline(pipelineHandle), [dev = device.handle()](VkPipeline* pipeline) { @@ -55,8 +50,5 @@ Pipeline::Pipeline(const Device& device, const ShaderModule& shader) { } void Pipeline::bind(const CommandBuffer& commandBuffer) const { - if (!commandBuffer) - throw std::invalid_argument("Invalid command buffer"); - - vkCmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, *this->pipeline); + vkCmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, *this->pipeline); } diff --git a/src/core/sampler.cpp b/src/core/sampler.cpp index e817e54..2f7d5a0 100644 --- a/src/core/sampler.cpp +++ b/src/core/sampler.cpp @@ -4,9 +4,6 @@ using namespace Vulkan::Core; Sampler::Sampler(const Device& device, VkSamplerAddressMode mode) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - // create sampler const VkSamplerCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, @@ -23,7 +20,7 @@ Sampler::Sampler(const Device& device, VkSamplerAddressMode mode) { if (res != VK_SUCCESS || samplerHandle == VK_NULL_HANDLE) throw ls::vulkan_error(res, "Unable to create sampler"); - // store the sampler in a shared pointer + // store sampler in shared ptr this->sampler = std::shared_ptr( new VkSampler(samplerHandle), [dev = device.handle()](VkSampler* samplerHandle) { diff --git a/src/core/semaphore.cpp b/src/core/semaphore.cpp index 7008764..510a1e9 100644 --- a/src/core/semaphore.cpp +++ b/src/core/semaphore.cpp @@ -4,16 +4,13 @@ using namespace Vulkan::Core; Semaphore::Semaphore(const Device& device, std::optional initial) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - // create semaphore const VkSemaphoreTypeCreateInfo typeInfo{ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, .initialValue = initial.value_or(0) }; - const VkSemaphoreCreateInfo desc = { + const VkSemaphoreCreateInfo desc{ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .pNext = initial.has_value() ? &typeInfo : nullptr, }; @@ -24,7 +21,6 @@ Semaphore::Semaphore(const Device& device, std::optional initial) { // store semaphore in shared ptr this->isTimeline = initial.has_value(); - this->device = device.handle(); this->semaphore = std::shared_ptr( new VkSemaphore(semaphoreHandle), [dev = device.handle()](VkSemaphore* semaphoreHandle) { @@ -33,7 +29,7 @@ Semaphore::Semaphore(const Device& device, std::optional initial) { ); } -void Semaphore::signal(uint64_t value) const { +void Semaphore::signal(const Device& device, uint64_t value) const { if (!this->isTimeline) throw std::logic_error("Invalid timeline semaphore"); @@ -42,12 +38,12 @@ void Semaphore::signal(uint64_t value) const { .semaphore = this->handle(), .value = value }; - auto res = vkSignalSemaphore(this->device, &signalInfo); + auto res = vkSignalSemaphore(device.handle(), &signalInfo); if (res != VK_SUCCESS) throw ls::vulkan_error(res, "Unable to signal semaphore"); } -bool Semaphore::wait(uint64_t value, uint64_t timeout) const { +bool Semaphore::wait(const Device& device, uint64_t value, uint64_t timeout) const { if (!this->isTimeline) throw std::logic_error("Invalid timeline semaphore"); @@ -58,7 +54,7 @@ bool Semaphore::wait(uint64_t value, uint64_t timeout) const { .pSemaphores = &semaphore, .pValues = &value }; - auto res = vkWaitSemaphores(this->device, &waitInfo, timeout); + auto res = vkWaitSemaphores(device.handle(), &waitInfo, timeout); if (res != VK_SUCCESS && res != VK_TIMEOUT) throw ls::vulkan_error(res, "Unable to wait for semaphore"); diff --git a/src/core/shadermodule.cpp b/src/core/shadermodule.cpp index 4d777b3..006832d 100644 --- a/src/core/shadermodule.cpp +++ b/src/core/shadermodule.cpp @@ -7,9 +7,6 @@ using namespace Vulkan::Core; ShaderModule::ShaderModule(const Device& device, const std::string& path, const std::vector>& descriptorTypes) { - if (!device) - throw std::invalid_argument("Invalid Vulkan device"); - // read shader bytecode std::ifstream file(path, std::ios::ate | std::ios::binary); if (!file) @@ -36,14 +33,6 @@ ShaderModule::ShaderModule(const Device& device, const std::string& path, if (res != VK_SUCCESS || !shaderModuleHandle) throw ls::vulkan_error(res, "Failed to create shader module"); - // store shader module in shared ptr - this->shaderModule = std::shared_ptr( - new VkShaderModule(shaderModuleHandle), - [dev = device.handle()](VkShaderModule* shaderModuleHandle) { - vkDestroyShaderModule(dev, *shaderModuleHandle, nullptr); - } - ); - // create descriptor set layout std::vector layoutBindings; size_t bindIdx = 0; @@ -66,7 +55,13 @@ ShaderModule::ShaderModule(const Device& device, const std::string& path, if (res != VK_SUCCESS || !descriptorSetLayout) throw ls::vulkan_error(res, "Failed to create descriptor set layout"); - // store layout in shared ptr + // store module and layout in shared ptr + this->shaderModule = std::shared_ptr( + new VkShaderModule(shaderModuleHandle), + [dev = device.handle()](VkShaderModule* shaderModuleHandle) { + vkDestroyShaderModule(dev, *shaderModuleHandle, nullptr); + } + ); this->descriptorSetLayout = std::shared_ptr( new VkDescriptorSetLayout(descriptorSetLayout), [dev = device.handle()](VkDescriptorSetLayout* layout) { diff --git a/src/device.cpp b/src/device.cpp index d8e1bcf..894322a 100644 --- a/src/device.cpp +++ b/src/device.cpp @@ -7,9 +7,6 @@ using namespace Vulkan; Device::Device(const Instance& instance) { - if (!instance) - throw std::invalid_argument("Invalid Vulkan instance"); - // get all physical devices uint32_t deviceCount{}; auto res = vkEnumeratePhysicalDevices(instance.handle(), &deviceCount, nullptr); diff --git a/src/main.cpp b/src/main.cpp index 6094deb..39ec734 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -145,7 +145,7 @@ int main() { commandBuffer.end(); commandBuffer.submit(device.getComputeQueue(), fence); - assert(fence.wait() && "Synchronization fence timed out"); + assert(fence.wait(device) && "Synchronization fence timed out"); std::cerr << "Application finished" << '\n'; return 0;