Updated gitignore, added pipeline creation code and basic render loop
							parent
							
								
									bf3a2c33df
								
							
						
					
					
						commit
						1fa7b38624
					
				| @ -0,0 +1,20 @@ | ||||
| #ifndef PIPELINE_H | ||||
| #define PIPELINE_H | ||||
| 
 | ||||
| #include "vulkan/vulkan_core.h" | ||||
| #include "cglm/types.h" | ||||
| 
 | ||||
| typedef struct GraphicsPipelineStruct { | ||||
|   VkDescriptorPool      descriptor_pool; | ||||
|   VkDescriptorSet*      descriptors; | ||||
| 
 | ||||
|   VkPipelineLayout      layout; | ||||
|   VkPipeline            pipeline; | ||||
| } GraphicsPipeline; | ||||
| 
 | ||||
| struct Vertex2 { | ||||
|   vec2 pos; | ||||
|   vec3 color; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
											
												Binary file not shown.
											
										
									
								| @ -0,0 +1,249 @@ | ||||
| #include "pipeline.h" | ||||
| #include "stdio.h" | ||||
| #include "stdlib.h" | ||||
| 
 | ||||
| VkShaderModule load_shader_file(const char* path, VkDevice device) { | ||||
|   FILE* file; | ||||
|   file = fopen(path, "rb"); | ||||
|   if(file == 0) { | ||||
|     return VK_NULL_HANDLE; | ||||
|   } | ||||
| 
 | ||||
|   int result = fseek(file, 0, SEEK_END); | ||||
|   if(result != 0) { | ||||
|     return VK_NULL_HANDLE; | ||||
|   } | ||||
| 
 | ||||
|   long buffer_size = ftell(file); | ||||
| 
 | ||||
|   result = fseek(file, 0, SEEK_SET); | ||||
|   if(result != 0) { | ||||
|     return VK_NULL_HANDLE; | ||||
|   } | ||||
| 
 | ||||
|   char * buffer = malloc(buffer_size); | ||||
|   if(buffer == 0) { | ||||
|     return VK_NULL_HANDLE; | ||||
|   } | ||||
| 
 | ||||
|   size_t read = fread(buffer, 1, buffer_size, file); | ||||
| 
 | ||||
|   VkShaderModuleCreateInfo shader_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, | ||||
|     .codeSize = read, | ||||
|     .pCode = (uint32_t*)buffer, | ||||
|   }; | ||||
| 
 | ||||
|   VkShaderModule shader; | ||||
|   result = vkCreateShaderModule(device, &shader_info, 0, &shader); | ||||
|   free(buffer); | ||||
|   if(result != VK_SUCCESS) { | ||||
|     return VK_NULL_HANDLE; | ||||
|   } | ||||
| 
 | ||||
|   return shader; | ||||
| } | ||||
| 
 | ||||
| VkResult create_ui_rect_pipeline(VkDevice device, VkRenderPass render_pass, GraphicsPipeline* out) { | ||||
|   if(out == NULL) { | ||||
|     return VK_ERROR_VALIDATION_FAILED_EXT; | ||||
|   } | ||||
| 
 | ||||
|   VkShaderModule vert_shader = load_shader_file("shader_src/ui_rect.vert.spv", device); | ||||
|   VkShaderModule frag_shader = load_shader_file("shader_src/ui_rect.frag.spv", device); | ||||
|   VkPipelineShaderStageCreateInfo shader_stages[2] = { | ||||
|     { | ||||
|       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | ||||
|       .stage = VK_SHADER_STAGE_VERTEX_BIT, | ||||
|       .module = vert_shader, | ||||
|       .pName = "main", | ||||
|     }, | ||||
|     { | ||||
|       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | ||||
|       .stage = VK_SHADER_STAGE_FRAGMENT_BIT, | ||||
|       .module = frag_shader, | ||||
|       .pName = "main", | ||||
|     }, | ||||
|   }; | ||||
| 
 | ||||
|   VkVertexInputBindingDescription bindings[1] = { | ||||
|     { | ||||
|       .binding = 0, // Which buffer 'binding' to use
 | ||||
|       .stride = sizeof(struct Vertex2), // How many bytes to increase the index between instance
 | ||||
|       .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, // Whether an instance is a vertex or an index
 | ||||
|     }, | ||||
|   }; | ||||
| 
 | ||||
|   VkVertexInputAttributeDescription attributes[3] = { | ||||
|     { | ||||
|       .binding = 0, // Which buffer 'binding' to use
 | ||||
|       .location = 0, // Which 'location' to export as to shader
 | ||||
|       .format = VK_FORMAT_R32G32_SFLOAT, // What format to interpret as for shader
 | ||||
|       .offset = offsetof(struct Vertex2, pos), // What offset from instance start
 | ||||
|     }, | ||||
|     { | ||||
|       .binding = 0, | ||||
|       .location = 1, | ||||
|       .format = VK_FORMAT_R32G32B32_SFLOAT, | ||||
|       .offset = offsetof(struct Vertex2, color), | ||||
|     }, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineVertexInputStateCreateInfo input_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | ||||
|     .pVertexBindingDescriptions = bindings, | ||||
|     .vertexBindingDescriptionCount = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), | ||||
|     .pVertexAttributeDescriptions = attributes, | ||||
|     .vertexAttributeDescriptionCount = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), | ||||
|   }; | ||||
| 
 | ||||
|   VkPushConstantRange pcr = { | ||||
|     .stageFlags = VK_SHADER_STAGE_ALL, | ||||
|     .offset = 0, | ||||
|     .size = sizeof(VkDeviceAddress), | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineLayoutCreateInfo layout_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | ||||
|     .pushConstantRangeCount = 1, | ||||
|     .pPushConstantRanges = &pcr, | ||||
|   }; | ||||
| 
 | ||||
