/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "FrameBuffer.hpp" #include "RenderPass.hpp" void OpenVulkano::Vulkan::FrameBuffer::Init(Device* device, vk::Extent3D size, bool useDepthBuffer) { this->size = size; this->device = device; this->useDepthBuffer = useDepthBuffer; colorFormat = FindColorFormat(); if (useDepthBuffer) { depthBufferFormat = FindDepthFormat(); CreateDepthStencil(); } } void OpenVulkano::Vulkan::FrameBuffer::RegisterRenderPass(RenderPass* renderPass) { if (!device) throw std:: runtime_error("The frame buffer needs to be initialized before binding it to a render pass"); if (!renderPasses.empty()) { //TODO check compatibility // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#renderpass-compatibility } renderPasses.push_back(renderPass); if (renderPasses.size() == 1) CreateFrameBuffer(); } void OpenVulkano::Vulkan::FrameBuffer::Resize(vk::Extent3D size) { this->size = size; DestroyFrameBuffer(); if (depthBuffer) depthBuffer.Close(); if (useDepthBuffer) CreateDepthStencil(); CreateFrameBuffer(); for(RenderPass* renderPass : renderPasses) { renderPass->Resize(size); } } void OpenVulkano::Vulkan::FrameBuffer::CreateDepthStencil() { vk::ImageCreateInfo depthStencilCreateInfo({}, vk::ImageType::e2D, depthBufferFormat, size, 1, 1); depthStencilCreateInfo.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits:: eTransferSrc; const vk::ImageAspectFlags aspectMask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil; const vk::ImageViewCreateInfo depthStencilViewCreateInfo({}, {}, vk::ImageViewType::e2D, depthBufferFormat, {}, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1)); depthBuffer.Init(device, depthStencilCreateInfo, depthStencilViewCreateInfo); device->ExecuteNow([&](auto commandBuffer) { depthBuffer.SetLayout(commandBuffer, aspectMask, vk::ImageLayout::eDepthStencilAttachmentOptimal); }); } void OpenVulkano::Vulkan::FrameBuffer::CreateFrameBuffer() { vk::ImageView attachments[2]; // First attachment is the color buffer, second (optional) the depth buffer if (useDepthBuffer) attachments[1] = depthBuffer.view; //Depth buffer is the same for all frame buffers const vk::FramebufferCreateInfo fbCreateInfo({}, renderPasses[0]->renderPass, useDepthBuffer ? 2 : 1, attachments, size.width, size.height, 1); auto images = GetImages(); frameBuffers.resize(images.size()); for (uint32_t i = 0; i < frameBuffers.size(); i++) { attachments[0] = images[i]->GetView(); frameBuffers[i] = device->device.createFramebuffer(fbCreateInfo); } } void OpenVulkano::Vulkan::FrameBuffer::DestroyFrameBuffer() { for (const auto frameBuffer : frameBuffers) { device->device.destroyFramebuffer(frameBuffer); } frameBuffers.clear(); }