Loading vulkan/scripts/code_generator.py +3 −0 Original line number Diff line number Diff line Loading @@ -19,8 +19,11 @@ import generator_common as gencom import api_generator as apigen import driver_generator as drivergen if __name__ == '__main__': gencom.parseVulkanRegistry() apigen.api_genh() apigen.api_gencpp() drivergen.driver_genh() drivergen.driver_gencpp() vulkan/scripts/driver_generator.py 0 → 100644 +393 −0 Original line number Diff line number Diff line #!/usr/bin/env python3 # # Copyright 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This script provides the functions for generating the # vulkan driver framework directly from the vulkan registry (vk.xml). import generator_common as gencom import os interceptedExtensions = [ 'VK_ANDROID_native_buffer', 'VK_EXT_debug_report', 'VK_EXT_hdr_metadata', 'VK_EXT_swapchain_colorspace', 'VK_GOOGLE_display_timing', 'VK_KHR_android_surface', 'VK_KHR_incremental_present', 'VK_KHR_shared_presentable_image', 'VK_KHR_surface', 'VK_KHR_swapchain', 'VK_KHR_get_surface_capabilities2' ] knownExtensions = interceptedExtensions + [ 'VK_KHR_get_physical_device_properties2', 'VK_ANDROID_external_memory_android_hardware_buffer', 'VK_KHR_bind_memory2' ] def defineProcHookType(f): f.write ("""struct ProcHook { enum Type { GLOBAL, INSTANCE, DEVICE, }; enum Extension {\n""") for exts in knownExtensions: f.write (gencom.clang_off_spaces*2 + exts[3:] + ',\n') f.write ('\n') f.write (gencom.clang_off_spaces*2 + """EXTENSION_CORE, // valid bit EXTENSION_COUNT, EXTENSION_UNKNOWN, }; const char* name; Type type; Extension extension; PFN_vkVoidFunction proc; PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks };\n\n""") def isExtensionIntercepted(extensionName): if extensionName in interceptedExtensions: return True return False def isDriverTableEntry(functionName): switchCase = { # Create functions of dispatchable objects 'vkCreateDevice' : True, 'vkGetDeviceQueue' : True, 'vkGetDeviceQueue2' : True, 'vkAllocateCommandBuffers' : True, # Destroy functions of dispatchable objects 'vkDestroyInstance' : True, 'vkDestroyDevice' : True, # Enumeration of extensions 'vkEnumerateDeviceExtensionProperties' : True, # We cache physical devices in loader.cpp 'vkEnumeratePhysicalDevices' : True, 'vkEnumeratePhysicalDeviceGroups' : True, 'vkGetInstanceProcAddr' : True, 'vkGetDeviceProcAddr' : True, # VK_KHR_swapchain->VK_ANDROID_native_buffer translation 'vkCreateImage' : True, 'vkDestroyImage' : True, 'vkGetPhysicalDeviceProperties' : True, 'vkGetPhysicalDeviceProperties2' : True, 'vkGetPhysicalDeviceProperties2KHR' : True, # VK_KHR_swapchain v69 requirement 'vkBindImageMemory2' : True, 'vkBindImageMemory2KHR' : True } if gencom.isFunctionSupported(functionName): if functionName in switchCase: return True if functionName in gencom.extensionsDict: if gencom.extensionsDict[functionName] == 'VK_ANDROID_native_buffer' or gencom.extensionsDict[functionName] == 'VK_EXT_debug_report': return True return False def isInstanceDriverTableEntry(functionName): if isDriverTableEntry(functionName) and gencom.isInstanceDispatched(functionName): return True return False def isDeviceDriverTableEntry(functionName): if isDriverTableEntry(functionName) and gencom.isDeviceDispatched(functionName): return True return False def driver_genh(): header = """#ifndef LIBVULKAN_DRIVER_GEN_H #define LIBVULKAN_DRIVER_GEN_H #include <vulkan/vk_android_native_buffer.h> #include <vulkan/vulkan.h> #include <bitset> namespace vulkan { namespace driver {\n\n""" genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','driver_gen2.h') with open(genfile, 'w') as f: f.write (gencom.copyright) f.write (gencom.warning) f.write (header) defineProcHookType(f) f.write ('struct InstanceDriverTable {\n') gencom.clang_off(f, 1) for cmds in gencom.allCommandsList: if isInstanceDriverTableEntry(cmds): f.write (gencom.clang_off_spaces + 'PFN_' + cmds + ' ' + cmds[2:] + ';\n') gencom.clang_on(f, 1) f.write ('};\n\n') f.write ('struct DeviceDriverTable {\n') gencom.clang_off(f,1) for cmds in gencom.allCommandsList: if isDeviceDriverTableEntry(cmds): f.write (gencom.clang_off_spaces + 'PFN_' + cmds + ' ' + cmds[2:] + ';\n') gencom.clang_on(f,1) f.write ('};\n\n') f.write ("""const ProcHook* GetProcHook(const char* name); ProcHook::Extension GetProcHookExtension(const char* name); bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions); bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions); } // namespace driver } // namespace vulkan #endif // LIBVULKAN_DRIVER_TABLE_H\n""") def isIntercepted(functionName): switchCase = { # Create functions of dispatchable objects 'vkCreateInstance' : True, 'vkCreateDevice' : True, 'vkEnumeratePhysicalDevices' : True, 'vkEnumeratePhysicalDeviceGroups' : True, 'vkGetDeviceQueue' : True, 'vkGetDeviceQueue2' : True, 'vkAllocateCommandBuffers' : True, # Destroy functions of dispatchable objects 'vkDestroyInstance' : True, 'vkDestroyDevice' : True, # Enumeration of extensions 'vkEnumerateInstanceExtensionProperties' : True, 'vkEnumerateDeviceExtensionProperties' : True, 'vkGetInstanceProcAddr' : True, 'vkGetDeviceProcAddr' : True, # VK_KHR_swapchain v69 requirement 'vkBindImageMemory2' : True, 'vkBindImageMemory2KHR' : True } if gencom.isFunctionSupported(functionName): if functionName in switchCase: return switchCase[functionName] if functionName in gencom.extensionsDict: return isExtensionIntercepted(gencom.extensionsDict[functionName]) return False def needProcHookStub(functionName): if isIntercepted(functionName) and gencom.isDeviceDispatched(functionName): if functionName in gencom.extensionsDict: if not gencom.isExtensionInternal(gencom.extensionsDict[functionName]): return True return False def defineInitProc(name, f): f.write ('#define UNLIKELY(expr) __builtin_expect((expr), 0)\n') f.write ('\n') f.write ("""#define INIT_PROC(required, obj, proc) \\ do { \\ data.""" + name + """.proc = \\ reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\ if (UNLIKELY(required && !data.""" + name + """.proc)) { \\ ALOGE("missing " #obj " proc: vk" #proc); \\ success = false; \\ } \\ } while (0)\n\n""") def defineInitProcExt(f): f.write ("""#define INIT_PROC_EXT(ext, required, obj, proc) \\ do { \\ if (extensions[ProcHook::ext]) \\ INIT_PROC(required, obj, proc); \\ } while (0)\n\n""") def defineProcHookStub(functionName, f): if needProcHookStub(functionName): ext_name = gencom.extensionsDict[functionName] base_name = functionName[2:] paramList = [''.join(i) for i in gencom.paramDict[functionName]] p0 = gencom.paramDict[functionName][0][1] f.write ('VKAPI_ATTR ' + gencom.returnTypeDict[functionName] + ' checked' + base_name + '(' + ', '.join(paramList) + ') {\n') ext_hook = 'ProcHook::' + ext_name[3:] f.write (gencom.clang_off_spaces + 'if (GetData(' + p0 + ').hook_extensions[' + ext_hook + ']) {\n') f.write (gencom.clang_off_spaces *2) if gencom.returnTypeDict[functionName] != 'void': f.write ('return ') paramNames = [''.join(i[1]) for i in gencom.paramDict[functionName]] f.write (base_name + '(' + ', '.join(paramNames) + ');\n') f.write (gencom.clang_off_spaces + '} else {\n') f.write (gencom.clang_off_spaces*2 + 'Logger(' + p0 + ').Err(' + p0 + ', \"' + ext_name + ' not enabled. ' + functionName + ' not executed.\");\n') if gencom.returnTypeDict[functionName] != 'void': f.write (gencom.clang_off_spaces*2 + 'return VK_SUCCESS;\n') f.write (gencom.clang_off_spaces + '}\n') f.write ('}\n\n') def defineGlobalProcHook(functionName, f): base_name = functionName[2:] assert (functionName not in gencom.extensionsDict) f.write (gencom.clang_off_spaces + '{\n' + gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n' + gencom.clang_off_spaces*2) f.write ("""ProcHook::GLOBAL, ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """), nullptr, },\n""") def defineInstanceProcHook(functionName, f): base_name = functionName[2:] f.write (gencom.clang_off_spaces + '{\n') f.write (gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n') f.write (gencom.clang_off_spaces*2 + 'ProcHook::INSTANCE,\n') if functionName in gencom.extensionsDict: ext_name = gencom.extensionsDict[functionName] f.write (gencom.clang_off_spaces*2 + 'ProcHook::' + ext_name[3:] + ',\n') if gencom.isExtensionInternal(ext_name): f.write (gencom.clang_off_spaces*2 + 'nullptr,\n' + gencom.clang_off_spaces*2 + 'nullptr,\n') else: f.write (gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(' + base_name + '),\n' + gencom.clang_off_spaces*2 + 'nullptr,\n') else: f.write (gencom.clang_off_spaces*2 + """ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """), nullptr,\n""") f.write (gencom.clang_off_spaces + '},\n') def defineDeviceProcHook(functionName, f): base_name = functionName[2:] f.write (gencom.clang_off_spaces + '{\n') f.write (gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n') f.write (gencom.clang_off_spaces*2 + 'ProcHook::DEVICE,\n') if functionName in gencom.extensionsDict: ext_name = gencom.extensionsDict[functionName] f.write (gencom.clang_off_spaces*2 + 'ProcHook::' + ext_name[3:] + ',\n') if gencom.isExtensionInternal(ext_name): f.write (gencom.clang_off_spaces*2 + 'nullptr,\n' + gencom.clang_off_spaces*2 + 'nullptr,\n') else: f.write (gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(' + base_name + '),\n' + gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(checked' + base_name + '),\n') else: f.write (gencom.clang_off_spaces*2 + """ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """), nullptr,\n""") f.write (gencom.clang_off_spaces + '},\n') def driver_gencpp(): header = """#include <log/log.h> #include <string.h> #include <algorithm> #include "driver.h" namespace vulkan { namespace driver { namespace { // clang-format off\n\n""" genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','driver_gen2.cpp') with open(genfile, 'w') as f: f.write (gencom.copyright) f.write (gencom.warning) f.write (header) for cmds in gencom.allCommandsList: defineProcHookStub(cmds, f) gencom.clang_on(f, 0) f.write ('\n') f.write ('const ProcHook g_proc_hooks[] = {\n') gencom.clang_off(f, 1) sortedCommandsList = sorted(gencom.allCommandsList) for cmds in sortedCommandsList: if isIntercepted(cmds): if gencom.isGloballyDispatched(cmds): defineGlobalProcHook(cmds, f) elif gencom.isInstanceDispatched(cmds): defineInstanceProcHook(cmds, f) elif gencom.isDeviceDispatched(cmds): defineDeviceProcHook(cmds, f) gencom.clang_on(f, 1) f.write ('};\n\n} // namespace\n\n') f.write ("""const ProcHook* GetProcHook(const char* name) { const auto& begin = g_proc_hooks; const auto& end = g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]); const auto hook = std::lower_bound( begin, end, name, [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; }); return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr; }\n\n""") f.write ('ProcHook::Extension GetProcHookExtension(const char* name) {\n') gencom.clang_off(f, 1) for exts in knownExtensions: f.write (gencom.clang_off_spaces + 'if (strcmp(name, \"' + exts + '\") == 0) return ProcHook::' + exts[3:] + ';\n') gencom.clang_on(f, 1) f.write (gencom.clang_off_spaces + 'return ProcHook::EXTENSION_UNKNOWN;\n') f.write ('}\n\n') defineInitProc('driver', f) defineInitProcExt(f) f.write ("""bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) { auto& data = GetData(instance); bool success = true;\n\n""") gencom.clang_off(f, 1) for cmds in gencom.allCommandsList: if isInstanceDriverTableEntry(cmds): gencom.initProc(cmds, f) gencom.clang_on(f, 1) f.write ('\n' + gencom.clang_off_spaces + 'return success;\n') f.write ('}\n\n') f.write ("""bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) { auto& data = GetData(dev); bool success = true;\n\n""") gencom.clang_off(f, 1) for cmds in gencom.allCommandsList: if isDeviceDriverTableEntry(cmds): gencom.initProc(cmds, f) gencom.clang_on(f, 1) f.write ('\n' + gencom.clang_off_spaces + 'return success;\n') f.write ('}\n\n} // namespace driver\n} // namespace vulkan\n\n') gencom.clang_on(f, 0) vulkan/scripts/generator_common.py +26 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,11 @@ blacklistedExtensions = [ 'VK_NV_win32_keyed_mutex', 'VK_EXT_metal_surface', #not present in vulkan.api 'VK_NVX_image_view_handle', #not present in vulkan.api 'VK_NV_cooperative_matrix' #not present in vulkan.api 'VK_NV_cooperative_matrix', #not present in vulkan.api 'VK_EXT_headless_surface', #not present in vulkan.api 'VK_GGP_stream_descriptor_surface', #not present in vulkan.api 'VK_NV_coverage_reduction_mode', #not present in vulkan.api 'VK_EXT_full_screen_exclusive' #not present in vulkan.api ] exportedExtensions = [ Loading @@ -71,6 +75,11 @@ exportedExtensions = [ 'VK_ANDROID_external_memory_android_hardware_buffer' ] def isExtensionInternal(extensionName): if extensionName == 'VK_ANDROID_native_buffer': return True return False def isFunctionSupported(functionName): if functionName not in extensionsDict: return True Loading Loading @@ -167,6 +176,7 @@ def parseVulkanRegistry(): aliasDict[fnName] = alias allCommandsList.append(fnName) paramDict[fnName] = paramDict[alias].copy() returnTypeDict[fnName] = returnTypeDict[alias] for params in command: if(params.tag == 'param'): paramtype = "" Loading Loading @@ -208,6 +218,19 @@ def parseVulkanRegistry(): if apiversion != "": versionDict[commandname] = apiversion # TODO(adsrini): http://b/136570819 extensionsDict['vkGetSwapchainGrallocUsage2ANDROID'] = 'VK_ANDROID_native_buffer' allCommandsList.append('vkGetSwapchainGrallocUsage2ANDROID') returnTypeDict['vkGetSwapchainGrallocUsage2ANDROID'] = 'VkResult' paramDict['vkGetSwapchainGrallocUsage2ANDROID'] = [ ('VkDevice ', 'device', None), ('VkFormat ', 'format', None), ('VkImageUsageFlags', 'imageUsage', None), ('VkSwapchainImageUsageFlagsANDROID ', 'swapchainImageUsage', None), ('u64* ', 'grallocConsumerUsage', None), ('u64* ', 'grallocProducerUsage', None) ] for feature in root.iter('feature'): apiversion = feature.get('name') for req in feature: Loading @@ -226,6 +249,8 @@ def initProc(name, f): if name in versionDict and versionDict[name] == 'VK_VERSION_1_1': f.write('false, ') elif name == 'vkGetSwapchainGrallocUsageANDROID' or name == 'vkGetSwapchainGrallocUsage2ANDROID': # optional in vulkan.api f.write('false, ') else: f.write('true, ') Loading Loading
vulkan/scripts/code_generator.py +3 −0 Original line number Diff line number Diff line Loading @@ -19,8 +19,11 @@ import generator_common as gencom import api_generator as apigen import driver_generator as drivergen if __name__ == '__main__': gencom.parseVulkanRegistry() apigen.api_genh() apigen.api_gencpp() drivergen.driver_genh() drivergen.driver_gencpp()
vulkan/scripts/driver_generator.py 0 → 100644 +393 −0 Original line number Diff line number Diff line #!/usr/bin/env python3 # # Copyright 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This script provides the functions for generating the # vulkan driver framework directly from the vulkan registry (vk.xml). import generator_common as gencom import os interceptedExtensions = [ 'VK_ANDROID_native_buffer', 'VK_EXT_debug_report', 'VK_EXT_hdr_metadata', 'VK_EXT_swapchain_colorspace', 'VK_GOOGLE_display_timing', 'VK_KHR_android_surface', 'VK_KHR_incremental_present', 'VK_KHR_shared_presentable_image', 'VK_KHR_surface', 'VK_KHR_swapchain', 'VK_KHR_get_surface_capabilities2' ] knownExtensions = interceptedExtensions + [ 'VK_KHR_get_physical_device_properties2', 'VK_ANDROID_external_memory_android_hardware_buffer', 'VK_KHR_bind_memory2' ] def defineProcHookType(f): f.write ("""struct ProcHook { enum Type { GLOBAL, INSTANCE, DEVICE, }; enum Extension {\n""") for exts in knownExtensions: f.write (gencom.clang_off_spaces*2 + exts[3:] + ',\n') f.write ('\n') f.write (gencom.clang_off_spaces*2 + """EXTENSION_CORE, // valid bit EXTENSION_COUNT, EXTENSION_UNKNOWN, }; const char* name; Type type; Extension extension; PFN_vkVoidFunction proc; PFN_vkVoidFunction checked_proc; // always nullptr for non-device hooks };\n\n""") def isExtensionIntercepted(extensionName): if extensionName in interceptedExtensions: return True return False def isDriverTableEntry(functionName): switchCase = { # Create functions of dispatchable objects 'vkCreateDevice' : True, 'vkGetDeviceQueue' : True, 'vkGetDeviceQueue2' : True, 'vkAllocateCommandBuffers' : True, # Destroy functions of dispatchable objects 'vkDestroyInstance' : True, 'vkDestroyDevice' : True, # Enumeration of extensions 'vkEnumerateDeviceExtensionProperties' : True, # We cache physical devices in loader.cpp 'vkEnumeratePhysicalDevices' : True, 'vkEnumeratePhysicalDeviceGroups' : True, 'vkGetInstanceProcAddr' : True, 'vkGetDeviceProcAddr' : True, # VK_KHR_swapchain->VK_ANDROID_native_buffer translation 'vkCreateImage' : True, 'vkDestroyImage' : True, 'vkGetPhysicalDeviceProperties' : True, 'vkGetPhysicalDeviceProperties2' : True, 'vkGetPhysicalDeviceProperties2KHR' : True, # VK_KHR_swapchain v69 requirement 'vkBindImageMemory2' : True, 'vkBindImageMemory2KHR' : True } if gencom.isFunctionSupported(functionName): if functionName in switchCase: return True if functionName in gencom.extensionsDict: if gencom.extensionsDict[functionName] == 'VK_ANDROID_native_buffer' or gencom.extensionsDict[functionName] == 'VK_EXT_debug_report': return True return False def isInstanceDriverTableEntry(functionName): if isDriverTableEntry(functionName) and gencom.isInstanceDispatched(functionName): return True return False def isDeviceDriverTableEntry(functionName): if isDriverTableEntry(functionName) and gencom.isDeviceDispatched(functionName): return True return False def driver_genh(): header = """#ifndef LIBVULKAN_DRIVER_GEN_H #define LIBVULKAN_DRIVER_GEN_H #include <vulkan/vk_android_native_buffer.h> #include <vulkan/vulkan.h> #include <bitset> namespace vulkan { namespace driver {\n\n""" genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','driver_gen2.h') with open(genfile, 'w') as f: f.write (gencom.copyright) f.write (gencom.warning) f.write (header) defineProcHookType(f) f.write ('struct InstanceDriverTable {\n') gencom.clang_off(f, 1) for cmds in gencom.allCommandsList: if isInstanceDriverTableEntry(cmds): f.write (gencom.clang_off_spaces + 'PFN_' + cmds + ' ' + cmds[2:] + ';\n') gencom.clang_on(f, 1) f.write ('};\n\n') f.write ('struct DeviceDriverTable {\n') gencom.clang_off(f,1) for cmds in gencom.allCommandsList: if isDeviceDriverTableEntry(cmds): f.write (gencom.clang_off_spaces + 'PFN_' + cmds + ' ' + cmds[2:] + ';\n') gencom.clang_on(f,1) f.write ('};\n\n') f.write ("""const ProcHook* GetProcHook(const char* name); ProcHook::Extension GetProcHookExtension(const char* name); bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions); bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions); } // namespace driver } // namespace vulkan #endif // LIBVULKAN_DRIVER_TABLE_H\n""") def isIntercepted(functionName): switchCase = { # Create functions of dispatchable objects 'vkCreateInstance' : True, 'vkCreateDevice' : True, 'vkEnumeratePhysicalDevices' : True, 'vkEnumeratePhysicalDeviceGroups' : True, 'vkGetDeviceQueue' : True, 'vkGetDeviceQueue2' : True, 'vkAllocateCommandBuffers' : True, # Destroy functions of dispatchable objects 'vkDestroyInstance' : True, 'vkDestroyDevice' : True, # Enumeration of extensions 'vkEnumerateInstanceExtensionProperties' : True, 'vkEnumerateDeviceExtensionProperties' : True, 'vkGetInstanceProcAddr' : True, 'vkGetDeviceProcAddr' : True, # VK_KHR_swapchain v69 requirement 'vkBindImageMemory2' : True, 'vkBindImageMemory2KHR' : True } if gencom.isFunctionSupported(functionName): if functionName in switchCase: return switchCase[functionName] if functionName in gencom.extensionsDict: return isExtensionIntercepted(gencom.extensionsDict[functionName]) return False def needProcHookStub(functionName): if isIntercepted(functionName) and gencom.isDeviceDispatched(functionName): if functionName in gencom.extensionsDict: if not gencom.isExtensionInternal(gencom.extensionsDict[functionName]): return True return False def defineInitProc(name, f): f.write ('#define UNLIKELY(expr) __builtin_expect((expr), 0)\n') f.write ('\n') f.write ("""#define INIT_PROC(required, obj, proc) \\ do { \\ data.""" + name + """.proc = \\ reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\ if (UNLIKELY(required && !data.""" + name + """.proc)) { \\ ALOGE("missing " #obj " proc: vk" #proc); \\ success = false; \\ } \\ } while (0)\n\n""") def defineInitProcExt(f): f.write ("""#define INIT_PROC_EXT(ext, required, obj, proc) \\ do { \\ if (extensions[ProcHook::ext]) \\ INIT_PROC(required, obj, proc); \\ } while (0)\n\n""") def defineProcHookStub(functionName, f): if needProcHookStub(functionName): ext_name = gencom.extensionsDict[functionName] base_name = functionName[2:] paramList = [''.join(i) for i in gencom.paramDict[functionName]] p0 = gencom.paramDict[functionName][0][1] f.write ('VKAPI_ATTR ' + gencom.returnTypeDict[functionName] + ' checked' + base_name + '(' + ', '.join(paramList) + ') {\n') ext_hook = 'ProcHook::' + ext_name[3:] f.write (gencom.clang_off_spaces + 'if (GetData(' + p0 + ').hook_extensions[' + ext_hook + ']) {\n') f.write (gencom.clang_off_spaces *2) if gencom.returnTypeDict[functionName] != 'void': f.write ('return ') paramNames = [''.join(i[1]) for i in gencom.paramDict[functionName]] f.write (base_name + '(' + ', '.join(paramNames) + ');\n') f.write (gencom.clang_off_spaces + '} else {\n') f.write (gencom.clang_off_spaces*2 + 'Logger(' + p0 + ').Err(' + p0 + ', \"' + ext_name + ' not enabled. ' + functionName + ' not executed.\");\n') if gencom.returnTypeDict[functionName] != 'void': f.write (gencom.clang_off_spaces*2 + 'return VK_SUCCESS;\n') f.write (gencom.clang_off_spaces + '}\n') f.write ('}\n\n') def defineGlobalProcHook(functionName, f): base_name = functionName[2:] assert (functionName not in gencom.extensionsDict) f.write (gencom.clang_off_spaces + '{\n' + gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n' + gencom.clang_off_spaces*2) f.write ("""ProcHook::GLOBAL, ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """), nullptr, },\n""") def defineInstanceProcHook(functionName, f): base_name = functionName[2:] f.write (gencom.clang_off_spaces + '{\n') f.write (gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n') f.write (gencom.clang_off_spaces*2 + 'ProcHook::INSTANCE,\n') if functionName in gencom.extensionsDict: ext_name = gencom.extensionsDict[functionName] f.write (gencom.clang_off_spaces*2 + 'ProcHook::' + ext_name[3:] + ',\n') if gencom.isExtensionInternal(ext_name): f.write (gencom.clang_off_spaces*2 + 'nullptr,\n' + gencom.clang_off_spaces*2 + 'nullptr,\n') else: f.write (gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(' + base_name + '),\n' + gencom.clang_off_spaces*2 + 'nullptr,\n') else: f.write (gencom.clang_off_spaces*2 + """ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """), nullptr,\n""") f.write (gencom.clang_off_spaces + '},\n') def defineDeviceProcHook(functionName, f): base_name = functionName[2:] f.write (gencom.clang_off_spaces + '{\n') f.write (gencom.clang_off_spaces*2 + '\"' + functionName + '\",\n') f.write (gencom.clang_off_spaces*2 + 'ProcHook::DEVICE,\n') if functionName in gencom.extensionsDict: ext_name = gencom.extensionsDict[functionName] f.write (gencom.clang_off_spaces*2 + 'ProcHook::' + ext_name[3:] + ',\n') if gencom.isExtensionInternal(ext_name): f.write (gencom.clang_off_spaces*2 + 'nullptr,\n' + gencom.clang_off_spaces*2 + 'nullptr,\n') else: f.write (gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(' + base_name + '),\n' + gencom.clang_off_spaces*2 + 'reinterpret_cast<PFN_vkVoidFunction>(checked' + base_name + '),\n') else: f.write (gencom.clang_off_spaces*2 + """ProcHook::EXTENSION_CORE, reinterpret_cast<PFN_vkVoidFunction>(""" + base_name + """), nullptr,\n""") f.write (gencom.clang_off_spaces + '},\n') def driver_gencpp(): header = """#include <log/log.h> #include <string.h> #include <algorithm> #include "driver.h" namespace vulkan { namespace driver { namespace { // clang-format off\n\n""" genfile = os.path.join(os.path.dirname(__file__),'..','libvulkan','driver_gen2.cpp') with open(genfile, 'w') as f: f.write (gencom.copyright) f.write (gencom.warning) f.write (header) for cmds in gencom.allCommandsList: defineProcHookStub(cmds, f) gencom.clang_on(f, 0) f.write ('\n') f.write ('const ProcHook g_proc_hooks[] = {\n') gencom.clang_off(f, 1) sortedCommandsList = sorted(gencom.allCommandsList) for cmds in sortedCommandsList: if isIntercepted(cmds): if gencom.isGloballyDispatched(cmds): defineGlobalProcHook(cmds, f) elif gencom.isInstanceDispatched(cmds): defineInstanceProcHook(cmds, f) elif gencom.isDeviceDispatched(cmds): defineDeviceProcHook(cmds, f) gencom.clang_on(f, 1) f.write ('};\n\n} // namespace\n\n') f.write ("""const ProcHook* GetProcHook(const char* name) { const auto& begin = g_proc_hooks; const auto& end = g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]); const auto hook = std::lower_bound( begin, end, name, [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; }); return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr; }\n\n""") f.write ('ProcHook::Extension GetProcHookExtension(const char* name) {\n') gencom.clang_off(f, 1) for exts in knownExtensions: f.write (gencom.clang_off_spaces + 'if (strcmp(name, \"' + exts + '\") == 0) return ProcHook::' + exts[3:] + ';\n') gencom.clang_on(f, 1) f.write (gencom.clang_off_spaces + 'return ProcHook::EXTENSION_UNKNOWN;\n') f.write ('}\n\n') defineInitProc('driver', f) defineInitProcExt(f) f.write ("""bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) { auto& data = GetData(instance); bool success = true;\n\n""") gencom.clang_off(f, 1) for cmds in gencom.allCommandsList: if isInstanceDriverTableEntry(cmds): gencom.initProc(cmds, f) gencom.clang_on(f, 1) f.write ('\n' + gencom.clang_off_spaces + 'return success;\n') f.write ('}\n\n') f.write ("""bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc, const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) { auto& data = GetData(dev); bool success = true;\n\n""") gencom.clang_off(f, 1) for cmds in gencom.allCommandsList: if isDeviceDriverTableEntry(cmds): gencom.initProc(cmds, f) gencom.clang_on(f, 1) f.write ('\n' + gencom.clang_off_spaces + 'return success;\n') f.write ('}\n\n} // namespace driver\n} // namespace vulkan\n\n') gencom.clang_on(f, 0)
vulkan/scripts/generator_common.py +26 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,11 @@ blacklistedExtensions = [ 'VK_NV_win32_keyed_mutex', 'VK_EXT_metal_surface', #not present in vulkan.api 'VK_NVX_image_view_handle', #not present in vulkan.api 'VK_NV_cooperative_matrix' #not present in vulkan.api 'VK_NV_cooperative_matrix', #not present in vulkan.api 'VK_EXT_headless_surface', #not present in vulkan.api 'VK_GGP_stream_descriptor_surface', #not present in vulkan.api 'VK_NV_coverage_reduction_mode', #not present in vulkan.api 'VK_EXT_full_screen_exclusive' #not present in vulkan.api ] exportedExtensions = [ Loading @@ -71,6 +75,11 @@ exportedExtensions = [ 'VK_ANDROID_external_memory_android_hardware_buffer' ] def isExtensionInternal(extensionName): if extensionName == 'VK_ANDROID_native_buffer': return True return False def isFunctionSupported(functionName): if functionName not in extensionsDict: return True Loading Loading @@ -167,6 +176,7 @@ def parseVulkanRegistry(): aliasDict[fnName] = alias allCommandsList.append(fnName) paramDict[fnName] = paramDict[alias].copy() returnTypeDict[fnName] = returnTypeDict[alias] for params in command: if(params.tag == 'param'): paramtype = "" Loading Loading @@ -208,6 +218,19 @@ def parseVulkanRegistry(): if apiversion != "": versionDict[commandname] = apiversion # TODO(adsrini): http://b/136570819 extensionsDict['vkGetSwapchainGrallocUsage2ANDROID'] = 'VK_ANDROID_native_buffer' allCommandsList.append('vkGetSwapchainGrallocUsage2ANDROID') returnTypeDict['vkGetSwapchainGrallocUsage2ANDROID'] = 'VkResult' paramDict['vkGetSwapchainGrallocUsage2ANDROID'] = [ ('VkDevice ', 'device', None), ('VkFormat ', 'format', None), ('VkImageUsageFlags', 'imageUsage', None), ('VkSwapchainImageUsageFlagsANDROID ', 'swapchainImageUsage', None), ('u64* ', 'grallocConsumerUsage', None), ('u64* ', 'grallocProducerUsage', None) ] for feature in root.iter('feature'): apiversion = feature.get('name') for req in feature: Loading @@ -226,6 +249,8 @@ def initProc(name, f): if name in versionDict and versionDict[name] == 'VK_VERSION_1_1': f.write('false, ') elif name == 'vkGetSwapchainGrallocUsageANDROID' or name == 'vkGetSwapchainGrallocUsage2ANDROID': # optional in vulkan.api f.write('false, ') else: f.write('true, ') Loading