Skip to content

Commit

Permalink
expanded image functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
maxortner01 committed Oct 3, 2024
1 parent a296293 commit 991f30b
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 71 deletions.
75 changes: 62 additions & 13 deletions include/midnight/Graphics/Image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,72 @@

namespace mn::Graphics
{
struct Image : ObjectHandle<Image>
// Reformat this as image w/ attachments
// Then we can add has_attachment<>() function to determine if there's depth/stencil
struct ImageFactory;

struct Image
{
enum Type
{
Color, DepthStencil
};

struct Attachment
{
mn::handle_t handle, allocation, view;
u32 format;
Math::Vec2u size;
};

enum Format : u32
{
DF32_SU8 = 130
};

Image(const Image&) = delete;
Image(Image&&) = default;

~Image();

template<Type T>
bool
hasAttachment() const
{
return attachments.count(T);
}

template<Type T>
const Attachment&
getAttachment() const
{
return attachments.at(T);
}

private:
friend struct ImageFactory;

Image() = default;

std::unordered_map<Type, Attachment> attachments;
};

struct ImageFactory
{
MN_SYMBOL Image(u32 format, const Math::Vec2u& size, bool depth = true);
MN_SYMBOL Image(Handle<Image> h, u32 f, const Math::Vec2u& s, bool depth = true);
MN_SYMBOL ~Image();
ImageFactory();

auto size() const { return _size; }
auto format() const { return _format; }
template<Image::Type T>
ImageFactory&
addAttachment(u32 format, const Math::Vec2u& size);

auto getColorImageView() const { return color_view; }
auto getDepthImageView() const { return depth_view; }
auto getDepthImage() const { return depth_image; }
template<Image::Type T>
ImageFactory&
addImage(handle_t handle, u32 format, const Math::Vec2u& size);

[[nodiscard]] Image&&
build();

private:
mn::handle_t image_allocation, depth_allocation;
Handle<Image> color_view, depth_view, depth_image;
u32 _format;
Math::Vec2u _size;
std::unique_ptr<Image> image;
};
}
2 changes: 1 addition & 1 deletion src/Graphics/Backend/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ std::pair<Handle<Image>, mn::handle_t> Device::createImage(const Math::Vec2u& si
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = static_cast<VkImageUsageFlags>(depth ? (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | static_cast<VkImageUsageFlags>(depth ? (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
};

VmaAllocationCreateInfo alloc_create_info = {
Expand Down
92 changes: 46 additions & 46 deletions src/Graphics/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,65 @@

namespace mn::Graphics
{
Image::Image(u32 format, const Math::Vec2u& size, bool depth) :
_format(format),
_size(size),
depth_allocation{0},
image_allocation{0}
Image::~Image()
{
auto& device = Backend::Instance::get()->getDevice();
std::tie(handle, image_allocation) = device->createImage(size, format);
color_view = device->createImageView(handle, format);

if (depth)
for (auto& [ type, a ] : attachments)
{
std::tie(depth_image, depth_allocation) = device->createImage(size, 130, true);
depth_view = device->createImageView(depth_image, 130, true);
device->destroyImageView(a.view);

if (a.allocation)
device->destroyImage(a.handle, a.allocation);
}
}

Image::Image(Handle<Image> h, u32 f, const Math::Vec2u& s, bool depth) :
ObjectHandle(h),
_format(f),
_size(s),
depth_allocation{0},
image_allocation{0}
{
ImageFactory::ImageFactory() :
image(std::unique_ptr<Image>(new Image()))
{ }

template<Image::Type T>
ImageFactory&
ImageFactory::addAttachment(u32 format, const Math::Vec2u& size)
{
constexpr bool depth = (T == Image::DepthStencil);
auto& device = Backend::Instance::get()->getDevice();
color_view = device->createImageView(h, f);
Image::Attachment a;
std::tie(a.handle, a.allocation) =
device->createImage(size, format, depth);
a.view = device->createImageView(a.handle, format, depth);
a.format = format;
a.size = size;

if (depth)
{
std::tie(depth_image, depth_allocation) = device->createImage(s, 130, true);
depth_view = device->createImageView(depth_image, 130, true);
}
image->attachments[T] = std::move(a);

return *this;
}
template ImageFactory& ImageFactory::addAttachment<Image::Color>(u32, const Math::Vec2u&);
template ImageFactory& ImageFactory::addAttachment<Image::DepthStencil>(u32, const Math::Vec2u&);

Image::~Image()
template<Image::Type T>
ImageFactory&
ImageFactory::addImage(handle_t handle, u32 format, const Math::Vec2u& size)
{
constexpr bool depth = (T == Image::DepthStencil);
auto& device = Backend::Instance::get()->getDevice();
if (color_view)
{
device->destroyImageView(color_view);
color_view = nullptr;
}
Image::Attachment a;
a.handle = handle;
a.allocation = nullptr;
a.view = device->createImageView(a.handle, format, depth);
a.format = format;
a.size = size;

if (depth_view)
{
device->destroyImageView(depth_view);
depth_view = nullptr;
}

if (depth_image)
{
device->destroyImage(depth_image, depth_allocation);
depth_image = nullptr;
}
image->attachments[T] = std::move(a);

if (image_allocation)
{
device->destroyImage(handle, image_allocation);
handle = nullptr;
}
return *this;
}
template ImageFactory& ImageFactory::addImage<Image::Color>(handle_t, u32, const Math::Vec2u&);
template ImageFactory& ImageFactory::addImage<Image::DepthStencil>(handle_t, u32, const Math::Vec2u&);

Image&&
ImageFactory::build()
{
return std::move(*image.release());
}
}
15 changes: 8 additions & 7 deletions src/Graphics/RenderFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ void RenderFrame::startRender()
VkRenderingAttachmentInfo color_attach = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.pNext = nullptr,
.imageView = image->getColorImageView().as<VkImageView>(),
.imageView = static_cast<VkImageView>(image->getAttachment<Image::Color>().view),
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};

std::optional<VkRenderingAttachmentInfo> depth_attach;

if (image->getDepthImageView())
if (image->hasAttachment<Image::DepthStencil>())
{
auto attachment_info = VkRenderingAttachmentInfo {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.pNext = nullptr,
.imageView = image->getDepthImageView().as<VkImageView>(),
.imageView = static_cast<VkImageView>( image->getAttachment<Image::DepthStencil>().view ),
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
Expand All @@ -36,11 +36,12 @@ void RenderFrame::startRender()
depth_attach.emplace(attachment_info);
}

const auto& image_size = image->getAttachment<Image::Color>().size;
VkRenderingInfo render_info = {
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.pNext = nullptr,
.flags = 0,
.renderArea = { 0, 0, Math::x( image->size() ), Math::y( image->size() ) },
.renderArea = { 0, 0, Math::x( image_size ), Math::y( image_size ) },
.layerCount = 1,
.colorAttachmentCount = 1,
.pColorAttachments = &color_attach,
Expand All @@ -49,10 +50,10 @@ void RenderFrame::startRender()

const auto command_buffer = frame_data->command_buffer->getHandle().as<VkCommandBuffer>();

VkRect2D sc = { 0, 0, Math::x( image->size() ), Math::y( image->size() ) };
VkRect2D sc = { 0, 0, Math::x( image_size ), Math::y( image_size ) };
vkCmdSetScissor(command_buffer, 0, 1, &sc);

VkViewport extent = { .x = 0, .y = 0, .width = static_cast<float>(Math::x(image->size())), .height = static_cast<float>(Math::y(image->size())), .minDepth = 0, .maxDepth = 1.f };
VkViewport extent = { .x = 0, .y = 0, .width = static_cast<float>(Math::x(image_size)), .height = static_cast<float>(Math::y(image_size)), .minDepth = 0, .maxDepth = 1.f };
vkCmdSetViewport(command_buffer, 0, 1, &extent);

auto& device = Backend::Instance::get()->getDevice();
Expand Down Expand Up @@ -95,7 +96,7 @@ void RenderFrame::clear(std::tuple<float, float, float> color) const
//clear image
vkCmdClearColorImage(
frame_data->command_buffer->getHandle().as<VkCommandBuffer>(),
image->getHandle().as<VkImage>(),
static_cast<VkImage>(image->getAttachment<Image::Color>().handle),
VK_IMAGE_LAYOUT_GENERAL,
&clearValue,
1,
Expand Down
16 changes: 12 additions & 4 deletions src/Graphics/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,14 @@ void Window::_open(const Math::Vec2u& req_size, const std::string& name)

const auto [ s, _images, format, size ] = device->createSwapchain(handle, surface);
for (const auto& image : _images)
images.emplace_back(std::make_shared<Image>(image, format, size, true));
{
images.emplace_back(std::make_shared<Image>(
ImageFactory()
.addImage<Image::Color>(image, format, size)
.addAttachment<Image::DepthStencil>(Image::DF32_SU8, size)
.build()
));
}

swapchain = s;

Expand Down Expand Up @@ -178,10 +185,11 @@ RenderFrame Window::startFrame() const
next_frame->command_buffer->reset();
next_frame->command_buffer->begin();

auto _image = images[n_image]->getHandle().as<VkImage>();
auto _image = static_cast<VkImage>(images[n_image]->getAttachment<Image::Color>().handle);
auto _depth_image = static_cast<VkImage>(images[n_image]->getAttachment<Image::DepthStencil>().handle);
auto _cmd = next_frame->command_buffer->getHandle().as<VkCommandBuffer>();
transition_image(_cmd, _image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
transition_image(_cmd, images[n_image]->getDepthImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
transition_image(_cmd, _depth_image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);

RenderFrame frame(n_image, images[n_image]);
frame.frame_data = next_frame;
Expand All @@ -193,7 +201,7 @@ void Window::endFrame(RenderFrame& rf) const
{
// All this code essentially copied...

auto _image = images[rf.image_index]->getHandle().as<VkImage>();
auto _image = static_cast<VkImage>(images[rf.image_index]->getAttachment<Image::Color>().handle);
auto _cmd = rf.frame_data->command_buffer->getHandle().as<VkCommandBuffer>();
transition_image(_cmd, _image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
rf.frame_data->command_buffer->end();
Expand Down

0 comments on commit 991f30b

Please sign in to comment.