From d60e44d9899be1ac8a954a288c193bd7d79792d0 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Wed, 19 Feb 2025 16:50:37 -0800 Subject: [PATCH] vk: reformat, cleanup VulkanPlatform.cpp (#8457) --- .../src/vulkan/platform/VulkanPlatform.cpp | 311 +++++++++--------- 1 file changed, 156 insertions(+), 155 deletions(-) diff --git a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp index e793fa8b42..5c9c0deda6 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp @@ -45,7 +45,7 @@ namespace filament::backend { namespace { -constexpr uint32_t const INVALID_VK_INDEX = 0xFFFFFFFF; +constexpr uint32_t INVALID_VK_INDEX = 0xFFFFFFFF; using ExtensionSet = VulkanPlatform::ExtensionSet; @@ -56,25 +56,25 @@ inline bool setContains(ExtensionSet const& set, utils::CString const& extension #if FVK_ENABLED(FVK_DEBUG_VALIDATION) // These strings need to be allocated outside a function stack const std::string_view DESIRED_LAYERS[] = { - "VK_LAYER_KHRONOS_validation", + "VK_LAYER_KHRONOS_validation", #if FVK_ENABLED(FVK_DEBUG_DUMP_API) - "VK_LAYER_LUNARG_api_dump", + "VK_LAYER_LUNARG_api_dump", #endif #if defined(ENABLE_RENDERDOC) - "VK_LAYER_RENDERDOC_Capture", + "VK_LAYER_RENDERDOC_Capture", #endif }; FixedCapacityVector getEnabledLayers() { constexpr size_t kMaxEnabledLayersCount = sizeof(DESIRED_LAYERS) / sizeof(DESIRED_LAYERS[0]); - const FixedCapacityVector availableLayers + FixedCapacityVector const availableLayers = fvkutils::enumerate(vkEnumerateInstanceLayerProperties); auto enabledLayers = FixedCapacityVector::with_capacity(kMaxEnabledLayersCount); for (auto const& desired: DESIRED_LAYERS) { - for (const VkLayerProperties& layer: availableLayers) { - const std::string_view availableLayer(layer.layerName); + for (VkLayerProperties const& layer: availableLayers) { + std::string_view const availableLayer(layer.layerName); if (availableLayer == desired) { enabledLayers.push_back(desired.data()); break; @@ -127,13 +127,13 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) { // Since we don't have any vendor-specific workarounds yet, there's no need to make this // mapping in code. The "deviceName" string informally reveals the marketing name for the // GPU. (e.g., Quadro) - const uint32_t driverVersion = deviceProperties.driverVersion; - const uint32_t vendorID = deviceProperties.vendorID; - const uint32_t deviceID = deviceProperties.deviceID; - const int major = VK_VERSION_MAJOR(deviceProperties.apiVersion); - const int minor = VK_VERSION_MINOR(deviceProperties.apiVersion); + uint32_t const driverVersion = deviceProperties.driverVersion; + uint32_t const vendorID = deviceProperties.vendorID; + uint32_t const deviceID = deviceProperties.deviceID; + int const major = VK_VERSION_MAJOR(deviceProperties.apiVersion); + int const minor = VK_VERSION_MINOR(deviceProperties.apiVersion); - const FixedCapacityVector physicalDevices + FixedCapacityVector const physicalDevices = fvkutils::enumerate(vkEnumeratePhysicalDevices, instance); FVK_LOGI << "Selected physical device '" << deviceProperties.deviceName << "' from " @@ -148,8 +148,8 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) { void printDepthFormats(VkPhysicalDevice device) { // For diagnostic purposes, print useful information about available depth formats. // Note that Vulkan is more constrained than OpenGL ES 3.1 in this area. - const VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT - | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; + constexpr VkFormatFeatureFlags required = + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; FVK_LOGI << "Sampleable depth formats: "; for (VkFormat format : fvkutils::ALL_VK_FORMATS) { VkFormatProperties props; @@ -168,11 +168,13 @@ ExtensionSet getInstanceExtensions(ExtensionSet const& externallyRequiredExts = VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, - // Request these if available. + // Request these if available. #if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) VK_EXT_DEBUG_UTILS_EXTENSION_NAME, #endif +#if defined(__APPLE__) VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, +#endif #if FVK_ENABLED(FVK_DEBUG_VALIDATION) VK_EXT_DEBUG_REPORT_EXTENSION_NAME, @@ -182,8 +184,8 @@ ExtensionSet getInstanceExtensions(ExtensionSet const& externallyRequiredExts = FixedCapacityVector const availableExts = fvkutils::enumerate(vkEnumerateInstanceExtensionProperties, static_cast(nullptr) /* pLayerName */); - for (auto const& extProps: availableExts) { - utils::CString name { extProps.extensionName }; + for (auto const& extension: availableExts) { + utils::CString name { extension.extensionName }; // To workaround an Adreno bug where the extension name could be of 0 length. if (name.size() == 0) { @@ -200,22 +202,24 @@ ExtensionSet getInstanceExtensions(ExtensionSet const& externallyRequiredExts = ExtensionSet getDeviceExtensions(VkPhysicalDevice device) { ExtensionSet const TARGET_EXTS = { #if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) - VK_EXT_DEBUG_MARKER_EXTENSION_NAME, + VK_EXT_DEBUG_MARKER_EXTENSION_NAME, #endif - // We only support external image for Android for now, but nothing bars us from - // supporting other platforms. + // We only support external image for Android for now, but nothing bars us from + // supporting other platforms. #if defined(__ANDROID__) - VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, - VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, - VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, - VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, - #endif - - VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME, - VK_KHR_MAINTENANCE1_EXTENSION_NAME, - VK_KHR_MAINTENANCE2_EXTENSION_NAME, - VK_KHR_MAINTENANCE3_EXTENSION_NAME, - VK_KHR_MULTIVIEW_EXTENSION_NAME, + VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, + VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, + VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, + VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, +#endif + // MoltenVk is the only non-conformant implementation we're interested in. +#if defined(__APPLE__) + VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME, +#endif + VK_KHR_MAINTENANCE1_EXTENSION_NAME, + VK_KHR_MAINTENANCE2_EXTENSION_NAME, + VK_KHR_MAINTENANCE3_EXTENSION_NAME, + VK_KHR_MULTIVIEW_EXTENSION_NAME, }; ExtensionSet exts; // Identify supported physical device extensions @@ -238,9 +242,18 @@ ExtensionSet getDeviceExtensions(VkPhysicalDevice device) { } VkInstance createInstance(ExtensionSet const& requiredExts) { + // Create the Vulkan instance. + VkApplicationInfo appInfo = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pEngineName = "Filament", + .apiVersion = + VK_MAKE_API_VERSION(0, FVK_REQUIRED_VERSION_MAJOR, FVK_REQUIRED_VERSION_MINOR, 0), + }; + VkInstance instance; VkInstanceCreateInfo instanceCreateInfo = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pApplicationInfo = &appInfo, }; bool validationFeaturesSupported = false; @@ -271,10 +284,10 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { } #endif // FVK_ENABLED(FVK_DEBUG_VALIDATION) - // The Platform class can require 1 or 2 instance extensions, plus we'll request at most 5 - // instance extensions here in the common code. So that's a max of 7. - static constexpr uint32_t MAX_INSTANCE_EXTENSION_COUNT = 8; - const char* ppEnabledExtensions[MAX_INSTANCE_EXTENSION_COUNT]; + // The Platform class can require 1 or 2 instance extensions, plus we'll request at most 6 + // instance extensions here in the common code. So that's a max of 8. + constexpr uint32_t MAX_INSTANCE_EXTENSION_COUNT = 8; + char const* ppEnabledExtensions[MAX_INSTANCE_EXTENSION_COUNT]; uint32_t enabledExtensionCount = 0; if (validationFeaturesSupported) { @@ -286,29 +299,23 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { ppEnabledExtensions[enabledExtensionCount++] = requiredExt.data(); } - // Create the Vulkan instance. - VkApplicationInfo appInfo = {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pEngineName = "Filament"; - appInfo.apiVersion - = VK_MAKE_API_VERSION(0, FVK_REQUIRED_VERSION_MAJOR, FVK_REQUIRED_VERSION_MINOR, 0); - instanceCreateInfo.pApplicationInfo = &appInfo; instanceCreateInfo.enabledExtensionCount = enabledExtensionCount; instanceCreateInfo.ppEnabledExtensionNames = ppEnabledExtensions; if (setContains(requiredExts, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) { instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; } - VkValidationFeaturesEXT features = { - .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, - }; + // Validation features VkValidationFeatureEnableEXT enables[] = { VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT, }; + VkValidationFeaturesEXT features = { + .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, + .enabledValidationFeatureCount = sizeof(enables) / sizeof(enables[0]), + .pEnabledValidationFeatures = enables, + }; if (validationFeaturesSupported) { - features.enabledValidationFeatureCount = sizeof(enables) / sizeof(enables[0]); - features.pEnabledValidationFeatures = enables; chainStruct(&instanceCreateInfo, &features); } @@ -336,16 +343,15 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice, requestExtensions.push_back(ext.data()); } VkDeviceQueueCreateInfo deviceQueueCreateInfo[2] = {}; - deviceQueueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - deviceQueueCreateInfo[0].queueFamilyIndex = graphicsQueueFamilyIndex; - deviceQueueCreateInfo[0].queueCount = 1; - deviceQueueCreateInfo[0].pQueuePriorities = &queuePriority[0]; + deviceQueueCreateInfo[0] = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueFamilyIndex = graphicsQueueFamilyIndex, + .queueCount = 1, + .pQueuePriorities = &queuePriority[0], + }; // Protected queue - deviceQueueCreateInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + deviceQueueCreateInfo[1] = deviceQueueCreateInfo[0]; deviceQueueCreateInfo[1].flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT; - deviceQueueCreateInfo[1].queueFamilyIndex = protectedGraphicsQueueFamilyIndex; - deviceQueueCreateInfo[1].queueCount = 1; - deviceQueueCreateInfo[1].pQueuePriorities = &queuePriority[0]; bool const hasProtectedQueue = protectedGraphicsQueueFamilyIndex != INVALID_VK_INDEX; deviceCreateInfo.queueCreateInfoCount = hasProtectedQueue ? 2 : 1; @@ -354,21 +360,21 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice, // We could simply enable all supported features, but since that may have performance // consequences let's just enable the features we need. VkPhysicalDeviceFeatures enabledFeatures{ - .depthClamp = features.features.depthClamp, - .samplerAnisotropy = features.features.samplerAnisotropy, - .textureCompressionETC2 = features.features.textureCompressionETC2, - .textureCompressionBC = features.features.textureCompressionBC, - .shaderClipDistance = features.features.shaderClipDistance, + .depthClamp = features.features.depthClamp, + .samplerAnisotropy = features.features.samplerAnisotropy, + .textureCompressionETC2 = features.features.textureCompressionETC2, + .textureCompressionBC = features.features.textureCompressionBC, + .shaderClipDistance = features.features.shaderClipDistance, }; - deviceCreateInfo.pEnabledFeatures = &enabledFeatures; + deviceCreateInfo.enabledExtensionCount = (uint32_t) requestExtensions.size(); deviceCreateInfo.ppEnabledExtensionNames = requestExtensions.data(); VkPhysicalDevicePortabilitySubsetFeaturesKHR portability = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR, .imageViewFormatSwizzle = VK_TRUE, - .imageView2DOn3DImage = requestImageView2DOn3DImage ? VK_TRUE : VK_FALSE, + .imageView2DOn3DImage = requestImageView2DOn3DImage ? VK_TRUE : VK_FALSE, .mutableComparisonSamplers = VK_TRUE, }; if (setContains(deviceExtensions, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) { @@ -404,7 +410,8 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice, // This method is used to enable/disable extensions based on external factors (i.e. // driver/device workarounds). std::tuple pruneExtensions(VkPhysicalDevice device, - ExtensionSet const& instExts, ExtensionSet const& deviceExts) { + Platform::DriverConfig const& driverConfig, ExtensionSet const& instExts, + ExtensionSet const& deviceExts) noexcept { ExtensionSet newInstExts = instExts; ExtensionSet newDeviceExts = deviceExts; @@ -424,6 +431,10 @@ std::tuple pruneExtensions(VkPhysicalDevice device, } #endif + if (driverConfig.stereoscopicType != StereoscopicType::MULTIVIEW) { + newDeviceExts.erase(VK_KHR_MULTIVIEW_EXTENSION_NAME); + } + return std::tuple(newInstExts, newDeviceExts); } @@ -457,22 +468,17 @@ uint32_t identifyGraphicsQueueFamilyIndex(VkPhysicalDevice physicalDevice, VkQue // Enum based on: // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceType.html inline int deviceTypeOrder(VkPhysicalDeviceType deviceType) { - switch (deviceType) { - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - return 5; - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - return 4; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - return 3; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - return 2; - case VK_PHYSICAL_DEVICE_TYPE_OTHER: - return 1; - default: - FVK_LOGW << "deviceTypeOrder: Unexpected deviceType: " << deviceType - << utils::io::endl; - return -1; + constexpr std::array TYPES = { + VK_PHYSICAL_DEVICE_TYPE_OTHER, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + VK_PHYSICAL_DEVICE_TYPE_CPU, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + }; + if (auto itr = std::find(TYPES.begin(), TYPES.end(), deviceType); itr != TYPES.end()) { + return std::distance(TYPES.begin(), itr); } + return -1; } VkPhysicalDevice selectPhysicalDevice(VkInstance instance, @@ -515,20 +521,19 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, FixedCapacityVector const extensions = fvkutils::enumerate(vkEnumerateDeviceExtensionProperties, candidateDevice, static_cast(nullptr) /* pLayerName */); - bool supportsSwapchain = false; - for (auto const& extension: extensions) { - if (!strcmp(extension.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) { - supportsSwapchain = true; - break; - } - } + bool const supportsSwapchain = + std::any_of(extensions.begin(), extensions.end(), [](auto const& ext) { + return !strcmp(ext.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME); + }); if (!supportsSwapchain) { continue; } - deviceList[deviceInd].device = candidateDevice; - deviceList[deviceInd].deviceType = targetDeviceProperties.deviceType; - deviceList[deviceInd].index = deviceInd; - deviceList[deviceInd].name = targetDeviceProperties.deviceName; + deviceList[deviceInd] = { + .device = candidateDevice, + .deviceType = targetDeviceProperties.deviceType, + .index = (int8_t) deviceInd, + .name = targetDeviceProperties.deviceName, + }; } FILAMENT_CHECK_PRECONDITION(gpuPreference.index < static_cast(deviceList.size())) @@ -569,7 +574,7 @@ fvkutils::VkFormatList findAttachmentDepthStencilFormats(VkPhysicalDevice device VkFormatFeatureFlags const features = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; // The ordering here indicates the preference of choosing depth+stencil format. - VkFormat const formats[] = { + constexpr VkFormat formats[] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_X8_D24_UNORM_PACK32, @@ -591,7 +596,7 @@ fvkutils::VkFormatList findAttachmentDepthStencilFormats(VkPhysicalDevice device fvkutils::VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) { std::vector selectedFormats; - VkFormatFeatureFlags const required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | + constexpr VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; for (VkFormat format : fvkutils::ALL_VK_FORMATS) { if (fvkutils::isVkDepthFormat(format)) { @@ -651,7 +656,7 @@ void VulkanPlatform::terminate() { // This is the main entry point for context creation. Driver* VulkanPlatform::createDriver(void* sharedContext, - const Platform::DriverConfig& driverConfig) noexcept { + Platform::DriverConfig const& driverConfig) noexcept { // Load Vulkan entry points. FILAMENT_CHECK_POSTCONDITION(bluevk::initialize()) << "BlueVK is unable to load entry points."; @@ -679,7 +684,6 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, } VulkanContext context; - ExtensionSet instExts; // If using a shared context, we do not assume any extensions. if (!mImpl->mSharedContext) { @@ -704,9 +708,9 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, instExts.merge(getRequiredInstanceExtensions()); } - - mImpl->mInstance - = mImpl->mInstance == VK_NULL_HANDLE ? createInstance(instExts) : mImpl->mInstance; + if (mImpl->mInstance == VK_NULL_HANDLE) { + mImpl->mInstance = createInstance(instExts); + } assert_invariant(mImpl->mInstance != VK_NULL_HANDLE); bluevk::bindInstance(mImpl->mInstance); @@ -716,9 +720,9 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, FILAMENT_CHECK_PRECONDITION(!(hasGPUPreference && sharedContext)) << "Cannot both share context and indicate GPU preference"; - mImpl->mPhysicalDevice = mImpl->mPhysicalDevice == VK_NULL_HANDLE - ? selectPhysicalDevice(mImpl->mInstance, pref) - : mImpl->mPhysicalDevice; + if (mImpl->mPhysicalDevice == VK_NULL_HANDLE) { + mImpl->mPhysicalDevice = selectPhysicalDevice(mImpl->mInstance, pref); + } assert_invariant(mImpl->mPhysicalDevice != VK_NULL_HANDLE); printDeviceInfo(mImpl->mInstance, mImpl->mPhysicalDevice); @@ -732,59 +736,52 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, chainStruct(&context.mPhysicalDeviceFeatures, &queryProtectedMemoryFeatures); chainStruct(&context.mPhysicalDeviceProperties, &protectedMemoryProperties); + // We know we need to allocate the protected version of the VK objects + context.mProtectedMemorySupported = + static_cast(queryProtectedMemoryFeatures.protectedMemory); + // Initialize the following fields: physicalDeviceProperties, memoryProperties, // physicalDeviceFeatures, graphicsQueueFamilyIndex. vkGetPhysicalDeviceProperties2(mImpl->mPhysicalDevice, &context.mPhysicalDeviceProperties); vkGetPhysicalDeviceFeatures2(mImpl->mPhysicalDevice, &context.mPhysicalDeviceFeatures); vkGetPhysicalDeviceMemoryProperties(mImpl->mPhysicalDevice, &context.mMemoryProperties); - mImpl->mGraphicsQueueFamilyIndex - = mImpl->mGraphicsQueueFamilyIndex == INVALID_VK_INDEX - ? identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice, - VK_QUEUE_GRAPHICS_BIT) - : mImpl->mGraphicsQueueFamilyIndex; - assert_invariant(mImpl->mGraphicsQueueFamilyIndex != INVALID_VK_INDEX); - - // We know we need to allocate the protected version of the VK objects - context.mProtectedMemorySupported = - static_cast(queryProtectedMemoryFeatures.protectedMemory); - if (context.mProtectedMemorySupported) { - mImpl->mProtectedGraphicsQueueFamilyIndex - = identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice, - (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_PROTECTED_BIT)); - assert_invariant(mImpl->mProtectedGraphicsQueueFamilyIndex != INVALID_VK_INDEX); - } - - // Only enable shaderClipDistance if we are doing instanced stereoscopic rendering. - if (context.mPhysicalDeviceFeatures.features.shaderClipDistance == VK_TRUE - && driverConfig.stereoscopicType != StereoscopicType::INSTANCED) { - context.mPhysicalDeviceFeatures.features.shaderClipDistance = VK_FALSE; + if (mImpl->mGraphicsQueueFamilyIndex == INVALID_VK_INDEX) { + mImpl->mGraphicsQueueFamilyIndex = + identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice, VK_QUEUE_GRAPHICS_BIT); } // At this point, we should have a family index that points to a family that has > 0 queues for // graphics. In which case, we will allocate one queue for all of Filament (and assumes at least // one has been allocated by the client if context was shared). If the index of the target queue // within the family hasn't been provided by the client, we assume it to be 0. - mImpl->mGraphicsQueueIndex - = mImpl->mGraphicsQueueIndex == INVALID_VK_INDEX ? 0 : mImpl->mGraphicsQueueIndex; + if (mImpl->mGraphicsQueueIndex == INVALID_VK_INDEX) { + mImpl->mGraphicsQueueIndex = 0; + } - // Applying the same logic to the protected queue index (Not sure about shared context and protection) - mImpl->mProtectedGraphicsQueueIndex - = mImpl->mProtectedGraphicsQueueIndex == INVALID_VK_INDEX ? 0 : - mImpl->mProtectedGraphicsQueueIndex; + if (context.mProtectedMemorySupported) { + mImpl->mProtectedGraphicsQueueFamilyIndex = identifyGraphicsQueueFamilyIndex( + mImpl->mPhysicalDevice, (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_PROTECTED_BIT)); + // Applying the same logic to the protected queue index (Not sure about shared context and + // protection) + if (mImpl->mProtectedGraphicsQueueIndex == INVALID_VK_INDEX) { + mImpl->mProtectedGraphicsQueueIndex = 0; + } + } + + // Only enable shaderClipDistance if we are doing instanced stereoscopic rendering. + if (driverConfig.stereoscopicType != StereoscopicType::INSTANCED) { + context.mPhysicalDeviceFeatures.features.shaderClipDistance = VK_FALSE; + } ExtensionSet deviceExts; // If using a shared context, we do not assume any extensions. if (!mImpl->mSharedContext) { deviceExts = getDeviceExtensions(mImpl->mPhysicalDevice); - auto [prunedInstExts, prunedDeviceExts] - = pruneExtensions(mImpl->mPhysicalDevice, instExts, deviceExts); + auto [prunedInstExts, prunedDeviceExts] = + pruneExtensions(mImpl->mPhysicalDevice, driverConfig, instExts, deviceExts); instExts = prunedInstExts; deviceExts = prunedDeviceExts; - - if (driverConfig.stereoscopicType != StereoscopicType::MULTIVIEW) { - deviceExts.erase(VK_KHR_MULTIVIEW_EXTENSION_NAME); - } } bool requestPortabilitySubsetImageView2DOn3DImage = false; @@ -797,26 +794,32 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, context.mPortabilitySubsetFeatures.imageView2DOn3DImage == VK_TRUE; } - mImpl->mDevice = - mImpl->mDevice == VK_NULL_HANDLE - ? createLogicalDevice(mImpl->mPhysicalDevice, context.mPhysicalDeviceFeatures, - mImpl->mGraphicsQueueFamilyIndex, - mImpl->mProtectedGraphicsQueueFamilyIndex, deviceExts, - requestPortabilitySubsetImageView2DOn3DImage) - : mImpl->mDevice; + if (mImpl->mDevice == VK_NULL_HANDLE) { + mImpl->mDevice = + createLogicalDevice(mImpl->mPhysicalDevice, context.mPhysicalDeviceFeatures, + mImpl->mGraphicsQueueFamilyIndex, mImpl->mProtectedGraphicsQueueFamilyIndex, + deviceExts, requestPortabilitySubsetImageView2DOn3DImage); + } + assert_invariant(mImpl->mDevice != VK_NULL_HANDLE); + assert_invariant(mImpl->mGraphicsQueueFamilyIndex != INVALID_VK_INDEX); + assert_invariant(mImpl->mGraphicsQueueIndex != INVALID_VK_INDEX); vkGetDeviceQueue(mImpl->mDevice, mImpl->mGraphicsQueueFamilyIndex, mImpl->mGraphicsQueueIndex, &mImpl->mGraphicsQueue); assert_invariant(mImpl->mGraphicsQueue != VK_NULL_HANDLE); if (context.mProtectedMemorySupported) { - VkDeviceQueueInfo2 info = {}; - info.queueFamilyIndex = mImpl->mProtectedGraphicsQueueFamilyIndex; - info.queueIndex = mImpl->mProtectedGraphicsQueueIndex; - info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2; - info.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT; + assert_invariant(mImpl->mProtectedGraphicsQueueFamilyIndex != INVALID_VK_INDEX); + assert_invariant(mImpl->mProtectedGraphicsQueueIndex != INVALID_VK_INDEX); + VkDeviceQueueInfo2 info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2, + .flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, + .queueFamilyIndex = mImpl->mProtectedGraphicsQueueFamilyIndex, + .queueIndex = mImpl->mProtectedGraphicsQueueIndex, + }; vkGetDeviceQueue2(mImpl->mDevice, &info, &mImpl->mProtectedGraphicsQueue); + assert_invariant(mImpl->mProtectedGraphicsQueue != VK_NULL_HANDLE); } // Store the extension support in the context @@ -832,16 +835,14 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, } // Check the availability of lazily allocated memory - { - context.mLazilyAllocatedMemorySupported = false; - const uint32_t typeCount = context.mMemoryProperties.memoryTypeCount; - for(uint32_t i = 0; i < typeCount; ++i) { - const VkMemoryType type = context.mMemoryProperties.memoryTypes[i]; - if (type.propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { - context.mLazilyAllocatedMemorySupported = true; - assert_invariant(type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - break; - } + context.mLazilyAllocatedMemorySupported = false; + for (uint32_t i = 0, typeCount = context.mMemoryProperties.memoryTypeCount; i < typeCount; + ++i) { + VkMemoryType const type = context.mMemoryProperties.memoryTypes[i]; + if (type.propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { + context.mLazilyAllocatedMemorySupported = true; + assert_invariant(type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + break; } }