1 #include <kiba/gpu/pipeline.h>
2 #include <kiba/gpu/vulkan/allocator.h>
3 #include <kiba/gpu/vulkan/conv.h>
4 #include <kiba/gpu/vulkan/device.h>
5 #include <kiba/gpu/vulkan/util.h>
10 VkPipelineLayoutCreateInfo info = {
11 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
12 .setLayoutCount = desc.bind_group_layouts ? (u32) array_size(desc.bind_group_layouts) : 0,
13 .pSetLayouts = desc.bind_group_layouts,
14 .pushConstantRangeCount = 0,
15 .pPushConstantRanges = NULL,
17 VK_CALL_B8(vkCreatePipelineLayout(device->logical, &info, &
vk_alloc.vulkan_callbacks, &layout->raw));
18 vk_device_set_object_name(device->logical, VK_OBJECT_TYPE_PIPELINE_LAYOUT, layout->raw, desc.label);
24 if (layout->raw != VK_NULL_HANDLE) {
25 vkDestroyPipelineLayout(device->logical, layout->raw, &
vk_alloc.vulkan_callbacks);
26 layout->raw = VK_NULL_HANDLE;
33 VkDynamicState dynamic_states[] = {
34 VK_DYNAMIC_STATE_VIEWPORT,
35 VK_DYNAMIC_STATE_SCISSOR,
40 VkPipelineDynamicStateCreateInfo dynamic_state_info = {
41 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
42 .dynamicStateCount =
sizeof(dynamic_states) /
sizeof(dynamic_states[0]),
43 .pDynamicStates = dynamic_states,
47 array_of(VkVertexInputBindingDescription) vertex_input_bindings =
KB_NULL;
48 array_of(VkVertexInputAttributeDescription) vertex_attributes =
KB_NULL;
49 VkPipelineVertexInputStateCreateInfo vertex_input_info = {
50 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
51 .vertexBindingDescriptionCount = 0,
52 .pVertexBindingDescriptions = vertex_input_bindings,
53 .vertexAttributeDescriptionCount = 0,
54 .pVertexAttributeDescriptions = vertex_attributes,
56 if (desc.vertex.buffers !=
KB_NULL) {
57 usize attribute_count = 0;
59 attribute_count += array_size(layout->attributes);
61 vertex_input_bindings =
62 array_create(VkVertexInputBindingDescription, array_size(desc.vertex.buffers), &
vk_alloc.kiba_alloc);
63 if (vertex_input_bindings ==
KB_NULL) {
64 KB_ERROR(
"could not allocate list of pipeline vertex inputs");
67 vertex_attributes = array_create(VkVertexInputAttributeDescription, attribute_count, &
vk_alloc.kiba_alloc);
68 if (vertex_attributes ==
KB_NULL) {
69 KB_ERROR(
"could not allocate list of pipeline vertex input's attribute descriptions");
70 array_destroy(vertex_input_bindings);
75 VkVertexInputBindingDescription input_binding_description = {
77 .inputRate = vk_convert_step_mode(layout->step_mode),
78 .stride = (u32) layout->stride,
80 array_push(vertex_input_bindings, input_binding_description);
83 VkVertexInputAttributeDescription attribute_description = {
85 .location = location++,
86 .format = vk_convert_vertex_format(attribute->format),
87 .offset = (u32) attribute->offset,
89 array_push(vertex_attributes, attribute_description);
93 vertex_input_info.vertexBindingDescriptionCount = (u32) array_size(vertex_input_bindings);
94 vertex_input_info.pVertexBindingDescriptions = vertex_input_bindings;
95 vertex_input_info.vertexAttributeDescriptionCount = (u32) array_size(vertex_attributes);
96 vertex_input_info.pVertexAttributeDescriptions = vertex_attributes;
100 VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {
101 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
102 .topology = vk_convert_primitive_topology(desc.primitive.topology),
103 .primitiveRestartEnable = VK_FALSE,
106 VkPipelineViewportStateCreateInfo viewport_state_info = {
107 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
113 VkPipelineRasterizationStateCreateInfo rasterizer_info = {
114 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
115 .depthClampEnable = VK_FALSE,
116 .rasterizerDiscardEnable = VK_FALSE,
117 .polygonMode = vk_convert_polygon_mode(desc.primitive.polygon_mode),
119 .cullMode = vk_convert_cull_mode(desc.primitive.cull_mode),
120 .frontFace = vk_convert_front_face(desc.primitive.front_face),
121 .depthBiasEnable = VK_FALSE,
123 .depthBiasConstantFactor = desc.depth_stencil.depth_bias.constant,
124 .depthBiasClamp = desc.depth_stencil.depth_bias.clamp,
125 .depthBiasSlopeFactor = desc.depth_stencil.depth_bias.slope_scale,
129 VkPipelineMultisampleStateCreateInfo multisampling_info = {
130 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
131 .sampleShadingEnable = VK_FALSE,
132 .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
133 .minSampleShading = 1.0f,
135 .alphaToCoverageEnable = VK_FALSE,
136 .alphaToOneEnable = VK_FALSE,
146 array_of(VkPipelineColorBlendAttachmentState) color_blend_attachments =
147 array_create(VkPipelineColorBlendAttachmentState, array_size(desc.fragment.targets), &
vk_alloc.kiba_alloc);
148 if (color_blend_attachments ==
KB_NULL) {
149 KB_ERROR(
"failed to allocate list of color blend attachments");
153 VkPipelineColorBlendAttachmentState color_blend_attachment = {
154 .colorWriteMask = target_state->write_mask,
155 .blendEnable = target_state->blend.active,
156 .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
157 .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
158 .colorBlendOp = VK_BLEND_OP_ADD,
159 .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
160 .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
161 .alphaBlendOp = VK_BLEND_OP_ADD,
163 array_push(color_blend_attachments, color_blend_attachment);
165 .format = vk_convert_texture_format(target_state->format),
166 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
167 .ops = GPU_ATTACHMENT_OP_ALL,
169 rp_key.colors[rp_key.color_count++].base = cak;
172 VkPipelineColorBlendStateCreateInfo color_blend_info = {
173 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
174 .logicOpEnable = VK_FALSE,
175 .logicOp = VK_LOGIC_OP_COPY,
176 .attachmentCount = (u32) array_size(color_blend_attachments),
177 .pAttachments = color_blend_attachments,
178 .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
182 VkPipelineDepthStencilStateCreateInfo depth_info = {
183 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
185 desc.depth_stencil.depth_compare != GPU_COMPARE_FUNC_ALWAYS || desc.depth_stencil.depth_write_enabled,
186 .depthWriteEnable = desc.depth_stencil.depth_write_enabled,
187 .depthCompareOp = vk_convert_compare_function(desc.depth_stencil.depth_compare),
188 .depthBoundsTestEnable = VK_FALSE,
189 .minDepthBounds = 0.f,
190 .maxDepthBounds = 1.f,
191 .stencilTestEnable = VK_FALSE,
196 VkRenderPass renderpass;
197 if (!vk_device_create_renderpass(device, rp_key, &renderpass)) {
198 KB_ERROR(
"could not create renderpass for pipeline");
203 VkPipelineShaderStageCreateInfo shader_stages[2] = {
205 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
206 .stage = VK_SHADER_STAGE_VERTEX_BIT,
207 .module = desc.vertex.shader->bs.raw,
208 .pName = desc.vertex.entry_point,
211 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
212 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
213 .module = desc.fragment.shader->bs.raw,
214 .pName = desc.fragment.entry_point,
218 VkGraphicsPipelineCreateInfo pipeline_info = {
219 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
220 .stageCount =
sizeof(shader_stages) /
sizeof(shader_stages[0]),
221 .pStages = shader_stages,
222 .pVertexInputState = &vertex_input_info,
223 .pInputAssemblyState = &input_assembly_info,
224 .pViewportState = &viewport_state_info,
225 .pRasterizationState = &rasterizer_info,
226 .pMultisampleState = &multisampling_info,
227 .pDepthStencilState = &depth_info,
228 .pColorBlendState = &color_blend_info,
229 .pDynamicState = &dynamic_state_info,
230 .layout = desc.layout->bl.raw,
231 .renderPass = renderpass,
233 .basePipelineHandle = VK_NULL_HANDLE,
234 .basePipelineIndex = -1,
236 VK_CALL_B8(vkCreateGraphicsPipelines(device->logical,
242 vk_device_set_object_name(device->logical, VK_OBJECT_TYPE_PIPELINE, pipeline->raw, desc.label);
243 array_destroy(&color_blend_attachments);
244 array_destroy(&vertex_attributes);
245 array_destroy(&vertex_input_bindings);
251 if (pipeline->raw != VK_NULL_HANDLE) {
252 vkDestroyPipeline(device->logical, pipeline->raw, &
vk_alloc.vulkan_callbacks);
253 pipeline->raw = VK_NULL_HANDLE;
#define KB_NULL
Value of an invalid ptr (nullptr).
#define KB_ERROR(...)
Log entry with error log level.