From e386b9fd4ebc13a6a04def65585e795f4d39335d Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Thu, 8 Sep 2022 13:59:17 -0300 Subject: refa Move layouts away from graphics pipelines --- src/core.cpp | 193 ++++++------------------- src/core.hpp | 8 +- src/vk/graphics_pipeline_2d.cpp | 147 +++---------------- src/vk/graphics_pipeline_2d.hpp | 4 - src/vk/graphics_pipeline_2d_layout.cpp | 232 ++++++++++++++++++++++++++++++ src/vk/graphics_pipeline_2d_layout.hpp | 38 +++++ src/vk/graphics_pipeline_3d.cpp | 160 +++------------------ src/vk/graphics_pipeline_3d.hpp | 4 - src/vk/graphics_pipeline_3d_layout.cpp | 252 +++++++++++++++++++++++++++++++++ src/vk/graphics_pipeline_3d_layout.hpp | 38 +++++ src/vk/model.cpp | 2 +- src/vk/sprite.cpp | 2 +- 12 files changed, 651 insertions(+), 429 deletions(-) create mode 100644 src/vk/graphics_pipeline_2d_layout.cpp create mode 100644 src/vk/graphics_pipeline_2d_layout.hpp create mode 100644 src/vk/graphics_pipeline_3d_layout.cpp create mode 100644 src/vk/graphics_pipeline_3d_layout.hpp diff --git a/src/core.cpp b/src/core.cpp index 2ad14bd..46fb6eb 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -452,154 +452,43 @@ unload_vk_swapchain(void *obj) } static void -load_vk_render_pass_3d(void *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, &cg_core.vk_render_pass_3d) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 3D."}; -} - -static void -unload_vk_render_pass_3d(void *obj) -{ - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, cg_core.vk_render_pass_3d, - nullptr); -} - -static void -load_vk_render_pass_2d(void *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, &cg_core.vk_render_pass_2d) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan Render Pass 2D."}; -} - -static void -unload_vk_render_pass_2d(void *obj) -{ - vkDestroyRenderPass( - cg_core.vk_device_with_swapchain->device, cg_core.vk_render_pass_2d, - nullptr); +load_vk_graphics_pipeline_3d_layout(void *obj) +{ + try + { + cg_core.vk_graphics_pipeline_3d_layout = + new VK::GraphicsPipeline3DLayout(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 3d graphics pipeline."}; + } +} + +static void +unload_vk_graphics_pipeline_3d_layout(void *obj) +{ + delete cg_core.vk_graphics_pipeline_3d_layout; +} + +static void +load_vk_graphics_pipeline_2d_layout(void *obj) +{ + try + { + cg_core.vk_graphics_pipeline_2d_layout = + new VK::GraphicsPipeline2DLayout(); + } + catch(const CommandError &e) + { + throw CommandError{"Failed to create 2d graphics pipeline."}; + } +} + +static void +unload_vk_graphics_pipeline_2d_layout(void *obj) +{ + delete cg_core.vk_graphics_pipeline_2d_layout; } static void @@ -697,10 +586,14 @@ const CommandChain cg_sCore::loader{ #endif {&load_vk_devices, &unload_vk_devices}, {&load_vk_swapchain, &unload_vk_swapchain}, - {&load_vk_render_pass_3d, &unload_vk_render_pass_3d}, - {&load_vk_render_pass_2d, &unload_vk_render_pass_2d}, + + {&load_vk_graphics_pipeline_3d_layout, + &unload_vk_graphics_pipeline_3d_layout}, + {&load_vk_graphics_pipeline_2d_layout, + &unload_vk_graphics_pipeline_2d_layout}, {&load_vk_graphics_pipeline_3d, &unload_vk_graphics_pipeline_3d}, {&load_vk_graphics_pipeline_2d, &unload_vk_graphics_pipeline_2d}, + {&load_vk_renderer, &unload_vk_renderer}, {&load_mruby, &unload_mruby}, {&load_mruby_symbols, nullptr} diff --git a/src/core.hpp b/src/core.hpp index 414173e..c7dbceb 100644 --- a/src/core.hpp +++ b/src/core.hpp @@ -42,6 +42,8 @@ #include "log.hpp" #include "vk/device.hpp" +#include "vk/graphics_pipeline_3d_layout.hpp" +#include "vk/graphics_pipeline_2d_layout.hpp" #include "vk/graphics_pipeline_3d.hpp" #include "vk/graphics_pipeline_2d.hpp" #include "vk/renderer.hpp" @@ -105,10 +107,12 @@ struct cg_sCore std::vector vk_devices; VK::Device *vk_device_with_swapchain; VK::Swapchain *vk_swapchain; - VkRenderPass vk_render_pass_3d; - VkRenderPass vk_render_pass_2d; + + VK::GraphicsPipeline3DLayout *vk_graphics_pipeline_3d_layout; + VK::GraphicsPipeline2DLayout *vk_graphics_pipeline_2d_layout; VK::GraphicsPipeline3D *vk_graphics_pipeline_3d; VK::GraphicsPipeline2D *vk_graphics_pipeline_2d; + VK::Renderer *vk_renderer; bool quit_game; diff --git a/src/vk/graphics_pipeline_2d.cpp b/src/vk/graphics_pipeline_2d.cpp index bc1eca1..61cfe3f 100644 --- a/src/vk/graphics_pipeline_2d.cpp +++ b/src/vk/graphics_pipeline_2d.cpp @@ -24,119 +24,6 @@ namespace { -void -load_descriptor_set_layout_projection(void *obj) -{ - auto self = static_cast(obj); - - std::array layout_bindings{}; - - layout_bindings[0].binding = 0; - layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layout_bindings[0].descriptorCount = 1; - layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - layout_bindings[0].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = static_cast(layout_bindings.size()); - layout_info.pBindings = layout_bindings.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->descriptor_set_layout_projection) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for projection."}; -} - -void -unload_descriptor_set_layout_projection(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, - self->descriptor_set_layout_projection, nullptr); -} - -void -load_descriptor_set_layout_sprite(void *obj) -{ - auto self = static_cast(obj); - - std::array layout_bindings{}; - - layout_bindings[0].binding = 0; - layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layout_bindings[0].descriptorCount = 1; - layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - layout_bindings[0].pImmutableSamplers = nullptr; - - layout_bindings[1].binding = 1; - layout_bindings[1].descriptorType = - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - layout_bindings[1].descriptorCount = 1; - layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - layout_bindings[1].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = static_cast(layout_bindings.size()); - layout_info.pBindings = layout_bindings.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->descriptor_set_layout_sprite) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for sprites."}; -} - -void -unload_descriptor_set_layout_sprite(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, - self->descriptor_set_layout_sprite, nullptr); -} - -void -load_pipeline_layout(void *obj) -{ - auto self = static_cast(obj); - - std::array set_layouts{ - self->descriptor_set_layout_projection, - self->descriptor_set_layout_sprite - }; - - VkPipelineLayoutCreateInfo pipeline_layout_info{}; - pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = set_layouts.size(); - pipeline_layout_info.pSetLayouts = set_layouts.data(); - pipeline_layout_info.pushConstantRangeCount = 0; - pipeline_layout_info.pPushConstantRanges = nullptr; - - if(vkCreatePipelineLayout( - cg_core.vk_device_with_swapchain->device, - &pipeline_layout_info, nullptr, &self->pipeline_layout) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan pipeline layout."}; -} - -void -unload_pipeline_layout(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyPipelineLayout( - cg_core.vk_device_with_swapchain->device, self->pipeline_layout, nullptr); -} - void load_projection_uniform_buffer(void *obj) { @@ -181,8 +68,8 @@ load_descriptor_pool(void *obj) pool_info.pPoolSizes = &descriptor_pool_size; if(vkCreateDescriptorPool( - cg_core.vk_device_with_swapchain->device, - &pool_info, nullptr, &self->descriptor_pool) != VK_SUCCESS) + cg_core.vk_device_with_swapchain->device, &pool_info, nullptr, + &self->descriptor_pool) != VK_SUCCESS) throw CommandError{"Failed to create a Vulkan descriptor pool."}; } @@ -192,7 +79,8 @@ unload_descriptor_pool(void *obj) auto self = static_cast(obj); vkDestroyDescriptorPool( - cg_core.vk_device_with_swapchain->device, self->descriptor_pool, nullptr); + cg_core.vk_device_with_swapchain->device, self->descriptor_pool, + nullptr); } void @@ -202,7 +90,7 @@ load_projection_descriptor_sets(void *obj) std::vector layouts( self->ub_projection.size(), - self->descriptor_set_layout_projection); + cg_core.vk_graphics_pipeline_2d_layout->descriptor_set_projection); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; @@ -267,7 +155,8 @@ load_framebuffer(void *obj) VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = cg_core.vk_render_pass_2d; + framebuffer_info.renderPass = + cg_core.vk_graphics_pipeline_2d_layout->render_pass; framebuffer_info.attachmentCount = attachments.size(); framebuffer_info.pAttachments = attachments.data(); framebuffer_info.width = cg_core.screen_width; @@ -276,7 +165,8 @@ load_framebuffer(void *obj) if(vkCreateFramebuffer( cg_core.vk_device_with_swapchain->device, &framebuffer_info, nullptr, - &self->swapchain_framebuffers[i]) != VK_SUCCESS) + &self->swapchain_framebuffers[i]) + != VK_SUCCESS) throw CommandError{"Failed to create Vulkan Framebuffer."}; } } @@ -454,15 +344,17 @@ load_pipeline(void *obj) pipeline_info.pDepthStencilState = nullptr; pipeline_info.pColorBlendState = &color_blending; pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = self->pipeline_layout; - pipeline_info.renderPass = cg_core.vk_render_pass_2d; + pipeline_info.layout = cg_core.vk_graphics_pipeline_2d_layout->pipeline; + pipeline_info.renderPass = + cg_core.vk_graphics_pipeline_2d_layout->render_pass; pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; if(vkCreateGraphicsPipelines( cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) != VK_SUCCESS) + &pipeline_info, nullptr, &self->graphic_pipeline) + != VK_SUCCESS) throw CommandError{"Failed to create graphics pipeline."}; } @@ -476,10 +368,6 @@ unload_pipeline(void *obj) } const CommandChain loader{ - {&load_descriptor_set_layout_projection, - &unload_descriptor_set_layout_projection}, - {&load_descriptor_set_layout_sprite, &unload_descriptor_set_layout_sprite}, - {&load_pipeline_layout, &unload_pipeline_layout}, {&load_projection_uniform_buffer, &unload_projection_uniform_buffer}, {&load_descriptor_pool, &unload_descriptor_pool}, // By destroying the pool the sets are also destroyed. @@ -515,7 +403,8 @@ GraphicsPipeline2D::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_render_pass_2d; + render_pass_begin.renderPass = + cg_core.vk_graphics_pipeline_2d_layout->render_pass; render_pass_begin.framebuffer = this->swapchain_framebuffers[image_index]; render_pass_begin.renderArea.offset = {0, 0}; render_pass_begin.renderArea.extent = { @@ -552,8 +441,8 @@ GraphicsPipeline2D::draw( vkCmdBindDescriptorSets( draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->pipeline_layout, 0, vk_descriptor_sets.size(), - vk_descriptor_sets.data(), 0, nullptr); + cg_core.vk_graphics_pipeline_2d_layout->pipeline, 0, + vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); vkCmdBindPipeline( draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, this->graphic_pipeline); diff --git a/src/vk/graphics_pipeline_2d.hpp b/src/vk/graphics_pipeline_2d.hpp index dc122be..193c06d 100644 --- a/src/vk/graphics_pipeline_2d.hpp +++ b/src/vk/graphics_pipeline_2d.hpp @@ -27,10 +27,6 @@ namespace VK struct GraphicsPipeline2D { - VkDescriptorSetLayout descriptor_set_layout_projection; - VkDescriptorSetLayout descriptor_set_layout_sprite; - VkPipelineLayout pipeline_layout; - // FIXME: if this vector get resized, it will cause a segmentation fault! std::vector ub_projection; diff --git a/src/vk/graphics_pipeline_2d_layout.cpp b/src/vk/graphics_pipeline_2d_layout.cpp new file mode 100644 index 0000000..f8822b9 --- /dev/null +++ b/src/vk/graphics_pipeline_2d_layout.cpp @@ -0,0 +1,232 @@ +/* + * Copyright 2022 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 "graphics_pipeline_2d_layout.hpp" + +#include + +#include "../core.hpp" + +namespace +{ + +void +load_descriptor_set_layout_projection(void *obj) +{ + auto self = static_cast(obj); + + std::array layout_bindings{}; + + layout_bindings[0].binding = 0; + layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + layout_bindings[0].descriptorCount = 1; + layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + layout_bindings[0].pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo layout_info{}; + layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layout_info.pNext = nullptr; + layout_info.flags = 0; + layout_info.bindingCount = static_cast(layout_bindings.size()); + layout_info.pBindings = layout_bindings.data(); + + if(vkCreateDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, + &self->descriptor_set_projection) != VK_SUCCESS) + throw CommandError{ + "Failed to create Vulkan descriptor set layout for projection."}; +} + +void +unload_descriptor_set_layout_projection(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, self->descriptor_set_projection, + nullptr); +} + +void +load_descriptor_set_layout_sprite(void *obj) +{ + auto self = static_cast(obj); + + std::array layout_bindings{}; + + layout_bindings[0].binding = 0; + layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + layout_bindings[0].descriptorCount = 1; + layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + layout_bindings[0].pImmutableSamplers = nullptr; + + layout_bindings[1].binding = 1; + layout_bindings[1].descriptorType = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + layout_bindings[1].descriptorCount = 1; + layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + layout_bindings[1].pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo layout_info{}; + layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layout_info.pNext = nullptr; + layout_info.flags = 0; + layout_info.bindingCount = static_cast(layout_bindings.size()); + layout_info.pBindings = layout_bindings.data(); + + if(vkCreateDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, + &self->descriptor_set_sprite) != VK_SUCCESS) + throw CommandError{ + "Failed to create Vulkan descriptor set layout for sprites."}; +} + +void +unload_descriptor_set_layout_sprite(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, + self->descriptor_set_sprite, nullptr); +} + +void +load_pipeline_layout(void *obj) +{ + auto self = static_cast(obj); + + std::array set_layouts{ + self->descriptor_set_projection, self->descriptor_set_sprite + }; + + VkPipelineLayoutCreateInfo pipeline_layout_info{}; + pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_info.setLayoutCount = set_layouts.size(); + pipeline_layout_info.pSetLayouts = set_layouts.data(); + pipeline_layout_info.pushConstantRangeCount = 0; + pipeline_layout_info.pPushConstantRanges = nullptr; + + if(vkCreatePipelineLayout( + cg_core.vk_device_with_swapchain->device, &pipeline_layout_info, + nullptr, &self->pipeline) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan pipeline layout."}; +} + +void +unload_pipeline_layout(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyPipelineLayout( + 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_descriptor_set_layout_projection, + &unload_descriptor_set_layout_projection}, + {&load_descriptor_set_layout_sprite, &unload_descriptor_set_layout_sprite}, + {&load_pipeline_layout, &unload_pipeline_layout}, + {&load_render_pass, &unload_render_pass} +}; + +} + +namespace VK +{ + +GraphicsPipeline2DLayout::GraphicsPipeline2DLayout() +{ + loader.execute(this); +} + +GraphicsPipeline2DLayout::~GraphicsPipeline2DLayout() +{ + loader.revert(this); +} + +} diff --git a/src/vk/graphics_pipeline_2d_layout.hpp b/src/vk/graphics_pipeline_2d_layout.hpp new file mode 100644 index 0000000..520bbc1 --- /dev/null +++ b/src/vk/graphics_pipeline_2d_layout.hpp @@ -0,0 +1,38 @@ +/* + * Copyright 2022 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_GRAPHICS_PIPELINE_2D_LAYOUT_H +#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_LAYOUT_H 1 + +#include "core.hpp" + +namespace VK +{ + +struct GraphicsPipeline2DLayout +{ + VkDescriptorSetLayout descriptor_set_projection; + VkDescriptorSetLayout descriptor_set_sprite; + VkPipelineLayout pipeline; + VkRenderPass render_pass; + + GraphicsPipeline2DLayout(); + ~GraphicsPipeline2DLayout(); +}; + +} + +#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_2D_LAYOUT_H */ diff --git a/src/vk/graphics_pipeline_3d.cpp b/src/vk/graphics_pipeline_3d.cpp index de5adde..31e9365 100644 --- a/src/vk/graphics_pipeline_3d.cpp +++ b/src/vk/graphics_pipeline_3d.cpp @@ -27,123 +27,6 @@ namespace { -void -load_descriptor_set_layout_model_instance(void *obj) -{ - auto self = static_cast(obj); - - std::array layout_bindings{}; - - layout_bindings[0].binding = 0; - layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layout_bindings[0].descriptorCount = 1; - layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - layout_bindings[0].pImmutableSamplers = nullptr; - - layout_bindings[1].binding = 1; - layout_bindings[1].descriptorType = - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - layout_bindings[1].descriptorCount = 1; - layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - layout_bindings[1].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = static_cast(layout_bindings.size()); - layout_info.pBindings = layout_bindings.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->descriptor_set_layout_model_instance) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for model instance."}; -} - -void -unload_descriptor_set_layout_model_instance(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, - self->descriptor_set_layout_model_instance, nullptr); -} - -void -load_descriptor_set_layout_world_view(void *obj) -{ - auto self = static_cast(obj); - - std::array set_layouts{}; - set_layouts[0].binding = 0; - set_layouts[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - set_layouts[0].descriptorCount = 1; - set_layouts[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - set_layouts[0].pImmutableSamplers = nullptr; - - set_layouts[1].binding = 1; - set_layouts[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - set_layouts[1].descriptorCount = 1; - set_layouts[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - set_layouts[1].pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo layout_info{}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = nullptr; - layout_info.flags = 0; - layout_info.bindingCount = set_layouts.size(); - layout_info.pBindings = set_layouts.data(); - - if(vkCreateDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, - &self->descriptor_set_layout_world_view) != VK_SUCCESS) - throw CommandError{ - "Failed to create Vulkan descriptor set layout for world view."}; -} - -void -unload_descriptor_set_layout_world_view(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyDescriptorSetLayout( - cg_core.vk_device_with_swapchain->device, - self->descriptor_set_layout_world_view, nullptr); -} - -void -load_pipeline_layout(void *obj) -{ - auto self = static_cast(obj); - - std::array set_layouts{ - self->descriptor_set_layout_world_view, - self->descriptor_set_layout_model_instance}; - - VkPipelineLayoutCreateInfo pipeline_layout_info{}; - pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = set_layouts.size(); - pipeline_layout_info.pSetLayouts = set_layouts.data(); - pipeline_layout_info.pushConstantRangeCount = 0; - pipeline_layout_info.pPushConstantRanges = nullptr; - - if(vkCreatePipelineLayout( - cg_core.vk_device_with_swapchain->device, - &pipeline_layout_info, nullptr, &self->pipeline_layout) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan pipeline layout."}; -} - -void -unload_pipeline_layout(void *obj) -{ - auto self = static_cast(obj); - - vkDestroyPipelineLayout( - cg_core.vk_device_with_swapchain->device, self->pipeline_layout, nullptr); -} - void load_view_projection_uniform_buffer(void *obj) { @@ -210,14 +93,14 @@ load_descriptor_pool(void *obj) pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.pNext = nullptr; pool_info.flags = 0; - pool_info.maxSets = - self->ub_view_projection.size() + self->ub_directional_light.size(); + pool_info.maxSets = self->ub_view_projection.size() + + self->ub_directional_light.size(); pool_info.poolSizeCount = 1; pool_info.pPoolSizes = &descriptor_pool_size; if(vkCreateDescriptorPool( - cg_core.vk_device_with_swapchain->device, - &pool_info, nullptr, &self->descriptor_pool) != VK_SUCCESS) + cg_core.vk_device_with_swapchain->device, &pool_info, nullptr, + &self->descriptor_pool) != VK_SUCCESS) throw CommandError{"Failed to create a Vulkan descriptor pool."}; } @@ -227,7 +110,8 @@ unload_descriptor_pool(void *obj) auto self = static_cast(obj); vkDestroyDescriptorPool( - cg_core.vk_device_with_swapchain->device, self->descriptor_pool, nullptr); + cg_core.vk_device_with_swapchain->device, self->descriptor_pool, + nullptr); } void @@ -237,7 +121,7 @@ load_world_view_descriptor_sets(void *obj) std::vector layouts( cg_core.vk_swapchain->images_count, - self->descriptor_set_layout_world_view); + cg_core.vk_graphics_pipeline_3d_layout->descriptor_set_world_view); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; @@ -334,10 +218,11 @@ unload_depth_image(void *obj) auto self = static_cast(obj); vkDestroyImage( - cg_core.vk_device_with_swapchain->device, self->depth_image, nullptr); - vkFreeMemory( - cg_core.vk_device_with_swapchain->device, self->depth_image_memory, + cg_core.vk_device_with_swapchain->device, self->depth_image, nullptr); + vkFreeMemory( + cg_core.vk_device_with_swapchain->device, + self->depth_image_memory, nullptr); } void @@ -384,7 +269,8 @@ load_framebuffer(void *obj) VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = cg_core.vk_render_pass_3d; + framebuffer_info.renderPass = + cg_core.vk_graphics_pipeline_3d_layout->render_pass; framebuffer_info.attachmentCount = attachments.size(); framebuffer_info.pAttachments = attachments.data(); framebuffer_info.width = cg_core.screen_width; @@ -595,15 +481,17 @@ load_pipeline(void *obj) pipeline_info.pDepthStencilState = &depth_stencil; pipeline_info.pColorBlendState = &color_blending; pipeline_info.pDynamicState = &dynamic_state_info; - pipeline_info.layout = self->pipeline_layout; - pipeline_info.renderPass = cg_core.vk_render_pass_3d; + 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.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; if(vkCreateGraphicsPipelines( cg_core.vk_device_with_swapchain->device, VK_NULL_HANDLE, 1, - &pipeline_info, nullptr, &self->graphic_pipeline) != VK_SUCCESS) + &pipeline_info, nullptr, &self->graphic_pipeline) + != VK_SUCCESS) throw CommandError{"Failed to create graphics pipeline."}; } @@ -617,11 +505,6 @@ unload_pipeline(void *obj) } const CommandChain loader{ - {&load_descriptor_set_layout_model_instance, - &unload_descriptor_set_layout_model_instance}, - {&load_descriptor_set_layout_world_view, - &unload_descriptor_set_layout_world_view}, - {&load_pipeline_layout, &unload_pipeline_layout}, {&load_view_projection_uniform_buffer, &unload_view_projection_uniform_buffer}, {&load_directional_light_uniform_buffer, @@ -669,7 +552,8 @@ GraphicsPipeline3D::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_render_pass_3d; + render_pass_begin.renderPass = + cg_core.vk_graphics_pipeline_3d_layout->render_pass; render_pass_begin.framebuffer = this->swapchain_framebuffers[image_index]; render_pass_begin.renderArea.offset = {0, 0}; render_pass_begin.renderArea.extent = { @@ -707,8 +591,8 @@ GraphicsPipeline3D::draw( vkCmdBindDescriptorSets( draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->pipeline_layout, 0, vk_descriptor_sets.size(), - vk_descriptor_sets.data(), 0, nullptr); + cg_core.vk_graphics_pipeline_3d_layout->pipeline, 0, + vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); vkCmdBindPipeline( draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, this->graphic_pipeline); diff --git a/src/vk/graphics_pipeline_3d.hpp b/src/vk/graphics_pipeline_3d.hpp index d14479f..97ca63c 100644 --- a/src/vk/graphics_pipeline_3d.hpp +++ b/src/vk/graphics_pipeline_3d.hpp @@ -32,10 +32,6 @@ namespace VK struct GraphicsPipeline3D { - VkDescriptorSetLayout descriptor_set_layout_model_instance; - VkDescriptorSetLayout descriptor_set_layout_world_view; - VkPipelineLayout pipeline_layout; - // Depth image. VkImage depth_image; VkDeviceMemory depth_image_memory; diff --git a/src/vk/graphics_pipeline_3d_layout.cpp b/src/vk/graphics_pipeline_3d_layout.cpp new file mode 100644 index 0000000..62c894c --- /dev/null +++ b/src/vk/graphics_pipeline_3d_layout.cpp @@ -0,0 +1,252 @@ +/* + * Copyright 2022 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 "graphics_pipeline_3d_layout.hpp" + +#include + +#include "../core.hpp" + +namespace +{ +void +load_descriptor_set_layout_world_view(void *obj) +{ + auto self = static_cast(obj); + + std::array set_layouts{}; + set_layouts[0].binding = 0; + set_layouts[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + set_layouts[0].descriptorCount = 1; + set_layouts[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + set_layouts[0].pImmutableSamplers = nullptr; + + set_layouts[1].binding = 1; + set_layouts[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + set_layouts[1].descriptorCount = 1; + set_layouts[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + set_layouts[1].pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo layout_info{}; + layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layout_info.pNext = nullptr; + layout_info.flags = 0; + layout_info.bindingCount = set_layouts.size(); + layout_info.pBindings = set_layouts.data(); + + if(vkCreateDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, + &self->descriptor_set_world_view) != VK_SUCCESS) + throw CommandError{ + "Failed to create Vulkan descriptor set layout for world view."}; +} + +void +unload_descriptor_set_layout_world_view(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, + self->descriptor_set_world_view, nullptr); +} + +void +load_descriptor_set_layout_model_instance(void *obj) +{ + auto self = static_cast(obj); + + std::array layout_bindings{}; + + layout_bindings[0].binding = 0; + layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + layout_bindings[0].descriptorCount = 1; + layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + layout_bindings[0].pImmutableSamplers = nullptr; + + layout_bindings[1].binding = 1; + layout_bindings[1].descriptorType = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + layout_bindings[1].descriptorCount = 1; + layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + layout_bindings[1].pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo layout_info{}; + layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layout_info.pNext = nullptr; + layout_info.flags = 0; + layout_info.bindingCount = static_cast(layout_bindings.size()); + layout_info.pBindings = layout_bindings.data(); + + if(vkCreateDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, &layout_info, nullptr, + &self->descriptor_set_model_instance) != VK_SUCCESS) + throw CommandError{ + "Failed to create Vulkan descriptor set layout for model instance."}; +} + +void +unload_descriptor_set_layout_model_instance(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyDescriptorSetLayout( + cg_core.vk_device_with_swapchain->device, + self->descriptor_set_model_instance, nullptr); +} + +void +load_pipeline_layout(void *obj) +{ + auto self = static_cast(obj); + + std::array set_layouts{ + self->descriptor_set_world_view, + self->descriptor_set_model_instance}; + + VkPipelineLayoutCreateInfo pipeline_layout_info{}; + pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_info.setLayoutCount = set_layouts.size(); + pipeline_layout_info.pSetLayouts = set_layouts.data(); + pipeline_layout_info.pushConstantRangeCount = 0; + pipeline_layout_info.pPushConstantRanges = nullptr; + + if(vkCreatePipelineLayout( + cg_core.vk_device_with_swapchain->device, + &pipeline_layout_info, nullptr, &self->pipeline) != VK_SUCCESS) + throw CommandError{"Failed to create Vulkan pipeline layout."}; +} + +void +unload_pipeline_layout(void *obj) +{ + auto self = static_cast(obj); + + vkDestroyPipelineLayout( + 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_descriptor_set_layout_world_view, + &unload_descriptor_set_layout_world_view}, + {&load_descriptor_set_layout_model_instance, + &unload_descriptor_set_layout_model_instance}, + {&load_pipeline_layout, &unload_pipeline_layout}, + {&load_render_pass, &unload_render_pass} +}; + +} + +namespace VK +{ + +GraphicsPipeline3DLayout::GraphicsPipeline3DLayout() +{ + loader.execute(this); +} + +GraphicsPipeline3DLayout::~GraphicsPipeline3DLayout() +{ + loader.revert(this); +} + +} diff --git a/src/vk/graphics_pipeline_3d_layout.hpp b/src/vk/graphics_pipeline_3d_layout.hpp new file mode 100644 index 0000000..296bdb2 --- /dev/null +++ b/src/vk/graphics_pipeline_3d_layout.hpp @@ -0,0 +1,38 @@ +/* + * Copyright 2022 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_GRAPHICS_PIPELINE_3D_LAYOUT_H +#define CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_LAYOUT_H 1 + +#include "core.hpp" + +namespace VK +{ + +struct GraphicsPipeline3DLayout +{ + VkDescriptorSetLayout descriptor_set_world_view; + VkDescriptorSetLayout descriptor_set_model_instance; + VkPipelineLayout pipeline; + VkRenderPass render_pass; + + GraphicsPipeline3DLayout(); + ~GraphicsPipeline3DLayout(); +}; + +} + +#endif /* CANDY_GEAR_VK_GRAPHICS_PIPELINE_3D_LAYOUT_H */ diff --git a/src/vk/model.cpp b/src/vk/model.cpp index 240ad13..b92ec91 100644 --- a/src/vk/model.cpp +++ b/src/vk/model.cpp @@ -195,7 +195,7 @@ load_descriptor_sets(void *obj) std::vector layouts( cg_core.vk_swapchain->images_count, - cg_core.vk_graphics_pipeline_3d->descriptor_set_layout_model_instance); + cg_core.vk_graphics_pipeline_3d_layout->descriptor_set_model_instance); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; diff --git a/src/vk/sprite.cpp b/src/vk/sprite.cpp index a7b65d7..9a718d7 100644 --- a/src/vk/sprite.cpp +++ b/src/vk/sprite.cpp @@ -137,7 +137,7 @@ load_descriptor_sets(void *obj) std::vector layouts( cg_core.vk_swapchain->images_count, - cg_core.vk_graphics_pipeline_2d->descriptor_set_layout_sprite); + cg_core.vk_graphics_pipeline_2d_layout->descriptor_set_sprite); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; -- cgit v1.2.3