xash3d-fwgs/ref_vk/vk_pipeline.c

164 lines
5.0 KiB
C

#include "vk_pipeline.h"
#include "vk_framectl.h" // VkRenderPass
#include "eiface.h"
#define MAX_STAGES 2
VkPipelineCache g_pipeline_cache;
qboolean VK_PipelineInit( void )
{
VkPipelineCacheCreateInfo pcci = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
.initialDataSize = 0,
.pInitialData = NULL,
};
XVK_CHECK(vkCreatePipelineCache(vk_core.device, &pcci, NULL, &g_pipeline_cache));
return true;
}
void VK_PipelineShutdown( void )
{
vkDestroyPipelineCache(vk_core.device, g_pipeline_cache, NULL);
}
VkPipeline VK_PipelineGraphicsCreate(const vk_pipeline_graphics_create_info_t *ci)
{
VkPipeline pipeline;
VkVertexInputBindingDescription vibd = {
.binding = 0,
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
.stride = ci->vertex_stride,
};
VkPipelineVertexInputStateCreateInfo vertex_input = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = &vibd,
.vertexAttributeDescriptionCount = ci->num_attribs,
.pVertexAttributeDescriptions = ci->attribs,
};
VkPipelineInputAssemblyStateCreateInfo input_assembly = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
};
VkPipelineViewportStateCreateInfo viewport_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.viewportCount = 1,
.scissorCount = 1,
};
VkPipelineRasterizationStateCreateInfo raster_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.polygonMode = VK_POLYGON_MODE_FILL,
.cullMode = ci->cullMode,
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
.lineWidth = 1.f,
};
VkPipelineMultisampleStateCreateInfo multi_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
};
VkPipelineColorBlendAttachmentState blend_attachment = {
.blendEnable = ci->blendEnable,
.srcColorBlendFactor = ci->srcColorBlendFactor,
.dstColorBlendFactor = ci->dstColorBlendFactor,
.colorBlendOp = ci->colorBlendOp,
.srcAlphaBlendFactor = ci->srcAlphaBlendFactor,
.dstAlphaBlendFactor = ci->dstAlphaBlendFactor,
.alphaBlendOp = ci->alphaBlendOp,
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
};
VkPipelineColorBlendStateCreateInfo color_blend = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.attachmentCount = 1,
.pAttachments = &blend_attachment,
};
VkPipelineDepthStencilStateCreateInfo depth = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.depthTestEnable = ci->depthTestEnable,
.depthWriteEnable = ci->depthWriteEnable,
.depthCompareOp = ci->depthCompareOp,
};
VkDynamicState dynamic_states[] = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
};
VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = ARRAYSIZE(dynamic_states),
.pDynamicStates = dynamic_states,
};
VkPipelineShaderStageCreateInfo stage_create_infos[MAX_STAGES];
VkGraphicsPipelineCreateInfo gpci = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = ci->num_stages,
.pStages = stage_create_infos,
.pVertexInputState = &vertex_input,
.pInputAssemblyState = &input_assembly,
.pViewportState = &viewport_state,
.pRasterizationState = &raster_state,
.pMultisampleState = &multi_state,
.pColorBlendState = &color_blend,
.pDepthStencilState = &depth,
.layout = ci->layout,
.renderPass = vk_frame.render_pass.raster,
.pDynamicState = &dynamic_state_create_info,
.subpass = 0,
};
if (ci->num_stages > MAX_STAGES)
return VK_NULL_HANDLE;
for (int i = 0; i < ci->num_stages; ++i) {
stage_create_infos[i] = (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = ci->stages[i].stage,
.module = loadShader(ci->stages[i].filename),
.pSpecializationInfo = ci->stages[i].specialization_info,
.pName = "main",
};
}
XVK_CHECK(vkCreateGraphicsPipelines(vk_core.device, g_pipeline_cache, 1, &gpci, NULL, &pipeline));
for (int i = 0; i < ci->num_stages; ++i) {
vkDestroyShaderModule(vk_core.device, stage_create_infos[i].module, NULL);
}
return pipeline;
}
VkPipeline VK_PipelineComputeCreate(const vk_pipeline_compute_create_info_t *ci) {
const VkComputePipelineCreateInfo cpci = {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.layout = ci->layout,
.stage = (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = loadShader(ci->shader_filename),
.pName = "main",
.pSpecializationInfo = ci->specialization_info,
},
};
VkPipeline pipeline;
XVK_CHECK(vkCreateComputePipelines(vk_core.device, VK_NULL_HANDLE, 1, &cpci, NULL, &pipeline));
vkDestroyShaderModule(vk_core.device, cpci.stage.module, NULL);
return pipeline;
}