10 changed files with 392 additions and 98 deletions
@ -0,0 +1,124 @@ |
|||
// Copyright 2022 Simon Boyé
|
|||
|
|||
#include <vk/Image.h> |
|||
#include <vk/Context.h> |
|||
|
|||
#include <cassert> |
|||
|
|||
|
|||
namespace vk { |
|||
|
|||
|
|||
Image::Image() noexcept { |
|||
} |
|||
|
|||
Image::Image(Context& context, VkImageCreateInfo create_info) |
|||
: Wrapper(context) |
|||
{ |
|||
assert(m_context); |
|||
|
|||
if(vkCreateImage( |
|||
context.device(), |
|||
&create_info, |
|||
nullptr, |
|||
&m_image |
|||
) != VK_SUCCESS) |
|||
throw std::runtime_error("failed to create image"); |
|||
} |
|||
|
|||
Image::Image(Context& context, VkImageCreateInfo create_info, VkMemoryPropertyFlags memory_properties) |
|||
: Image(context, create_info) |
|||
{ |
|||
allocate_and_bind_memory(memory_properties); |
|||
} |
|||
|
|||
Image::Image(Image&& other) noexcept |
|||
{ |
|||
swap(other); |
|||
} |
|||
|
|||
Image::~Image() noexcept { |
|||
if(!is_null()) |
|||
destroy(); |
|||
} |
|||
|
|||
|
|||
Image& Image::operator=(Image&& other) noexcept { |
|||
swap(other); |
|||
if(other) |
|||
other.destroy(); |
|||
return *this; |
|||
} |
|||
|
|||
|
|||
VkMemoryRequirements Image::memory_requirements() const noexcept { |
|||
assert(!is_null()); |
|||
assert(*m_context); |
|||
|
|||
VkMemoryRequirements memory_requirements; |
|||
vkGetImageMemoryRequirements( |
|||
m_context->device(), |
|||
m_image, |
|||
&memory_requirements |
|||
); |
|||
|
|||
return memory_requirements; |
|||
} |
|||
|
|||
|
|||
void Image::bind_memory(const MemoryBlock& memory_block, VkDeviceSize offset) { |
|||
assert(!is_null()); |
|||
assert(*m_context); |
|||
assert(memory_block); |
|||
|
|||
// m_memory = std::move(memory_block);
|
|||
if(vkBindImageMemory( |
|||
m_context->device(), |
|||
m_image, |
|||
memory_block.device_memory(), |
|||
memory_block.offset() + offset |
|||
) != VK_SUCCESS) |
|||
throw std::runtime_error("failed to bind image memory"); |
|||
} |
|||
|
|||
void Image::bind_memory(MemoryBlock&& memory_block) { |
|||
bind_memory(memory_block); |
|||
m_memory = std::move(memory_block); |
|||
} |
|||
|
|||
void Image::allocate_and_bind_memory(VkMemoryPropertyFlags memory_properties) { |
|||
assert(!is_null()); |
|||
assert(*m_context); |
|||
|
|||
const auto memory_requirements = this->memory_requirements(); |
|||
m_memory = m_context->allocator().allocate( |
|||
memory_requirements.size, |
|||
memory_requirements.memoryTypeBits, |
|||
memory_properties |
|||
); |
|||
|
|||
bind_memory(m_memory); |
|||
} |
|||
|
|||
|
|||
void Image::destroy() noexcept { |
|||
assert(!is_null()); |
|||
assert(m_context); |
|||
|
|||
if(m_memory) { |
|||
m_memory.free(); |
|||
m_memory = MemoryBlock(); |
|||
} |
|||
|
|||
vkDestroyImage( |
|||
m_context->device(), |
|||
m_image, |
|||
nullptr |
|||
); |
|||
|
|||
m_context = nullptr; |
|||
m_image = VK_NULL_HANDLE; |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
// Copyright 2022 Simon Boyé
|
|||
#pragma once |
|||
|
|||
#include <vk/forward.h> |
|||
#include <vk/Wrapper.h> |
|||
#include <vk/Memory.h> |
|||
|
|||
#include <vulkan/vulkan.h> |
|||
|
|||
|
|||
namespace vk { |
|||
|
|||
|
|||
class Image: public Wrapper { |
|||
public: |
|||
Image() noexcept; |
|||
Image(Context& context, VkImageCreateInfo create_info); |
|||
Image(Context& context, VkImageCreateInfo create_info, VkMemoryPropertyFlags memory_properties); |
|||
Image(const Image&) = default; |
|||
Image(Image&& other) noexcept; |
|||
~Image() noexcept; |
|||
|
|||
Image& operator=(const Image&) = default; |
|||
Image& operator=(Image&& other) noexcept; |
|||
|
|||
explicit inline operator bool() const noexcept { |
|||
return !is_null(); |
|||
} |
|||
|
|||
inline bool is_null() const noexcept { |
|||
return m_image == VK_NULL_HANDLE; |
|||
} |
|||
|
|||
inline operator VkImage() noexcept { |
|||
return m_image; |
|||
} |
|||
|
|||
inline VkImage image() noexcept { |
|||
return m_image; |
|||
} |
|||
|
|||
VkMemoryRequirements memory_requirements() const noexcept; |
|||
|
|||
void bind_memory(const MemoryBlock& memory_block, VkDeviceSize offset=0); |
|||
void bind_memory(MemoryBlock&& memory_block); |
|||
void allocate_and_bind_memory(VkMemoryPropertyFlags memory_properties); |
|||
|
|||
inline void swap(Image& other) noexcept { |
|||
using std::swap; |
|||
Wrapper::swap(other); |
|||
swap(m_image, other.m_image); |
|||
} |
|||
|
|||
friend inline void swap(Image& image_0, Image& image_1) noexcept { |
|||
image_0.swap(image_1); |
|||
} |
|||
|
|||
void destroy() noexcept; |
|||
|
|||
private: |
|||
VkImage m_image = VK_NULL_HANDLE; |
|||
MemoryBlock m_memory; |
|||
}; |
|||
|
|||
|
|||
} |
|||
Loading…
Reference in new issue