Internal Framebuffer detached from Swapchain.
This commit is contained in:
parent
cd49d5b869
commit
6e14b74244
|
|
@ -15,6 +15,12 @@ ToExtent2D(const vk::Extent3D &extent)
|
|||
return {extent.width, extent.height};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vk::Extent3D
|
||||
ToExtent3D(const vk::Extent2D &extent, const u32 depth)
|
||||
{
|
||||
return {extent.width, extent.height, depth};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vk::Offset2D
|
||||
ToOffset2D(const vk::Extent3D &extent)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@
|
|||
#include "swapchain.h"
|
||||
|
||||
Frame::Frame(const Device *device, const u32 queueFamilyIndex, const u32 frameCount)
|
||||
: m_FrameIdx(0)
|
||||
: m_FrameIdx(frameCount)
|
||||
, m_ImageIdx(0)
|
||||
{
|
||||
m_Device = device;
|
||||
|
||||
eastl::fixed_string<char, 50, false> name = "Frame ";
|
||||
name += Cast<char>('0' + frameCount);
|
||||
const vk::CommandPoolCreateInfo commandPoolCreateInfo = {
|
||||
.flags = vk::CommandPoolCreateFlagBits::eTransient,
|
||||
.queueFamilyIndex = queueFamilyIndex,
|
||||
|
|
@ -40,6 +42,12 @@ Frame::Frame(const Device *device, const u32 queueFamilyIndex, const u32 frameCo
|
|||
|
||||
AbortIfFailed(m_Device->m_Device.allocateCommandBuffers(&allocateInfo, &m_CommandBuffer));
|
||||
|
||||
device->SetName(m_Pool, name.c_str());
|
||||
device->SetName(m_FrameAvailableFence, name.c_str());
|
||||
device->SetName(m_ImageAcquireSem, name.c_str());
|
||||
device->SetName(m_RenderFinishSem, name.c_str());
|
||||
device->SetName(m_CommandBuffer, name.c_str());
|
||||
|
||||
DEBUG("Frame {} created successfully.", frameCount);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ EndBuild()
|
|||
}
|
||||
|
||||
void
|
||||
Draw(const vk::CommandBuffer commandBuffer, const AttachmentImage *attachmentImage)
|
||||
Draw(const vk::CommandBuffer commandBuffer, const vk::Extent2D extent, const vk::ImageView view)
|
||||
{
|
||||
// OPTICK_EVENT();
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ Draw(const vk::CommandBuffer commandBuffer, const AttachmentImage *attachmentIma
|
|||
};
|
||||
commandBuffer.beginDebugUtilsLabelEXT(&label);
|
||||
vk::RenderingAttachmentInfo attachmentInfo = {
|
||||
.imageView = attachmentImage->m_View,
|
||||
.imageView = view,
|
||||
.imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||
.resolveMode = vk::ResolveModeFlagBits::eNone,
|
||||
.loadOp = vk::AttachmentLoadOp::eLoad,
|
||||
|
|
@ -181,7 +181,7 @@ Draw(const vk::CommandBuffer commandBuffer, const AttachmentImage *attachmentIma
|
|||
};
|
||||
|
||||
const vk::RenderingInfo renderingInfo = {
|
||||
.renderArea = {.extent = ToExtent2D(attachmentImage->m_Extent)},
|
||||
.renderArea = {.extent = extent},
|
||||
.layerCount = 1,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &attachmentInfo,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void Destroy(const Device *device);
|
|||
void Recreate();
|
||||
void StartBuild();
|
||||
void EndBuild();
|
||||
void Draw(vk::CommandBuffer commandBuffer, const AttachmentImage *attachmentImage);
|
||||
void Draw(vk::CommandBuffer commandBuffer, vk::Extent2D extent, vk::ImageView view);
|
||||
|
||||
void PushDisable();
|
||||
void PopDisable();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ struct Camera
|
|||
{
|
||||
mat4 m_View;
|
||||
mat4 m_Perspective;
|
||||
vec4 m_Position;
|
||||
vec3 m_Position;
|
||||
f32 m_AspectRatio;
|
||||
};
|
||||
|
||||
int
|
||||
|
|
@ -66,7 +67,11 @@ main(int, char **)
|
|||
.descriptorBindingPartiallyBound = true,
|
||||
.runtimeDescriptorArray = true,
|
||||
},
|
||||
.m_Vulkan13Features = {.dynamicRendering = true},
|
||||
.m_Vulkan13Features =
|
||||
{
|
||||
.synchronization2 = true,
|
||||
.dynamicRendering = true,
|
||||
},
|
||||
};
|
||||
|
||||
QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse);
|
||||
|
|
@ -83,13 +88,6 @@ main(int, char **)
|
|||
vk::Format attachmentFormat = vk::Format::eR8G8B8A8Srgb;
|
||||
Pipeline pipeline = CreatePipeline(&device, attachmentFormat, &resourceManager);
|
||||
|
||||
Camera camera = {
|
||||
.m_View = glm::lookAt(vec3(0.0f, 2.0f, 2.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)),
|
||||
.m_Perspective = glm::perspective(
|
||||
70_deg, Cast<f32>(swapchain.m_Extent.width) / Cast<f32>(swapchain.m_Extent.height), 0.1f, 100.0f),
|
||||
.m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f},
|
||||
};
|
||||
|
||||
lightManager.AddDirectional(vec3(0.0f, -1.0f, 0.0f), {0.0f, 0.7f, 0.0f});
|
||||
lightManager.AddPoint(vec3{2.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 15.0f);
|
||||
lightManager.AddPoint(vec3{-2.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 15.0f);
|
||||
|
|
@ -119,6 +117,16 @@ main(int, char **)
|
|||
AbortIfFailed(device.m_Device.allocateDescriptorSets(&descriptorSetAllocateInfo, &descriptorSet));
|
||||
}
|
||||
|
||||
vk::Extent2D internalResolution = {1920, 1080};
|
||||
|
||||
Camera camera = {
|
||||
.m_View = lookAt(vec3(0.0f, 2.0f, 2.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)),
|
||||
.m_Perspective = glm::perspective(
|
||||
70_deg, Cast<f32>(internalResolution.width) / Cast<f32>(internalResolution.height), 0.1f, 100.0f),
|
||||
.m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f},
|
||||
.m_AspectRatio = Cast<f32>(internalResolution.width) / Cast<f32>(internalResolution.height),
|
||||
};
|
||||
|
||||
UniformBuffer ubo;
|
||||
ubo.Init(&device, sizeof camera, "Camera UBO");
|
||||
ubo.Write(&device, 0, sizeof camera, &camera);
|
||||
|
|
@ -144,16 +152,16 @@ main(int, char **)
|
|||
// Persistent variables
|
||||
vk::Viewport viewport = {
|
||||
.x = 0,
|
||||
.y = Cast<f32>(swapchain.m_Extent.height),
|
||||
.width = Cast<f32>(swapchain.m_Extent.width),
|
||||
.height = -Cast<f32>(swapchain.m_Extent.height),
|
||||
.y = Cast<f32>(internalResolution.height),
|
||||
.width = Cast<f32>(internalResolution.width),
|
||||
.height = -Cast<f32>(internalResolution.height),
|
||||
.minDepth = 0.0,
|
||||
.maxDepth = 1.0,
|
||||
};
|
||||
|
||||
vk::Rect2D scissor = {
|
||||
.offset = {0, 0},
|
||||
.extent = swapchain.m_Extent,
|
||||
.extent = internalResolution,
|
||||
};
|
||||
|
||||
vk::ImageSubresourceRange subresourceRange = {
|
||||
|
|
@ -163,21 +171,39 @@ main(int, char **)
|
|||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
vk::ImageMemoryBarrier topOfThePipeBarrier = {
|
||||
|
||||
vk::ImageMemoryBarrier2 preRenderBarrier = {
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eTopOfPipe,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eNone,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||
.oldLayout = vk::ImageLayout::eUndefined,
|
||||
.newLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.subresourceRange = subresourceRange,
|
||||
};
|
||||
vk::ImageMemoryBarrier renderToTransferSrcBarrier = {
|
||||
vk::DependencyInfo preRenderDependencies = {
|
||||
.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &preRenderBarrier,
|
||||
};
|
||||
|
||||
vk::ImageMemoryBarrier2 renderToBlitBarrier = {
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllTransfer,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eTransferRead,
|
||||
.oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||
.newLayout = vk::ImageLayout::eTransferSrcOptimal,
|
||||
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.subresourceRange = subresourceRange,
|
||||
};
|
||||
vk::ImageMemoryBarrier acquireToTransferDstBarrier = {
|
||||
vk::ImageMemoryBarrier2 acquireToTransferDstBarrier = {
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eTopOfPipe,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eNone,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllTransfer,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.oldLayout = vk::ImageLayout::eUndefined,
|
||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||
|
|
@ -185,16 +211,45 @@ main(int, char **)
|
|||
.subresourceRange = subresourceRange,
|
||||
};
|
||||
eastl::array postRenderBarriers = {
|
||||
renderToTransferSrcBarrier,
|
||||
renderToBlitBarrier,
|
||||
acquireToTransferDstBarrier,
|
||||
};
|
||||
vk::ImageMemoryBarrier transferDstToPresentBarrier = {
|
||||
vk::DependencyInfo postRenderDependencies = {
|
||||
.imageMemoryBarrierCount = Cast<u32>(postRenderBarriers.size()),
|
||||
.pImageMemoryBarriers = postRenderBarriers.data(),
|
||||
};
|
||||
|
||||
vk::ImageMemoryBarrier2 transferDstToGuiRenderBarrier = {
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllTransfer,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.newLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.subresourceRange = subresourceRange,
|
||||
};
|
||||
vk::DependencyInfo preGuiDependencies = {
|
||||
.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &transferDstToGuiRenderBarrier,
|
||||
};
|
||||
|
||||
vk::ImageMemoryBarrier2 prePresentBarrier = {
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eBottomOfPipe,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eNone,
|
||||
.oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||
.newLayout = vk::ImageLayout::ePresentSrcKHR,
|
||||
.srcQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.dstQueueFamilyIndex = queueAllocation.m_Family,
|
||||
.subresourceRange = subresourceRange,
|
||||
};
|
||||
vk::DependencyInfo prePresentDependencies = {
|
||||
.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &prePresentBarrier,
|
||||
};
|
||||
|
||||
FrameManager frameManager = {&device, queueAllocation.m_Family, MAX_FRAMES_IN_FLIGHT};
|
||||
eastl::fixed_vector<DepthImage, MAX_FRAMES_IN_FLIGHT> depthImages(frameManager.m_FramesInFlight);
|
||||
|
|
@ -205,19 +260,20 @@ main(int, char **)
|
|||
for (u32 index = 0; index < frameManager.m_FramesInFlight; ++index)
|
||||
{
|
||||
auto name = fmt::format("Depth Frame{}", index);
|
||||
depthIter->Init(&device, swapchain.m_Extent, name.c_str());
|
||||
depthIter->Init(&device, internalResolution, name.c_str());
|
||||
|
||||
name = fmt::format("Attachment0 Frame{}", index);
|
||||
attachmentIter->Init(&device, swapchain.m_Extent, attachmentFormat, name.c_str());
|
||||
attachmentIter->Init(&device, internalResolution, attachmentFormat, name.c_str());
|
||||
|
||||
++depthIter;
|
||||
++attachmentIter;
|
||||
}
|
||||
}
|
||||
|
||||
gui::Init(&context, &device, &window, attachmentFormat, frameManager.m_FramesInFlight, queueAllocation.m_Family,
|
||||
commandQueue);
|
||||
gui::Init(&context, &device, &window, swapchain.m_Format, Cast<u32>(swapchain.m_ImageViews.size()),
|
||||
queueAllocation.m_Family, commandQueue);
|
||||
bool rotating = false;
|
||||
i32 currentInternalResolution[2] = {Cast<i32>(internalResolution.width), Cast<i32>(internalResolution.height)};
|
||||
|
||||
Time::Init();
|
||||
|
||||
|
|
@ -229,6 +285,31 @@ main(int, char **)
|
|||
gui::StartBuild();
|
||||
|
||||
gui::Begin("Settings");
|
||||
gui::Text("Window Resolution: %udx%ud", swapchain.m_Extent.width, swapchain.m_Extent.height);
|
||||
gui::Text("FrameBuffer Resolution %dx%d", currentInternalResolution[0], currentInternalResolution[1]);
|
||||
gui::InputInt("FrameBuffer Height", ¤tInternalResolution[1], 1, 10);
|
||||
|
||||
camera.m_AspectRatio = Cast<f32>(swapchain.m_Extent.width) / Cast<f32>(swapchain.m_Extent.height);
|
||||
currentInternalResolution[0] = Cast<i32>(camera.m_AspectRatio * currentInternalResolution[1]);
|
||||
for (i32 &val : currentInternalResolution)
|
||||
{
|
||||
val = eastl::clamp(val, 64, 7680);
|
||||
}
|
||||
camera.m_Perspective = glm::perspective(70_deg, camera.m_AspectRatio, 0.1f, 100.0f);
|
||||
|
||||
if (gui::Button("Change Resolution"))
|
||||
{
|
||||
if (currentInternalResolution[0] != internalResolution.width ||
|
||||
currentInternalResolution[1] != internalResolution.height)
|
||||
{
|
||||
internalResolution =
|
||||
vk::Extent2D{}.setWidth(currentInternalResolution[0]).setHeight(currentInternalResolution[1]);
|
||||
viewport.width = Cast<f32>(internalResolution.width);
|
||||
viewport.height = -Cast<f32>(internalResolution.height);
|
||||
viewport.y = Cast<f32>(internalResolution.height);
|
||||
scissor.extent = internalResolution;
|
||||
}
|
||||
}
|
||||
gui::Text("Delta: %0.6f ms", 1000.0f * Time::m_Delta);
|
||||
gui::Text("FPS: %0.6f", 1.0f / Time::m_Delta);
|
||||
gui::Checkbox("Rotate", &rotating);
|
||||
|
|
@ -252,23 +333,38 @@ main(int, char **)
|
|||
|
||||
u32 imageIndex = currentFrame->m_ImageIdx;
|
||||
vk::Image currentSwapchainImage = swapchain.m_Images[imageIndex];
|
||||
vk::ImageView currentSwapchainImageView = swapchain.m_ImageViews[imageIndex];
|
||||
vk::CommandBuffer cmd = currentFrame->m_CommandBuffer;
|
||||
vk::ImageView currentDepthImageView = depthImages[currentFrame->m_FrameIdx].m_View;
|
||||
|
||||
AttachmentImage *currentAttachment = &attachmentImages[currentFrame->m_ImageIdx];
|
||||
DepthImage *currentDepthImage = &depthImages[currentFrame->m_FrameIdx];
|
||||
AttachmentImage *currentAttachment = &attachmentImages[currentFrame->m_FrameIdx];
|
||||
|
||||
if (currentAttachment->m_Extent.width != internalResolution.width ||
|
||||
currentAttachment->m_Extent.height != internalResolution.height)
|
||||
{
|
||||
auto name = fmt::format("Depth Frame{}", currentFrame->m_FrameIdx);
|
||||
currentDepthImage->Destroy(&device);
|
||||
currentDepthImage->Init(&device, internalResolution, name.c_str());
|
||||
|
||||
name = fmt::format("Attachment0 Frame{}", currentFrame->m_FrameIdx);
|
||||
currentAttachment->Destroy(&device);
|
||||
currentAttachment->Init(&device, internalResolution, attachmentFormat, name.c_str());
|
||||
}
|
||||
|
||||
vk::ImageView currentDepthImageView = currentDepthImage->m_View;
|
||||
vk::Image currentImage = currentAttachment->m_Image;
|
||||
vk::ImageView currentImageView = currentAttachment->m_View;
|
||||
|
||||
topOfThePipeBarrier.image = currentImage;
|
||||
preRenderBarrier.image = currentImage;
|
||||
postRenderBarriers[0].image = currentImage;
|
||||
postRenderBarriers[1].image = currentSwapchainImage;
|
||||
transferDstToPresentBarrier.image = currentSwapchainImage;
|
||||
transferDstToGuiRenderBarrier.image = currentSwapchainImage;
|
||||
prePresentBarrier.image = currentSwapchainImage;
|
||||
|
||||
vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
|
||||
AbortIfFailed(cmd.begin(&beginInfo));
|
||||
|
||||
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
{}, 0, nullptr, 0, nullptr, 1, &topOfThePipeBarrier);
|
||||
cmd.pipelineBarrier2(&preRenderDependencies);
|
||||
|
||||
// Render
|
||||
eastl::array attachmentInfos = {
|
||||
|
|
@ -332,11 +428,7 @@ main(int, char **)
|
|||
|
||||
cmd.endRendering();
|
||||
|
||||
gui::Draw(cmd, currentAttachment);
|
||||
|
||||
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eAllCommands,
|
||||
{}, 0, nullptr, 0, nullptr, Cast<u32>(postRenderBarriers.size()),
|
||||
postRenderBarriers.data());
|
||||
cmd.pipelineBarrier2(&postRenderDependencies);
|
||||
|
||||
vk::ImageBlit blitRegion = {
|
||||
.srcSubresource =
|
||||
|
|
@ -367,8 +459,11 @@ main(int, char **)
|
|||
cmd.blitImage(currentImage, postRenderBarriers[0].newLayout, currentSwapchainImage,
|
||||
postRenderBarriers[1].newLayout, 1, &blitRegion, vk::Filter::eLinear);
|
||||
|
||||
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands, {}, 0,
|
||||
nullptr, 0, nullptr, 1, &transferDstToPresentBarrier);
|
||||
cmd.pipelineBarrier2(&preGuiDependencies);
|
||||
|
||||
gui::Draw(cmd, swapchain.m_Extent, currentSwapchainImageView);
|
||||
|
||||
cmd.pipelineBarrier2(&prePresentDependencies);
|
||||
|
||||
AbortIfFailed(cmd.end());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue