Cleaned up pipeline creation into structs(MeshType to describe Mesh buffers, and PipelineLayout to describe descriptor sets/PCRs(TODO))

main
noah metz 2024-01-09 18:36:40 -07:00
parent 9ccfe3d0f7
commit 91d8ed6e3b
1 changed files with 74 additions and 53 deletions

@ -64,6 +64,24 @@ typedef struct TextureStruct {
VkSampler sampler;
} Texture;
// Defines how a mesh is read from a buffer into a graphics pipeline
typedef struct MeshTypeStruct {
uint32_t bindings_count;
VkVertexInputBindingDescription* bindings;
uint32_t attributes_count;
VkVertexInputAttributeDescription* attributes;
} MeshType;
// Defines what descriptors are bound at two different upate rates for the pipeline
typedef struct PipelineLayoutStruct {
uint32_t mesh_bindings_count;
VkDescriptorSetLayoutBinding* mesh_bindings;
uint32_t material_bindings_count;
VkDescriptorSetLayoutBinding* material_bindings;
} PipelineLayout;
typedef struct MeshStruct {
uint32_t vertex_count;
AllocatedBuffer vertex_buffer;
@ -93,7 +111,7 @@ typedef struct MaterialStruct {
VkDescriptorSetLayout material_set_layout;
VkDescriptorSetLayout mesh_set_layout;
VkPipelineLayout pipeline_layout;
VkPipelineLayout layout;
VkPipeline pipeline;
} Material;
@ -1469,10 +1487,7 @@ VkPipeline create_graphics_pipeline(
VkRenderPass render_pass,
uint32_t shader_stage_count,
VkPipelineShaderStageCreateInfo* shader_stages,
uint32_t bindings_count,
VkVertexInputBindingDescription* bindings,
uint32_t attributes_count,
VkVertexInputAttributeDescription* attributes
MeshType mesh_type
) {
VkDynamicState dynamic_states[] = {
VK_DYNAMIC_STATE_VIEWPORT,
@ -1487,15 +1502,15 @@ VkPipeline create_graphics_pipeline(
VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_input_info.vertexBindingDescriptionCount = bindings_count;
vertex_input_info.pVertexBindingDescriptions = bindings;
vertex_input_info.vertexAttributeDescriptionCount = attributes_count;
vertex_input_info.pVertexAttributeDescriptions = attributes;
vertex_input_info.vertexBindingDescriptionCount = mesh_type.bindings_count;
vertex_input_info.pVertexBindingDescriptions = mesh_type.bindings;
vertex_input_info.vertexAttributeDescriptionCount = mesh_type.attributes_count;
vertex_input_info.pVertexAttributeDescriptions = mesh_type.attributes;
VkPipelineInputAssemblyStateCreateInfo input_assemvly_info = {};
input_assemvly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
input_assemvly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
input_assemvly_info.primitiveRestartEnable = VK_FALSE;
VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {};
input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
input_assembly_info.primitiveRestartEnable = VK_FALSE;
VkViewport viewport = {};
viewport.x = 0.0f;
@ -1578,7 +1593,7 @@ VkPipeline create_graphics_pipeline(
pipeline_info.stageCount = shader_stage_count;
pipeline_info.pStages = shader_stages;
pipeline_info.pVertexInputState = &vertex_input_info;
pipeline_info.pInputAssemblyState = &input_assemvly_info;
pipeline_info.pInputAssemblyState = &input_assembly_info;
pipeline_info.pViewportState = &viewport_state;
pipeline_info.pRasterizationState = &raster_info;
pipeline_info.pDepthStencilState = 0;
@ -1687,7 +1702,7 @@ void record_command_buffer_mesh(Mesh mesh, VkCommandBuffer command_buffer) {
void record_command_buffer_material(Material material, uint32_t mesh_count, Mesh* meshes, VkDescriptorSet scene_ubo_descriptor, VkCommandBuffer command_buffer) {
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline);
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline_layout, 0, 1, &scene_ubo_descriptor, 0, 0);
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_ubo_descriptor, 0, 0);
for(uint32_t i = 0; i < mesh_count; i++) {
record_command_buffer_mesh(meshes[i], command_buffer);
}
@ -1877,16 +1892,8 @@ Material create_material(
uint32_t shader_stage_count,
VkPipelineShaderStageCreateInfo* shader_stages,
VkDescriptorSetLayout scene_ubo_layout,
uint32_t material_set_bindings_count,
VkDescriptorSetLayoutBinding* material_set_bindings,
uint32_t mesh_set_bindings_count,
VkDescriptorSetLayoutBinding* mesh_set_bindings,
uint32_t pcr_count,
VkPushConstantRange* pcrs,
uint32_t vertex_bindings_count,
VkVertexInputBindingDescription* vertex_bindings,
uint32_t attributes_count,
VkVertexInputAttributeDescription* attributes
PipelineLayout pipeline_layout,
MeshType mesh_type
) {
Material zero_material = {
.pipeline = VK_NULL_HANDLE,
@ -1897,11 +1904,11 @@ Material create_material(
VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, VK_NULL_HANDLE, VK_NULL_HANDLE};
uint32_t num_layouts = 1;
if(material_set_bindings_count > 0) {
if(pipeline_layout.material_bindings_count > 0) {
VkDescriptorSetLayoutCreateInfo layout_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = material_set_bindings_count,
.pBindings = material_set_bindings,
.bindingCount = pipeline_layout.material_bindings_count,
.pBindings = pipeline_layout.material_bindings,
};
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &material_set_layout);
@ -1913,11 +1920,11 @@ Material create_material(
num_layouts += 1;
}
if(mesh_set_bindings_count > 0) {
if(pipeline_layout.mesh_bindings_count > 0) {
VkDescriptorSetLayoutCreateInfo layout_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = mesh_set_bindings_count,
.pBindings = mesh_set_bindings,
.bindingCount = pipeline_layout.mesh_bindings_count,
.pBindings = pipeline_layout.mesh_bindings,
};
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &mesh_set_layout);
@ -1929,28 +1936,19 @@ Material create_material(
num_layouts += 1;
}
VkPushConstantRange* all_pcrs = malloc(sizeof(VkPushConstantRange)*(0+pcr_count));
if((all_pcrs == 0) && (pcr_count != 0)) {
return zero_material;
}
for(uint32_t i = 0; i < pcr_count; i++) {
all_pcrs[i] = pcrs[i];
}
VkPipelineLayout pipeline_layout = create_pipeline_layout(device, num_layouts, all_layouts, pcr_count, all_pcrs);
if(pipeline_layout == VK_NULL_HANDLE) {
free(all_pcrs);
VkPipelineLayout layout = create_pipeline_layout(device, num_layouts, all_layouts, 0, 0);
if(layout == VK_NULL_HANDLE) {
return zero_material;
}
VkPipeline pipeline = create_graphics_pipeline(device, extent, pipeline_layout, render_pass, shader_stage_count, shader_stages, vertex_bindings_count, vertex_bindings, attributes_count, attributes);
VkPipeline pipeline = create_graphics_pipeline(device, extent, layout, render_pass, shader_stage_count, shader_stages, mesh_type);
if(pipeline == VK_NULL_HANDLE) {
return zero_material;
}
Material material = {
.pipeline_layout = pipeline_layout,
.layout = layout,
.pipeline = pipeline,
.material_set_layout = material_set_layout,
@ -1976,18 +1974,18 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
VkVertexInputBindingDescription bindings[1] = {
{
.binding = 0,
.stride = sizeof(struct Vertex),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
.binding = 0, // Which buffer 'binding' to use
.stride = sizeof(struct Vertex), // How many bytes to increase the index between instance
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX, // Whether an instance is a vertex or an index
},
};
VkVertexInputAttributeDescription attributes[2] = {
{
.binding = 0,
.location = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(struct Vertex, pos),
.binding = 0, // Which buffer 'binding' to use
.location = 0, // Which 'location' to export as to shader
.format = VK_FORMAT_R32G32B32_SFLOAT, // What format to interpret as for shader
.offset = offsetof(struct Vertex, pos), // What offset from instance start
},
{
.binding = 0,
@ -1997,7 +1995,18 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
},
};
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, 0, 0, 0, 0, 0, 0, 1, bindings, 2, attributes);
MeshType simple_mesh_type = {
.bindings = bindings,
.bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
.attributes = attributes,
.attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
};
PipelineLayout simple_layout = {
};
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, simple_layout, simple_mesh_type);
}
Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout) {
@ -2061,7 +2070,19 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend
},
};
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, 0, 0, 1, mesh_set_bindings, 0, 0, 1, bindings, 3, attributes);
MeshType textured_mesh_type = {
.bindings = bindings,
.bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription),
.attributes = attributes,
.attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
};
PipelineLayout texture_layout = {
.mesh_bindings_count = sizeof(mesh_set_bindings)/sizeof(VkDescriptorSetLayoutBinding),
.mesh_bindings = mesh_set_bindings,
};
return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, texture_layout, textured_mesh_type);
}
VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {