1+ #include " vulkan_base.h"
2+
3+ VkShaderModule createShaderModule (VulkanContext* context, const char * shaderFilename) {
4+ VkShaderModule result = {};
5+
6+ // Read shader file
7+ FILE* file = fopen (shaderFilename, " rb" );
8+ if (!file) {
9+ LOG_ERROR (" Shader not found: " , shaderFilename);
10+ return result;
11+ }
12+ fseek (file, 0 , SEEK_END);
13+ long fileSize = ftell (file);
14+ fseek (file, 0 , SEEK_SET);
15+ assert ((fileSize & 0x03 ) == 0 );
16+ uint8_t * buffer = new uint8_t [fileSize];
17+ fread (buffer, 1 , fileSize, file);
18+
19+ VkShaderModuleCreateInfo createInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };
20+ createInfo.codeSize = fileSize;
21+ createInfo.pCode = (uint32_t *)buffer;
22+ VKA (vkCreateShaderModule (context->device , &createInfo, 0 , &result));
23+
24+ delete[] buffer;
25+ fclose (file);
26+
27+ return result;
28+ }
29+
30+ VulkanPipeline createPipeline (VulkanContext* context, const char * vertexShaderFilename, const char * fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height) {
31+ VkShaderModule vertexShaderModule = createShaderModule (context, vertexShaderFilename);
32+ VkShaderModule fragmentShaderModule = createShaderModule (context, fragmentShaderFilename);
33+
34+ VkPipelineShaderStageCreateInfo shaderStages[2 ];
35+ shaderStages[0 ] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
36+ shaderStages[0 ].stage = VK_SHADER_STAGE_VERTEX_BIT;
37+ shaderStages[0 ].module = vertexShaderModule;
38+ shaderStages[0 ].pName = " main" ;
39+ shaderStages[1 ] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
40+ shaderStages[1 ].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
41+ shaderStages[1 ].module = fragmentShaderModule;
42+ shaderStages[1 ].pName = " main" ;
43+
44+ VkPipelineVertexInputStateCreateInfo vertexInputState = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
45+
46+ VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
47+ inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
48+
49+ VkPipelineViewportStateCreateInfo viewportState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
50+ viewportState.viewportCount = 1 ;
51+ VkViewport viewport = { 0 .0f , 0 .0f , (float )width, (float )height };
52+ viewportState.pViewports = &viewport;
53+ viewportState.scissorCount = 1 ;
54+ VkRect2D scissor = { {0 , 0 }, {width, height} };
55+ viewportState.pScissors = &scissor;
56+
57+ VkPipelineRasterizationStateCreateInfo rasterizationState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
58+ rasterizationState.lineWidth = 1 .0f ;
59+
60+ VkPipelineMultisampleStateCreateInfo multisampleState = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
61+ multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
62+
63+ VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
64+ colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
65+ colorBlendAttachment.blendEnable = VK_FALSE;
66+ VkPipelineColorBlendStateCreateInfo colorBlendState = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
67+ colorBlendState.attachmentCount = 1 ;
68+ colorBlendState.pAttachments = &colorBlendAttachment;
69+
70+ VkPipelineLayout pipelineLayout;
71+ {
72+ VkPipelineLayoutCreateInfo createInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
73+ VKA (vkCreatePipelineLayout (context->device , &createInfo, 0 , &pipelineLayout));
74+ }
75+
76+ VkPipeline pipeline;
77+ {
78+ VkGraphicsPipelineCreateInfo createInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
79+ createInfo.stageCount = ARRAY_COUNT (shaderStages);
80+ createInfo.pStages = shaderStages;
81+ createInfo.pVertexInputState = &vertexInputState;
82+ createInfo.pInputAssemblyState = &inputAssemblyState;
83+ createInfo.pViewportState = &viewportState;
84+ createInfo.pRasterizationState = &rasterizationState;
85+ createInfo.pMultisampleState = &multisampleState;
86+ createInfo.pColorBlendState = &colorBlendState;
87+ createInfo.layout = pipelineLayout;
88+ createInfo.renderPass = renderPass;
89+ createInfo.subpass = 0 ;
90+ VKA (vkCreateGraphicsPipelines (context->device , 0 , 1 , &createInfo, 0 , &pipeline));
91+ }
92+
93+ // Module can be destroyed after pipeline creation
94+ VK (vkDestroyShaderModule (context->device , vertexShaderModule, 0 ));
95+ VK (vkDestroyShaderModule (context->device , fragmentShaderModule, 0 ));
96+
97+ VulkanPipeline result = {};
98+ result.pipeline = pipeline;
99+ result.pipelineLayout = pipelineLayout;
100+ return result;
101+ }
102+
103+ void destroyPipeline (VulkanContext* context, VulkanPipeline* pipeline) {
104+ VK (vkDestroyPipeline (context->device , pipeline->pipeline , 0 ));
105+ VK (vkDestroyPipelineLayout (context->device , pipeline->pipelineLayout , 0 ));
106+ }
0 commit comments