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}