247 lines
8.8 KiB
C
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);
|
|
}
|