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 <airlied@redhat.com>
This commit is contained in:
@@ -2311,10 +2311,15 @@ VkResult radv_EnumerateDeviceExtensionProperties(
|
|||||||
}
|
}
|
||||||
|
|
||||||
PFN_vkVoidFunction radv_GetInstanceProcAddr(
|
PFN_vkVoidFunction radv_GetInstanceProcAddr(
|
||||||
VkInstance instance,
|
VkInstance _instance,
|
||||||
const char* pName)
|
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
|
/* 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(
|
PFN_vkVoidFunction radv_GetDeviceProcAddr(
|
||||||
VkDevice device,
|
VkDevice _device,
|
||||||
const char* pName)
|
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,
|
bool radv_get_memory_fd(struct radv_device *device,
|
||||||
|
|||||||
@@ -185,7 +185,45 @@ static const uint16_t map[] = {
|
|||||||
% endfor
|
% 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)
|
radv_lookup_entrypoint(const char *name)
|
||||||
{
|
{
|
||||||
static const uint32_t prime_factor = ${prime_factor};
|
static const uint32_t prime_factor = ${prime_factor};
|
||||||
@@ -202,15 +240,36 @@ radv_lookup_entrypoint(const char *name)
|
|||||||
do {
|
do {
|
||||||
i = map[h & ${hash_mask}];
|
i = map[h & ${hash_mask}];
|
||||||
if (i == none)
|
if (i == none)
|
||||||
return NULL;
|
return -1;
|
||||||
e = &entrypoints[i];
|
e = &entrypoints[i];
|
||||||
h += prime_step;
|
h += prime_step;
|
||||||
} while (e->hash != hash);
|
} while (e->hash != hash);
|
||||||
|
|
||||||
if (strcmp(name, strings + e->name) != 0)
|
if (strcmp(name, strings + e->name) != 0)
|
||||||
return NULL;
|
return -1;
|
||||||
|
|
||||||
return radv_resolve_entrypoint(i);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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')
|
}""", output_encoding='utf-8')
|
||||||
|
|
||||||
NONE = 0xffff
|
NONE = 0xffff
|
||||||
@@ -239,6 +298,7 @@ class Entrypoint(object):
|
|||||||
# Extensions which require this entrypoint
|
# Extensions which require this entrypoint
|
||||||
self.core_version = None
|
self.core_version = None
|
||||||
self.extension = 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):
|
def prefixed_name(self, prefix):
|
||||||
assert self.name.startswith('vk')
|
assert self.name.startswith('vk')
|
||||||
|
|||||||
@@ -255,7 +255,11 @@ void radv_loge_v(const char *format, va_list va);
|
|||||||
return; \
|
return; \
|
||||||
} while (0)
|
} 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 {
|
struct radv_physical_device {
|
||||||
VK_LOADER_DATA _loader_data;
|
VK_LOADER_DATA _loader_data;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
static PFN_vkVoidFunction
|
static PFN_vkVoidFunction
|
||||||
radv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
|
radv_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
|
||||||
{
|
{
|
||||||
return radv_lookup_entrypoint(pName);
|
return radv_lookup_entrypoint_unchecked(pName);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
|
|||||||
Reference in New Issue
Block a user