aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLenny Komow <lenny@lunarg.com>2018-03-29 13:25:38 -0600
committerLenny Komow <lenny@lunarg.com>2018-03-29 16:50:20 -0600
commit8df2c26952f6748d964d146d1ac592931ef61bda (patch)
tree061d954ee45dc57574e33df80bcf39b9fa0b65c4
parent249440ac0c67ed804dd1372ff1ce1f5127c83702 (diff)
downloadusermoji-8df2c26952f6748d964d146d1ac592931ef61bda.tar.xz
loader: Fix GetDeviceProcAddr with terminators
Fix a bug where vkGetDeviceProcAddr would return a valid pointer for any device command that used a custom terminator, even if it was part of an extension which wasn't enabled Change-Id: I3b088fe0c850fbaa5f7285ced81552273bc38e7e
-rw-r--r--loader/loader.c15
-rw-r--r--loader/loader.h8
-rw-r--r--scripts/loader_extension_generator.py23
3 files changed, 40 insertions, 6 deletions
diff --git a/loader/loader.c b/loader/loader.c
index 1e7a8049..266222f3 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -4005,7 +4005,7 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_device_internal(VkDevice dev
// object before passing the appropriate info along to the ICD.
// This is why we also have to override the direct ICD call to
// vkGetDeviceProcAddr to intercept those calls.
- PFN_vkVoidFunction addr = get_extension_device_proc_terminator(pName);
+ PFN_vkVoidFunction addr = get_extension_device_proc_terminator(dev, pName);
if (NULL != addr) {
return addr;
}
@@ -5542,6 +5542,19 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(VkPhysicalDevice physical
}
}
+ // Every extension that has a loader-defined terminator needs to be marked as enabled or disabled so that we know whether or
+ // not to return that terminator when vkGetDeviceProcAddr is called
+ for (uint32_t i = 0; i < localCreateInfo.enabledExtensionCount; ++i) {
+ if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
+ dev->extensions.khr_swapchain_enabled = true;
+ } else if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME)) {
+ dev->extensions.khr_display_swapchain_enabled = true;
+ } else if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
+ dev->extensions.ext_debug_marker_enabled = true;
+ }
+ dev->extensions.ext_debug_utils_enabled = icd_term->this_instance->enabled_known_extensions.ext_debug_utils;
+ }
+
res = fpCreateDevice(phys_dev_term->phys_dev, &localCreateInfo, pAllocator, &dev->icd_device);
if (res != VK_SUCCESS) {
loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
diff --git a/loader/loader.h b/loader/loader.h
index 8abc034a..9ffa3bb9 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -192,6 +192,14 @@ struct loader_device {
VkAllocationCallbacks alloc_callbacks;
+ // List of activated device extensions that have terminators implemented in the loader
+ struct {
+ bool khr_swapchain_enabled;
+ bool khr_display_swapchain_enabled;
+ bool ext_debug_marker_enabled;
+ bool ext_debug_utils_enabled;
+ } extensions;
+
struct loader_device *next;
};
diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
index 7f38de91..d9f5564c 100644
--- a/scripts/loader_extension_generator.py
+++ b/scripts/loader_extension_generator.py
@@ -383,6 +383,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
protos = ''
protos += '// Structures defined externally, but used here\n'
protos += 'struct loader_instance;\n'
+ protos += 'struct loader_device;\n'
protos += 'struct loader_icd_term;\n'
protos += 'struct loader_dev_dispatch_table;\n'
protos += '\n'
@@ -401,7 +402,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
protos += '// Extension interception for vkGetDeviceProcAddr function, so we can return\n'
protos += '// an appropriate terminator if this is one of those few device commands requiring\n'
protos += '// a terminator.\n'
- protos += 'PFN_vkVoidFunction get_extension_device_proc_terminator(const char *pName);\n'
+ protos += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName);\n'
protos += '\n'
protos += '// Dispatch table properly filled in with appropriate terminators for the\n'
protos += '// supported extensions.\n'
@@ -1365,28 +1366,38 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
term_func += '// Some device commands still need a terminator because the loader needs to unwrap something about them.\n'
term_func += '// In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object. But there may be other items\n'
term_func += '// in the future.\n'
- term_func += 'PFN_vkVoidFunction get_extension_device_proc_terminator(const char *pName) {\n'
+ term_func += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName) {\n'
term_func += ' PFN_vkVoidFunction addr = NULL;\n'
count = 0
+ is_extension = False
for ext_cmd in self.ext_commands:
if ext_cmd.name in DEVICE_CMDS_NEED_TERM:
if ext_cmd.ext_name != cur_extension_name:
+ if count > 0:
+ count = 0;
+ term_func += ' }\n'
+ if is_extension:
+ term_func += ' }\n'
+ is_extension = False
+
if 'VK_VERSION_' in ext_cmd.ext_name:
term_func += '\n // ---- Core %s commands\n' % ext_cmd.ext_name[11:]
else:
term_func += '\n // ---- %s extension commands\n' % ext_cmd.ext_name
+ term_func += ' if (dev->extensions.%s_enabled) {\n' % ext_cmd.ext_name[3:].lower()
+ is_extension = True
cur_extension_name = ext_cmd.ext_name
if ext_cmd.protect is not None:
term_func += '#ifdef %s\n' % ext_cmd.protect
if count == 0:
- term_func += ' if'
+ term_func += ' if'
else:
- term_func += ' } else if'
+ term_func += ' } else if'
term_func += '(!strcmp(pName, "%s")) {\n' % (ext_cmd.name)
- term_func += ' addr = (PFN_vkVoidFunction)terminator_%s;\n' % (ext_cmd.name[2:])
+ term_func += ' addr = (PFN_vkVoidFunction)terminator_%s;\n' % (ext_cmd.name[2:])
if ext_cmd.protect is not None:
term_func += '#endif // %s\n' % ext_cmd.protect
@@ -1394,6 +1405,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
count += 1
if count > 0:
+ term_func += ' }\n'
+ if is_extension:
term_func += ' }\n'
term_func += ' return addr;\n'