diff --git a/main.cpp b/main.cpp index a213e50..8b03f74 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ // vim:fileencoding=utf-8:foldmethod=marker +#include "vulkan/vulkan_core.h" #include "wapp/wapp.h" #include "vulkan_profiles/vulkan_profiles.h" #include "ktx.h" @@ -91,6 +92,9 @@ typedef VkDescriptorImageInfo *VkDescriptorImageInfoArray; typedef VkBufferImageCopy *VkBufferImageCopyArray; typedef slang::TargetDesc *SlangTargetDescArray; typedef slang::CompilerOptionEntry *SlangCompOptEntryArray; +typedef VkVertexInputAttributeDescription *VkVertexInputAttributeDescriptionArray; +typedef VkPipelineShaderStageCreateInfo *VkPipelineShaderStageCreateInfoArray; +typedef VkDynamicState *VkDynamicStateArray; // }}} // {{{ Helper Function Declarations @@ -144,6 +148,8 @@ wapp_intern VkDescriptorPool desc_pool = VK_NULL_HANDLE; wapp_intern VkDescriptorSet desc_set_tex = VK_NULL_HANDLE; wapp_intern Slang::ComPtr slang_global_session; wapp_intern VkShaderModule shader_module = VK_NULL_HANDLE; +wapp_intern VkPipelineLayout graphics_pipeline_layout = VK_NULL_HANDLE; +wapp_intern VkPipeline graphics_pipeline = VK_NULL_HANDLE; // }}} int main() { @@ -960,6 +966,143 @@ int main() { // }}} // }}} + // {{{ Graphics Pipeline + // {{{ Create Pipeline Layout + // The pipeline layout defines the interface between the pipeline and our shaders. We add a push + // constant range and the texture descriptor set layout. A push constant range defines a range of + // values that we can directly push to the shader without having to go through a buffer. We use + // these to pass a pointer to the shader data buffer. + VkPushConstantRange push_constants = {}; + push_constants.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constants.size = sizeof(VkDeviceAddress); + + VkPipelineLayoutCreateInfo pl_create_info = {}; + pl_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pl_create_info.setLayoutCount = 1; + pl_create_info.pSetLayouts = &desc_set_layout_tex; + pl_create_info.pushConstantRangeCount = 1; + pl_create_info.pPushConstantRanges = &push_constants; + + check(vkCreatePipelineLayout(device, &pl_create_info, NULL, &graphics_pipeline_layout)); + // }}} + + // {{{ Vertex Binding And Attributes + VkVertexInputBindingDescription vertex_binding = {}; + vertex_binding.binding = 0; + vertex_binding.stride = sizeof(Vertex); + vertex_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + VkVertexInputAttributeDescriptionArray vertex_attributes = wapp_array( + VkVertexInputAttributeDescription, + // Location, Binding, Format, Offset + VkVertexInputAttributeDescription{0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}, + VkVertexInputAttributeDescription{1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal)}, + VkVertexInputAttributeDescription{2, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv)} + ); + + VkPipelineVertexInputStateCreateInfo vertex_input_state = {}; + vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_input_state.vertexBindingDescriptionCount = 1; + vertex_input_state.pVertexBindingDescriptions = &vertex_binding; + vertex_input_state.vertexAttributeDescriptionCount = wapp_array_count(vertex_attributes); + vertex_input_state.pVertexAttributeDescriptions = vertex_attributes; + // }}} + + // {{{ Input Assembly + VkPipelineInputAssemblyStateCreateInfo input_assembly_state = {}; + input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + // }}} + + // {{{ Shader Stages + VkPipelineShaderStageCreateInfoArray shader_stages = wapp_array_with_capacity(VkPipelineShaderStageCreateInfo, 2, ARRAY_INIT_FILLED); + + // Vertex Shader + shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + shader_stages[0].module = shader_module; + shader_stages[0].pName = "main"; + + // Fragment Shader + shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shader_stages[1].module = shader_module; + shader_stages[1].pName = "main"; + // }}} + + // {{{ Viewport And Scissor Dynamic States + VkPipelineViewportStateCreateInfo viewport_state = {}; + viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_state.viewportCount = 1; + viewport_state.scissorCount = 1; + + VkDynamicStateArray dynamic_states = wapp_array(VkDynamicState, VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR); + + VkPipelineDynamicStateCreateInfo dynamic_state = {}; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.dynamicStateCount = wapp_array_count(dynamic_states); + dynamic_state.pDynamicStates = dynamic_states; + // }}} + + // {{{ Depth/Stencil State + VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {}; + depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depth_stencil_state.depthTestEnable = VK_TRUE; + depth_stencil_state.depthWriteEnable = VK_TRUE; + depth_stencil_state.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + // }}} + + // {{{ Dynamic Rendering + VkPipelineRenderingCreateInfo rendering_create_info = {}; + rendering_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + rendering_create_info.colorAttachmentCount = 1; + rendering_create_info.pColorAttachmentFormats = &image_format; + rendering_create_info.depthAttachmentFormat = depth_format; + // }}} + + // {{{ Blending State + // Blending disabled + VkPipelineColorBlendAttachmentState blend_attachment = {}; + blend_attachment.colorWriteMask = 0xf; + + VkPipelineColorBlendStateCreateInfo blend_state = {}; + blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + blend_state.attachmentCount = 1; + blend_state.pAttachments = &blend_attachment; + // }}} + + // {{{ Rasterization State + VkPipelineRasterizationStateCreateInfo rasterization_state = {}; + rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterization_state.lineWidth = 1.0f; + // }}} + + // {{{ Multisampling State + VkPipelineMultisampleStateCreateInfo multisampling_state = {}; + multisampling_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + // }}} + + // {{{ Create Graphics Pipeline + VkGraphicsPipelineCreateInfo graphics_pipeline_create_info = {}; + graphics_pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + graphics_pipeline_create_info.pNext = &rendering_create_info; + graphics_pipeline_create_info.stageCount = wapp_array_count(shader_stages); + graphics_pipeline_create_info.pStages = shader_stages; + graphics_pipeline_create_info.pVertexInputState = &vertex_input_state; + graphics_pipeline_create_info.pInputAssemblyState = &input_assembly_state; + graphics_pipeline_create_info.pViewportState = &viewport_state; + graphics_pipeline_create_info.pRasterizationState = &rasterization_state; + graphics_pipeline_create_info.pMultisampleState = &multisampling_state; + graphics_pipeline_create_info.pDepthStencilState = &depth_stencil_state; + graphics_pipeline_create_info.pColorBlendState = &blend_state; + graphics_pipeline_create_info.pDynamicState = &dynamic_state; + graphics_pipeline_create_info.layout = graphics_pipeline_layout; + + check(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, NULL, &graphics_pipeline)); + // }}} + // }}} + // {{{ Render Loop SDL_Event event = {}; while (running) { @@ -979,6 +1122,8 @@ int main() { // }}} // {{{ Cleanup + vkDestroyPipeline(device, graphics_pipeline, NULL); + vkDestroyPipelineLayout(device, graphics_pipeline_layout, NULL); vkDestroyShaderModule(device, shader_module, NULL); vkDestroyDescriptorPool(device, desc_pool, NULL); vkDestroyDescriptorSetLayout(device, desc_set_layout_tex, NULL);