From 5f3c5d4fc1a14374090cfe4a268ace1d15581770 Mon Sep 17 00:00:00 2001 From: Jiga228 Date: Thu, 25 Jun 2026 20:08:11 +0700 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=BD=D0=B5=D1=81=20=D1=83=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20VkDescriptor?= =?UTF-8?q?SetLayout=20=D0=B8=20VkPipeline=20=D0=B2=20=D0=BE=D1=82=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RenderEngine/UwURenderEngine.cpp | 193 +----------------- .../RenderEngine/UwURenderEngine.hpp | 12 +- .../VkObjects/DescriptorSetLayout.cpp | 30 +++ .../VkObjects/DescriptorSetLayout.hpp | 19 ++ .../RenderEngine/VkObjects/Device.cpp | 2 + .../RenderEngine/VkObjects/Instance.cpp | 2 + .../RenderEngine/VkObjects/Pipeline.cpp | 177 ++++++++++++++++ .../RenderEngine/VkObjects/Pipeline.hpp | 28 +++ .../RenderEngine/VkObjects/RenderPass.cpp | 5 +- .../RenderEngine/VkObjects/Surface.cpp | 3 + .../RenderEngine/VkObjects/Swapchain.cpp | 2 + 11 files changed, 277 insertions(+), 196 deletions(-) create mode 100644 UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.cpp create mode 100644 UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.hpp create mode 100644 UwURenderEngine/RenderEngine/VkObjects/Pipeline.cpp create mode 100644 UwURenderEngine/RenderEngine/VkObjects/Pipeline.hpp diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp index bf0e98f..0b2ae6b 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp @@ -18,36 +18,6 @@ RENDER_ENGINE_FACTORY_GENERATE(UwURenderEngine) -VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) const -{ - VkShaderModuleCreateInfo shader_module_info{}; - shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shader_module_info.codeSize = code.size(); - shader_module_info.pCode = reinterpret_cast(code.c_str()); - - VkShaderModule shader_module; - VK_CHECK(vkCreateShaderModule(device_.get_native(), &shader_module_info, nullptr, &shader_module)) - return shader_module; -} - - -void UwURenderEngine::create_description_set_layout() -{ - VkDescriptorSetLayoutBinding ubo_layout_binding; - ubo_layout_binding.binding = 0; - ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - ubo_layout_binding.descriptorCount = 1; - ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - ubo_layout_binding.pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo ubo_layout_info{}; - ubo_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - ubo_layout_info.bindingCount = 1; - ubo_layout_info.pBindings = &ubo_layout_binding; - - VK_CHECK(vkCreateDescriptorSetLayout(device_.get_native(), &ubo_layout_info, nullptr, &ubo_layout_binding_)) -} - void UwURenderEngine::create_uniform_buffers() { uniform_buffers_.resize(swapchain_.get_images().size()); @@ -83,7 +53,7 @@ void UwURenderEngine::create_descriptor_pool() void UwURenderEngine::create_descriptor_sets() { - std::vector layouts(swapchain_.get_images().size(), ubo_layout_binding_); + std::vector layouts(swapchain_.get_images().size(), layout_binding_.get_native()); VkDescriptorSetAllocateInfo descriptor_set_allocate_info{}; descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; descriptor_set_allocate_info.descriptorPool = descriptor_pool_; @@ -115,148 +85,6 @@ void UwURenderEngine::create_descriptor_sets() } } -void UwURenderEngine::create_graphics_pipeline() -{ - std::ifstream vertex_shader_file("Shaders/vertex.spv", std::ios::binary); - if (!vertex_shader_file.is_open()) - throw std::runtime_error("Vertex shader not found"); - std::ifstream fragment_shader_file("Shaders/fragment.spv", std::ios::binary); - if (!fragment_shader_file.is_open()) { - vertex_shader_file.close(); - throw std::runtime_error("Fragment shader not found"); - } - - std::string vertex_shader_code((std::istreambuf_iterator(vertex_shader_file)), std::istreambuf_iterator()); - std::string fragment_shader_code((std::istreambuf_iterator(fragment_shader_file)), std::istreambuf_iterator()); - vertex_shader_file.close(); - fragment_shader_file.close(); - - VkShaderModule vertex_shader = create_shader_module(vertex_shader_code); - VkShaderModule fragment_shader = create_shader_module(fragment_shader_code); - - VkPipelineShaderStageCreateInfo vertex_shader_stage_info{}; - vertex_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vertex_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; - vertex_shader_stage_info.module = vertex_shader; - vertex_shader_stage_info.pName = "main"; - - VkPipelineShaderStageCreateInfo fragment_shader_stage_info{}; - fragment_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - fragment_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - fragment_shader_stage_info.module = fragment_shader; - fragment_shader_stage_info.pName = "main"; - - VkPipelineShaderStageCreateInfo shader_stages[] = {vertex_shader_stage_info, fragment_shader_stage_info}; - const std::vector dynamic_states = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR - }; - - VkPipelineDynamicStateCreateInfo dynamic_state_info{}; - dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = static_cast(dynamic_states.size()); - dynamic_state_info.pDynamicStates = dynamic_states.data(); - - VkVertexInputBindingDescription binding_description = ModelManager::Vertex::get_binding_description(); - std::array attribute_descriptions = ModelManager::Vertex::get_vertex_attribute_descriptions(); - - VkPipelineVertexInputStateCreateInfo vertex_input_info{}; - vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.vertexBindingDescriptionCount = 1; - vertex_input_info.pVertexBindingDescriptions = &binding_description; - vertex_input_info.vertexAttributeDescriptionCount = static_cast(attribute_descriptions.size()); - vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data(); - - VkPipelineInputAssemblyStateCreateInfo input_assembly_info{}; - input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - input_assembly_info.primitiveRestartEnable = VK_FALSE; - - VkViewport viewport{}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = static_cast(swapchain_.get_extent().width); - viewport.height = static_cast(swapchain_.get_extent().height); - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - VkRect2D scissor{}; - scissor.offset = {0, 0}; - scissor.extent = swapchain_.get_extent(); - - VkPipelineViewportStateCreateInfo viewport_info{}; - viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_info.viewportCount = 1; - viewport_info.pViewports = &viewport; - viewport_info.scissorCount = 1; - viewport_info.pScissors = &scissor; - - VkPipelineRasterizationStateCreateInfo rasterization_info{}; - rasterization_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterization_info.depthClampEnable = VK_FALSE; - rasterization_info.rasterizerDiscardEnable = VK_FALSE; - rasterization_info.polygonMode = VK_POLYGON_MODE_FILL; - rasterization_info.lineWidth = 1.0f; - rasterization_info.cullMode = VK_CULL_MODE_BACK_BIT; - rasterization_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rasterization_info.depthBiasEnable = VK_FALSE; - - VkPipelineMultisampleStateCreateInfo multisample_info{}; - multisample_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisample_info.sampleShadingEnable = VK_FALSE; - multisample_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - - VkPipelineColorBlendAttachmentState color_blend_attachment_state{}; - color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - color_blend_attachment_state.blendEnable = VK_TRUE; - color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD; - color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD; - - VkPipelineColorBlendStateCreateInfo color_blend_info{}; - color_blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blend_info.logicOpEnable = VK_FALSE; - color_blend_info.attachmentCount = 1; - color_blend_info.pAttachments = &color_blend_attachment_state; - color_blend_info.blendConstants[0] = 0.0f; - color_blend_info.blendConstants[1] = 0.0f; - color_blend_info.blendConstants[2] = 0.0f; - color_blend_info.blendConstants[3] = 0.0f; - - VkPipelineLayoutCreateInfo pipeline_layout_info{}; - pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = 1; - pipeline_layout_info.pSetLayouts = &ubo_layout_binding_; - - VK_CHECK(vkCreatePipelineLayout(device_.get_native(), &pipeline_layout_info, nullptr, &pipeline_layout_)) - - VkGraphicsPipelineCreateInfo graphics_pipeline_info{}; - graphics_pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - graphics_pipeline_info.stageCount = 2; - graphics_pipeline_info.pStages = shader_stages; - graphics_pipeline_info.layout = pipeline_layout_; - graphics_pipeline_info.pColorBlendState = &color_blend_info; - graphics_pipeline_info.pDynamicState = &dynamic_state_info; - graphics_pipeline_info.pInputAssemblyState = &input_assembly_info; - graphics_pipeline_info.pMultisampleState = &multisample_info; - graphics_pipeline_info.pRasterizationState = &rasterization_info; - graphics_pipeline_info.pViewportState = &viewport_info; - graphics_pipeline_info.pVertexInputState = &vertex_input_info; - graphics_pipeline_info.pDepthStencilState = nullptr; - graphics_pipeline_info.renderPass = render_pass_.get_native(); - graphics_pipeline_info.subpass = 0; - graphics_pipeline_info.basePipelineHandle = nullptr; - graphics_pipeline_info.basePipelineIndex = -1; - - VK_CHECK(vkCreateGraphicsPipelines(device_.get_native(), nullptr, 1, &graphics_pipeline_info, nullptr, &graphics_pipeline_)) - - vkDestroyShaderModule(device_.get_native(), vertex_shader, nullptr); - vkDestroyShaderModule(device_.get_native(), fragment_shader, nullptr); -} - void UwURenderEngine::create_framebuffers() { framebuffers_.resize(swapchain_.get_images().size()); @@ -400,13 +228,13 @@ void UwURenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint render_pass_begin_info.pClearValues = &clear_color; vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_); + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_.get_native()); VkBuffer vertex_buffers[] = {vertex_buffer_}; VkDeviceSize offset[] = {0}; vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offset); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout_, 0, 1, &descriptor_sets_[current_frame_], 0, nullptr); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_.get_layout(), 0, 1, &descriptor_sets_[current_frame_], 0, nullptr); vkCmdBindIndexBuffer(command_buffer, index_buffer_, 0, VK_INDEX_TYPE_UINT16); @@ -511,13 +339,13 @@ surface_(instance_, get_window()), physical_device_(instance_, surface_, deviceExtensions), device_(physical_device_, deviceExtensions), swapchain_(surface_, physical_device_, device_, get_window()), -render_pass_(device_, swapchain_) +render_pass_(device_, swapchain_), +layout_binding_(device_), +pipeline_(device_, swapchain_, render_pass_, layout_binding_) { - create_description_set_layout(); create_uniform_buffers(); create_descriptor_pool(); create_descriptor_sets(); - create_graphics_pipeline(); create_framebuffers(); create_command_pool(); allocate_vertex_buffer(); @@ -563,12 +391,6 @@ UwURenderEngine::~UwURenderEngine() for (auto& i : framebuffers_) vkDestroyFramebuffer(device_.get_native(), i, nullptr); - if (graphics_pipeline_ != VK_NULL_HANDLE) - vkDestroyPipeline(device_.get_native(), graphics_pipeline_, nullptr); - - if (pipeline_layout_ != VK_NULL_HANDLE) - vkDestroyPipelineLayout(device_.get_native(), pipeline_layout_, nullptr); - for (size_t i = 0; i < uniform_buffers_.size(); ++i) { vkUnmapMemory(device_.get_native(), uniform_buffers_memory_[i]); @@ -580,9 +402,6 @@ UwURenderEngine::~UwURenderEngine() uniform_buffers_mapped_.clear(); vkDestroyDescriptorPool(device_.get_native(), descriptor_pool_, nullptr); - - if (ubo_layout_binding_ != VK_NULL_HANDLE) - vkDestroyDescriptorSetLayout(device_.get_native(), ubo_layout_binding_, nullptr); } void UwURenderEngine::start() diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp index 5cb9401..daa75c9 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp @@ -11,9 +11,11 @@ #include #include +#include "VkObjects/DescriptorSetLayout.hpp" #include "VkObjects/Device.hpp" #include "VkObjects/Instance.hpp" #include "VkObjects/PhysicalDevice.hpp" +#include "VkObjects/Pipeline.hpp" #include "VkObjects/RenderPass.hpp" #include "VkObjects/Surface.hpp" #include "VkObjects/Swapchain.hpp" @@ -69,11 +71,10 @@ class UwURenderEngine final : public RenderEngineBase VkObjects::Device device_; VkObjects::Swapchain swapchain_; VkObjects::RenderPass render_pass_; - VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE; + VkObjects::DescriptorSetLayout layout_binding_; VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE; std::vector descriptor_sets_; - VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; - VkPipeline graphics_pipeline_ = VK_NULL_HANDLE; + VkObjects::Pipeline pipeline_; std::vector framebuffers_; VkCommandPool command_pool_ = VK_NULL_HANDLE; std::vector command_buffers_; @@ -89,14 +90,9 @@ class UwURenderEngine final : public RenderEngineBase std::vector image_available_semaphores_, render_finished_semaphores_; std::vector in_flight_fences_; - - VkShaderModule create_shader_module(const std::string& code) const; - - void create_description_set_layout(); void create_uniform_buffers(); void create_descriptor_pool(); void create_descriptor_sets(); - void create_graphics_pipeline(); void create_framebuffers(); void create_command_pool(); void allocate_command_buffers(); diff --git a/UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.cpp b/UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.cpp new file mode 100644 index 0000000..3d85ecc --- /dev/null +++ b/UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.cpp @@ -0,0 +1,30 @@ +#include "DescriptorSetLayout.hpp" + +#include +#include + +#include "Device.hpp" +#include "DeviceFunctions/DeviceFunctions.hpp" + +VkObjects::DescriptorSetLayout::DescriptorSetLayout(const Device& device):device_(device) +{ + VkDescriptorSetLayoutBinding ubo_layout_binding; + ubo_layout_binding.binding = 0; + ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + ubo_layout_binding.descriptorCount = 1; + ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + ubo_layout_binding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo ubo_layout_info{}; + ubo_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + ubo_layout_info.bindingCount = 1; + ubo_layout_info.pBindings = &ubo_layout_binding; + + VK_CHECK(vkCreateDescriptorSetLayout(device_.get_native(), &ubo_layout_info, nullptr, &layout_binding_)) +} + +VkObjects::DescriptorSetLayout::~DescriptorSetLayout() +{ + if (layout_binding_ != nullptr) + vkDestroyDescriptorSetLayout(device_.get_native(), layout_binding_, nullptr); +} diff --git a/UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.hpp b/UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.hpp new file mode 100644 index 0000000..8ef5382 --- /dev/null +++ b/UwURenderEngine/RenderEngine/VkObjects/DescriptorSetLayout.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace VkObjects +{ + class Device; + + class DescriptorSetLayout + { + VkDescriptorSetLayout layout_binding_ = nullptr; + const Device& device_; + public: + DescriptorSetLayout(const Device& device); + ~DescriptorSetLayout(); + + inline VkDescriptorSetLayout get_native() const { return layout_binding_; } + }; +} \ No newline at end of file diff --git a/UwURenderEngine/RenderEngine/VkObjects/Device.cpp b/UwURenderEngine/RenderEngine/VkObjects/Device.cpp index a518dec..a9bfbcb 100644 --- a/UwURenderEngine/RenderEngine/VkObjects/Device.cpp +++ b/UwURenderEngine/RenderEngine/VkObjects/Device.cpp @@ -3,6 +3,8 @@ #include "PhysicalDevice.hpp" #include +#include +#include #include "DeviceFunctions/DeviceFunctions.hpp" diff --git a/UwURenderEngine/RenderEngine/VkObjects/Instance.cpp b/UwURenderEngine/RenderEngine/VkObjects/Instance.cpp index a6dacd7..11c0978 100644 --- a/UwURenderEngine/RenderEngine/VkObjects/Instance.cpp +++ b/UwURenderEngine/RenderEngine/VkObjects/Instance.cpp @@ -1,5 +1,7 @@ #include "Instance.hpp" +#include + #include "Core/CoreInstance.hpp" #include "DeviceFunctions/DeviceFunctions.hpp" #include "Log/Log.hpp" diff --git a/UwURenderEngine/RenderEngine/VkObjects/Pipeline.cpp b/UwURenderEngine/RenderEngine/VkObjects/Pipeline.cpp new file mode 100644 index 0000000..e34267e --- /dev/null +++ b/UwURenderEngine/RenderEngine/VkObjects/Pipeline.cpp @@ -0,0 +1,177 @@ +#include "Pipeline.hpp" + +#include +#include +#include + +#include "DescriptorSetLayout.hpp" +#include "Device.hpp" +#include "RenderPass.hpp" +#include "Swapchain.hpp" +#include "DeviceFunctions/DeviceFunctions.hpp" +#include "../ModelManager.hpp" + +VkShaderModule VkObjects::Pipeline::create_shader_module(const Device& device, const std::string& code) const +{ + VkShaderModuleCreateInfo shader_module_info{}; + shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_module_info.codeSize = code.size(); + shader_module_info.pCode = reinterpret_cast(code.c_str()); + + VkShaderModule shader_module; + VK_CHECK(vkCreateShaderModule(device.get_native(), &shader_module_info, nullptr, &shader_module)) + return shader_module; +} + +VkObjects::Pipeline::Pipeline(const Device& device, const Swapchain& swapchain, + const RenderPass& render_pass, const DescriptorSetLayout& layout_binding):device_(device) +{ + std::ifstream vertex_shader_file("Shaders/vertex.spv", std::ios::binary); + if (!vertex_shader_file.is_open()) + throw std::runtime_error("Vertex shader not found"); + std::ifstream fragment_shader_file("Shaders/fragment.spv", std::ios::binary); + if (!fragment_shader_file.is_open()) { + vertex_shader_file.close(); + throw std::runtime_error("Fragment shader not found"); + } + + std::string vertex_shader_code((std::istreambuf_iterator(vertex_shader_file)), std::istreambuf_iterator()); + std::string fragment_shader_code((std::istreambuf_iterator(fragment_shader_file)), std::istreambuf_iterator()); + vertex_shader_file.close(); + fragment_shader_file.close(); + + VkShaderModule vertex_shader = create_shader_module(device_, vertex_shader_code); + VkShaderModule fragment_shader = create_shader_module(device_, fragment_shader_code); + + VkPipelineShaderStageCreateInfo vertex_shader_stage_info{}; + vertex_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vertex_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; + vertex_shader_stage_info.module = vertex_shader; + vertex_shader_stage_info.pName = "main"; + + VkPipelineShaderStageCreateInfo fragment_shader_stage_info{}; + fragment_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + fragment_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fragment_shader_stage_info.module = fragment_shader; + fragment_shader_stage_info.pName = "main"; + + VkPipelineShaderStageCreateInfo shader_stages[] = {vertex_shader_stage_info, fragment_shader_stage_info}; + const std::vector dynamic_states = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR + }; + + VkPipelineDynamicStateCreateInfo dynamic_state_info{}; + dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state_info.dynamicStateCount = static_cast(dynamic_states.size()); + dynamic_state_info.pDynamicStates = dynamic_states.data(); + + VkVertexInputBindingDescription binding_description = ModelManager::Vertex::get_binding_description(); + std::array attribute_descriptions = ModelManager::Vertex::get_vertex_attribute_descriptions(); + + VkPipelineVertexInputStateCreateInfo vertex_input_info{}; + vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input_info.vertexBindingDescriptionCount = 1; + vertex_input_info.pVertexBindingDescriptions = &binding_description; + vertex_input_info.vertexAttributeDescriptionCount = static_cast(attribute_descriptions.size()); + vertex_input_info.pVertexAttributeDescriptions = attribute_descriptions.data(); + + VkPipelineInputAssemblyStateCreateInfo input_assembly_info{}; + input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + input_assembly_info.primitiveRestartEnable = VK_FALSE; + + VkViewport viewport{}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = static_cast(swapchain.get_extent().width); + viewport.height = static_cast(swapchain.get_extent().height); + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + VkRect2D scissor{}; + scissor.offset = {0, 0}; + scissor.extent = swapchain.get_extent(); + + VkPipelineViewportStateCreateInfo viewport_info{}; + viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_info.viewportCount = 1; + viewport_info.pViewports = &viewport; + viewport_info.scissorCount = 1; + viewport_info.pScissors = &scissor; + + VkPipelineRasterizationStateCreateInfo rasterization_info{}; + rasterization_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_info.depthClampEnable = VK_FALSE; + rasterization_info.rasterizerDiscardEnable = VK_FALSE; + rasterization_info.polygonMode = VK_POLYGON_MODE_FILL; + rasterization_info.lineWidth = 1.0f; + rasterization_info.cullMode = VK_CULL_MODE_BACK_BIT; + rasterization_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterization_info.depthBiasEnable = VK_FALSE; + + VkPipelineMultisampleStateCreateInfo multisample_info{}; + multisample_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisample_info.sampleShadingEnable = VK_FALSE; + multisample_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_blend_attachment_state{}; + color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + color_blend_attachment_state.blendEnable = VK_TRUE; + color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD; + color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD; + + VkPipelineColorBlendStateCreateInfo color_blend_info{}; + color_blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + color_blend_info.logicOpEnable = VK_FALSE; + color_blend_info.attachmentCount = 1; + color_blend_info.pAttachments = &color_blend_attachment_state; + color_blend_info.blendConstants[0] = 0.0f; + color_blend_info.blendConstants[1] = 0.0f; + color_blend_info.blendConstants[2] = 0.0f; + color_blend_info.blendConstants[3] = 0.0f; + + VkDescriptorSetLayout layout = layout_binding.get_native(); + VkPipelineLayoutCreateInfo pipeline_layout_info{}; + pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_info.setLayoutCount = 1; + pipeline_layout_info.pSetLayouts = &layout; + + VK_CHECK(vkCreatePipelineLayout(device_.get_native(), &pipeline_layout_info, nullptr, &pipeline_layout_)) + + VkGraphicsPipelineCreateInfo pipeline_info{}; + pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_info.stageCount = 2; + pipeline_info.pStages = shader_stages; + pipeline_info.layout = pipeline_layout_; + pipeline_info.pColorBlendState = &color_blend_info; + pipeline_info.pDynamicState = &dynamic_state_info; + pipeline_info.pInputAssemblyState = &input_assembly_info; + pipeline_info.pMultisampleState = &multisample_info; + pipeline_info.pRasterizationState = &rasterization_info; + pipeline_info.pViewportState = &viewport_info; + pipeline_info.pVertexInputState = &vertex_input_info; + pipeline_info.pDepthStencilState = nullptr; + pipeline_info.renderPass = render_pass.get_native(); + pipeline_info.subpass = 0; + pipeline_info.basePipelineHandle = nullptr; + pipeline_info.basePipelineIndex = -1; + + VK_CHECK(vkCreateGraphicsPipelines(device_.get_native(), nullptr, 1, &pipeline_info, nullptr, &pipeline_)) + + vkDestroyShaderModule(device_.get_native(), vertex_shader, nullptr); + vkDestroyShaderModule(device_.get_native(), fragment_shader, nullptr); +} + +VkObjects::Pipeline::~Pipeline() +{ + if (pipeline_ != nullptr) + vkDestroyPipeline(device_.get_native(), pipeline_, nullptr); + + if (pipeline_layout_ != nullptr) + vkDestroyPipelineLayout(device_.get_native(), pipeline_layout_, nullptr); +} diff --git a/UwURenderEngine/RenderEngine/VkObjects/Pipeline.hpp b/UwURenderEngine/RenderEngine/VkObjects/Pipeline.hpp new file mode 100644 index 0000000..e0cb7d9 --- /dev/null +++ b/UwURenderEngine/RenderEngine/VkObjects/Pipeline.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace VkObjects +{ + class DescriptorSetLayout; + class RenderPass; + class Swapchain; + class Device; + + class Pipeline + { + VkPipeline pipeline_ = nullptr; + VkPipelineLayout pipeline_layout_ = nullptr; + const Device& device_; + + VkShaderModule create_shader_module(const Device& device, const std::string& code) const; + public: + Pipeline(const Device& device, const Swapchain& swapchain, + const RenderPass& render_pass, const DescriptorSetLayout& layout_binding); + ~Pipeline(); + + inline VkPipeline get_native() const { return pipeline_; } + inline VkPipelineLayout get_layout() const { return pipeline_layout_; } + }; +} diff --git a/UwURenderEngine/RenderEngine/VkObjects/RenderPass.cpp b/UwURenderEngine/RenderEngine/VkObjects/RenderPass.cpp index e959005..1657d74 100644 --- a/UwURenderEngine/RenderEngine/VkObjects/RenderPass.cpp +++ b/UwURenderEngine/RenderEngine/VkObjects/RenderPass.cpp @@ -1,5 +1,8 @@ #include "RenderPass.hpp" +#include +#include + #include "DeviceFunctions/DeviceFunctions.hpp" #include "Swapchain.hpp" #include "Device.hpp" @@ -47,6 +50,6 @@ VkObjects::RenderPass::RenderPass(const Device& device, const Swapchain& swapcha VkObjects::RenderPass::~RenderPass() { - if (render_pass_ != VK_NULL_HANDLE) + if (render_pass_ != nullptr) vkDestroyRenderPass(device_.get_native(), render_pass_, nullptr); } diff --git a/UwURenderEngine/RenderEngine/VkObjects/Surface.cpp b/UwURenderEngine/RenderEngine/VkObjects/Surface.cpp index 650b8fa..36a5ce2 100644 --- a/UwURenderEngine/RenderEngine/VkObjects/Surface.cpp +++ b/UwURenderEngine/RenderEngine/VkObjects/Surface.cpp @@ -1,5 +1,8 @@ #include "Surface.hpp" +#include +#include + #include "Instance.hpp" #include "DeviceFunctions/DeviceFunctions.hpp" diff --git a/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp b/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp index 4f0ff33..70feabd 100644 --- a/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp +++ b/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp @@ -1,6 +1,8 @@ #include "Swapchain.hpp" #include +#include +#include #include "Device.hpp" #include "PhysicalDevice.hpp"