diff --git a/CMakeLists.txt b/CMakeLists.txt index 257a05e..c4a0b55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ find_package(Vulkan REQUIRED) include(cmake/Shaders.cmake) include(FetchContent) +set(FMT_HEADER_ONLY ON) + FetchContent_Declare( glm GIT_REPOSITORY "https://github.com/g-truc/glm.git" diff --git a/include/vulkan/graphics.h b/include/vulkan/graphics.h index c2bb8a1..c2a8f67 100644 --- a/include/vulkan/graphics.h +++ b/include/vulkan/graphics.h @@ -21,7 +21,7 @@ class Graphics final { }; struct SwapChainProperties { - VkSurfaceCapabilitiesKHR capabilities; + VkSurfaceCapabilitiesKHR capabilities = {}; std::vector formats; std::vector present_modes; @@ -36,6 +36,7 @@ class Graphics final { void CreateSurface(); void CreateSwapChain(); void CreateImageViews(); + void CreateRenderPass(); void CreateGraphicsPipeline(); std::vector GetRequiredInstanceExtentions(); @@ -83,6 +84,10 @@ class Graphics final { std::vector swap_chain_images_; std::vector swap_chain_image_views_; + VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; + VkRenderPass render_pass_ = VK_NULL_HANDLE; + VkPipeline pipeline_ = VK_NULL_HANDLE; + gsl::not_null window_; bool validation_enabled_ = false; }; diff --git a/shaders/basic.frag b/shaders/basic.frag index 112d91f..c464517 100644 --- a/shaders/basic.frag +++ b/shaders/basic.frag @@ -1,5 +1,4 @@ #version 450 -#include "common.glsl" layout(location = 0) out vec4 out_color; diff --git a/src/vulkan/graphics.cpp b/src/vulkan/graphics.cpp index 6f86e8b..0a639e6 100644 --- a/src/vulkan/graphics.cpp +++ b/src/vulkan/graphics.cpp @@ -17,17 +17,30 @@ Graphics::Graphics(gsl::not_null window) : window_(window) { Graphics::~Graphics() { if (logical_device_ != VK_NULL_HANDLE) { + if (logical_device_ != VK_NULL_HANDLE) + vkDestroyPipeline(logical_device_, pipeline_, nullptr); + + if (pipeline_layout_ != VK_NULL_HANDLE) + vkDestroyPipelineLayout(logical_device_, pipeline_layout_, nullptr); + + if (render_pass_ != VK_NULL_HANDLE) + vkDestroyRenderPass(logical_device_, render_pass_, nullptr); + for (VkImageView image_view : swap_chain_image_views_) vkDestroyImageView(logical_device_, image_view, nullptr); + if (swap_chain_ != VK_NULL_HANDLE) vkDestroySwapchainKHR(logical_device_, swap_chain_, nullptr); + vkDestroyDevice(logical_device_, nullptr); } if (instance_ != VK_NULL_HANDLE) { if (surface_ != VK_NULL_HANDLE) vkDestroySurfaceKHR(instance_, surface_, nullptr); + if (debug_messenger_ != VK_NULL_HANDLE) vkDestroyDebugUtilsMessengerEXT(instance_, debug_messenger_, nullptr); + vkDestroyInstance(instance_, nullptr); } } @@ -39,6 +52,7 @@ void Graphics::InitializeVulkan() { PickPhysicalDevice(); CreateLogicalDeviceAndQueues(); CreateSwapChain(); + CreateRenderPass(); CreateGraphicsPipeline(); } diff --git a/src/vulkan/graphics_pipeline.cpp b/src/vulkan/graphics_pipeline.cpp index 312a3b2..3da1eae 100644 --- a/src/vulkan/graphics_pipeline.cpp +++ b/src/vulkan/graphics_pipeline.cpp @@ -52,5 +52,135 @@ void Graphics::CreateGraphicsPipeline() { std::array stage_infos = { vertex_stage_info, fragment_stage_info}; + + std::array 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 = dynamic_states.size(); + dynamic_state_info.pDynamicStates = dynamic_states.data(); + + VkViewport viewport = {}; + viewport.x = 0.f; + viewport.y = 0.f; + viewport.width = static_cast(extent_.width); + viewport.height = static_cast(extent_.height); + viewport.minDepth = 0.f; + viewport.maxDepth = 1.f; + + VkRect2D scissor = {}; + scissor.offset = {0, 0}; + scissor.extent = 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; + + VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; + vertex_input_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input_info.vertexBindingDescriptionCount = 0; + vertex_input_info.vertexAttributeDescriptionCount = 0; + + 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; + + VkPipelineRasterizationStateCreateInfo rasterization_state_info = {}; + rasterization_state_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state_info.depthClampEnable = VK_FALSE; + rasterization_state_info.rasterizerDiscardEnable = VK_FALSE; + rasterization_state_info.polygonMode = VK_POLYGON_MODE_FILL; + rasterization_state_info.lineWidth = 1.f; + rasterization_state_info.cullMode = VK_CULL_MODE_NONE; + rasterization_state_info.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterization_state_info.depthBiasEnable = VK_FALSE; + + VkPipelineMultisampleStateCreateInfo multisampling_info = {}; + multisampling_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling_info.sampleShadingEnable = VK_FALSE; + multisampling_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_blend_attachment = {}; + color_blend_attachment.blendEnable = VK_FALSE; + color_blend_attachment.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + VkPipelineColorBlendStateCreateInfo color_blending_info = {}; + color_blending_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + color_blending_info.logicOpEnable = VK_FALSE; + color_blending_info.attachmentCount = 1; + color_blending_info.pAttachments = &color_blend_attachment; + + VkPipelineLayoutCreateInfo layout_info = {}; + layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + + VkResult layout_result = vkCreatePipelineLayout(logical_device_, &layout_info, + nullptr, &pipeline_layout_); + if (layout_result != VK_SUCCESS) std::exit(EXIT_FAILURE); + + VkGraphicsPipelineCreateInfo pipeline_info = {}; + pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline_info.stageCount = stage_infos.size(); + pipeline_info.pStages = stage_infos.data(); + pipeline_info.pVertexInputState = &vertex_input_info; + pipeline_info.pInputAssemblyState = &input_assembly_info; + pipeline_info.pViewportState = &viewport_info; + pipeline_info.pRasterizationState = &rasterization_state_info; + pipeline_info.pMultisampleState = &multisampling_info; + pipeline_info.pDepthStencilState = nullptr; + pipeline_info.pColorBlendState = &color_blending_info; + pipeline_info.pDynamicState = &dynamic_state_info; + pipeline_info.layout = pipeline_layout_; + pipeline_info.renderPass = render_pass_; + pipeline_info.subpass = 0; + + VkResult pipline_result = vkCreateGraphicsPipelines( + logical_device_, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &pipeline_); + if (pipline_result != VK_SUCCESS) std::exit(EXIT_FAILURE); } + +void Graphics::CreateRenderPass() { + VkAttachmentDescription color_attachment = {}; + color_attachment.format = surface_format_.format; + color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; + color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + color_attachment.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 main_subpass = {}; + main_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + main_subpass.colorAttachmentCount = 1; + main_subpass.pColorAttachments = &color_attachment_ref; + + VkRenderPassCreateInfo render_pass_info = {}; + render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info.attachmentCount = 1; + render_pass_info.pAttachments = &color_attachment; + render_pass_info.subpassCount = 1; + render_pass_info.pSubpasses = &main_subpass; + + VkResult result = vkCreateRenderPass(logical_device_, &render_pass_info, + nullptr, &render_pass_); + if (result != VK_SUCCESS) std::exit(EXIT_FAILURE); +} + } // namespace veng diff --git a/src/vulkan/presentation.cpp b/src/vulkan/presentation.cpp index 60a837e..3cface2 100644 --- a/src/vulkan/presentation.cpp +++ b/src/vulkan/presentation.cpp @@ -163,7 +163,7 @@ void Graphics::CreateImageViews() { VkResult result = vkCreateImageView(logical_device_, &info, nullptr, &*image_view_it); if (result != VK_SUCCESS) std::exit(EXIT_FAILURE); - std::next(image_view_it); + std::advance(image_view_it, 1); } }