diff --git a/aster/image.h b/aster/image.h index e7048f9..b3c93c5 100644 --- a/aster/image.h +++ b/aster/image.h @@ -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) { diff --git a/samples/00_util/frame.cpp b/samples/00_util/frame.cpp index 356f156..48326c6 100644 --- a/samples/00_util/frame.cpp +++ b/samples/00_util/frame.cpp @@ -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 name = "Frame "; + name += Cast('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); } diff --git a/samples/00_util/gui.cpp b/samples/00_util/gui.cpp index ee8048a..a5a6a94 100644 --- a/samples/00_util/gui.cpp +++ b/samples/00_util/gui.cpp @@ -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, diff --git a/samples/00_util/gui.h b/samples/00_util/gui.h index 82075c7..24a4c97 100644 --- a/samples/00_util/gui.h +++ b/samples/00_util/gui.h @@ -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(); diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index 11b9ea4..4531309 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -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(swapchain.m_Extent.width) / Cast(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(internalResolution.width) / Cast(internalResolution.height), 0.1f, 100.0f), + .m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f}, + .m_AspectRatio = Cast(internalResolution.width) / Cast(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(swapchain.m_Extent.height), - .width = Cast(swapchain.m_Extent.width), - .height = -Cast(swapchain.m_Extent.height), + .y = Cast(internalResolution.height), + .width = Cast(internalResolution.width), + .height = -Cast(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(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 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(swapchain.m_ImageViews.size()), + queueAllocation.m_Family, commandQueue); bool rotating = false; + i32 currentInternalResolution[2] = {Cast(internalResolution.width), Cast(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(swapchain.m_Extent.width) / Cast(swapchain.m_Extent.height); + currentInternalResolution[0] = Cast(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(internalResolution.width); + viewport.height = -Cast(internalResolution.height); + viewport.y = Cast(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(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());