summaryrefslogtreecommitdiffstats
path: root/src/amd
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2018-02-11 14:38:42 +0100
committerBas Nieuwenhuizen <[email protected]>2018-02-23 00:39:02 +0100
commite72ad05c1d6bdedf3b15cfe7ba42c801254d6112 (patch)
treef38b69296fb1f70aa666092c44e4a6ed1d636eeb /src/amd
parent414f5e0e14e5f2e90b688344660751803935c6f2 (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')
-rw-r--r--src/amd/vulkan/radv_device.c18
-rw-r--r--src/amd/vulkan/radv_entrypoints_gen.py66
-rw-r--r--src/amd/vulkan/radv_private.h6
-rw-r--r--src/amd/vulkan/radv_wsi.c2
4 files changed, 83 insertions, 9 deletions
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 79534fbd5fc..f197b7f484c 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -2311,10 +2311,15 @@ VkResult radv_EnumerateDeviceExtensionProperties(
}
PFN_vkVoidFunction radv_GetInstanceProcAddr(
- VkInstance instance,
+ VkInstance _instance,
const char* pName)
{
- return radv_lookup_entrypoint(pName);
+ RADV_FROM_HANDLE(radv_instance, instance, _instance);
+
+ return radv_lookup_entrypoint_checked(pName,
+ instance ? instance->apiVersion : 0,
+ instance ? &instance->enabled_extensions : NULL,
+ NULL);
}
/* The loader wants us to expose a second GetInstanceProcAddr function
@@ -2334,10 +2339,15 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
}
PFN_vkVoidFunction radv_GetDeviceProcAddr(
- VkDevice device,
+ VkDevice _device,
const char* pName)
{
- return radv_lookup_entrypoint(pName);
+ RADV_FROM_HANDLE(radv_device, device, _device);
+
+ return radv_lookup_entrypoint_checked(pName,
+ device->instance->apiVersion,
+ &device->instance->enabled_extensions,
+ &device->enabled_extensions);
}
bool radv_get_memory_fd(struct radv_device *device,
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')
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 18665557eda..10690cbb727 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -255,7 +255,11 @@ void radv_loge_v(const char *format, va_list va);
return; \
} while (0)
-void *radv_lookup_entrypoint(const char *name);
+void *radv_lookup_entrypoint_unchecked(const char *name);
+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);
struct radv_physical_device {
VK_LOADER_DATA _loader_data;
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index e016e837102..3b525fe4453 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -32,7 +32,7 @@
static PFN_vkVoidFunction
radv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
{
- return radv_lookup_entrypoint(pName);
+ return radv_lookup_entrypoint_unchecked(pName);
}
VkResult