aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Ashburn <jon@lunarg.com>2015-05-28 16:25:02 -0600
committerCourtney Goeltzenleuchter <courtney@LunarG.com>2015-06-17 20:56:36 -0600
commit0d67c29d5d2a2f3383e11279a091a1f164f8eb95 (patch)
treee3e1ccc09ecdb9eba13aff5c12ca748787742e84
parent813d8d2445d30223a6f46ccf4806f9e41754b333 (diff)
downloadusermoji-0d67c29d5d2a2f3383e11279a091a1f164f8eb95.tar.xz
loader: Support layers that don't have an extension entrypoint
Change all layers and loader interface to init dispatch tables on GPA("GetXXXProcAddr"). After that initialization rest of dispatch tables are inited via unwrapped object using the GPA in the dispatch table. This also allows App generated GPA calls that the loader can't resolve to function correctly.
-rw-r--r--layers/basic.cpp41
-rw-r--r--layers/draw_state.cpp40
-rw-r--r--layers/mem_tracker.cpp41
-rw-r--r--layers/multi.cpp72
-rw-r--r--layers/param_checker.cpp40
-rw-r--r--layers/shader_checker.cpp47
-rw-r--r--loader/loader.c15
-rw-r--r--loader/loader.h7
-rw-r--r--loader/table_ops.h23
-rwxr-xr-xvk-generate.py38
-rwxr-xr-xvk-layer-generate.py40
11 files changed, 213 insertions, 191 deletions
diff --git a/layers/basic.cpp b/layers/basic.cpp
index 0742cb21..1ba3188e 100644
--- a/layers/basic.cpp
+++ b/layers/basic.cpp
@@ -58,7 +58,7 @@ static VkLayerInstanceDispatchTable * initLayerInstanceTable(const VkBaseLayerOb
return it->second;
}
- layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instancew->pGPA, (VkInstance) instancew->nextObject);
+ layer_init_instance_dispatch_table(pTable, instancew);
return pTable;
}
@@ -79,7 +79,7 @@ static VkLayerDispatchTable * initLayerTable(const VkBaseLayerObject *devw)
return it->second;
}
- layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
+ layer_initialize_dispatch_table(pTable, devw);
return pTable;
}
@@ -207,21 +207,25 @@ VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pN
if (device == NULL)
return NULL;
- initLayerTable((const VkBaseLayerObject *) device);
-
- if (!strcmp("vkGetDeviceProcAddr", pName))
+ /* loader uses this to force layer initialization; device object is wrapped */
+ if (!strcmp("vkGetDeviceProcAddr", pName)) {
+ initLayerTable((const VkBaseLayerObject *) device);
return (void *) vkGetDeviceProcAddr;
+ }
+
if (!strcmp("vkGetFormatInfo", pName))
return (void *) vkGetFormatInfo;
if (!strcmp("vkDestroyDevice", pName))
return (void *) vkDestroyDevice;
if (!strcmp("vkLayerExtension1", pName))
return (void *) vkLayerExtension1;
- else {
- VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
- if (devw->pGPA == NULL)
+ else
+ {
+ VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
+ VkLayerDispatchTable* pTable = tableMap[*ppDisp];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- return devw->pGPA((VkObject) devw->nextObject, pName);
+ return pTable->GetDeviceProcAddr(device, pName);
}
}
@@ -230,10 +234,12 @@ VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const ch
if (instance == NULL)
return NULL;
- initLayerInstanceTable((const VkBaseLayerObject *) instance);
-
- if (!strcmp("vkGetInstanceProcAddr", pName))
+ /* loader uses this to force layer initialization; instance object is wrapped */
+ if (!strcmp("vkGetInstanceProcAddr", pName)) {
+ initLayerInstanceTable((const VkBaseLayerObject *) instance);
return (void *) vkGetInstanceProcAddr;
+ }
+
if (!strcmp("vkDestroyInstance", pName))
return (void *) vkDestroyInstance;
if (!strcmp("vkEnumeratePhysicalDevices", pName))
@@ -242,10 +248,13 @@ VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const ch
return (void*) vkGetGlobalExtensionInfo;
if (!strcmp("vkCreateDevice", pName))
return (void *) vkCreateDevice;
- else {
- VkBaseLayerObject* instancew = (VkBaseLayerObject *) instance;
- if (instancew->pGPA == NULL)
+ else
+ {
+ VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap[*ppDisp];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- return instancew->pGPA((VkObject) instancew->nextObject, pName);
+ return pTable->GetInstanceProcAddr(instance, pName);
}
+
}
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 54f6813a..72b87f36 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -1462,9 +1462,9 @@ static VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
return it->second;
}
- VkDevice device = (VkDevice) devw->nextObject;
- layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, device);
+ layer_initialize_dispatch_table(pTable, devw);
+ VkDevice device = (VkDevice) devw->baseObject;
pDebugMarkerTable->CmdDbgMarkerBegin = (PFN_vkCmdDbgMarkerBegin) devw->pGPA(device, "vkCmdDbgMarkerBegin");
pDebugMarkerTable->CmdDbgMarkerEnd = (PFN_vkCmdDbgMarkerEnd) devw->pGPA(device, "vkCmdDbgMarkerEnd");
pDebugMarkerTable->DbgSetObjectTag = (PFN_vkDbgSetObjectTag) devw->pGPA(device, "vkDbgSetObjectTag");
@@ -1490,7 +1490,7 @@ static VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject
return it->second;
}
- layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
+ layer_init_instance_dispatch_table(pTable, instw);
return pTable;
}
@@ -2898,16 +2898,16 @@ void drawStateDumpPngFile(char* outFileName)
VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
{
- VkBaseLayerObject* devw = (VkBaseLayerObject *) dev;
-
if (dev == NULL)
return NULL;
loader_platform_thread_once(&g_initOnce, initDrawState);
- initDeviceTable((const VkBaseLayerObject *) dev);
- if (!strcmp(funcName, "vkGetDeviceProcAddr"))
+ /* loader uses this to force layer initialization; device object is wrapped */
+ if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
+ initDeviceTable((const VkBaseLayerObject *) dev);
return (void *) vkGetDeviceProcAddr;
+ }
if (!strcmp(funcName, "vkDestroyDevice"))
return (void*) vkDestroyDevice;
if (!strcmp(funcName, "vkQueueSubmit"))
@@ -3036,31 +3036,39 @@ VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice dev, const char* funcNa
return (void*) drawStateDumpCommandBufferDotFile;
if (!strcmp("drawStateDumpPngFile", funcName))
return (void*) drawStateDumpPngFile;
- else {
- if (devw->pGPA == NULL)
+ else
+ {
+ VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) dev;
+ VkLayerDispatchTable* pTable = tableMap[*ppDisp];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- return devw->pGPA((VkObject)devw->nextObject, funcName);
+ return pTable->GetDeviceProcAddr(dev, funcName);
}
}
VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- VkBaseLayerObject* instw = (VkBaseLayerObject *) instance;
if (instance == NULL)
return NULL;
loader_platform_thread_once(&g_initOnce, initDrawState);
- initInstanceTable((const VkBaseLayerObject *) instance);
- if (!strcmp(funcName, "vkGetInstanceProcAddr"))
+ /* loader uses this to force layer initialization; instance object is wrapped */
+ if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
+ initInstanceTable((const VkBaseLayerObject *) instance);
return (void *) vkGetInstanceProcAddr;
+ }
if (!strcmp(funcName, "vkDestroyInstance"))
return (void *) vkDestroyInstance;
if (!strcmp(funcName, "vkCreateDevice"))
return (void*) vkCreateDevice;
- else {
- if (instw->pGPA == NULL)
+ else
+ {
+ VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap[*ppDisp];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- return instw->pGPA((VkObject) instw->nextObject, funcName);
+ return pTable->GetInstanceProcAddr(instance, funcName);
}
+
}
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index b77b7423..3898a543 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -796,7 +796,7 @@ static VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
return it->second;
}
- layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
+ layer_initialize_dispatch_table(pTable, devw);
return pTable;
}
@@ -818,7 +818,7 @@ static VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject
return it->second;
}
- layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
+ layer_init_instance_dispatch_table(pTable, instw);
return pTable;
}
@@ -2151,17 +2151,17 @@ VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(
VkDevice dev,
const char *funcName)
{
- VkBaseLayerObject* devw = (VkBaseLayerObject *) dev;
-
if (dev == NULL) {
return NULL;
}
loader_platform_thread_once(&g_initOnce, initMemTracker);
- initDeviceTable((const VkBaseLayerObject *) dev);
- if (!strcmp(funcName, "vkGetDeviceProcAddr"))
+ /* loader uses this to force layer initialization; device object is wrapped */
+ if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
+ initDeviceTable((const VkBaseLayerObject *) dev);
return (void *) vkGetDeviceProcAddr;
+ }
if (!strcmp(funcName, "vkDestroyDevice"))
return (void*) vkDestroyDevice;
if (!strcmp(funcName, "vkQueueSubmit"))
@@ -2296,11 +2296,13 @@ VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(
return (void*) vkDestroySwapChainWSI;
if (!strcmp(funcName, "vkGetSwapChainInfoWSI"))
return (void*) vkGetSwapChainInfoWSI;
- else {
- if (devw->pGPA == NULL) {
+ else
+ {
+ VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) dev;
+ VkLayerDispatchTable* pTable = tableMap[*ppDisp];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- }
- return devw->pGPA((VkObject)devw->nextObject, funcName);
+ return pTable->GetDeviceProcAddr(dev, funcName);
}
}
@@ -2308,25 +2310,28 @@ VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr(
VkInstance instance,
const char *funcName)
{
- VkBaseLayerObject* instw = (VkBaseLayerObject *) instance;
-
if (instance == NULL) {
return NULL;
}
loader_platform_thread_once(&g_initOnce, initMemTracker);
- initInstanceTable((const VkBaseLayerObject *) instance);
- if (!strcmp(funcName, "vkGetInstanceProcAddr"))
+ /* loader uses this to force layer initialization; instance object is wrapped */
+ if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
+ initInstanceTable((const VkBaseLayerObject *) instance);
return (void *) vkGetInstanceProcAddr;
+ }
+
if (!strcmp(funcName, "vkDestroyInstance"))
return (void *) vkDestroyInstance;
if (!strcmp(funcName, "vkCreateDevice"))
return (void*) vkCreateDevice;
- else {
- if (instw->pGPA == NULL) {
+ else
+ {
+ VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap[*ppDisp];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- }
- return instw->pGPA((VkObject)instw->nextObject, funcName);
+ return pTable->GetInstanceProcAddr(instance, funcName);
}
}
diff --git a/layers/multi.cpp b/layers/multi.cpp
index 2cc9e0c4..b0e8f212 100644
--- a/layers/multi.cpp
+++ b/layers/multi.cpp
@@ -149,22 +149,26 @@ VK_LAYER_EXPORT void * VKAPI multi1GetDeviceProcAddr(VkDevice device, const char
if (device == NULL)
return NULL;
- getLayer1Table(devw);
- if (!strcmp("vkGetDeviceProcAddr", pName))
+
+ if (!strcmp("vkGetDeviceProcAddr", pName)) {
+ getLayer1Table(devw);
return (void *) multi1GetDeviceProcAddr;
+ }
if (!strcmp("vkDestroyDevice", pName))
return (void *) multi1DestroyDevice;
if (!strcmp("vkCreateSampler", pName))
return (void *) multi1CreateSampler;
- else if (!strcmp("vkCreateGraphicsPipeline", pName))
+ if (!strcmp("vkCreateGraphicsPipeline", pName))
return (void *) multi1CreateGraphicsPipeline;
- else if (!strcmp("vkStorePipeline", pName))
+ if (!strcmp("vkStorePipeline", pName))
return (void *) multi1StorePipeline;
else {
- if (devw->pGPA == NULL)
+ VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
+ VkLayerDispatchTable* pTable = tableMap1[*ppDisp];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- return devw->pGPA((VkObject) devw->nextObject, pName);
+ return pTable->GetDeviceProcAddr(device, pName);
}
}
@@ -175,18 +179,22 @@ VK_LAYER_EXPORT void * VKAPI multi1GetInstanceProcAddr(VkInstance inst, const ch
if (inst == NULL)
return NULL;
- getLayer1InstanceTable(instw);
- if (!strcmp("vkGetInstanceProcAddr", pName))
+
+ if (!strcmp("vkGetInstanceProcAddr", pName)) {
+ getLayer1InstanceTable(instw);
return (void *) multi1GetInstanceProcAddr;
+ }
if (!strcmp("vkDestroyInstance", pName))
return (void *) multi1DestroyInstance;
- else if (!strcmp("GetGlobalExtensionInfo", pName))
+ if (!strcmp("GetGlobalExtensionInfo", pName))
return (void*) vkGetGlobalExtensionInfo;
else {
- if (instw->pGPA == NULL)
+ VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[*ppDisp];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- return instw->pGPA((VkObject) instw->nextObject, pName);
+ return pTable->GetInstanceProcAddr(inst, pName);
}
}
@@ -310,10 +318,10 @@ VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char
if (device == NULL)
return NULL;
- getLayer2Table(devw);
-
- if (!strcmp("vkGetDeviceProcAddr", pName))
+ if (!strcmp("vkGetDeviceProcAddr", pName)) {
+ getLayer2Table(devw);
return (void *) multi2GetDeviceProcAddr;
+ }
if (!strcmp("vkDestroyDevice", pName))
return (void *) multi2DestroyDevice;
if (!strcmp("vkCreateCommandBuffer", pName))
@@ -321,9 +329,11 @@ VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char
else if (!strcmp("vkBeginCommandBuffer", pName))
return (void *) multi2BeginCommandBuffer;
else {
- if (devw->pGPA == NULL)
+ VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
+ VkLayerDispatchTable* pTable = tableMap2[*ppDisp];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- return devw->pGPA((VkObject) devw->nextObject, pName);
+ return pTable->GetDeviceProcAddr(device, pName);
}
}
@@ -334,10 +344,10 @@ VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const ch
if (inst == NULL)
return NULL;
- getLayer2InstanceTable(instw);
-
- if (!strcmp("vkGetInstanceProcAddr", pName))
+ if (!strcmp("vkGetInstanceProcAddr", pName)) {
+ getLayer2InstanceTable(instw);
return (void *) multi2GetInstanceProcAddr;
+ }
if (!strcmp("vkEnumeratePhysicalDevices", pName))
return (void *) multi2EnumeratePhysicalDevices;
if (!strcmp("vkDestroyInstance", pName))
@@ -347,27 +357,15 @@ VK_LAYER_EXPORT void * VKAPI multi2GetInstanceProcAddr(VkInstance inst, const ch
else if (!strcmp("GetGlobalExtensionInfo", pName))
return (void*) vkGetGlobalExtensionInfo;
else {
- if (instw->pGPA == NULL)
+ VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) inst;
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[*ppDisp];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- return instw->pGPA((VkObject) instw->nextObject, pName);
+ return pTable->GetInstanceProcAddr(inst, pName);
}
}
/********************************* Common functions ********************************/
-VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
- size_t* pLayerCount, char* const* pOutLayers,
- void* pReserved)
-{
- if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
- return VK_ERROR_INVALID_POINTER;
-
- if (*pLayerCount < 2)
- return VK_ERROR_INITIALIZATION_FAILED;
- *pLayerCount = 2;
- strncpy((char *) pOutLayers[0], "multi1", maxStringSize);
- strncpy((char *) pOutLayers[1], "multi2", maxStringSize);
- return VK_SUCCESS;
-}
struct extProps {
uint32_t version;
@@ -479,7 +477,7 @@ static void initLayerTable(const VkBaseLayerObject *devw, VkLayerDispatchTable *
if (layerNum == 1 && layer2_first_activated == false)
layer1_first_activated = true;
- layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
+ layer_initialize_dispatch_table(pTable, devw);
}
static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstanceDispatchTable *pTable, const unsigned int layerNum)
@@ -489,5 +487,5 @@ static void initLayerInstanceTable(const VkBaseLayerObject *instw, VkLayerInstan
if (layerNum == 1 && layer2_first_activated == false)
layer1_first_activated = true;
- layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
+ layer_init_instance_dispatch_table(pTable, instw);
}
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index 4068ac62..a27d54e0 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -83,9 +83,9 @@ static VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
return it->second;
}
- VkDevice device = (VkDevice) devw->nextObject;
- layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) device);
+ layer_initialize_dispatch_table(pTable, devw);
+ VkDevice device = (VkDevice) devw->baseObject;
pDebugMarkerTable->CmdDbgMarkerBegin = (PFN_vkCmdDbgMarkerBegin) devw->pGPA(device, "vkCmdDbgMarkerBegin");
pDebugMarkerTable->CmdDbgMarkerEnd = (PFN_vkCmdDbgMarkerEnd) devw->pGPA(device, "vkCmdDbgMarkerEnd");
pDebugMarkerTable->DbgSetObjectTag = (PFN_vkDbgSetObjectTag) devw->pGPA(device, "vkDbgSetObjectTag");
@@ -111,7 +111,7 @@ static VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject
return it->second;
}
- layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
+ layer_init_instance_dispatch_table(pTable, instw);
return pTable;
}
@@ -1977,8 +1977,6 @@ static inline void* layer_intercept_proc(const char *name)
return NULL;
name += 2;
- if (!strcmp(name, "GetDeviceProcAddr"))
- return (void*) vkGetDeviceProcAddr;
if (!strcmp(name, "DestroyDevice"))
return (void*) vkDestroyDevice;
if (!strcmp(name, "GetDeviceQueue"))
@@ -2201,8 +2199,6 @@ static inline void* layer_intercept_instance_proc(const char *name)
return NULL;
name += 2;
- if (!strcmp(name, "GetInstanceProcAddr"))
- return (void*) vkGetInstanceProcAddr;
if (!strcmp(name, "CreateInstance"))
return (void*) vkCreateInstance;
if (!strcmp(name, "DestroyInstance"))
@@ -2223,46 +2219,56 @@ static inline void* layer_intercept_instance_proc(const char *name)
VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
{
- VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
void* addr;
if (device == NULL) {
return NULL;
}
loader_platform_thread_once(&initOnce, initParamChecker);
- initDeviceTable((const VkBaseLayerObject *) device);
+
+ /* loader uses this to force layer initialization; device object is wrapped */
+ if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
+ initDeviceTable((const VkBaseLayerObject *) device);
+ return (void*) vkGetDeviceProcAddr;
+ }
addr = layer_intercept_proc(funcName);
if (addr) {
return addr;
}
else {
- if (devw->pGPA == NULL) {
+ VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;
+ VkLayerDispatchTable* pTable = tableMap[*ppDisp];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- }
- return devw->pGPA((VkObject)devw->nextObject, funcName);
+ return pTable->GetDeviceProcAddr(device, funcName);
}
}
VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- VkBaseLayerObject* instw = (VkBaseLayerObject *) instance;
void* addr;
if (instance == NULL) {
return NULL;
}
loader_platform_thread_once(&initOnce, initParamChecker);
- initInstanceTable((const VkBaseLayerObject *) instance);
+
+ /* loader uses this to force layer initialization; instance object is wrapped */
+ if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
+ initInstanceTable((const VkBaseLayerObject *) instance);
+ return (void*) vkGetInstanceProcAddr;
+ }
addr = layer_intercept_instance_proc(funcName);
if (addr) {
return addr;
}
else {
- if (instw->pGPA == NULL) {
+ VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap[*ppDisp];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- }
- return instw->pGPA((VkObject)instw->nextObject, funcName);
+ return pTable->GetInstanceProcAddr(instance, funcName);
}
}
diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp
index 9484cd0b..5b66c631 100644
--- a/layers/shader_checker.cpp
+++ b/layers/shader_checker.cpp
@@ -160,7 +160,7 @@ static VkLayerDispatchTable * initLayerTable(const VkBaseLayerObject *devw)
return it->second;
}
- layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);
+ layer_initialize_dispatch_table(pTable, devw);
return pTable;
}
@@ -180,24 +180,11 @@ static VkLayerInstanceDispatchTable * initLayerInstanceTable(const VkBaseLayerOb
return it->second;
}
- layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);
+ layer_init_instance_dispatch_table(pTable, instw);
return pTable;
}
-VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice physicalDevice, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved)
-{
- if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pOutLayers[1] == NULL || pReserved == NULL)
- return VK_ERROR_INVALID_POINTER;
-
- if (*pLayerCount < 1)
- return VK_ERROR_INITIALIZATION_FAILED;
- *pLayerCount = 1;
- strncpy((char *) pOutLayers[0], "ShaderChecker", maxStringSize);
- return VK_SUCCESS;
-}
-
-
#define SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE 2
static const VkExtensionProperties shaderCheckerExts[SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
{
@@ -966,25 +953,27 @@ VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pN
if (device == NULL)
return NULL;
- initLayerTable((const VkBaseLayerObject *) device);
-
loader_platform_thread_once(&g_initOnce, initLayer);
+ /* loader uses this to force layer initialization; device object is wrapped */
+ if (!strcmp("vkGetDeviceProcAddr", pName)) {
+ initLayerTable((const VkBaseLayerObject *) device);
+ return (void *) vkGetDeviceProcAddr;
+ }
+
#define ADD_HOOK(fn) \
if (!strncmp(#fn, pName, sizeof(#fn))) \
return (void *) fn
- ADD_HOOK(vkGetDeviceProcAddr);
ADD_HOOK(vkCreateShader);
ADD_HOOK(vkDestroyDevice);
ADD_HOOK(vkCreateGraphicsPipeline);
ADD_HOOK(vkCreateGraphicsPipelineDerivative);
#undef ADD_HOOK
-
- VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
- if (devw->pGPA == NULL)
+ VkLayerDispatchTable* pTable = tableMap[(VkBaseLayerObject *)device];
+ if (pTable->GetDeviceProcAddr == NULL)
return NULL;
- return devw->pGPA((VkObject) devw->nextObject, pName);
+ return pTable->GetDeviceProcAddr(device, pName);
}
VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
@@ -992,22 +981,22 @@ VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char*
if (inst == NULL)
return NULL;
- initLayerInstanceTable((const VkBaseLayerObject *) inst);
-
loader_platform_thread_once(&g_initOnce, initLayer);
+ if (!strcmp("vkGetInstanceProcAddr", pName)) {
+ initLayerInstanceTable((const VkBaseLayerObject *) inst);
+ return (void *) vkGetInstanceProcAddr;
+ }
#define ADD_HOOK(fn) \
if (!strncmp(#fn, pName, sizeof(#fn))) \
return (void *) fn
- ADD_HOOK(vkGetInstanceProcAddr);
ADD_HOOK(vkDestroyInstance);
- ADD_HOOK(vkEnumerateLayers);
ADD_HOOK(vkGetGlobalExtensionInfo);
#undef ADD_HOOK
- VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
- if (instw->pGPA == NULL)
+ VkLayerInstanceDispatchTable* pTable = tableInstanceMap[(VkBaseLayerObject *) inst];
+ if (pTable->GetInstanceProcAddr == NULL)
return NULL;
- return instw->pGPA((VkObject) instw->nextObject, pName);
+ return pTable->GetInstanceProcAddr(inst, pName);
}
diff --git a/loader/loader.c b/loader/loader.c
index 064b3dca..fd234657 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -820,14 +820,12 @@ static void* VKAPI loader_gpa_instance_internal(VkInstance inst, const char * pN
VkLayerInstanceDispatchTable* disp_table = * (VkLayerInstanceDispatchTable **) inst;
void *addr;
+ if (!strcmp(pName, "vkGetInstanceProcAddr"))
+ return (void *) loader_gpa_instance_internal;
+
if (disp_table == NULL)
return NULL;
-// addr = debug_report_instance_gpa((struct loader_instance *) inst, pName);
-// if (addr) {
-// return addr;
-// }
-
addr = loader_lookup_instance_dispatch_table(disp_table, pName);
if (addr) {
return addr;
@@ -1138,7 +1136,7 @@ uint32_t loader_activate_instance_layers(struct loader_instance *inst)
layer_idx--;
}
- loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj);
+ loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);
return inst->layer_count;
}
@@ -1225,7 +1223,8 @@ extern uint32_t loader_activate_device_layers(
layer_idx--;
}
- loader_init_device_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, (VkPhysicalDevice) nextObj);
+ loader_init_device_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA,
+ (VkPhysicalDevice) nextObj, (VkPhysicalDevice) baseObj);
} else {
// TODO: Check that active layers match requested?
}
@@ -1370,7 +1369,7 @@ VkResult loader_EnumeratePhysicalDevices(
(wrapped_gpus + i)->nextObject = gpus[i];
memcpy(pPhysicalDevices + count, gpus, sizeof(*pPhysicalDevices));
loader_init_device_dispatch_table(icd->loader_dispatch + i,
- get_proc_addr, gpus[i]);
+ get_proc_addr, gpus[i], gpus[i]);
loader_init_dispatch(gpus[i], ptr_instance->disp);
}
diff --git a/loader/loader.h b/loader/loader.h
index 73b780fd..8b427b5f 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -321,13 +321,6 @@ VkResult loader_GetPhysicalDeviceExtensionInfo(
size_t* pDataSize,
void* pData);
-VkResult loader_EnumerateLayers(
- VkPhysicalDevice gpu,
- size_t maxStringSize,
- size_t* pLayerCount,
- char* const* pOutLayers,
- void* pReserved);
-
VkResult loader_GetMultiDeviceCompatibility(
VkPhysicalDevice gpu0,
VkPhysicalDevice gpu1,
diff --git a/loader/table_ops.h b/loader/table_ops.h
index 1fb624bc..93131b18 100644
--- a/loader/table_ops.h
+++ b/loader/table_ops.h
@@ -30,9 +30,13 @@
static inline void loader_init_device_dispatch_table(VkLayerDispatchTable *table,
PFN_vkGetDeviceProcAddr gpa,
+ VkDevice dev_next,
VkDevice dev)
{
- table->GetDeviceProcAddr = gpa;
+ // If layer is next, this will trigger layers to initialize their dispatch tables
+ //then use the gpa in their dispatch for subsequent layers in the chain
+ table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(dev_next, "vkGetDeviceProcAddr");
+
table->DestroyDevice = (PFN_vkDestroyDevice) gpa(dev, "vkDestroyDevice");
table->GetDeviceQueue = (PFN_vkGetDeviceQueue) gpa(dev, "vkGetDeviceQueue");
table->QueueSubmit = (PFN_vkQueueSubmit) gpa(dev, "vkQueueSubmit");
@@ -137,6 +141,8 @@ static inline void loader_init_device_dispatch_table(VkLayerDispatchTable *table
table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) gpa(dev, "vkCmdBeginRenderPass");
table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass) gpa(dev, "vkCmdEndRenderPass");
//TODO move into it's own table
+//TODO also consider dropping trampoline code for these device level extensions entirely
+// then don't need loader to know about these at all but then not queryable via GIPA
table->CreateSwapChainWSI = (PFN_vkCreateSwapChainWSI) gpa(dev, "vkCreateSwapChainWSI");
table->DestroySwapChainWSI = (PFN_vkDestroySwapChainWSI) gpa(dev, "vkDestroySwapChainWSI");
table->GetSwapChainInfoWSI = (PFN_vkGetSwapChainInfoWSI) gpa(dev, "vkGetSwapChainInfoWSI");
@@ -359,28 +365,23 @@ static inline void *loader_lookup_device_dispatch_table(
return (void *) table->CmdBeginRenderPass;
if (!strcmp(name, "CmdEndRenderPass"))
return (void *) table->CmdEndRenderPass;
-//TODO put in it's own table
- if (!strcmp(name, "CreateSwapChainWSI"))
- return (void *) table->CreateSwapChainWSI;
- if (!strcmp(name, "DestroySwapChainWSI"))
- return (void *) table->DestroySwapChainWSI;
- if (!strcmp(name, "GetSwapChainInfoWSI"))
- return (void *) table->GetSwapChainInfoWSI;
- if (!strcmp(name, "QueuePresentWSI"))
- return (void *) table->QueuePresentWSI;
return NULL;
}
static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table,
PFN_vkGetInstanceProcAddr gpa,
+ VkInstance inst_next,
VkInstance inst)
{
+ // If layer is next, this will trigger layers to initialize their dispatch tables
+ //then use the gpa in their dispatch for subsequent layers in the chain
+ table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(inst_next, "vkGetInstanceProcAddr");
+
table->CreateInstance = (PFN_vkCreateInstance) gpa(inst, "vkCreateInstance");
table->DestroyInstance = (PFN_vkDestroyInstance) gpa(inst, "vkDestroyInstance");
table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(inst, "vkEnumeratePhysicalDevices");
table->GetPhysicalDeviceInfo = (PFN_vkGetPhysicalDeviceInfo) gpa(inst, "vkGetPhysicalDeviceInfo");
- table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(inst, "vkGetInstanceProcAddr");
table->CreateDevice = (PFN_vkCreateDevice) gpa(inst, "vkCreateDevice");
table->GetGlobalExtensionInfo = (PFN_vkGetGlobalExtensionInfo) gpa(inst,"vkGetGlobalExtensionInfo");
table->GetPhysicalDeviceExtensionInfo = (PFN_vkGetPhysicalDeviceExtensionInfo) gpa(inst, "vkGetPhysicalDeviceExtensionInfo");
diff --git a/vk-generate.py b/vk-generate.py
index a2ec6bf0..790a543f 100755
--- a/vk-generate.py
+++ b/vk-generate.py
@@ -110,38 +110,42 @@ class DispatchTableOpsSubcommand(Subcommand):
"#include <vkLayer.h>",
"#include <string.h>"])
- def _generate_init(self, type):
+ def _generate_init_dispatch(self, type):
stmts = []
func = []
if type == "device":
+ # GPA has to be first one and uses wrapped object
+ stmts.append("VkDevice device = (VkDevice) devw->nextObject;")
+ stmts.append("PFN_vkGetDeviceProcAddr gpa = (PFN_vkGetDeviceProcAddr) devw->pGPA;")
+ stmts.append("VkDevice baseDevice = (VkDevice) devw->baseObject;")
+ stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init")
+ stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr) gpa(device,\"vkGetDeviceProcAddr\");")
for proto in self.protos:
if proto.name == "CreateInstance" or proto.name == "GetGlobalExtensionInfo" or proto.name == "GetDisplayInfoWSI" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice":
continue
- if proto.name == "GetDeviceProcAddr":
- stmts.append("table->%s = gpa; // direct assignment" % proto.name)
- else:
- stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
+ if proto.name != "GetDeviceProcAddr":
+ stmts.append("table->%s = (PFN_vk%s) gpa(baseDevice, \"vk%s\");" %
(proto.name, proto.name, proto.name))
func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table,"
% self.prefix)
- func.append("%s PFN_vkGetDeviceProcAddr gpa,"
- % (" " * len(self.prefix)))
- func.append("%s VkDevice device)"
+ func.append("%s const VkBaseLayerObject *devw)"
% (" " * len(self.prefix)))
else:
+ # GPA has to be first one and uses wrapped object
+ stmts.append("VkInstance instance = (VkInstance) instw->nextObject;")
+ stmts.append("PFN_vkGetInstanceProcAddr gpa = (PFN_vkGetInstanceProcAddr) instw->pGPA;")
+ stmts.append("VkInstance baseInstance = (VkInstance) instw->baseObject;")
+ stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init")
+ stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr) gpa(instance,\"vkGetInstanceProcAddr\");")
for proto in self.protos:
if proto.name != "CreateInstance" and proto.name != "GetGlobalExtensionInfo" and proto.name != "GetDisplayInfoWSI" and proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
continue
- if proto.name == "GetInstanceProcAddr":
- stmts.append("table->%s = gpa; // direct assignment" % proto.name)
- else:
- stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
+ if proto.name != "GetInstanceProcAddr":
+ stmts.append("table->%s = (PFN_vk%s) gpa(baseInstance, \"vk%s\");" %
(proto.name, proto.name, proto.name))
func.append("static inline void %s_init_instance_dispatch_table(VkLayerInstanceDispatchTable *table,"
% self.prefix)
- func.append("%s PFN_vkGetInstanceProcAddr gpa,"
- % (" " * len(self.prefix)))
- func.append("%s VkInstance instance)"
+ func.append("%s const VkBaseLayerObject *instw)"
% (" " * len(self.prefix)))
func.append("{")
func.append(" %s" % "\n ".join(stmts))
@@ -150,8 +154,8 @@ class DispatchTableOpsSubcommand(Subcommand):
return "\n".join(func)
def generate_body(self):
- body = [self._generate_init("device"),
- self._generate_init("instance")]
+ body = [self._generate_init_dispatch("device"),
+ self._generate_init_dispatch("instance")]
return "\n\n".join(body)
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 184cf365..c1d6fdc7 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -223,7 +223,7 @@ class Subcommand(object):
intercepted = []
for proto in self.protos:
if proto.name == "GetDeviceProcAddr" or proto.name == "GetInstanceProcAddr":
- intercepted.append(proto)
+ continue
else:
intercept = self.generate_intercept(proto, qual)
if intercept is None:
@@ -352,13 +352,16 @@ class Subcommand(object):
func_body = []
func_body.append("VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
"{\n"
- " VkBaseLayerObject* devw = (VkBaseLayerObject *) device;\n"
" void* addr;\n"
" if (device == VK_NULL_HANDLE) {\n"
" return NULL;\n"
" }\n"
- " loader_platform_thread_once(&initOnce, init%s);\n"
- " initDeviceTable((const VkBaseLayerObject *) device);\n\n"
+ " loader_platform_thread_once(&initOnce, init%s);\n\n"
+ " /* loader uses this to force layer initialization; device object is wrapped */\n"
+ " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
+ " initDeviceTable((const VkBaseLayerObject *) device);\n"
+ " return (void *) vkGetDeviceProcAddr;\n"
+ " }\n\n"
" addr = layer_intercept_proc(funcName);\n"
" if (addr)\n"
" return addr;" % self.layer_name)
@@ -373,20 +376,25 @@ class Subcommand(object):
func_body.append(' else if (!strcmp("%s", funcName))\n'
' return %s%s%s;' % (ext_name, cpp_prefix, ext_name, cpp_postfix))
func_body.append(" else {\n"
- " if (devw->pGPA == NULL)\n"
+ " VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;\n"
+ " VkLayerDispatchTable* pTable = tableMap[*ppDisp];\n"
+ " if (pTable->GetDeviceProcAddr == NULL)\n"
" return NULL;\n"
- " return devw->pGPA((VkObject)devw->nextObject, funcName);\n"
+ " return pTable->GetDeviceProcAddr(device, funcName);\n"
" }\n"
"}\n")
func_body.append("VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
"{\n"
- " VkBaseLayerObject* instw = (VkBaseLayerObject *) instance;\n"
" void* addr;\n"
" if (instance == VK_NULL_HANDLE) {\n"
" return NULL;\n"
" }\n"
- " loader_platform_thread_once(&initOnce, init%s);\n"
- " initInstanceTable((const VkBaseLayerObject *) instance);\n\n"
+ " loader_platform_thread_once(&initOnce, init%s);\n\n"
+ " /* loader uses this to force layer initialization; instance object is wrapped */\n"
+ " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
+ " initInstanceTable((const VkBaseLayerObject *) instance);\n"
+ " return (void *) vkGetInstanceProcAddr;\n"
+ " }\n\n"
" addr = layer_intercept_instance_proc(funcName);\n"
" if (addr)\n"
" return addr;" % self.layer_name)
@@ -396,9 +404,11 @@ class Subcommand(object):
func_body.append(' else if (!strcmp("%s", funcName))\n'
' return %s;' % (ext_name, ext_name))
func_body.append(" else {\n"
- " if (instw->pGPA == NULL)\n"
+ " VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;\n"
+ " VkLayerInstanceDispatchTable* pTable = tableInstanceMap[*ppDisp];\n"
+ " if (pTable->GetInstanceProcAddr == NULL)\n"
" return NULL;\n"
- " return instw->pGPA((VkObject)instw->nextObject, funcName);\n"
+ " return pTable->GetInstanceProcAddr(instance, funcName);\n"
" }\n"
"}\n")
return "\n".join(func_body)
@@ -453,7 +463,7 @@ class Subcommand(object):
func_body.append(' return it->second;')
func_body.append(' }')
func_body.append('')
- func_body.append(' layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);')
+ func_body.append(' layer_initialize_dispatch_table(pTable, devw);')
func_body.append('')
func_body.append(' return pTable;')
func_body.append('}')
@@ -474,7 +484,7 @@ class Subcommand(object):
func_body.append(' return it->second;')
func_body.append(' }')
func_body.append('')
- func_body.append(' layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);')
+ func_body.append(' layer_init_instance_dispatch_table(pTable, instw);')
func_body.append('')
func_body.append(' return pTable;')
func_body.append('}')
@@ -773,7 +783,7 @@ class APIDumpSubcommand(Subcommand):
func_body.append(' return it->second;')
func_body.append(' }')
func_body.append('')
- func_body.append(' layer_initialize_dispatch_table(pTable, (PFN_vkGetDeviceProcAddr) devw->pGPA, (VkDevice) devw->nextObject);')
+ func_body.append(' layer_initialize_dispatch_table(pTable, devw);')
func_body.append('')
func_body.append(' return pTable;')
func_body.append('}')
@@ -794,7 +804,7 @@ class APIDumpSubcommand(Subcommand):
func_body.append(' return it->second;')
func_body.append(' }')
func_body.append('')
- func_body.append(' layer_init_instance_dispatch_table(pTable, (PFN_vkGetInstanceProcAddr) instw->pGPA, (VkInstance) instw->nextObject);')
+ func_body.append(' layer_init_instance_dispatch_table(pTable, instw);')
func_body.append('')
func_body.append(' return pTable;')
func_body.append('}')