From 6af7e785890a322f60c21a51e3d41cd9015e6773 Mon Sep 17 00:00:00 2001 From: gramanas Date: Wed, 5 Jun 2024 02:48:40 +0300 Subject: more vks --- src/render.c | 428 ++--------------------------------------------------------- 1 file changed, 14 insertions(+), 414 deletions(-) (limited to 'src/render.c') diff --git a/src/render.c b/src/render.c index 810db51..ae9c05b 100644 --- a/src/render.c +++ b/src/render.c @@ -170,7 +170,7 @@ debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, void vulkan_setup_debug_messenger() { - if (!enableValidationLayers) return; + if (!enable_validation_layers) return; VkDebugUtilsMessengerCreateInfoEXT createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; @@ -191,92 +191,6 @@ vulkan_setup_debug_messenger() } } -VkExtent2D -chooseSwapExtent(const VkSurfaceCapabilitiesKHR * capabilities) -{ - if (capabilities->currentExtent.width != UINT32_MAX) { - return capabilities->currentExtent; - } else { - int width, height; - SDL_GetWindowSize(s.vk.window, &width, &height); - - VkExtent2D actualExtent; - actualExtent.width = (uint32_t) width; - actualExtent.height = (uint32_t) height; - - // Manual implementation of std::clamp since it is not available in C - actualExtent.width = (actualExtent.width < capabilities->minImageExtent.width) ? capabilities->minImageExtent.width : - (actualExtent.width > capabilities->maxImageExtent.width) ? capabilities->maxImageExtent.width : - actualExtent.width; - - actualExtent.height = (actualExtent.height < capabilities->minImageExtent.height) ? capabilities->minImageExtent.height : - (actualExtent.height > capabilities->maxImageExtent.height) ? capabilities->maxImageExtent.height : - actualExtent.height; - - return actualExtent; - } -} - -VkSurfaceFormatKHR -chooseSwapSurfaceFormat(const VkSurfaceFormatKHR * availableFormats, uint32_t formatCount) -{ - for (uint32_t i = 0 ; i < formatCount; i ++) { - if (availableFormats[i].format == VK_FORMAT_B8G8R8A8_SRGB && - availableFormats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { - return availableFormats[i]; - } - } - - // if it fails pick the first one - return availableFormats[0]; -} - -VkPresentModeKHR -chooseSwapPresentMode(const VkPresentModeKHR * presentModes, uint32_t presentModeCount) -{ - for (uint32_t i = 0 ; i < presentModeCount; i ++) { - if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { - return presentModes[i]; - } - } - - // if it fails pick the the FIFO one - return VK_PRESENT_MODE_FIFO_KHR; -} - -typedef struct SwapChainSupportDetails { - VkSurfaceCapabilitiesKHR capabilities; - VkSurfaceFormatKHR formats[100]; - uint32_t formatCount; - VkPresentModeKHR presentModes[100]; - uint32_t presentModeCount; -} SwapChainSupportDetails; - -SwapChainSupportDetails -querySwapChainSupport(VkPhysicalDevice device) -{ - // TODO Make SwapChainSupportDetails malloc it;s arrays and free it after it is used. - SwapChainSupportDetails details; - - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, s.vk.surface, &details.capabilities); - - vkGetPhysicalDeviceSurfaceFormatsKHR(device, s.vk.surface, &details.formatCount, NULL); - - if (details.formatCount != 0) { - // todo alloc format arrray - vkGetPhysicalDeviceSurfaceFormatsKHR(device, s.vk.surface, &details.formatCount, details.formats); - } - - vkGetPhysicalDeviceSurfacePresentModesKHR(device, s.vk.surface, &details.presentModeCount, NULL); - - if (details.presentModeCount != 0) { - // todo alloc presentModes array - vkGetPhysicalDeviceSurfacePresentModesKHR(device, s.vk.surface, &details.presentModeCount, details.presentModes); - } - - return details; -} - typedef struct QueueFamilyIndices { uint32_t graphicsAndComputeFamily; bool graphicsFlag; @@ -320,154 +234,6 @@ QueueFamilyIndices vulkan_find_queue_families(VkPhysicalDevice device) { return indices; } -bool -vulkan_check_device_extension_support(VkPhysicalDevice device) -{ - uint32_t extensionCount; - vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, NULL); - - VkExtensionProperties availableExtensions[extensionCount]; - vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, availableExtensions); - - uint32_t flag = 0; - - for (uint32_t i = 0; i < deviceExtensionCount; i++) { - for (uint32_t j = 0; j < extensionCount; j++) { - if (strcmp(device_extensions[i], availableExtensions[j].extensionName) == 0) { - flag++; - break; - } - } - } - - return flag == deviceExtensionCount; -} - -bool -vulkan_is_device_suitable(VkPhysicalDevice device) -{ - QueueFamilyIndices indices = vulkan_find_queue_families(device); - bool extensionsSupported = vulkan_check_device_extension_support(device); - - bool swapChainAdequate = false; - if (extensionsSupported) { - SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device); - swapChainAdequate = !(swapChainSupport.formatCount == 0) && !(swapChainSupport.presentModeCount == 0); - } - - VkPhysicalDeviceFeatures supportedFeatures; - vkGetPhysicalDeviceFeatures(device, &supportedFeatures); - - return vulkan_queue_family_check_flags(indices) && extensionsSupported - && swapChainAdequate && supportedFeatures.samplerAnisotropy; -} - -VkSampleCountFlagBits getMaxUsableSampleCount() { - VkPhysicalDeviceProperties physicalDeviceProperties; - vkGetPhysicalDeviceProperties(s.vk.physical_device, &physicalDeviceProperties); - - VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts; - if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; } - if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; } - if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; } - if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; } - if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; } - if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; } - - return VK_SAMPLE_COUNT_1_BIT; -} - -void -vulkan_pick_physical_device() -{ - uint32_t deviceCount = 0; - vkEnumeratePhysicalDevices(s.vk.instance, &deviceCount, NULL); - if (deviceCount == 0) { - vk_log(VK_INFO, "failed to find GPUs with Vulkan support!\n"); - } - - VkPhysicalDevice devices[deviceCount]; - vkEnumeratePhysicalDevices(s.vk.instance, &deviceCount, devices); - - for (uint32_t i = 0; i < deviceCount; i++) { - if (vulkan_is_device_suitable(devices[i])) { - s.vk.physical_device = devices[i]; - s.msaa_samples = getMaxUsableSampleCount(); - break; - } - } - - if (s.vk.physical_device == VK_NULL_HANDLE) { - vk_log(VK_ERROR, "failed to find a suitable GPU!\n"); - } - - VkPhysicalDeviceProperties deviceProperties; - vkGetPhysicalDeviceProperties(s.vk.physical_device, &deviceProperties); - vk_log(VK_INFO, "Picked [%s] physical device.\n", deviceProperties.deviceName); - - uint32_t extensionCount = 0; - vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL); - VkExtensionProperties extensions[extensionCount]; - VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions); - - vk_log(VK_INFO, "Vulkan enabled extensions: %s\n", string_VkResult(result)); - for (uint32_t i = 0; i < extensionCount; i++) { - vk_log(VK_INFO, "\t%s\n", extensions[i].extensionName); - } - -} - -void -vulkan_create_logical_device() -{ - QueueFamilyIndices indices = vulkan_find_queue_families(s.vk.physical_device); - - // TODO CREATE MULPILE QUEUES - // https://vulkan-tutorial.com/en/Drawing_a_triangle/Presentation/Window_surface#page_Creating-the-presentation-queue - - VkDeviceQueueCreateInfo queueCreateInfo = { - .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = indices.graphicsAndComputeFamily, - .queueCount = 1, - }; - - float queuePriority = 1.0f; - queueCreateInfo.pQueuePriorities = &queuePriority; - - VkPhysicalDeviceFeatures deviceFeatures = {0}; - vkGetPhysicalDeviceFeatures(s.vk.physical_device, &deviceFeatures); - deviceFeatures.samplerAnisotropy = VK_TRUE; - //deviceFeatures.sampleRateShading = VK_TRUE; -#ifndef VKDEBUG - /* Disable robust buffer access when building without debug */ - deviceFeatures.robustBufferAccess = VK_FALSE; -#endif - - VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering_feature = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR, - .dynamicRendering = VK_TRUE, - }; - - VkDeviceCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pQueueCreateInfos = &queueCreateInfo, - .queueCreateInfoCount = 1, - .pNext = &dynamic_rendering_feature, - .pEnabledFeatures = &deviceFeatures, - .enabledExtensionCount = deviceExtensionCount, - .ppEnabledExtensionNames = device_extensions, - .enabledLayerCount = 0, - }; - - if (vkCreateDevice(s.vk.physical_device, &createInfo, NULL, &s.vk.device) != VK_SUCCESS) { - vk_log(VK_ERROR, "failed to create logical device!\n"); - } - vk_log(VK_INFO, "Vulkan logical device created\n"); - - vkGetDeviceQueue(s.vk.device, indices.graphicsAndComputeFamily, 0, &s.vk_graphics_and_compute_queue); - vkGetDeviceQueue(s.vk.device, indices.presentFamily, 0, &s.vk_present_queue); -} - void move_relative(vec3 position, vec3 front, float step, int x) { // Calculate the direction vector from position to front float direction_vec[3] = { @@ -549,108 +315,6 @@ mouseCallback(SDL_Event *event) return; } -void -vulkan_create_surface() -{ - if (SDL_Vulkan_CreateSurface(s.vk.window, s.vk.instance, &s.vk.surface) == SDL_FALSE) { - vk_log(VK_ERROR, "Failed to create surface\n"); - } else { - vk_log(VK_INFO, "Vulkan surface created\n"); - } -} - -void -vulkan_create_swap_chain() -{ - SwapChainSupportDetails swapChainSupport = querySwapChainSupport(s.vk.physical_device); - - VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats, swapChainSupport.formatCount); - VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes, swapChainSupport.presentModeCount); - VkExtent2D extent = chooseSwapExtent(&swapChainSupport.capabilities); - - uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; - - if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { - imageCount = swapChainSupport.capabilities.maxImageCount; - } - - VkSwapchainCreateInfoKHR createInfo = { - .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .surface = s.vk.surface, - .minImageCount = imageCount, - .imageFormat = surfaceFormat.format, - .imageColorSpace = surfaceFormat.colorSpace, - .imageExtent = extent, - .imageArrayLayers = 1, - .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - }; - - QueueFamilyIndices indices = vulkan_find_queue_families(s.vk.physical_device); - - uint32_t queueFamilyIndices[] = {indices.graphicsAndComputeFamily, indices.presentFamily}; - - if (indices.graphicsAndComputeFamily != indices.presentFamily) { - createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - createInfo.queueFamilyIndexCount = 2; - createInfo.pQueueFamilyIndices = queueFamilyIndices; - } else { - createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - createInfo.queueFamilyIndexCount = 0; // Optional - createInfo.pQueueFamilyIndices = NULL; // Optional - } - - createInfo.preTransform = swapChainSupport.capabilities.currentTransform; - createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - createInfo.presentMode = presentMode; - createInfo.clipped = VK_TRUE; - createInfo.oldSwapchain = VK_NULL_HANDLE; - - VK_CHECK(vkCreateSwapchainKHR(s.vk.device, &createInfo, NULL, &s.vk.swapchain.handle)); - /* if (result != VK_SUCCESS) { */ - /* vk_log(VK_ERROR, "ERROR: failed to create swap chain! %s\n", string_VkResult(result)); */ - /* } */ - - VK_CHECK(vkGetSwapchainImagesKHR(s.vk.device, s.vk.swapchain.handle, &s.vk.swapchain.image_count, NULL)); - //vk_log(VK_INFO, "vk_swap_chain_images count: %d\n", s.vk.swapchain.image_count); - // todo alloc space for images - VK_CHECK(vkGetSwapchainImagesKHR(s.vk.device, s.vk.swapchain.handle, &s.vk.swapchain.image_count, s.vk.swapchain.images)); - - s.vk.swapchain.image_format = surfaceFormat.format; - s.vk.swapchain.extent = extent; - - vk_log(VK_INFO, "Vulkan swapchain created!\n"); -} - - -VkImageView -create_image_view(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels) -{ - VkImageViewCreateInfo viewInfo = {0}; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.image = image; - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = format; - viewInfo.subresourceRange.aspectMask = aspectFlags; - viewInfo.subresourceRange.baseMipLevel = 0; - viewInfo.subresourceRange.levelCount = mipLevels; - viewInfo.subresourceRange.baseArrayLayer = 0; - viewInfo.subresourceRange.layerCount = 1; - - VkImageView imageView; - VK_CHECK(vkCreateImageView(s.vk.device, &viewInfo, NULL, &imageView)); - - return imageView; -} - -void -vulkan_create_image_views() -{ - for (size_t i = 0; i < s.vk.swapchain.image_count; i++) { - s.vk.swapchain.image_views[i] = create_image_view(s.vk.swapchain.images[i], s.vk.swapchain.image_format, VK_IMAGE_ASPECT_COLOR_BIT, 1); - } - vk_log(VK_INFO, "Vulkan image views created!\n"); -} - VkShaderModule createShaderModule(const char * code, long size) { @@ -719,59 +383,6 @@ load_compile_shader_data(const char * path, shaderc_shader_kind shader_kind) return result; } -uint32_t -findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) -{ - VkPhysicalDeviceMemoryProperties memProperties; - vkGetPhysicalDeviceMemoryProperties(s.vk.physical_device, &memProperties); - - for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { - if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { - return i; - } - } - - vk_log(VK_ERROR, "failed to find suitable memory type!\n"); - return 9999; -} - -VkCommandBuffer -beginSingleTimeCommands() -{ - VkCommandBufferAllocateInfo allocInfo = {0}; - allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandPool = s.vk_command_pool; - allocInfo.commandBufferCount = 1; - - VkCommandBuffer commandBuffer; - VK_CHECK(vkAllocateCommandBuffers(s.vk.device, &allocInfo, &commandBuffer)); - - VkCommandBufferBeginInfo beginInfo = {0}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - VK_CHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo)); - - return commandBuffer; -} - -void -endSingleTimeCommands(VkCommandBuffer commandBuffer) -{ - VK_CHECK(vkEndCommandBuffer(commandBuffer)); - - VkSubmitInfo submitInfo = {0}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; - - VK_CHECK(vkQueueSubmit(s.vk_graphics_and_compute_queue, 1, &submitInfo, VK_NULL_HANDLE)); - VK_CHECK(vkQueueWaitIdle(s.vk_graphics_and_compute_queue)); - - vkFreeCommandBuffers(s.vk.device, s.vk_command_pool, 1, &commandBuffer); -} - VkFormat findSupportedFormat(VkFormat *candidates, size_t n, VkImageTiling tiling, @@ -809,10 +420,10 @@ vulkan_create_depth_resources() vks_create_image(s.vk, s.vk.swapchain.extent.width, s.vk.swapchain.extent.height, 1, depth_format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, s.msaa_samples, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, s.vk.msaa_samples, &s.depth_image); - s.depth_image.view = create_image_view(s.depth_image.handle, depth_format, - VK_IMAGE_ASPECT_DEPTH_BIT, 1); + s.depth_image.view = vks_create_image_view(s.vk, s.depth_image.handle, depth_format, + VK_IMAGE_ASPECT_DEPTH_BIT, 1); vks_transition_image_layout_info transition_info = { 0 }; transition_info.cmd_info.vk = s.vk; @@ -839,9 +450,9 @@ void vulkan_create_color_resources() { colorFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, s.msaa_samples, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, s.vk.msaa_samples, &s.color_image); - s.color_image.view = create_image_view(s.color_image.handle, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); + s.color_image.view = vks_create_image_view(s.vk, s.color_image.handle, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); } void @@ -972,7 +583,7 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode) VkPipelineMultisampleStateCreateInfo multisampling = {0}; multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.sampleShadingEnable = VK_FALSE; - multisampling.rasterizationSamples = s.msaa_samples; + multisampling.rasterizationSamples = s.vk.msaa_samples; multisampling.minSampleShading = 1.0f; // Optional multisampling.pSampleMask = NULL; // Optional multisampling.alphaToCoverageEnable = VK_FALSE; // Optional @@ -1441,8 +1052,7 @@ recreateSwapChain() cleanupSwapChain(); - vulkan_create_swap_chain(); - vulkan_create_image_views(); + _vulkan_create_swap_chain(&s.vk); vulkan_create_color_resources(); vulkan_create_depth_resources(); } @@ -1665,7 +1275,7 @@ vulkan_create_texture_image() void vulkan_create_texture_image_view() { - s.texture_image.view = create_image_view(s.texture_image.handle, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT, s.vk_mip_levels); + s.texture_image.view = vks_create_image_view(s.vk, s.texture_image.handle, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT, s.vk_mip_levels); } void vulkan_create_texture_sampler() { @@ -1765,7 +1375,6 @@ load_model_obj() vk_log(VK_INFO, "[obj] %s: Loaded %ld vertices %ld indices\n", s.model_path, s.vertices_count, s.indices_count); - fast_obj_destroy(m); } @@ -1941,8 +1550,6 @@ void vulkan_create_compute_stuff() VK_CHECK(vkCreateDescriptorSetLayout(s.vk.device, &layoutInfo, NULL, &s.vk_compute_descriptor_set_layout)); - - VkComputePipelineCreateInfo pipelineInfo = {0}; pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pipelineInfo.layout = s.vk_compute_pipeline_layout; @@ -1972,16 +1579,8 @@ init_vulkan() vk_log(VK_WARN, " DEBUG ON \n"); vk_log(VK_WARN, "====================================\n"); - //vulkan_create_instance(); - s.vk.instance = - vks_create_instance(enableValidationLayers, validation_layers, - validation_layer_count, s.vk.window); - // vulkan_setup_debug_messenger(); - vulkan_create_surface(); - vulkan_pick_physical_device(); - vulkan_create_logical_device(); - vulkan_create_swap_chain(); - vulkan_create_image_views(); + vks_create_vulkan_context(&s.vk, &s.vk_graphics_and_compute_queue, &s.vk_present_queue); + vulkan_create_descriptor_set_layout(); vulkan_create_graphics_pipeline(s.polygon_mode); //vulkan_create_compute_stuff(); @@ -2040,7 +1639,7 @@ close_vulkan() vkDestroyPipelineLayout(s.vk.device, s.graphics_pipeline.layout, NULL); vkDestroyDevice(s.vk.device, NULL); vkDestroySurfaceKHR(s.vk.instance, s.vk.surface, NULL); - /* if (enableValidationLayers) { */ + /* if (enable_validation_layers) { */ /* DestroyDebugUtilsMessengerEXT(s.vk.instance, s.vk_debug_messenger, NULL); */ /* } */ vkDestroyInstance(s.vk.instance, NULL); @@ -2113,7 +1712,8 @@ updateUniformBuffer(uint32_t currentImage, float dt) float prev_time = 0; void -draw_frame() { +draw_frame() +{ float time = current_time(); float dt = time - prev_time; -- cgit v1.2.3