|
|
@@ -12,8 +12,10 @@ 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 = "subpass.vert.spv"; |
|
|
|
const std::string kFragmentShaderPath = "subpass.frag.spv"; |
|
|
|
const std::string kDrawVertexShaderPath = "draw.vert.spv"; |
|
|
|
const std::string kDrawFragmentShaderPath = "draw.frag.spv"; |
|
|
|
const std::string kDarkenVertexShaderPath = "darken.vert.spv"; |
|
|
|
const std::string kDarkenFragmentShaderPath = "darken.frag.spv"; |
|
|
|
|
|
|
|
#define ERROR(message) \ |
|
|
|
std::cerr << message << std::endl; \ |
|
|
@@ -118,6 +120,107 @@ VkDevice CreateVkDevice(VkPhysicalDevice physical_device, uint32_t device_queue_ |
|
|
|
return device; |
|
|
|
} |
|
|
|
|
|
|
|
void CreateVkBuffer(VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, |
|
|
|
VkBuffer* buffer, VkDeviceMemory* bufferMemory) { |
|
|
|
VkBufferCreateInfo bufferInfo = {}; |
|
|
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
|
|
|
bufferInfo.size = size; |
|
|
|
bufferInfo.usage = usage; |
|
|
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
|
|
|
|
|
|
|
if (vkCreateBuffer(device, &bufferInfo, nullptr, buffer) != VK_SUCCESS) { |
|
|
|
ERROR("Unable to create buffer: "); |
|
|
|
} |
|
|
|
|
|
|
|
VkMemoryRequirements memRequirements; |
|
|
|
vkGetBufferMemoryRequirements(device, *buffer, &memRequirements); |
|
|
|
|
|
|
|
VkMemoryAllocateInfo allocInfo = {}; |
|
|
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
|
|
|
allocInfo.allocationSize = memRequirements.size; |
|
|
|
allocInfo.memoryTypeIndex = 0; |
|
|
|
|
|
|
|
if (vkAllocateMemory(device, &allocInfo, nullptr, bufferMemory) != VK_SUCCESS) { |
|
|
|
ERROR("Unable to allocate buffer memory: "); |
|
|
|
} |
|
|
|
|
|
|
|
vkBindBufferMemory(device, *buffer, *bufferMemory, 0); |
|
|
|
} |
|
|
|
|
|
|
|
VkDescriptorSetLayout CreateVkDescriptorSetLayout(VkDevice device) { |
|
|
|
VkDescriptorSetLayoutBinding layout_binding = {}; |
|
|
|
layout_binding.binding = 0; |
|
|
|
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; |
|
|
|
layout_binding.descriptorCount = 1; |
|
|
|
layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; |
|
|
|
layout_binding.pImmutableSamplers = nullptr; |
|
|
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo layout_info = {}; |
|
|
|
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; |
|
|
|
layout_info.bindingCount = 1; |
|
|
|
layout_info.pBindings = &layout_binding; |
|
|
|
|
|
|
|
VkDescriptorSetLayout layout; |
|
|
|
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, nullptr, &layout); |
|
|
|
if (result != VK_SUCCESS) { |
|
|
|
ERROR("Unable to create descriptor set layout: " << result); |
|
|
|
} |
|
|
|
return layout; |
|
|
|
} |
|
|
|
|
|
|
|
VkDescriptorPool CreateAttachmentVkDescriptorPool(VkDevice device) { |
|
|
|
VkDescriptorPoolSize pool_size = {}; |
|
|
|
pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; |
|
|
|
pool_size.descriptorCount = 1; |
|
|
|
|
|
|
|
VkDescriptorPoolCreateInfo pool_create_info = {}; |
|
|
|
pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; |
|
|
|
pool_create_info.poolSizeCount = 1; |
|
|
|
pool_create_info.pPoolSizes = &pool_size; |
|
|
|
pool_create_info.maxSets = 1; |
|
|
|
|
|
|
|
VkDescriptorPool pool; |
|
|
|
VkResult result = vkCreateDescriptorPool(device, &pool_create_info, nullptr, &pool); |
|
|
|
if (result != VK_SUCCESS) { |
|
|
|
ERROR("Unable to create descriptor pool: " << result); |
|
|
|
} |
|
|
|
return pool; |
|
|
|
} |
|
|
|
|
|
|
|
VkDescriptorSet CreateVkDescriptorSet(VkDevice device, VkDescriptorSetLayout layout, |
|
|
|
VkDescriptorPool pool) { |
|
|
|
VkDescriptorSetAllocateInfo allocate_info = {}; |
|
|
|
allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; |
|
|
|
allocate_info.descriptorPool = pool; |
|
|
|
allocate_info.descriptorSetCount = 1; |
|
|
|
allocate_info.pSetLayouts = &layout; |
|
|
|
|
|
|
|
VkDescriptorSet descriptor_set; |
|
|
|
VkResult result = vkAllocateDescriptorSets(device, &allocate_info, &descriptor_set); |
|
|
|
if (result != VK_SUCCESS) { |
|
|
|
ERROR("Unable to allocate descriptor set: " << result); |
|
|
|
} |
|
|
|
return descriptor_set; |
|
|
|
} |
|
|
|
|
|
|
|
void UpdateVkDescriptorSet(VkDevice device, VkImageView image_view, VkDescriptorSet set) { |
|
|
|
VkDescriptorImageInfo image_info = {}; |
|
|
|
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |
|
|
|
image_info.imageView = image_view; |
|
|
|
image_info.sampler = VK_NULL_HANDLE; |
|
|
|
|
|
|
|
VkWriteDescriptorSet descriptor_write = {}; |
|
|
|
descriptor_write.dstSet = set; |
|
|
|
descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; |
|
|
|
descriptor_write.descriptorCount = 1; |
|
|
|
descriptor_write.dstBinding = 0; |
|
|
|
descriptor_write.pImageInfo = &image_info; |
|
|
|
descriptor_write.pBufferInfo = nullptr; |
|
|
|
descriptor_write.pTexelBufferView = nullptr; |
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr); |
|
|
|
} |
|
|
|
|
|
|
|
VkQueue GetVkQueue(VkDevice device, uint32_t device_queue_family_index) { |
|
|
|
VkQueue queue; |
|
|
|
vkGetDeviceQueue(device, device_queue_family_index, /*queueIndex*/ 0, &queue); |
|
|
@@ -153,7 +256,7 @@ VkCommandBuffer CreateVkCommandBuffer(VkDevice device, VkCommandPool command_poo |
|
|
|
} |
|
|
|
|
|
|
|
VkRenderPass CreateVkRenderPass(VkDevice device) { |
|
|
|
std::array<VkAttachmentDescription, 2> attachment_descriptions = {}; |
|
|
|
std::array<VkAttachmentDescription, 3> attachment_descriptions = {}; |
|
|
|
|
|
|
|
VkAttachmentDescription* color_attachment_description = &attachment_descriptions[0]; |
|
|
|
color_attachment_description->format = kVulkanFormat; |
|
|
@@ -183,29 +286,64 @@ VkRenderPass CreateVkRenderPass(VkDevice device) { |
|
|
|
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 = &color_attachment_reference; |
|
|
|
subpass_description.pDepthStencilAttachment = &depth_attachment_reference; |
|
|
|
|
|
|
|
VkSubpassDependency subpass_dependency = {}; |
|
|
|
subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; |
|
|
|
subpass_dependency.dstSubpass = 0; |
|
|
|
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
|
|
|
subpass_dependency.srcAccessMask = 0; |
|
|
|
subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
|
|
|
subpass_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | |
|
|
|
VkAttachmentDescription* input_attachment_description = &attachment_descriptions[2]; |
|
|
|
input_attachment_description->format = kVulkanFormat; |
|
|
|
input_attachment_description->samples = VK_SAMPLE_COUNT_1_BIT; |
|
|
|
input_attachment_description->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
|
|
|
input_attachment_description->storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
|
|
|
input_attachment_description->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
|
|
|
input_attachment_description->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
|
|
|
input_attachment_description->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
|
|
|
input_attachment_description->finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; |
|
|
|
|
|
|
|
VkAttachmentReference input_attachment_reference = {}; |
|
|
|
input_attachment_reference.attachment = 2; |
|
|
|
input_attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
|
|
|
|
|
|
|
std::array<VkSubpassDescription, 2> subpass_descriptions = {}; |
|
|
|
VkSubpassDescription* draw_subpass_description = &subpass_descriptions[0]; |
|
|
|
draw_subpass_description->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
|
|
|
draw_subpass_description->colorAttachmentCount = 1; |
|
|
|
draw_subpass_description->pColorAttachments = &input_attachment_reference; |
|
|
|
draw_subpass_description->pDepthStencilAttachment = &depth_attachment_reference; |
|
|
|
|
|
|
|
VkSubpassDescription* darken_subpass_description = &subpass_descriptions[1]; |
|
|
|
darken_subpass_description->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
|
|
|
darken_subpass_description->colorAttachmentCount = 1; |
|
|
|
darken_subpass_description->pColorAttachments = &color_attachment_reference; |
|
|
|
darken_subpass_description->pDepthStencilAttachment = &depth_attachment_reference; |
|
|
|
darken_subpass_description->inputAttachmentCount = 1; |
|
|
|
darken_subpass_description->pInputAttachments = &input_attachment_reference; |
|
|
|
|
|
|
|
std::array<VkSubpassDependency, 2> subpass_dependencies = {}; |
|
|
|
VkSubpassDependency* color_subpass_dependency = &subpass_dependencies[0]; |
|
|
|
color_subpass_dependency->srcSubpass = VK_SUBPASS_EXTERNAL; |
|
|
|
color_subpass_dependency->dstSubpass = 0; |
|
|
|
color_subpass_dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
|
|
|
color_subpass_dependency->dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
|
|
|
color_subpass_dependency->srcAccessMask = 0; |
|
|
|
color_subpass_dependency->dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; |
|
|
|
color_subpass_dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; |
|
|
|
|
|
|
|
VkSubpassDependency* darken_subpass_dependency = &subpass_dependencies[1]; |
|
|
|
darken_subpass_dependency->srcSubpass = 0; |
|
|
|
darken_subpass_dependency->dstSubpass = 1; |
|
|
|
darken_subpass_dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
|
|
|
darken_subpass_dependency->dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; |
|
|
|
darken_subpass_dependency->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; |
|
|
|
darken_subpass_dependency->dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | |
|
|
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; |
|
|
|
darken_subpass_dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; |
|
|
|
|
|
|
|
VkRenderPassCreateInfo render_pass_info = {}; |
|
|
|
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; |
|
|
|
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; |
|
|
|
render_pass_info.pDependencies = &subpass_dependency; |
|
|
|
render_pass_info.subpassCount = subpass_descriptions.size(); |
|
|
|
render_pass_info.pSubpasses = subpass_descriptions.data(); |
|
|
|
render_pass_info.dependencyCount = subpass_dependencies.size(); |
|
|
|
render_pass_info.pDependencies = subpass_dependencies.data(); |
|
|
|
|
|
|
|
VkRenderPass render_pass; |
|
|
|
VkResult result = vkCreateRenderPass(device, &render_pass_info, nullptr, &render_pass); |
|
|
@@ -237,10 +375,27 @@ VkShaderModule CreateVkShaderModule(VkDevice device, std::string path) { |
|
|
|
return shader_module; |
|
|
|
} |
|
|
|
|
|
|
|
VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) { |
|
|
|
VkShaderModule vertex_shader_module = CreateVkShaderModule(device, kVertexShaderPath); |
|
|
|
VkShaderModule fragment_shader_module = CreateVkShaderModule(device, kFragmentShaderPath); |
|
|
|
VkPipelineLayout CreateVkPipelineLayout(VkDevice device, |
|
|
|
VkDescriptorSetLayout descriptor_set_layout) { |
|
|
|
VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; |
|
|
|
pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; |
|
|
|
if (descriptor_set_layout != VK_NULL_HANDLE) { |
|
|
|
pipeline_layout_create_info.setLayoutCount = 1; |
|
|
|
pipeline_layout_create_info.pSetLayouts = &descriptor_set_layout; |
|
|
|
} |
|
|
|
|
|
|
|
VkPipelineLayout pipeline_layout; |
|
|
|
VkResult result = vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, |
|
|
|
&pipeline_layout); |
|
|
|
if (result != VK_SUCCESS) { |
|
|
|
ERROR("Unable to create VkPipelineLayout: " << result); |
|
|
|
} |
|
|
|
return pipeline_layout; |
|
|
|
} |
|
|
|
|
|
|
|
VkPipeline CreateVkPipeline(VkDevice device, VkShaderModule vertex_shader_module, |
|
|
|
VkShaderModule fragment_shader_module, VkPipelineLayout pipeline_layout, |
|
|
|
VkRenderPass render_pass, uint32_t subpass) { |
|
|
|
VkPipelineShaderStageCreateInfo vertex_shader_stage_info = {}; |
|
|
|
vertex_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; |
|
|
|
vertex_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; |
|
|
@@ -327,16 +482,6 @@ VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) { |
|
|
|
color_blend_state.attachmentCount = 1; |
|
|
|
color_blend_state.pAttachments = &color_blend_attachment_state; |
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; |
|
|
|
pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; |
|
|
|
|
|
|
|
VkPipelineLayout pipeline_layout; |
|
|
|
VkResult result = vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, |
|
|
|
&pipeline_layout); |
|
|
|
if (result != VK_SUCCESS) { |
|
|
|
ERROR("Unable to create VkPipelineLayout: " << result); |
|
|
|
} |
|
|
|
|
|
|
|
VkGraphicsPipelineCreateInfo pipeline_create_info = {}; |
|
|
|
pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; |
|
|
|
pipeline_create_info.stageCount = 2; |
|
|
@@ -351,12 +496,12 @@ VkPipeline CreateVkPipeline(VkDevice device, VkRenderPass render_pass) { |
|
|
|
pipeline_create_info.pDynamicState = nullptr; |
|
|
|
pipeline_create_info.layout = pipeline_layout; |
|
|
|
pipeline_create_info.renderPass = render_pass; |
|
|
|
pipeline_create_info.subpass = 0; |
|
|
|
pipeline_create_info.subpass = subpass; |
|
|
|
pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE; |
|
|
|
pipeline_create_info.basePipelineIndex = -1; |
|
|
|
|
|
|
|
VkPipeline pipeline; |
|
|
|
result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, |
|
|
|
VkResult result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, |
|
|
|
&pipeline); |
|
|
|
if (result != VK_SUCCESS) { |
|
|
|
ERROR("Unable to create VkPipeline: " << result); |
|
|
@@ -504,8 +649,9 @@ VkImageView CreateDepthVkImageView(VkDevice device, VkImage image) { |
|
|
|
} |
|
|
|
|
|
|
|
VkFramebuffer CreateVkFramebuffer(VkDevice device, VkRenderPass render_pass, |
|
|
|
VkImageView render_image_view, VkImageView depth_image_view) { |
|
|
|
std::array<VkImageView, 2> attachments = { render_image_view, depth_image_view }; |
|
|
|
VkImageView render_image_view, VkImageView depth_image_view, VkImageView input_image_view) { |
|
|
|
std::array<VkImageView, 3> attachments = |
|
|
|
{ render_image_view, depth_image_view, input_image_view }; |
|
|
|
|
|
|
|
VkFramebufferCreateInfo create_info = {}; |
|
|
|
create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; |
|
|
@@ -560,8 +706,9 @@ void WaitForIdle(VkQueue queue) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline pipeline, |
|
|
|
VkFramebuffer framebuffer, VkCommandBuffer command_buffer) { |
|
|
|
void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline draw_pipeline, |
|
|
|
VkPipeline darken_pipeline, VkPipelineLayout darken_pipeline_layout, |
|
|
|
VkDescriptorSet descriptor_set, VkFramebuffer framebuffer, VkCommandBuffer command_buffer) { |
|
|
|
BeginCommandBuffer(command_buffer); |
|
|
|
VkRenderPassBeginInfo render_pass_begin_info = {}; |
|
|
|
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; |
|
|
@@ -574,19 +721,30 @@ void Draw(VkDevice device, VkQueue queue, VkRenderPass render_pass, VkPipeline p |
|
|
|
|
|
|
|
std::array<VkClearValue, 2> clear_values = {}; |
|
|
|
clear_values[0].color.float32[0] = 1.0f; |
|
|
|
clear_values[0].color.float32[1] = 1.0f; |
|
|
|
clear_values[0].color.float32[2] = 1.0f; |
|
|
|
clear_values[0].color.float32[1] = 0.0f; |
|
|
|
clear_values[0].color.float32[2] = 0.0f; |
|
|
|
clear_values[0].color.float32[3] = 1.0f; |
|
|
|
clear_values[1].depthStencil.depth = 1.0f; |
|
|
|
clear_values[1].depthStencil.stencil = 0.0f; |
|
|
|
clear_values[2].color.float32[0] = 1.0f; |
|
|
|
clear_values[2].color.float32[1] = 1.0f; |
|
|
|
clear_values[2].color.float32[2] = 1.0f; |
|
|
|
clear_values[2].color.float32[3] = 1.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); |
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, draw_pipeline); |
|
|
|
vkCmdDraw(command_buffer, 3, 1, 0, 0); |
|
|
|
vkCmdDraw(command_buffer, 3, 1, 3, 0); |
|
|
|
|
|
|
|
vkCmdNextSubpass(command_buffer, VK_SUBPASS_CONTENTS_INLINE); |
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, darken_pipeline); |
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, darken_pipeline_layout, |
|
|
|
0, 1, &descriptor_set, 0, nullptr); |
|
|
|
vkCmdDraw(command_buffer, 6, 1, 0, 0); |
|
|
|
|
|
|
|
vkCmdEndRenderPass(command_buffer); |
|
|
|
} |
|
|
|
|
|
|
@@ -675,23 +833,47 @@ int main() { |
|
|
|
VkCommandPool command_pool = CreateVkCommandPool(device, device_queue_family_index); |
|
|
|
VkCommandBuffer command_buffer = CreateVkCommandBuffer(device, command_pool); |
|
|
|
|
|
|
|
VkRenderPass render_pass = CreateVkRenderPass(device); |
|
|
|
VkPipeline pipeline = CreateVkPipeline(device, render_pass); |
|
|
|
|
|
|
|
VkImage render_image = CreateRenderVkImage(device); |
|
|
|
AllocateAndBindRenderMemory(physical_device, device, render_image); |
|
|
|
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); |
|
|
|
VkImage input_image = CreateRenderVkImage(device); |
|
|
|
AllocateAndBindRenderMemory(physical_device, device, input_image); |
|
|
|
VkImageView input_image_view = CreateRenderVkImageView(device, input_image); |
|
|
|
|
|
|
|
VkDescriptorSetLayout descriptor_set_layout = CreateVkDescriptorSetLayout(device); |
|
|
|
VkDescriptorPool descriptor_pool = CreateAttachmentVkDescriptorPool(device); |
|
|
|
VkDescriptorSet descriptor_set = CreateVkDescriptorSet(device, descriptor_set_layout, |
|
|
|
descriptor_pool); |
|
|
|
UpdateVkDescriptorSet(device, render_image_view, descriptor_set); |
|
|
|
|
|
|
|
VkRenderPass render_pass = CreateVkRenderPass(device); |
|
|
|
VkShaderModule draw_vertex_shader_module = |
|
|
|
CreateVkShaderModule(device, kDrawVertexShaderPath); |
|
|
|
VkShaderModule draw_fragment_shader_module = |
|
|
|
CreateVkShaderModule(device, kDrawFragmentShaderPath); |
|
|
|
VkPipelineLayout draw_pipeline_layout = CreateVkPipelineLayout(device, VK_NULL_HANDLE); |
|
|
|
VkPipeline draw_pipeline = CreateVkPipeline(device, draw_vertex_shader_module, |
|
|
|
draw_fragment_shader_module, draw_pipeline_layout, render_pass, 0 /* subpass */); |
|
|
|
VkShaderModule darken_vertex_shader_module = |
|
|
|
CreateVkShaderModule(device, kDarkenVertexShaderPath); |
|
|
|
VkShaderModule darken_fragment_shader_module = |
|
|
|
CreateVkShaderModule(device, kDarkenFragmentShaderPath); |
|
|
|
VkPipelineLayout darken_pipeline_layout = CreateVkPipelineLayout(device, descriptor_set_layout); |
|
|
|
VkPipeline darken_pipeline = CreateVkPipeline(device, darken_vertex_shader_module, |
|
|
|
darken_fragment_shader_module, darken_pipeline_layout, render_pass, 1 /* subpass */); |
|
|
|
|
|
|
|
VkFramebuffer framebuffer = CreateVkFramebuffer(device, render_pass, render_image_view, |
|
|
|
depth_image_view); |
|
|
|
depth_image_view, input_image_view); |
|
|
|
|
|
|
|
VkImage scanout_image = CreateScanoutVkImage(device); |
|
|
|
VkDeviceMemory scanout_image_memory = |
|
|
|
AllocateAndBindScanoutMemory(physical_device, device, scanout_image); |
|
|
|
|
|
|
|
Draw(device, queue, render_pass, pipeline, framebuffer, command_buffer); |
|
|
|
Draw(device, queue, render_pass, draw_pipeline, darken_pipeline, darken_pipeline_layout, |
|
|
|
descriptor_set, framebuffer, command_buffer); |
|
|
|
// Since the render target is created with VK_IMAGE_TILING_OPTIMAL, we need to copy it to a linear |
|
|
|
// format before scanning out. |
|
|
|
BlitToScanoutImage(queue, command_buffer, render_image, scanout_image); |