// VULKAN CONFIG static const VkFormat VK_IMAGE_FORMATS[] = { VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R8G8B8A8_UNORM, }; static VkApplicationInfo app_info = { .sType = STYPE(APPLICATION_INFO), .pApplicationName = "Video Game", .applicationVersion = VK_MAKE_API_VERSION(0, 0, 0, 1), .pEngineName = "None (yet)", .engineVersion = VK_MAKE_API_VERSION(0, 0, 0, 1), .apiVersion = VK_API_VERSION_1_3, }; static const char *instance_layers[] = { #ifdef BUILD_DEBUG "VK_LAYER_KHRONOS_validation" #endif }; static const char *instance_extensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, #ifdef __linux__ VK_KHR_XCB_SURFACE_EXTENSION_NAME, #endif #ifdef _WIN32 VK_KHR_WIN32_SURFACE_EXTENSION_NAME, #endif #ifdef BUILD_DEBUG VK_EXT_DEBUG_UTILS_EXTENSION_NAME, #endif }; static VkInstanceCreateInfo inst_info = { .sType = STYPE(INSTANCE_CREATE_INFO), .pApplicationInfo = &app_info, .enabledLayerCount = sizeof(instance_layers) / sizeof(char *), .ppEnabledLayerNames = instance_layers, .enabledExtensionCount = sizeof(instance_extensions) / sizeof(char *), .ppEnabledExtensionNames = instance_extensions, }; const char *device_extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, }; #ifdef BUILD_DEBUG static VkDebugUtilsMessengerCreateInfoEXT debug_msg_info = { .sType = STYPE(DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT), .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, .pfnUserCallback = (PFN_vkDebugUtilsMessengerCallbackEXT)vDebugCallback, }; #endif static VkPhysicalDeviceVulkan13Features vk_13_features = { .sType = STYPE(PHYSICAL_DEVICE_VULKAN_1_3_FEATURES), .synchronization2 = VK_TRUE, .dynamicRendering = VK_TRUE }; static VkPhysicalDeviceVulkan12Features vk_12_features = { .sType = STYPE(PHYSICAL_DEVICE_VULKAN_1_2_FEATURES), .pNext = &vk_13_features, .descriptorIndexing = VK_TRUE, .bufferDeviceAddress = VK_TRUE, .descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE, .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, .descriptorBindingStorageImageUpdateAfterBind = VK_TRUE, .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, .descriptorBindingPartiallyBound = VK_TRUE, .shaderSampledImageArrayNonUniformIndexing = VK_TRUE, .runtimeDescriptorArray = VK_TRUE, }; static VkPhysicalDeviceVulkan11Features vk_11_features = { .sType = STYPE(PHYSICAL_DEVICE_VULKAN_1_1_FEATURES), .pNext = &vk_12_features }; static const VkPhysicalDeviceFeatures2 vk_features_2 = { .sType = STYPE(PHYSICAL_DEVICE_FEATURES_2), .pNext = &vk_11_features, .features = { .shaderUniformBufferArrayDynamicIndexing = VK_TRUE, .shaderSampledImageArrayDynamicIndexing = VK_TRUE, .shaderStorageBufferArrayDynamicIndexing = VK_TRUE, .shaderStorageImageArrayDynamicIndexing = VK_TRUE, .samplerAnisotropy = VK_TRUE, }, }; static VkDeviceCreateInfo device_info = { .sType = STYPE(DEVICE_CREATE_INFO), .pNext = &vk_features_2, .ppEnabledExtensionNames = device_extensions, .enabledExtensionCount = Len(device_extensions), .pEnabledFeatures = NULL, }; static VmaAllocatorCreateInfo vma_create_info = { .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, .vulkanApiVersion = VK_API_VERSION_1_3, }; static VkCommandPoolCreateInfo pool_create_info = { .sType = STYPE(COMMAND_POOL_CREATE_INFO), .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, }; static VkFenceCreateInfo fence_create_info = { .sType = STYPE(FENCE_CREATE_INFO), .flags = VK_FENCE_CREATE_SIGNALED_BIT, }; static VkSemaphoreCreateInfo semaphore_create_info = { .sType = STYPE(SEMAPHORE_CREATE_INFO), }; static VkCommandBufferAllocateInfo cmd_buf_info = { .sType = STYPE(COMMAND_BUFFER_ALLOCATE_INFO), .commandBufferCount = 1, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, }; static VkSwapchainCreateInfoKHR swapchain_create_info = { .sType = STYPE(SWAPCHAIN_CREATE_INFO_KHR), .imageArrayLayers = 1, .imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, .clipped = VK_TRUE, .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, }; static VkImageViewCreateInfo sc_image_view_create_info = { .sType = STYPE(IMAGE_VIEW_CREATE_INFO), .viewType = VK_IMAGE_VIEW_TYPE_2D, .components = { .r = VK_COMPONENT_SWIZZLE_IDENTITY, .g = VK_COMPONENT_SWIZZLE_IDENTITY, .b = VK_COMPONENT_SWIZZLE_IDENTITY, .a = VK_COMPONENT_SWIZZLE_IDENTITY, }, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1, }, }; static VkImageCreateInfo draw_image_create_info = { .sType = STYPE(IMAGE_CREATE_INFO), .imageType = VK_IMAGE_TYPE_2D, .mipLevels = 1, .arrayLayers = 1, .samples = VK_SAMPLE_COUNT_1_BIT, .tiling = VK_IMAGE_TILING_OPTIMAL, .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, }; static VkImageViewCreateInfo draw_image_view_create_info = { .sType = STYPE(IMAGE_VIEW_CREATE_INFO), .viewType = VK_IMAGE_VIEW_TYPE_2D, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1, }, }; static VkImageCreateInfo depth_image_create_info = { .sType = STYPE(IMAGE_CREATE_INFO), .imageType = VK_IMAGE_TYPE_2D, .mipLevels = 1, .arrayLayers = 1, .samples = VK_SAMPLE_COUNT_1_BIT, .tiling = VK_IMAGE_TILING_OPTIMAL, .format = VK_FORMAT_D32_SFLOAT, .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, }; static VkImageViewCreateInfo depth_image_view_create_info = { .sType = STYPE(IMAGE_VIEW_CREATE_INFO), .viewType = VK_IMAGE_VIEW_TYPE_2D, .format = VK_FORMAT_D32_SFLOAT, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1, }, }; // // PIPELINES & DESCRIPTORS // static VkDescriptorPoolSize descriptor_pool_sizes[] = { { .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 4096 }, { .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 4096}, { .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = 4096}, { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 4096}, }; static VkDescriptorPoolCreateInfo desc_pool_info = { .sType = STYPE(DESCRIPTOR_POOL_CREATE_INFO), .poolSizeCount = Len(descriptor_pool_sizes), .pPoolSizes = descriptor_pool_sizes, .maxSets = 12, // Not sure if this is correct .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, }; static VkDescriptorBindingFlags shared_desc_binding_flags[] = { VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, }; static VkDescriptorSetLayoutBindingFlagsCreateInfo shared_layout_binding_flags_info = { .sType = STYPE(DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO), .bindingCount = Len(shared_desc_binding_flags), .pBindingFlags = shared_desc_binding_flags, }; static VkDescriptorSetLayoutBinding shared_layout_bindings[] = { { .binding = 0, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, { .binding = 1, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, { .binding = 2, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, { .binding = 3, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_ALL }, }; static VkDescriptorSetLayoutCreateInfo shared_layout_create_info = { .sType = STYPE(DESCRIPTOR_SET_LAYOUT_CREATE_INFO), .pNext = &shared_layout_binding_flags_info, .bindingCount = Len(shared_layout_bindings), .pBindings = shared_layout_bindings, .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, }; static VkDescriptorType desc_type_map[vDT_MAX] = { [vDT_SAMPLED_IMAGE] = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, [vDT_MATERIAL] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, }; static VkDescriptorBindingFlags bindless_desc_binding_flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT; static VkDescriptorSetLayoutBindingFlagsCreateInfo bindless_layout_flag_create_info = { .sType = STYPE(DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO), .bindingCount = 1, .pBindingFlags = &bindless_desc_binding_flags, }; static VkDescriptorSetLayoutBinding bindless_layout_binding = { .binding = 0, .descriptorCount = 1024, .stageFlags = VK_SHADER_STAGE_ALL, }; static VkDescriptorSetLayoutCreateInfo bindless_layout_create_info = { .sType = STYPE(DESCRIPTOR_SET_LAYOUT_CREATE_INFO), .pNext = &bindless_layout_flag_create_info, .bindingCount = 1, .pBindings = &bindless_layout_binding, .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, }; static VkDescriptorSetAllocateInfo set_allocate_info = { .sType = STYPE(DESCRIPTOR_SET_ALLOCATE_INFO), .descriptorSetCount = vDT_MAX, }; static VkPushConstantRange push_const_range = { .offset = 0, .size = sizeof(rPushConst), .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT, }; static VkPipelineLayoutCreateInfo pipeline_layout_create_info = { .sType = STYPE(PIPELINE_LAYOUT_CREATE_INFO), .setLayoutCount = vDT_MAX, .pushConstantRangeCount = 1, .pPushConstantRanges = &push_const_range, }; // // PIPELINES // #define PIPELINE_DYNAMIC_STATE { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR } static VkDynamicState pipeline_dynamic_state[] = PIPELINE_DYNAMIC_STATE; #define PIPELINE_DEFAULT_DYN_STATE_INFO { \ .sType = STYPE(PIPELINE_DYNAMIC_STATE_CREATE_INFO), \ .pDynamicStates = pipeline_dynamic_state, \ .dynamicStateCount = Len(pipeline_dynamic_state), \ } static VkPipelineDynamicStateCreateInfo pipeline_default_dyn_state_info = PIPELINE_DEFAULT_DYN_STATE_INFO; #define PIPELINE_DEFAULT_ASSEMBLY_INFO { \ .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), \ .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, \ .primitiveRestartEnable = VK_FALSE, \ } static VkPipelineInputAssemblyStateCreateInfo pipeline_default_assembly_info = PIPELINE_DEFAULT_ASSEMBLY_INFO; #define PIPELINE_DEFAULT_RASTERIZATION_INFO { \ .sType = STYPE(PIPELINE_RASTERIZATION_STATE_CREATE_INFO), \ .polygonMode = VK_POLYGON_MODE_FILL, \ .lineWidth = 1.0, \ .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, \ } static VkPipelineRasterizationStateCreateInfo pipeline_default_rasterization_info = PIPELINE_DEFAULT_RASTERIZATION_INFO; #define PIPELINE_DEFAULT_MULTISAMPLE_INFO { \ .sType = STYPE(PIPELINE_MULTISAMPLE_STATE_CREATE_INFO), \ .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, \ .minSampleShading = 1.0, \ .alphaToCoverageEnable = VK_FALSE, \ .alphaToOneEnable = VK_FALSE, \ } static VkPipelineMultisampleStateCreateInfo pipeline_default_multisample_info = PIPELINE_DEFAULT_MULTISAMPLE_INFO; #define PIPELINE_DEFAULT_DEPTH_INFO { \ .sType = STYPE(PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO), \ .depthTestEnable = VK_TRUE, \ .depthWriteEnable = VK_TRUE, \ .depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL, \ .depthBoundsTestEnable = VK_FALSE, \ .stencilTestEnable = VK_FALSE, \ .minDepthBounds = 0.0, \ .maxDepthBounds = 1.0, \ } static VkPipelineDepthStencilStateCreateInfo pipeline_default_depth_info = PIPELINE_DEFAULT_DEPTH_INFO; #define PIPELINE_DEFAULT_RENDERING_INFO { \ .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), \ .colorAttachmentCount = 1, \ } static VkPipelineRenderingCreateInfo pipeline_default_rendering_info = PIPELINE_DEFAULT_RENDERING_INFO; #define PIPELINE_DEFAULT_BLEND_ATTACH_STATE { \ .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, \ .blendEnable = VK_FALSE, \ } static VkPipelineColorBlendAttachmentState pipeline_default_blend_attach_state = PIPELINE_DEFAULT_BLEND_ATTACH_STATE; #define PIPELINE_DEFAULT_BLEND_INFO { \ .sType = STYPE(PIPELINE_COLOR_BLEND_STATE_CREATE_INFO), \ .logicOpEnable = VK_FALSE, \ .logicOp = VK_LOGIC_OP_COPY, \ .attachmentCount = 1, \ .pAttachments = &pipeline_default_blend_attach_state, \ } static VkPipelineColorBlendStateCreateInfo pipeline_default_blend_info = PIPELINE_DEFAULT_BLEND_INFO; #define PIPELINE_DEFAULT_VERTEX_INFO { \ .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), \ } static VkPipelineVertexInputStateCreateInfo pipeline_default_vertex_info = PIPELINE_DEFAULT_VERTEX_INFO; #define PIPELINE_DEFAULT_VIEWPORT_INFO { \ .sType = STYPE(PIPELINE_VIEWPORT_STATE_CREATE_INFO), \ .viewportCount = 1, \ .scissorCount = 1, \ } const static VkPipelineViewportStateCreateInfo pipeline_default_viewport_info = PIPELINE_DEFAULT_VIEWPORT_INFO; #define INIT_PIPELINE_DEFAULTS(pipeline) \ VkPipelineDynamicStateCreateInfo pipeline##_default_dynamic_info = PIPELINE_DEFAULT_DYN_STATE_INFO; \ VkPipelineInputAssemblyStateCreateInfo pipeline##_default_assembly_info = PIPELINE_DEFAULT_ASSEMBLY_INFO; \ VkPipelineRasterizationStateCreateInfo pipeline##_default_rasterization_info = PIPELINE_DEFAULT_RASTERIZATION_INFO; \ VkPipelineMultisampleStateCreateInfo pipeline##_default_multisample_info = PIPELINE_DEFAULT_MULTISAMPLE_INFO; \ VkPipelineDepthStencilStateCreateInfo pipeline##_default_depth_info = PIPELINE_DEFAULT_DEPTH_INFO; \ VkPipelineRenderingCreateInfo pipeline##_default_rendering_info = PIPELINE_DEFAULT_RENDERING_INFO; \ VkPipelineColorBlendStateCreateInfo pipeline##_default_blend_info = PIPELINE_DEFAULT_BLEND_INFO; \ VkPipelineVertexInputStateCreateInfo pipeline##_default_vertex_info = PIPELINE_DEFAULT_VERTEX_INFO; \ VkPipelineViewportStateCreateInfo pipeline##_default_viewport_info = PIPELINE_DEFAULT_VIEWPORT_INFO; \ VkGraphicsPipelineCreateInfo pipeline##_create_info = { \ .sType = STYPE(GRAPHICS_PIPELINE_CREATE_INFO), \ .pNext = &pipeline##_default_rendering_info, \ .pVertexInputState = &pipeline##_default_vertex_info, \ .pInputAssemblyState = &pipeline##_default_assembly_info, \ .pViewportState = &pipeline##_default_viewport_info, \ .pRasterizationState = &pipeline##_default_rasterization_info,\ .pMultisampleState = &pipeline##_default_multisample_info, \ .pColorBlendState = &pipeline##_default_blend_info, \ .pDepthStencilState = &pipeline##_default_depth_info, \ .pDynamicState = &pipeline##_default_dynamic_info, \ }; INIT_PIPELINE_DEFAULTS(cube); // GUI Pipeline INIT_PIPELINE_DEFAULTS(gui); VkVertexInputBindingDescription gui_input_bind_desc = { .binding = 0, .stride = sizeof(rUIVertex), .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE, }; VkVertexInputAttributeDescription gui_input_descriptions[] = { { .binding = 0, .location = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = 0 }, { .binding = 0, .location = 1, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(rUIVertex, p1) }, { .binding = 0, .location = 2, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof(rUIVertex, col) }, { .binding = 0, .location = 3, .format = VK_FORMAT_R32_UINT, .offset = offsetof(rUIVertex, tex_idx) }, }; VkPipelineVertexInputStateCreateInfo gui_vertex_input_info = { .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), .vertexBindingDescriptionCount = 1, .pVertexBindingDescriptions = &gui_input_bind_desc, .vertexAttributeDescriptionCount = Len(gui_input_descriptions), .pVertexAttributeDescriptions = gui_input_descriptions, }; VkPipelineInputAssemblyStateCreateInfo gui_assembly_info = { .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, .primitiveRestartEnable = VK_FALSE, }; // PBR Pipeline INIT_PIPELINE_DEFAULTS(pbr); VkVertexInputBindingDescription pbr_input_bind_desc = { .binding = 0, .stride = sizeof(rPBRVertex), .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, }; VkVertexInputAttributeDescription pbr_input_descriptions[] = { { .binding = 0, .location = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = 0 }, { .binding = 1, .location = 1, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof(rPBRVertex, col) }, }; VkPipelineVertexInputStateCreationInfo pbr_vertex_input_info = { .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), .vertexBindingDescriptionCount = 1, .pVertexBindingDescriptions = &pbr_vertex_bind_desc, .vertexAttributeDescriptionCount = Len(pbr_input_descriptions), .pVertexAttributeDescriptions = pbr_input_descriptions, }; VkPipelineInputAssemblyStateCreateInfo pbr_assembly_info = { .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, .primitiveRestartEnable = VK_FALSE, }; static void vCustomizePipelines() { // GUI gui_create_info.pVertexInputState = &gui_vertex_input_info; gui_create_info.pInputAssemblyState = &gui_assembly_info; // PBR pbr_create_info.pVertexInputState = &pbr_vertex_input_info; pbr_create_info.pInputAssemblyState = &pbr_assembly_info; }