Skip to content

Commit a67ef9e

Browse files
Merge pull request #223 from KhronosGroup/chapter_34_depth_buffer
Add depth buffering to chapter 34
2 parents 0e3035d + 985c568 commit a67ef9e

File tree

1 file changed

+122
-68
lines changed

1 file changed

+122
-68
lines changed

attachments/34_android.cpp

Lines changed: 122 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -329,24 +329,27 @@ class HelloTriangleApplication
329329
bool framebufferResized = false;
330330

331331
// Vulkan objects
332-
vk::raii::Context context;
333-
vk::raii::Instance instance = nullptr;
334-
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
335-
vk::raii::SurfaceKHR surface = nullptr;
336-
vk::raii::PhysicalDevice physicalDevice = nullptr;
337-
vk::raii::Device device = nullptr;
338-
uint32_t queueIndex = ~0;
339-
vk::raii::Queue queue = nullptr;
340-
vk::raii::SwapchainKHR swapChain = nullptr;
341-
std::vector<vk::Image> swapChainImages;
342-
vk::SurfaceFormatKHR swapChainSurfaceFormat;
343-
vk::Extent2D swapChainExtent;
344-
std::vector<vk::raii::ImageView> swapChainImageViews;
345-
332+
vk::raii::Context context;
333+
vk::raii::Instance instance = nullptr;
334+
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
335+
vk::raii::SurfaceKHR surface = nullptr;
336+
vk::raii::PhysicalDevice physicalDevice = nullptr;
337+
vk::raii::Device device = nullptr;
338+
uint32_t queueIndex = ~0;
339+
vk::raii::Queue queue = nullptr;
340+
vk::raii::SwapchainKHR swapChain = nullptr;
341+
std::vector<vk::Image> swapChainImages;
342+
vk::SurfaceFormatKHR swapChainSurfaceFormat;
343+
vk::Extent2D swapChainExtent;
344+
std::vector<vk::raii::ImageView> swapChainImageViews;
346345
vk::raii::RenderPass renderPass = nullptr;
347346
vk::raii::DescriptorSetLayout descriptorSetLayout = nullptr;
348347
vk::raii::PipelineLayout pipelineLayout = nullptr;
349348
vk::raii::Pipeline graphicsPipeline = nullptr;
349+
vk::Format depthFormat;
350+
vk::raii::Image depthImage = nullptr;
351+
vk::raii::DeviceMemory depthImageMemory = nullptr;
352+
vk::raii::ImageView depthImageView = nullptr;
350353
std::vector<vk::raii::Framebuffer> swapChainFramebuffers;
351354
vk::raii::CommandPool commandPool = nullptr;
352355
std::vector<vk::raii::CommandBuffer> commandBuffers;
@@ -396,6 +399,7 @@ class HelloTriangleApplication
396399
createLogicalDevice();
397400
createSwapChain();
398401
createImageViews();
402+
createDepthResources();
399403
createRenderPass();
400404
createDescriptorSetLayout();
401405
createGraphicsPipeline();
@@ -694,22 +698,42 @@ class HelloTriangleApplication
694698
.attachment = 0,
695699
.layout = vk::ImageLayout::eColorAttachmentOptimal};
696700

701+
vk::AttachmentDescription depthAttachment{
702+
.format = depthFormat,
703+
.samples = vk::SampleCountFlagBits::e1,
704+
.loadOp = vk::AttachmentLoadOp::eClear,
705+
.storeOp = vk::AttachmentStoreOp::eStore,
706+
.stencilLoadOp = vk::AttachmentLoadOp::eDontCare,
707+
.stencilStoreOp = vk::AttachmentStoreOp::eDontCare,
708+
.initialLayout = vk::ImageLayout::eUndefined,
709+
.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal};
710+
711+
vk::AttachmentReference depthAttachmentRef{
712+
.attachment = 1,
713+
.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal};
714+
697715
vk::SubpassDescription subpass{
698-
.pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
699-
.colorAttachmentCount = 1,
700-
.pColorAttachments = &colorAttachmentRef};
716+
.pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
717+
.colorAttachmentCount = 1,
718+
.pColorAttachments = &colorAttachmentRef,
719+
.pDepthStencilAttachment = &depthAttachmentRef};
701720

721+
// @todo: barrier for deoth
702722
vk::SubpassDependency dependency{
703723
.srcSubpass = VK_SUBPASS_EXTERNAL,
704724
.dstSubpass = 0,
705-
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
706-
.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
707-
.srcAccessMask = vk::AccessFlagBits::eNone,
708-
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite};
725+
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests,
726+
.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests,
727+
.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite,
728+
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite};
729+
730+
vk::AttachmentDescription attachments[] = {
731+
colorAttachment,
732+
depthAttachment};
709733

