mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Hook CAMetalLayer nextDrawable message
PR Feedback. Replace the brittle callstack string comparison
This commit is contained in:
committed by
Baldur Karlsson
parent
cef722a3d8
commit
00fdb79d68
@@ -46,12 +46,38 @@ WrappedMTLDevice::WrappedMTLDevice(MTL::Device *realMTLDevice, ResourceId objId)
|
||||
WrappedMTLDevice *WrappedMTLDevice::MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice)
|
||||
{
|
||||
MTLFixupForMetalDriverAssert();
|
||||
MTLHookObjcMethods();
|
||||
ResourceId objId = ResourceIDGen::GetNewUniqueID();
|
||||
WrappedMTLDevice *wrappedMTLDevice = new WrappedMTLDevice(realMTLDevice, objId);
|
||||
|
||||
return wrappedMTLDevice;
|
||||
}
|
||||
|
||||
IMP WrappedMTLDevice::real_CAMetalLayer_nextDrawable;
|
||||
uint64_t WrappedMTLDevice::nextDrawableTLSSlot;
|
||||
|
||||
MTL::Drawable *hooked_CAMetalLayer_nextDrawable(id self, SEL _cmd)
|
||||
{
|
||||
RDCASSERTEQUAL(Threading::GetTLSValue(WrappedMTLDevice::nextDrawableTLSSlot), 0);
|
||||
Threading::SetTLSValue(WrappedMTLDevice::nextDrawableTLSSlot, (void *)(uintptr_t) true);
|
||||
MTL::Drawable *drawable =
|
||||
((MTL::Drawable * (*)(id, SEL))WrappedMTLDevice::real_CAMetalLayer_nextDrawable)(self, _cmd);
|
||||
Threading::SetTLSValue(WrappedMTLDevice::nextDrawableTLSSlot, (void *)(uintptr_t) false);
|
||||
return drawable;
|
||||
}
|
||||
|
||||
void WrappedMTLDevice::MTLHookObjcMethods()
|
||||
{
|
||||
static bool s_hookObjcMethods = false;
|
||||
if(s_hookObjcMethods)
|
||||
return;
|
||||
|
||||
Method m =
|
||||
class_getInstanceMethod(objc_lookUpClass("CAMetalLayer"), sel_registerName("nextDrawable"));
|
||||
real_CAMetalLayer_nextDrawable = method_setImplementation(m, (IMP)hooked_CAMetalLayer_nextDrawable);
|
||||
nextDrawableTLSSlot = Threading::AllocateTLSSlot();
|
||||
}
|
||||
|
||||
void WrappedMTLDevice::MTLFixupForMetalDriverAssert()
|
||||
{
|
||||
static bool s_fixupMetalDriverAssert = false;
|
||||
@@ -311,14 +337,10 @@ WrappedMTLTexture *WrappedMTLDevice::newTextureWithDescriptor(MTL::TextureDescri
|
||||
IOSurfaceRef iosurface,
|
||||
NS::UInteger plane)
|
||||
{
|
||||
return Common_NewTexture(descriptor, MetalChunk::MTLDevice_newTextureWithDescriptor_iosurface,
|
||||
true, iosurface, plane);
|
||||
}
|
||||
|
||||
WrappedMTLTexture *WrappedMTLDevice::nextDrawableTexture(MTL::TextureDescriptor *descriptor,
|
||||
IOSurfaceRef iosurface, NS::UInteger plane)
|
||||
{
|
||||
return Common_NewTexture(descriptor, MetalChunk::MTLDevice_newTextureWithDescriptor_nextDrawable,
|
||||
bool nextDrawable = (bool)(uintptr_t)Threading::GetTLSValue(nextDrawableTLSSlot);
|
||||
return Common_NewTexture(descriptor,
|
||||
nextDrawable ? MetalChunk::MTLDevice_newTextureWithDescriptor_nextDrawable
|
||||
: MetalChunk::MTLDevice_newTextureWithDescriptor_iosurface,
|
||||
true, iosurface, plane);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@ public:
|
||||
NS::Error **error);
|
||||
WrappedMTLTexture *newTextureWithDescriptor(MTL::TextureDescriptor *descriptor,
|
||||
IOSurfaceRef iosurface, NS::UInteger plane);
|
||||
WrappedMTLTexture *nextDrawableTexture(MTL::TextureDescriptor *descriptor, IOSurfaceRef iosurface,
|
||||
NS::UInteger plane);
|
||||
WrappedMTLTexture *newTextureWithDescriptor(MTL::TextureDescriptor *descriptor);
|
||||
template <typename SerialiserType>
|
||||
bool Serialise_newTextureWithDescriptor(SerialiserType &ser, WrappedMTLTexture *,
|
||||
@@ -96,8 +94,12 @@ public:
|
||||
TypeEnum = eResDevice
|
||||
};
|
||||
|
||||
static uint64_t nextDrawableTLSSlot;
|
||||
static IMP real_CAMetalLayer_nextDrawable;
|
||||
|
||||
private:
|
||||
static void MTLFixupForMetalDriverAssert();
|
||||
static void MTLHookObjcMethods();
|
||||
bool Prepare_InitialState(WrappedMTLObject *res);
|
||||
uint64_t GetSize_InitialState(ResourceId id, const MetalInitialContents &initial);
|
||||
template <typename SerialiserType>
|
||||
|
||||
@@ -266,21 +266,6 @@
|
||||
plane:(NSUInteger)plane
|
||||
API_AVAILABLE(macos(10.11), ios(11.0))
|
||||
{
|
||||
NS::String *nsString = (NS::String *)[[NSThread callStackSymbols] objectAtIndex:1];
|
||||
// Example parentCallsite string
|
||||
//"1 QuartzCore 0x00000001b956ece8 _ZL19get_unused_drawableP20_CAMetalLayerPrivatebb + 676"
|
||||
bool nextDrawable = false;
|
||||
if(nsString)
|
||||
{
|
||||
rdcstr parentCallsite(nsString->utf8String());
|
||||
nextDrawable = (parentCallsite.contains("CAMetalLayer") && parentCallsite.contains("drawable"));
|
||||
}
|
||||
|
||||
if(nextDrawable)
|
||||
{
|
||||
return id<MTLTexture>(GetWrapped(self)->nextDrawableTexture(
|
||||
(MTL::TextureDescriptor *)descriptor, iosurface, plane));
|
||||
}
|
||||
return id<MTLTexture>(GetWrapped(self)->newTextureWithDescriptor(
|
||||
(MTL::TextureDescriptor *)descriptor, iosurface, plane));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user