Module: Mesa
Branch: master
Commit: e72ad05c1d6bdedf3b15cfe7ba42c801254d6112
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e72ad05c1d6bdedf3b15cfe7ba42c801254d6112

Author: Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl>
Date:   Sun Feb 11 14:38:42 2018 +0100

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 <airl...@redhat.com>

---

 src/amd/vulkan/radv_device.c           | 18 +++++++---
 src/amd/vulkan/radv_entrypoints_gen.py | 66 ++++++++++++++++++++++++++++++++--
 src/amd/vulkan/radv_private.h          |  6 +++-
 src/amd/vulkan/radv_wsi.c              |  2 +-
 4 files changed, 83 insertions(+), 9 deletions(-)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 79534fbd5f..f197b7f484 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 f7a791967b..08ca9ccca1 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 18665557ed..10690cbb72 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 e016e83710..3b525fe445 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

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to