From 8b7b509077c52093a9fa936c0462248a24646c90 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Sat, 30 Sep 2023 14:34:22 -0300 Subject: refa Remove redundant render pass * src/vk/render_pass.hpp: Both 2D pipelines used identical render passes. I merged both in a single render pass. * src/vk/renderer.cpp (Renderer::draw): Use only one render pass for both 2D graphics pipelines. --- src/core.cpp | 20 +++ src/core.hpp | 2 + src/vk/graphics_pipeline_2d_solid.cpp | 6 +- src/vk/graphics_pipeline_2d_solid_layout.cpp | 74 +--------- src/vk/graphics_pipeline_2d_solid_layout.hpp | 1 - src/vk/graphics_pipeline_2d_wired.cpp | 6 +- src/vk/graphics_pipeline_2d_wired_layout.cpp | 74 +--------- src/vk/graphics_pipeline_2d_wired_layout.hpp | 1 - src/vk/graphics_pipeline_3d.cpp | 6 +- src/vk/graphics_pipeline_3d_layout.cpp | 89 +----------- src/vk/graphics_pipeline_3d_layout.hpp | 1 - src/vk/graphics_pipeline_3d_skeletal.cpp | 6 +- src/vk/render_pass.cpp | 203 +++++++++++++++++++++++++++ src/vk/render_pass.hpp | 36 +++++ src/vk/renderer.cpp | 121 +++++++--------- 15 files changed, 322 insertions(+), 324 deletions(-) create mode 100644 src/vk/render_pass.cpp create mode 100644 src/vk/render_pass.hpp diff --git a/src/core.cpp b/src/core.cpp index 34271bc..2f3cd77 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -524,6 +524,25 @@ unload_vk_swapchain(void *obj) delete cg_core.vk_swapchain; } +void +load_vk_render_pass(void *obj) +{ + try + { + cg_core.vk_render_pass = new VK::RenderPass(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create descriptor set layouts."}; + } +} + +void +unload_vk_render_pass(void *obj) +{ + delete cg_core.vk_render_pass; +} + void load_vk_descriptor_set_layout(void *obj) { @@ -747,6 +766,7 @@ const CommandChain cg_sCore::loader{ {&load_vk_devices, &unload_vk_devices}, {&load_vk_swapchain, &unload_vk_swapchain}, + {&load_vk_render_pass, &unload_vk_render_pass}, {&load_vk_descriptor_set_layout, &unload_vk_descriptor_set_layout}, {&load_vk_graphics_pipeline_3d_layout, &unload_vk_graphics_pipeline_3d_layout}, diff --git a/src/core.hpp b/src/core.hpp index 3f5edae..6336f6e 100644 --- a/src/core.hpp +++ b/src/core.hpp @@ -49,6 +49,7 @@ #include "vk/device.hpp" #include "vk/descriptor_set_layout.hpp" +#include "vk/render_pass.hpp" #include "vk/graphics_pipeline_2d_solid_layout.hpp" #include "vk/graphics_pipeline_2d_wired_layout.hpp" #include "vk/graphics_pipeline_2d_solid.hpp" @@ -118,6 +119,7 @@ struct cg_sCore VK::Device *vk_device_with_swapchain; VK::Swapchain *vk_swapchain; + VK::RenderPass *vk_render_pass; VK::DescriptorSetLayout *vk_descriptor_set_layout; VK::GraphicsPipeline3DLayout *vk_graphics_pipeline_3d_layout; VK::GraphicsPipeline2DSolidLayout *vk_graphics_pipeline_2d_solid_layout; diff --git a/src/vk/graphics_pipeline_2d_solid.cpp b/src/vk/graphics_pipeline_2d_solid.cpp index d7f2b17..8432a8a 100644 --- a/src/vk/graphics_pipeline_2d_solid.cpp +++ b/src/vk/graphics_pipeline_2d_solid.cpp @@ -39,8 +39,7 @@ load_framebuffer(void *obj) VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = - cg_core.vk_graphics_pipeline_2d_solid_layout->render_pass; + framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_2d; framebuffer_info.attachmentCount = attachments.size(); framebuffer_info.pAttachments = attachments.data(); framebuffer_info.width = cg_core.display_width; @@ -232,8 +231,7 @@ load_pipeline(void *obj) pipeline_info.pDynamicState = &dynamic_state_info; pipeline_info.layout = cg_core.vk_graphics_pipeline_2d_solid_layout->pipeline; - pipeline_info.renderPass = - cg_core.vk_graphics_pipeline_2d_solid_layout->render_pass; + pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_2d; pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; diff --git a/src/vk/graphics_pipeline_2d_solid_layout.cpp b/src/vk/graphics_pipeline_2d_solid_layout.cpp index cbd656a..712e840 100644 --- a/src/vk/graphics_pipeline_2d_solid_layout.cpp +++ b/src/vk/graphics_pipeline_2d_solid_layout.cpp @@ -61,80 +61,8 @@ unload_pipeline(void *obj) cg_core.vk_device_with_swapchain->device, self->pipeline, nullptr); } -void -load_render_pass(void *obj) -{ - auto self = static_cast(obj); - - std::array attachments{}; - // Color attachment. - attachments[0].flags = 0; - attachments[0].format = cg_core.vk_swapchain->image_format; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkAttachmentReference color_attachment_ref{}; - color_attachment_ref.attachment = 0; - color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass{}; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment_ref; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkSubpassDependency dependency{}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - 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 | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPassCreateInfo render_pass_info{}; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.pNext = nullptr; - render_pass_info.flags = 0; - render_pass_info.attachmentCount = attachments.size(); - render_pass_info.pAttachments = attachments.data(); - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - render_pass_info.dependencyCount = 1; - render_pass_info.pDependencies = &dependency; - - if(vkCreateRenderPass( - cg_core.vk_device_with_swapchain->device, &render_pass_info, - nullptr, &self->render_pass) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 2D."}; -} - -static void -unload_render_pass(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, self->render_pass, nullptr); -} - const CommandChain loader{ - {&load_pipeline, &unload_pipeline}, - {&load_render_pass, &unload_render_pass} + {&load_pipeline, &unload_pipeline} }; } diff --git a/src/vk/graphics_pipeline_2d_solid_layout.hpp b/src/vk/graphics_pipeline_2d_solid_layout.hpp index 59a5c5e..0bb9de8 100644 --- a/src/vk/graphics_pipeline_2d_solid_layout.hpp +++ b/src/vk/graphics_pipeline_2d_solid_layout.hpp @@ -25,7 +25,6 @@ namespace VK struct GraphicsPipeline2DSolidLayout { VkPipelineLayout pipeline; - VkRenderPass render_pass; GraphicsPipeline2DSolidLayout(); ~GraphicsPipeline2DSolidLayout(); diff --git a/src/vk/graphics_pipeline_2d_wired.cpp b/src/vk/graphics_pipeline_2d_wired.cpp index 51431b4..6590508 100644 --- a/src/vk/graphics_pipeline_2d_wired.cpp +++ b/src/vk/graphics_pipeline_2d_wired.cpp @@ -67,8 +67,7 @@ load_framebuffer(void *obj) VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = - cg_core.vk_graphics_pipeline_2d_wired_layout->render_pass; + framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_2d; framebuffer_info.attachmentCount = attachments.size(); framebuffer_info.pAttachments = attachments.data(); framebuffer_info.width = cg_core.display_width; @@ -244,8 +243,7 @@ load_pipeline(void *obj) pipeline_info.pDynamicState = &dynamic_state_info; pipeline_info.layout = cg_core.vk_graphics_pipeline_2d_wired_layout->pipeline; - pipeline_info.renderPass = - cg_core.vk_graphics_pipeline_2d_wired_layout->render_pass; + pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_2d; pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; diff --git a/src/vk/graphics_pipeline_2d_wired_layout.cpp b/src/vk/graphics_pipeline_2d_wired_layout.cpp index fe935eb..10e2b50 100644 --- a/src/vk/graphics_pipeline_2d_wired_layout.cpp +++ b/src/vk/graphics_pipeline_2d_wired_layout.cpp @@ -65,80 +65,8 @@ unload_pipeline(void *obj) cg_core.vk_device_with_swapchain->device, self->pipeline, nullptr); } -void -load_render_pass(void *obj) -{ - auto self = static_cast(obj); - - std::array attachments{}; - // Color attachment. - attachments[0].flags = 0; - attachments[0].format = cg_core.vk_swapchain->image_format; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - VkAttachmentReference color_attachment_ref{}; - color_attachment_ref.attachment = 0; - color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass{}; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment_ref; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkSubpassDependency dependency{}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - 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 | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPassCreateInfo render_pass_info{}; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.pNext = nullptr; - render_pass_info.flags = 0; - render_pass_info.attachmentCount = attachments.size(); - render_pass_info.pAttachments = attachments.data(); - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - render_pass_info.dependencyCount = 1; - render_pass_info.pDependencies = &dependency; - - if(vkCreateRenderPass( - cg_core.vk_device_with_swapchain->device, &render_pass_info, - nullptr, &self->render_pass) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 2D."}; -} - -static void -unload_render_pass(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, self->render_pass, nullptr); -} - const CommandChain loader{ - {&load_pipeline, &unload_pipeline}, - {&load_render_pass, &unload_render_pass} + {&load_pipeline, &unload_pipeline} }; } diff --git a/src/vk/graphics_pipeline_2d_wired_layout.hpp b/src/vk/graphics_pipeline_2d_wired_layout.hpp index f08aeaa..004f009 100644 --- a/src/vk/graphics_pipeline_2d_wired_layout.hpp +++ b/src/vk/graphics_pipeline_2d_wired_layout.hpp @@ -25,7 +25,6 @@ namespace VK struct GraphicsPipeline2DWiredLayout { VkPipelineLayout pipeline; - VkRenderPass render_pass; GraphicsPipeline2DWiredLayout(); ~GraphicsPipeline2DWiredLayout(); diff --git a/src/vk/graphics_pipeline_3d.cpp b/src/vk/graphics_pipeline_3d.cpp index 3d4b7cd..a1a1785 100644 --- a/src/vk/graphics_pipeline_3d.cpp +++ b/src/vk/graphics_pipeline_3d.cpp @@ -270,8 +270,7 @@ load_framebuffer(void *obj) VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; + framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_3d; framebuffer_info.attachmentCount = attachments.size(); framebuffer_info.pAttachments = attachments.data(); framebuffer_info.width = cg_core.display_width; @@ -483,8 +482,7 @@ load_pipeline(void *obj) pipeline_info.pColorBlendState = &color_blending; pipeline_info.pDynamicState = &dynamic_state_info; pipeline_info.layout = cg_core.vk_graphics_pipeline_3d_layout->pipeline; - pipeline_info.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; + pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_3d; pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; diff --git a/src/vk/graphics_pipeline_3d_layout.cpp b/src/vk/graphics_pipeline_3d_layout.cpp index e5a0c82..5f8cf5b 100644 --- a/src/vk/graphics_pipeline_3d_layout.cpp +++ b/src/vk/graphics_pipeline_3d_layout.cpp @@ -56,95 +56,8 @@ unload_pipeline(void *obj) cg_core.vk_device_with_swapchain->device, self->pipeline, nullptr); } -void -load_render_pass(void *obj) -{ - auto self = static_cast(obj); - - std::array attachments{}; - // Color attachment. - attachments[0].flags = 0; - attachments[0].format = cg_core.vk_swapchain->image_format; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - // Depth attachment. - attachments[1].flags = 0; - attachments[1].format = VK_FORMAT_D32_SFLOAT; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[1].finalLayout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference color_attachment_ref{}; - color_attachment_ref.attachment = 0; - color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - VkAttachmentReference depth_attachment_ref{}; - depth_attachment_ref.attachment = 1; - depth_attachment_ref.layout = - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass = {}; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment_ref; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = &depth_attachment_ref; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkSubpassDependency dependency = {}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - 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 | - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - VkRenderPassCreateInfo render_pass_info{}; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.pNext = nullptr; - render_pass_info.flags = 0; - render_pass_info.attachmentCount = attachments.size(); - render_pass_info.pAttachments = attachments.data(); - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - render_pass_info.dependencyCount = 1; - render_pass_info.pDependencies = &dependency; - - if(vkCreateRenderPass( - cg_core.vk_device_with_swapchain->device, &render_pass_info, nullptr, - &self->render_pass) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 3D."}; -} - -void -unload_render_pass(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, self->render_pass, nullptr); -} - const CommandChain loader{ - {&load_pipeline, &unload_pipeline}, - {&load_render_pass, &unload_render_pass} + {&load_pipeline, &unload_pipeline} }; } diff --git a/src/vk/graphics_pipeline_3d_layout.hpp b/src/vk/graphics_pipeline_3d_layout.hpp index 2117fb6..4b2b9b9 100644 --- a/src/vk/graphics_pipeline_3d_layout.hpp +++ b/src/vk/graphics_pipeline_3d_layout.hpp @@ -25,7 +25,6 @@ namespace VK struct GraphicsPipeline3DLayout { VkPipelineLayout pipeline; - VkRenderPass render_pass; GraphicsPipeline3DLayout(); ~GraphicsPipeline3DLayout(); diff --git a/src/vk/graphics_pipeline_3d_skeletal.cpp b/src/vk/graphics_pipeline_3d_skeletal.cpp index 7bf2521..bf75b25 100644 --- a/src/vk/graphics_pipeline_3d_skeletal.cpp +++ b/src/vk/graphics_pipeline_3d_skeletal.cpp @@ -270,8 +270,7 @@ load_framebuffer(void *obj) VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; + framebuffer_info.renderPass = cg_core.vk_render_pass->pipeline_3d; framebuffer_info.attachmentCount = attachments.size(); framebuffer_info.pAttachments = attachments.data(); framebuffer_info.width = cg_core.display_width; @@ -493,8 +492,7 @@ load_pipeline(void *obj) pipeline_info.pColorBlendState = &color_blending; pipeline_info.pDynamicState = &dynamic_state_info; pipeline_info.layout = cg_core.vk_graphics_pipeline_3d_layout->pipeline; - pipeline_info.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; + pipeline_info.renderPass = cg_core.vk_render_pass->pipeline_3d; pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; diff --git a/src/vk/render_pass.cpp b/src/vk/render_pass.cpp new file mode 100644 index 0000000..799cde4 --- /dev/null +++ b/src/vk/render_pass.cpp @@ -0,0 +1,203 @@ +/* + * Copyright 2022-2023 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "render_pass.hpp" + +#include + +#include "../core.hpp" + +namespace +{ + +void +load_3d(void *obj) +{ + auto self = static_cast(obj); + + std::array attachments{}; + // Color attachment. + attachments[0].flags = 0; + attachments[0].format = cg_core.vk_swapchain->image_format; + attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; + attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + // Depth attachment. + attachments[1].flags = 0; + attachments[1].format = VK_FORMAT_D32_SFLOAT; + attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; + attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachments[1].finalLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkAttachmentReference color_attachment_ref{}; + color_attachment_ref.attachment = 0; + color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkAttachmentReference depth_attachment_ref{}; + depth_attachment_ref.attachment = 1; + depth_attachment_ref.layout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass = {}; + subpass.flags = 0; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_attachment_ref; + subpass.pResolveAttachments = nullptr; + subpass.pDepthStencilAttachment = &depth_attachment_ref; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = nullptr; + + VkSubpassDependency dependency = {}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + 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 | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + VkRenderPassCreateInfo render_pass_info{}; + render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info.pNext = nullptr; + render_pass_info.flags = 0; + render_pass_info.attachmentCount = attachments.size(); + render_pass_info.pAttachments = attachments.data(); + render_pass_info.subpassCount = 1; + render_pass_info.pSubpasses = &subpass; + render_pass_info.dependencyCount = 1; + render_pass_info.pDependencies = &dependency; + + if(vkCreateRenderPass( + cg_core.vk_device_with_swapchain->device, &render_pass_info, nullptr, + &self->pipeline_3d) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan Render Pass 3D."}; +} + +void +unload_3d(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyRenderPass( + cg_core.vk_device_with_swapchain->device, self->pipeline_3d, nullptr); +} + +void +load_2d(void *obj) +{ + auto self = static_cast(obj); + + std::array attachments{}; + // Color attachment. + attachments[0].flags = 0; + attachments[0].format = cg_core.vk_swapchain->image_format; + attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; + attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + VkAttachmentReference color_attachment_ref{}; + color_attachment_ref.attachment = 0; + color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkSubpassDescription subpass{}; + subpass.flags = 0; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.inputAttachmentCount = 0; + subpass.pInputAttachments = nullptr; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_attachment_ref; + subpass.pResolveAttachments = nullptr; + subpass.pDepthStencilAttachment = nullptr; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = nullptr; + + VkSubpassDependency dependency{}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + 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 | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + VkRenderPassCreateInfo render_pass_info{}; + render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info.pNext = nullptr; + render_pass_info.flags = 0; + render_pass_info.attachmentCount = attachments.size(); + render_pass_info.pAttachments = attachments.data(); + render_pass_info.subpassCount = 1; + render_pass_info.pSubpasses = &subpass; + render_pass_info.dependencyCount = 1; + render_pass_info.pDependencies = &dependency; + + if(vkCreateRenderPass( + cg_core.vk_device_with_swapchain->device, &render_pass_info, + nullptr, &self->pipeline_2d) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan Render Pass 2D."}; +} + +void +unload_2d(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyRenderPass( + cg_core.vk_device_with_swapchain->device, self->pipeline_2d, nullptr); +} + +const CommandChain loader{ + {&load_3d, &unload_3d}, + {&load_2d, &unload_2d} +}; + +} + +namespace VK +{ + +RenderPass::RenderPass() +{ + loader.execute(this); +} + +RenderPass::~RenderPass() +{ + loader.revert(this); +} + +} diff --git a/src/vk/render_pass.hpp b/src/vk/render_pass.hpp new file mode 100644 index 0000000..2f96062 --- /dev/null +++ b/src/vk/render_pass.hpp @@ -0,0 +1,36 @@ +/* + * Copyright 2022-2023 Frederico de Oliveira Linhares + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CANDY_GEAR_VK_RENDER_PASS_H +#define CANDY_GEAR_VK_RENDER_PASS_H 1 + +#include "core.hpp" + +namespace VK +{ + +struct RenderPass +{ + VkRenderPass pipeline_2d; + VkRenderPass pipeline_3d; + + RenderPass(); + ~RenderPass(); +}; + +} + +#endif /* CANDY_GEAR_VK_RENDER_PASS_H */ diff --git a/src/vk/renderer.cpp b/src/vk/renderer.cpp index 753b5f7..3daeee7 100644 --- a/src/vk/renderer.cpp +++ b/src/vk/renderer.cpp @@ -102,9 +102,9 @@ unload_command_pool(void *obj) auto self = static_cast(obj); vkWaitForFences(cg_core.vk_device_with_swapchain->device, - VK::Swapchain::max_frames_in_flight, - cg_core.vk_swapchain->in_flight_fences.data(), VK_TRUE, - std::numeric_limits::max()); + VK::Swapchain::max_frames_in_flight, + cg_core.vk_swapchain->in_flight_fences.data(), VK_TRUE, + std::numeric_limits::max()); vkDestroyCommandPool( self->queue_family->device->device, self->command_pool, nullptr); } @@ -143,7 +143,7 @@ namespace VK { Renderer::Renderer(std::vector> views_2d, - std::vector> views_3d): + std::vector> views_3d): skeletal_models_to_draw{cg_core.vk_swapchain->images_count}, static_models_to_draw{cg_core.vk_swapchain->images_count}, views_2d{views_2d}, @@ -153,7 +153,7 @@ Renderer::Renderer(std::vector> views_2d, } Renderer::Renderer(std::initializer_list> views_2d, - std::initializer_list> views_3d): + std::initializer_list> views_3d): Renderer(std::vector(views_2d), std::vector(views_3d)) { } @@ -177,15 +177,15 @@ Renderer::draw() if(next_frame == Swapchain::max_frames_in_flight) next_frame = 0; vkResetFences(cg_core.vk_device_with_swapchain->device, 1, - &cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]); + &cg_core.vk_swapchain->in_flight_fences[ + cg_core.vk_swapchain->current_frame]); uint32_t image_index; vkAcquireNextImageKHR( cg_core.vk_device_with_swapchain->device, cg_core.vk_swapchain->swapchain, std::numeric_limits::max(), cg_core.vk_swapchain->image_available_semaphores[ - cg_core.vk_swapchain->current_frame], VK_NULL_HANDLE, &image_index); + cg_core.vk_swapchain->current_frame], VK_NULL_HANDLE, &image_index); VkCommandBuffer draw_command_buffer = this->draw_command_buffers[cg_core.vk_swapchain->current_frame]; @@ -198,7 +198,7 @@ Renderer::draw() begin_info.flags = 0; begin_info.pInheritanceInfo = nullptr; if (vkBeginCommandBuffer(draw_command_buffer, &begin_info) != VK_SUCCESS) - throw std::runtime_error{"Failed to beggin draw command buffer."}; + throw std::runtime_error{"Failed to beggin draw command buffer."}; } // 3D drawing. @@ -227,94 +227,73 @@ Renderer::draw() VkRenderPassBeginInfo render_pass_begin{}; render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_3d_layout->render_pass; + render_pass_begin.renderPass = cg_core.vk_render_pass->pipeline_3d; render_pass_begin.framebuffer = - cg_core.vk_graphics_pipeline_3d->swapchain_framebuffers[image_index]; + cg_core.vk_graphics_pipeline_3d->swapchain_framebuffers[image_index]; render_pass_begin.renderArea.offset = {0, 0}; render_pass_begin.renderArea.extent = { - static_cast(cg_core.display_width), - static_cast(cg_core.display_height)}; + static_cast(cg_core.display_width), + static_cast(cg_core.display_height)}; render_pass_begin.clearValueCount = clear_values.size(); render_pass_begin.pClearValues = clear_values.data(); vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_3d->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - image_index); + cg_core.vk_graphics_pipeline_3d->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + image_index); vkCmdEndRenderPass(draw_command_buffer); } - // 2D solid drawing - { + { // 2D render pass VkRenderPassBeginInfo render_pass_begin{}; render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_2d_solid_layout->render_pass; + render_pass_begin.renderPass = cg_core.vk_render_pass->pipeline_2d; render_pass_begin.framebuffer = - cg_core.vk_graphics_pipeline_2d_solid->swapchain_framebuffers[ - image_index]; + cg_core.vk_graphics_pipeline_2d_solid->swapchain_framebuffers[ + image_index]; render_pass_begin.renderArea.offset = {0, 0}; render_pass_begin.renderArea.extent = { - static_cast(cg_core.display_width), - static_cast(cg_core.display_height)}; + static_cast(cg_core.display_width), + static_cast(cg_core.display_height)}; render_pass_begin.clearValueCount = 0; render_pass_begin.pClearValues = nullptr; vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); + + } + { // 2D solid drawing for(auto &view: this->views_2d) - cg_core.vk_graphics_pipeline_2d_solid->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); + cg_core.vk_graphics_pipeline_2d_solid->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + next_frame, image_index); for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_2d_solid->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - - vkCmdEndRenderPass(draw_command_buffer); + cg_core.vk_graphics_pipeline_2d_solid->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + next_frame, image_index); } - // 2D wired drawing - { - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_2d_wired_layout->render_pass; - render_pass_begin.framebuffer = - cg_core.vk_graphics_pipeline_2d_wired->swapchain_framebuffers[ - image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - static_cast(cg_core.display_width), - static_cast(cg_core.display_height)}; - render_pass_begin.clearValueCount = 0; - render_pass_begin.pClearValues = nullptr; - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - + { // 2D wired drawing for(auto &view: this->views_2d) - cg_core.vk_graphics_pipeline_2d_wired->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); + cg_core.vk_graphics_pipeline_2d_wired->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + next_frame, image_index); for(auto &view: this->views_3d) - cg_core.vk_graphics_pipeline_2d_wired->draw( - view, draw_command_buffer, cg_core.vk_swapchain->current_frame, - next_frame, image_index); - - vkCmdEndRenderPass(draw_command_buffer); + cg_core.vk_graphics_pipeline_2d_wired->draw( + view, draw_command_buffer, cg_core.vk_swapchain->current_frame, + next_frame, image_index); } + vkCmdEndRenderPass(draw_command_buffer); + // End command buffer. if(vkEndCommandBuffer(draw_command_buffer) != VK_SUCCESS) throw std::runtime_error{"Failed to end draw command buffer."}; @@ -324,13 +303,13 @@ Renderer::draw() auto queue{this->queue_family->get_queue()}; VkSemaphore wait_semaphores[]{ - cg_core.vk_swapchain->image_available_semaphores[ - cg_core.vk_swapchain->current_frame]}; + cg_core.vk_swapchain->image_available_semaphores[ + cg_core.vk_swapchain->current_frame]}; VkPipelineStageFlags wait_stages[] = - {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkSemaphore signal_semaphores[]{ - cg_core.vk_swapchain->render_finished_semaphores[ - cg_core.vk_swapchain->current_frame]}; + cg_core.vk_swapchain->render_finished_semaphores[ + cg_core.vk_swapchain->current_frame]}; VkSubmitInfo submit_info{}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -344,9 +323,9 @@ Renderer::draw() submit_info.pSignalSemaphores = signal_semaphores; if(vkQueueSubmit( - queue.queue, 1, &submit_info, cg_core.vk_swapchain->in_flight_fences[ - cg_core.vk_swapchain->current_frame]) != VK_SUCCESS) - throw std::runtime_error{"Failed to submit draw command buffer."}; + queue.queue, 1, &submit_info, cg_core.vk_swapchain->in_flight_fences[ + cg_core.vk_swapchain->current_frame]) != VK_SUCCESS) + throw std::runtime_error{"Failed to submit draw command buffer."}; VkSwapchainKHR swap_chains[]{cg_core.vk_swapchain->swapchain}; -- cgit v1.2.3