Added basic MetalResourceManager implementation

Added MetalResourceManager to WrappedMTLDevice

Added helper macros:
METAL_NOT_IMPLEMENTED
METAL_NOT_IMPLEMENTED_ONCE

Added WrappedMTLDevice InitialState methods to metal_init_state.cpp
Added WrappedMTLDevice Serialiser helper methods to metal_core.cpp
This commit is contained in:
Jake Turner
2022-03-12 19:51:57 +00:00
committed by Baldur Karlsson
parent d79617cb46
commit 88a2b3d74a
18 changed files with 541 additions and 12 deletions
+5
View File
@@ -20,6 +20,11 @@ set(sources
metal_function.h
metal_function_bridge.mm
metal_common.h
metal_core.cpp
metal_core.h
metal_manager.cpp
metal_manager.h
metal_init_state.cpp
metal_helpers_bridge.h
metal_helpers_bridge.mm
official/metal-cpp.h
+32
View File
@@ -26,10 +26,24 @@
#include "api/replay/rdcstr.h"
#include "common/common.h"
#include "common/timing.h"
#include "official/metal-cpp.h"
#include "serialise/serialiser.h"
#include "metal_resources.h"
#include "metal_types.h"
enum class MetalChunk : uint32_t
{
MTLCreateSystemDefaultDevice = (uint32_t)SystemChunk::FirstDriverChunk,
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__);
#ifdef __OBJC__
#define METAL_NOT_HOOKED() \
do \
@@ -37,3 +51,21 @@
RDCWARN("Metal %s %s not hooked", class_getName([self class]), sel_getName(_cmd)); \
} while((void)0, 0)
#endif
// similar to RDCUNIMPLEMENTED but without the debugbreak
#define METAL_NOT_IMPLEMENTED(...) \
do \
{ \
RDCWARN("Metal '%s' not implemented -" __VA_ARGS__, __PRETTY_FUNCTION__); \
} while((void)0, 0)
// similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the
// debugbreak.
#define METAL_NOT_IMPLEMENTED_ONCE(...) \
do \
{ \
static bool msgprinted = false; \
if(!msgprinted) \
RDCDEBUG("Metal '%s' not implemented - " __VA_ARGS__, __PRETTY_FUNCTION__); \
msgprinted = true; \
} while((void)0, 0)
+55
View File
@@ -0,0 +1,55 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2022 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "metal_core.h"
#include "metal_device.h"
WriteSerialiser &WrappedMTLDevice::GetThreadSerialiser()
{
WriteSerialiser *ser = (WriteSerialiser *)Threading::GetTLSValue(threadSerialiserTLSSlot);
if(ser)
return *ser;
// slow path, but rare
ser = new WriteSerialiser(new StreamWriter(1024), Ownership::Stream);
uint32_t flags = WriteSerialiser::ChunkDuration | WriteSerialiser::ChunkTimestamp |
WriteSerialiser::ChunkThreadID;
if(RenderDoc::Inst().GetCaptureOptions().captureCallstacks)
flags |= WriteSerialiser::ChunkCallstack;
ser->SetChunkMetadataRecording(flags);
ser->SetUserData(GetResourceManager());
ser->SetVersion(MetalInitParams::CurrentVersion);
Threading::SetTLSValue(threadSerialiserTLSSlot, (void *)ser);
{
SCOPED_LOCK(m_ThreadSerialisersLock);
m_ThreadSerialisers.push_back(ser);
}
return *ser;
}
+35
View File
@@ -0,0 +1,35 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2022 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include "metal_common.h"
struct MetalInitParams
{
// check if a frame capture section version is supported
static const uint64_t CurrentVersion = 0x1;
};
DECLARE_REFLECTION_STRUCT(MetalInitParams);
+12
View File
@@ -23,12 +23,24 @@
******************************************************************************/
#include "metal_device.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;
threadSerialiserTLSSlot = Threading::AllocateTLSSlot();
m_ResourceManager = new MetalResourceManager(m_State, this);
RDCASSERT(m_WrappedMTLDevice == this);
}
MTL::Device *WrappedMTLDevice::MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice)
+23
View File
@@ -25,20 +25,43 @@
#pragma once
#include "metal_common.h"
#include "metal_manager.h"
class WrappedMTLDevice : public WrappedMTLObject
{
friend class MetalResourceManager;
public:
WrappedMTLDevice(MTL::Device *realMTLDevice, ResourceId objId);
~WrappedMTLDevice() {}
static MTL::Device *MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice);
CaptureState &GetStateRef() { return m_State; }
CaptureState GetState() { return m_State; }
MetalResourceManager *GetResourceManager() { return m_ResourceManager; };
WriteSerialiser &GetThreadSerialiser();
enum
{
TypeEnum = eResDevice
};
private:
void Construct();
bool Prepare_InitialState(WrappedMTLObject *res);
uint64_t GetSize_InitialState(ResourceId id, const MetalInitialContents &initial);
template <typename SerialiserType>
bool Serialise_InitialState(SerialiserType &ser, ResourceId id, MetalResourceRecord *record,
const MetalInitialContents *initial);
void Create_InitialState(ResourceId id, WrappedMTLObject *live, bool hasData);
void Apply_InitialState(WrappedMTLObject *live, const MetalInitialContents &initial);
MetalResourceManager *m_ResourceManager;
CaptureState m_State;
uint64_t threadSerialiserTLSSlot;
Threading::CriticalSection m_ThreadSerialisersLock;
rdcarray<WriteSerialiser *> m_ThreadSerialisers;
};
@@ -37,7 +37,7 @@
// ObjCWrappedMTLDevice specific
- (id<MTLDevice>)real
{
MTL::Device *real = Unwrap<MTL::Device *>(self.wrappedCPP);
MTL::Device *real = Unwrap(self.wrappedCPP);
return id<MTLDevice>(real);
}
+1 -1
View File
@@ -29,5 +29,5 @@ WrappedMTLFunction::WrappedMTLFunction(MTL::Function *realMTLFunction, ResourceI
WrappedMTLDevice *wrappedMTLDevice)
: WrappedMTLObject(realMTLFunction, objId, wrappedMTLDevice, wrappedMTLDevice->GetStateRef())
{
wrappedObjC = AllocateObjCWrapper(this);
objc = AllocateObjCWrapper(this);
}
@@ -31,7 +31,7 @@
// ObjCWrappedMTLFunction specific
- (id<MTLFunction>)real
{
MTL::Function *real = Unwrap<MTL::Function *>(self.wrappedCPP);
MTL::Function *real = Unwrap(self.wrappedCPP);
return id<MTLFunction>(real);
}
@@ -0,0 +1,70 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2022 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "metal_common.h"
#include "metal_device.h"
bool WrappedMTLDevice::Prepare_InitialState(WrappedMTLObject *res)
{
ResourceId id = GetResourceManager()->GetID(res);
MetalResourceType type = res->record->resType;
{
RDCERR("Unhandled resource type %d", type);
}
return false;
}
uint64_t WrappedMTLDevice::GetSize_InitialState(ResourceId id, const MetalInitialContents &initial)
{
METAL_NOT_IMPLEMENTED();
return 128;
}
template <typename SerialiserType>
bool WrappedMTLDevice::Serialise_InitialState(SerialiserType &ser, ResourceId id,
MetalResourceRecord *record,
const MetalInitialContents *initial)
{
METAL_NOT_IMPLEMENTED();
return false;
}
void WrappedMTLDevice::Create_InitialState(ResourceId id, WrappedMTLObject *live, bool hasData)
{
METAL_NOT_IMPLEMENTED();
}
void WrappedMTLDevice::Apply_InitialState(WrappedMTLObject *live, const MetalInitialContents &initial)
{
METAL_NOT_IMPLEMENTED();
}
template bool WrappedMTLDevice::Serialise_InitialState(ReadSerialiser &ser, ResourceId id,
MetalResourceRecord *record,
const MetalInitialContents *initial);
template bool WrappedMTLDevice::Serialise_InitialState(WriteSerialiser &ser, ResourceId id,
MetalResourceRecord *record,
const MetalInitialContents *initial);
+1 -1
View File
@@ -30,5 +30,5 @@ WrappedMTLLibrary::WrappedMTLLibrary(MTL::Library *realMTLLibrary, ResourceId ob
WrappedMTLDevice *wrappedMTLDevice)
: WrappedMTLObject(realMTLLibrary, objId, wrappedMTLDevice, wrappedMTLDevice->GetStateRef())
{
wrappedObjC = AllocateObjCWrapper(this);
objc = AllocateObjCWrapper(this);
}
@@ -31,7 +31,7 @@
// ObjCWrappedMTLLibrary specific
- (id<MTLLibrary>)real
{
MTL::Library *real = Unwrap<MTL::Library *>(self.wrappedCPP);
MTL::Library *real = Unwrap(self.wrappedCPP);
return id<MTLLibrary>(real);
}
+60
View File
@@ -0,0 +1,60 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2021 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "metal_manager.h"
#include "metal_device.h"
bool MetalResourceManager::ResourceTypeRelease(WrappedResourceType res)
{
METAL_NOT_IMPLEMENTED();
return false;
}
bool MetalResourceManager::Prepare_InitialState(WrappedMTLObject *res)
{
return m_WrappedMTLDevice->Prepare_InitialState(res);
}
uint64_t MetalResourceManager::GetSize_InitialState(ResourceId id, const MetalInitialContents &initial)
{
return m_WrappedMTLDevice->GetSize_InitialState(id, initial);
}
bool MetalResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id,
MetalResourceRecord *record,
const MetalInitialContents *initial)
{
return m_WrappedMTLDevice->Serialise_InitialState(ser, id, record, initial);
}
void MetalResourceManager::Create_InitialState(ResourceId id, WrappedMTLObject *live, bool hasData)
{
return m_WrappedMTLDevice->Create_InitialState(id, live, hasData);
}
void MetalResourceManager::Apply_InitialState(WrappedMTLObject *live,
const MetalInitialContents &initial)
{
return m_WrappedMTLDevice->Apply_InitialState(live, initial);
}
+151
View File
@@ -0,0 +1,151 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2021 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include "core/resource_manager.h"
#include "metal_resources.h"
struct MetalInitialContents
{
MetalInitialContents()
{
RDCCOMPILE_ASSERT(std::is_standard_layout<MetalInitialContents>::value,
"MetalInitialContents must be POD");
memset(this, 0, sizeof(*this));
}
MetalInitialContents(MetalResourceType t)
{
memset(this, 0, sizeof(*this));
type = t;
}
template <typename Configuration>
void Free(ResourceManager<Configuration> *rm)
{
RDCASSERT(false);
}
bytebuf resourceContents;
// for plain resources, we store the resource type
MetalResourceType type;
};
struct MetalResourceManagerConfiguration
{
typedef WrappedMTLObject *WrappedResourceType;
typedef void *RealResourceType;
typedef MetalResourceRecord RecordType;
typedef MetalInitialContents InitialContentData;
};
class MetalResourceManager : public ResourceManager<MetalResourceManagerConfiguration>
{
public:
MetalResourceManager(CaptureState &state, WrappedMTLDevice *device)
: ResourceManager(state), m_WrappedMTLDevice(device)
{
}
void SetState(CaptureState state) { m_State = state; }
CaptureState GetState() { return m_State; }
~MetalResourceManager() {}
void ClearWithoutReleasing()
{
// if any objects leaked past, it's no longer safe to delete them as we would
// be calling Shutdown() after the device that owns them is destroyed. Instead
// we just have to leak ourselves.
RDCASSERT(m_LiveResourceMap.empty());
RDCASSERT(m_InitialContents.empty());
RDCASSERT(m_ResourceRecords.empty());
RDCASSERT(m_CurrentResourceMap.empty());
RDCASSERT(m_WrapperMap.empty());
m_LiveResourceMap.clear();
m_InitialContents.clear();
m_ResourceRecords.clear();
m_CurrentResourceMap.clear();
m_WrapperMap.clear();
}
// ResourceManager interface
ResourceId GetID(WrappedMTLObject *res)
{
if(res == NULL)
return ResourceId();
return res->id;
}
// ResourceManager interface
template <typename realtype>
ResourceId WrapResource(realtype obj, typename UnwrapHelper<realtype>::Outer *&wrapped)
{
RDCASSERT(obj != NULL);
RDCASSERT(m_WrappedMTLDevice != NULL);
ResourceId id = ResourceIDGen::GetNewUniqueID();
using WrappedType = typename UnwrapHelper<realtype>::Outer;
wrapped = new WrappedType(obj, id, m_WrappedMTLDevice);
wrapped->real = obj;
AddCurrentResource(id, wrapped);
// TODO: implement RD MTL replay
// if(IsReplayMode(m_State))
// AddWrapper(wrapMetalResourceManager(obj));
return id;
}
using ResourceManager::AddResourceRecord;
template <typename wrappedtype>
MetalResourceRecord *AddResourceRecord(wrappedtype *wrapped)
{
MetalResourceRecord *ret = wrapped->record = ResourceManager::AddResourceRecord(wrapped->id);
ret->Resource = (WrappedMTLObject *)wrapped;
ret->resType = (MetalResourceType)wrappedtype::TypeEnum;
return ret;
}
// ResourceRecordHandler interface implemented in ResourceManager
// void MarkDirtyResource(ResourceId id);
// void RemoveResourceRecord(ResourceId id);
// void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType);
// void DestroyResourceRecord(ResourceRecord *record);
// ResourceRecordHandler interface
private:
// ResourceManager interface
bool ResourceTypeRelease(WrappedMTLObject *res);
bool Prepare_InitialState(WrappedMTLObject *res);
uint64_t GetSize_InitialState(ResourceId id, const MetalInitialContents &initial);
bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, MetalResourceRecord *record,
const MetalInitialContents *initial);
void Create_InitialState(ResourceId id, WrappedMTLObject *live, bool hasData);
void Apply_InitialState(WrappedMTLObject *live, const MetalInitialContents &initial);
// ResourceManager interface
WrappedMTLDevice *m_WrappedMTLDevice;
};
+6 -1
View File
@@ -38,9 +38,14 @@ void WrappedMTLObject::Dealloc()
// TODO: call the wrapped object destructor
}
MetalResourceManager *WrappedMTLObject::GetResourceManager()
{
return m_WrappedMTLDevice->GetResourceManager();
}
MTL::Device *WrappedMTLObject::GetObjCWrappedMTLDevice()
{
return UnwrapObjC<MTL::Device *>(m_WrappedMTLDevice);
return GetObjC<MTL::Device *>(m_WrappedMTLDevice);
}
MetalResourceRecord::~MetalResourceRecord()
+43 -5
View File
@@ -26,9 +26,11 @@
#include "core/resource_manager.h"
#include "metal_common.h"
#include "metal_types.h"
struct MetalResourceRecord;
class WrappedMTLDevice;
class MetalResourceManager;
enum MetalResourceType
{
@@ -44,7 +46,7 @@ struct WrappedMTLObject
{
WrappedMTLObject() = delete;
WrappedMTLObject(WrappedMTLDevice *wrappedMTLDevice, CaptureState &captureState)
: wrappedObjC(NULL),
: objc(NULL),
real(NULL),
record(NULL),
m_WrappedMTLDevice(wrappedMTLDevice),
@@ -53,7 +55,7 @@ struct WrappedMTLObject
}
WrappedMTLObject(void *mtlObject, ResourceId objId, WrappedMTLDevice *wrappedMTLDevice,
CaptureState &captureState)
: wrappedObjC(NULL),
: objc(NULL),
real(mtlObject),
id(objId),
record(NULL),
@@ -67,7 +69,9 @@ struct WrappedMTLObject
MTL::Device *GetObjCWrappedMTLDevice();
void *wrappedObjC;
MetalResourceManager *GetResourceManager();
void *objc;
void *real;
ResourceId id;
MetalResourceRecord *record;
@@ -77,6 +81,15 @@ struct WrappedMTLObject
ResourceId GetResID(WrappedMTLObject *obj);
template <typename WrappedType>
MetalResourceRecord *GetRecord(WrappedType *obj)
{
if(obj == NULL)
return NULL;
return obj->record;
}
template <typename RealType>
RealType Unwrap(WrappedMTLObject *obj)
{
@@ -87,14 +100,39 @@ RealType Unwrap(WrappedMTLObject *obj)
}
template <typename RealType>
RealType UnwrapObjC(WrappedMTLObject *obj)
RealType GetObjC(WrappedMTLObject *obj)
{
if(obj == NULL)
return RealType();
return (RealType)obj->wrappedObjC;
return (RealType)obj->objc;
}
// template magic voodoo to unwrap types
template <typename inner>
struct UnwrapHelper
{
};
#define UNWRAP_HELPER(CPPTYPE) \
template <> \
struct UnwrapHelper<MTL::CPPTYPE *> \
{ \
typedef CONCAT(WrappedMTL, CPPTYPE) Outer; \
};
METALCPP_WRAPPED_PROTOCOLS(UNWRAP_HELPER)
#undef UNWRAP_HELPER
#define IMPLEMENT_WRAPPED_TYPE_UNWRAP(CPPTYPE) \
inline MTL::CPPTYPE *Unwrap(WrappedMTL##CPPTYPE *obj) \
{ \
return Unwrap<MTL::CPPTYPE *>((WrappedMTLObject *)obj); \
}
METALCPP_WRAPPED_PROTOCOLS(IMPLEMENT_WRAPPED_TYPE_UNWRAP)
#undef IMPLEMENT_WRAPPED_TYPE_UNWRAP
struct MetalResourceRecord : public ResourceRecord
{
public:
+3 -1
View File
@@ -24,7 +24,9 @@
#pragma once
#include "metal_common.h"
#include "api/replay/rdcstr.h"
#include "official/metal-cpp.h"
#include "serialise/serialiser.h"
#define METALCPP_WRAPPED_PROTOCOLS(FUNC) \
FUNC(Device); \
@@ -24,9 +24,50 @@
#include "metal_types_bridge.h"
#include "metal_device.h"
#include "metal_function.h"
#include "metal_library.h"
#define DEFINE_OBJC_HELPERS(CPPTYPE) \
static ObjCWrappedMTL##CPPTYPE *GetObjC(MTL::CPPTYPE *cppType) \
{ \
if(cppType == NULL) \
{ \
return NULL; \
} \
ObjCWrappedMTL##CPPTYPE *objC = (ObjCWrappedMTL##CPPTYPE *)cppType; \
RDCASSERT([objC isKindOfClass:[ObjCWrappedMTL##CPPTYPE class]]); \
return objC; \
} \
\
WrappedMTL##CPPTYPE *GetWrapped(MTL::CPPTYPE *cppType) \
{ \
ObjCWrappedMTL##CPPTYPE *objC = GetObjC(cppType); \
return objC.wrappedCPP; \
} \
\
MTL::CPPTYPE *GetReal(MTL::CPPTYPE *cppType) \
{ \
ObjCWrappedMTL##CPPTYPE *objC = GetObjC(cppType); \
MTL::CPPTYPE *real = (MTL::CPPTYPE *)objC.real; \
return real; \
} \
\
bool IsObjCWrapped(MTL::CPPTYPE *cppType) \
{ \
ObjCWrappedMTL##CPPTYPE *objC = (ObjCWrappedMTL##CPPTYPE *)cppType; \
return [objC isKindOfClass:[ObjCWrappedMTL##CPPTYPE class]]; \
} \
\
ResourceId GetId(MTL::CPPTYPE *cppType) \
{ \
WrappedMTL##CPPTYPE *wrappedCPP = GetWrapped(cppType); \
if(wrappedCPP == NULL) \
{ \
return ResourceId(); \
} \
return wrappedCPP->id; \
} \
\
MTL::CPPTYPE *AllocateObjCWrapper(WrappedMTL##CPPTYPE *wrappedCPP) \
{ \
ObjCWrappedMTL##CPPTYPE *objC = [ObjCWrappedMTL##CPPTYPE alloc]; \