diff options
author | 2019-10-11 19:02:09 -0700 | |
---|---|---|
committer | 2019-10-17 16:27:44 -0700 | |
commit | 7cc36a50e15cc781d9b1260d2cf418780173b2ee (patch) | |
tree | 38a72f26380a5f2d82cfc80923502e16b2679141 | |
parent | aeaa867b6079f5593e9d94b9bd23eb400320adc0 (diff) |
Vulkan: correctly expose Vulkan entry points
This change fixes the advertisement of core Vulkan entry points as below:
1. GIPA returns a valid checked_proc for 1.1 core device APIs.
2. GDPA returns NULL for 1.1 core device APIs on a 1.0 physical device.
Bug: 134185757
Bug: 142266108
Test: dEQP-VK.memory.binding on 1.1 loader and 1.0 device ICD
Test: dEQP-VK.api.info.instance on 1.1 loader and 1.0 instance ICD
Change-Id: I0a3e06dc04bade4f36a7e68ee2f53979c656ee4e
-rw-r--r-- | vulkan/libvulkan/api.cpp | 6 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 60 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.h | 8 | ||||
-rw-r--r-- | vulkan/libvulkan/driver_gen.cpp | 51 | ||||
-rw-r--r-- | vulkan/libvulkan/driver_gen.h | 3 | ||||
-rw-r--r-- | vulkan/scripts/driver_generator.py | 65 | ||||
-rw-r--r-- | vulkan/scripts/generator_common.py | 19 |
7 files changed, 158 insertions, 54 deletions
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 48f26e7e43..1578d9ffce 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -519,7 +519,11 @@ LayerChain::LayerChain(bool is_instance, get_device_proc_addr_(nullptr), driver_extensions_(nullptr), driver_extension_count_(0) { - enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE); + // advertise the loader supported core Vulkan API version at vulkan::api + for (uint32_t i = driver::ProcHook::EXTENSION_CORE_1_0; + i != driver::ProcHook::EXTENSION_COUNT; ++i) { + enabled_extensions_.set(i); + } } LayerChain::~LayerChain() { diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index b413ac9375..c3c19ecdff 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -99,6 +99,7 @@ class CreateInfoWrapper { VkResult Validate(); void DowngradeApiVersion(); + void UpgradeDeviceCoreApiVersion(uint32_t api_version); const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const; const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const; @@ -328,8 +329,12 @@ CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info, physical_dev_(VK_NULL_HANDLE), instance_info_(create_info), extension_filter_() { - hook_extensions_.set(ProcHook::EXTENSION_CORE); - hal_extensions_.set(ProcHook::EXTENSION_CORE); + // instance core versions need to match the loader api version + for (uint32_t i = ProcHook::EXTENSION_CORE_1_0; + i != ProcHook::EXTENSION_COUNT; ++i) { + hook_extensions_.set(i); + hal_extensions_.set(i); + } } CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev, @@ -340,8 +345,9 @@ CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev, physical_dev_(physical_dev), dev_info_(create_info), extension_filter_() { - hook_extensions_.set(ProcHook::EXTENSION_CORE); - hal_extensions_.set(ProcHook::EXTENSION_CORE); + // initialize with baseline core API version + hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0); + hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0); } CreateInfoWrapper::~CreateInfoWrapper() { @@ -540,7 +546,8 @@ void CreateInfoWrapper::FilterExtension(const char* name) { case ProcHook::ANDROID_external_memory_android_hardware_buffer: case ProcHook::ANDROID_native_buffer: case ProcHook::GOOGLE_display_timing: - case ProcHook::EXTENSION_CORE: + case ProcHook::EXTENSION_CORE_1_0: + case ProcHook::EXTENSION_CORE_1_1: case ProcHook::EXTENSION_COUNT: // Device and meta extensions. If we ever get here it's a bug in // our code. But enumerating them lets us avoid having a default @@ -588,7 +595,8 @@ void CreateInfoWrapper::FilterExtension(const char* name) { case ProcHook::EXT_debug_report: case ProcHook::EXT_swapchain_colorspace: case ProcHook::ANDROID_native_buffer: - case ProcHook::EXTENSION_CORE: + case ProcHook::EXTENSION_CORE_1_0: + case ProcHook::EXTENSION_CORE_1_1: case ProcHook::EXTENSION_COUNT: // Instance and meta extensions. If we ever get here it's a bug // in our code. But enumerating them lets us avoid having a @@ -636,6 +644,31 @@ void CreateInfoWrapper::DowngradeApiVersion() { } } +void CreateInfoWrapper::UpgradeDeviceCoreApiVersion(uint32_t api_version) { + ALOG_ASSERT(!is_instance_, "Device only API called by instance wrapper."); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" + api_version ^= VK_VERSION_PATCH(api_version); +#pragma clang diagnostic pop + + // cap the API version to the loader supported highest version + if (api_version > VK_API_VERSION_1_1) + api_version = VK_API_VERSION_1_1; + + switch (api_version) { + case VK_API_VERSION_1_1: + hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1); + hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1); + [[clang::fallthrough]]; + case VK_API_VERSION_1_0: + break; + default: + ALOGD("Unknown upgrade API version[%u]", api_version); + break; + } +} + VKAPI_ATTR void* DefaultAllocate(void*, size_t size, size_t alignment, @@ -771,7 +804,7 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { : nullptr; break; case ProcHook::DEVICE: - proc = (hook->extension == ProcHook::EXTENSION_CORE) + proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0) ? hook->proc : hook->checked_proc; break; @@ -1117,6 +1150,13 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice, if (!data) return VK_ERROR_OUT_OF_HOST_MEMORY; + VkPhysicalDeviceProperties properties; + ATRACE_BEGIN("driver.GetPhysicalDeviceProperties"); + instance_data.driver.GetPhysicalDeviceProperties(physicalDevice, + &properties); + ATRACE_END(); + + wrapper.UpgradeDeviceCoreApiVersion(properties.apiVersion); data->hook_extensions |= wrapper.GetHookExtensions(); // call into the driver @@ -1161,12 +1201,6 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice, return VK_ERROR_INCOMPATIBLE_DRIVER; } - VkPhysicalDeviceProperties properties; - ATRACE_BEGIN("driver.GetPhysicalDeviceProperties"); - instance_data.driver.GetPhysicalDeviceProperties(physicalDevice, - &properties); - ATRACE_END(); - if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) { // Log that the app is hitting software Vulkan implementation android::GraphicsEnv::getInstance().setTargetStats( diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index f058c47d54..61e1818f28 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -67,9 +67,7 @@ struct InstanceData { : opaque_api_data(), allocator(alloc), driver(), - get_device_proc_addr(nullptr) { - hook_extensions.set(ProcHook::EXTENSION_CORE); - } + get_device_proc_addr(nullptr) {} api::InstanceData opaque_api_data; @@ -89,9 +87,7 @@ struct DeviceData { : opaque_api_data(), allocator(alloc), debug_report_callbacks(debug_report_callbacks_), - driver() { - hook_extensions.set(ProcHook::EXTENSION_CORE); - } + driver() {} api::DeviceData opaque_api_data; diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index f676573de9..52205e9e79 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -74,6 +74,15 @@ VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR } } +VKAPI_ATTR VkResult checkedBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) { + if (GetData(device).hook_extensions[ProcHook::EXTENSION_CORE_1_1]) { + return BindImageMemory2(device, bindInfoCount, pBindInfos); + } else { + Logger(device).Err(device, "VK_VERSION_1_1 not enabled. vkBindImageMemory2 not executed."); + return VK_SUCCESS; + } +} + VKAPI_ATTR VkResult checkedBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) { if (GetData(device).hook_extensions[ProcHook::KHR_bind_memory2]) { return BindImageMemory2KHR(device, bindInfoCount, pBindInfos); @@ -145,6 +154,14 @@ VKAPI_ATTR VkResult checkedGetPastPresentationTimingGOOGLE(VkDevice device, VkSw } } +VKAPI_ATTR void checkedGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue) { + if (GetData(device).hook_extensions[ProcHook::EXTENSION_CORE_1_1]) { + GetDeviceQueue2(device, pQueueInfo, pQueue); + } else { + Logger(device).Err(device, "VK_VERSION_1_1 not enabled. vkGetDeviceQueue2 not executed."); + } +} + // clang-format on const ProcHook g_proc_hooks[] = { @@ -173,16 +190,16 @@ const ProcHook g_proc_hooks[] = { { "vkAllocateCommandBuffers", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers), nullptr, }, { "vkBindImageMemory2", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_1, reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory2), - nullptr, + reinterpret_cast<PFN_vkVoidFunction>(checkedBindImageMemory2), }, { "vkBindImageMemory2KHR", @@ -208,14 +225,14 @@ const ProcHook g_proc_hooks[] = { { "vkCreateDevice", ProcHook::INSTANCE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(CreateDevice), nullptr, }, { "vkCreateInstance", ProcHook::GLOBAL, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(CreateInstance), nullptr, }, @@ -243,14 +260,14 @@ const ProcHook g_proc_hooks[] = { { "vkDestroyDevice", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice), nullptr, }, { "vkDestroyInstance", ProcHook::INSTANCE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance), nullptr, }, @@ -271,28 +288,28 @@ const ProcHook g_proc_hooks[] = { { "vkEnumerateDeviceExtensionProperties", ProcHook::INSTANCE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties), nullptr, }, { "vkEnumerateInstanceExtensionProperties", ProcHook::GLOBAL, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties), nullptr, }, { "vkEnumeratePhysicalDeviceGroups", ProcHook::INSTANCE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_1, reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDeviceGroups), nullptr, }, { "vkEnumeratePhysicalDevices", ProcHook::INSTANCE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices), nullptr, }, @@ -313,28 +330,28 @@ const ProcHook g_proc_hooks[] = { { "vkGetDeviceProcAddr", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr), nullptr, }, { "vkGetDeviceQueue", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue), nullptr, }, { "vkGetDeviceQueue2", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_1, reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue2), - nullptr, + reinterpret_cast<PFN_vkVoidFunction>(checkedGetDeviceQueue2), }, { "vkGetInstanceProcAddr", ProcHook::INSTANCE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr), nullptr, }, @@ -446,7 +463,7 @@ const ProcHook g_proc_hooks[] = { { "vkQueueSubmit", ProcHook::DEVICE, - ProcHook::EXTENSION_CORE, + ProcHook::EXTENSION_CORE_1_0, reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit), nullptr, }, diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h index cd7d8f82e0..43c4d1469e 100644 --- a/vulkan/libvulkan/driver_gen.h +++ b/vulkan/libvulkan/driver_gen.h @@ -49,7 +49,8 @@ struct ProcHook { KHR_bind_memory2, KHR_get_physical_device_properties2, - EXTENSION_CORE, // valid bit + EXTENSION_CORE_1_0, + EXTENSION_CORE_1_1, EXTENSION_COUNT, EXTENSION_UNKNOWN, }; diff --git a/vulkan/scripts/driver_generator.py b/vulkan/scripts/driver_generator.py index 0f3d760d5f..a64a7026db 100644 --- a/vulkan/scripts/driver_generator.py +++ b/vulkan/scripts/driver_generator.py @@ -177,8 +177,12 @@ struct ProcHook { for ext in _KNOWN_EXTENSIONS: f.write(gencom.indent(2) + gencom.base_ext_name(ext) + ',\n') - f.write(""" - EXTENSION_CORE, // valid bit + f.write('\n') + for version in gencom.version_code_list: + f.write(gencom.indent(2) + 'EXTENSION_CORE_' + version + ',\n') + + # EXTENSION_COUNT must be the next enum after the highest API version. + f.write("""\ EXTENSION_COUNT, EXTENSION_UNKNOWN, }; @@ -249,6 +253,18 @@ def _is_intercepted(cmd): return False +def _get_proc_hook_enum(cmd): + """Returns the ProcHook enumeration for the corresponding core function. + + Args: + cmd: Vulkan function name. + """ + assert cmd in gencom.version_dict + for version in gencom.version_code_list: + if gencom.version_dict[cmd] == 'VK_VERSION_' + version: + return 'ProcHook::EXTENSION_CORE_' + version + + def _need_proc_hook_stub(cmd): """Returns true if a function needs a ProcHook stub. @@ -259,6 +275,8 @@ def _need_proc_hook_stub(cmd): if cmd in gencom.extension_dict: if not gencom.is_extension_internal(gencom.extension_dict[cmd]): return True + elif gencom.version_dict[cmd] != 'VK_VERSION_1_0': + return True return False @@ -271,8 +289,16 @@ def _define_proc_hook_stub(cmd, f): """ if _need_proc_hook_stub(cmd): return_type = gencom.return_type_dict[cmd] - ext_name = gencom.extension_dict[cmd] - ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name) + + ext_name = '' + ext_hook = '' + if cmd in gencom.extension_dict: + ext_name = gencom.extension_dict[cmd] + ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name) + else: + ext_name = gencom.version_dict[cmd] + ext_hook = _get_proc_hook_enum(cmd) + handle = gencom.param_dict[cmd][0][1] param_types = ', '.join([''.join(i) for i in gencom.param_dict[cmd]]) param_names = ', '.join([''.join(i[1]) for i in gencom.param_dict[cmd]]) @@ -306,12 +332,12 @@ def _define_global_proc_hook(cmd, f): f.write(gencom.indent(1) + '{\n') f.write(gencom.indent(2) + '\"' + cmd + '\",\n') - f.write("""\ - ProcHook::GLOBAL, - ProcHook::EXTENSION_CORE, - reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """), - nullptr, - },\n""") + f.write(gencom.indent(2) + 'ProcHook::GLOBAL,\n') + f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n') + f.write(gencom.indent(2) + 'reinterpret_cast<PFN_vkVoidFunction>(' + + gencom.base_name(cmd) + '),\n') + f.write(gencom.indent(2) + 'nullptr,\n') + f.write(gencom.indent(1) + '},\n') def _define_instance_proc_hook(cmd, f): @@ -339,8 +365,8 @@ def _define_instance_proc_hook(cmd, f): reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """), nullptr,\n""") else: + f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n') f.write("""\ - ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """), nullptr,\n""") @@ -358,10 +384,17 @@ def _define_device_proc_hook(cmd, f): f.write(gencom.indent(2) + '\"' + cmd + '\",\n') f.write(gencom.indent(2) + 'ProcHook::DEVICE,\n') - if cmd in gencom.extension_dict: - ext_name = gencom.extension_dict[cmd] - f.write(gencom.indent(2) + 'ProcHook::' + - gencom.base_ext_name(ext_name) + ',\n') + if (cmd in gencom.extension_dict or + gencom.version_dict[cmd] != 'VK_VERSION_1_0'): + ext_name = '' + ext_hook = '' + if cmd in gencom.extension_dict: + ext_name = gencom.extension_dict[cmd] + ext_hook = 'ProcHook::' + gencom.base_ext_name(ext_name) + else: + ext_name = gencom.version_dict[cmd] + ext_hook = _get_proc_hook_enum(cmd) + f.write(gencom.indent(2) + ext_hook + ',\n') if gencom.is_extension_internal(ext_name): f.write("""\ @@ -374,8 +407,8 @@ def _define_device_proc_hook(cmd, f): gencom.base_name(cmd) + '),\n') else: + f.write(gencom.indent(2) + _get_proc_hook_enum(cmd) + ',\n') f.write("""\ - ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + gencom.base_name(cmd) + """), nullptr,\n""") diff --git a/vulkan/scripts/generator_common.py b/vulkan/scripts/generator_common.py index 670ba66d1b..cf370fafe5 100644 --- a/vulkan/scripts/generator_common.py +++ b/vulkan/scripts/generator_common.py @@ -91,6 +91,9 @@ param_dict = {} # Dict for mapping a function to its return type. return_type_dict = {} +# List of the sorted Vulkan version codes. e.g. '1_0', '1_1'. +version_code_list = [] + # Dict for mapping a function to the core Vulkan API version. version_dict = {} @@ -171,6 +174,15 @@ def base_ext_name(ext): return ext[3:] +def version_code(version): + """Returns the version code from a version string. + + Args: + version: Vulkan version string. + """ + return version[11:] + + def is_function_supported(cmd): """Returns true if a function is core or from a supportable extension. @@ -313,6 +325,7 @@ def parse_vulkan_registry(): extension_dict param_dict return_type_dict + version_code_list version_dict """ registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', @@ -385,3 +398,9 @@ def parse_vulkan_registry(): cmd_name = command.get('name') if cmd_name in command_list: version_dict[cmd_name] = apiversion + + version_code_set = set() + for version in version_dict.values(): + version_code_set.add(version_code(version)) + for code in sorted(version_code_set): + version_code_list.append(code) |