diff options
author | Bas Nieuwenhuizen <[email protected]> | 2018-02-11 14:38:42 +0100 |
---|---|---|
committer | Bas Nieuwenhuizen <[email protected]> | 2018-02-23 00:39:02 +0100 |
commit | e72ad05c1d6bdedf3b15cfe7ba42c801254d6112 (patch) | |
tree | f38b69296fb1f70aa666092c44e4a6ed1d636eeb /src/amd/vulkan/radv_entrypoints_gen.py | |
parent | 414f5e0e14e5f2e90b688344660751803935c6f2 (diff) |
radv: Return NULL for entrypoints when not supported.
This implements strict checking for the entrypoint ProcAddr
functions.
- InstanceProcAddr with instance = NULL, only returns the 3 allowed
entrypoints.
- DeviceProcAddr does not return any instance entrypoints.
- InstanceProcAddr does not return non-supported or disabled
instance entrypoints.
- DeviceProcAddr does not return non-supported or disabled device
entrypoints.
- InstanceProcAddr still returns non-supported device entrypoints.
Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd/vulkan/radv_entrypoints_gen.py')
-rw-r--r-- | src/amd/vulkan/radv_entrypoints_gen.py | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/src/amd/vulkan/radv_entrypoints_gen.py b/src/amd/vulkan/radv_entrypoints_gen.py index f7a791967b9..08ca9ccca13 100644 --- a/src/amd/vulkan/radv_entrypoints_gen.py +++ b/src/amd/vulkan/radv_entrypoints_gen.py @@ -185,7 +185,45 @@ static const uint16_t map[] = { % endfor }; -void * +/** Return true if the core version or extension in which the given entrypoint + * is defined is enabled. + * + * If instance is NULL, we only allow the 3 commands explicitly allowed by the vk + * spec. + * + * If device is NULL, all device extensions are considered enabled. + */ +static bool +radv_entrypoint_is_enabled(int index, uint32_t core_version, + const struct radv_instance_extension_table *instance, + const struct radv_device_extension_table *device) +{ + switch (index) { +% for e in entrypoints: + case ${e.num}: + % if not e.device_command: + if (device) return false; + % endif + % if e.name == 'vkCreateInstance' or e.name == 'vkEnumerateInstanceExtensionProperties' or e.name == 'vkEnumerateInstanceLayerProperties': + return !device; + % elif e.core_version: + return instance && ${e.core_version.c_vk_version()} <= core_version; + % elif e.extension: + % if e.extension.type == 'instance': + return instance && instance->${e.extension.name[3:]}; + % else: + return instance && (!device || device->${e.extension.name[3:]}); + % endif + % else: + return instance; + % endif +% endfor + default: + return false; + } +} + +static int radv_lookup_entrypoint(const char *name) { static const uint32_t prime_factor = ${prime_factor}; @@ -202,15 +240,36 @@ radv_lookup_entrypoint(const char *name) do { i = map[h & ${hash_mask}]; if (i == none) - return NULL; + return -1; e = &entrypoints[i]; h += prime_step; } while (e->hash != hash); if (strcmp(name, strings + e->name) != 0) + return -1; + + return i; +} + +void * +radv_lookup_entrypoint_unchecked(const char *name) +{ + int index = radv_lookup_entrypoint(name); + if (index < 0) return NULL; + return radv_resolve_entrypoint(index); +} - return radv_resolve_entrypoint(i); +void * +radv_lookup_entrypoint_checked(const char *name, + uint32_t core_version, + const struct radv_instance_extension_table *instance, + const struct radv_device_extension_table *device) +{ + int index = radv_lookup_entrypoint(name); + if (index < 0 || !radv_entrypoint_is_enabled(index, core_version, instance, device)) + return NULL; + return radv_resolve_entrypoint(index); }""", output_encoding='utf-8') NONE = 0xffff @@ -239,6 +298,7 @@ class Entrypoint(object): # Extensions which require this entrypoint self.core_version = None self.extension = None + self.device_command = len(params) > 0 and (params[0].type == 'VkDevice' or params[0].type == 'VkQueue' or params[0].type == 'VkCommandBuffer') def prefixed_name(self, prefix): assert self.name.startswith('vk') |