std::pair<VkFormat, VkColorSpaceKHR> SwapChain::ChooseFormat(rhi::GfxSetting & gfxSetting) { uint32_t formatCount; K3D_VK_VERIFY(fpGetPhysicalDeviceSurfaceFormatsKHR(GetPhysicalDevice(), m_Surface, &formatCount, NULL)); std::vector<VkSurfaceFormatKHR> surfFormats(formatCount); K3D_VK_VERIFY(fpGetPhysicalDeviceSurfaceFormatsKHR(GetPhysicalDevice(), m_Surface, &formatCount, surfFormats.data())); VkFormat colorFormat; VkColorSpaceKHR colorSpace; if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) { colorFormat = g_FormatTable[gfxSetting.ColorFormat]; } else { K3D_ASSERT(formatCount >= 1); colorFormat = surfFormats[0].format; } colorSpace = surfFormats[0].colorSpace; return std::make_pair(colorFormat, colorSpace); }
bool VulkanContext::InitQueue() { // Iterate over each queue to learn whether it supports presenting: VkBool32 *supportsPresent = new VkBool32[queue_count]; for (uint32_t i = 0; i < queue_count; i++) { vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices_[physical_device_], i, surface_, &supportsPresent[i]); } // Search for a graphics queue and a present queue in the array of queue // families, try to find one that supports both uint32_t graphicsQueueNodeIndex = UINT32_MAX; uint32_t presentQueueNodeIndex = UINT32_MAX; for (uint32_t i = 0; i < queue_count; i++) { if ((queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) { if (graphicsQueueNodeIndex == UINT32_MAX) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == VK_TRUE) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex == UINT32_MAX) { // If didn't find a queue that supports both graphics and present, then // find a separate present queue. for (uint32_t i = 0; i < queue_count; ++i) { if (supportsPresent[i] == VK_TRUE) { presentQueueNodeIndex = i; break; } } } delete[] supportsPresent; // Generate error if could not find both a graphics and a present queue if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX) { ELOG("Could not find a graphics and a present queue"); return false; } graphics_queue_family_index_ = graphicsQueueNodeIndex; // Get the list of VkFormats that are supported: uint32_t formatCount = 0; VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, nullptr); _assert_msg_(G3D, res == VK_SUCCESS, "Failed to get formats for device %p: %d surface: %p", physical_devices_[physical_device_], (int)res, surface_); if (res != VK_SUCCESS) { return false; } std::vector<VkSurfaceFormatKHR> surfFormats(formatCount); res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, surfFormats.data()); assert(res == VK_SUCCESS); if (res != VK_SUCCESS) { return false; } // If the format list includes just one entry of VK_FORMAT_UNDEFINED, // the surface has no preferred format. Otherwise, at least one // supported format will be returned. if (formatCount == 0 || (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED)) { ILOG("swapchain_format: Falling back to B8G8R8A8_UNORM"); swapchainFormat_ = VK_FORMAT_B8G8R8A8_UNORM; } else { swapchainFormat_ = VK_FORMAT_UNDEFINED; for (uint32_t i = 0; i < formatCount; ++i) { if (surfFormats[i].colorSpace != VK_COLORSPACE_SRGB_NONLINEAR_KHR) { continue; } if (surfFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM || surfFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) { swapchainFormat_ = surfFormats[i].format; break; } } if (swapchainFormat_ == VK_FORMAT_UNDEFINED) { // Okay, take the first one then. swapchainFormat_ = surfFormats[0].format; } ILOG("swapchain_format: %d (/%d)", swapchainFormat_, formatCount); } vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_); ILOG("gfx_queue_: %p", gfx_queue_); return true; }