diff --git a/NothinFancy/src/client/render/RenderEngine.cpp b/NothinFancy/src/client/render/RenderEngine.cpp index 5386997..e2a84c5 100644 --- a/NothinFancy/src/client/render/RenderEngine.cpp +++ b/NothinFancy/src/client/render/RenderEngine.cpp @@ -22,6 +22,8 @@ namespace nf::client::render { , m_swapchainImageFormat() , m_swapchainImages() , m_swapchainImageViews() + , m_pipelineLayoutOutput() + , m_pipelineOutput() { NFLog("Initializing render engine"); m_window->setDisplay(m_display); @@ -227,7 +229,6 @@ namespace nf::client::render { swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchainCI.presentMode = chosenPresentMode; swapchainCI.clipped = VK_TRUE; - swapchainCI.oldSwapchain = VK_NULL_HANDLE; if (vkCreateSwapchainKHR(m_device, &swapchainCI, nullptr, &m_swapchain) != VK_SUCCESS) NFError("Could not create Vulkan swapchain."); @@ -284,17 +285,85 @@ namespace nf::client::render { void RenderEngine::createOutputPipeline() { // First, create shader modules - std::string outputShaderVertex, outputShaderFragment; - if (!util::readFile("shaders/output.vert.glsl.spv", outputShaderVertex) || !util::readFile("shaders/output.frag.glsl.spv", outputShaderFragment)) + std::string outputShaderVertexBinary, outputShaderFragmentBinary; + if (!util::readFile("shaders/output.vert.glsl.spv", outputShaderVertexBinary) || !util::readFile("shaders/output.frag.glsl.spv", outputShaderFragmentBinary)) NFError("Could not read output shader binaries."); - ShaderModule outputShaderVertexModule(m_device, outputShaderVertex); - ShaderModule outputShaderFragmentModule(m_device, outputShaderFragment); + ShaderModule outputShaderVertexModule(m_device, outputShaderVertexBinary); + ShaderModule outputShaderFragmentModule(m_device, outputShaderFragmentBinary); - // And cleanup shader modules + // Fill out pipeline shader stages + VkPipelineShaderStageCreateInfo outputShaderStages[] = { {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO}, {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO} }; + outputShaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + outputShaderStages[0].module = outputShaderVertexModule.getHandle(); + outputShaderStages[0].pName = outputShaderStages[1].pName = "main"; + outputShaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + outputShaderStages[1].module = outputShaderFragmentModule.getHandle(); + + // Specify dynamic state + VkDynamicState dynamicState = VK_DYNAMIC_STATE_VIEWPORT; + VkPipelineDynamicStateCreateInfo dynamicStateCI = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dynamicStateCI.dynamicStateCount = 1; + dynamicStateCI.pDynamicStates = &dynamicState; + + // Specify vertex input state + VkPipelineVertexInputStateCreateInfo vertexInputStateCI = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + + // Specify input assembly state + VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + inputAssemblyStateCI.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + // Specify viewport state + VkRect2D scissor = { {0, 0}, {m_display.width, m_display.height} }; + VkPipelineViewportStateCreateInfo viewportStateCI = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + viewportStateCI.viewportCount = 1; + viewportStateCI.scissorCount = 1; + viewportStateCI.pScissors = &scissor; + + // Specify rasterization state + VkPipelineRasterizationStateCreateInfo rasterizationCI = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + rasterizationCI.lineWidth = 1.0; + rasterizationCI.cullMode = VK_CULL_MODE_BACK_BIT; + rasterizationCI.frontFace = VK_FRONT_FACE_CLOCKWISE; + + // Specify multisample state + VkPipelineMultisampleStateCreateInfo multisampleStateCI = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + // Specify color blend state + VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {}; + colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + VkPipelineColorBlendStateCreateInfo colorBlendStateCI = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + colorBlendStateCI.attachmentCount = 1; + colorBlendStateCI.pAttachments = &colorBlendAttachmentState; + + // Create pipeline layout + VkPipelineLayoutCreateInfo layoutCI = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + + if (vkCreatePipelineLayout(m_device, &layoutCI, nullptr, &m_pipelineLayoutOutput) != VK_SUCCESS) + NFError("Could not create pipeline layout."); + + // And finally put it all together + VkGraphicsPipelineCreateInfo pipelineCI = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; + pipelineCI.stageCount = 2; + pipelineCI.pStages = outputShaderStages; + pipelineCI.pVertexInputState = &vertexInputStateCI; + pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; + pipelineCI.pViewportState = &viewportStateCI; + pipelineCI.pRasterizationState = &rasterizationCI; + pipelineCI.pMultisampleState = &multisampleStateCI; + pipelineCI.pColorBlendState = &colorBlendStateCI; + pipelineCI.pDynamicState = &dynamicStateCI; + pipelineCI.layout = m_pipelineLayoutOutput; + pipelineCI.renderPass = m_renderPassOutput; + + if (vkCreateGraphicsPipelines(m_device, nullptr, 1, &pipelineCI, nullptr, &m_pipelineOutput) != VK_SUCCESS) + NFError("Could not create graphics pipeline."); } RenderEngine::~RenderEngine() { + vkDestroyPipeline(m_device, m_pipelineOutput, nullptr); + vkDestroyPipelineLayout(m_device, m_pipelineLayoutOutput, nullptr); vkDestroyRenderPass(m_device, m_renderPassOutput, nullptr); for (int i = 0; i < m_swapchainImageViews.size(); i++) diff --git a/NothinFancy/src/client/render/RenderEngine.h b/NothinFancy/src/client/render/RenderEngine.h index 9601765..923fabe 100644 --- a/NothinFancy/src/client/render/RenderEngine.h +++ b/NothinFancy/src/client/render/RenderEngine.h @@ -36,5 +36,9 @@ namespace nf::client::render { VkFormat m_swapchainImageFormat; std::vector m_swapchainImages; std::vector m_swapchainImageViews; + + // Pipelines + VkPipelineLayout m_pipelineLayoutOutput; + VkPipeline m_pipelineOutput; }; } diff --git a/NothinFancy/src/client/render/ShaderModule.cpp b/NothinFancy/src/client/render/ShaderModule.cpp index 3c5a110..6ac5e37 100644 --- a/NothinFancy/src/client/render/ShaderModule.cpp +++ b/NothinFancy/src/client/render/ShaderModule.cpp @@ -12,6 +12,7 @@ namespace nf::client::render { VkShaderModuleCreateInfo shaderModuleCI = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; shaderModuleCI.codeSize = shaderBinary.size(); shaderModuleCI.pCode = reinterpret_cast(shaderBinary.data()); + if (vkCreateShaderModule(device, &shaderModuleCI, nullptr, &m_shaderModule) != VK_SUCCESS) NFError("Could not create shader module."); }