|
|
@@ -1,6 +1,7 @@ |
|
|
|
#include <png.h> |
|
|
|
#include <vulkan/vulkan.h> |
|
|
|
|
|
|
|
#include <array> |
|
|
|
#include <fstream> |
|
|
|
#include <iostream> |
|
|
|
#include <sstream> |
|
|
@@ -10,6 +11,7 @@ |
|
|
|
const uint32_t kWidth = 256; |
|
|
|
const uint32_t kHeight = 256; |
|
|
|
const VkFormat kVulkanFormat = VK_FORMAT_A8B8G8R8_UNORM_PACK32; |
|
|
|
const VkFormat kVulkanDepthFormat = VK_FORMAT_D32_SFLOAT; |
|
|
|
const std::string kVertexShaderPath = "occlusion.vert.spv"; |
|
|
|
const std::string kFragmentShaderPath = "occlusion.frag.spv"; |
|
|
|
|
|
|
@@ -168,24 +170,41 @@ VkQueryPool CreateVkQueryPool(VkDevice device) { |
|
|
|
} |
|
|
|
|
|
|
|
VkRenderPass CreateVkRenderPass(VkDevice device) { |
|
|
|
VkAttachmentDescription attachment_description = {}; |
|
|
|
attachment_description.format = kVulkanFormat; |
|
|
|
attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; |
|
|
|
attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
|
|
|
attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
|
|
|
attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
|
|
|
attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
|
|
|
attachment_description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
|
|
|
attachment_description.finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; |
|
|
|
|
|
|
|
VkAttachmentReference attachment_reference = {}; |
|
|
|
attachment_reference.attachment = 0; |
|
|
|
attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
|
|
|
std::array<VkAttachmentDescription, 2> attachment_descriptions = {}; |
|
|
|
|
|
|
|
VkAttachmentDescription* color_attachment_description = &attachment_descriptions[0]; |
|
|
|
color_attachment_description->format = kVulkanFormat; |
|
|
|
color_attachment_description->samples = VK_SAMPLE_COUNT_1_BIT; |
|
|
|
color_attachment_description->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
|
|
|
color_attachment_description->storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
|
|
|
color_attachment_description->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
|
|
|
color_attachment_description->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
|
|
|
color_attachment_description->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
|
|
|
color_attachment_description->finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; |
|
|
|
|
|
|
|
VkAttachmentReference color_attachment_reference = {}; |
|
|
|
color_attachment_reference.attachment = 0; |
|
|
|
color_attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
|
|
|
|
|
|
|
VkAttachmentDescription* depth_attachment_description = &attachment_descriptions[1]; |
|
|
|
depth_attachment_description->format = kVulkanDepthFormat; |
|
|
|
depth_attachment_description->samples = VK_SAMPLE_COUNT_1_BIT; |
|
|
|
depth_attachment_description->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
|
|
|
depth_attachment_description->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
|
|
|
depth_attachment_description->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
|
|
|
depth_attachment_description->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
|
|
|
depth_attachment_description->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
|
|
|
depth_attachment_description->finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
|
|
|
|
|
|
|
VkAttachmentReference depth_attachment_reference = {}; |
|
|
|
depth_attachment_reference.attachment = 1; |
|
|
|
depth_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
|
|
|
|
|
|
|
VkSubpassDescription subpass_description = {}; |
|
|
|
subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
|
|
|
subpass_description.colorAttachmentCount = 1; |
|
|
|
subpass_description.pColorAttachments = &attachment_reference; |
|
|
|
subpass_description.pColorAttachments = &color_attachment_reference; |
|
|
|
subpass_description.pDepthStencilAttachment = &depth_attachment_reference; |
|
|
|
|
|
|
|
VkSubpassDependency subpass_dependency = {}; |
|
|
|
subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; |
|
|
@@ -198,8 +217,8 @@ VkRenderPass CreateVkRenderPass(VkDevice device) { |
|
|
|
|
|
|
|
VkRenderPassCreateInfo render_pass_info = {}; |
|
|
|
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; |
|
|
|
render_pass_info.attachmentCount = 1; |
|
|
|
render_pass_info.pAttachments = &attachment_description; |
|
|
|
render_pass_info.attachmentCount = attachment_descriptions.size(); |
|
|
|
render_pass_info.pAttachments = attachment_descriptions.data(); |
|
|
|
render_pass_info.subpassCount = 1; |
|
|
|
render_pass_info.pSubpasses = &subpass_description; |
|
|
|
render_pass_info.dependencyCount = 1; |
|
|
@@ -303,6 +322,17 @@ VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) { |
|
|
|
multisampling_state_info.sampleShadingEnable = VK_FALSE; |
|
|
|
multisampling_state_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; |
|
|
|
|
|
|
|
VkPipelineDepthStencilStateCreateInfo depth_stencil_create_info = {}; |
|
|
|
depth_stencil_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; |
|
|
|
depth_stencil_create_info.depthTestEnable = VK_TRUE; |
|
|
|
depth_stencil_create_info.depthWriteEnable = VK_TRUE; |
|
|
|
depth_stencil_create_info.depthCompareOp = VK_COMPARE_OP_LESS; |
|
|
|
// TODO(brkho): Test depth bounds functionality. |
|
|
|
depth_stencil_create_info.depthBoundsTestEnable = VK_FALSE; |
|
|
|
depth_stencil_create_info.minDepthBounds = 0.0f; |
|
|
|
depth_stencil_create_info.maxDepthBounds = 1.0f; |
|
|
|
depth_stencil_create_info.stencilTestEnable = VK_FALSE; |
|
|
|
|
|
|
|
VkPipelineColorBlendAttachmentState color_blend_attachment_state = {}; |
|
|
|
color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | |
|
|
|
VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; |
|
|
@@ -333,7 +363,7 @@ VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) { |
|
|
|
pipeline_create_info.pViewportState = &viewport_state_info; |
|
|
|
pipeline_create_info.pRasterizationState = &rasterization_state_info; |
|
|
|
pipeline_create_info.pMultisampleState = &multisampling_state_info; |
|
|
|
pipeline_create_info.pDepthStencilState = nullptr; |
|
|
|
pipeline_create_info.pDepthStencilState = &depth_stencil_create_info; |
|
|
|
pipeline_create_info.pColorBlendState = &color_blend_state; |
|
|
|
pipeline_create_info.pDynamicState = nullptr; |
|
|
|
pipeline_create_info.layout = pipeline_layout; |
|
|
@@ -351,12 +381,13 @@ VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) { |
|
|
|
return pipeline; |
|
|
|
} |
|
|
|
|
|
|
|
VkImage CreateVkImage(VkDevice device, VkImageTiling image_tiling, VkImageUsageFlags usage) { |
|
|
|
VkImage CreateVkImage(VkDevice device, VkFormat format, VkImageTiling image_tiling, |
|
|
|
VkImageUsageFlags usage) { |
|
|
|
VkImageCreateInfo create_info = {}; |
|
|
|
create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; |
|
|
|
create_info.pNext = nullptr; |
|
|
|
create_info.imageType = VK_IMAGE_TYPE_2D; |
|
|
|
create_info.format = kVulkanFormat; |
|
|
|
create_info.format = format; |
|
|
|
VkExtent3D extent = {}; |
|
|
|
extent.width = kWidth; |
|
|
|
extent.height = kHeight; |
|
|
@@ -379,12 +410,17 @@ VkImage CreateVkImage(VkDevice device, VkImageTiling image_tiling, VkImageUsageF |
|
|
|
} |
|
|
|
|
|
|
|
inline VkImage CreateRenderVkImage(VkDevice device) { |
|
|
|
return CreateVkImage(device, VK_IMAGE_TILING_OPTIMAL, |
|
|
|
return CreateVkImage(device, kVulkanFormat, VK_IMAGE_TILING_OPTIMAL, |
|
|
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
inline VkImage CreateDepthVkImage(VkDevice device) { |
|
|
|
return CreateVkImage(device, kVulkanDepthFormat, VK_IMAGE_TILING_OPTIMAL, |
|
|
|
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
inline VkImage CreateScanoutVkImage(VkDevice device) { |
|
|
|
return CreateVkImage(device, VK_IMAGE_TILING_LINEAR, |
|
|
|
return CreateVkImage(device, kVulkanFormat, VK_IMAGE_TILING_LINEAR, |
|
|
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
|
|
|
} |
|
|
|
|
|
|
@@ -435,17 +471,23 @@ inline VkDeviceMemory AllocateAndBindRenderMemory(VkPhysicalDevice physical_devi |
|
|
|
return AllocateAndBindMemory(physical_device, device, image, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
inline VkDeviceMemory AllocateAndBindDepthMemory(VkPhysicalDevice physical_device, |
|
|
|
VkDevice device, VkImage image) { |
|
|
|
return AllocateAndBindMemory(physical_device, device, image, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
inline VkDeviceMemory AllocateAndBindScanoutMemory(VkPhysicalDevice physical_device, |
|
|
|
VkDevice device, VkImage image) { |
|
|
|
return AllocateAndBindMemory(physical_device, device, image, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
VkImageView CreateVkImageView(VkDevice device, VkImage image) { |
|
|
|
VkImageView CreateVkImageView(VkDevice device, VkImage image, VkFormat format, |
|
|
|
VkImageAspectFlags aspect) { |
|
|
|
VkImageViewCreateInfo create_info = {}; |
|
|
|
create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; |
|
|
|
create_info.image = image; |
|
|
|
create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; |
|
|
|
create_info.format = kVulkanFormat; |
|
|
|
create_info.format = format; |
|
|
|
|
|
|
|
VkComponentMapping component_mapping = {}; |
|
|
|
component_mapping.r = VK_COMPONENT_SWIZZLE_IDENTITY; |
|
|
@@ -455,7 +497,7 @@ VkImageView CreateVkImageView(VkDevice device, VkImage image) { |
|
|
|
create_info.components = component_mapping; |
|
|
|
|
|
|
|
VkImageSubresourceRange subresource_range = {}; |
|
|
|
subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
|
|
|
subresource_range.aspectMask = aspect; |
|
|
|
subresource_range.baseMipLevel = 0; |
|
|
|
subresource_range.levelCount = 1; |
|
|
|
subresource_range.baseArrayLayer = 0; |
|
|
@@ -470,13 +512,23 @@ VkImageView CreateVkImageView(VkDevice device, VkImage image) { |
|
|
|
return image_view; |
|
|
|
} |
|
|
|
|
|
|
|
VkImageView CreateRenderVkImageView(VkDevice device, VkImage image) { |
|
|
|
return CreateVkImageView(device, image, kVulkanFormat, VK_IMAGE_ASPECT_COLOR_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
VkImageView CreateDepthVkImageView(VkDevice device, VkImage image) { |
|
|
|
return CreateVkImageView(device, image, kVulkanDepthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
VkFramebuffer CreateVkFramebuffer(VkDevice device, VkRenderPass render_pass, |
|
|
|
VkImageView image_view) { |
|
|
|
VkImageView render_image_view, VkImageView depth_image_view) { |
|
|
|
std::array<VkImageView, 2> attachments = { render_image_view, depth_image_view }; |
|
|
|
|
|
|
|
VkFramebufferCreateInfo create_info = {}; |
|
|
|
create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; |
|
|
|
create_info.renderPass = render_pass; |
|
|
|
create_info.attachmentCount = 1; |
|
|
|
create_info.pAttachments = &image_view; |
|
|
|
create_info.attachmentCount = attachments.size(); |
|
|
|
create_info.pAttachments = attachments.data(); |
|
|
|
create_info.width = kWidth; |
|
|
|
create_info.height = kHeight; |
|
|
|
create_info.layers = 1; |
|
|
@@ -546,13 +598,17 @@ void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline p |
|
|
|
render_area.offset = { 0, 0 }; |
|
|
|
render_area.extent = { kWidth, kHeight }; |
|
|
|
render_pass_begin_info.renderArea = render_area; |
|
|
|
render_pass_begin_info.clearValueCount = 1; |
|
|
|
VkClearValue clear_value = {}; |
|
|
|
clear_value.color.float32[0] = 0.0f; |
|
|
|
clear_value.color.float32[1] = 0.0f; |
|
|
|
clear_value.color.float32[2] = 1.0f; |
|
|
|
clear_value.color.float32[3] = 1.0f; |
|
|
|
render_pass_begin_info.pClearValues = &clear_value; |
|
|
|
|
|
|
|
std::array<VkClearValue, 2> clear_values = {}; |
|
|
|
clear_values[0].color.float32[0] = 0.0f; |
|
|
|
clear_values[0].color.float32[1] = 0.0f; |
|
|
|
clear_values[0].color.float32[2] = 1.0f; |
|
|
|
clear_values[0].color.float32[3] = 1.0f; |
|
|
|
clear_values[1].depthStencil.depth = 1.0f; |
|
|
|
clear_values[1].depthStencil.stencil = 0.0f; |
|
|
|
|
|
|
|
render_pass_begin_info.clearValueCount = clear_values.size(); |
|
|
|
render_pass_begin_info.pClearValues = clear_values.data(); |
|
|
|
vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
|
|
|
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); |
|
|
@@ -679,8 +735,12 @@ int main() { |
|
|
|
|
|
|
|
VkImage render_image = CreateRenderVkImage(device); |
|
|
|
AllocateAndBindRenderMemory(physical_device, device, render_image); |
|
|
|
VkImageView render_image_view = CreateVkImageView(device, render_image); |
|
|
|
VkFramebuffer framebuffer = CreateVkFramebuffer(device, render_pass, render_image_view); |
|
|
|
VkImageView render_image_view = CreateRenderVkImageView(device, render_image); |
|
|
|
VkImage depth_image = CreateDepthVkImage(device); |
|
|
|
AllocateAndBindDepthMemory(physical_device, device, depth_image); |
|
|
|
VkImageView depth_image_view = CreateDepthVkImageView(device, depth_image); |
|
|
|
VkFramebuffer framebuffer = CreateVkFramebuffer(device, render_pass, render_image_view, |
|
|
|
depth_image_view); |
|
|
|
|
|
|
|
VkImage scanout_image = CreateScanoutVkImage(device); |
|
|
|
VkDeviceMemory scanout_image_memory = |