depth testing

main
Benjamin Kraft 2 weeks ago
parent 85ebf53ee1
commit 7c85f8efaa
  1. 17
      src/vulkan/application.cpp
  2. 6
      src/vulkan/application.hpp
  3. 14
      src/vulkan/buffer.cpp
  4. 2
      src/vulkan/buffer.hpp
  5. 63
      src/vulkan/image.cpp
  6. 19
      src/vulkan/image.hpp
  7. 8
      src/vulkan/pipeline.cpp
  8. 108
      src/vulkan/swapchain.cpp
  9. 12
      src/vulkan/swapchain.hpp
  10. 17
      src/vulkan/utils.cpp
  11. 3
      src/vulkan/utils.h

@ -4,7 +4,7 @@
#include "instance.hpp"
#include "buffer.hpp"
#include "command_pool.hpp"
#include "image.hpp"
Application::Application() {
@ -34,8 +34,6 @@ Application::Application() {
stagedVertexBuffer->copyTo(vertexBuffer, commandPool);
stagedIndexBuffer->copyTo(indexBuffer, commandPool);
createDepthResources();
delete stagedVertexBuffer;
delete stagedIndexBuffer;
@ -71,9 +69,12 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im
renderPassInfo.renderArea.offset = {0, 0};
renderPassInfo.renderArea.extent = swapchain->extent;
VkClearValue clearColor = {{{0, 0, 0, 1}}};
renderPassInfo.clearValueCount = 1;
renderPassInfo.pClearValues = &clearColor;
VkClearValue clearValues[2] {};
clearValues[0].color = {{0, 0, 0, 1}};
clearValues[1].depthStencil = {1.0f, 0};
renderPassInfo.clearValueCount = 2;
renderPassInfo.pClearValues = clearValues;
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
@ -199,10 +200,6 @@ Application::~Application() {
delete Instance::instance;
}
void Application::createDepthResources() {
}

@ -19,6 +19,7 @@ class Swapchain;
class Pipeline;
class Buffer;
class CommandPool;
class Image;
constexpr int MAX_FRAMES_IN_FLIGHT = 1;
@ -50,11 +51,6 @@ private:
void* uniformBufferMapped = nullptr;
VkImage depthImage = VK_NULL_HANDLE;
VkDeviceMemory depthImageMemory = VK_NULL_HANDLE;
VkImageView depthImageView = VK_NULL_HANDLE;
void createDepthResources();
void updateUniformBuffer();
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);

@ -4,6 +4,7 @@
#include "vertex.hpp"
#include "instance.hpp"
#include "command_pool.hpp"
#include "utils.h"
Buffer::Buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) : size(size){
VkBufferCreateInfo bufferInfo{};
@ -27,19 +28,6 @@ Buffer::Buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlag
vkBindBufferMemory(Instance::instance->device, handle, memory, 0);
}
uint32_t Buffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) {
VkPhysicalDeviceMemoryProperties memoryProperties;
vkGetPhysicalDeviceMemoryProperties(Instance::instance->physicalDevice, &memoryProperties);
for (uint32_t type = 0; type < memoryProperties.memoryTypeCount; type++){
if ((typeFilter & (1 << type)) && (memoryProperties.memoryTypes[type].propertyFlags & propertyFlags)){
return type;
}
}
throw std::runtime_error("failed to find suitable memory type!");
}
Buffer::~Buffer() {
vkFreeMemory(Instance::instance->device, memory, nullptr);
vkDestroyBuffer(Instance::instance->device, handle, nullptr);

@ -26,6 +26,4 @@ public:
void copyTo(Buffer* dst, CommandPool* commandPool);
private:
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags);
};

@ -0,0 +1,63 @@
#include "image.hpp"
#include "instance.hpp"
#include "utils.h"
Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage, VkMemoryPropertyFlags properties) {
VkImageCreateInfo imageCreateInfo {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.format = format;
imageCreateInfo.tiling = tiling;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.usage = usage;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vkCreateImage(Instance::instance->device, &imageCreateInfo, nullptr, &handle);
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(Instance::instance->device, handle, &memoryRequirements);
VkMemoryAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, properties);
vkAllocateMemory(Instance::instance->device, &allocateInfo, nullptr, &memory);
vkBindImageMemory(Instance::instance->device, handle, memory, 0);
}
Image::~Image() {
vkFreeMemory(Instance::instance->device, memory, nullptr);
if (view)
vkDestroyImageView(Instance::instance->device, view, nullptr);
vkDestroyImage(Instance::instance->device, handle, nullptr);
}
VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) {
VkImageSubresourceRange subresourceRange {};
subresourceRange.aspectMask = aspectFlags;
subresourceRange.baseMipLevel = 0;
subresourceRange.levelCount = 1;
subresourceRange.baseArrayLayer = 0;
subresourceRange.layerCount = 1;
VkImageViewCreateInfo createInfo {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.format = format;
createInfo.image = handle;
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.subresourceRange = subresourceRange;
vkCreateImageView(Instance::instance->device, &createInfo, nullptr, &view);
return view;
}

@ -0,0 +1,19 @@
#pragma once
#include <vulkan/vulkan.h>
class Instance;
class Image {
public:
explicit Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage, VkMemoryPropertyFlags properties);
~Image();
VkImageView createView(VkFormat format, VkImageAspectFlags aspectFlags);
VkImage handle = VK_NULL_HANDLE;
VkImageView view = VK_NULL_HANDLE;
private:
VkDeviceMemory memory = VK_NULL_HANDLE;
};

