aboutsummaryrefslogtreecommitdiffstats
path: root/src/amd/vulkan/radv_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd/vulkan/radv_device.c')
-rw-r--r--src/amd/vulkan/radv_device.c139
1 files changed, 118 insertions, 21 deletions
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 0a5db57e715..aa7b1b06835 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -708,6 +708,50 @@ VkResult radv_CreateInstance(
instance->enabled_extensions.extensions[index] = true;
}
+ bool unchecked = instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have
+ * not been enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_instance_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions)) {
+ instance->dispatch.entrypoints[i] = NULL;
+ } else {
+ instance->dispatch.entrypoints[i] =
+ radv_instance_dispatch_table.entrypoints[i];
+ }
+ }
+
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->physical_device_dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have
+ * not been enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_physical_device_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions)) {
+ instance->physical_device_dispatch.entrypoints[i] = NULL;
+ } else {
+ instance->physical_device_dispatch.entrypoints[i] =
+ radv_physical_device_dispatch_table.entrypoints[i];
+ }
+ }
+
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->device_dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have
+ * not been enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_device_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions, NULL)) {
+ instance->device_dispatch.entrypoints[i] = NULL;
+ } else {
+ instance->device_dispatch.entrypoints[i] =
+ radv_device_dispatch_table.entrypoints[i];
+ }
+ }
+
result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
if (result != VK_SUCCESS) {
vk_free2(&default_alloc, pAllocator, instance);
@@ -2795,6 +2839,28 @@ static VkResult fork_secure_compile_idle_device(struct radv_device *device)
return VK_SUCCESS;
}
+static void
+radv_device_init_dispatch(struct radv_device *device)
+{
+ const struct radv_instance *instance = device->physical_device->instance;
+ bool unchecked = instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(device->dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have not been
+ * enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_device_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions,
+ &device->enabled_extensions)) {
+ device->dispatch.entrypoints[i] = NULL;
+ } else {
+ device->dispatch.entrypoints[i] =
+ radv_device_dispatch_table.entrypoints[i];
+ }
+ }
+}
+
static VkResult
radv_create_pthread_cond(pthread_cond_t *cond)
{
@@ -2867,6 +2933,8 @@ VkResult radv_CreateDevice(
device->enabled_extensions.extensions[index] = true;
}
+ radv_device_init_dispatch(device);
+
keep_shader_info = device->enabled_extensions.AMD_shader_info;
/* With update after bind we can't attach bo's to the command buffer
@@ -4843,16 +4911,41 @@ PFN_vkVoidFunction radv_GetInstanceProcAddr(
const char* pName)
{
RADV_FROM_HANDLE(radv_instance, instance, _instance);
- bool unchecked = instance ? instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS : false;
- if (unchecked) {
- return radv_lookup_entrypoint_unchecked(pName);
- } else {
- return radv_lookup_entrypoint_checked(pName,
- instance ? instance->apiVersion : 0,
- instance ? &instance->enabled_extensions : NULL,
- NULL);
- }
+ /* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly
+ * when we have to return valid function pointers, NULL, or it's left
+ * undefined. See the table for exact details.
+ */
+ if (pName == NULL)
+ return NULL;
+
+#define LOOKUP_RADV_ENTRYPOINT(entrypoint) \
+ if (strcmp(pName, "vk" #entrypoint) == 0) \
+ return (PFN_vkVoidFunction)radv_##entrypoint
+
+ LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceExtensionProperties);
+ LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceLayerProperties);
+ LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceVersion);
+ LOOKUP_RADV_ENTRYPOINT(CreateInstance);
+
+#undef LOOKUP_RADV_ENTRYPOINT
+
+ if (instance == NULL)
+ return NULL;
+
+ int idx = radv_get_instance_entrypoint_index(pName);
+ if (idx >= 0)
+ return instance->dispatch.entrypoints[idx];
+
+ idx = radv_get_physical_device_entrypoint_index(pName);
+ if (idx >= 0)
+ return instance->physical_device_dispatch.entrypoints[idx];
+
+ idx = radv_get_device_entrypoint_index(pName);
+ if (idx >= 0)
+ return instance->device_dispatch.entrypoints[idx];
+
+ return NULL;
}
/* The loader wants us to expose a second GetInstanceProcAddr function
@@ -4883,9 +4976,14 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
{
RADV_FROM_HANDLE(radv_instance, instance, _instance);
- return radv_lookup_physical_device_entrypoint_checked(pName,
- instance ? instance->apiVersion : 0,
- instance ? &instance->enabled_extensions : NULL);
+ if (!pName || !instance)
+ return NULL;
+
+ int idx = radv_get_physical_device_entrypoint_index(pName);
+ if (idx < 0)
+ return NULL;
+
+ return instance->physical_device_dispatch.entrypoints[idx];
}
PFN_vkVoidFunction radv_GetDeviceProcAddr(
@@ -4893,16 +4991,15 @@ PFN_vkVoidFunction radv_GetDeviceProcAddr(
const char* pName)
{
RADV_FROM_HANDLE(radv_device, device, _device);
- bool unchecked = device ? device->instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS : false;
- if (unchecked) {
- return radv_lookup_entrypoint_unchecked(pName);
- } else {
- return radv_lookup_entrypoint_checked(pName,
- device->instance->apiVersion,
- &device->instance->enabled_extensions,
- &device->enabled_extensions);
- }
+ if (!device || !pName)
+ return NULL;
+
+ int idx = radv_get_device_entrypoint_index(pName);
+ if (idx < 0)
+ return NULL;
+
+ return device->dispatch.entrypoints[idx];
}
bool radv_get_memory_fd(struct radv_device *device,