diff --git a/src/main.c b/src/main.c index 4f957b7..62f0f7f 100644 --- a/src/main.c +++ b/src/main.c @@ -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) {