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; VkSampler sampler;
} Texture; } 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 { typedef struct MeshStruct {
uint32_t vertex_count; uint32_t vertex_count;
AllocatedBuffer vertex_buffer; AllocatedBuffer vertex_buffer;
@ -93,7 +111,7 @@ typedef struct MaterialStruct {
VkDescriptorSetLayout material_set_layout; VkDescriptorSetLayout material_set_layout;
VkDescriptorSetLayout mesh_set_layout; VkDescriptorSetLayout mesh_set_layout;
VkPipelineLayout pipeline_layout; VkPipelineLayout layout;
VkPipeline pipeline; VkPipeline pipeline;
} Material; } Material;
@ -1469,10 +1487,7 @@ VkPipeline create_graphics_pipeline(
VkRenderPass render_pass, VkRenderPass render_pass,
uint32_t shader_stage_count, uint32_t shader_stage_count,
VkPipelineShaderStageCreateInfo* shader_stages, VkPipelineShaderStageCreateInfo* shader_stages,
uint32_t bindings_count, MeshType mesh_type
VkVertexInputBindingDescription* bindings,
uint32_t attributes_count,
VkVertexInputAttributeDescription* attributes
) { ) {
VkDynamicState dynamic_states[] = { VkDynamicState dynamic_states[] = {
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_VIEWPORT,
@ -1487,15 +1502,15 @@ VkPipeline create_graphics_pipeline(
VkPipelineVertexInputStateCreateInfo vertex_input_info = {}; VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_input_info.vertexBindingDescriptionCount = bindings_count; vertex_input_info.vertexBindingDescriptionCount = mesh_type.bindings_count;
vertex_input_info.pVertexBindingDescriptions = bindings; vertex_input_info.pVertexBindingDescriptions = mesh_type.bindings;
vertex_input_info.vertexAttributeDescriptionCount = attributes_count; vertex_input_info.vertexAttributeDescriptionCount = mesh_type.attributes_count;
vertex_input_info.pVertexAttributeDescriptions = attributes; vertex_input_info.pVertexAttributeDescriptions = mesh_type.attributes;
VkPipelineInputAssemblyStateCreateInfo input_assemvly_info = {}; VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {};
input_assemvly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
input_assemvly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
input_assemvly_info.primitiveRestartEnable = VK_FALSE; input_assembly_info.primitiveRestartEnable = VK_FALSE;
VkViewport viewport = {}; VkViewport viewport = {};
viewport.x = 0.0f; viewport.x = 0.0f;
@ -1578,7 +1593,7 @@ VkPipeline create_graphics_pipeline(
pipeline_info.stageCount = shader_stage_count; pipeline_info.stageCount = shader_stage_count;
pipeline_info.pStages = shader_stages; pipeline_info.pStages = shader_stages;
pipeline_info.pVertexInputState = &vertex_input_info; 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.pViewportState = &viewport_state;
pipeline_info.pRasterizationState = &raster_info; pipeline_info.pRasterizationState = &raster_info;
pipeline_info.pDepthStencilState = 0; 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) { 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); 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++) { for(uint32_t i = 0; i < mesh_count; i++) {
record_command_buffer_mesh(meshes[i], command_buffer); record_command_buffer_mesh(meshes[i], command_buffer);
} }
@ -1877,16 +1892,8 @@ Material create_material(
uint32_t shader_stage_count, uint32_t shader_stage_count,
VkPipelineShaderStageCreateInfo* shader_stages, VkPipelineShaderStageCreateInfo* shader_stages,
VkDescriptorSetLayout scene_ubo_layout, VkDescriptorSetLayout scene_ubo_layout,
uint32_t material_set_bindings_count, PipelineLayout pipeline_layout,
VkDescriptorSetLayoutBinding* material_set_bindings, MeshType mesh_type
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
) { ) {
Material zero_material = { Material zero_material = {
.pipeline = VK_NULL_HANDLE, .pipeline = VK_NULL_HANDLE,
@ -1897,11 +1904,11 @@ Material create_material(
VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, VK_NULL_HANDLE, VK_NULL_HANDLE}; VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, VK_NULL_HANDLE, VK_NULL_HANDLE};
uint32_t num_layouts = 1; uint32_t num_layouts = 1;
if(material_set_bindings_count > 0) { if(pipeline_layout.material_bindings_count > 0) {
VkDescriptorSetLayoutCreateInfo layout_info = { VkDescriptorSetLayoutCreateInfo layout_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = material_set_bindings_count, .bindingCount = pipeline_layout.material_bindings_count,
.pBindings = material_set_bindings, .pBindings = pipeline_layout.material_bindings,
}; };
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &material_set_layout); VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &material_set_layout);
@ -1913,11 +1920,11 @@ Material create_material(
num_layouts += 1; num_layouts += 1;
} }
if(mesh_set_bindings_count > 0) { if(pipeline_layout.mesh_bindings_count > 0) {
VkDescriptorSetLayoutCreateInfo layout_info = { VkDescriptorSetLayoutCreateInfo layout_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = mesh_set_bindings_count, .bindingCount = pipeline_layout.mesh_bindings_count,
.pBindings = mesh_set_bindings, .pBindings = pipeline_layout.mesh_bindings,
}; };
VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &mesh_set_layout); VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &mesh_set_layout);
@ -1929,28 +1936,19 @@ Material create_material(
num_layouts += 1; 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); VkPipelineLayout layout = create_pipeline_layout(device, num_layouts, all_layouts, 0, 0);
if(pipeline_layout == VK_NULL_HANDLE) { if(layout == VK_NULL_HANDLE) {
free(all_pcrs);
return zero_material; 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) { if(pipeline == VK_NULL_HANDLE) {
return zero_material; return zero_material;
} }
Material material = { Material material = {
.pipeline_layout = pipeline_layout, .layout = layout,
.pipeline = pipeline, .pipeline = pipeline,
.material_set_layout = material_set_layout, .material_set_layout = material_set_layout,
@ -1976,18 +1974,18 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende
VkVertexInputBindingDescription bindings[1] = { VkVertexInputBindingDescription bindings[1] = {
{ {
.binding = 0, .binding = 0, // Which buffer 'binding' to use
.stride = sizeof(struct Vertex), .stride = sizeof(struct Vertex), // How many bytes to increase the index between instance
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX, .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, // Whether an instance is a vertex or an index
}, },
}; };
VkVertexInputAttributeDescription attributes[2] = { VkVertexInputAttributeDescription attributes[2] = {
{ {
.binding = 0, .binding = 0, // Which buffer 'binding' to use
.location = 0, .location = 0, // Which 'location' to export as to shader
.format = VK_FORMAT_R32G32B32_SFLOAT, .format = VK_FORMAT_R32G32B32_SFLOAT, // What format to interpret as for shader
.offset = offsetof(struct Vertex, pos), .offset = offsetof(struct Vertex, pos), // What offset from instance start
}, },
{ {
.binding = 0, .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) { 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) { VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) {