mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
general cleanup
This commit is contained in:
parent
6261a6ed6e
commit
dc11a64c0a
26 changed files with 75 additions and 235 deletions
|
|
@ -25,7 +25,6 @@ namespace Vulkan::Core {
|
||||||
/// @param data Initial data for the buffer.
|
/// @param data Initial data for the buffer.
|
||||||
/// @param usage Usage flags 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.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
||||||
|
|
@ -36,11 +35,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the size of the buffer.
|
/// Get the size of the buffer.
|
||||||
[[nodiscard]] size_t getSize() const { return this->size; }
|
[[nodiscard]] size_t getSize() const { return this->size; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->buffer); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
Buffer(const Buffer&) noexcept = default;
|
Buffer(const Buffer&) noexcept = default;
|
||||||
Buffer& operator=(const Buffer&) noexcept = default;
|
Buffer& operator=(const Buffer&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ namespace Vulkan::Core {
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
/// @param pool Vulkan command pool
|
/// @param pool Vulkan command pool
|
||||||
///
|
///
|
||||||
/// @throws std::invalid_argument if the device or pool are invalid.
|
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
CommandBuffer(const Device& device, const CommandPool& pool);
|
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 signalSemaphores Semaphores to signal after executing the command buffer
|
||||||
/// @param signalSemaphoreValues Values for the semaphores to signal
|
/// @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 std::logic_error if the command buffer is not in Full state.
|
||||||
/// @throws ls::vulkan_error if submission fails.
|
/// @throws ls::vulkan_error if submission fails.
|
||||||
///
|
///
|
||||||
|
|
@ -98,11 +96,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->commandBuffer; }
|
[[nodiscard]] auto handle() const { return *this->commandBuffer; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->commandBuffer); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
CommandBuffer(const CommandBuffer&) noexcept = default;
|
CommandBuffer(const CommandBuffer&) noexcept = default;
|
||||||
CommandBuffer& operator=(const CommandBuffer&) noexcept = default;
|
CommandBuffer& operator=(const CommandBuffer&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace Vulkan::Core {
|
||||||
///
|
///
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
///
|
///
|
||||||
/// @throws std::invalid_argument if the device is invalid.
|
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
CommandPool(const Device& device);
|
CommandPool(const Device& device);
|
||||||
|
|
@ -29,11 +28,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->commandPool; }
|
[[nodiscard]] auto handle() const { return *this->commandPool; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->commandPool); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
CommandPool(const CommandPool&) noexcept = default;
|
CommandPool(const CommandPool&) noexcept = default;
|
||||||
CommandPool& operator=(const CommandPool&) noexcept = default;
|
CommandPool& operator=(const CommandPool&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace Vulkan::Core {
|
||||||
///
|
///
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
///
|
///
|
||||||
/// @throws std::invalid_argument if the device is invalid.
|
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
DescriptorPool(const Device& device);
|
DescriptorPool(const Device& device);
|
||||||
|
|
@ -29,11 +28,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->descriptorPool; }
|
[[nodiscard]] auto handle() const { return *this->descriptorPool; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->descriptorPool); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
DescriptorPool(const DescriptorPool&) noexcept = default;
|
DescriptorPool(const DescriptorPool&) noexcept = default;
|
||||||
DescriptorPool& operator=(const DescriptorPool&) noexcept = default;
|
DescriptorPool& operator=(const DescriptorPool&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ namespace Vulkan::Core {
|
||||||
/// @param pool Descriptor pool to allocate from
|
/// @param pool Descriptor pool to allocate from
|
||||||
/// @param shaderModule Shader module to use for the descriptor set
|
/// @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.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
DescriptorSet(const Device& device,
|
DescriptorSet(const Device& device,
|
||||||
|
|
@ -45,8 +44,6 @@ namespace Vulkan::Core {
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
/// @param resources Resources to update the descriptor set with
|
/// @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,
|
void update(const Device& device,
|
||||||
const std::vector<std::vector<ResourcePair>>& resources) const;
|
const std::vector<std::vector<ResourcePair>>& resources) const;
|
||||||
|
|
||||||
|
|
@ -56,18 +53,11 @@ namespace Vulkan::Core {
|
||||||
/// @param commandBuffer Command buffer to bind the descriptor set to.
|
/// @param commandBuffer Command buffer to bind the descriptor set to.
|
||||||
/// @param pipeline Pipeline 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;
|
void bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const;
|
||||||
|
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->descriptorSet; }
|
[[nodiscard]] auto handle() const { return *this->descriptorSet; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->descriptorSet); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
DescriptorSet(const DescriptorSet&) noexcept = default;
|
DescriptorSet(const DescriptorSet&) noexcept = default;
|
||||||
DescriptorSet& operator=(const DescriptorSet&) noexcept = default;
|
DescriptorSet& operator=(const DescriptorSet&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace Vulkan::Core {
|
||||||
///
|
///
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
///
|
///
|
||||||
/// @throws std::invalid_argument if the device is invalid.
|
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Fence(const Device& device);
|
Fence(const Device& device);
|
||||||
|
|
@ -29,28 +28,26 @@ namespace Vulkan::Core {
|
||||||
///
|
///
|
||||||
/// Reset the fence to an unsignaled state.
|
/// Reset the fence to an unsignaled state.
|
||||||
///
|
///
|
||||||
|
/// @param device Vulkan device
|
||||||
|
///
|
||||||
/// @throws ls::vulkan_error if resetting fails.
|
/// @throws ls::vulkan_error if resetting fails.
|
||||||
///
|
///
|
||||||
void reset() const;
|
void reset(const Device& device) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Wait for the fence
|
/// Wait for the fence
|
||||||
///
|
///
|
||||||
|
/// @param device Vulkan device
|
||||||
/// @param timeout The timeout in nanoseconds, or UINT64_MAX for no timeout.
|
/// @param timeout The timeout in nanoseconds, or UINT64_MAX for no timeout.
|
||||||
/// @returns true if the fence signaled, false if it timed out.
|
/// @returns true if the fence signaled, false if it timed out.
|
||||||
///
|
///
|
||||||
/// @throws ls::vulkan_error if waiting fails.
|
/// @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.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->fence; }
|
[[nodiscard]] auto handle() const { return *this->fence; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->fence); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
// Trivially copyable, moveable and destructible
|
// Trivially copyable, moveable and destructible
|
||||||
Fence(const Fence&) noexcept = default;
|
Fence(const Fence&) noexcept = default;
|
||||||
Fence& operator=(const Fence&) noexcept = default;
|
Fence& operator=(const Fence&) noexcept = default;
|
||||||
|
|
@ -59,7 +56,6 @@ namespace Vulkan::Core {
|
||||||
~Fence() = default;
|
~Fence() = default;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<VkFence> fence;
|
std::shared_ptr<VkFence> fence;
|
||||||
VkDevice device{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ namespace Vulkan::Core {
|
||||||
/// @param usage Usage flags for the image
|
/// @param usage Usage flags for the image
|
||||||
/// @param aspectFlags Aspect flags for the image view
|
/// @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.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Image(const Device& device, VkExtent2D extent, VkFormat format,
|
Image(const Device& device, VkExtent2D extent, VkFormat format,
|
||||||
|
|
@ -40,11 +39,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the format of the image.
|
/// Get the format of the image.
|
||||||
[[nodiscard]] VkFormat getFormat() const { return this->format; }
|
[[nodiscard]] VkFormat getFormat() const { return this->format; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->image); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
Image(const Image&) noexcept = default;
|
Image(const Image&) noexcept = default;
|
||||||
Image& operator=(const Image&) noexcept = default;
|
Image& operator=(const Image&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ namespace Vulkan::Core {
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
/// @param shader Shader module to use for the pipeline.
|
/// @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.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Pipeline(const Device& device, const ShaderModule& shader);
|
Pipeline(const Device& device, const ShaderModule& shader);
|
||||||
|
|
@ -34,8 +33,6 @@ namespace Vulkan::Core {
|
||||||
///
|
///
|
||||||
/// @param commandBuffer Command buffer to bind the pipeline to.
|
/// @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;
|
void bind(const CommandBuffer& commandBuffer) const;
|
||||||
|
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
|
|
@ -43,11 +40,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the pipeline layout.
|
/// Get the pipeline layout.
|
||||||
[[nodiscard]] auto getLayout() const { return *this->layout; }
|
[[nodiscard]] auto getLayout() const { return *this->layout; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->pipeline); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
Pipeline(const Pipeline&) noexcept = default;
|
Pipeline(const Pipeline&) noexcept = default;
|
||||||
Pipeline& operator=(const Pipeline&) noexcept = default;
|
Pipeline& operator=(const Pipeline&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ namespace Vulkan::Core {
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
/// @param mode Address mode for the sampler.
|
/// @param mode Address mode for the sampler.
|
||||||
///
|
///
|
||||||
/// @throws std::invalid_argument if the device is invalid.
|
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Sampler(const Device& device, VkSamplerAddressMode mode);
|
Sampler(const Device& device, VkSamplerAddressMode mode);
|
||||||
|
|
@ -30,11 +29,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->sampler; }
|
[[nodiscard]] auto handle() const { return *this->sampler; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->sampler); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
Sampler(const Sampler&) noexcept = default;
|
Sampler(const Sampler&) noexcept = default;
|
||||||
Sampler& operator=(const Sampler&) noexcept = default;
|
Sampler& operator=(const Sampler&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ namespace Vulkan::Core {
|
||||||
/// @param device Vulkan device
|
/// @param device Vulkan device
|
||||||
/// @param initial Optional initial value for creating a timeline semaphore.
|
/// @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.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Semaphore(const Device& device, std::optional<uint32_t> initial = std::nullopt);
|
Semaphore(const Device& device, std::optional<uint32_t> initial = std::nullopt);
|
||||||
|
|
@ -31,16 +30,18 @@ namespace Vulkan::Core {
|
||||||
///
|
///
|
||||||
/// Signal the semaphore to a specific value.
|
/// Signal the semaphore to a specific value.
|
||||||
///
|
///
|
||||||
|
/// @param device Vulkan device
|
||||||
/// @param value The value to signal the semaphore to.
|
/// @param value The value to signal the semaphore to.
|
||||||
///
|
///
|
||||||
/// @throws std::logic_error if the semaphore is not a timeline semaphore.
|
/// @throws std::logic_error if the semaphore is not a timeline semaphore.
|
||||||
/// @throws ls::vulkan_error if signaling fails.
|
/// @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.
|
/// Wait for the semaphore to reach a specific value.
|
||||||
///
|
///
|
||||||
|
/// @param device Vulkan device
|
||||||
/// @param value The value to wait for.
|
/// @param value The value to wait for.
|
||||||
/// @param timeout The timeout in nanoseconds, or UINT64_MAX for no timeout.
|
/// @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.
|
/// @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 std::logic_error if the semaphore is not a timeline semaphore.
|
||||||
/// @throws ls::vulkan_error if waiting fails.
|
/// @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.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return *this->semaphore; }
|
[[nodiscard]] auto handle() const { return *this->semaphore; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->semaphore); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
// Trivially copyable, moveable and destructible
|
// Trivially copyable, moveable and destructible
|
||||||
Semaphore(const Semaphore&) noexcept = default;
|
Semaphore(const Semaphore&) noexcept = default;
|
||||||
Semaphore& operator=(const Semaphore&) noexcept = default;
|
Semaphore& operator=(const Semaphore&) noexcept = default;
|
||||||
|
|
@ -66,7 +62,6 @@ namespace Vulkan::Core {
|
||||||
~Semaphore() = default;
|
~Semaphore() = default;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<VkSemaphore> semaphore;
|
std::shared_ptr<VkSemaphore> semaphore;
|
||||||
VkDevice device{};
|
|
||||||
bool isTimeline{};
|
bool isTimeline{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ namespace Vulkan::Core {
|
||||||
/// @param path Path to the shader file.
|
/// @param path Path to the shader file.
|
||||||
/// @param descriptorTypes Descriptor types used in the shader.
|
/// @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 std::system_error if the shader file cannot be opened or read.
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
|
|
@ -38,11 +37,6 @@ namespace Vulkan::Core {
|
||||||
/// Get the descriptor set layout.
|
/// Get the descriptor set layout.
|
||||||
[[nodiscard]] auto getDescriptorSetLayout() const { return *this->descriptorSetLayout; }
|
[[nodiscard]] auto getDescriptorSetLayout() const { return *this->descriptorSetLayout; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->shaderModule); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
/// Trivially copyable, moveable and destructible
|
/// Trivially copyable, moveable and destructible
|
||||||
ShaderModule(const ShaderModule&) noexcept = default;
|
ShaderModule(const ShaderModule&) noexcept = default;
|
||||||
ShaderModule& operator=(const ShaderModule&) noexcept = default;
|
ShaderModule& operator=(const ShaderModule&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace Vulkan {
|
||||||
///
|
///
|
||||||
/// @param instance Vulkan instance
|
/// @param instance Vulkan instance
|
||||||
///
|
///
|
||||||
/// @throws std::invalid_argument if the instance is invalid.
|
|
||||||
/// @throws ls::vulkan_error if object creation fails.
|
/// @throws ls::vulkan_error if object creation fails.
|
||||||
///
|
///
|
||||||
Device(const Vulkan::Instance& instance);
|
Device(const Vulkan::Instance& instance);
|
||||||
|
|
@ -35,11 +34,6 @@ namespace Vulkan {
|
||||||
/// Get the compute queue.
|
/// Get the compute queue.
|
||||||
[[nodiscard]] VkQueue getComputeQueue() const { return this->computeQueue; }
|
[[nodiscard]] VkQueue getComputeQueue() const { return this->computeQueue; }
|
||||||
|
|
||||||
/// Check whether the object is valid.
|
|
||||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->device); }
|
|
||||||
/// if (obj) operator. Checks if the object is valid.
|
|
||||||
explicit operator bool() const { return this->isValid(); }
|
|
||||||
|
|
||||||
// Trivially copyable, moveable and destructible
|
// Trivially copyable, moveable and destructible
|
||||||
Device(const Device&) noexcept = default;
|
Device(const Device&) noexcept = default;
|
||||||
Device& operator=(const Device&) noexcept = default;
|
Device& operator=(const Device&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,6 @@ namespace Vulkan {
|
||||||
/// Get the Vulkan handle.
|
/// Get the Vulkan handle.
|
||||||
[[nodiscard]] auto handle() const { return this->instance ? *this->instance : VK_NULL_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
|
/// Trivially copyable, moveable and destructible
|
||||||
Instance(const Instance&) noexcept = default;
|
Instance(const Instance&) noexcept = default;
|
||||||
Instance& operator=(const Instance&) noexcept = default;
|
Instance& operator=(const Instance&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,6 @@ using namespace Vulkan::Core;
|
||||||
|
|
||||||
Buffer::Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
Buffer::Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
||||||
VkBufferUsageFlags usage) : size(size) {
|
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
|
// create buffer
|
||||||
const VkBufferCreateInfo desc{
|
const VkBufferCreateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
|
@ -62,6 +57,14 @@ Buffer::Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
throw ls::vulkan_error(res, "Failed to bind memory to Vulkan buffer");
|
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<void**>(&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
|
// store buffer and memory in shared ptr
|
||||||
this->buffer = std::shared_ptr<VkBuffer>(
|
this->buffer = std::shared_ptr<VkBuffer>(
|
||||||
new VkBuffer(bufferHandle),
|
new VkBuffer(bufferHandle),
|
||||||
|
|
@ -75,12 +78,4 @@ Buffer::Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
||||||
vkFreeMemory(dev, *mem, nullptr);
|
vkFreeMemory(dev, *mem, nullptr);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// upload data to buffer
|
|
||||||
uint8_t* buf{};
|
|
||||||
res = vkMapMemory(device.handle(), memoryHandle, 0, size, 0, reinterpret_cast<void**>(&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);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,8 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
CommandBuffer::CommandBuffer(const Device& device, const CommandPool& pool) {
|
CommandBuffer::CommandBuffer(const Device& device, const CommandPool& pool) {
|
||||||
if (!device || !pool)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device or command pool");
|
|
||||||
|
|
||||||
// create command buffer
|
// create command buffer
|
||||||
const VkCommandBufferAllocateInfo desc = {
|
const VkCommandBufferAllocateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||||
.commandPool = pool.handle(),
|
.commandPool = pool.handle(),
|
||||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||||
|
|
@ -67,14 +64,12 @@ void CommandBuffer::submit(VkQueue queue, std::optional<Fence> fence,
|
||||||
std::optional<std::vector<uint64_t>> waitSemaphoreValues,
|
std::optional<std::vector<uint64_t>> waitSemaphoreValues,
|
||||||
const std::vector<Semaphore>& signalSemaphores,
|
const std::vector<Semaphore>& signalSemaphores,
|
||||||
std::optional<std::vector<uint64_t>> signalSemaphoreValues) {
|
std::optional<std::vector<uint64_t>> signalSemaphoreValues) {
|
||||||
if (!queue)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan queue");
|
|
||||||
if (*this->state != CommandBufferState::Full)
|
if (*this->state != CommandBufferState::Full)
|
||||||
throw std::logic_error("Command buffer is not in Full state");
|
throw std::logic_error("Command buffer is not in Full state");
|
||||||
|
|
||||||
const std::vector<VkPipelineStageFlags> waitStages(waitSemaphores.size(),
|
const std::vector<VkPipelineStageFlags> waitStages(waitSemaphores.size(),
|
||||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
VkTimelineSemaphoreSubmitInfo timelineInfo = {
|
VkTimelineSemaphoreSubmitInfo timelineInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
|
||||||
};
|
};
|
||||||
if (waitSemaphoreValues.has_value()) {
|
if (waitSemaphoreValues.has_value()) {
|
||||||
|
|
@ -88,20 +83,14 @@ void CommandBuffer::submit(VkQueue queue, std::optional<Fence> fence,
|
||||||
timelineInfo.pSignalSemaphoreValues = signalSemaphoreValues->data();
|
timelineInfo.pSignalSemaphoreValues = signalSemaphoreValues->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VkSemaphore> waitSemaphoresHandles;
|
std::vector<VkSemaphore> waitSemaphoresHandles(waitSemaphores.size());
|
||||||
for (const auto& semaphore : waitSemaphores) {
|
for (const auto& semaphore : waitSemaphores)
|
||||||
if (!semaphore)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan semaphore in waitSemaphores");
|
|
||||||
waitSemaphoresHandles.push_back(semaphore.handle());
|
waitSemaphoresHandles.push_back(semaphore.handle());
|
||||||
}
|
std::vector<VkSemaphore> signalSemaphoresHandles(signalSemaphores.size());
|
||||||
std::vector<VkSemaphore> signalSemaphoresHandles;
|
for (const auto& semaphore : signalSemaphores)
|
||||||
for (const auto& semaphore : signalSemaphores) {
|
|
||||||
if (!semaphore)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan semaphore in signalSemaphores");
|
|
||||||
signalSemaphoresHandles.push_back(semaphore.handle());
|
signalSemaphoresHandles.push_back(semaphore.handle());
|
||||||
}
|
|
||||||
|
|
||||||
const VkSubmitInfo submitInfo = {
|
const VkSubmitInfo submitInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||||
.pNext = (waitSemaphoreValues.has_value() || signalSemaphoreValues.has_value())
|
.pNext = (waitSemaphoreValues.has_value() || signalSemaphoreValues.has_value())
|
||||||
? &timelineInfo : nullptr,
|
? &timelineInfo : nullptr,
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,8 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
CommandPool::CommandPool(const Device& device) {
|
CommandPool::CommandPool(const Device& device) {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// create command pool
|
// create command pool
|
||||||
const VkCommandPoolCreateInfo desc = {
|
const VkCommandPoolCreateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||||
.queueFamilyIndex = device.getComputeFamilyIdx()
|
.queueFamilyIndex = device.getComputeFamilyIdx()
|
||||||
};
|
};
|
||||||
|
|
@ -17,7 +14,7 @@ CommandPool::CommandPool(const Device& device) {
|
||||||
if (res != VK_SUCCESS || commandPoolHandle == VK_NULL_HANDLE)
|
if (res != VK_SUCCESS || commandPoolHandle == VK_NULL_HANDLE)
|
||||||
throw ls::vulkan_error(res, "Unable to create command pool");
|
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<VkCommandPool>(
|
this->commandPool = std::shared_ptr<VkCommandPool>(
|
||||||
new VkCommandPool(commandPoolHandle),
|
new VkCommandPool(commandPoolHandle),
|
||||||
[dev = device.handle()](VkCommandPool* commandPoolHandle) {
|
[dev = device.handle()](VkCommandPool* commandPoolHandle) {
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
DescriptorPool::DescriptorPool(const Device& device) {
|
DescriptorPool::DescriptorPool(const Device& device) {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// create descriptor pool
|
// create descriptor pool
|
||||||
const std::array<VkDescriptorPoolSize, 4> pools{{ // arbitrary limits
|
const std::array<VkDescriptorPoolSize, 4> pools{{ // arbitrary limits
|
||||||
{ .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 4096 },
|
{ .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 4096 },
|
||||||
|
|
@ -18,7 +15,7 @@ DescriptorPool::DescriptorPool(const Device& device) {
|
||||||
}};
|
}};
|
||||||
const VkDescriptorPoolCreateInfo desc{
|
const VkDescriptorPoolCreateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
.maxSets = 16384, // arbitrary limit
|
.maxSets = 16384,
|
||||||
.poolSizeCount = static_cast<uint32_t>(pools.size()),
|
.poolSizeCount = static_cast<uint32_t>(pools.size()),
|
||||||
.pPoolSizes = pools.data()
|
.pPoolSizes = pools.data()
|
||||||
};
|
};
|
||||||
|
|
@ -27,7 +24,7 @@ DescriptorPool::DescriptorPool(const Device& device) {
|
||||||
if (res != VK_SUCCESS || poolHandle == VK_NULL_HANDLE)
|
if (res != VK_SUCCESS || poolHandle == VK_NULL_HANDLE)
|
||||||
throw ls::vulkan_error(res, "Unable to create descriptor pool");
|
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<VkDescriptorPool>(
|
this->descriptorPool = std::shared_ptr<VkDescriptorPool>(
|
||||||
new VkDescriptorPool(poolHandle),
|
new VkDescriptorPool(poolHandle),
|
||||||
[dev = device.handle()](VkDescriptorPool* poolHandle) {
|
[dev = device.handle()](VkDescriptorPool* poolHandle) {
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,6 @@ using namespace Vulkan::Core;
|
||||||
|
|
||||||
DescriptorSet::DescriptorSet(const Device& device,
|
DescriptorSet::DescriptorSet(const Device& device,
|
||||||
DescriptorPool pool, const ShaderModule& shaderModule) {
|
DescriptorPool pool, const ShaderModule& shaderModule) {
|
||||||
if (!device || !pool)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// create descriptor set
|
// create descriptor set
|
||||||
VkDescriptorSetLayout layout = shaderModule.getDescriptorSetLayout();
|
VkDescriptorSetLayout layout = shaderModule.getDescriptorSetLayout();
|
||||||
const VkDescriptorSetAllocateInfo desc{
|
const VkDescriptorSetAllocateInfo desc{
|
||||||
|
|
@ -21,7 +18,7 @@ DescriptorSet::DescriptorSet(const Device& device,
|
||||||
if (res != VK_SUCCESS || descriptorSetHandle == VK_NULL_HANDLE)
|
if (res != VK_SUCCESS || descriptorSetHandle == VK_NULL_HANDLE)
|
||||||
throw ls::vulkan_error(res, "Unable to allocate descriptor set");
|
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<VkDescriptorSet>(
|
this->descriptorSet = std::shared_ptr<VkDescriptorSet>(
|
||||||
new VkDescriptorSet(descriptorSetHandle),
|
new VkDescriptorSet(descriptorSetHandle),
|
||||||
[dev = device.handle(), pool = std::move(pool)](VkDescriptorSet* setHandle) {
|
[dev = device.handle(), pool = std::move(pool)](VkDescriptorSet* setHandle) {
|
||||||
|
|
@ -32,9 +29,6 @@ DescriptorSet::DescriptorSet(const Device& device,
|
||||||
|
|
||||||
void DescriptorSet::update(const Device& device,
|
void DescriptorSet::update(const Device& device,
|
||||||
const std::vector<std::vector<ResourcePair>>& resources) const {
|
const std::vector<std::vector<ResourcePair>>& resources) const {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||||
uint32_t bindingIndex = 0;
|
uint32_t bindingIndex = 0;
|
||||||
for (const auto& list : resources) {
|
for (const auto& list : resources) {
|
||||||
|
|
@ -48,36 +42,23 @@ void DescriptorSet::update(const Device& device,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (std::holds_alternative<Image>(resource)) {
|
if (std::holds_alternative<Image>(resource)) {
|
||||||
const auto& image = std::get<Image>(resource);
|
|
||||||
if (!image)
|
|
||||||
throw std::invalid_argument("Invalid image resource");
|
|
||||||
|
|
||||||
const VkDescriptorImageInfo imageInfo{
|
const VkDescriptorImageInfo imageInfo{
|
||||||
.imageView = image.getView(),
|
.imageView = std::get<Image>(resource).getView(),
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
||||||
};
|
};
|
||||||
writeDesc.pImageInfo = &imageInfo;
|
writeDesc.pImageInfo = &imageInfo;
|
||||||
} else if (std::holds_alternative<Sampler>(resource)) {
|
} else if (std::holds_alternative<Sampler>(resource)) {
|
||||||
const auto& sampler = std::get<Sampler>(resource);
|
|
||||||
if (!sampler)
|
|
||||||
throw std::invalid_argument("Invalid sampler resource");
|
|
||||||
|
|
||||||
const VkDescriptorImageInfo imageInfo{
|
const VkDescriptorImageInfo imageInfo{
|
||||||
.sampler = sampler.handle()
|
.sampler = std::get<Sampler>(resource).handle()
|
||||||
};
|
};
|
||||||
writeDesc.pImageInfo = &imageInfo;
|
writeDesc.pImageInfo = &imageInfo;
|
||||||
} else if (std::holds_alternative<Buffer>(resource)) {
|
} else if (std::holds_alternative<Buffer>(resource)) {
|
||||||
const auto& buffer = std::get<Buffer>(resource);
|
const auto& buffer = std::get<Buffer>(resource);
|
||||||
if (!buffer)
|
|
||||||
throw std::invalid_argument("Invalid buffer resource");
|
|
||||||
|
|
||||||
const VkDescriptorBufferInfo bufferInfo{
|
const VkDescriptorBufferInfo bufferInfo{
|
||||||
.buffer = buffer.handle(),
|
.buffer = buffer.handle(),
|
||||||
.range = buffer.getSize()
|
.range = buffer.getSize()
|
||||||
};
|
};
|
||||||
writeDesc.pBufferInfo = &bufferInfo;
|
writeDesc.pBufferInfo = &bufferInfo;
|
||||||
} else {
|
|
||||||
throw std::invalid_argument("Unsupported resource type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeDescriptorSets.push_back(writeDesc);
|
writeDescriptorSets.push_back(writeDesc);
|
||||||
|
|
@ -86,18 +67,12 @@ void DescriptorSet::update(const Device& device,
|
||||||
|
|
||||||
vkUpdateDescriptorSets(device.handle(),
|
vkUpdateDescriptorSets(device.handle(),
|
||||||
static_cast<uint32_t>(writeDescriptorSets.size()),
|
static_cast<uint32_t>(writeDescriptorSets.size()),
|
||||||
writeDescriptorSets.data(),
|
writeDescriptorSets.data(), 0, nullptr);
|
||||||
0, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const {
|
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();
|
VkDescriptorSet descriptorSetHandle = this->handle();
|
||||||
vkCmdBindDescriptorSets(commandBuffer.handle(),
|
vkCmdBindDescriptorSets(commandBuffer.handle(),
|
||||||
VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getLayout(),
|
VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getLayout(),
|
||||||
0, 1, &descriptorSetHandle,
|
0, 1, &descriptorSetHandle, 0, nullptr);
|
||||||
0, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,8 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
Fence::Fence(const Device& device) {
|
Fence::Fence(const Device& device) {
|
||||||
if (!device)
|
// create fence
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
const VkFenceCreateInfo desc{
|
||||||
|
|
||||||
// create fence
|
|
||||||
const VkFenceCreateInfo desc = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
||||||
};
|
};
|
||||||
VkFence fenceHandle{};
|
VkFence fenceHandle{};
|
||||||
|
|
@ -17,7 +14,6 @@ Fence::Fence(const Device& device) {
|
||||||
throw ls::vulkan_error(res, "Unable to create fence");
|
throw ls::vulkan_error(res, "Unable to create fence");
|
||||||
|
|
||||||
// store fence in shared ptr
|
// store fence in shared ptr
|
||||||
this->device = device.handle();
|
|
||||||
this->fence = std::shared_ptr<VkFence>(
|
this->fence = std::shared_ptr<VkFence>(
|
||||||
new VkFence(fenceHandle),
|
new VkFence(fenceHandle),
|
||||||
[dev = device.handle()](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();
|
VkFence fenceHandle = this->handle();
|
||||||
auto res = vkResetFences(this->device, 1, &fenceHandle);
|
auto res = vkResetFences(device.handle(), 1, &fenceHandle);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
throw ls::vulkan_error(res, "Unable to reset fence");
|
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();
|
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)
|
if (res != VK_SUCCESS && res != VK_TIMEOUT)
|
||||||
throw ls::vulkan_error(res, "Unable to wait for fence");
|
throw ls::vulkan_error(res, "Unable to wait for fence");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@ using namespace Vulkan::Core;
|
||||||
Image::Image(const Device& device, VkExtent2D extent, VkFormat format,
|
Image::Image(const Device& device, VkExtent2D extent, VkFormat format,
|
||||||
VkImageUsageFlags usage, VkImageAspectFlags aspectFlags)
|
VkImageUsageFlags usage, VkImageAspectFlags aspectFlags)
|
||||||
: extent(extent), format(format) {
|
: extent(extent), format(format) {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// create image
|
// create image
|
||||||
const VkImageCreateInfo desc{
|
const VkImageCreateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
|
|
@ -68,24 +65,10 @@ Image::Image(const Device& device, VkExtent2D extent, VkFormat format,
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
throw ls::vulkan_error(res, "Failed to bind memory to Vulkan image");
|
throw ls::vulkan_error(res, "Failed to bind memory to Vulkan image");
|
||||||
|
|
||||||
// store image and memory in shared ptr
|
|
||||||
this->image = std::shared_ptr<VkImage>(
|
|
||||||
new VkImage(imageHandle),
|
|
||||||
[dev = device.handle()](VkImage* img) {
|
|
||||||
vkDestroyImage(dev, *img, nullptr);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this->memory = std::shared_ptr<VkDeviceMemory>(
|
|
||||||
new VkDeviceMemory(memoryHandle),
|
|
||||||
[dev = device.handle()](VkDeviceMemory* mem) {
|
|
||||||
vkFreeMemory(dev, *mem, nullptr);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// create image view
|
// create image view
|
||||||
const VkImageViewCreateInfo viewDesc{
|
const VkImageViewCreateInfo viewDesc{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
.image = *this->image,
|
.image = imageHandle,
|
||||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
.format = format,
|
.format = format,
|
||||||
.components = {
|
.components = {
|
||||||
|
|
@ -106,7 +89,19 @@ Image::Image(const Device& device, VkExtent2D extent, VkFormat format,
|
||||||
if (res != VK_SUCCESS || viewHandle == VK_NULL_HANDLE)
|
if (res != VK_SUCCESS || viewHandle == VK_NULL_HANDLE)
|
||||||
throw ls::vulkan_error(res, "Failed to create image view");
|
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<VkImage>(
|
||||||
|
new VkImage(imageHandle),
|
||||||
|
[dev = device.handle()](VkImage* img) {
|
||||||
|
vkDestroyImage(dev, *img, nullptr);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this->memory = std::shared_ptr<VkDeviceMemory>(
|
||||||
|
new VkDeviceMemory(memoryHandle),
|
||||||
|
[dev = device.handle()](VkDeviceMemory* mem) {
|
||||||
|
vkFreeMemory(dev, *mem, nullptr);
|
||||||
|
}
|
||||||
|
);
|
||||||
this->view = std::shared_ptr<VkImageView>(
|
this->view = std::shared_ptr<VkImageView>(
|
||||||
new VkImageView(viewHandle),
|
new VkImageView(viewHandle),
|
||||||
[dev = device.handle()](VkImageView* imgView) {
|
[dev = device.handle()](VkImageView* imgView) {
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
Pipeline::Pipeline(const Device& device, const ShaderModule& shader) {
|
Pipeline::Pipeline(const Device& device, const ShaderModule& shader) {
|
||||||
if (!device || !shader)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device or shader module");
|
|
||||||
|
|
||||||
// create pipeline layout
|
// create pipeline layout
|
||||||
VkDescriptorSetLayout shaderLayout = shader.getDescriptorSetLayout();
|
VkDescriptorSetLayout shaderLayout = shader.getDescriptorSetLayout();
|
||||||
const VkPipelineLayoutCreateInfo layoutDesc{
|
const VkPipelineLayoutCreateInfo layoutDesc{
|
||||||
|
|
@ -19,14 +16,6 @@ Pipeline::Pipeline(const Device& device, const ShaderModule& shader) {
|
||||||
if (res != VK_SUCCESS || !layoutHandle)
|
if (res != VK_SUCCESS || !layoutHandle)
|
||||||
throw ls::vulkan_error(res, "Failed to create pipeline layout");
|
throw ls::vulkan_error(res, "Failed to create pipeline layout");
|
||||||
|
|
||||||
// store layout in shared ptr
|
|
||||||
this->layout = std::shared_ptr<VkPipelineLayout>(
|
|
||||||
new VkPipelineLayout(layoutHandle),
|
|
||||||
[dev = device.handle()](VkPipelineLayout* layout) {
|
|
||||||
vkDestroyPipelineLayout(dev, *layout, nullptr);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// create pipeline
|
// create pipeline
|
||||||
const VkPipelineShaderStageCreateInfo shaderStageInfo{
|
const VkPipelineShaderStageCreateInfo shaderStageInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
.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)
|
if (res != VK_SUCCESS || !pipelineHandle)
|
||||||
throw ls::vulkan_error(res, "Failed to create compute pipeline");
|
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<VkPipelineLayout>(
|
||||||
|
new VkPipelineLayout(layoutHandle),
|
||||||
|
[dev = device.handle()](VkPipelineLayout* layout) {
|
||||||
|
vkDestroyPipelineLayout(dev, *layout, nullptr);
|
||||||
|
}
|
||||||
|
);
|
||||||
this->pipeline = std::shared_ptr<VkPipeline>(
|
this->pipeline = std::shared_ptr<VkPipeline>(
|
||||||
new VkPipeline(pipelineHandle),
|
new VkPipeline(pipelineHandle),
|
||||||
[dev = device.handle()](VkPipeline* pipeline) {
|
[dev = device.handle()](VkPipeline* pipeline) {
|
||||||
|
|
@ -55,8 +50,5 @@ Pipeline::Pipeline(const Device& device, const ShaderModule& shader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipeline::bind(const CommandBuffer& commandBuffer) const {
|
void Pipeline::bind(const CommandBuffer& commandBuffer) const {
|
||||||
if (!commandBuffer)
|
vkCmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, *this->pipeline);
|
||||||
throw std::invalid_argument("Invalid command buffer");
|
|
||||||
|
|
||||||
vkCmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, *this->pipeline);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
Sampler::Sampler(const Device& device, VkSamplerAddressMode mode) {
|
Sampler::Sampler(const Device& device, VkSamplerAddressMode mode) {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// create sampler
|
// create sampler
|
||||||
const VkSamplerCreateInfo desc{
|
const VkSamplerCreateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
.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)
|
if (res != VK_SUCCESS || samplerHandle == VK_NULL_HANDLE)
|
||||||
throw ls::vulkan_error(res, "Unable to create sampler");
|
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<VkSampler>(
|
this->sampler = std::shared_ptr<VkSampler>(
|
||||||
new VkSampler(samplerHandle),
|
new VkSampler(samplerHandle),
|
||||||
[dev = device.handle()](VkSampler* samplerHandle) {
|
[dev = device.handle()](VkSampler* samplerHandle) {
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,13 @@
|
||||||
using namespace Vulkan::Core;
|
using namespace Vulkan::Core;
|
||||||
|
|
||||||
Semaphore::Semaphore(const Device& device, std::optional<uint32_t> initial) {
|
Semaphore::Semaphore(const Device& device, std::optional<uint32_t> initial) {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// create semaphore
|
// create semaphore
|
||||||
const VkSemaphoreTypeCreateInfo typeInfo{
|
const VkSemaphoreTypeCreateInfo typeInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
|
||||||
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
|
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
|
||||||
.initialValue = initial.value_or(0)
|
.initialValue = initial.value_or(0)
|
||||||
};
|
};
|
||||||
const VkSemaphoreCreateInfo desc = {
|
const VkSemaphoreCreateInfo desc{
|
||||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||||
.pNext = initial.has_value() ? &typeInfo : nullptr,
|
.pNext = initial.has_value() ? &typeInfo : nullptr,
|
||||||
};
|
};
|
||||||
|
|
@ -24,7 +21,6 @@ Semaphore::Semaphore(const Device& device, std::optional<uint32_t> initial) {
|
||||||
|
|
||||||
// store semaphore in shared ptr
|
// store semaphore in shared ptr
|
||||||
this->isTimeline = initial.has_value();
|
this->isTimeline = initial.has_value();
|
||||||
this->device = device.handle();
|
|
||||||
this->semaphore = std::shared_ptr<VkSemaphore>(
|
this->semaphore = std::shared_ptr<VkSemaphore>(
|
||||||
new VkSemaphore(semaphoreHandle),
|
new VkSemaphore(semaphoreHandle),
|
||||||
[dev = device.handle()](VkSemaphore* semaphoreHandle) {
|
[dev = device.handle()](VkSemaphore* semaphoreHandle) {
|
||||||
|
|
@ -33,7 +29,7 @@ Semaphore::Semaphore(const Device& device, std::optional<uint32_t> initial) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Semaphore::signal(uint64_t value) const {
|
void Semaphore::signal(const Device& device, uint64_t value) const {
|
||||||
if (!this->isTimeline)
|
if (!this->isTimeline)
|
||||||
throw std::logic_error("Invalid timeline semaphore");
|
throw std::logic_error("Invalid timeline semaphore");
|
||||||
|
|
||||||
|
|
@ -42,12 +38,12 @@ void Semaphore::signal(uint64_t value) const {
|
||||||
.semaphore = this->handle(),
|
.semaphore = this->handle(),
|
||||||
.value = value
|
.value = value
|
||||||
};
|
};
|
||||||
auto res = vkSignalSemaphore(this->device, &signalInfo);
|
auto res = vkSignalSemaphore(device.handle(), &signalInfo);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
throw ls::vulkan_error(res, "Unable to signal semaphore");
|
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)
|
if (!this->isTimeline)
|
||||||
throw std::logic_error("Invalid timeline semaphore");
|
throw std::logic_error("Invalid timeline semaphore");
|
||||||
|
|
||||||
|
|
@ -58,7 +54,7 @@ bool Semaphore::wait(uint64_t value, uint64_t timeout) const {
|
||||||
.pSemaphores = &semaphore,
|
.pSemaphores = &semaphore,
|
||||||
.pValues = &value
|
.pValues = &value
|
||||||
};
|
};
|
||||||
auto res = vkWaitSemaphores(this->device, &waitInfo, timeout);
|
auto res = vkWaitSemaphores(device.handle(), &waitInfo, timeout);
|
||||||
if (res != VK_SUCCESS && res != VK_TIMEOUT)
|
if (res != VK_SUCCESS && res != VK_TIMEOUT)
|
||||||
throw ls::vulkan_error(res, "Unable to wait for semaphore");
|
throw ls::vulkan_error(res, "Unable to wait for semaphore");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,6 @@ using namespace Vulkan::Core;
|
||||||
|
|
||||||
ShaderModule::ShaderModule(const Device& device, const std::string& path,
|
ShaderModule::ShaderModule(const Device& device, const std::string& path,
|
||||||
const std::vector<std::pair<size_t, VkDescriptorType>>& descriptorTypes) {
|
const std::vector<std::pair<size_t, VkDescriptorType>>& descriptorTypes) {
|
||||||
if (!device)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan device");
|
|
||||||
|
|
||||||
// read shader bytecode
|
// read shader bytecode
|
||||||
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
||||||
if (!file)
|
if (!file)
|
||||||
|
|
@ -36,14 +33,6 @@ ShaderModule::ShaderModule(const Device& device, const std::string& path,
|
||||||
if (res != VK_SUCCESS || !shaderModuleHandle)
|
if (res != VK_SUCCESS || !shaderModuleHandle)
|
||||||
throw ls::vulkan_error(res, "Failed to create shader module");
|
throw ls::vulkan_error(res, "Failed to create shader module");
|
||||||
|
|
||||||
// store shader module in shared ptr
|
|
||||||
this->shaderModule = std::shared_ptr<VkShaderModule>(
|
|
||||||
new VkShaderModule(shaderModuleHandle),
|
|
||||||
[dev = device.handle()](VkShaderModule* shaderModuleHandle) {
|
|
||||||
vkDestroyShaderModule(dev, *shaderModuleHandle, nullptr);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// create descriptor set layout
|
// create descriptor set layout
|
||||||
std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
|
std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
|
||||||
size_t bindIdx = 0;
|
size_t bindIdx = 0;
|
||||||
|
|
@ -66,7 +55,13 @@ ShaderModule::ShaderModule(const Device& device, const std::string& path,
|
||||||
if (res != VK_SUCCESS || !descriptorSetLayout)
|
if (res != VK_SUCCESS || !descriptorSetLayout)
|
||||||
throw ls::vulkan_error(res, "Failed to create descriptor set layout");
|
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<VkShaderModule>(
|
||||||
|
new VkShaderModule(shaderModuleHandle),
|
||||||
|
[dev = device.handle()](VkShaderModule* shaderModuleHandle) {
|
||||||
|
vkDestroyShaderModule(dev, *shaderModuleHandle, nullptr);
|
||||||
|
}
|
||||||
|
);
|
||||||
this->descriptorSetLayout = std::shared_ptr<VkDescriptorSetLayout>(
|
this->descriptorSetLayout = std::shared_ptr<VkDescriptorSetLayout>(
|
||||||
new VkDescriptorSetLayout(descriptorSetLayout),
|
new VkDescriptorSetLayout(descriptorSetLayout),
|
||||||
[dev = device.handle()](VkDescriptorSetLayout* layout) {
|
[dev = device.handle()](VkDescriptorSetLayout* layout) {
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,6 @@
|
||||||
using namespace Vulkan;
|
using namespace Vulkan;
|
||||||
|
|
||||||
Device::Device(const Instance& instance) {
|
Device::Device(const Instance& instance) {
|
||||||
if (!instance)
|
|
||||||
throw std::invalid_argument("Invalid Vulkan instance");
|
|
||||||
|
|
||||||
// get all physical devices
|
// get all physical devices
|
||||||
uint32_t deviceCount{};
|
uint32_t deviceCount{};
|
||||||
auto res = vkEnumeratePhysicalDevices(instance.handle(), &deviceCount, nullptr);
|
auto res = vkEnumeratePhysicalDevices(instance.handle(), &deviceCount, nullptr);
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ int main() {
|
||||||
commandBuffer.end();
|
commandBuffer.end();
|
||||||
|
|
||||||
commandBuffer.submit(device.getComputeQueue(), fence);
|
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';
|
std::cerr << "Application finished" << '\n';
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue