mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-08 19:10:35 +00:00
Create a WrappedVulkan per VkInstance and indirect to find it in layer
This commit is contained in:
@@ -41,9 +41,12 @@ void InitDeviceReplayTables(VkDevice device);
|
||||
VkLayerDispatchTable *GetDeviceDispatchTable(void *device);
|
||||
VkLayerInstanceDispatchTable *GetInstanceDispatchTable(void *instance);
|
||||
|
||||
class WrappedVulkan;
|
||||
|
||||
template<typename parenttype, typename wrappedtype>
|
||||
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
|
||||
|
||||
@@ -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); \
|
||||
|
||||
@@ -112,7 +112,7 @@ class VulkanResourceManager : public ResourceManager<WrappedVkRes*, TypedRealHan
|
||||
ResourceId id = ResourceIDGen::GetNewUniqueID();
|
||||
typename UnwrapHelper<realtype>::Outer *wrapped = new typename UnwrapHelper<realtype>::Outer(obj, id);
|
||||
|
||||
SetTableIfDispatchable(m_State >= WRITING, parentObj, wrapped);
|
||||
SetTableIfDispatchable(m_State >= WRITING, parentObj, m_Core, wrapped);
|
||||
|
||||
AddCurrentResource(id, wrapped);
|
||||
|
||||
|
||||
@@ -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<RealType>::Outer::DispatchTableType *ObjDisp(RealType obj)
|
||||
return (typename UnwrapHelper<RealType>::Outer::DispatchTableType *)GetWrapped(obj)->table;
|
||||
}
|
||||
|
||||
template<typename RealType>
|
||||
WrappedVulkan *CoreDisp(RealType obj)
|
||||
{
|
||||
return (WrappedVulkan *)GetWrapped(obj)->core;
|
||||
}
|
||||
|
||||
template<typename RealType>
|
||||
RealType Unwrap(RealType obj)
|
||||
{
|
||||
@@ -500,17 +510,17 @@ TypedRealHandle ToTypedHandle(RealType obj)
|
||||
}
|
||||
|
||||
template<typename parenttype, typename wrappedtype>
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user