diff --git a/aster/image.cpp b/aster/image.cpp index 90afaf2..b4d1deb 100644 --- a/aster/image.cpp +++ b/aster/image.cpp @@ -50,3 +50,36 @@ Texture::Init(const Device *device, const vk::Extent2D extent, const bool isMipm device->SetName(m_Image, name); } + +void +DepthImage::Init(const Device *device, vk::Extent2D extent, cstr name) +{ + vk::ImageCreateInfo imageCreateInfo = { + .imageType = vk::ImageType::e2D, + .format = vk::Format::eD32Sfloat, + .extent = {.width = extent.width, .height = extent.height, .depth = 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = vk::SampleCountFlagBits::e1, + .tiling = vk::ImageTiling::eOptimal, + .usage = vk::ImageUsageFlagBits::eDepthStencilAttachment, + .sharingMode = vk::SharingMode::eExclusive, + .initialLayout = vk::ImageLayout::eUndefined, + }; + constexpr VmaAllocationCreateInfo allocationCreateInfo = { + .flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + + VkImage image; + VmaAllocation allocation; + auto result = Cast(vmaCreateImage(device->m_Allocator, Recast(&imageCreateInfo), + &allocationCreateInfo, &image, &allocation, nullptr)); + ERROR_IF(Failed(result), "Could not allocate buffer. Cause: {}", result) THEN_ABORT(result); + + m_Image = image; + m_Allocation = allocation; + m_Extent = {extent.width, extent.height, 1}; + + device->SetName(m_Image, name); +} diff --git a/aster/image.h b/aster/image.h index befa459..3d6fb39 100644 --- a/aster/image.h +++ b/aster/image.h @@ -22,4 +22,9 @@ struct Image struct Texture : Image { void Init(const Device *device, vk::Extent2D extent, bool isMipmapped, cstr name = nullptr); +}; + +struct DepthImage : Image +{ + void Init(const Device *device, vk::Extent2D extent, cstr name = nullptr); }; \ No newline at end of file diff --git a/aster/swapchain.cpp b/aster/swapchain.cpp index d731eb4..f462716 100644 --- a/aster/swapchain.cpp +++ b/aster/swapchain.cpp @@ -12,6 +12,7 @@ Swapchain::Swapchain(const Window *window, const Device *device, NameString &&name) : m_Device(device) , m_Name(std::move(name)) + , m_Format(vk::Format::eUndefined) { this->Create(window); } @@ -176,6 +177,17 @@ Swapchain::Create(const Window *window) } DEBUG("Swapchain {} Image Views created.", m_Name); + + for (auto &callback : m_ResizeCallbacks) + { + callback(m_Extent); + } +} + +void +Swapchain::RegisterResizeCallback(FnResizeCallback &&callback) +{ + m_ResizeCallbacks.emplace_back(callback); } void diff --git a/aster/swapchain.h b/aster/swapchain.h index 2d827b8..9ed2137 100644 --- a/aster/swapchain.h +++ b/aster/swapchain.h @@ -15,6 +15,8 @@ struct Device; struct Swapchain final { + using FnResizeCallback = eastl::function; + const Device *m_Device; vk::SwapchainKHR m_Swapchain; NameString m_Name; @@ -23,7 +25,10 @@ struct Swapchain final eastl::fixed_vector m_Images; eastl::fixed_vector m_ImageViews; + eastl::vector m_ResizeCallbacks; + void Create(const Window *window); + void RegisterResizeCallback(FnResizeCallback &&callback); // Ctor/Dtor Swapchain(const Window *window, const Device *device, NameString &&name); diff --git a/samples/02_box/box.cpp b/samples/02_box/box.cpp index 605a168..9e870d3 100644 --- a/samples/02_box/box.cpp +++ b/samples/02_box/box.cpp @@ -420,6 +420,14 @@ main(int, char **) .extent = swapchain.m_Extent, }; + auto ResizeViewportScissor = [&viewport, &scissor](vk::Extent2D extent) { + viewport.y = Cast(extent.height); + viewport.width = Cast(extent.width); + viewport.height = -Cast(extent.height); + scissor.extent = extent; + }; + swapchain.RegisterResizeCallback(ResizeViewportScissor); + vk::ImageSubresourceRange subresourceRange = { .aspectMask = vk::ImageAspectFlagBits::eColor, .baseMipLevel = 0, @@ -442,14 +450,57 @@ main(int, char **) .subresourceRange = subresourceRange, }; - // Frames - eastl::fixed_vector frames; - for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) + FrameManager frameManager = {&device, queueAllocation.m_Family, MAX_FRAMES_IN_FLIGHT}; + eastl::fixed_vector depthImages(frameManager.m_FramesInFlight); + eastl::fixed_vector depthViews(frameManager.m_FramesInFlight); + + vk::ImageSubresourceRange depthSubresourceRange = { + .aspectMask = vk::ImageAspectFlagBits::eDepth, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }; + + u32 index = 0; + for (auto &depthImage : depthImages) { - frames.emplace_back(&device, queueAllocation.m_Family, i); + auto name = fmt::format("Depth image {}", index); + depthImage.Init(&device, swapchain.m_Extent, name.c_str()); + vk::ImageViewCreateInfo imageViewCreateInfo = { + .image = depthImage.m_Image, + .viewType = vk::ImageViewType::e2D, + .format = vk::Format::eD32Sfloat, + .components = vk::ComponentMapping{.r = vk::ComponentSwizzle::eIdentity}, + .subresourceRange = depthSubresourceRange, + }; + AbortIfFailed(device.m_Device.createImageView(&imageViewCreateInfo, nullptr, &depthViews[index])); + + index++; } - FrameManager frameManager = {&device, queueAllocation.m_Family, MAX_FRAMES_IN_FLIGHT}; + auto RecreateDepthBuffers = [&device, &depthImages, &depthViews, depthSubresourceRange](vk::Extent2D extent) { + for (auto &depthView : depthViews) + { + device.m_Device.destroy(depthView, nullptr); + } + u32 index = 0; + for (auto &depthImage : depthImages) + { + depthImage.Destroy(&device); + depthImage.Init(&device, extent, "Depth"); + vk::ImageViewCreateInfo imageViewCreateInfo = { + .image = depthImage.m_Image, + .viewType = vk::ImageViewType::e2D, + .format = vk::Format::eD32Sfloat, + .components = vk::ComponentMapping{.r = vk::ComponentSwizzle::eIdentity}, + .subresourceRange = depthSubresourceRange, + }; + AbortIfFailed(device.m_Device.createImageView(&imageViewCreateInfo, nullptr, &depthViews[index])); + ++index; + } + }; + swapchain.RegisterResizeCallback(RecreateDepthBuffers); Time::Init(); @@ -462,16 +513,12 @@ main(int, char **) ubo.Write(&device, 0, sizeof camera, &camera); Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &window); - viewport.y = Cast(swapchain.m_Extent.height); - viewport.width = Cast(swapchain.m_Extent.width); - viewport.height = -Cast(swapchain.m_Extent.height); - scissor.extent = swapchain.m_Extent; - // Frame *currentFrame = &frames[frameIndex]; u32 imageIndex = currentFrame->m_ImageIdx; vk::ImageView currentImageView = swapchain.m_ImageViews[imageIndex]; vk::Image currentImage = swapchain.m_Images[imageIndex]; vk::CommandBuffer cmd = currentFrame->m_CommandBuffer; + vk::ImageView currentDepthImageView = depthViews[currentFrame->m_FrameIdx]; topOfThePipeBarrier.image = currentImage; renderToPresentBarrier.image = currentImage; @@ -483,20 +530,32 @@ main(int, char **) {}, 0, nullptr, 0, nullptr, 1, &topOfThePipeBarrier); // Render - vk::RenderingAttachmentInfo attachmentInfo = { - .imageView = currentImageView, - .imageLayout = vk::ImageLayout::eColorAttachmentOptimal, + eastl::array attachmentInfos = { + vk::RenderingAttachmentInfo{ + .imageView = currentImageView, + .imageLayout = vk::ImageLayout::eColorAttachmentOptimal, + .resolveMode = vk::ResolveModeFlagBits::eNone, + .loadOp = vk::AttachmentLoadOp::eClear, + .storeOp = vk::AttachmentStoreOp::eStore, + .clearValue = vk::ClearColorValue{0.0f, 0.0f, 0.0f, 1.0f}, + }, + }; + + vk::RenderingAttachmentInfo depthAttachment = { + .imageView = currentDepthImageView, + .imageLayout = vk::ImageLayout::eDepthAttachmentOptimal, .resolveMode = vk::ResolveModeFlagBits::eNone, .loadOp = vk::AttachmentLoadOp::eClear, - .storeOp = vk::AttachmentStoreOp::eStore, - .clearValue = vk::ClearColorValue{0.0f, 0.0f, 0.0f, 1.0f}, + .storeOp = vk::AttachmentStoreOp::eDontCare, + .clearValue = vk::ClearDepthStencilValue{.depth = 1.0f, .stencil = 0}, }; vk::RenderingInfo renderingInfo = { .renderArea = {.extent = swapchain.m_Extent}, .layerCount = 1, - .colorAttachmentCount = 1, - .pColorAttachments = &attachmentInfo, + .colorAttachmentCount = Cast(attachmentInfos.size()), + .pColorAttachments = attachmentInfos.data(), + .pDepthAttachment = &depthAttachment, }; cmd.beginRendering(&renderingInfo); @@ -533,6 +592,14 @@ main(int, char **) AbortIfFailed(device.m_Device.waitIdle()); + for (auto &depthView : depthViews) + { + device.m_Device.destroy(depthView, nullptr); + } + for (auto &depthImage : depthImages) + { + depthImage.Destroy(&device); + } device.m_Device.destroy(sampler, nullptr); device.m_Device.destroy(imageView, nullptr); ubo.Destroy(&device); @@ -619,7 +686,7 @@ CreatePipeline(const Device *device, const Swapchain *swapchain) .depthClampEnable = false, .rasterizerDiscardEnable = false, .polygonMode = vk::PolygonMode::eFill, - .cullMode = vk::CullModeFlagBits::eBack, + .cullMode = vk::CullModeFlagBits::eNone, .frontFace = vk::FrontFace::eCounterClockwise, .depthBiasEnable = false, .lineWidth = 1.0, @@ -629,8 +696,9 @@ CreatePipeline(const Device *device, const Swapchain *swapchain) .sampleShadingEnable = false, }; vk::PipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = { - .depthTestEnable = false, - .depthWriteEnable = false, + .depthTestEnable = true, + .depthWriteEnable = true, + .depthCompareOp = vk::CompareOp::eLess, }; vk::PipelineColorBlendAttachmentState colorBlendAttachmentState = { .blendEnable = false, @@ -663,6 +731,7 @@ CreatePipeline(const Device *device, const Swapchain *swapchain) .viewMask = 0, .colorAttachmentCount = 1, .pColorAttachmentFormats = &swapchain->m_Format, + .depthAttachmentFormat = vk::Format::eD32Sfloat, }; vk::GraphicsPipelineCreateInfo pipelineCreateInfo = {