From c24d3f4f27442fb4c65e5eca0624b2aff748bce4 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Sat, 4 Oct 2025 00:25:40 +0100 Subject: [PATCH] Move some things around to prepare for multiple pipelines --- CMakeLists.txt | 15 +- frag.glsl => default-frag.glsl | 0 gpu.c | 338 ++++++++++++++++----------------- gpu.h | 6 +- vert.glsl => model-vert.glsl | 0 5 files changed, 180 insertions(+), 179 deletions(-) rename frag.glsl => default-frag.glsl (100%) rename vert.glsl => model-vert.glsl (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ed0d07..1ac1716 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,9 @@ find_program(glslc glslc) function(add_shaders target) set(bin_dir "${CMAKE_CURRENT_BINARY_DIR}/${target}") foreach(src ${ARGN}) - get_filename_component(stage ${src} NAME_WLE) - set(bin "${bin_dir}/${stage}.spv") + get_filename_component(name ${src} NAME_WLE) + string(REGEX MATCH "(vert|frag)$" stage "${name}") + set(bin "${bin_dir}/${name}.spv") list(APPEND bins ${bin}) add_custom_command( OUTPUT ${bin} @@ -25,16 +26,16 @@ function(add_shaders target) endforeach() add_custom_target(${target}-spirv DEPENDS ${bins}) add_library(${target} INTERFACE) - target_compile_definitions(${target} INTERFACE - VERT_SHADER_SPV="${bin_dir}/vert.spv" - FRAG_SHADER_SPV="${bin_dir}/frag.spv") add_dependencies(${target} ${target}-spirv) endfunction() add_shaders(shaders - vert.glsl - frag.glsl + model-vert.glsl + default-frag.glsl ) +target_compile_definitions(shaders INTERFACE + MODEL_VERT_SHADER_SPV="${CMAKE_CURRENT_BINARY_DIR}/shaders/model-vert.spv" + FRAG_SHADER_SPV="${CMAKE_CURRENT_BINARY_DIR}/shaders/default-frag.spv") add_executable(demo animation.c diff --git a/frag.glsl b/default-frag.glsl similarity index 100% rename from frag.glsl rename to default-frag.glsl diff --git a/gpu.c b/gpu.c index b274299..abce301 100644 --- a/gpu.c +++ b/gpu.c @@ -27,7 +27,7 @@ static const char *extensions[] = { static constexpr size_t extension_count = NELEMS(extensions); static const char vert_shader[] = { -#embed VERT_SHADER_SPV +#embed MODEL_VERT_SHADER_SPV }; static const char frag_shader[] = { @@ -387,111 +387,6 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name) ctx->dev, &depth_img_view_config, nullptr, &ctx->depth_img_view); assert(result == VK_SUCCESS); - // Load vertex and fragment shader modules - ctx->vert_shader - = load_shader_module(ctx->dev, vert_shader, sizeof(vert_shader)); - ctx->frag_shader - = load_shader_module(ctx->dev, frag_shader, sizeof(frag_shader)); - const VkPipelineShaderStageCreateInfo shader_stages[] = { - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = ctx->vert_shader, - .pName = "main", - }, - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = ctx->frag_shader, - .pName = "main", - }, - }; - - // Create descriptor set layout - const VkDescriptorSetLayoutBinding desc_set_layout_bindings[] = { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - }, - }; - const VkDescriptorSetLayoutCreateInfo desc_set_layout_config = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = NELEMS(desc_set_layout_bindings), - .pBindings = desc_set_layout_bindings, - }; - result = vkCreateDescriptorSetLayout( - ctx->dev, &desc_set_layout_config, nullptr, &ctx->desc_set_layout); - assert(result == VK_SUCCESS); - - // Create descriptor pool - const VkDescriptorPoolCreateInfo desc_pool_config = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .poolSizeCount = 1, - .pPoolSizes = &(VkDescriptorPoolSize) { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount - = MAX_MODEL_COUNT * 2 * ctx->swapchain_img_count, - }, - .maxSets = MAX_MODEL_COUNT * 2 * ctx->swapchain_img_count, - }; - result = vkCreateDescriptorPool( - ctx->dev, &desc_pool_config, nullptr, &ctx->desc_pool); - assert(result == VK_SUCCESS); - - // Set up input configuration - const VkVertexInputBindingDescription input_binding_descs[] = { - { - .binding = 0, - .stride = sizeof(vertex_t), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }, - }; - const VkVertexInputAttributeDescription input_attribute_descs[] = { - { - .binding = 0, - .location = 0, - .format = VK_FORMAT_R32G32B32_SFLOAT, - .offset = offsetof(vertex_t, position), - }, - { - .binding = 0, - .location = 1, - .format = VK_FORMAT_R32G32B32_SFLOAT, - .offset = offsetof(vertex_t, normal), - }, - { - .binding = 0, - .location = 2, - .format = VK_FORMAT_R16G16B16A16_UINT, - .offset = offsetof(vertex_t, bones), - }, - { - .binding = 0, - .location = 3, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = offsetof(vertex_t, weights), - }, - }; - const VkPipelineVertexInputStateCreateInfo vertex_input_config = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = NELEMS(input_binding_descs), - .pVertexBindingDescriptions = input_binding_descs, - .vertexAttributeDescriptionCount = NELEMS(input_attribute_descs), - .pVertexAttributeDescriptions = input_attribute_descs, - }; - const VkPipelineInputAssemblyStateCreateInfo input_assembly_config = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - }; - // Set up viewport configuration const VkViewport viewport = { .width = (float)ctx->swapchain_extent.width, @@ -508,54 +403,6 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name) .pScissors = &scissor, }; - // Populate rasterizer configuration - const VkPipelineRasterizationStateCreateInfo rasterizer_config = { - .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, - }; - - // Populate multisampling configuration - const VkPipelineMultisampleStateCreateInfo multisampling_config = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .sampleShadingEnable = VK_FALSE, - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, - }; - - // Set up colour blending configuration - const VkPipelineColorBlendAttachmentState colour_blend_attatchment = { - .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - .blendEnable = VK_FALSE, - }; - const VkPipelineColorBlendStateCreateInfo colour_blend_config = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .logicOpEnable = VK_FALSE, - .attachmentCount = 1, - .pAttachments = &colour_blend_attatchment, - }; - - // Create pipeline layout - const VkPushConstantRange push_constant_range = { - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - .offset = 0, - .size = sizeof(vp_t), - }; - const VkPipelineLayoutCreateInfo pipeline_layout_config = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 1, - .pSetLayouts = &ctx->desc_set_layout, - .pushConstantRangeCount = 1, - .pPushConstantRanges = &push_constant_range, - }; - result = vkCreatePipelineLayout( - ctx->dev, &pipeline_layout_config, nullptr, &ctx->pipeline_layout); - assert(result == VK_SUCCESS); - // Set up colour attachment const VkAttachmentDescription colour_attachment = { .format = surface_fmt.format, @@ -621,7 +468,159 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name) ctx->dev, &render_pass_config, nullptr, &ctx->render_pass); assert(result == VK_SUCCESS); - // Create pipeline + // Populate multisampling configuration + const VkPipelineMultisampleStateCreateInfo multisampling_config = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .sampleShadingEnable = VK_FALSE, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + }; + + // Set up colour blending configuration + const VkPipelineColorBlendAttachmentState colour_blend_attatchment = { + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + .blendEnable = VK_FALSE, + }; + const VkPipelineColorBlendStateCreateInfo colour_blend_config = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .logicOpEnable = VK_FALSE, + .attachmentCount = 1, + .pAttachments = &colour_blend_attatchment, + }; + + // Set up push constant config + const VkPushConstantRange push_constant_range = { + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .offset = 0, + .size = sizeof(vp_t), + }; + + // Load vertex and fragment shader modules + ctx->model_vert_shader + = load_shader_module(ctx->dev, vert_shader, sizeof(vert_shader)); + ctx->frag_shader + = load_shader_module(ctx->dev, frag_shader, sizeof(frag_shader)); + + // Create descriptor set layout + const VkDescriptorSetLayoutBinding desc_set_layout_bindings[] = { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + }, + { + .binding = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + }, + }; + const VkDescriptorSetLayoutCreateInfo desc_set_layout_config = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = NELEMS(desc_set_layout_bindings), + .pBindings = desc_set_layout_bindings, + }; + result = vkCreateDescriptorSetLayout( + ctx->dev, &desc_set_layout_config, nullptr, &ctx->desc_set_layout); + assert(result == VK_SUCCESS); + + // Create descriptor pool + const VkDescriptorPoolCreateInfo desc_pool_config = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .poolSizeCount = 1, + .pPoolSizes = &(VkDescriptorPoolSize) { + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount + = MAX_MODEL_COUNT * 2 * ctx->swapchain_img_count, + }, + .maxSets = MAX_MODEL_COUNT * 2 * ctx->swapchain_img_count, + }; + result = vkCreateDescriptorPool( + ctx->dev, &desc_pool_config, nullptr, &ctx->desc_pool); + assert(result == VK_SUCCESS); + + // Set up model input configuration + const VkVertexInputBindingDescription input_binding_descs[] = { + { + .binding = 0, + .stride = sizeof(vertex_t), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }, + }; + const VkVertexInputAttributeDescription input_attribute_descs[] = { + { + .binding = 0, + .location = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(vertex_t, position), + }, + { + .binding = 0, + .location = 1, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(vertex_t, normal), + }, + { + .binding = 0, + .location = 2, + .format = VK_FORMAT_R16G16B16A16_UINT, + .offset = offsetof(vertex_t, bones), + }, + { + .binding = 0, + .location = 3, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(vertex_t, weights), + }, + }; + const VkPipelineVertexInputStateCreateInfo vertex_input_config = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = NELEMS(input_binding_descs), + .pVertexBindingDescriptions = input_binding_descs, + .vertexAttributeDescriptionCount = NELEMS(input_attribute_descs), + .pVertexAttributeDescriptions = input_attribute_descs, + }; + const VkPipelineInputAssemblyStateCreateInfo input_assembly_config = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + }; + + // Create model pipeline + const VkPipelineShaderStageCreateInfo model_shader_stages[] = { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = ctx->model_vert_shader, + .pName = "main", + }, + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = ctx->frag_shader, + .pName = "main", + }, + }; + const VkPipelineRasterizationStateCreateInfo model_rasterizer_config = { + .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, + }; + const VkPipelineLayoutCreateInfo model_pipeline_layout_config = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 1, + .pSetLayouts = &ctx->desc_set_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_constant_range, + }; + result = vkCreatePipelineLayout( + ctx->dev, &model_pipeline_layout_config, nullptr, + &ctx->model_pipeline_layout); + assert(result == VK_SUCCESS); const VkPipelineDepthStencilStateCreateInfo depth_stencil_config = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, .depthTestEnable = VK_TRUE, @@ -630,24 +629,24 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name) .depthBoundsTestEnable = VK_FALSE, .stencilTestEnable = VK_FALSE, }; - const VkGraphicsPipelineCreateInfo pipeline_config = { + const VkGraphicsPipelineCreateInfo model_pipeline_config = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .stageCount = 2, - .pStages = shader_stages, + .pStages = model_shader_stages, .pVertexInputState = &vertex_input_config, .pInputAssemblyState = &input_assembly_config, .pViewportState = &viewport_config, - .pRasterizationState = &rasterizer_config, + .pRasterizationState = &model_rasterizer_config, .pMultisampleState = &multisampling_config, .pColorBlendState = &colour_blend_config, - .layout = ctx->pipeline_layout, + .layout = ctx->model_pipeline_layout, .renderPass = ctx->render_pass, .subpass = 0, .pDepthStencilState = &depth_stencil_config, }; result = vkCreateGraphicsPipelines( - ctx->dev, VK_NULL_HANDLE, 1, &pipeline_config, nullptr, - &ctx->pipeline); + ctx->dev, VK_NULL_HANDLE, 1, &model_pipeline_config, nullptr, + &ctx->model_pipeline); assert(result == VK_SUCCESS); // Create framebuffers @@ -747,14 +746,14 @@ void gpu_cleanup(const gpu_ctx_t *ctx) vkDestroyCommandPool(ctx->dev, ctx->cmd_pool, nullptr); - vkDestroyPipeline(ctx->dev, ctx->pipeline, nullptr); + vkDestroyPipeline(ctx->dev, ctx->model_pipeline, nullptr); vkDestroyRenderPass(ctx->dev, ctx->render_pass, nullptr); - vkDestroyPipelineLayout(ctx->dev, ctx->pipeline_layout, nullptr); + vkDestroyPipelineLayout(ctx->dev, ctx->model_pipeline_layout, nullptr); vkDestroyDescriptorPool(ctx->dev, ctx->desc_pool, nullptr); vkDestroyDescriptorSetLayout(ctx->dev, ctx->desc_set_layout, nullptr); - vkDestroyShaderModule(ctx->dev, ctx->vert_shader, nullptr); + vkDestroyShaderModule(ctx->dev, ctx->model_vert_shader, nullptr); vkDestroyShaderModule(ctx->dev, ctx->frag_shader, nullptr); vkDestroyImageView(ctx->dev, ctx->depth_img_view, nullptr); @@ -924,11 +923,11 @@ void gpu_render_begin(gpu_ctx_t *ctx, vp_t vp) vkCmdBeginRenderPass( ctx->cmd_buf, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline( - ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pipeline); + ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->model_pipeline); vkCmdPushConstants( - ctx->cmd_buf, ctx->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, - sizeof(vp_t), &vp); + ctx->cmd_buf, ctx->model_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, + 0, sizeof(vp_t), &vp); } void gpu_render_model( @@ -948,8 +947,9 @@ void gpu_render_model( ctx->cmd_buf, model->index_buf, 0, VK_INDEX_TYPE_UINT16); vkCmdBindDescriptorSets( - ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pipeline_layout, - 0, 1, model->desc_sets + ctx->active_img_index, 0, nullptr); + ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, + ctx->model_pipeline_layout, 0, 1, + model->desc_sets + ctx->active_img_index, 0, nullptr); vkCmdDrawIndexed(ctx->cmd_buf, model->index_count, 1, 0, 0, 0); } diff --git a/gpu.h b/gpu.h index 4aa013b..846f490 100644 --- a/gpu.h +++ b/gpu.h @@ -28,13 +28,13 @@ typedef struct { VkDeviceMemory depth_img_mem; VkImageView depth_img_view; VkFramebuffer framebuffers[MAX_FRAMES_IN_FLIGHT]; - VkShaderModule vert_shader; + VkShaderModule model_vert_shader; VkShaderModule frag_shader; VkDescriptorSetLayout desc_set_layout; VkDescriptorPool desc_pool; - VkPipelineLayout pipeline_layout; VkRenderPass render_pass; - VkPipeline pipeline; + VkPipelineLayout model_pipeline_layout; + VkPipeline model_pipeline; VkCommandPool cmd_pool; VkCommandBuffer cmd_buf; VkFence in_flight; diff --git a/vert.glsl b/model-vert.glsl similarity index 100% rename from vert.glsl rename to model-vert.glsl