Open github-actions[bot] opened 1 month ago
https://github.com/mge-engine/mge/blob/344ac4b7cae078a7e8196c088d61d4b57cd4b2d2/src/modules/vulkan/render_context.cpp#L563
#ifdef MGE_COMPILER_MSVC # pragma warning(pop) #endif } void render_context::clear_functions() { MGE_DEBUG_TRACE(VULKAN) << "Clear device functions"; #ifdef MGE_COMPILER_MSVC # pragma warning(push) # pragma warning(disable : 4191) #endif #define RESOLVE(X) this->X = nullptr; #define BASIC_INSTANCE_FUNCTION(X) RESOLVE(X) #define INSTANCE_FUNCTION(X) RESOLVE(X) #define DEVICE_FUNCTION(X) RESOLVE(X) #include "vulkan_core.inc" #ifdef MGE_OS_WINDOWS # include "vulkan_win32.inc" #endif #undef BASIC_INSTANCE_FUNCTION #undef INSTANCE_FUNCTION #undef DEVICE_FUNCTION #undef RESOLVE #ifdef MGE_COMPILER_MSVC # pragma warning(pop) #endif } void render_context::get_device_queue() { MGE_DEBUG_TRACE(VULKAN) << "Get device queue"; vkGetDeviceQueue(m_device, m_render_system->graphics_queue_index(), 0, &m_queue); } void render_context::fetch_surface_capabilities() { MGE_DEBUG_TRACE(VULKAN) << "Fetch surface capabilities"; CHECK_VK_CALL( m_render_system->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( m_render_system->physical_device(), m_surface, &m_surface_capabilities)); enumerate( [this](uint32_t* count, VkSurfaceFormatKHR* data) { CHECK_VK_CALL( m_render_system->vkGetPhysicalDeviceSurfaceFormatsKHR( m_render_system->physical_device(), m_surface, count, data)); }, m_surface_formats); MGE_DEBUG_TRACE(VULKAN) << "Found " << m_surface_formats.size() << " surface formats"; size_t format_index = m_surface_formats.size(); for (const auto& format : m_surface_formats) { MGE_DEBUG_TRACE(VULKAN) << " " << format.format << "/" << format.colorSpace; if (format.format == VK_FORMAT_B8G8R8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { format_index = &format - m_surface_formats.data(); } } if (format_index < m_surface_formats.size()) { m_used_surface_format = m_surface_formats[format_index]; } else { m_used_surface_format = m_surface_formats[0]; } MGE_DEBUG_TRACE(VULKAN) << "Using surface format " << m_used_surface_format.format << "/" << m_used_surface_format.colorSpace; enumerate( [this](uint32_t* count, VkPresentModeKHR* data) { CHECK_VK_CALL( m_render_system->vkGetPhysicalDeviceSurfacePresentModesKHR( m_render_system->physical_device(), m_surface, count, data)); }, m_surface_present_modes); MGE_DEBUG_TRACE(VULKAN) << "Found " << m_surface_present_modes.size() << " present modes"; for (const auto& f : m_surface_present_modes) { MGE_DEBUG_TRACE(VULKAN) << " " << f; } m_used_present_mode = VK_PRESENT_MODE_FIFO_KHR; for (const auto& mode : m_surface_present_modes) { if (mode == VK_PRESENT_MODE_MAILBOX_KHR) { m_used_present_mode = VK_PRESENT_MODE_MAILBOX_KHR; break; } } MGE_DEBUG_TRACE(VULKAN) << "Using present mode " << m_used_present_mode; } void render_context::choose_extent() { MGE_DEBUG_TRACE(VULKAN) << "Choose extent"; if (m_surface_capabilities.currentExtent.width != UINT32_MAX) { m_extent = m_surface_capabilities.currentExtent; } else { m_extent.width = std::max(m_surface_capabilities.minImageExtent.width, std::min(m_surface_capabilities.maxImageExtent.width, m_window.extent().width)); m_extent.height = std::max(m_surface_capabilities.minImageExtent.height, std::min(m_surface_capabilities.maxImageExtent.height, m_window.extent().height)); } MGE_DEBUG_TRACE(VULKAN) << "Using extent " << m_extent.width << "x" << m_extent.height; } void render_context::create_swap_chain() { MGE_DEBUG_TRACE(VULKAN) << "Create swap chain"; uint32_t image_count = m_surface_capabilities.minImageCount + 1; if (m_surface_capabilities.maxImageCount > 0 && image_count > m_surface_capabilities.maxImageCount) { image_count = m_surface_capabilities.maxImageCount; } MGE_DEBUG_TRACE(VULKAN) << "Using " << image_count << " images"; VkSwapchainCreateInfoKHR create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; create_info.surface = m_surface; create_info.minImageCount = image_count; create_info.imageFormat = m_used_surface_format.format; create_info.imageColorSpace = m_used_surface_format.colorSpace; create_info.imageExtent = m_extent; create_info.imageArrayLayers = 1; create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; uint32_t queue_indices[] = {m_render_system->graphics_queue_index(), m_render_system->present_queue_index()}; if (m_render_system->graphics_queue_index() != m_render_system->present_queue_index()) { create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; create_info.queueFamilyIndexCount = 2; create_info.pQueueFamilyIndices = queue_indices; } else { create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; } create_info.preTransform = m_surface_capabilities.currentTransform; create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; create_info.presentMode = m_used_present_mode; create_info.clipped = VK_TRUE; create_info.oldSwapchain = VK_NULL_HANDLE; CHECK_VK_CALL(vkCreateSwapchainKHR(m_device, &create_info, nullptr, &m_swap_chain_khr)); enumerate( [this](uint32_t* count, VkImage* data) { CHECK_VK_CALL(vkGetSwapchainImagesKHR(m_device, m_swap_chain_khr, count, data)); }, m_swap_chain_images); MGE_DEBUG_TRACE(VULKAN) << "Created swap chain with " << m_swap_chain_images.size() << " images"; } void render_context::create_image_views() { MGE_DEBUG_TRACE(VULKAN) << "Create image views"; m_swap_chain_image_views.resize(m_swap_chain_images.size()); for (size_t i = 0; i < m_swap_chain_images.size(); ++i) { VkImageViewCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; create_info.image = m_swap_chain_images[i]; create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; create_info.format = m_used_surface_format.format; create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; create_info.subresourceRange.baseMipLevel = 0; create_info.subresourceRange.levelCount = 1; create_info.subresourceRange.baseArrayLayer = 0; create_info.subresourceRange.layerCount = 1; CHECK_VK_CALL(vkCreateImageView(m_device, &create_info, nullptr, &m_swap_chain_image_views[i])); } } void render_context::create_allocator() { MGE_DEBUG_TRACE(VULKAN) << "Create allocator"; VmaVulkanFunctions vk_functions = {}; vk_functions.vkGetInstanceProcAddr = m_render_system->library().vkGetInstanceProcAddr; vk_functions.vkGetDeviceProcAddr = m_render_system->vkGetDeviceProcAddr; VmaAllocatorCreateInfo allocator_info = {}; allocator_info.physicalDevice = m_render_system->physical_device(); allocator_info.device = m_device; allocator_info.instance = m_render_system->instance(); allocator_info.flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT; allocator_info.pVulkanFunctions = &vk_functions; allocator_info.vulkanApiVersion = VK_API_VERSION_1_3; CHECK_VK_CALL(vmaCreateAllocator(&allocator_info, &m_allocator)); } void render_context::create_render_pass() { MGE_DEBUG_TRACE(VULKAN) << "Create render pass"; VkAttachmentDescription color_attachment = {}; // single color buffer used for presentation color_attachment.format = m_used_surface_format.format; // TODO: multisampling in vulkan color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; // don't care about content of the image at beginning color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // store content of the image for later color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // nothing needed for stencil color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; VkAttachmentReference color_attachment_ref = {}; color_attachment_ref.attachment = 0; color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &color_attachment_ref; VkSubpassDependency dependency = {}; dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
https://github.com/mge-engine/mge/blob/344ac4b7cae078a7e8196c088d61d4b57cd4b2d2/src/modules/vulkan/render_context.cpp#L563