aboutsummaryrefslogtreecommitdiff
path: root/loader/loader.c
diff options
context:
space:
mode:
authorJon Ashburn <jon@lunarg.com>2015-09-30 12:56:42 -0600
committerJon Ashburn <jon@lunarg.com>2015-10-02 11:06:05 -0600
commit0a506d6db5034f08a26c21d94e3bc8f4fa8133bf (patch)
tree7a5000cce5c1d4dc2cb2a2d976f8635c662d4e28 /loader/loader.c
parentf347df9242e2821251dd20c7b7c1822b6139d36c (diff)
downloadusermoji-0a506d6db5034f08a26c21d94e3bc8f4fa8133bf.tar.xz
loader: Fixes in trampoline code to support layers which wrap objects
Loader trampoline code may see wrapped objects. Don't do value comparisons of dispatchable objects but instead compare dispatch tables to find objects. PhysicalDevice objects where may have multiple gpus with same instance dispatch will be fixed in a later patch.
Diffstat (limited to 'loader/loader.c')
-rw-r--r--loader/loader.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/loader/loader.c b/loader/loader.c
index 4b132c84..544d6e48 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -890,7 +890,8 @@ struct loader_icd *loader_get_icd_and_device(const VkDevice device,
for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
for (struct loader_icd *icd = inst->icds; icd; icd = icd->next) {
for (struct loader_device *dev = icd->logical_device_list; dev; dev = dev->next)
- if (dev->device == device) {
+ /* Value comparison of device prevents object wrapping by layers */
+ if (loader_get_dispatch(dev->device) == loader_get_dispatch(device)) {
*found_dev = dev;
return icd;
}
@@ -1984,6 +1985,24 @@ static PFN_vkVoidFunction VKAPI loader_gpa_instance_internal(VkInstance inst, co
return disp_table->GetInstanceProcAddr(inst, pName);
}
+struct loader_instance *loader_get_instance(const VkInstance instance)
+{
+ /* look up the loader_instance in our list by comparing dispatch tables, as
+ * there is no guarantee the instance is still a loader_instance* after any
+ * layers which wrap the instance object.
+ */
+ const VkLayerInstanceDispatchTable *disp;
+ struct loader_instance *ptr_instance = NULL;
+ disp = loader_get_instance_dispatch(instance);
+ for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
+ if (inst->disp == disp) {
+ ptr_instance = inst;
+ break;
+ }
+ }
+ return ptr_instance;
+}
+
struct loader_icd * loader_get_icd(const VkPhysicalDevice gpu, uint32_t *gpu_index)
{
@@ -1991,7 +2010,11 @@ struct loader_icd * loader_get_icd(const VkPhysicalDevice gpu, uint32_t *gpu_ind
for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
for (struct loader_icd *icd = inst->icds; icd; icd = icd->next) {
for (uint32_t i = 0; i < icd->gpu_count; i++)
- if (icd->gpus[i] == gpu) {
+ /* Value comparison of VkPhysicalDevice prevents wrapping, use
+ * instance device table instead (TODO this aliases GPUs within
+ * an instance, since they have identical dispatch tables)
+ */
+ if (loader_get_instance_dispatch(icd->gpus[i]) == loader_get_instance_dispatch(gpu)) {
*gpu_index = i;
return icd;
}
@@ -2973,7 +2996,9 @@ VkResult VKAPI loader_CreateDevice(
}
}
- res = icd->CreateDevice(gpu, pCreateInfo, pDevice);
+ // since gpu object maybe wrapped by a layer need to get unwrapped version
+ // we haven't yet called down the chain for the layer to unwrap the object
+ res = icd->CreateDevice(icd->gpus[gpu_index], pCreateInfo, pDevice);
if (res != VK_SUCCESS) {
return res;
}
@@ -3022,6 +3047,7 @@ LOADER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance
if (instance == VK_NULL_HANDLE) {
/* get entrypoint addresses that are global (in the loader),
doesn't include any instance extensions since they may not be enabled yet*/
+
addr = globalGetProcAddr(pName);
return addr;
@@ -3037,7 +3063,7 @@ LOADER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance
/* debug_report is a special case; need to return loader trampoline entrypoints
* unless the extension is not enabled; also need to handle debug_report
* utility functions */
- struct loader_instance *ptr_instance = (struct loader_instance *) instance;
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
if (debug_report_instance_gpa(ptr_instance, pName, &addr)) {
return addr;
}