@ -102,6 +102,13 @@ Pipeline::Pipeline(VkRenderPass renderPass) {
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
VkPipelineDepthStencilStateCreateInfo depthStencil {};
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.depthTestEnable = VK_TRUE;
depthStencil.depthWriteEnable = VK_TRUE;
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
depthStencil.stencilTestEnable = VK_FALSE;
VkPipelineLayoutCreateInfo pipelineLayoutInfo {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1;
@ -123,6 +130,7 @@ Pipeline::Pipeline(VkRenderPass renderPass) {
pipelineInfo.pMultisampleState = &multisample;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicState;
pipelineInfo.pDepthStencilState = &depthStencil;
pipelineInfo.layout = layout;

@ -2,6 +2,7 @@
#include <stdexcept>
#include "swapchain.hpp"
#include "instance.hpp"
#include "image.hpp"
SwapchainSupportDetails querySwapchainSupport(VkPhysicalDevice device, VkSurfaceKHR surface){
SwapchainSupportDetails details;
@ -29,6 +30,7 @@ Swapchain::Swapchain() {
createSwapchain();
createImageViews();
createRenderpass();
createDepthResources();
createFramebuffers();
}
@ -111,6 +113,7 @@ void Swapchain::cleanupSwapchain() {
for (auto imageView : imageViews){
vkDestroyImageView(Instance::instance->device, imageView, nullptr);
}
delete depthImage;
vkDestroySwapchainKHR(Instance::instance->device, handle, nullptr);
}
@ -121,6 +124,7 @@ void Swapchain::recreateSwapchain() {
createSwapchain();
createImageViews();
createDepthResources();
createFramebuffers();
}
@ -143,37 +147,6 @@ void Swapchain::createImageViews() {
}
}
void Swapchain::createFramebuffers() {
frameBuffers.resize(imageViews.size());
for (size_t i = 0; i < imageViews.size(); i++){
VkImageView attachments[] = {imageViews[i]};
VkFramebufferCreateInfo framebufferInfo {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = extent.width;
framebufferInfo.height = extent.height;
framebufferInfo.layers = 1;
vkCreateFramebuffer(Instance::instance->device, &framebufferInfo, nullptr, &frameBuffers[i]);
}
}
VkSurfaceFormatKHR Swapchain::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {
for (const auto& availableFormat : availableFormats){
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
return availableFormat;
}
}
return availableFormats[0];
}
VkPresentModeKHR Swapchain::chooseSwapPresentMode(const std::vector<VkPresentModeKHR> &availablePresentModes) {
return VK_PRESENT_MODE_FIFO_KHR;
}
void Swapchain::createRenderpass() {
VkAttachmentDescription colorAttachment {};
colorAttachment.format = imageFormat;
@ -185,27 +158,44 @@ void Swapchain::createRenderpass() {
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentDescription depthAttachment {};
depthAttachment.format = VK_FORMAT_D32_SFLOAT;
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentDescription attachments[2] = {colorAttachment, depthAttachment};
VkAttachmentReference colorAttachmentRef {};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depthAttachmentRef {};
depthAttachmentRef.attachment = 1;
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
subpass.pDepthStencilAttachment = &depthAttachmentRef;
VkSubpassDependency dependency {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo renderPassInfo {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.attachmentCount = 2;
renderPassInfo.pAttachments = attachments;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = 1;
@ -213,3 +203,49 @@ void Swapchain::createRenderpass() {
vkCreateRenderPass(Instance::instance->device, &renderPassInfo, nullptr, &renderPass);
}
void Swapchain::createDepthResources() {
depthImage = new Image(
extent.width,
extent.height,
VK_FORMAT_D32_SFLOAT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
depthImage->createView(VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT);
}
void Swapchain::createFramebuffers() {
frameBuffers.resize(imageViews.size());
for (size_t i = 0; i < imageViews.size(); i++){
VkImageView attachments[] = {
imageViews[i],
depthImage->view
};
VkFramebufferCreateInfo framebufferInfo {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = 2;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = extent.width;
framebufferInfo.height = extent.height;
framebufferInfo.layers = 1;
vkCreateFramebuffer(Instance::instance->device, &framebufferInfo, nullptr, &frameBuffers[i]);
}
}
VkSurfaceFormatKHR Swapchain::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {
for (const auto& availableFormat : availableFormats){
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
return availableFormat;
}
}
return availableFormats[0];
}
VkPresentModeKHR Swapchain::chooseSwapPresentMode(const std::vector<VkPresentModeKHR> &availablePresentModes) {
return VK_PRESENT_MODE_FIFO_KHR;
}

@ -3,6 +3,7 @@
#include <vulkan/vulkan.h>
#include <vector>
class Image;
class Instance;
struct SwapchainSupportDetails {
@ -28,7 +29,14 @@ private:
std::vector<VkImage> images;
VkFormat imageFormat {};
std::vector<VkImageView> imageViews;
void createImageViews();
void createRenderpass();
Image* depthImage = nullptr;
void createDepthResources();
void createFramebuffers();
static VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
@ -37,8 +45,4 @@ private:
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
void createSwapchain();
std::vector<VkImageView> imageViews;
void createImageViews();
};

@ -0,0 +1,17 @@
#include <stdexcept>
#include "utils.h"
#include "instance.hpp"
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags) {
VkPhysicalDeviceMemoryProperties memoryProperties;
vkGetPhysicalDeviceMemoryProperties(Instance::instance->physicalDevice, &memoryProperties);
for (uint32_t type = 0; type < memoryProperties.memoryTypeCount; type++){
if ((typeFilter & (1 << type)) && (memoryProperties.memoryTypes[type].propertyFlags & propertyFlags)){
return type;
}
}
throw std::runtime_error("failed to find suitable memory type!");
}

@ -0,0 +1,3 @@
#include <vulkan/vulkan_core.h>
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags propertyFlags);
Loading…
Cancel
Save