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 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<uint8_t> 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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<std::vector<ResourcePair>>& 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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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<VkFence> fence;
|
||||
VkDevice device{};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<uint32_t> 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<bool>(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<VkSemaphore> semaphore;
|
||||
VkDevice device{};
|
||||
bool isTimeline{};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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<bool>(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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -8,11 +8,6 @@ using namespace Vulkan::Core;
|
|||
|
||||
Buffer::Buffer(const Device& device, size_t size, std::vector<uint8_t> 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<uint8_t> 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<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
|
||||
this->buffer = std::shared_ptr<VkBuffer>(
|
||||
new VkBuffer(bufferHandle),
|
||||
|
|
@ -75,12 +78,4 @@ Buffer::Buffer(const Device& device, size_t size, std::vector<uint8_t> data,
|
|||
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;
|
||||
|
||||
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> fence,
|
|||
std::optional<std::vector<uint64_t>> waitSemaphoreValues,
|
||||
const std::vector<Semaphore>& signalSemaphores,
|
||||
std::optional<std::vector<uint64_t>> 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<VkPipelineStageFlags> 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> fence,
|
|||
timelineInfo.pSignalSemaphoreValues = signalSemaphoreValues->data();
|
||||
}
|
||||
|
||||
std::vector<VkSemaphore> waitSemaphoresHandles;
|
||||
for (const auto& semaphore : waitSemaphores) {
|
||||
if (!semaphore)
|
||||
throw std::invalid_argument("Invalid Vulkan semaphore in waitSemaphores");
|
||||
std::vector<VkSemaphore> waitSemaphoresHandles(waitSemaphores.size());
|
||||
for (const auto& semaphore : waitSemaphores)
|
||||
waitSemaphoresHandles.push_back(semaphore.handle());
|
||||
}
|
||||
std::vector<VkSemaphore> signalSemaphoresHandles;
|
||||
for (const auto& semaphore : signalSemaphores) {
|
||||
if (!semaphore)
|
||||
throw std::invalid_argument("Invalid Vulkan semaphore in signalSemaphores");
|
||||
std::vector<VkSemaphore> 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,
|
||||
|
|
|
|||
|
|
@ -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<VkCommandPool>(
|
||||
new VkCommandPool(commandPoolHandle),
|
||||
[dev = device.handle()](VkCommandPool* commandPoolHandle) {
|
||||
|
|
|
|||
|
|
@ -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<VkDescriptorPoolSize, 4> 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<uint32_t>(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<VkDescriptorPool>(
|
||||
new VkDescriptorPool(poolHandle),
|
||||
[dev = device.handle()](VkDescriptorPool* poolHandle) {
|
||||
|
|
|
|||
|
|
@ -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<VkDescriptorSet>(
|
||||
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<std::vector<ResourcePair>>& resources) const {
|
||||
if (!device)
|
||||
throw std::invalid_argument("Invalid Vulkan device");
|
||||
|
||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||
uint32_t bindingIndex = 0;
|
||||
for (const auto& list : resources) {
|
||||
|
|
@ -48,36 +42,23 @@ void DescriptorSet::update(const Device& device,
|
|||
};
|
||||
|
||||
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{
|
||||
.imageView = image.getView(),
|
||||
.imageView = std::get<Image>(resource).getView(),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
||||
};
|
||||
writeDesc.pImageInfo = &imageInfo;
|
||||
} 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{
|
||||
.sampler = sampler.handle()
|
||||
.sampler = std::get<Sampler>(resource).handle()
|
||||
};
|
||||
writeDesc.pImageInfo = &imageInfo;
|
||||
} else if (std::holds_alternative<Buffer>(resource)) {
|
||||
const auto& buffer = std::get<Buffer>(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<uint32_t>(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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<VkFence>(
|
||||
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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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<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
|
||||
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<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>(
|
||||
new VkImageView(viewHandle),
|
||||
[dev = device.handle()](VkImageView* imgView) {
|
||||
|
|
|
|||
|
|
@ -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<VkPipelineLayout>(
|
||||
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<VkPipelineLayout>(
|
||||
new VkPipelineLayout(layoutHandle),
|
||||
[dev = device.handle()](VkPipelineLayout* layout) {
|
||||
vkDestroyPipelineLayout(dev, *layout, nullptr);
|
||||
}
|
||||
);
|
||||
this->pipeline = std::shared_ptr<VkPipeline>(
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<VkSampler>(
|
||||
new VkSampler(samplerHandle),
|
||||
[dev = device.handle()](VkSampler* samplerHandle) {
|
||||
|
|
|
|||
|
|
@ -4,16 +4,13 @@
|
|||
using namespace Vulkan::Core;
|
||||
|
||||
Semaphore::Semaphore(const Device& device, std::optional<uint32_t> 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<uint32_t> initial) {
|
|||
|
||||
// store semaphore in shared ptr
|
||||
this->isTimeline = initial.has_value();
|
||||
this->device = device.handle();
|
||||
this->semaphore = std::shared_ptr<VkSemaphore>(
|
||||
new 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)
|
||||
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");
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ using namespace Vulkan::Core;
|
|||
|
||||
ShaderModule::ShaderModule(const Device& device, const std::string& path,
|
||||
const std::vector<std::pair<size_t, VkDescriptorType>>& 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<VkShaderModule>(
|
||||
new VkShaderModule(shaderModuleHandle),
|
||||
[dev = device.handle()](VkShaderModule* shaderModuleHandle) {
|
||||
vkDestroyShaderModule(dev, *shaderModuleHandle, nullptr);
|
||||
}
|
||||
);
|
||||
|
||||
// create descriptor set layout
|
||||
std::vector<VkDescriptorSetLayoutBinding> 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<VkShaderModule>(
|
||||
new VkShaderModule(shaderModuleHandle),
|
||||
[dev = device.handle()](VkShaderModule* shaderModuleHandle) {
|
||||
vkDestroyShaderModule(dev, *shaderModuleHandle, nullptr);
|
||||
}
|
||||
);
|
||||
this->descriptorSetLayout = std::shared_ptr<VkDescriptorSetLayout>(
|
||||
new VkDescriptorSetLayout(descriptorSetLayout),
|
||||
[dev = device.handle()](VkDescriptorSetLayout* layout) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue