summaryrefslogtreecommitdiff
path: root/src/vk
diff options
context:
space:
mode:
authorFrederico Linhares <fred@linhares.blue>2023-09-30 14:34:22 -0300
committerFrederico Linhares <fred@linhares.blue>2023-09-30 14:44:29 -0300
commit8b7b509077c52093a9fa936c0462248a24646c90 (patch)
tree2f005557813ae9ec52bbf3d1df8cd588f36851a3 /src/vk
parentb44c79e11ba574c74ae650e1430b1d173aacc910 (diff)
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.
Diffstat (limited to 'src/vk')
-rw-r--r--src/vk/graphics_pipeline_2d_solid.cpp6
-rw-r--r--src/vk/graphics_pipeline_2d_solid_layout.cpp74
-rw-r--r--src/vk/graphics_pipeline_2d_solid_layout.hpp1
-rw-r--r--src/vk/graphics_pipeline_2d_wired.cpp6
-rw-r--r--src/vk/graphics_pipeline_2d_wired_layout.cpp74
-rw-r--r--src/vk/graphics_pipeline_2d_wired_layout.hpp1
-rw-r--r--src/vk/graphics_pipeline_3d.cpp6
-rw-r--r--src/vk/graphics_pipeline_3d_layout.cpp89
-rw-r--r--src/vk/graphics_pipeline_3d_layout.hpp1
-rw-r--r--src/vk/graphics_pipeline_3d_skeletal.cpp6
-rw-r--r--src/vk/render_pass.cpp203
-rw-r--r--src/vk/render_pass.hpp36
-rw-r--r--src/vk/renderer.cpp121
13 files changed, 300 insertions, 324 deletions
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<VK::GraphicsPipeline2DSolidLayout*>(obj);
-
- std::array<VkAttachmentDescription, 1> 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<VK::GraphicsPipeline2DSolidLayout*>(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<VK::GraphicsPipeline2DWiredLayout*>(obj);
-
- std::array<VkAttachmentDescription, 1> 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<VK::GraphicsPipeline2DWiredLayout*>(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<VK::GraphicsPipeline3DLayout*>(obj);
-
- std::array<VkAttachmentDescription, 2> 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<VK::GraphicsPipeline3DLayout*>(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 <array>
+
+#include "../core.hpp"
+
+namespace
+{
+
+void
+load_3d(void *obj)
+{
+ auto self = static_cast<VK::RenderPass*>(obj);
+
+ std::array<VkAttachmentDescription, 2> 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<VK::RenderPass*>(obj);
+
+ vkDestroyRenderPass(
+ cg_core.vk_device_with_swapchain->device, self->pipeline_3d, nullptr);
+}
+
+void
+load_2d(void *obj)
+{
+ auto self = static_cast<VK::RenderPass*>(obj);
+
+ std::array<VkAttachmentDescription, 1> 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<VK::RenderPass*>(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<VK::Renderer*>(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<uint64_t>::max());
+ VK::Swapchain::max_frames_in_flight,
+ cg_core.vk_swapchain->in_flight_fences.data(), VK_TRUE,
+ std::numeric_limits<uint64_t>::max());
vkDestroyCommandPool(
self->queue_family->device->device, self->command_pool, nullptr);
}
@@ -143,7 +143,7 @@ namespace VK
{
Renderer::Renderer(std::vector<std::shared_ptr<View2D>> views_2d,
- std::vector<std::shared_ptr<View3D>> views_3d):
+ std::vector<std::shared_ptr<View3D>> 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<std::shared_ptr<View2D>> views_2d,
}
Renderer::Renderer(std::initializer_list<std::shared_ptr<View2D>> views_2d,
- std::initializer_list<std::shared_ptr<View3D>> views_3d):
+ std::initializer_list<std::shared_ptr<View3D>> 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<uint64_t>::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<uint32_t>(cg_core.display_width),
- static_cast<uint32_t>(cg_core.display_height)};
+ static_cast<uint32_t>(cg_core.display_width),
+ static_cast<uint32_t>(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<uint32_t>(cg_core.display_width),
- static_cast<uint32_t>(cg_core.display_height)};
+ static_cast<uint32_t>(cg_core.display_width),
+ static_cast<uint32_t>(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<uint32_t>(cg_core.display_width),
- static_cast<uint32_t>(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};