vulkan游戏引擎的pipeline管道实现

1.vulkan_pipeline.h

#pragma once

#include "vulkan_types.inl"

b8 vulkan_graphics_pipeline_create(

vulkan_context* context,

vulkan_renderpass* renderpass,

u32 attribute_count,

VkVertexInputAttributeDescription* attributes,

u32 descriptor_set_layout_count,

VkDescriptorSetLayout* descriptor_set_layouts,

u32 stage_count,

VkPipelineShaderStageCreateInfo* stages,

VkViewport viewport,

VkRect2D scissor,

b8 is_wireframe,

vulkan_pipeline* out_pipeline

);

void vulkan_pipeline_destroy(vulkan_context* context,vulkan_pipeline* pipeline);

void vulkan_pipeline_bind(vulkan_command_buffer* command_buffer,VkPipelineBindPoint bind_point,vulkan_pipeline* pipeline);

2.vulkan_pipeline.c

#include "vulkan_pipeline.h"

#include "vulkan_utils.h"

#include "core/kmemory.h"

#include "core/logger.h"

#include "math/math_types.h"

b8 vulkan_graphics_pipeline_create(

vulkan_context* context,

vulkan_renderpass* renderpass,

u32 attribute_count,

VkVertexInputAttributeDescription* attributes,

u32 descriptor_set_layout_count,

VkDescriptorSetLayout* descriptor_set_layouts,

u32 stage_count,

VkPipelineShaderStageCreateInfo* stages,

VkViewport viewport,

VkRect2D scissor,

b8 is_wireframe,

vulkan_pipeline* out_pipeline

)

{

//viewport state

VkPipelineViewportStateCreateInfo viewport_state = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};

viewport_state.viewportCount = 1;

viewport_state.pViewports = &viewport;

viewport_state.scissorCount = 1;

viewport_state.pScissors=&scissor;

//Rasterizer

VkPipelineRasterizationStateCreateInfo rasterizer_create_info = {VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO};

rasterizer_create_info.depthClampEnable = VK_FALSE;

rasterizer_create_info.rasterizerDiscardEnable = VK_FALSE;

rasterizer_create_info.polygonMode = is_wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;

rasterizer_create_info.lineWidth = 1.0f;

rasterizer_create_info.cullMode = VK_CULL_MODE_BACK_BIT;

rasterizer_create_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;

rasterizer_create_info.depthBiasEnable = VK_FALSE;

rasterizer_create_info.depthBiasConstantFactor = 0.0f;

rasterizer_create_info.depthBiasClamp = 0.0f;

rasterizer_create_info.depthBiasSlopeFactor = 0.0f;

//Multisampling

VkPipelineMultisampleStateCreateInfo multisampling_create_info = {VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};

multisampling_create_info.sampleShadingEnable = VK_FALSE;

multisampling_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;

multisampling_create_info.minSampleShading = 1.0f;

multisampling_create_info.pSampleMask = 0;

multisampling_create_info.alphaToCoverageEnable = VK_FALSE;

multisampling_create_info.alphaToOneEnable = VK_FALSE;

//Depth and stencil testing

VkPipelineDepthStencilStateCreateInfo depth_stencil = {VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};

depth_stencil.depthTestEnable = VK_TRUE;

depth_stencil.depthWriteEnable = VK_TRUE;

depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS;

depth_stencil.depthBoundsTestEnable = VK_FALSE;

depth_stencil.stencilTestEnable = VK_FALSE;

VkPipelineColorBlendAttachmentState color_blend_attachment_state;

kzero_memory(&color_blend_attachment_state,sizeof(VkPipelineColorBlendAttachmentState));

color_blend_attachment_state.blendEnable = VK_TRUE;

color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;

color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;

color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;

color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;

color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;

color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;

color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |

VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;

VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};

color_blend_state_create_info.logicOpEnable = VK_FALSE;

color_blend_state_create_info.logicOp = VK_LOGIC_OP_COPY;

color_blend_state_create_info.attachmentCount = 1;

color_blend_state_create_info.pAttachments = &color_blend_attachment_state;

//Dynamic state

const u32 dynamic_state_count = 3;

VkDynamicState dynamic_states[dynamic_state_count] = {

VK_DYNAMIC_STATE_VIEWPORT,

VK_DYNAMIC_STATE_SCISSOR,

VK_DYNAMIC_STATE_LINE_WIDTH

};

VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO};

dynamic_state_create_info.dynamicStateCount = dynamic_state_count;

dynamic_state_create_info.pDynamicStates = dynamic_states;

//Vertex input

VkVertexInputBindingDescription binding_description;

binding_description.binding = 0;

binding_description.stride = sizeof(vertex_3d);

binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

//Atrributes

VkPipelineVertexInputStateCreateInfo vertex_input_info = {VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};

vertex_input_info.vertexBindingDescriptionCount = 1;

vertex_input_info.pVertexBindingDescriptions = &binding_description;

vertex_input_info.vertexAttributeDescriptionCount = attribute_count;

vertex_input_info.pVertexAttributeDescriptions = attributes;

//Input assembly

VkPipelineInputAssemblyStateCreateInfo input_assembly = {VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};

input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

input_assembly.primitiveRestartEnable = VK_FALSE;

//Pipeline layout

VkPipelineLayoutCreateInfo pipeline_layout_create_info = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};

//Push constants

VkPushConstantRange push_constant;

push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;

push_constant.offset = sizeof(mat4) * 0;

push_constant.size = sizeof(mat4) * 2;

pipeline_layout_create_info.pushConstantRangeCount = 1;

pipeline_layout_create_info.pPushConstantRanges = &push_constant;

pipeline_layout_create_info.setLayoutCount = descriptor_set_layout_count;

pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts;

//Create the pipeline layout

VK_CHECK(vkCreatePipelineLayout(

context->device.logical_device,

&pipeline_layout_create_info,

context->allocator,

&out_pipeline->pipeline_layout

));

//Pipeline create

VkGraphicsPipelineCreateInfo pipeline_create_info = {VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};

pipeline_create_info.stageCount = stage_count;

pipeline_create_info.pStages = stages;

pipeline_create_info.pVertexInputState = &vertex_input_info;

pipeline_create_info.pInputAssemblyState = &input_assembly;

pipeline_create_info.pViewportState = &viewport_state;

pipeline_create_info.pRasterizationState = &rasterizer_create_info;

pipeline_create_info.pMultisampleState = &multisampling_create_info;

pipeline_create_info.pDepthStencilState = &depth_stencil;

pipeline_create_info.pColorBlendState = &color_blend_state_create_info;

pipeline_create_info.pDynamicState = &dynamic_state_create_info;

pipeline_create_info.pTessellationState = 0;

pipeline_create_info.layout = out_pipeline->pipeline_layout;

pipeline_create_info.renderPass = renderpass->handle;

pipeline_create_info.subpass = 0;

pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;

pipeline_create_info.basePipelineIndex = -1;

VkResult result = vkCreateGraphicsPipelines(

context->device.logical_device,

VK_NULL_HANDLE,

1,

&pipeline_create_info,

context->allocator,

&out_pipeline->handle

);

if(vulkan_result_is_success(result))

{

KDEBUG("Graphics pipeline created!");

return true;

}

KERROR("vkCreateGraphicsPipelines failed with %s.",vulkan_result_string(result,true));

return false;

}

void vulkan_pipeline_destroy(vulkan_context* context,vulkan_pipeline* pipeline)

{

if(pipeline){

//Destroy pipeline

if(pipeline->handle)

{

vkDestroyPipeline(context->device.logical_device,pipeline->handle,context->allocator);

pipeline->handle=0;

}

//Destroy layout

if(pipeline->pipeline_layout)

{

vkDestroyPipelineLayout(context->device.logical_device,pipeline->pipeline_layout,context->allocator);

pipeline->pipeline_layout = 0;

}

}

}

void vulkan_pipeline_bind(vulkan_command_buffer* command_buffer,VkPipelineBindPoint bind_point,vulkan_pipeline* pipeline)

{

vkCmdBindPipeline(command_buffer->handle,bind_point,pipeline->handle);

}

相关推荐
破刺不会编程几秒前
linux中基础IO(上)
linux·运维·服务器·开发语言
在未来等你5 分钟前
互联网大厂Java求职面试:AI大模型推理服务性能优化与向量数据库分布式检索
java·llm·milvus·向量数据库·rag·spring ai·语义缓存
不爱吃饭爱吃菜9 分钟前
uniapp小程序开发,判断跳转页面是否需要登录方法封装
开发语言·前端·javascript·vue.js·uni-app
代码小将17 分钟前
java方法重写学习笔记
java·笔记·学习
饕餮争锋28 分钟前
单点登陆(SSO)简介-笔记
java·笔记
行星0081 小时前
docker常用命令
java·云原生·eureka
破刺不会编程1 小时前
Linux中基础IO(下)
linux·运维·服务器·开发语言
阮少年、1 小时前
Course 1: Best Practice of RK‘s start Maps SDK for javascript
开发语言·javascript·ecmascript
magic 2452 小时前
实时同步缓存,与阶段性同步缓存——补充理解《补充》
java·redis·mysql
牛马baby2 小时前
Java高频面试之并发编程-23
java·开发语言·面试