mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-13 13:30:44 +00:00
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:
committed by
Baldur Karlsson
parent
d79617cb46
commit
88a2b3d74a
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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]; \
|
||||
|
||||
Reference in New Issue
Block a user