Files
evk/evk/evkPipeline.c
T
mo7sen 3f4792c7f1
Test Compilation / Build evk (push) Failing after 22s
WIP Samples
2026-05-08 01:53:34 +03:00

247 lines
8.8 KiB
C

#include "evkPipeline.h"
#include "evk/evkTypes.h"
#include "evkShader.h"
#include "evk/evkVertexLayout.h"
const u32 DESCRIPTOR_SET_LAYOUT_COUNT = 4;
evkPipelineLayout evkCreatePipelineLayout(evkDevice device, evkPipelineLayoutCreateInfo createInfo)
{
evkPipelineLayout layout;
vec(VkDescriptorSetLayout) setLayouts = vec_init(VkDescriptorSetLayout);
for(int i = 0; i < vec_len(&createInfo.setLayouts); i++)
vec_push(&setLayouts, &createInfo.setLayouts[i].vk);
VkPipelineLayoutCreateInfo vkCreateInfo = (VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.setLayoutCount = vec_len(&setLayouts),
.pSetLayouts = setLayouts,
.pushConstantRangeCount = vec_len(&createInfo.pushConstantRanges),
.pPushConstantRanges = createInfo.pushConstantRanges,
};
vkCreatePipelineLayout(device.vk, &vkCreateInfo, NULL, &layout.vk);
return layout;
}
void evkDestroyPipelineLayout(evkDevice device, evkPipelineLayout layout)
{
vkDestroyPipelineLayout(device.vk, layout.vk, NULL);
}
evkPipeline evkCreateComputePipeline(evkDevice device, evkPipelineCreateInfo createInfo)
{
// return EV_INVALID(evkPipeline);
}
evkPipeline evkCreateGraphicsPipeline(evkDevice device, evkPipelineCreateInfo createInfo)
{
u32 shaderStageCount = vec_len(&createInfo.shaderStages);
u32 colorAttachmentCount = vec_len(&createInfo.colorAttachments);
u32 dynamicStateCount = vec_len(&createInfo.dynamicStates);
evkPipeline res;
res.type = createInfo.type;
VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = dynamicStateCount,
.pDynamicStates = createInfo.dynamicStates,
};
VkFormat colorAttachmentFormats[colorAttachmentCount];
for(int i = 0; i < colorAttachmentCount; i++)
colorAttachmentFormats[i] = createInfo.colorAttachments[i].format;
VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
.colorAttachmentCount = colorAttachmentCount,
.pColorAttachmentFormats = colorAttachmentFormats,
.depthAttachmentFormat = createInfo.depthAttachmentFormat,
.stencilAttachmentFormat = createInfo.stencilAttachmentFormat,
.viewMask = createInfo.viewMask,
};
VkPipelineColorBlendAttachmentState colorAttachmentBlendStates[colorAttachmentCount];
for(int i = 0; i < colorAttachmentCount; i++)
colorAttachmentBlendStates[i] = createInfo.colorAttachments[i].blendState;
VkPipelineColorBlendStateCreateInfo colorBlending = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.pNext = NULL,
.flags = 0, // Update if VK_EXT_rasterization_order_attachment_access is supported
.logicOpEnable = createInfo.blendingOp != VK_LOGIC_OP_NO_OP,
.logicOp = createInfo.blendingOp,
.attachmentCount = colorAttachmentCount,
.pAttachments = colorAttachmentBlendStates,
};
colorBlending.blendConstants[0] = createInfo.blendConstants[0];
colorBlending.blendConstants[1] = createInfo.blendConstants[1];
colorBlending.blendConstants[2] = createInfo.blendConstants[2];
colorBlending.blendConstants[3] = createInfo.blendConstants[3];
u32 viewportCount = createInfo.viewportCountOverride;
if(viewportCount == 0 && createInfo.viewports)
viewportCount = vec_len(&createInfo.viewports);
VkViewport viewports[viewportCount];
VkRect2D scissors[viewportCount];
if(createInfo.viewports)
{
for(int i = 0; i < viewportCount; i++)
{
viewports[i] = createInfo.viewports[i].vkViewport;
VkRect2D currScis = createInfo.viewports[i].vkScissor;
scissors[i].offset.x = max(currScis.offset.x, viewports[i].x);
scissors[i].offset.y = max(currScis.offset.y, viewports[i].y);
scissors[i].extent.width = currScis.extent.width == 0? viewports[i].width : currScis.extent.width;
scissors[i].extent.height = currScis.extent.height == 0? viewports[i].height : currScis.extent.height;
}
}
VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.viewportCount = viewportCount,
.scissorCount = viewportCount,
.pViewports = viewports,
.pScissors = scissors,
};
VkPipelineShaderStageCreateInfo shaderStageCreateInfos[shaderStageCount];
for(int i = 0; i < vec_len(&createInfo.shaderStages); i++)
shaderStageCreateInfos[i] = evkGetShaderStageCreateInfo(createInfo.shaderStages[i]);
vec(VkVertexInputBindingDescription) binding_descriptions = vec_init(VkVertexInputBindingDescription);
vec(VkVertexInputAttributeDescription) attribute_descriptions = vec_init(VkVertexInputAttributeDescription);
for(int i = 0; i < vec_len(&createInfo.vertexBufferLayouts); i++)
{
evkVertexBufferLayout buf = createInfo.vertexBufferLayouts[i];
int vertexStride = 0;
for(int j = 0; j < EVK_VERTEX_ATTRIBUTE_TYPE_COUNT; j++)
{
evkVertexAttribute attr = buf.attributes[j];
if(attr.fmt == EVK_VERTEX_ATTRIBUTE_INVALID) break;
VkVertexInputAttributeDescription attr_desc = {
.binding = i,
.location = j,
.format = evkVertexAttributeGetVkFormat(attr),
.offset = vertexStride,
};
vec_push(&attribute_descriptions, &attr_desc);
vertexStride += evkVertexAttributeGetSize(attr);
}
VkVertexInputBindingDescription vert_desc = // {0, 8, VK_VERTEX_INPUT_RATE_VERTEX};
{
.inputRate = createInfo.vertexBufferLayouts[i].inputRate,
.binding = i,
.stride = vertexStride,
};
vec_push(&binding_descriptions, &vert_desc);
}
VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = vec_len(&binding_descriptions),
.pVertexBindingDescriptions = binding_descriptions,
.vertexAttributeDescriptionCount = vec_len(&attribute_descriptions),
.pVertexAttributeDescriptions = attribute_descriptions,
};
/* VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfos[DESCRIPTOR_SET_LAYOUT_COUNT] = {}; */
/* for(u32 di = 0; di < DESCRIPTOR_SET_LAYOUT_COUNT; di++) */
/* { */
/* descriptorSetLayoutCreateInfos[di].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; */
/* for(u32 si = 0; si < vec_len(&createInfo.shaderStages); si++) */
/* { */
/**/
/* } */
/* } */
// VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfos[4];
//
// svec(VkDescriptorSetLayout) descriptorSetLayouts = svec_init_w_len(VkDescriptorSetLayout, 4);
//
// for(int i = 0; i < 4; i++)
// {
// VkDescriptorSetLayoutCreateInfo dsCreateInfo = {};
//
// // Fill descriptorSetLayoutCreateInfos[i] from shader reflection data + Create descriptorSetLayouts[i]
// }
if(createInfo.setLayouts != NULL)
{
res.layout = evkCreatePipelineLayout(device,
EV_DEFAULT(evkPipelineLayoutCreateInfo,
setLayouts = createInfo.setLayouts,
)
);
}
else
{
assert(!"Set Layout construction through shader reflection not implemented yet.");
}
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &pipelineRenderingCreateInfo,
.flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
.stageCount = shaderStageCount,
.pStages = shaderStageCreateInfos,
.pVertexInputState = &vertexInputStateCreateInfo,
.pInputAssemblyState = &EV_DEFAULT(VkPipelineInputAssemblyStateCreateInfo),
.pViewportState = &viewportStateCreateInfo,
.pRasterizationState = &EV_DEFAULT(VkPipelineRasterizationStateCreateInfo),
.pMultisampleState = &EV_DEFAULT(VkPipelineMultisampleStateCreateInfo),
.pColorBlendState = &colorBlending,
.pDynamicState = &dynamicStateCreateInfo,
.layout = res.layout.vk,
};
EVK_ASSERT(vkCreateGraphicsPipelines(device.vk, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, NULL, &res.vk));
res._device = device;
vec_fini(&attribute_descriptions);
vec_fini(&binding_descriptions);
return res;
}
evkPipeline evkCreatePipeline(evkDevice device, evkPipelineCreateInfo createInfo)
{
if(createInfo.type == EVK_PIPELINE_TYPE_GRAPHICS)
return evkCreateGraphicsPipeline(device, createInfo);
else
return evkCreateComputePipeline(device, createInfo);
}
void evkDestroyPipeline(evkPipeline pipeline)
{
vkDestroyPipeline(pipeline._device.vk, pipeline.vk, NULL);
evkDestroyPipelineLayout(pipeline._device, pipeline.layout);
}
void evkCmdBindPipeline(evkCommandBuffer* cmdbuf, evkPipeline* pipeline)
{
cmdbuf->boundPipeline = pipeline;
vkCmdBindPipeline(cmdbuf->vk, (VkPipelineBindPoint)pipeline->type, pipeline->vk);
}
void evkCmdImageBarrier(evkCommandBuffer* cmdbuf, VkImageMemoryBarrier barrier)
{
vkCmdPipelineBarrier(cmdbuf->vk, 0, 0, 0, 0, NULL, 0, NULL, 1, &barrier);
}