Loading libs/hwui/renderthread/VulkanManager.cpp +55 −105 Original line number Diff line number Diff line Loading @@ -43,21 +43,14 @@ namespace android { namespace uirenderer { namespace renderthread { // Not all of these are strictly required, but are all enabled if present. // Not all of these are strictly required, but are all enabled if present. Only // extensions that hwui itself wants to use are added. The ones implicitly used by Skia // are added by Skia itself via VulkanPreferredFeatures. static std::array<std::string_view, 26> sEnableExtensions{ VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, Loading @@ -70,7 +63,6 @@ static std::array<std::string_view, 26> sEnableExtensions{ VK_EXT_DEVICE_FAULT_EXTENSION_NAME, VK_EXT_FRAME_BOUNDARY_EXTENSION_NAME, VK_ANDROID_FRAME_BOUNDARY_EXTENSION_NAME, VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, }; static bool shouldEnableExtension(const std::string_view& extension) { Loading @@ -82,23 +74,6 @@ static bool shouldEnableExtension(const std::string_view& extension) { return false; } static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& features) { // All Vulkan structs that could be part of the features chain will start with the // structure type followed by the pNext pointer. We cast to the CommonVulkanHeader // so we can get access to the pNext for the next struct. struct CommonVulkanHeader { VkStructureType sType; void* pNext; }; void* pNext = features.pNext; while (pNext) { void* current = pNext; pNext = static_cast<CommonVulkanHeader*>(current)->pNext; free(current); } } #define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vk" #F) #define GET_INST_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(mInstance, "vk" #F) #define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F) Loading Loading @@ -142,12 +117,12 @@ VulkanManager::~VulkanManager() { mInstanceExtensions.clear(); mDeviceExtensionsOwner.clear(); mDeviceExtensions.clear(); free_features_extensions_structs(mPhysicalDeviceFeatures2); mPhysicalDeviceFeatures2 = {}; mDeviceFaultFeatures = {}; mGlobalPriorityQueryFeatures = {}; } void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, VkPhysicalDeviceFeatures2& features) { void VulkanManager::setupDevice() { VkResult err; constexpr VkApplicationInfo app_info = { Loading Loading @@ -189,6 +164,12 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, LOG_ALWAYS_FATAL_IF(!hasKHRSurfaceExtension || !hasKHRAndroidSurfaceExtension); } // Let Skia enable instance extensions. mVulkanFeatures.init(mAPIVersion); mVulkanFeatures.addToInstanceExtensions(mInstanceExtensionsOwner.data(), mInstanceExtensionsOwner.size(), mInstanceExtensions); const VkInstanceCreateInfo instance_create = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType nullptr, // pNext Loading Loading @@ -260,6 +241,10 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, } LOG_ALWAYS_FATAL_IF(mGraphicsQueueIndex == queueCount); mPhysicalDeviceFeatures2 = {}; mPhysicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; void** tailPNext = &mPhysicalDeviceFeatures2.pNext; { uint32_t extensionCount = 0; err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount, Loading @@ -270,6 +255,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, mDeviceExtensionsOwner.data()); LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); bool hasKHRSwapchainExtension = false; bool hasGlobalPriority = mAPIVersion >= VK_API_VERSION_1_4; for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) { if (!shouldEnableExtension(extension.extensionName)) { ALOGV("Not enabling device extension %s", extension.extensionName); Loading @@ -280,9 +266,41 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, if (!strcmp(extension.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) { hasKHRSwapchainExtension = true; } else if (!strcmp(extension.extensionName, VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) { mDeviceFaultFeatures = {}; mDeviceFaultFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT; *tailPNext = &mDeviceFaultFeatures; tailPNext = &mDeviceFaultFeatures.pNext; } else if (!strcmp(extension.extensionName, VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME) || !strcmp(extension.extensionName, VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME)) { hasGlobalPriority = true; } } LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension); if (hasGlobalPriority) { mGlobalPriorityQueryFeatures = {}; mGlobalPriorityQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT; *tailPNext = &mGlobalPriorityQueryFeatures; tailPNext = &mGlobalPriorityQueryFeatures.pNext; } } // Let Skia add features to be queried. mVulkanFeatures.addFeaturesToQuery(mDeviceExtensionsOwner.data(), mDeviceExtensionsOwner.size(), mPhysicalDeviceFeatures2); // Query to get the physical device features mGetPhysicalDeviceFeatures2(mPhysicalDevice, &mPhysicalDeviceFeatures2); // Robust buffer access can reduce performance on some platforms. It is not needed by // HWUI. mPhysicalDeviceFeatures2.features.robustBufferAccess = VK_FALSE; // Let Skia enable extensions and features. mVulkanFeatures.addFeaturesToEnable(mDeviceExtensions, mPhysicalDeviceFeatures2); auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { if (device != VK_NULL_HANDLE) { Loading @@ -291,81 +309,13 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, return vkGetInstanceProcAddr(instance, proc_name); }; grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), mExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data()); LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)); memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2)); features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; features.pNext = nullptr; // Setup all extension feature structs we may want to use. void** tailPNext = &features.pNext; if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) { VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend; blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc( sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)); LOG_ALWAYS_FATAL_IF(!blend); blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT; blend->pNext = nullptr; *tailPNext = blend; tailPNext = &blend->pNext; } VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature; ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc( sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures)); LOG_ALWAYS_FATAL_IF(!ycbcrFeature); ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; ycbcrFeature->pNext = nullptr; *tailPNext = ycbcrFeature; tailPNext = &ycbcrFeature->pNext; if (grExtensions.hasExtension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, 1)) { VkPhysicalDeviceFaultFeaturesEXT* deviceFaultFeatures = new VkPhysicalDeviceFaultFeaturesEXT; deviceFaultFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT; deviceFaultFeatures->pNext = nullptr; *tailPNext = deviceFaultFeatures; tailPNext = &deviceFaultFeatures->pNext; } if (grExtensions.hasExtension(VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME, 1)) { VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT* formatFeatures = new VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT; formatFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT; formatFeatures->pNext = nullptr; *tailPNext = formatFeatures; tailPNext = &formatFeatures->pNext; } if (grExtensions.hasExtension(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, 1)) { VkPhysicalDevicePipelineCreationCacheControlFeatures* cacheControlFeatures = new VkPhysicalDevicePipelineCreationCacheControlFeatures; cacheControlFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES; cacheControlFeatures->pNext = nullptr; *tailPNext = cacheControlFeatures; tailPNext = &cacheControlFeatures->pNext; } VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT* globalPriorityQueryFeatures = new VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; globalPriorityQueryFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT; globalPriorityQueryFeatures->pNext = nullptr; globalPriorityQueryFeatures->globalPriorityQuery = false; *tailPNext = globalPriorityQueryFeatures; tailPNext = &globalPriorityQueryFeatures->pNext; LOG_ALWAYS_FATAL_IF(!mExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)); // query to get the physical device features mGetPhysicalDeviceFeatures2(mPhysicalDevice, &features); // this looks like it would slow things down, // and we can't depend on it on all platforms features.features.robustBufferAccess = VK_FALSE; float queuePriorities[kRequestedQueueCount] = {0.0}; Loading @@ -374,7 +324,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo; if (Properties::contextPriority != 0 && grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { mExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { VkQueueGlobalPriorityEXT globalPriority; switch (Properties::contextPriority) { case EGL_CONTEXT_PRIORITY_LOW_IMG: Loading @@ -392,7 +342,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, // check if the requested priority is reported by the query bool attachGlobalPriority = false; if (globalPriorityQueryFeatures->globalPriorityQuery) { if (mGlobalPriorityQueryFeatures.globalPriorityQuery) { for (uint32_t i = 0; i < queuePriorityProps[mGraphicsQueueIndex].priorityCount; i++) { if (queuePriorityProps[mGraphicsQueueIndex].priorities[i] == globalPriority) { attachGlobalPriority = true; Loading Loading @@ -440,7 +390,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, const VkDeviceCreateInfo deviceInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType &features, // pNext &mPhysicalDeviceFeatures2, // pNext 0, // VkDeviceCreateFlags 1, // queueCreateInfoCount &queueInfo, // pQueueCreateInfos Loading Loading @@ -484,7 +434,7 @@ void VulkanManager::initialize() { LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); this->setupDevice(); mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue); Loading libs/hwui/renderthread/VulkanManager.h +8 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <include/gpu/ganesh/GrContextOptions.h> #include <utils/StrongPointer.h> #include <vk/VulkanExtensions.h> #include <vk/VulkanPreferredFeatures.h> #include <vulkan/vulkan.h> // VK_ANDROID_frame_boundary is a bespoke extension defined by AGI Loading Loading @@ -120,9 +121,9 @@ private: explicit VulkanManager() {} ~VulkanManager(); // Sets up the VkInstance and VkDevice objects. Also fills out the passed in // VkPhysicalDeviceFeatures struct. void setupDevice(skgpu::VulkanExtensions&, VkPhysicalDeviceFeatures2&); // Sets up the VkInstance and VkDevice objects. Fills out mPhysicalDeviceFeatures2 and // other feature structs. void setupDevice(); // simple wrapper class that exists only to initialize a pointer to NULL template <typename FNPTR_TYPE> Loading Loading @@ -189,12 +190,14 @@ private: VkQueue mAHBUploadQueue = VK_NULL_HANDLE; // Variables saved to populate VkFunctorInitParams. static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0); static const uint32_t mAPIVersion = VK_API_VERSION_1_1; std::vector<VkExtensionProperties> mInstanceExtensionsOwner; std::vector<const char*> mInstanceExtensions; std::vector<VkExtensionProperties> mDeviceExtensionsOwner; std::vector<const char*> mDeviceExtensions; VkPhysicalDeviceFeatures2 mPhysicalDeviceFeatures2{}; VkPhysicalDeviceFaultFeaturesEXT mDeviceFaultFeatures{}; VkPhysicalDeviceGlobalPriorityQueryFeatures mGlobalPriorityQueryFeatures{}; enum class SwapBehavior { Discard, Loading @@ -202,6 +205,7 @@ private: }; SwapBehavior mSwapBehavior = SwapBehavior::Discard; skgpu::VulkanExtensions mExtensions; skgpu::VulkanPreferredFeatures mVulkanFeatures; uint32_t mDriverVersion = 0; std::once_flag mInitFlag; Loading Loading
libs/hwui/renderthread/VulkanManager.cpp +55 −105 Original line number Diff line number Diff line Loading @@ -43,21 +43,14 @@ namespace android { namespace uirenderer { namespace renderthread { // Not all of these are strictly required, but are all enabled if present. // Not all of these are strictly required, but are all enabled if present. Only // extensions that hwui itself wants to use are added. The ones implicitly used by Skia // are added by Skia itself via VulkanPreferredFeatures. static std::array<std::string_view, 26> sEnableExtensions{ VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, Loading @@ -70,7 +63,6 @@ static std::array<std::string_view, 26> sEnableExtensions{ VK_EXT_DEVICE_FAULT_EXTENSION_NAME, VK_EXT_FRAME_BOUNDARY_EXTENSION_NAME, VK_ANDROID_FRAME_BOUNDARY_EXTENSION_NAME, VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, }; static bool shouldEnableExtension(const std::string_view& extension) { Loading @@ -82,23 +74,6 @@ static bool shouldEnableExtension(const std::string_view& extension) { return false; } static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& features) { // All Vulkan structs that could be part of the features chain will start with the // structure type followed by the pNext pointer. We cast to the CommonVulkanHeader // so we can get access to the pNext for the next struct. struct CommonVulkanHeader { VkStructureType sType; void* pNext; }; void* pNext = features.pNext; while (pNext) { void* current = pNext; pNext = static_cast<CommonVulkanHeader*>(current)->pNext; free(current); } } #define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vk" #F) #define GET_INST_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(mInstance, "vk" #F) #define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F) Loading Loading @@ -142,12 +117,12 @@ VulkanManager::~VulkanManager() { mInstanceExtensions.clear(); mDeviceExtensionsOwner.clear(); mDeviceExtensions.clear(); free_features_extensions_structs(mPhysicalDeviceFeatures2); mPhysicalDeviceFeatures2 = {}; mDeviceFaultFeatures = {}; mGlobalPriorityQueryFeatures = {}; } void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, VkPhysicalDeviceFeatures2& features) { void VulkanManager::setupDevice() { VkResult err; constexpr VkApplicationInfo app_info = { Loading Loading @@ -189,6 +164,12 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, LOG_ALWAYS_FATAL_IF(!hasKHRSurfaceExtension || !hasKHRAndroidSurfaceExtension); } // Let Skia enable instance extensions. mVulkanFeatures.init(mAPIVersion); mVulkanFeatures.addToInstanceExtensions(mInstanceExtensionsOwner.data(), mInstanceExtensionsOwner.size(), mInstanceExtensions); const VkInstanceCreateInfo instance_create = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType nullptr, // pNext Loading Loading @@ -260,6 +241,10 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, } LOG_ALWAYS_FATAL_IF(mGraphicsQueueIndex == queueCount); mPhysicalDeviceFeatures2 = {}; mPhysicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; void** tailPNext = &mPhysicalDeviceFeatures2.pNext; { uint32_t extensionCount = 0; err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount, Loading @@ -270,6 +255,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, mDeviceExtensionsOwner.data()); LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err); bool hasKHRSwapchainExtension = false; bool hasGlobalPriority = mAPIVersion >= VK_API_VERSION_1_4; for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) { if (!shouldEnableExtension(extension.extensionName)) { ALOGV("Not enabling device extension %s", extension.extensionName); Loading @@ -280,9 +266,41 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, if (!strcmp(extension.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) { hasKHRSwapchainExtension = true; } else if (!strcmp(extension.extensionName, VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) { mDeviceFaultFeatures = {}; mDeviceFaultFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT; *tailPNext = &mDeviceFaultFeatures; tailPNext = &mDeviceFaultFeatures.pNext; } else if (!strcmp(extension.extensionName, VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME) || !strcmp(extension.extensionName, VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME)) { hasGlobalPriority = true; } } LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension); if (hasGlobalPriority) { mGlobalPriorityQueryFeatures = {}; mGlobalPriorityQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT; *tailPNext = &mGlobalPriorityQueryFeatures; tailPNext = &mGlobalPriorityQueryFeatures.pNext; } } // Let Skia add features to be queried. mVulkanFeatures.addFeaturesToQuery(mDeviceExtensionsOwner.data(), mDeviceExtensionsOwner.size(), mPhysicalDeviceFeatures2); // Query to get the physical device features mGetPhysicalDeviceFeatures2(mPhysicalDevice, &mPhysicalDeviceFeatures2); // Robust buffer access can reduce performance on some platforms. It is not needed by // HWUI. mPhysicalDeviceFeatures2.features.robustBufferAccess = VK_FALSE; // Let Skia enable extensions and features. mVulkanFeatures.addFeaturesToEnable(mDeviceExtensions, mPhysicalDeviceFeatures2); auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { if (device != VK_NULL_HANDLE) { Loading @@ -291,81 +309,13 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, return vkGetInstanceProcAddr(instance, proc_name); }; grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), mExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data()); LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)); memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2)); features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; features.pNext = nullptr; // Setup all extension feature structs we may want to use. void** tailPNext = &features.pNext; if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) { VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend; blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc( sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)); LOG_ALWAYS_FATAL_IF(!blend); blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT; blend->pNext = nullptr; *tailPNext = blend; tailPNext = &blend->pNext; } VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature; ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc( sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures)); LOG_ALWAYS_FATAL_IF(!ycbcrFeature); ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; ycbcrFeature->pNext = nullptr; *tailPNext = ycbcrFeature; tailPNext = &ycbcrFeature->pNext; if (grExtensions.hasExtension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, 1)) { VkPhysicalDeviceFaultFeaturesEXT* deviceFaultFeatures = new VkPhysicalDeviceFaultFeaturesEXT; deviceFaultFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT; deviceFaultFeatures->pNext = nullptr; *tailPNext = deviceFaultFeatures; tailPNext = &deviceFaultFeatures->pNext; } if (grExtensions.hasExtension(VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME, 1)) { VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT* formatFeatures = new VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT; formatFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT; formatFeatures->pNext = nullptr; *tailPNext = formatFeatures; tailPNext = &formatFeatures->pNext; } if (grExtensions.hasExtension(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, 1)) { VkPhysicalDevicePipelineCreationCacheControlFeatures* cacheControlFeatures = new VkPhysicalDevicePipelineCreationCacheControlFeatures; cacheControlFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES; cacheControlFeatures->pNext = nullptr; *tailPNext = cacheControlFeatures; tailPNext = &cacheControlFeatures->pNext; } VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT* globalPriorityQueryFeatures = new VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; globalPriorityQueryFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT; globalPriorityQueryFeatures->pNext = nullptr; globalPriorityQueryFeatures->globalPriorityQuery = false; *tailPNext = globalPriorityQueryFeatures; tailPNext = &globalPriorityQueryFeatures->pNext; LOG_ALWAYS_FATAL_IF(!mExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)); // query to get the physical device features mGetPhysicalDeviceFeatures2(mPhysicalDevice, &features); // this looks like it would slow things down, // and we can't depend on it on all platforms features.features.robustBufferAccess = VK_FALSE; float queuePriorities[kRequestedQueueCount] = {0.0}; Loading @@ -374,7 +324,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo; if (Properties::contextPriority != 0 && grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { mExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) { VkQueueGlobalPriorityEXT globalPriority; switch (Properties::contextPriority) { case EGL_CONTEXT_PRIORITY_LOW_IMG: Loading @@ -392,7 +342,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, // check if the requested priority is reported by the query bool attachGlobalPriority = false; if (globalPriorityQueryFeatures->globalPriorityQuery) { if (mGlobalPriorityQueryFeatures.globalPriorityQuery) { for (uint32_t i = 0; i < queuePriorityProps[mGraphicsQueueIndex].priorityCount; i++) { if (queuePriorityProps[mGraphicsQueueIndex].priorities[i] == globalPriority) { attachGlobalPriority = true; Loading Loading @@ -440,7 +390,7 @@ void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions, const VkDeviceCreateInfo deviceInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType &features, // pNext &mPhysicalDeviceFeatures2, // pNext 0, // VkDeviceCreateFlags 1, // queueCreateInfoCount &queueInfo, // pQueueCreateInfos Loading Loading @@ -484,7 +434,7 @@ void VulkanManager::initialize() { LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); this->setupDevice(); mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue); Loading
libs/hwui/renderthread/VulkanManager.h +8 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <include/gpu/ganesh/GrContextOptions.h> #include <utils/StrongPointer.h> #include <vk/VulkanExtensions.h> #include <vk/VulkanPreferredFeatures.h> #include <vulkan/vulkan.h> // VK_ANDROID_frame_boundary is a bespoke extension defined by AGI Loading Loading @@ -120,9 +121,9 @@ private: explicit VulkanManager() {} ~VulkanManager(); // Sets up the VkInstance and VkDevice objects. Also fills out the passed in // VkPhysicalDeviceFeatures struct. void setupDevice(skgpu::VulkanExtensions&, VkPhysicalDeviceFeatures2&); // Sets up the VkInstance and VkDevice objects. Fills out mPhysicalDeviceFeatures2 and // other feature structs. void setupDevice(); // simple wrapper class that exists only to initialize a pointer to NULL template <typename FNPTR_TYPE> Loading Loading @@ -189,12 +190,14 @@ private: VkQueue mAHBUploadQueue = VK_NULL_HANDLE; // Variables saved to populate VkFunctorInitParams. static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0); static const uint32_t mAPIVersion = VK_API_VERSION_1_1; std::vector<VkExtensionProperties> mInstanceExtensionsOwner; std::vector<const char*> mInstanceExtensions; std::vector<VkExtensionProperties> mDeviceExtensionsOwner; std::vector<const char*> mDeviceExtensions; VkPhysicalDeviceFeatures2 mPhysicalDeviceFeatures2{}; VkPhysicalDeviceFaultFeaturesEXT mDeviceFaultFeatures{}; VkPhysicalDeviceGlobalPriorityQueryFeatures mGlobalPriorityQueryFeatures{}; enum class SwapBehavior { Discard, Loading @@ -202,6 +205,7 @@ private: }; SwapBehavior mSwapBehavior = SwapBehavior::Discard; skgpu::VulkanExtensions mExtensions; skgpu::VulkanPreferredFeatures mVulkanFeatures; uint32_t mDriverVersion = 0; std::once_flag mInitFlag; Loading