|   VkResult result = vkCreatePipelineLayout(device, &layout_info, 0, &out->layout); | ||||
|   if(result != VK_SUCCESS) { | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   VkDynamicState dynamic_states[] = { | ||||
|     VK_DYNAMIC_STATE_VIEWPORT, | ||||
|     VK_DYNAMIC_STATE_SCISSOR, | ||||
|   }; | ||||
| 
 | ||||
|   uint32_t dynamic_state_count = sizeof(dynamic_states)/sizeof(VkDynamicState); | ||||
| 
 | ||||
|   VkPipelineDynamicStateCreateInfo dynamic_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | ||||
|     .dynamicStateCount = dynamic_state_count, | ||||
|     .pDynamicStates = dynamic_states, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineInputAssemblyStateCreateInfo input_assembly_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | ||||
|     .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, | ||||
|     .primitiveRestartEnable = VK_FALSE, | ||||
|   }; | ||||
| 
 | ||||
|   VkViewport viewport = { | ||||
|     .x = 0.0f, | ||||
|     .y = 0.0f, | ||||
|     .width = (float)(100), | ||||
|     .height = (float)(100), | ||||
|     .minDepth = 0.0f, | ||||
|     .maxDepth = 1.0f, | ||||
|   }; | ||||
| 
 | ||||
|   VkRect2D scissor = { | ||||
|     .offset = { | ||||
|       .x = 0, | ||||
|       .y = 0, | ||||
|     }, | ||||
|     .extent = { | ||||
|       .width = 100, | ||||
|       .height = 100, | ||||
|     }, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineViewportStateCreateInfo viewport_state = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, | ||||
|     .viewportCount = 1, | ||||
|     .pViewports = &viewport, | ||||
|     .scissorCount = 1, | ||||
|     .pScissors = &scissor, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineRasterizationStateCreateInfo raster_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | ||||
|     .depthClampEnable = VK_FALSE, | ||||
|     .rasterizerDiscardEnable = VK_FALSE, | ||||
|     .polygonMode = VK_POLYGON_MODE_FILL, | ||||
|     .lineWidth = 1.0f, | ||||
|     .cullMode = VK_CULL_MODE_BACK_BIT, | ||||
|     .frontFace = VK_FRONT_FACE_CLOCKWISE, | ||||
|     .depthBiasEnable = VK_FALSE, | ||||
|     .depthBiasConstantFactor = 0.0f, | ||||
|     .depthBiasClamp = 0.0f, | ||||
|     .depthBiasSlopeFactor = 0.0f, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineMultisampleStateCreateInfo multisample_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | ||||
|     .sampleShadingEnable = VK_FALSE, | ||||
|     .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, | ||||
|     .minSampleShading = 1.0f, | ||||
|     .pSampleMask = 0, | ||||
|     .alphaToCoverageEnable = VK_FALSE, | ||||
|     .alphaToOneEnable = VK_FALSE, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineDepthStencilStateCreateInfo depth_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, | ||||
|     .depthTestEnable = VK_TRUE, | ||||
|     .depthWriteEnable = VK_TRUE, | ||||
|     .depthCompareOp = VK_COMPARE_OP_LESS, | ||||
|     .depthBoundsTestEnable = VK_FALSE, | ||||
|     .maxDepthBounds = 1.0f, | ||||
|     .minDepthBounds = 0.0f, | ||||
|     .stencilTestEnable = VK_FALSE, | ||||
|     .front = {}, | ||||
|     .back = {}, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineColorBlendAttachmentState color_blend_attachment = { | ||||
|     .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, | ||||
|     .blendEnable = VK_TRUE, | ||||
|     .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, | ||||
|     .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, | ||||
|     .colorBlendOp = VK_BLEND_OP_ADD, | ||||
|     .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, | ||||
|     .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, | ||||
|     .alphaBlendOp = VK_BLEND_OP_ADD, | ||||
|   }; | ||||
| 
 | ||||
|   VkPipelineColorBlendStateCreateInfo color_blend_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, | ||||
|     .logicOpEnable = VK_FALSE, | ||||
|     .logicOp = VK_LOGIC_OP_COPY, | ||||
|     .attachmentCount = 1, | ||||
|     .pAttachments = &color_blend_attachment, | ||||
|     .blendConstants[0] = 0.0f, | ||||
|     .blendConstants[1] = 0.0f, | ||||
|     .blendConstants[2] = 0.0f, | ||||
|     .blendConstants[3] = 0.0f, | ||||
|   }; | ||||
| 
 | ||||
|   VkGraphicsPipelineCreateInfo draw_pipeline_info = { | ||||
|     .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | ||||
|     .stageCount = 2, | ||||
|     .pStages = shader_stages, | ||||
|     .pVertexInputState = &input_info, | ||||
|     .pInputAssemblyState = &input_assembly_info, | ||||
|     .pViewportState = &viewport_state, | ||||
|     .pRasterizationState = &raster_info, | ||||
|     .pColorBlendState = &color_blend_info, | ||||
|     .pDynamicState = &dynamic_info, | ||||
|     .pDepthStencilState = &depth_info, | ||||
|     .pMultisampleState = &multisample_info, | ||||
|     .layout = out->layout, | ||||
|     .renderPass = render_pass, | ||||
|     .subpass = 0, | ||||
|     .basePipelineHandle = VK_NULL_HANDLE, | ||||
|     .basePipelineIndex = -1, | ||||
|   }; | ||||
| 
 | ||||
|   result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &draw_pipeline_info, 0, &out->pipeline); | ||||
|   if(result != VK_SUCCESS) { | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   return VK_SUCCESS; | ||||
| } | ||||
											
												Binary file not shown.
											
										
									
								
		Loading…
	
		Reference in New Issue