diff options
| author | vimene <vincent.menegaux@gmail.com> | 2025-12-18 16:24:32 +0100 |
|---|---|---|
| committer | vimene <vincent.menegaux@gmail.com> | 2025-12-18 16:24:32 +0100 |
| commit | 0639c2e9a3e1a1ecf36a66a5f2dd844b772856db (patch) | |
| tree | 005f2d57fdfb3ddd3801d4478993ba1cfb72f088 /src/engine.cpp | |
| parent | 79e2e5394e25a03022301f7e9c30ff256f2aaddc (diff) | |
| download | engine-0639c2e9a3e1a1ecf36a66a5f2dd844b772856db.tar.gz | |
added basic graphics pipeline and shaders
Diffstat (limited to 'src/engine.cpp')
| -rw-r--r-- | src/engine.cpp | 222 |
1 files changed, 221 insertions, 1 deletions
diff --git a/src/engine.cpp b/src/engine.cpp index 204b2e9..1c9f109 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -18,6 +18,8 @@ #include <tuple> #include <limits> #include <array> +#include <ios> +#include <fstream> #define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h> @@ -739,7 +741,7 @@ static int main_graphical() { device_create_info.pQueueCreateInfos = &deviceQueueCreateInfo; device_create_info.enabledExtensionCount = static_cast<uint32_t>(device_exts.size()); device_create_info.ppEnabledExtensionNames = device_exts.data(); - // we get device features while selection the physical device + // we get device features while selecting the physical device device_create_info.pNext = &device_features; VkPhysicalDeviceVulkan13Features device_vk13_features{}; @@ -880,9 +882,12 @@ static int main_graphical() { for (uint32_t i = 0; i < swapchain_imgs.size(); i++) { VkImageViewCreateInfo img_view_create_info { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = {}, + .flags = {}, .image = swapchain_imgs[i], .viewType = VK_IMAGE_VIEW_TYPE_2D, .format = surface_format.format, + .components = {}, .subresourceRange = { // VkImageSubresourceRange .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, @@ -897,12 +902,227 @@ static int main_graphical() { } } + // reading shader file + VkShaderModule shader_module; + { + // shader code has to be 32-bits aligned, which is the case with the default allocator + std::vector<char> shader_code; + { + const char* shader_file_name = SHADERSDIR "/shader.spv"; + std::ifstream shader_file(shader_file_name, std::ios::ate | std::ios::binary); + if (!shader_file.is_open()) { + std::cerr << "file `" << shader_file_name << "'not found" << std::endl; // TODO: improve + std::exit(EXIT_SUCCESS); + } + shader_code.resize(shader_file.tellg()); + shader_file.seekg(0, std::ios::beg); + shader_file.read(shader_code.data(), static_cast<std::streamsize>(shader_code.size())); + } + + VkShaderModuleCreateInfo shader_module_create_info { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .codeSize = shader_code.size(), + .pCode = reinterpret_cast<const uint32_t*>(shader_code.data()), + }; + if (VkResult res = vkCreateShaderModule(logical_device, &shader_module_create_info, nullptr, &shader_module); res != VK_SUCCESS) { + std::cerr << "failed to create shader module, error code: " << string_VkResult(res) << std::endl; + std::exit(EXIT_FAILURE); + } + } + + std::array pl_shader_stage_create_infos { + VkPipelineShaderStageCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = shader_module, + .pName = "vert_main", + .pSpecializationInfo = nullptr, + }, + VkPipelineShaderStageCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = shader_module, + .pName = "frag_main", + .pSpecializationInfo = nullptr, + }, + }; + + std::array<VkDynamicState, 2> dynamic_states { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + VkPipelineDynamicStateCreateInfo pl_dyn_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .dynamicStateCount = static_cast<uint32_t>(dynamic_states.size()), + .pDynamicStates = dynamic_states.data(), + }; + + VkPipelineVertexInputStateCreateInfo pl_vert_in_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .vertexBindingDescriptionCount = 0, + .pVertexBindingDescriptions = nullptr, + .vertexAttributeDescriptionCount = 0, + .pVertexAttributeDescriptions = nullptr, + }; + + VkPipelineInputAssemblyStateCreateInfo pl_in_asm_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, + }; + + VkViewport viewport { + .x = 0.f, + .y = 0.f, + .width = static_cast<float>(swapchain_extent.width), + .height = static_cast<float>(swapchain_extent.height), + .minDepth = 0.f, + .maxDepth = 1.f, + }; + VkRect2D scissor { + .offset = { 0, 0 }, + .extent = swapchain_extent, + }; + VkPipelineViewportStateCreateInfo pl_viewport_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .viewportCount = 1, + .pViewports = {}, + .scissorCount = 1, + .pScissors = {}, + }; + + VkPipelineRasterizationStateCreateInfo pl_raster_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .depthClampEnable = VK_FALSE, + .rasterizerDiscardEnable = VK_FALSE, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .depthBiasEnable = VK_FALSE, + .depthBiasConstantFactor = {}, + .depthBiasClamp = {}, + .depthBiasSlopeFactor = {}, + .lineWidth = 1.f, + }; + + VkPipelineMultisampleStateCreateInfo pl_ms_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + .sampleShadingEnable = VK_FALSE, + .minSampleShading = {}, + .pSampleMask = {}, + .alphaToCoverageEnable = VK_FALSE, + .alphaToOneEnable = VK_FALSE, + }; + + VkPipelineColorBlendAttachmentState pl_col_blend_attachment_state { + .blendEnable = VK_FALSE, + .srcColorBlendFactor = {}, + .dstColorBlendFactor = {}, + .colorBlendOp = {}, + .srcAlphaBlendFactor = {}, + .dstAlphaBlendFactor = {}, + .alphaBlendOp = {}, + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT + | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT + | VK_COLOR_COMPONENT_A_BIT, + }; + + VkPipelineColorBlendStateCreateInfo pl_col_blend_state_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .logicOpEnable = VK_FALSE, + .logicOp = {}, + .attachmentCount = 1, + .pAttachments = &pl_col_blend_attachment_state, + .blendConstants = { 0.f, 0.f, 0.f, 0.f }, + }; + + VkPipelineLayoutCreateInfo pl_layout_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = {}, + .setLayoutCount = 0, + .pSetLayouts = {}, + .pushConstantRangeCount = 0, + .pPushConstantRanges = {}, + }; + + VkPipelineLayout pl_layout; + if (VkResult res = vkCreatePipelineLayout(logical_device, &pl_layout_create_info, nullptr, &pl_layout); res != VK_SUCCESS) { + std::cerr << "failed to create pipeline layout, error code: " << string_VkResult(res) << std::endl; + std::exit(EXIT_FAILURE); + } + + VkPipelineRenderingCreateInfo pl_render_create_info { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + .pNext = nullptr, + .viewMask = {}, + .colorAttachmentCount = 1, + .pColorAttachmentFormats = &surface_format.format, + .depthAttachmentFormat = {}, + .stencilAttachmentFormat = {}, + }; + + VkGraphicsPipelineCreateInfo graphics_pl_create_info { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = &pl_render_create_info, + .flags = {}, + .stageCount = 2, + .pStages = pl_shader_stage_create_infos.data(), + .pVertexInputState = &pl_vert_in_state_create_info, + .pInputAssemblyState = &pl_in_asm_state_create_info, + .pTessellationState = {}, + .pViewportState = &pl_viewport_state_create_info, + .pRasterizationState = &pl_raster_state_create_info, + .pMultisampleState = &pl_ms_state_create_info, + .pDepthStencilState = {}, + .pColorBlendState = &pl_col_blend_state_create_info, + .pDynamicState = &pl_dyn_state_create_info, + .layout = pl_layout, + .renderPass = nullptr, + .subpass = {}, + .basePipelineHandle = {}, + .basePipelineIndex = {}, + }; + + VkPipeline graphics_pl; + if (VkResult res = vkCreateGraphicsPipelines(logical_device, nullptr, 1, &graphics_pl_create_info, nullptr, &graphics_pl); res != VK_SUCCESS) { + std::cerr << "failed to pipeline, error code: " << string_VkResult(res) << std::endl; + std::exit(EXIT_FAILURE); + } + + // destroy when pipeline creation is finished + vkDestroyShaderModule(logical_device, shader_module, nullptr); + // main loop while (!glfwWindowShouldClose(window)) { glfwPollEvents(); } // cleanup + vkDestroyPipeline(logical_device, graphics_pl, nullptr); + vkDestroyPipelineLayout(logical_device, pl_layout, nullptr); for (const auto img_view : swapchain_img_views) vkDestroyImageView(logical_device, img_view, nullptr); vkDestroySwapchainKHR(logical_device, swapchain, nullptr); |
