diff options
| -rw-r--r-- | src/window.cpp | 181 |
1 files changed, 177 insertions, 4 deletions
diff --git a/src/window.cpp b/src/window.cpp index f073df7..dc6de6f 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,4 +1,3 @@ -#include <vulkan/vulkan_core.h> #define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_VULKAN @@ -42,7 +41,9 @@ VkExtent2D extent; VkImage *swapchainImages = nullptr; VkImageView *swapchainImageViews = nullptr; VkRenderPass renderPass; +VkDescriptorSetLayout vkDescriptorSetLayout; VkPipelineLayout pipelineLayout; +VkPipeline graphicsPipeline; const std::vector<const char *> REQUIRED_EXTENSIONS = std::vector<const char *> { VK_KHR_SWAPCHAIN_EXTENSION_NAME @@ -478,6 +479,175 @@ void CreateRenderPass() { } } +void CreateGraphicsPipeline() { + AssetHandle vertShaderAsset = RegisterAsset("assets/shaders/present.vert.spv"); + AssetHandle fragShaderAsset = RegisterAsset("assets/shaders/present.frag.spv"); + auto vertShader = UploadShader(vertShaderAsset); + auto fragShader = UploadShader(fragShaderAsset); + + VkPipelineShaderStageCreateInfo shaderStages[2]; + for (long i = 0; i < 2; ++i) { + shaderStages[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[i].flags = 0; + shaderStages[i].pName = "main"; + shaderStages[i].pSpecializationInfo = nullptr; + shaderStages[i].pNext = nullptr; + } + shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shaderStages[0].module = vertShader; + shaderStages[1].module = fragShader; + + VkDynamicState dynamicStates[2] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR + }; + VkPipelineDynamicStateCreateInfo dynamicState{}; + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.dynamicStateCount = 2; + dynamicState.pDynamicStates = dynamicStates; + + VkPipelineVertexInputStateCreateInfo vertexInputInfo{}; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputInfo.vertexBindingDescriptionCount = 0; + vertexInputInfo.pVertexBindingDescriptions = nullptr; + vertexInputInfo.vertexAttributeDescriptionCount = 0; + vertexInputInfo.pVertexAttributeDescriptions = nullptr; + + VkPipelineInputAssemblyStateCreateInfo inputAssembly{}; + inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + inputAssembly.primitiveRestartEnable = VK_FALSE; + + VkViewport viewport{}; + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = (float) extent.width; + viewport.height = (float) extent.height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + + VkRect2D scissor{}; + scissor.offset = {0, 0}; + scissor.extent = extent; + + VkPipelineViewportStateCreateInfo viewportState{}; + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportState.viewportCount = 1; + viewportState.pViewports = &viewport; + viewportState.scissorCount = 1; + viewportState.pScissors = &scissor; + + VkPipelineRasterizationStateCreateInfo rasterizer{}; + rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizer.depthClampEnable = VK_FALSE; + rasterizer.rasterizerDiscardEnable = VK_FALSE; + rasterizer.polygonMode = VK_POLYGON_MODE_FILL; + rasterizer.lineWidth = 1.0f; + rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; + rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.depthBiasEnable = VK_FALSE; + rasterizer.depthBiasConstantFactor = 0.0f; + rasterizer.depthBiasClamp = 0.0f; + rasterizer.depthBiasSlopeFactor = 0.0f; + + VkPipelineMultisampleStateCreateInfo multisampling{}; + multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling.sampleShadingEnable = VK_FALSE; + multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisampling.minSampleShading = 1.0f; + multisampling.pSampleMask = nullptr; + multisampling.alphaToCoverageEnable = VK_FALSE; + multisampling.alphaToOneEnable = VK_FALSE; + + VkPipelineDepthStencilStateCreateInfo *depthStencilInfo = nullptr; + + VkPipelineColorBlendAttachmentState colorBlendAttachment{}; + colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + colorBlendAttachment.blendEnable = VK_FALSE; + colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; + colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; + colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; + + VkPipelineColorBlendStateCreateInfo colorBlending{}; + colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.logicOpEnable = VK_FALSE; + colorBlending.logicOp = VK_LOGIC_OP_COPY; + colorBlending.attachmentCount = 1; + colorBlending.pAttachments = &colorBlendAttachment; + colorBlending.blendConstants[0] = 0.0f; + colorBlending.blendConstants[1] = 0.0f; + colorBlending.blendConstants[2] = 0.0f; + colorBlending.blendConstants[3] = 0.0f; + + /* + * PipelineLayout + DescriptorSets + */ + + VkDescriptorSetLayoutBinding imageSamplerLayoutBinding{}; + imageSamplerLayoutBinding.binding = 0; + imageSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + imageSamplerLayoutBinding.descriptorCount = 1; + imageSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + imageSamplerLayoutBinding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{}; + descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.flags = 0; + descriptorSetLayoutCreateInfo.bindingCount = 1; + descriptorSetLayoutCreateInfo.pBindings = &imageSamplerLayoutBinding; + + auto result = vkCreateDescriptorSetLayout(vkDevice, &descriptorSetLayoutCreateInfo, vkAllocator, &vkDescriptorSetLayout); + if (result != VK_SUCCESS) { + throw "failed to create descriptor set layout"; + } + + VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.setLayoutCount = 1; + pipelineLayoutInfo.pSetLayouts = &vkDescriptorSetLayout; + pipelineLayoutInfo.pushConstantRangeCount = 0; + pipelineLayoutInfo.pPushConstantRanges = nullptr; + + result = vkCreatePipelineLayout(vkDevice, &pipelineLayoutInfo, vkAllocator, &pipelineLayout); + if (result != VK_SUCCESS) { + throw "failed to create pipeline layout"; + } + + VkGraphicsPipelineCreateInfo pipelineInfo{}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineInfo.stageCount = 2; + pipelineInfo.pStages = shaderStages; + + pipelineInfo.pVertexInputState = &vertexInputInfo; + pipelineInfo.pInputAssemblyState = &inputAssembly; + pipelineInfo.pViewportState = &viewportState; + pipelineInfo.pRasterizationState = &rasterizer; + pipelineInfo.pMultisampleState = &multisampling; + pipelineInfo.pDepthStencilState = depthStencilInfo; + pipelineInfo.pColorBlendState = &colorBlending; + pipelineInfo.pDynamicState = &dynamicState; + + pipelineInfo.layout = pipelineLayout; + pipelineInfo.renderPass = renderPass; + pipelineInfo.subpass = 0; + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; + pipelineInfo.basePipelineIndex = -1; + + result = vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, 1, &pipelineInfo, vkAllocator, &graphicsPipeline); + if (result != VK_SUCCESS) { + throw "failed to create graphics pipeline."; + } + + vkDestroyShaderModule(vkDevice, fragShader, vkAllocator); + vkDestroyShaderModule(vkDevice, vertShader, vkAllocator); + DestroyAsset(fragShaderAsset); + DestroyAsset(vertShaderAsset); +} + void DestroySwapchain() { if (swapchainImageViews!= nullptr && swapchainImageViews != CAFE_BABE(VkImageView)) { for (long i = 0; i < swapchainLength; ++i) { @@ -510,16 +680,19 @@ void CreateWindow(PKEWindowProperties *wp) { glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback); CreateSwapchain(); CreateRenderPass(); + CreateGraphicsPipeline(); } void DestroyWindow() { if (vkInstance == nullptr) return; if (VULKAN_DEBUG_REPORT) { auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(vkInstance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(vkInstance, vkDebugReport, nullptr); + vkDestroyDebugReportCallbackEXT(vkInstance, vkDebugReport, vkAllocator); } - vkDestroyPipelineLayout(vkDevice, pipelineLayout, nullptr); - vkDestroyRenderPass(vkDevice, renderPass, nullptr); + vkDestroyPipeline(vkDevice, graphicsPipeline, vkAllocator); + vkDestroyPipelineLayout(vkDevice, pipelineLayout, vkAllocator); + vkDestroyDescriptorSetLayout(vkDevice, vkDescriptorSetLayout, vkAllocator); + vkDestroyRenderPass(vkDevice, renderPass, vkAllocator); DestroySwapchain(); vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator); vkDestroyDevice(vkDevice, vkAllocator); |
