main
  1#include "gog_pipeline.h"
  2#include <stdlib.h>
  3#include <vulkan/vulkan_core.h>
  4
  5gog_result gog_create_pipeline_core(gog_pipeline_core * core, gog_pipeline_ci ci) {
  6	core->vk_pipeline_device = ci.device;
  7	core->type = ci.type;
  8
  9	GOG_LOG_INFO("Initializing Pipeline Core [Type: %d]", ci.type);
 10
 11	/* 1. Layout Creation (Linking Atomic Resources) */
 12	VkPipelineLayoutCreateInfo layout_ci = {
 13		.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 14		.pNext = NULL,
 15		.setLayoutCount = (ci.descriptor_set) ? 1 : 0,
 16		.pSetLayouts = (ci.descriptor_set) ? &ci.descriptor_set->layout.vk_layout : NULL,
 17		.pushConstantRangeCount = (ci.push_constants) ? 1 : 0,
 18		.pPushConstantRanges = (ci.push_constants) ? &ci.push_constants->vk_range : NULL
 19	};
 20
 21	VkResult res = vkCreatePipelineLayout(ci.device, &layout_ci, NULL, &core->vk_pipeline_layout);
 22	GOG_CHECK_VK(res, "Failed to create VkPipelineLayout");
 23
 24	/* 2. Shader Stage Setup */
 25	VkPipelineShaderStageCreateInfo *stages = alloca(sizeof(VkPipelineShaderStageCreateInfo) * ci.shader_c);
 26	for (uint32_t j = 0; j < ci.shader_c; j++) {
 27		stages[j] = (VkPipelineShaderStageCreateInfo){
 28			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
 29			.stage = ci.shaders_p[j].stage,
 30			.module = ci.shaders_p[j].mod,
 31			.pName = "main"
 32		};
 33	}
 34	
 35	/* 3. Pipeline Type-Specific Logic */
 36	if (ci.type == GOG_GRAPHICS_PIPELINE) {
 37		core->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
 38
 39		/* Pull Vertex Input from Atomic gog_vertex_buffer */
 40		VkVertexInputBindingDescription binding = { 
 41			.binding = 0, 
 42			.stride = (uint32_t)ci.graphics.v_buff->layout.stride, 
 43			.inputRate = VK_VERTEX_INPUT_RATE_VERTEX 
 44		};
 45
 46		VkPipelineVertexInputStateCreateInfo v_input_ci = {
 47			.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
 48			.vertexBindingDescriptionCount = 1,
 49			.pVertexBindingDescriptions = &binding,
 50			.vertexAttributeDescriptionCount = (uint32_t)ci.graphics.v_buff->layout.attr_c,
 51			.pVertexAttributeDescriptions = ci.graphics.v_buff->layout.vk_attrs
 52		};
 53
 54		/* Setup Dynamic Rendering (Modern Vulkan style) */
 55		VkPipelineRenderingCreateInfo dyn_render_ci = {
 56			.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
 57			.pNext = NULL,
 58			.colorAttachmentCount = 1,
 59			.pColorAttachmentFormats = &ci.graphics.canvas->format_i.color,
 60			.depthAttachmentFormat = ci.graphics.canvas->format_i.depth
 61		};
 62
 63		/* Fixed Function States from Atomic Raster/Canvas objects */
 64		VkPipelineInputAssemblyStateCreateInfo ia_ci = { 
 65			.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 
 66			.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST 
 67		};
 68		
 69		VkPipelineRasterizationStateCreateInfo rs_ci = { 
 70			.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 
 71			.lineWidth = 1.0f, 
 72			.polygonMode = VK_POLYGON_MODE_FILL, 
 73			.cullMode = ci.graphics.raster->cull_mode 
 74		};
 75
 76		VkPipelineDepthStencilStateCreateInfo ds_ci = { 
 77			.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 
 78			.depthTestEnable = ci.graphics.raster->depth_test, 
 79			.depthWriteEnable = ci.graphics.raster->depth_test, 
 80			.depthCompareOp = VK_COMPARE_OP_LESS 
 81		};
 82
 83		VkPipelineMultisampleStateCreateInfo ms_ci = { 
 84			.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 
 85			.rasterizationSamples = ci.graphics.canvas->format_i.samples 
 86		};
 87		
 88		VkPipelineViewportStateCreateInfo vp_ci = { 
 89			.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 
 90			.viewportCount = 1, 
 91			.scissorCount = 1 
 92		};
 93
 94		VkPipelineDynamicStateCreateInfo dyn_state_ci = { 
 95			.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 
 96			.dynamicStateCount = (uint32_t)ci.graphics.dynamic.count, 
 97			.pDynamicStates = (VkDynamicState*)ci.graphics.dynamic.states 
 98		};
 99
100		VkGraphicsPipelineCreateInfo gfx_ci = {
101			.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
102			.pNext = &dyn_render_ci,
103			.stageCount = ci.shader_c,
104			.pStages = stages,
105			.pVertexInputState = &v_input_ci,
106			.pInputAssemblyState = &ia_ci,
107			.pRasterizationState = &rs_ci,
108			.pMultisampleState = &ms_ci,
109			.pDepthStencilState = &ds_ci,
110			.pViewportState = &vp_ci,
111			.pDynamicState = &dyn_state_ci,
112			.layout = core->vk_pipeline_layout
113		};
114
115		res = vkCreateGraphicsPipelines(ci.device, VK_NULL_HANDLE, 1, &gfx_ci, NULL, &core->vk_pipeline);
116		GOG_CHECK_VK(res, "Failed to create Graphics VkPipeline");
117
118	} else {
119		core->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
120		
121		VkComputePipelineCreateInfo comp_ci = {
122			.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
123			.stage = stages[0],
124			.layout = core->vk_pipeline_layout
125		};
126		
127		res = vkCreateComputePipelines(ci.device, VK_NULL_HANDLE, 1, &comp_ci, NULL, &core->vk_pipeline);
128		GOG_CHECK_VK(res, "Failed to create Compute VkPipeline");
129	}
130
131	GOG_LOG_INFO("Pipeline core created at address: %p", (void*)core->vk_pipeline);
132	return GET_GOG_RESULT(GOG_SUCCES, 0);
133}