710734
vk::RenderPassCreateInfo renderPassInfo{
711-
.attachmentCount = 1,
712-
.pAttachments = &colorAttachment,
735+
.attachmentCount = 2,
736+
.pAttachments = attachments,
713737
.subpassCount = 1,
714738
.pSubpasses = &subpass,
715739
.dependencyCount = 1,
@@ -809,6 +833,12 @@ class HelloTriangleApplication
809833
.depthBiasEnable = VK_FALSE,
810834
.lineWidth = 1.0f};
811835

836+
// Depth/Stencil
837+
vk::PipelineDepthStencilStateCreateInfo depthStencil{
838+
.depthTestEnable = vk::True,
839+
.depthWriteEnable = vk::True,
840+
.depthCompareOp = vk::CompareOp::eLessOrEqual};
841+
812842
// Multisampling
813843
vk::PipelineMultisampleStateCreateInfo multisampling{
814844
.rasterizationSamples = vk::SampleCountFlagBits::e1,
@@ -850,7 +880,7 @@ class HelloTriangleApplication
850880
.pViewportState = &viewportState,
851881
.pRasterizationState = &rasterizer,
852882
.pMultisampleState = &multisampling,
853-
.pDepthStencilState = nullptr,
883+
.pDepthStencilState = &depthStencil,
854884
.pColorBlendState = &colorBlending,
855885
.pDynamicState = &dynamicState,
856886
.layout = *pipelineLayout,
@@ -869,11 +899,12 @@ class HelloTriangleApplication
869899
for (size_t i = 0; i < swapChainImageViews.size(); i++)
870900
{
871901
vk::ImageView attachments[] = {
872-
*swapChainImageViews[i]};
902+
*swapChainImageViews[i],
903+
*depthImageView};
873904

874905
vk::FramebufferCreateInfo framebufferInfo{
875906
.renderPass = *renderPass,
876-
.attachmentCount = 1,
907+
.attachmentCount = 2,
877908
.pAttachments = attachments,
878909
.width = swapChainExtent.width,
879910
.height = swapChainExtent.height,
@@ -893,6 +924,35 @@ class HelloTriangleApplication
893924
commandPool = device.createCommandPool(poolInfo);
894925
}
895926

927+
vk::Format findSupportedFormat(const std::vector<vk::Format> &candidates, vk::ImageTiling tiling, vk::FormatFeatureFlags features) const
928+
{
929+
for (const auto format : candidates)
930+
{
931+
vk::FormatProperties props = physicalDevice.getFormatProperties(format);
932+
933+
if (tiling == vk::ImageTiling::eLinear && (props.linearTilingFeatures & features) == features)
934+
{
935+
return format;
936+
}
937+
if (tiling == vk::ImageTiling::eOptimal && (props.optimalTilingFeatures & features) == features)
938+
{
939+
return format;
940+
}
941+
}
942+
943+
throw std::runtime_error("failed to find supported format!");
944+
}
945+
946+
void createDepthResources()
947+
{
948+
depthFormat = findSupportedFormat({vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint},
949+
vk::ImageTiling::eOptimal,
950+
vk::FormatFeatureFlagBits::eDepthStencilAttachment);
951+
952+
createImage(swapChainExtent.width, swapChainExtent.height, 1, depthFormat, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eDepthStencilAttachment, vk::MemoryPropertyFlagBits::eDeviceLocal, depthImage, depthImageMemory);
953+
depthImageView = createImageView(depthImage, depthFormat, vk::ImageAspectFlagBits::eDepth, 1);
954+
}
955+
896956
// Create texture image
897957
void createTextureImage()
898958
{
@@ -941,32 +1001,7 @@ class HelloTriangleApplication
9411001
}
9421002

9431003
// Create image
944-
vk::ImageCreateInfo imageInfo{
945-
.imageType = vk::ImageType::e2D,
946-
.format = vk::Format::eR8G8B8A8Srgb,
947-
.extent = {
948-
.width = static_cast<uint32_t>(texWidth),
949-
.height = static_cast<uint32_t>(texHeight),
950-
.depth = 1},
951-
.mipLevels = 1,
952-
.arrayLayers = 1,
953-
.samples = vk::SampleCountFlagBits::e1,
954-
.tiling = vk::ImageTiling::eOptimal,
955-
.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
956-
.sharingMode = vk::SharingMode::eExclusive,
957-
.initialLayout = vk::ImageLayout::eUndefined};
958-
959-
textureImage = device.createImage(imageInfo);
960-
961-
// Allocate memory for the image
962-
vk::MemoryRequirements memRequirements = textureImage.getMemoryRequirements();
963-
964-
vk::MemoryAllocateInfo allocInfo{
965-
.allocationSize = memRequirements.size,
966-
.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal)};
967-
968-
textureImageMemory = device.allocateMemory(allocInfo);
969-
textureImage.bindMemory(*textureImageMemory, 0);
1004+
createImage(texWidth, texHeight, 1, vk::Format::eR8G8B8A8Srgb, vk::ImageTiling::eOptimal, vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled, vk::MemoryPropertyFlagBits::eDeviceLocal, textureImage, textureImageMemory);
9701005

