From d38741e9abf65ea75006227c545705c64dd221de Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 23 Oct 2015 15:13:28 +0200 Subject: [PATCH] Create a WrappedVulkan per VkInstance and indirect to find it in layer --- renderdoc/driver/vulkan/vk_dispatchtables.h | 5 ++- renderdoc/driver/vulkan/vk_hookset_defs.h | 2 - renderdoc/driver/vulkan/vk_manager.h | 2 +- renderdoc/driver/vulkan/vk_resources.h | 48 +++++++++++++-------- renderdoc/driver/vulkan/vk_tracelayer.cpp | 46 ++++++++++++-------- 5 files changed, 61 insertions(+), 42 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_dispatchtables.h b/renderdoc/driver/vulkan/vk_dispatchtables.h index 25eed1bfa..2bc4c6e87 100644 --- a/renderdoc/driver/vulkan/vk_dispatchtables.h +++ b/renderdoc/driver/vulkan/vk_dispatchtables.h @@ -41,9 +41,12 @@ void InitDeviceReplayTables(VkDevice device); VkLayerDispatchTable *GetDeviceDispatchTable(void *device); VkLayerInstanceDispatchTable *GetInstanceDispatchTable(void *instance); +class WrappedVulkan; + template -void SetDispatchTable(bool writing, parenttype parent, wrappedtype *wrapped) +void SetDispatchTable(bool writing, parenttype parent, WrappedVulkan *core, wrappedtype *wrapped) { + wrapped->core = core; if(writing) { wrapped->table = wrappedtype::UseInstanceDispatchTable diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index 65724e860..84edc6fd5 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -179,8 +179,6 @@ HookInit(QueuePresentKHR); #define DefineHooks() \ - HookDefine2(VkResult, vkCreateInstance, const VkInstanceCreateInfo*, pCreateInfo, VkInstance*, pInstance); \ - HookDefine1(void, vkDestroyInstance, VkInstance, instance); \ HookDefine3(VkResult, vkEnumeratePhysicalDevices, VkInstance, instance, uint32_t*, pPhysicalDeviceCount, VkPhysicalDevice*, pPhysicalDevices); \ HookDefine2(VkResult, vkGetPhysicalDeviceFeatures, VkPhysicalDevice, physicalDevice, VkPhysicalDeviceFeatures*, pFeatures); \ HookDefine3(VkResult, vkGetPhysicalDeviceFormatProperties, VkPhysicalDevice, physicalDevice, VkFormat, format, VkFormatProperties*, pFormatProperties); \ diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index e31e64d40..fe0b9c49b 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -112,7 +112,7 @@ class VulkanResourceManager : public ResourceManager::Outer *wrapped = new typename UnwrapHelper::Outer(obj, id); - SetTableIfDispatchable(m_State >= WRITING, parentObj, wrapped); + SetTableIfDispatchable(m_State >= WRITING, parentObj, m_Core, wrapped); AddCurrentResource(id, wrapped); diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index f1883edbb..0de1aba43 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -128,34 +128,38 @@ struct WrappedVkNonDispRes : public WrappedVkRes VkResourceRecord *record; }; +class WrappedVulkan; + struct WrappedVkDispRes : public WrappedVkRes { - WrappedVkDispRes(VkInstance obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL) + WrappedVkDispRes(VkInstance obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) { loaderTable = *(uintptr_t*)obj; } - WrappedVkDispRes(VkPhysicalDevice obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL) + WrappedVkDispRes(VkPhysicalDevice obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) { loaderTable = *(uintptr_t*)obj; } - WrappedVkDispRes(VkDevice obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL) + WrappedVkDispRes(VkDevice obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) { loaderTable = *(uintptr_t*)obj; } - WrappedVkDispRes(VkQueue obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL) + WrappedVkDispRes(VkQueue obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) { loaderTable = *(uintptr_t*)obj; } - WrappedVkDispRes(VkCmdBuffer obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL) + WrappedVkDispRes(VkCmdBuffer obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) { loaderTable = *(uintptr_t*)obj; } - // VKTODOLOW there's padding here on 32-bit but I don't know if I really care about 32-bit. - // preserve dispatch table pointer in dispatchable objects uintptr_t loaderTable, table; RealVkRes real; ResourceId id; VkResourceRecord *record; + // we store this here so that any entry point with a dispatchable object can find the + // write instance to invoke into, without needing to keep any around. Its lifetime is + // tied to the VkInstance + WrappedVulkan *core; }; // ensure the structs don't accidentally get made larger -RDCCOMPILE_ASSERT(sizeof(WrappedVkDispRes) == (sizeof(uint64_t)*3 + sizeof(uintptr_t)*2), "Wrapped resource struct has changed size! This is bad"); +RDCCOMPILE_ASSERT(sizeof(WrappedVkDispRes) == (sizeof(uint64_t)*2 + sizeof(uintptr_t)*4), "Wrapped resource struct has changed size! This is bad"); RDCCOMPILE_ASSERT(sizeof(WrappedVkNonDispRes) == sizeof(uint64_t)*3, "Wrapped resource struct has changed size! This is bad"); // VKTODOLOW check that the pool counts approximated below are good for typical applications @@ -449,6 +453,12 @@ typename UnwrapHelper::Outer::DispatchTableType *ObjDisp(RealType obj) return (typename UnwrapHelper::Outer::DispatchTableType *)GetWrapped(obj)->table; } +template +WrappedVulkan *CoreDisp(RealType obj) +{ + return (WrappedVulkan *)GetWrapped(obj)->core; +} + template RealType Unwrap(RealType obj) { @@ -500,17 +510,17 @@ TypedRealHandle ToTypedHandle(RealType obj) } template -inline void SetTableIfDispatchable(bool writing, parenttype parent, wrappedtype *obj) {} -template<> inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVkInstance *obj) -{ SetDispatchTable(writing, parent, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVkPhysicalDevice *obj) -{ SetDispatchTable(writing, parent, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVkDevice *obj) -{ SetDispatchTable(writing, parent, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVkQueue *obj) -{ SetDispatchTable(writing, parent, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVkCmdBuffer *obj) -{ SetDispatchTable(writing, parent, obj); } +inline void SetTableIfDispatchable(bool writing, parenttype parent, WrappedVulkan *core, wrappedtype *obj) {} +template<> inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVulkan *core, WrappedVkInstance *obj) +{ SetDispatchTable(writing, parent, core, obj); } +template<> inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVulkan *core, WrappedVkPhysicalDevice *obj) +{ SetDispatchTable(writing, parent, core, obj); } +template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, WrappedVkDevice *obj) +{ SetDispatchTable(writing, parent, core, obj); } +template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, WrappedVkQueue *obj) +{ SetDispatchTable(writing, parent, core, obj); } +template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, WrappedVkCmdBuffer *obj) +{ SetDispatchTable(writing, parent, core, obj); } bool IsDispatchableRes(WrappedVkRes *ptr); VkResourceType IdentifyTypeByPtr(WrappedVkRes *ptr); diff --git a/renderdoc/driver/vulkan/vk_tracelayer.cpp b/renderdoc/driver/vulkan/vk_tracelayer.cpp index 38bd76540..eb3ec8542 100644 --- a/renderdoc/driver/vulkan/vk_tracelayer.cpp +++ b/renderdoc/driver/vulkan/vk_tracelayer.cpp @@ -30,6 +30,7 @@ #include "vk_common.h" #include "vk_core.h" +#include "vk_resources.h" #include "vk_hookset_defs.h" #include "common/common.h" @@ -48,40 +49,52 @@ void InitInstanceTable(const VkBaseLayerObject *obj); // RenderDoc State -WrappedVulkan *shadowVulkan = NULL; +// RenderDoc Intercepts, these must all be entry points with a dispatchable object +// as the first parameter -// RenderDoc Intercepts - -#define HookDefine0(ret, function) \ - ret VKAPI CONCAT(hooked_, function)() \ - { return shadowVulkan->function(); } #define HookDefine1(ret, function, t1, p1) \ ret VKAPI CONCAT(hooked_, function)(t1 p1) \ - { return shadowVulkan->function(p1); } + { return CoreDisp(p1)->function(p1); } #define HookDefine2(ret, function, t1, p1, t2, p2) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2) \ - { return shadowVulkan->function(p1, p2); } + { return CoreDisp(p1)->function(p1, p2); } #define HookDefine3(ret, function, t1, p1, t2, p2, t3, p3) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3) \ - { return shadowVulkan->function(p1, p2, p3); } + { return CoreDisp(p1)->function(p1, p2, p3); } #define HookDefine4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4) \ - { return shadowVulkan->function(p1, p2, p3, p4); } + { return CoreDisp(p1)->function(p1, p2, p3, p4); } #define HookDefine5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { return shadowVulkan->function(p1, p2, p3, p4, p5); } + { return CoreDisp(p1)->function(p1, p2, p3, p4, p5); } #define HookDefine6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { return shadowVulkan->function(p1, p2, p3, p4, p5, p6); } + { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6); } #define HookDefine7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { return shadowVulkan->function(p1, p2, p3, p4, p5, p6, p7); } + { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7); } #define HookDefine8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ ret VKAPI CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { return shadowVulkan->function(p1, p2, p3, p4, p5, p6, p7, p8); } + { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8); } DefineHooks(); +// need to implement vkCreateInstance and vkDestroyInstance specially, +// to create and destroy the core WrappedVulkan object + +VkResult hooked_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance) +{ + WrappedVulkan *core = new WrappedVulkan(""); + return core->vkCreateInstance(pCreateInfo, pInstance); +} + +void hooked_vkDestroyInstance(VkInstance instance) +{ + WrappedVulkan *core = CoreDisp(instance); + core->vkDestroyInstance(instance); + delete core; +} + // Layer Intercepts static const VkLayerProperties physLayers[] = { @@ -184,11 +197,6 @@ VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI RenderDoc_GetInstanceProcAddr(VkInstanc /* loader uses this to force layer initialization; instance object is wrapped */ if (!strcmp("vkGetInstanceProcAddr", pName)) { InitInstanceTable((const VkBaseLayerObject *) instance); - // VKTODOLOW I think this will be created and passed down in wrapped dispatchable - // objects - if (shadowVulkan == NULL) { - shadowVulkan = new WrappedVulkan(""); - } return (PFN_vkVoidFunction) &RenderDoc_GetInstanceProcAddr; }