diff --git a/renderdoc/driver/metal/metal_resources.cpp b/renderdoc/driver/metal/metal_resources.cpp index 9fceff759..7dfae74ce 100644 --- a/renderdoc/driver/metal/metal_resources.cpp +++ b/renderdoc/driver/metal/metal_resources.cpp @@ -23,7 +23,10 @@ ******************************************************************************/ #include "metal_resources.h" +#include "metal_command_queue.h" #include "metal_device.h" +#include "metal_function.h" +#include "metal_library.h" ResourceId GetResID(WrappedMTLObject *obj) { @@ -33,6 +36,16 @@ ResourceId GetResID(WrappedMTLObject *obj) return obj->id; } +#define IMPLEMENT_WRAPPED_TYPE_HELPERS(CPPTYPE) \ + MTL::CPPTYPE *Unwrap(WrappedMTL##CPPTYPE *obj) { return Unwrap(obj); } \ + MTL::CPPTYPE *GetObjCBridge(WrappedMTL##CPPTYPE *obj) \ + { \ + return GetObjCBridge(obj); \ + } + +METALCPP_WRAPPED_PROTOCOLS(IMPLEMENT_WRAPPED_TYPE_HELPERS) +#undef IMPLEMENT_WRAPPED_TYPE_HELPERS + void WrappedMTLObject::Dealloc() { // TODO: call the wrapped object destructor @@ -45,7 +58,7 @@ MetalResourceManager *WrappedMTLObject::GetResourceManager() MTL::Device *WrappedMTLObject::GetObjCBridgeMTLDevice() { - return GetObjCBridge(m_WrappedMTLDevice); + return GetObjCBridge(m_WrappedMTLDevice); } MetalResourceRecord::~MetalResourceRecord() diff --git a/renderdoc/driver/metal/metal_resources.h b/renderdoc/driver/metal/metal_resources.h index 4cdb68505..4fe7cb524 100644 --- a/renderdoc/driver/metal/metal_resources.h +++ b/renderdoc/driver/metal/metal_resources.h @@ -115,24 +115,17 @@ struct UnwrapHelper { }; -#define UNWRAP_HELPER(CPPTYPE) \ - template <> \ - struct UnwrapHelper \ - { \ - typedef CONCAT(WrappedMTL, CPPTYPE) Outer; \ - }; +#define WRAPPED_TYPE_HELPERS(CPPTYPE) \ + template <> \ + struct UnwrapHelper \ + { \ + typedef CONCAT(WrappedMTL, CPPTYPE) Outer; \ + }; \ + extern MTL::CPPTYPE *Unwrap(WrappedMTL##CPPTYPE *obj); \ + extern MTL::CPPTYPE *GetObjCBridge(WrappedMTL##CPPTYPE *obj); -METALCPP_WRAPPED_PROTOCOLS(UNWRAP_HELPER) -#undef UNWRAP_HELPER - -#define IMPLEMENT_WRAPPED_TYPE_UNWRAP(CPPTYPE) \ - inline MTL::CPPTYPE *Unwrap(WrappedMTL##CPPTYPE *obj) \ - { \ - return Unwrap((WrappedMTLObject *)obj); \ - } - -METALCPP_WRAPPED_PROTOCOLS(IMPLEMENT_WRAPPED_TYPE_UNWRAP) -#undef IMPLEMENT_WRAPPED_TYPE_UNWRAP +METALCPP_WRAPPED_PROTOCOLS(WRAPPED_TYPE_HELPERS) +#undef WRAPPED_TYPE_HELPERS struct MetalResourceRecord : public ResourceRecord { diff --git a/renderdoc/driver/metal/metal_types.cpp b/renderdoc/driver/metal/metal_types.cpp index e3d015994..27d2f558b 100644 --- a/renderdoc/driver/metal/metal_types.cpp +++ b/renderdoc/driver/metal/metal_types.cpp @@ -23,11 +23,58 @@ ******************************************************************************/ #include "metal_types.h" +#include "metal_command_queue.h" +#include "metal_device.h" +#include "metal_function.h" +#include "metal_library.h" +#include "metal_manager.h" +#include "metal_resources.h" RDCCOMPILE_ASSERT(sizeof(NS::Integer) == sizeof(std::intptr_t), "NS::Integer size does not match"); RDCCOMPILE_ASSERT(sizeof(NS::UInteger) == sizeof(std::uintptr_t), "NS::UInteger size does not match"); +// serialisation of object handles via IDs. +template +void DoSerialiseViaResourceId(SerialiserType &ser, type &el) +{ + MetalResourceManager *rm = (MetalResourceManager *)ser.GetUserData(); + + ResourceId id; + + if(ser.IsWriting() && rm) + id = GetResID(el); + if(ser.IsStructurising() && rm) + id = rm->GetOriginalID(GetResID(el)); + + DoSerialise(ser, id); + + if(ser.IsReading() && rm && !IsStructuredExporting(rm->GetState())) + { + el = NULL; + + if(id != ResourceId() && rm) + { + if(rm->HasLiveResource(id)) + { + // we leave this wrapped. + el = (type)rm->GetLiveResource(id); + } + } + } +} + +#define IMPLEMENT_WRAPPED_TYPE_SERIALISE(CPPTYPE) \ + template \ + void DoSerialise(SerialiserType &ser, WrappedMTL##CPPTYPE *&el) \ + { \ + DoSerialiseViaResourceId(ser, el); \ + } \ + INSTANTIATE_SERIALISE_TYPE(WrappedMTL##CPPTYPE *); + +METALCPP_WRAPPED_PROTOCOLS(IMPLEMENT_WRAPPED_TYPE_SERIALISE); +#undef IMPLEMENT_WRAPPED_TYPE_SERIALISE + template void DoSerialise(SerialiserType &ser, NS::String *&el) { diff --git a/renderdoc/driver/metal/metal_types.h b/renderdoc/driver/metal/metal_types.h index b5746605f..7c3606d70 100644 --- a/renderdoc/driver/metal/metal_types.h +++ b/renderdoc/driver/metal/metal_types.h @@ -34,6 +34,15 @@ FUNC(Function); \ FUNC(Library); +// These serialise overloads will fetch the ID during capture, serialise the ID +// directly as-if it were the original type, then on replay load up the resource if available. +#define DECLARE_WRAPPED_TYPE_SERIALISE(CPPTYPE) \ + class WrappedMTL##CPPTYPE; \ + DECLARE_REFLECTION_STRUCT(WrappedMTL##CPPTYPE *) + +METALCPP_WRAPPED_PROTOCOLS(DECLARE_WRAPPED_TYPE_SERIALISE); +#undef DECLARE_WRAPPED_TYPE_SERIALISE + #define DECLARE_OBJC_HELPERS(CPPTYPE) \ class WrappedMTL##CPPTYPE; \ extern WrappedMTL##CPPTYPE *GetWrapped(MTL::CPPTYPE *objCWrapped); \