9711006
// Transition image layout and copy buffer to image
9721007
transitionImageLayout(textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal);
@@ -977,7 +1012,7 @@ class HelloTriangleApplication
9771012
// Create texture image view
9781013
void createTextureImageView()
9791014
{
980-
textureImageView = createImageView(textureImage, vk::Format::eR8G8B8A8Srgb);
1015+
textureImageView = createImageView(textureImage, vk::Format::eR8G8B8A8Srgb, vk::ImageAspectFlagBits::eColor, 1);
9811016
}
9821017

9831018
// Create texture sampler
@@ -1238,17 +1273,18 @@ class HelloTriangleApplication
12381273
vk::CommandBufferBeginInfo beginInfo{};
12391274
commandBuffer.begin(beginInfo);
12401275

1276+
vk::ClearValue clearValues[]{
1277+
vk::ClearValue{vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f)},
1278+
vk::ClearValue{vk::ClearDepthStencilValue(1.0f, 0)}};
1279+
12411280
vk::RenderPassBeginInfo renderPassInfo{
12421281
.renderPass = *renderPass,
12431282
.framebuffer = *swapChainFramebuffers[imageIndex],
12441283
.renderArea = {
12451284
.offset = {0, 0},
1246-
.extent = swapChainExtent}};
1247-
1248-
vk::ClearValue clearColor;
1249-
clearColor.color.float32 = std::array<float, 4>{0.0f, 0.0f, 0.0f, 1.0f};
1250-
renderPassInfo.clearValueCount = 1;
1251-
renderPassInfo.pClearValues = &clearColor;
1285+
.extent = swapChainExtent},
1286+
.clearValueCount = 2,
1287+
.pClearValues = clearValues};
12521288

12531289
commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
12541290
commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, *graphicsPipeline);
@@ -1374,6 +1410,7 @@ class HelloTriangleApplication
13741410
// Create new swap chain and dependent resources
13751411
createSwapChain();
13761412
createImageViews();
1413+
createDepthResources();
13771414
createFramebuffers();
13781415

13791416
// Recreate per-swapchain-image present semaphores for presenting
@@ -1563,20 +1600,37 @@ class HelloTriangleApplication
15631600
}
15641601

15651602
// Create image view
1566-
vk::raii::ImageView createImageView(vk::raii::Image &image, vk::Format format)
1603+
[[nodiscard]] vk::raii::ImageView createImageView(const vk::raii::Image &image, vk::Format format, vk::ImageAspectFlags aspectFlags, uint32_t mipLevels) const
15671604
{
15681605
vk::ImageViewCreateInfo viewInfo{
15691606
.image = *image,
15701607
.viewType = vk::ImageViewType::e2D,
15711608
.format = format,
1572-
.subresourceRange = {
1573-
.aspectMask = vk::ImageAspectFlagBits::eColor,
1574-
.baseMipLevel = 0,
1575-
.levelCount = 1,
1576-
.baseArrayLayer = 0,
1577-
.layerCount = 1}};
1578-
1579-
return device.createImageView(viewInfo);
1609+
.subresourceRange = {aspectFlags, 0, mipLevels, 0, 1}};
1610+
return vk::raii::ImageView(device, viewInfo);
1611+
}
1612+
1613+
void createImage(uint32_t width, uint32_t height, uint32_t mipLevels, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags properties, vk::raii::Image &image, vk::raii::DeviceMemory &imageMemory)
1614+
{
1615+
vk::ImageCreateInfo imageInfo{
1616+
.imageType = vk::ImageType::e2D,
1617+
.format = format,
1618+
.extent = {width, height, 1},
1619+
.mipLevels = mipLevels,
1620+
.arrayLayers = 1,
1621+
.samples = vk::SampleCountFlagBits::e1,
1622+
.tiling = tiling,
1623+
.usage = usage,
1624+
.sharingMode = vk::SharingMode::eExclusive,
1625+
.initialLayout = vk::ImageLayout::eUndefined};
1626+
image = vk::raii::Image(device, imageInfo);
1627+
1628+
vk::MemoryRequirements memRequirements = image.getMemoryRequirements();
1629+
vk::MemoryAllocateInfo allocInfo{
1630+
.allocationSize = memRequirements.size,
1631+
.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties)};
1632+
imageMemory = vk::raii::DeviceMemory(device, allocInfo);
1633+
image.bindMemory(*imageMemory, 0);
15801634
}
15811635

15821636
// Transition image layout

0 commit comments

Comments
 (0)