From 91731d933d485996bd81d5a2333b606b2114a8cf Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Sat, 13 Jan 2024 12:32:17 -0700 Subject: [PATCH] Moved from material abstraction to pipeline abstraction, need to implement bindless textures\n --- shader_src/basic.vert | 3 +- shader_src/texture.frag | 4 +- shader_src/texture.vert | 3 +- src/main.c | 806 ++++++++++++++-------------------------- 4 files changed, 289 insertions(+), 527 deletions(-) diff --git a/shader_src/basic.vert b/shader_src/basic.vert index 99bb2b5..4b796d0 100644 --- a/shader_src/basic.vert +++ b/shader_src/basic.vert @@ -3,7 +3,6 @@ layout( push_constant ) uniform constants { mat4 view; mat4 proj; - mat4 model; } scene; layout(set = 0, binding = 0) uniform SceneUniform { @@ -16,6 +15,6 @@ layout(location = 1) in vec3 inColor; layout(location = 0) out vec3 fragColor; void main() { - gl_Position = scene.proj * scene.view * scene.model * vec4(inPosition, 1.0); + gl_Position = scene.proj * scene.view * vec4(inPosition, 1.0); fragColor = inColor; } diff --git a/shader_src/texture.frag b/shader_src/texture.frag index fc83647..3ce44fd 100644 --- a/shader_src/texture.frag +++ b/shader_src/texture.frag @@ -1,12 +1,10 @@ #version 450 -layout(set = 2, binding = 0) uniform sampler2D texSampler; - layout(location = 0) in vec3 fragColor; layout(location = 1) in vec2 fragTex; layout(location = 0) out vec4 outColor; void main() { - outColor = texture(texSampler, fragTex); + outColor = vec4(fragTex, 1.0, 1.0); } diff --git a/shader_src/texture.vert b/shader_src/texture.vert index 90422c9..af59d35 100644 --- a/shader_src/texture.vert +++ b/shader_src/texture.vert @@ -3,7 +3,6 @@ layout( push_constant ) uniform constants { mat4 view; mat4 proj; - mat4 model; } scene_pc; layout(set = 0, binding = 0) uniform SceneUniformBuffer { @@ -18,7 +17,7 @@ layout(location = 0) out vec3 fragColor; layout(location = 1) out vec2 fragTex; void main() { - gl_Position = scene_pc.proj * scene_pc.view * scene_pc.model * vec4(inPosition, 1.0); + gl_Position = scene_pc.proj * scene_pc.view * vec4(inPosition, 1.0); fragColor = inColor; fragTex = inTex; } diff --git a/src/main.c b/src/main.c index b5edbd5..4eb21b3 100644 --- a/src/main.c +++ b/src/main.c @@ -87,7 +87,7 @@ typedef struct MappingStruct { } Mapping; #define ATTRIBUTE_ID_MESH 0x00000001 // Mesh* -#define ATTRIBUTE_ID_MATERIAL 0x00000002 // Material* +#define ATTRIBUTE_ID_PIPELINE 0x00000002 // GraphicsPipeline* #define ATTRIBUTE_ID_DESCRIPTORS 0x00000003 // void***(array of array of data pointers) #define ATTRIBUTE_ID_DESCRIPTOR_SETS 0x00000004 // VkDescriptorSet* #define ATTRIBUTE_ID_POSITION 0x00000005 // Position* @@ -97,27 +97,6 @@ typedef struct ObjectStruct { Map attributes; } Object; -// 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; - -typedef struct PipelineLayoutStruct { - uint32_t object_bindings_count; - VkDescriptorSetLayoutBinding* object_bindings; - - uint32_t material_bindings_count; - VkDescriptorSetLayoutBinding* material_bindings; - - uint32_t object_pcr_size; - uint32_t material_pcr_size; - Mapping object_pcr_mapping; -} PipelineLayout; - typedef struct MeshStruct { uint32_t vertex_count; GPUBuffer vertex_buffer; @@ -126,22 +105,39 @@ typedef struct MeshStruct { GPUBuffer index_buffer; } Mesh; -typedef struct MaterialStruct { - VkDescriptorSetLayout material_set_layout; - VkDescriptorSetLayout object_set_layout; +typedef struct GraphicsPipelineInfoStruct { + uint32_t scene_pcr_size; + uint32_t pipeline_pcr_size; + + VkDescriptorSetLayout scene_layout; + + VkDescriptorSetLayoutBinding* descriptor_bindings; + uint32_t descriptor_bindings_count; - VkPipelineLayout layout; - VkPipeline pipeline; + uint32_t input_bindings_count; + VkVertexInputBindingDescription* input_bindings; - VkDescriptorPool material_descriptor_pool; - VkDescriptorSet* material_descriptors; - uint32_t material_descriptors_count; + uint32_t input_attributes_count; + VkVertexInputAttributeDescription* input_attributes; - Map object_descriptor_mappings; + uint32_t shader_stages_count; + VkPipelineShaderStageCreateInfo* shader_stages; +} GraphicsPipelineInfo; - PipelineLayout pipeline_layout; - void* material_pcr_ptr; -} Material; +typedef struct GraphicsPipelineStruct { + uint32_t max_frames_in_flight; + + VkDescriptorPool descriptor_pool; + VkDescriptorSet* descriptors; + VkDescriptorSetLayout descriptors_layout; + + uint32_t pcr_size; + uint32_t pcr_offset; + void** pcr_ptrs; + + VkPipelineLayout layout; + VkPipeline pipeline; +} GraphicsPipeline; typedef struct VulkanContextStruct { VkInstance instance; @@ -303,35 +299,6 @@ GLFWwindow* init_window(int width, int height) { return window; } -void object_update_mappings(Material material, Object object, uint32_t frame_num) { - if(material.object_descriptor_mappings.buckets == 0) { - return; - } - - MaybeValue maybe_descriptors = map_lookup(object.attributes, ATTRIBUTE_ID_DESCRIPTORS); - if(maybe_descriptors.has_value == false) { - return; - } - - void** descriptors = ((void***)(maybe_descriptors.value))[frame_num]; - - MapIterator mapping_iterator = map_iterator_create(material.object_descriptor_mappings); - for(uint32_t i = 0; i < mapping_iterator.count; i++) { - MaybeValue maybe_attribute = map_lookup(object.attributes, mapping_iterator.keys[i]); - if(maybe_attribute.has_value == true) { - Mapping* mapping = mapping_iterator.vals[i]; - if(mapping->mapping_type > sizeof(mapping_functions)/sizeof(MappingFunc)) { - fprintf(stderr, "material requested mapping_function 0x%02x which does not exist\n", mapping->mapping_type); - continue; - } - mapping_functions[mapping->mapping_type](descriptors[mapping->index], maybe_attribute.value); - } else { - fprintf(stderr, "material requested attribute 0x%02x from object, but it does not have it\n", mapping_iterator.keys[i]); - } - } - map_iterator_free(mapping_iterator); -} - VkSemaphore* create_semaphores(VkDevice device, VkSemaphoreCreateFlags flags, uint32_t count) { VkSemaphore* semaphores = malloc(sizeof(VkSemaphore)*count); if(semaphores == 0) { @@ -1245,154 +1212,6 @@ Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkComman return ret; } -VkPipeline create_graphics_pipeline( - VkDevice device, - VkExtent2D extent, - VkPipelineLayout layout, - VkRenderPass render_pass, - uint32_t shader_stage_count, - VkPipelineShaderStageCreateInfo* shader_stages, - MeshType mesh_type - ) { - VkDynamicState dynamic_states[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }; - uint32_t dynamic_state_count = sizeof(dynamic_states)/sizeof(VkDynamicState); - - VkPipelineDynamicStateCreateInfo dynamic_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = dynamic_state_count, - .pDynamicStates = dynamic_states, - }; - - VkPipelineVertexInputStateCreateInfo vertex_input_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = mesh_type.bindings_count, - .pVertexBindingDescriptions = mesh_type.bindings, - .vertexAttributeDescriptionCount = mesh_type.attributes_count, - .pVertexAttributeDescriptions = mesh_type.attributes, - }; - - VkPipelineInputAssemblyStateCreateInfo input_assembly_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - .primitiveRestartEnable = VK_FALSE, - }; - - VkViewport viewport = { - .x = 0.0f, - .y = 0.0f, - .width = (float)(extent.width), - .height = (float)(extent.height), - .minDepth = 0.0f, - .maxDepth = 1.0f, - }; - - VkRect2D scissor = { - .offset = { - .x = 0, - .y = 0, - }, - .extent = extent, - }; - - VkPipelineViewportStateCreateInfo viewport_state = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, - .pViewports = &viewport, - .scissorCount = 1, - .pScissors = &scissor, - }; - - VkPipelineRasterizationStateCreateInfo raster_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .depthClampEnable = VK_FALSE, - .rasterizerDiscardEnable = VK_FALSE, - .polygonMode = VK_POLYGON_MODE_FILL, - .lineWidth = 1.0f, - .cullMode = VK_CULL_MODE_BACK_BIT, - .frontFace = VK_FRONT_FACE_CLOCKWISE, - .depthBiasEnable = VK_FALSE, - .depthBiasConstantFactor = 0.0f, - .depthBiasClamp = 0.0f, - .depthBiasSlopeFactor = 0.0f, - }; - - VkPipelineMultisampleStateCreateInfo multisample_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .sampleShadingEnable = VK_FALSE, - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, - .minSampleShading = 1.0f, - .pSampleMask = 0, - .alphaToCoverageEnable = VK_FALSE, - .alphaToOneEnable = VK_FALSE, - }; - - VkPipelineDepthStencilStateCreateInfo depth_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_TRUE, - .depthWriteEnable = VK_TRUE, - .depthCompareOp = VK_COMPARE_OP_LESS, - .depthBoundsTestEnable = VK_FALSE, - .maxDepthBounds = 1.0f, - .minDepthBounds = 0.0f, - .stencilTestEnable = VK_FALSE, - .front = {}, - .back = {}, - }; - - VkPipelineColorBlendAttachmentState color_blend_attachment = { - .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - .blendEnable = VK_TRUE, - .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, - .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, - .alphaBlendOp = VK_BLEND_OP_ADD, - }; - - VkPipelineColorBlendStateCreateInfo color_blend_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .logicOpEnable = VK_FALSE, - .logicOp = VK_LOGIC_OP_COPY, - .attachmentCount = 1, - .pAttachments = &color_blend_attachment, - .blendConstants[0] = 0.0f, - .blendConstants[1] = 0.0f, - .blendConstants[2] = 0.0f, - .blendConstants[3] = 0.0f, - }; - - VkGraphicsPipelineCreateInfo pipeline_info = { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .stageCount = shader_stage_count, - .pStages = shader_stages, - .pVertexInputState = &vertex_input_info, - .pInputAssemblyState = &input_assembly_info, - .pViewportState = &viewport_state, - .pRasterizationState = &raster_info, - .pColorBlendState = &color_blend_info, - .pDynamicState = &dynamic_info, - .pDepthStencilState = &depth_info, - .pMultisampleState = &multisample_info, - .layout = layout, - .renderPass = render_pass, - .subpass = 0, - .basePipelineHandle = VK_NULL_HANDLE, - .basePipelineIndex = -1, - }; - - VkPipeline pipeline; - VkResult result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_info, 0, &pipeline); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - return pipeline; -} - int create_depth_image(VulkanContext* context) { VkExtent3D depth_extent = { .width = context->swapchain_extent.width, @@ -1557,43 +1376,14 @@ VkResult recreate_swapchain(VulkanContext* context) { return VK_SUCCESS; } -void command_draw_object(Material material, Object object, uint32_t frame_num, VkCommandBuffer command_buffer) { +void command_draw_object(Object object, VkCommandBuffer command_buffer) { MaybeValue maybe_mesh = map_lookup(object.attributes, ATTRIBUTE_ID_MESH); if(maybe_mesh.has_value == false) { return; } - object_update_mappings(material, object, frame_num); - Mesh* mesh = maybe_mesh.value; - if(material.pipeline_layout.object_pcr_size > 0) { - MaybeValue maybe_attribute = map_lookup(object.attributes, material.pipeline_layout.object_pcr_mapping.index); - if(maybe_attribute.has_value == false) { - return; - } - - MaybeValue maybe_pc = map_lookup(object.attributes, ATTRIBUTE_ID_PUSH_CONSTANTS); - if(maybe_pc.has_value == false) { - return; - } - - void** pc_ptrs = maybe_pc.value; - - mapping_functions[material.pipeline_layout.object_pcr_mapping.mapping_type](pc_ptrs[frame_num], maybe_attribute.value); - vkCmdPushConstants(command_buffer, material.layout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(struct ScenePC) + material.pipeline_layout.material_pcr_size, material.pipeline_layout.object_pcr_size, pc_ptrs[frame_num]); - } - - if(material.object_set_layout != VK_NULL_HANDLE) { - MaybeValue maybe_descriptors = map_lookup(object.attributes, ATTRIBUTE_ID_DESCRIPTOR_SETS); - if(maybe_descriptors.has_value == false) { - return; - } - - VkDescriptorSet* descriptor_sets = maybe_descriptors.value; - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 2, 1, &descriptor_sets[frame_num], 0, 0); - } - VkBuffer vertex_buffers[] = {mesh->vertex_buffer.handle}; VkDeviceSize offsets[] = {0}; @@ -1603,24 +1393,24 @@ void command_draw_object(Material material, Object object, uint32_t frame_num, V vkCmdDrawIndexed(command_buffer, mesh->index_count, 1, 0, 0, 0); } -void command_draw_material(Material material, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer) { - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline); - vkCmdPushConstants(command_buffer, material.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(struct ScenePC), scene_constants); +void command_draw_pipeline(GraphicsPipeline pipeline, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer) { + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline); + vkCmdPushConstants(command_buffer, pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, pipeline.pcr_offset, scene_constants); - if(material.material_pcr_ptr != NULL && material.pipeline_layout.material_pcr_size > 0) { - vkCmdPushConstants(command_buffer, material.material_pcr_ptr, VK_SHADER_STAGE_VERTEX_BIT, sizeof(struct ScenePC), material.pipeline_layout.material_pcr_size, material.material_pcr_ptr); + if(pipeline.pcr_ptrs != NULL && pipeline.pcr_size > 0) { + vkCmdPushConstants(command_buffer, pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, pipeline.pcr_offset, pipeline.pcr_size, pipeline.pcr_ptrs[frame_num]); } - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_descriptors[frame_num], 0, 0); - if(material.material_descriptors != 0) { - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 1, 1, &material.material_descriptors[frame_num], 0, 0); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &scene_descriptors[frame_num], 0, 0); + if(pipeline.descriptors != NULL) { + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 1, 1, &pipeline.descriptors[frame_num], 0, 0); } for(uint32_t i = 0; i < object_count; i++) { - command_draw_object(material, objects[i], frame_num, command_buffer); + command_draw_object(objects[i], command_buffer); } } -VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { +VkResult command_draw_scene(uint32_t pipelines_count, GraphicsPipeline* pipelines, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, struct ScenePC* scene_constants, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { VkCommandBufferBeginInfo begin_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = 0, @@ -1679,8 +1469,8 @@ VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint3 }; vkCmdSetScissor(command_buffer, 0, 1, &scissor); - for(uint i = 0; i < materials_count; i++) { - command_draw_material(materials[i], object_counts[i], objects[i], frame_num, scene_descriptors, scene_constants, command_buffer); + for(uint i = 0; i < pipelines_count; i++) { + command_draw_pipeline(pipelines[i], object_counts[i], objects[i], frame_num, scene_descriptors, scene_constants, command_buffer); } vkCmdEndRenderPass(command_buffer); @@ -1730,7 +1520,7 @@ VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count return fences; } -Object create_object(uint32_t max_frames_in_flight, uint32_t descriptor_count) { +Object create_object() { Object ret = { .attributes = { .buckets = 0, @@ -1742,60 +1532,24 @@ Object create_object(uint32_t max_frames_in_flight, uint32_t descriptor_count) { return ret; } - if(descriptor_count > 0) { - void*** descriptor_arrays = malloc(sizeof(void**)*max_frames_in_flight); - if(descriptor_arrays == 0) { - return ret; - } - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - descriptor_arrays[i] = malloc(sizeof(void*)*descriptor_count); - - if(descriptor_arrays[i] == 0) { - for(uint32_t j = 0; j < i; j++) { - free(descriptor_arrays[j]); - } - free(descriptor_arrays); - map_destroy(attributes); - } - } - - bool result = map_add(&attributes, ATTRIBUTE_ID_DESCRIPTORS, descriptor_arrays); - if(result == false) { - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - free(descriptor_arrays[i]); - } - free(descriptor_arrays); - map_destroy(attributes); - } - } - ret.attributes = attributes; return ret; } -Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_sets_count, VkDescriptorSet* descriptor_sets, uint32_t pc_size, uint32_t max_frames_in_flight) { +Object create_renderable(Mesh* mesh, GraphicsPipeline* pipeline) { Object zero = { .attributes = { .buckets = 0, }, }; - void** pc_ptrs = malloc(sizeof(void*)*max_frames_in_flight); - if(pc_ptrs == NULL) { - return zero; - } - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - pc_ptrs[i] = malloc(pc_size); - } - - Object object = create_object(max_frames_in_flight, descriptor_sets_count); + Object object = create_object(); if(object.attributes.buckets == 0) { return zero; } - if(mesh == 0 || material == 0) { + if(mesh == 0 || pipeline == 0) { return zero; } @@ -1805,19 +1559,7 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set return zero; } - result = map_add(&object.attributes, ATTRIBUTE_ID_MATERIAL, material); - if(result == false) { - map_destroy(object.attributes); - return zero; - } - - result = map_add(&object.attributes, ATTRIBUTE_ID_DESCRIPTOR_SETS, descriptor_sets); - if(result == false) { - map_destroy(object.attributes); - return zero; - } - - result = map_add(&object.attributes, ATTRIBUTE_ID_PUSH_CONSTANTS, pc_ptrs); + result = map_add(&object.attributes, ATTRIBUTE_ID_PIPELINE, pipeline); if(result == false) { map_destroy(object.attributes); return zero; @@ -1826,153 +1568,272 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set return object; } -Material create_material( +VkResult create_graphics_pipeline( VkDevice device, VkExtent2D extent, VkRenderPass render_pass, - uint32_t shader_stage_count, - VkPipelineShaderStageCreateInfo* shader_stages, - VkDescriptorSetLayout scene_ubo_layout, - uint32_t scene_pcr_size, - PipelineLayout pipeline_layout, - MeshType mesh_type, + GraphicsPipelineInfo pipeline_info, uint32_t max_frames_in_flight, - Map object_descriptor_mappings + GraphicsPipeline* out ) { - Material zero_material = { - .pipeline = VK_NULL_HANDLE, - }; - VkDescriptorSetLayout material_set_layout; - VkDescriptorSetLayout object_set_layout; + if(out == NULL) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } - VkDescriptorPool material_descriptor_pool = VK_NULL_HANDLE; - VkDescriptorSet* material_descriptors = 0; + out->max_frames_in_flight = max_frames_in_flight; + out->pcr_size = pipeline_info.pipeline_pcr_size; + out->pcr_offset = pipeline_info.scene_pcr_size; - VkDescriptorSetLayoutCreateInfo material_layout_info = { + VkDescriptorSetLayoutCreateInfo descriptor_layout_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = pipeline_layout.material_bindings_count, - .pBindings = pipeline_layout.material_bindings, + .bindingCount = pipeline_info.descriptor_bindings_count, + .pBindings = pipeline_info.descriptor_bindings, }; - VkResult result = vkCreateDescriptorSetLayout(device, &material_layout_info, 0, &material_set_layout); + VkResult result = vkCreateDescriptorSetLayout(device, &descriptor_layout_info, 0, &out->descriptors_layout); if(result != VK_SUCCESS) { - return zero_material; + return result; } - if(pipeline_layout.material_bindings_count > 0) { - material_descriptors = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); - if(material_descriptors == 0) { - return zero_material; + if(pipeline_info.pipeline_pcr_size > 0) { + out->pcr_ptrs = malloc(sizeof(void**)*max_frames_in_flight); + if(out->pcr_ptrs == NULL) { + return VK_ERROR_OUT_OF_HOST_MEMORY; } + for(uint32_t i = 0; i < max_frames_in_flight; i++) { + out->pcr_ptrs[i] = malloc(pipeline_info.pipeline_pcr_size); + if(out->pcr_ptrs[i] == NULL) { + for(uint32_t j = 0; j < i; j++) { + free(out->pcr_ptrs[j]); + } + free(out->pcr_ptrs); + } + } + } - VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*pipeline_layout.material_bindings_count); + if(pipeline_info.descriptor_bindings_count > 0) { + out->descriptors = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); + if(out->descriptors == 0) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*pipeline_info.descriptor_bindings_count); if(pool_sizes == 0) { - return zero_material; + return VK_ERROR_OUT_OF_HOST_MEMORY; } - for(uint32_t i = 0; i < pipeline_layout.material_bindings_count; i++) { + for(uint32_t i = 0; i < pipeline_info.descriptor_bindings_count; i++) { VkDescriptorPoolSize pool_size = { - .type = pipeline_layout.material_bindings[i].descriptorType, - .descriptorCount = pipeline_layout.material_bindings[i].descriptorCount, + .type = pipeline_info.descriptor_bindings[i].descriptorType, + .descriptorCount = pipeline_info.descriptor_bindings[i].descriptorCount * max_frames_in_flight, }; pool_sizes[i] = pool_size; } VkDescriptorPoolCreateInfo pool_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .poolSizeCount = pipeline_layout.material_bindings_count, + .poolSizeCount = pipeline_info.descriptor_bindings_count, .maxSets = max_frames_in_flight, .pPoolSizes = pool_sizes, }; - result = vkCreateDescriptorPool(device, &pool_info, 0, &material_descriptor_pool); + result = vkCreateDescriptorPool(device, &pool_info, 0, &out->descriptor_pool); free(pool_sizes); if(result != VK_SUCCESS) { - return zero_material; + return result; } VkDescriptorSetLayout* set_layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); if(set_layouts == 0) { - vkDestroyDescriptorPool(device, material_descriptor_pool, 0); - return zero_material; + vkDestroyDescriptorPool(device, out->descriptor_pool, 0); + return VK_ERROR_OUT_OF_HOST_MEMORY; } for(uint32_t i = 0; i < max_frames_in_flight; i++) { - set_layouts[i] = material_set_layout; + set_layouts[i] = out->descriptors_layout; } VkDescriptorSetAllocateInfo alloc_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .descriptorSetCount = max_frames_in_flight, - .descriptorPool = material_descriptor_pool, + .descriptorPool = out->descriptor_pool, .pSetLayouts = set_layouts, }; - result = vkAllocateDescriptorSets(device, &alloc_info, material_descriptors); + result = vkAllocateDescriptorSets(device, &alloc_info, out->descriptors); free(set_layouts); if(result != VK_SUCCESS) { - vkDestroyDescriptorPool(device, material_descriptor_pool, 0); - return zero_material; + vkDestroyDescriptorPool(device, out->descriptor_pool, 0); + return result; } } - VkDescriptorSetLayoutCreateInfo mesh_layout_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = pipeline_layout.object_bindings_count, - .pBindings = pipeline_layout.object_bindings, - }; - - result = vkCreateDescriptorSetLayout(device, &mesh_layout_info, 0, &object_set_layout); - if(result != VK_SUCCESS) { - return zero_material; - } - VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, material_set_layout, object_set_layout}; + VkDescriptorSetLayout all_layouts[2] = {pipeline_info.scene_layout, out->descriptors_layout}; VkPushConstantRange pcr = { .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .offset = 0, - .size = scene_pcr_size + pipeline_layout.material_pcr_size + pipeline_layout.object_pcr_size, + .size = pipeline_info.scene_pcr_size + pipeline_info.pipeline_pcr_size, }; - VkPipelineLayout layout; VkPipelineLayoutCreateInfo layout_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 3, + .setLayoutCount = 2, .pSetLayouts = all_layouts, .pushConstantRangeCount = 1, .pPushConstantRanges = &pcr, }; - result = vkCreatePipelineLayout(device, &layout_info, 0, &layout); + result = vkCreatePipelineLayout(device, &layout_info, 0, &out->layout); if(result != VK_SUCCESS) { - return zero_material; + return result; } - 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; - } + VkDynamicState dynamic_states[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + + uint32_t dynamic_state_count = sizeof(dynamic_states)/sizeof(VkDynamicState); + + VkPipelineDynamicStateCreateInfo dynamic_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = dynamic_state_count, + .pDynamicStates = dynamic_states, + }; + + VkPipelineVertexInputStateCreateInfo vertex_input_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = pipeline_info.input_bindings_count, + .pVertexBindingDescriptions = pipeline_info.input_bindings, + .vertexAttributeDescriptionCount = pipeline_info.input_attributes_count, + .pVertexAttributeDescriptions = pipeline_info.input_attributes, + }; + + VkPipelineInputAssemblyStateCreateInfo input_assembly_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, + }; - Material material = { - .layout = layout, - .pipeline = pipeline, + VkViewport viewport = { + .x = 0.0f, + .y = 0.0f, + .width = (float)(extent.width), + .height = (float)(extent.height), + .minDepth = 0.0f, + .maxDepth = 1.0f, + }; - .material_set_layout = material_set_layout, - .object_set_layout = object_set_layout, + VkRect2D scissor = { + .offset = { + .x = 0, + .y = 0, + }, + .extent = extent, + }; - .material_descriptors = material_descriptors, - .material_descriptor_pool = material_descriptor_pool, - .material_descriptors_count = max_frames_in_flight, - .object_descriptor_mappings = object_descriptor_mappings, + VkPipelineViewportStateCreateInfo viewport_state = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1, + .pViewports = &viewport, + .scissorCount = 1, + .pScissors = &scissor, + }; + + VkPipelineRasterizationStateCreateInfo raster_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .depthClampEnable = VK_FALSE, + .rasterizerDiscardEnable = VK_FALSE, + .polygonMode = VK_POLYGON_MODE_FILL, + .lineWidth = 1.0f, + .cullMode = VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .depthBiasEnable = VK_FALSE, + .depthBiasConstantFactor = 0.0f, + .depthBiasClamp = 0.0f, + .depthBiasSlopeFactor = 0.0f, + }; + + VkPipelineMultisampleStateCreateInfo multisample_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .sampleShadingEnable = VK_FALSE, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + .minSampleShading = 1.0f, + .pSampleMask = 0, + .alphaToCoverageEnable = VK_FALSE, + .alphaToOneEnable = VK_FALSE, + }; + + VkPipelineDepthStencilStateCreateInfo depth_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = VK_TRUE, + .depthWriteEnable = VK_TRUE, + .depthCompareOp = VK_COMPARE_OP_LESS, + .depthBoundsTestEnable = VK_FALSE, + .maxDepthBounds = 1.0f, + .minDepthBounds = 0.0f, + .stencilTestEnable = VK_FALSE, + .front = {}, + .back = {}, + }; + + VkPipelineColorBlendAttachmentState color_blend_attachment = { + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + .blendEnable = VK_TRUE, + .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, + .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, + .alphaBlendOp = VK_BLEND_OP_ADD, + }; + + VkPipelineColorBlendStateCreateInfo color_blend_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .logicOpEnable = VK_FALSE, + .logicOp = VK_LOGIC_OP_COPY, + .attachmentCount = 1, + .pAttachments = &color_blend_attachment, + .blendConstants[0] = 0.0f, + .blendConstants[1] = 0.0f, + .blendConstants[2] = 0.0f, + .blendConstants[3] = 0.0f, + }; - .pipeline_layout = pipeline_layout, + VkGraphicsPipelineCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .stageCount = pipeline_info.shader_stages_count, + .pStages = pipeline_info.shader_stages, + .pVertexInputState = &vertex_input_info, + .pInputAssemblyState = &input_assembly_info, + .pViewportState = &viewport_state, + .pRasterizationState = &raster_info, + .pColorBlendState = &color_blend_info, + .pDynamicState = &dynamic_info, + .pDepthStencilState = &depth_info, + .pMultisampleState = &multisample_info, + .layout = out->layout, + .renderPass = render_pass, + .subpass = 0, + .basePipelineHandle = VK_NULL_HANDLE, + .basePipelineIndex = -1, }; - return material; + result = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &info, 0, &out->pipeline); + if(result != VK_SUCCESS) { + return result; + } + + return VK_SUCCESS; } -Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t scene_pcr_size, uint32_t max_frames_in_flight) { +VkResult create_simple_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t scene_pcr_size, uint32_t max_frames_in_flight, GraphicsPipeline* out) { + if(out == NULL) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + VkShaderModule vert_shader = load_shader_file("shader_src/basic.vert.spv", device); VkShaderModule frag_shader = load_shader_file("shader_src/basic.frag.spv", device); VkPipelineShaderStageCreateInfo shader_stages[2] = { @@ -2013,26 +1874,25 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende }, }; - MeshType simple_mesh_type = { - .bindings = bindings, - .bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), - .attributes = attributes, - .attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), - }; - - PipelineLayout simple_layout = { - .object_pcr_size = sizeof(struct ObjectPC), - .object_pcr_mapping = { - .mapping_type = MAPPING_POSITION_TO_MATRIX, - .index = ATTRIBUTE_ID_POSITION, - }, + GraphicsPipelineInfo pipeline_info = { + .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), + .shader_stages = shader_stages, + .scene_pcr_size = scene_pcr_size, + .scene_layout = scene_layout, + .input_bindings = bindings, + .input_bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), + .input_attributes = attributes, + .input_attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), }; - Map object_descriptor_mappings = {0}; - return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, scene_pcr_size, simple_layout, simple_mesh_type, max_frames_in_flight, object_descriptor_mappings); + return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out); } -Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t scene_pcr_size, uint32_t max_frames_in_flight) { +VkResult create_texture_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t scene_pcr_size, uint32_t max_frames_in_flight, GraphicsPipeline* out) { + if(out == NULL) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + VkShaderModule vert_shader = load_shader_file("shader_src/texture.vert.spv", device); VkShaderModule frag_shader = load_shader_file("shader_src/texture.frag.spv", device); VkPipelineShaderStageCreateInfo shader_stages[2] = { @@ -2080,6 +1940,7 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend }, }; + // TODO: use bindless descriptors for textures, so each draw command will bind a large buffer that is indexed by object ID to get the address of the texture in GPU memory VkDescriptorSetLayoutBinding mesh_set_bindings[] = { { .binding = 0, @@ -2089,27 +1950,20 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, }, }; + (void)mesh_set_bindings; - MeshType textured_mesh_type = { - .bindings = bindings, - .bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), - .attributes = attributes, - .attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), - }; - - PipelineLayout texture_layout = { - .object_bindings_count = sizeof(mesh_set_bindings)/sizeof(VkDescriptorSetLayoutBinding), - .object_bindings = mesh_set_bindings, - - .object_pcr_size = sizeof(struct ObjectPC), - .object_pcr_mapping = { - .mapping_type = MAPPING_POSITION_TO_MATRIX, - .index = ATTRIBUTE_ID_POSITION, - }, + GraphicsPipelineInfo pipeline_info = { + .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), + .shader_stages = shader_stages, + .scene_pcr_size = scene_pcr_size, + .scene_layout = scene_layout, + .input_bindings = bindings, + .input_bindings_count = sizeof(bindings)/sizeof(VkVertexInputBindingDescription), + .input_attributes = attributes, + .input_attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), }; - Map object_descriptor_mappings = {0}; - return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, scene_pcr_size, texture_layout, textured_mesh_type, max_frames_in_flight, object_descriptor_mappings); + return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out); } VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, VkQueue queue) { @@ -2779,7 +2633,7 @@ struct ScenePC get_scene_constants(vec3 world_position, versor world_rotation, f return constants; } -VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, Material* materials, uint32_t* objects_counts, Object** objects) { +VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, GraphicsPipeline* pipelines, uint32_t* objects_counts, Object** objects) { struct ScenePC scene_constants = get_scene_constants(world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01); VkResult result; @@ -2804,7 +2658,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi return result; } - result = command_draw_scene(materials_count, materials, objects_counts, objects, context->current_frame, scene->descriptors, &scene_constants, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); + result = command_draw_scene(materials_count, pipelines, objects_counts, objects, context->current_frame, scene->descriptors, &scene_constants, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); if(result != VK_SUCCESS) { return result; } @@ -2839,7 +2693,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi return vkQueuePresentKHR(context->queues.present, &present_info); } -Object create_simple_mesh_object(PlyMesh ply_mesh, Material* simple_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) { +Object create_simple_mesh_object(PlyMesh ply_mesh, GraphicsPipeline* simple_mesh_pipeline, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue) { Object zero = {}; GPUPage* mesh_memory = NULL; @@ -2875,33 +2729,7 @@ Object create_simple_mesh_object(PlyMesh ply_mesh, Material* simple_mesh_materia return zero; } - VkDescriptorSetLayout* layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); - if(layouts == 0) { - return zero; - } - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - layouts[i] = simple_mesh_material->object_set_layout; - } - - VkDescriptorSetAllocateInfo allocation_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pSetLayouts = layouts, - .descriptorSetCount = max_frames_in_flight, - .descriptorPool = pool, - }; - - VkDescriptorSet* sets = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); - if(sets == 0) { - return zero; - } - - result = vkAllocateDescriptorSets(device, &allocation_info, sets); - if(result != VK_SUCCESS) { - return zero; - } - - Object object = create_renderable(mesh, simple_mesh_material, 1, sets, sizeof(struct ObjectPC), max_frames_in_flight); + Object object = create_renderable(mesh, simple_mesh_pipeline); if(object.attributes.buckets == 0) { return zero; } @@ -2925,7 +2753,7 @@ Object create_simple_mesh_object(PlyMesh ply_mesh, Material* simple_mesh_materia return object; } -Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool, uint32_t transfer_family, uint32_t graphics_family) { +Object create_texture_mesh_object(GraphicsPipeline* texture_mesh_pipeline, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue) { Object zero = {}; GPUPage* mesh_memory = NULL; @@ -2951,33 +2779,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev return zero; } - VkDescriptorSetLayout* layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); - if(layouts == 0) { - return zero; - } - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - layouts[i] = texture_mesh_material->object_set_layout; - } - - VkDescriptorSetAllocateInfo allocation_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = pool, - .descriptorSetCount = max_frames_in_flight, - .pSetLayouts = layouts, - }; - - VkDescriptorSet* sets = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); - if(sets == 0) { - return zero; - } - - result = vkAllocateDescriptorSets(device, &allocation_info, sets); - if(result != VK_SUCCESS) { - return zero; - } - - Object object = create_renderable(mesh, texture_mesh_material, 1, sets, sizeof(struct ObjectPC), max_frames_in_flight); + Object object = create_renderable(mesh, texture_mesh_pipeline); if(object.attributes.buckets == 0) { return zero; } @@ -3002,6 +2804,8 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev .width = 10, .height = 10, }; + (void)texture_size; + struct __attribute__((__packed__)) texel { uint8_t r; uint8_t g; @@ -3027,7 +2831,9 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, }; + (void)texture_data; + /* Texture test_texture = load_texture(device, mesh_memory, transfer_buffer, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family); for(uint32_t i = 0; i < max_frames_in_flight; i++) { @@ -3050,7 +2856,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev }; vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); - } + }*/ // TODO: bindless textures return object; } @@ -3061,81 +2867,41 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) { return; } - Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr_size, context->max_frames_in_flight); - if(simple_mesh_material.pipeline == VK_NULL_HANDLE) { - fprintf(stderr, "failed to create simple mesh material\n"); - return; - } - - VkDescriptorPoolSize simple_pool_sizes[] = { - { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = context->max_frames_in_flight, - }, - }; - - VkDescriptorPoolCreateInfo simple_pool_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .poolSizeCount = 1, - .pPoolSizes = simple_pool_sizes, - .maxSets = context->max_frames_in_flight, - }; - - VkDescriptorPool simple_pool; - VkResult result = vkCreateDescriptorPool(context->device, &simple_pool_info, 0, &simple_pool); + GraphicsPipeline simple_mesh_pipeline = {0}; + GraphicsPipeline texture_mesh_pipeline = {0}; + VkResult result = create_simple_mesh_pipeline(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr_size, context->max_frames_in_flight, &simple_mesh_pipeline); if(result != VK_SUCCESS) { - fprintf(stderr, "failed to allocate simple_pool\n"); + fprintf(stderr, "failed to create simple mesh material\n"); return; } - Object triangle_object = create_simple_mesh_object(ply_mesh, &simple_mesh_material, context->memories, context->device, context->transfer_command_pool, context->queues.transfer, context->max_frames_in_flight, simple_pool); + Object triangle_object = create_simple_mesh_object(ply_mesh, &simple_mesh_pipeline, context->memories, context->device, context->transfer_command_pool, context->queues.transfer); if(triangle_object.attributes.buckets == 0) { fprintf(stderr, "failed to create simple mesh object\n"); return; } - Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr_size, context->max_frames_in_flight); - if(texture_mesh_material.pipeline == VK_NULL_HANDLE) { - fprintf(stderr, "failed to create texture mesh material\n"); - return; - } - - VkDescriptorPoolSize texture_pool_sizes[] = { - { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = context->max_frames_in_flight, - }, - }; - - VkDescriptorPoolCreateInfo texture_pool_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .poolSizeCount = sizeof(texture_pool_sizes)/sizeof(VkDescriptorPoolSize), - .maxSets = context->max_frames_in_flight, - .pPoolSizes = texture_pool_sizes, - }; - - VkDescriptorPool texture_pool; - result = vkCreateDescriptorPool(context->device, &texture_pool_info, 0, &texture_pool); + result = create_texture_mesh_pipeline(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, scene.pcr_size, context->max_frames_in_flight, &texture_mesh_pipeline); if(result != VK_SUCCESS) { - fprintf(stderr, "failed to create temporary descriptor pool\n"); + fprintf(stderr, "failed to create texture mesh material\n"); return; } - Object triangle_object_textured = create_texture_mesh_object(&texture_mesh_material, context->memories, context->device, context->transfer_command_pool, context->queues.transfer, context->extra_graphics_pool, context->queues.graphics, context->max_frames_in_flight, texture_pool, context->queue_indices.transfer_family, context->queue_indices.graphics_family); + Object triangle_object_textured = create_texture_mesh_object(&texture_mesh_pipeline, context->memories, context->device, context->transfer_command_pool, context->queues.transfer); if(triangle_object_textured.attributes.buckets == 0) { fprintf(stderr, "failed to create texture mesh object\n"); return; } Object* objects[] = {&triangle_object, &triangle_object_textured}; - Material materials[] = {simple_mesh_material, texture_mesh_material}; + GraphicsPipeline pipelines[] = {simple_mesh_pipeline, texture_mesh_pipeline}; uint32_t objects_counts[] = {1, 1}; context->current_frame = 0; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); - VkResult result = draw_frame(context, &scene, sizeof(materials)/sizeof(Material), materials, objects_counts, objects); + VkResult result = draw_frame(context, &scene, sizeof(pipelines)/sizeof(GraphicsPipeline), pipelines, objects_counts, objects); if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { vkDeviceWaitIdle(context->device); recreate_swapchain(context);