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