diff options
Diffstat (limited to 'codegen/vulkan/scripts/cereal/dispatch.py')
-rw-r--r-- | codegen/vulkan/scripts/cereal/dispatch.py | 499 |
1 files changed, 0 insertions, 499 deletions
diff --git a/codegen/vulkan/scripts/cereal/dispatch.py b/codegen/vulkan/scripts/cereal/dispatch.py deleted file mode 100644 index 42cba8ca..00000000 --- a/codegen/vulkan/scripts/cereal/dispatch.py +++ /dev/null @@ -1,499 +0,0 @@ -# Copyright (c) 2018 The Android Open Source Project -# Copyright (c) 2018 Google Inc. -# -# 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. - -from .common.codegen import CodeGen -from .common.vulkantypes import \ - VulkanAPI, makeVulkanTypeSimple, iterateVulkanType - -from .wrapperdefs import VulkanWrapperGenerator - -# No real good way to automatically infer the most important Vulkan API -# functions as it relates to which getProcAddress function to use, plus -# we might want to control which function to use depending on our -# performance needs. - -# This is based on the minimum set of functions needed to be directly -# queried with dlsym and not returning null. -getProcAddrFuncs = [ - "vkGetInstanceProcAddr", - "vkDestroyInstance", - "vkEnumeratePhysicalDevices", - "vkGetPhysicalDeviceFeatures", - "vkGetPhysicalDeviceFormatProperties", - "vkGetPhysicalDeviceImageFormatProperties", - "vkGetPhysicalDeviceProperties", - "vkGetPhysicalDeviceQueueFamilyProperties", - "vkGetPhysicalDeviceMemoryProperties", - "vkCreateDevice", - "vkDestroyDevice", - "vkEnumerateDeviceExtensionProperties", - "vkEnumerateDeviceLayerProperties", -] - -# Some methods can only be found using dlsym() while we cannot get the function -# address using vkGetInstProcAddr() or vkGetDeviceProcAddr(). These function -# pointers should only be initialized when setting up the dispatch from system -# loader. -getProcAddrOnlyFuncs = [ - "vkGetMTLDeviceMVK", - "vkSetMTLTextureMVK", - "vkGetMTLTextureMVK", - "vkGetMTLBufferMVK", - "vkUseIOSurfaceMVK", - "vkGetIOSurfaceMVK", -] - -getInstanceProcAddrNoInstanceFuncs = [ - "vkCreateInstance", - "vkEnumerateInstanceExtensionProperties", - "vkEnumerateInstanceLayerProperties", -] - -getInstanceProcAddrFuncs = [ - "vkGetDeviceProcAddr", - "vkCreateSwapchainKHR", - "vkDestroySwapchainKHR", - "vkGetSwapchainImagesKHR", - "vkAcquireNextImageKHR", - "vkQueuePresentKHR", - "vkCreateMacOSSurfaceMVK", - "vkCreateWin32SurfaceKHR", - "vkGetPhysicalDeviceWin32PresentationSupportKHR", - "vkCreateXlibSurfaceKHR", - "vkGetPhysicalDeviceXlibPresentationSupportKHR", - "vkCreateXcbSurfaceKHR", - "vkGetPhysicalDeviceXcbPresentationSupportKHR", - "vkGetPhysicalDeviceSparseImageFormatProperties", - "vkEnumerateInstanceVersion", - "vkEnumeratePhysicalDeviceGroups", - "vkGetPhysicalDeviceFeatures2", - "vkGetPhysicalDeviceProperties2", - "vkGetPhysicalDeviceFormatProperties2", - "vkGetPhysicalDeviceImageFormatProperties2", - "vkGetPhysicalDeviceQueueFamilyProperties2", - "vkGetPhysicalDeviceMemoryProperties2", - "vkGetPhysicalDeviceSparseImageFormatProperties2", - "vkGetPhysicalDeviceExternalBufferProperties", - "vkGetPhysicalDeviceExternalFenceProperties", - "vkGetPhysicalDeviceExternalSemaphoreProperties", -] - -# Implicitly, everything else is going to be obtained -# with vkGetDeviceProcAddr, -# unless it has instance in the arg. - -def isGetProcAddressAPI(vulkanApi): - return vulkanApi.name in getProcAddrFuncs - -def isGetProcAddressOnlyAPI(vulkanApi): - return vulkanApi.name in getProcAddrOnlyFuncs - -def isGetInstanceProcAddressNoInstanceAPI(vulkanApi): - return vulkanApi.name in getInstanceProcAddrNoInstanceFuncs - -def isGetInstanceProcAddressAPI(vulkanApi): - if vulkanApi.name in getInstanceProcAddrFuncs: - return True - - if vulkanApi.parameters[0].typeName == "VkInstance": - return True - - return False - -def isGetDeviceProcAddressAPI(vulkanApi): - if isGetProcAddressAPI(vulkanApi): - return False - - if isGetProcAddressOnlyAPI(vulkanApi): - return False - - if isGetInstanceProcAddressAPI(vulkanApi): - return False - - return True - -def inferProcAddressFuncType(vulkanApi): - if isGetProcAddressAPI(vulkanApi): - return "global" - if isGetProcAddressOnlyAPI(vulkanApi): - return "global-only" - if isGetInstanceProcAddressNoInstanceAPI(vulkanApi): - return "global-instance" - if isGetInstanceProcAddressAPI(vulkanApi): - return "instance" - return "device" - -# VulkanDispatch defines a struct, VulkanDispatch, -# that is populated by function pointers from the Vulkan -# loader. No attempt is made to do something different -# for instance vs device functions. -class VulkanDispatch(VulkanWrapperGenerator): - def __init__(self, module, typeInfo): - VulkanWrapperGenerator.__init__(self, module, typeInfo) - - self.apisToGet = {} - - self.cgenHeader = CodeGen() - self.cgenImpl = CodeGen() - self.typeInfo = typeInfo - - self.currentFeature = "" - self.featureForCodegen = "" - - def onBegin(self): - - # The first way is to use just the loader to get symbols. This doesn't - # necessarily work with extensions because at that point the dispatch - # table needs to be specific to a particular Vulkan instance or device. - - self.cgenHeader.line(""" -void init_vulkan_dispatch_from_system_loader( - DlOpenFunc dlOpenFunc, - DlSymFunc dlSymFunc, - VulkanDispatch* dispatch_out); -""") - - # The second way is to initialize the table from a given Vulkan - # instance or device. Provided the instance or device was created with - # the right extensions, we can obtain function pointers to extension - # functions this way. - - self.cgenHeader.line(""" -void init_vulkan_dispatch_from_instance( - VulkanDispatch* vk, - VkInstance instance, - VulkanDispatch* dispatch_out); -""") - self.cgenHeader.line(""" -void init_vulkan_dispatch_from_device( - VulkanDispatch* vk, - VkDevice device, - VulkanDispatch* dispatch_out); -""") - - # After populating a VulkanDispatch with the above methods, - # it can be useful to check whether the Vulkan 1.0 or 1.1 methods - # are all there. - def emit_feature_check_decl(cgen, tag, featureToCheck): - cgen.line(""" -bool vulkan_dispatch_check_%s_%s( - const VulkanDispatch* vk); -""" % (tag, featureToCheck)) - - emit_feature_check_decl(self.cgenHeader, "instance", "VK_VERSION_1_0") - emit_feature_check_decl(self.cgenHeader, "instance", "VK_VERSION_1_1") - emit_feature_check_decl(self.cgenHeader, "device", "VK_VERSION_1_0") - emit_feature_check_decl(self.cgenHeader, "device", "VK_VERSION_1_1") - - self.cgenHeader.line("struct VulkanDispatch {") - self.module.appendHeader(self.cgenHeader.swapCode()) - - def syncFeatureQuiet(self, cgen, feature): - if self.featureForCodegen != feature: - if feature == "": - self.featureForCodegen = feature - return - - self.featureForCodegen = feature - - def syncFeature(self, cgen, feature): - if self.featureForCodegen != feature: - if feature == "": - cgen.leftline("#endif") - self.featureForCodegen = feature - return - - if self.featureForCodegen != "": - cgen.leftline("#endif") - - cgen.leftline("#ifdef %s" % feature) - self.featureForCodegen = feature - - def makeDlsymCall(self, cgen, apiname, typedecl): - cgen.stmt( \ - "out->%s = (%s)dlSymFunc(lib, \"%s\")" % \ - (apiname, typedecl, apiname)) - - def makeGetInstanceProcAddrCall(self, cgen, dispatch, instance, apiname, typedecl): - cgen.stmt( \ - "out->%s = (%s)%s->vkGetInstanceProcAddr(%s, \"%s\")" % \ - (apiname, typedecl, dispatch, instance, apiname)) - - def makeGetDeviceProcAddrCall(self, cgen, dispatch, device, apiname, typedecl): - cgen.stmt( \ - "out->%s = (%s)%s->vkGetDeviceProcAddr(%s, \"%s\")" % \ - (apiname, typedecl, dispatch, device, apiname)) - - def onEnd(self): - self.cgenHeader.line("};") - self.module.appendHeader(self.cgenHeader.swapCode()) - - # Getting dispatch tables from the loader - self.cgenImpl.line(""" -void init_vulkan_dispatch_from_system_loader( - DlOpenFunc dlOpenFunc, - DlSymFunc dlSymFunc, - VulkanDispatch* out)""") - - self.cgenImpl.beginBlock() - - self.cgenImpl.stmt("memset(out, 0x0, sizeof(VulkanDispatch))") - - self.cgenImpl.stmt("void* lib = dlOpenFunc()") - self.cgenImpl.stmt("if (!lib) return") - - apis = \ - self.apisToGet["global"] + \ - self.apisToGet["global-instance"] + \ - self.apisToGet["instance"] + \ - self.apisToGet["device"] + \ - self.apisToGet["global-only"] - - for vulkanApi, typeDecl, feature in apis: - self.syncFeature(self.cgenImpl, feature) - self.makeDlsymCall(self.cgenImpl, vulkanApi.name, typeDecl) - - self.syncFeature(self.cgenImpl, "") - self.cgenImpl.endBlock() - - # Getting instance dispatch tables - self.cgenImpl.line(""" -void init_vulkan_dispatch_from_instance( - VulkanDispatch* vk, - VkInstance instance, - VulkanDispatch* out)""") - - self.cgenImpl.beginBlock() - - self.cgenImpl.stmt("memset(out, 0x0, sizeof(VulkanDispatch))") - - apis = \ - self.apisToGet["global"] + \ - self.apisToGet["global-instance"] + \ - self.apisToGet["instance"] + \ - self.apisToGet["device"] - - for vulkanApi, typeDecl, feature in apis: - self.syncFeature(self.cgenImpl, feature) - self.makeGetInstanceProcAddrCall( - self.cgenImpl, "vk", "instance", vulkanApi.name, typeDecl) - - self.syncFeature(self.cgenImpl, "") - self.cgenImpl.endBlock() - - # Getting device dispatch tables - self.cgenImpl.line(""" -void init_vulkan_dispatch_from_device( - VulkanDispatch* vk, - VkDevice device, - VulkanDispatch* out)""") - - self.cgenImpl.beginBlock() - - self.cgenImpl.stmt("memset(out, 0x0, sizeof(VulkanDispatch))") - - apis = \ - self.apisToGet["global"] + \ - self.apisToGet["global-instance"] + \ - self.apisToGet["instance"] + \ - self.apisToGet["device"] - - for vulkanApi, typeDecl, feature in apis: - self.syncFeature(self.cgenImpl, feature) - self.makeGetDeviceProcAddrCall( - self.cgenImpl, "vk", "device", vulkanApi.name, typeDecl) - - self.syncFeature(self.cgenImpl, "") - self.cgenImpl.endBlock() - - # Check Vulkan 1.0 / 1.1 functions - - def emit_check_impl(cgen, dispatchVar, feature, featureToCheck, apiName): - if feature == featureToCheck: - cgen.beginIf("!%s->%s" % (dispatchVar, apiName)) - cgen.stmt("fprintf(stderr, \"%s check failed: %s not found\\n\")" % (featureToCheck, apiName)) - cgen.stmt("good = false") - cgen.endIf() - - def emit_feature_check_impl(context, cgen, tag, featureToCheck, apis): - cgen.line(""" -bool vulkan_dispatch_check_%s_%s( - const VulkanDispatch* vk) -""" % (tag, featureToCheck)) - - cgen.beginBlock() - - cgen.stmt("bool good = true") - - for vulkanApi, typeDecl, feature in apis: - context.syncFeatureQuiet(self.cgenImpl, feature) - emit_check_impl(cgen, "vk", feature, featureToCheck, vulkanApi.name) - - context.syncFeatureQuiet(self.cgenImpl, "") - - cgen.stmt("return good") - cgen.endBlock() - - instanceApis = self.apisToGet["global-instance"] + self.apisToGet["instance"] - - emit_feature_check_impl(self, self.cgenImpl, "instance", "VK_VERSION_1_0", instanceApis) - emit_feature_check_impl(self, self.cgenImpl, "instance", "VK_VERSION_1_1", instanceApis) - emit_feature_check_impl(self, self.cgenImpl, "device", "VK_VERSION_1_0", self.apisToGet["device"]) - emit_feature_check_impl(self, self.cgenImpl, "device", "VK_VERSION_1_1", self.apisToGet["device"]) - - self.module.appendImpl(self.cgenImpl.swapCode()) - - def onBeginFeature(self, featureName, featureType): - self.currentFeature = featureName - - def onGenType(self, typeXml, name, alias): - VulkanWrapperGenerator.onGenType(self, typeXml, name, alias) - - def onGenCmd(self, cmdinfo, name, alias): - VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias) - - vulkanApi = self.typeInfo.apis[name] - - typeDecl = "PFN_%s" % name - - procAddressType = inferProcAddressFuncType(vulkanApi) - - self.cgenHeader.stmt("%s %s" % (typeDecl, name)); - self.module.appendHeader(self.cgenHeader.swapCode()) - - current = self.apisToGet.get(procAddressType, []) - if current == []: - self.apisToGet[procAddressType] = current - current.append((vulkanApi, typeDecl, self.currentFeature)) - -# VulkanDispatchFast allows one to get the optimal function pointers -# for a given Vulkan API call, in order to improve performance. -# -# We can optionally query VkDevices to get function pointers that are -# closer to the ICD and have fewer levels of indirection from the loader -# to get there. -# See -# https://github.com/KhronosGroup/Vulkan-Loader/blob/master/loader/LoaderAndLayerInterface.md -# for more info. -# -# This requires the calling C++ code to provide functions to -# generate the desired instances and devices, otherwise we won't know -# which instance or device to pass to vkGet(Instance|Device)ProcAddr, -# so it does push more complexity to the user. -class VulkanDispatchFast(VulkanDispatch): - - def __init__(self, module, typeInfo): - VulkanDispatch.__init__(self, module, typeInfo) - - def onBegin(self): - self.cgenHeader.line(""" -void init_vulkan_dispatch_from_system_loader( - DlOpenFunc dlOpenFunc, - DlSymFunc dlSymFunc, - InstanceGetter instanceGetter, - DeviceGetter deviceGetter, - VulkanDispatch* dispatch_out); -""") - - self.cgenHeader.line("struct VulkanDispatch {") - self.cgenHeader.line("VkInstance instance;") - self.cgenHeader.line("VkPhysicalDevice physicalDevice;") - self.cgenHeader.line("uint32_t physicalDeviceQueueFamilyInfoCount;") - self.cgenHeader.line("VkQueueFamilyProperties* physicalDeviceQueueFamilyInfos;") - self.cgenHeader.line("VkDevice device;") - self.cgenHeader.line("bool presentCapable;") - self.module.appendHeader(self.cgenHeader.swapCode()) - - def makeGetProcAddr(self, cgen, dispatchLevel, dispatch, apiname, typedecl): - if dispatchLevel == "instance": - funcname = "vkGetInstanceProcAddr" - elif dispatchLevel == "device": - funcname = "vkGetDeviceProcAddr" - else: - raise - - cgen.stmt( \ - "out->%s = (%s)out->%s(%s, \"%s\")" % \ - (apiname, typedecl, funcname, dispatch, apiname)) - - def onEnd(self): - self.cgenHeader.line("};") - self.module.appendHeader(self.cgenHeader.swapCode()) - - self.cgenImpl.line(""" -void init_vulkan_dispatch_from_system_loader( - DlOpenFunc dlOpenFunc, - DlSymFunc dlSymFunc, - InstanceGetter instanceGetter, - DeviceGetter deviceGetter, - VulkanDispatch* out)""") - - self.cgenImpl.beginBlock() - - self.cgenImpl.stmt("out->instance = nullptr") - self.cgenImpl.stmt("out->physicalDevice = nullptr") - self.cgenImpl.stmt("out->physicalDeviceQueueFamilyInfoCount = 0") - self.cgenImpl.stmt("out->physicalDeviceQueueFamilyInfos = nullptr") - self.cgenImpl.stmt("out->device = nullptr") - self.cgenImpl.stmt("out->presentCapable = false") - - self.cgenImpl.stmt("void* lib = dlOpenFunc()") - self.cgenImpl.stmt("if (!lib) return") - - for vulkanApi, typeDecl, feature in self.apisToGet["global"]: - self.syncFeature(self.cgenImpl, feature) - self.makeDlsymCall(self.cgenImpl, vulkanApi.name, typeDecl) - - self.syncFeature(self.cgenImpl, "") - self.cgenImpl.stmt("if (!out->vkGetInstanceProcAddr) return") - - for vulkanApi, typeDecl, feature in self.apisToGet["global-instance"]: - self.syncFeature(self.cgenImpl, feature) - self.makeGetProcAddr( \ - self.cgenImpl, "instance", "nullptr", vulkanApi.name, typeDecl); - - self.syncFeature(self.cgenImpl, "") - self.cgenImpl.stmt("if (!instanceGetter(out, &out->instance)) return") - - for vulkanApi, typeDecl, feature in self.apisToGet["instance"]: - self.syncFeature(self.cgenImpl, feature) - self.makeGetProcAddr( \ - self.cgenImpl, "instance", "out->instance", vulkanApi.name, typeDecl); - - self.syncFeature(self.cgenImpl, "") - - self.cgenImpl.stmt("if (!deviceGetter(out, out->instance, &out->physicalDevice, &out->physicalDeviceQueueFamilyInfoCount, nullptr, &out->device, &out->presentCapable)) return") - self.cgenImpl.stmt("out->physicalDeviceQueueFamilyInfos = (VkQueueFamilyProperties*)malloc(out->physicalDeviceQueueFamilyInfoCount * sizeof(VkQueueFamilyProperties))"); - self.cgenImpl.stmt("if (!deviceGetter(out, out->instance, &out->physicalDevice, &out->physicalDeviceQueueFamilyInfoCount, out->physicalDeviceQueueFamilyInfos, &out->device, &out->presentCapable)) return") - - for vulkanApi, typeDecl, feature in self.apisToGet["device"]: - self.syncFeature(self.cgenImpl, feature) - self.makeGetProcAddr( \ - self.cgenImpl, "device", "out->device", vulkanApi.name, typeDecl); - - self.syncFeature(self.cgenImpl, "") - - self.cgenImpl.endBlock() - - self.module.appendImpl(self.cgenImpl.swapCode()) - - def onBeginFeature(self, featureName, featureType): - VulkanDispatch.onBeginFeature(self, featureName, featureType); - - def onGenType(self, typeXml, name, alias): - VulkanDispatch.onGenType(self, typeXml, name, alias); - - def onGenCmd(self, cmdinfo, name, alias): - VulkanDispatch.onGenCmd(self, cmdinfo, name, alias); |