mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
Hooking for MTLDevice basic new Library APIs
This commit is contained in:
committed by
Baldur Karlsson
parent
88a2b3d74a
commit
5f3203c698
@@ -29,20 +29,47 @@
|
||||
#include "common/timing.h"
|
||||
#include "official/metal-cpp.h"
|
||||
#include "serialise/serialiser.h"
|
||||
#include "serialise/serialiser.h"
|
||||
#include "metal_resources.h"
|
||||
#include "metal_types.h"
|
||||
|
||||
enum class MetalChunk : uint32_t
|
||||
{
|
||||
MTLCreateSystemDefaultDevice = (uint32_t)SystemChunk::FirstDriverChunk,
|
||||
MTLDevice_newDefaultLibrary,
|
||||
MTLDevice_newLibraryWithSource,
|
||||
MTLLibrary_newFunctionWithName,
|
||||
Max
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_ENUM(MetalChunk);
|
||||
|
||||
#define INSTANTIATE_FUNCTION_SERIALISED(CLASS, func, ...) \
|
||||
template bool CLASS::func(ReadSerialiser &ser, __VA_ARGS__); \
|
||||
template bool CLASS::func(WriteSerialiser &ser, __VA_ARGS__);
|
||||
// must be at the start of any function that serialises
|
||||
#define CACHE_THREAD_SERIALISER() WriteSerialiser &ser = m_WrappedMTLDevice->GetThreadSerialiser();
|
||||
|
||||
#define SERIALISE_TIME_CALL(...) \
|
||||
{ \
|
||||
WriteSerialiser &ser = m_WrappedMTLDevice->GetThreadSerialiser(); \
|
||||
ser.ChunkMetadata().timestampMicro = Timing::GetTick(); \
|
||||
__VA_ARGS__; \
|
||||
ser.ChunkMetadata().durationMicro = Timing::GetTick() - ser.ChunkMetadata().timestampMicro; \
|
||||
}
|
||||
|
||||
#define DECLARE_FUNCTION_SERIALISED(ret, func, ...) \
|
||||
ret func(__VA_ARGS__); \
|
||||
template <typename SerialiserType> \
|
||||
bool CONCAT(Serialise_, func(SerialiserType &ser, ##__VA_ARGS__));
|
||||
|
||||
#define INSTANTIATE_FUNCTION_SERIALISED(CLASS, ret, func, ...) \
|
||||
template bool CLASS::CONCAT(Serialise_, func(ReadSerialiser &ser, __VA_ARGS__)); \
|
||||
template bool CLASS::CONCAT(Serialise_, func(WriteSerialiser &ser, __VA_ARGS__));
|
||||
|
||||
// A handy macro to say "is the serialiser reading and we're doing replay-mode stuff?"
|
||||
// The reason we check both is that checking the first allows the compiler to eliminate the other
|
||||
// path at compile-time, and the second because we might be just struct-serialising in which case we
|
||||
// should be doing no work to restore states.
|
||||
// Writing is unambiguously during capture mode, so we don't have to check both in that case.
|
||||
#define IsReplayingAndReading() (ser.IsReading() && IsReplayMode(m_WrappedMTLDevice->GetState()))
|
||||
|
||||
#ifdef __OBJC__
|
||||
#define METAL_NOT_HOOKED() \
|
||||
|
||||
@@ -23,17 +23,12 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "metal_device.h"
|
||||
#include "metal_helpers_bridge.h"
|
||||
#include "metal_library.h"
|
||||
#include "metal_manager.h"
|
||||
|
||||
WrappedMTLDevice::WrappedMTLDevice(MTL::Device *realMTLDevice, ResourceId objId)
|
||||
: WrappedMTLObject(realMTLDevice, objId, this, GetStateRef())
|
||||
{
|
||||
wrappedObjC = AllocateObjCWrapper(this);
|
||||
Construct();
|
||||
GetResourceManager()->AddCurrentResource(objId, this);
|
||||
}
|
||||
|
||||
void WrappedMTLDevice::Construct()
|
||||
{
|
||||
objc = AllocateObjCWrapper(this);
|
||||
m_WrappedMTLDevice = this;
|
||||
@@ -41,12 +36,131 @@ void WrappedMTLDevice::Construct()
|
||||
|
||||
m_ResourceManager = new MetalResourceManager(m_State, this);
|
||||
RDCASSERT(m_WrappedMTLDevice == this);
|
||||
GetResourceManager()->AddCurrentResource(objId, this);
|
||||
}
|
||||
|
||||
MTL::Device *WrappedMTLDevice::MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice)
|
||||
WrappedMTLDevice *WrappedMTLDevice::MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice)
|
||||
{
|
||||
ResourceId objId = ResourceIDGen::GetNewUniqueID();
|
||||
WrappedMTLDevice *wrappedMTLDevice = new WrappedMTLDevice(realMTLDevice, objId);
|
||||
|
||||
return UnwrapObjC<MTL::Device *>(wrappedMTLDevice);
|
||||
// return GetObjC<MTL::Device *>(wrappedMTLDevice);
|
||||
return wrappedMTLDevice;
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedMTLDevice::Serialise_newDefaultLibrary(SerialiserType &ser, WrappedMTLLibrary *library)
|
||||
{
|
||||
void *pData;
|
||||
uint32_t bytesCount;
|
||||
if(ser.IsWriting())
|
||||
{
|
||||
ObjC::Get_defaultLibraryData(pData, bytesCount);
|
||||
}
|
||||
|
||||
SERIALISE_ELEMENT_LOCAL(Library, GetResID(library)).TypedAs("MTLLibrary"_lit);
|
||||
SERIALISE_ELEMENT(bytesCount);
|
||||
SERIALISE_ELEMENT_ARRAY(pData, bytesCount);
|
||||
|
||||
if(ser.IsWriting())
|
||||
{
|
||||
free(pData);
|
||||
}
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
// TODO: implement RD MTL replay
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WrappedMTLLibrary *WrappedMTLDevice::newDefaultLibrary()
|
||||
{
|
||||
MTL::Library *realMTLLibrary;
|
||||
|
||||
SERIALISE_TIME_CALL(realMTLLibrary = Unwrap(this)->newDefaultLibrary());
|
||||
WrappedMTLLibrary *wrappedMTLLibrary;
|
||||
ResourceId id = GetResourceManager()->WrapResource(realMTLLibrary, wrappedMTLLibrary);
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
Chunk *chunk = NULL;
|
||||
{
|
||||
CACHE_THREAD_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(MetalChunk::MTLDevice_newDefaultLibrary);
|
||||
Serialise_newDefaultLibrary(ser, wrappedMTLLibrary);
|
||||
chunk = scope.Get();
|
||||
}
|
||||
MetalResourceRecord *record = GetResourceManager()->AddResourceRecord(wrappedMTLLibrary);
|
||||
record->AddChunk(chunk);
|
||||
GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Read);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: implement RD MTL replay
|
||||
// GetResourceManager()->AddLiveResource(id, wrappedMTLLibrary);
|
||||
}
|
||||
return wrappedMTLLibrary;
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedMTLDevice::Serialise_newLibraryWithSource(SerialiserType &ser,
|
||||
WrappedMTLLibrary *library, NS::String *source,
|
||||
MTL::CompileOptions *options)
|
||||
{
|
||||
SERIALISE_ELEMENT_LOCAL(Library, GetResID(library)).TypedAs("MTLLibrary"_lit);
|
||||
SERIALISE_ELEMENT(source);
|
||||
// TODO:SERIALISE_ELEMENT(options);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
// TODO: implement RD MTL replay
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WrappedMTLLibrary *WrappedMTLDevice::newLibraryWithSource(NS::String *source,
|
||||
MTL::CompileOptions *options,
|
||||
NS::Error **error)
|
||||
{
|
||||
MTL::Library *realMTLLibrary;
|
||||
SERIALISE_TIME_CALL(realMTLLibrary = Unwrap(this)->newLibrary(source, options, error));
|
||||
WrappedMTLLibrary *wrappedMTLLibrary;
|
||||
ResourceId id = GetResourceManager()->WrapResource(realMTLLibrary, wrappedMTLLibrary);
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
Chunk *chunk = NULL;
|
||||
{
|
||||
CACHE_THREAD_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(MetalChunk::MTLDevice_newLibraryWithSource);
|
||||
Serialise_newLibraryWithSource(ser, wrappedMTLLibrary, source, options);
|
||||
chunk = scope.Get();
|
||||
}
|
||||
MetalResourceRecord *record = GetResourceManager()->AddResourceRecord(wrappedMTLLibrary);
|
||||
record->AddChunk(chunk);
|
||||
GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Read);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: implement RD MTL replay
|
||||
// GetResourceManager()->AddLiveResource(id, wrappedMTLLibrary);
|
||||
}
|
||||
return wrappedMTLLibrary;
|
||||
}
|
||||
|
||||
template bool WrappedMTLDevice::Serialise_newDefaultLibrary(ReadSerialiser &ser,
|
||||
WrappedMTLLibrary *library);
|
||||
template bool WrappedMTLDevice::Serialise_newDefaultLibrary(WriteSerialiser &ser,
|
||||
WrappedMTLLibrary *library);
|
||||
|
||||
template bool WrappedMTLDevice::Serialise_newLibraryWithSource(ReadSerialiser &ser,
|
||||
WrappedMTLLibrary *library,
|
||||
NS::String *source,
|
||||
MTL::CompileOptions *options);
|
||||
template bool WrappedMTLDevice::Serialise_newLibraryWithSource(WriteSerialiser &ser,
|
||||
WrappedMTLLibrary *library,
|
||||
NS::String *source,
|
||||
MTL::CompileOptions *options);
|
||||
|
||||
@@ -34,7 +34,17 @@ class WrappedMTLDevice : public WrappedMTLObject
|
||||
public:
|
||||
WrappedMTLDevice(MTL::Device *realMTLDevice, ResourceId objId);
|
||||
~WrappedMTLDevice() {}
|
||||
static MTL::Device *MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice);
|
||||
static WrappedMTLDevice *MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice);
|
||||
|
||||
WrappedMTLLibrary *newDefaultLibrary();
|
||||
template <typename SerialiserType>
|
||||
bool Serialise_newDefaultLibrary(SerialiserType &ser, WrappedMTLLibrary *library);
|
||||
|
||||
WrappedMTLLibrary *newLibraryWithSource(NS::String *source, MTL::CompileOptions *options,
|
||||
NS::Error **error);
|
||||
template <typename SerialiserType>
|
||||
bool Serialise_newLibraryWithSource(SerialiserType &ser, WrappedMTLLibrary *library,
|
||||
NS::String *source, MTL::CompileOptions *options);
|
||||
|
||||
CaptureState &GetStateRef() { return m_State; }
|
||||
CaptureState GetState() { return m_State; }
|
||||
@@ -47,8 +57,6 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
void Construct();
|
||||
|
||||
bool Prepare_InitialState(WrappedMTLObject *res);
|
||||
uint64_t GetSize_InitialState(ResourceId id, const MetalInitialContents &initial);
|
||||
template <typename SerialiserType>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "metal_device.h"
|
||||
#include <Availability.h>
|
||||
#include "metal_library.h"
|
||||
#include "metal_types_bridge.h"
|
||||
|
||||
// Define Mac SDK versions when compiling with earlier SDKs
|
||||
@@ -284,8 +285,9 @@
|
||||
|
||||
- (nullable id<MTLLibrary>)newDefaultLibrary
|
||||
{
|
||||
METAL_NOT_HOOKED();
|
||||
return [self.real newDefaultLibrary];
|
||||
WrappedMTLLibrary *wrapped = self.wrappedCPP->newDefaultLibrary();
|
||||
MTL::Library *objc = GetObjC<MTL::Library *>(wrapped);
|
||||
return id<MTLLibrary>(objc);
|
||||
}
|
||||
|
||||
- (nullable id<MTLLibrary>)newDefaultLibraryWithBundle:(NSBundle *)bundle
|
||||
@@ -322,8 +324,10 @@
|
||||
options:(nullable MTLCompileOptions *)options
|
||||
error:(__autoreleasing NSError **)error
|
||||
{
|
||||
METAL_NOT_HOOKED();
|
||||
return [self.real newLibraryWithSource:source options:options error:error];
|
||||
WrappedMTLLibrary *wrapped = self.wrappedCPP->newLibraryWithSource(
|
||||
(NS::String *)source, (MTL::CompileOptions *)options, (NS::Error **)error);
|
||||
MTL::Library *objc = GetObjC<MTL::Library *>(wrapped);
|
||||
return (id<MTLLibrary>)(objc);
|
||||
}
|
||||
|
||||
- (void)newLibraryWithSource:(NSString *)source
|
||||
|
||||
@@ -54,7 +54,8 @@ id<MTLDevice> METAL_EXPORT_NAME(MTLCreateSystemDefaultDevice)(void)
|
||||
}
|
||||
|
||||
id<MTLDevice> device = METAL.MTLCreateSystemDefaultDevice();
|
||||
return id<MTLDevice>(WrappedMTLDevice::MTLCreateSystemDefaultDevice((MTL::Device *)device));
|
||||
WrappedMTLDevice *wrapped = WrappedMTLDevice::MTLCreateSystemDefaultDevice((MTL::Device *)device);
|
||||
return id<MTLDevice>(GetObjC<MTL::Device *>(wrapped));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user