From ecb75feddba8f60a32ecdf4b56c217aad1b306ef Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Sun, 20 Mar 2022 07:12:14 +0000 Subject: [PATCH] Added wrapped MTLCommandBuffer Implemented capture serialisation for MTLCommandQueue::commandBuffer MTLCommandBuffer::presentDrawable MTLCommandBuffer::commit --- renderdoc/driver/metal/CMakeLists.txt | 3 + .../driver/metal/metal_command_buffer.cpp | 122 ++++++++ renderdoc/driver/metal/metal_command_buffer.h | 63 ++++ .../metal/metal_command_buffer_bridge.mm | 278 ++++++++++++++++++ .../driver/metal/metal_command_queue.cpp | 56 ++++ renderdoc/driver/metal/metal_command_queue.h | 4 + .../metal/metal_command_queue_bridge.mm | 3 +- renderdoc/driver/metal/metal_common.h | 23 ++ renderdoc/driver/metal/metal_resources.cpp | 3 + renderdoc/driver/metal/metal_resources.h | 26 +- renderdoc/driver/metal/metal_types.cpp | 1 + renderdoc/driver/metal/metal_types.h | 1 + renderdoc/driver/metal/metal_types_bridge.mm | 1 + 13 files changed, 581 insertions(+), 3 deletions(-) create mode 100644 renderdoc/driver/metal/metal_command_buffer.cpp create mode 100644 renderdoc/driver/metal/metal_command_buffer.h create mode 100644 renderdoc/driver/metal/metal_command_buffer_bridge.mm diff --git a/renderdoc/driver/metal/CMakeLists.txt b/renderdoc/driver/metal/CMakeLists.txt index 2a5dd4e4f..1a41923e3 100644 --- a/renderdoc/driver/metal/CMakeLists.txt +++ b/renderdoc/driver/metal/CMakeLists.txt @@ -23,6 +23,9 @@ set(sources metal_command_queue.cpp metal_command_queue.h metal_command_queue_bridge.mm + metal_command_buffer.cpp + metal_command_buffer.h + metal_command_buffer_bridge.mm metal_core.cpp metal_core.h metal_manager.cpp diff --git a/renderdoc/driver/metal/metal_command_buffer.cpp b/renderdoc/driver/metal/metal_command_buffer.cpp new file mode 100644 index 000000000..d6c4dfaed --- /dev/null +++ b/renderdoc/driver/metal/metal_command_buffer.cpp @@ -0,0 +1,122 @@ +/****************************************************************************** + * 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_command_buffer.h" +#include "core/settings.h" +#include "metal_device.h" +#include "metal_resources.h" + +WrappedMTLCommandBuffer::WrappedMTLCommandBuffer(MTL::CommandBuffer *realMTLCommandBuffer, + ResourceId objId, WrappedMTLDevice *wrappedMTLDevice) + : WrappedMTLObject(realMTLCommandBuffer, objId, wrappedMTLDevice, wrappedMTLDevice->GetStateRef()) +{ + objcBridge = AllocateObjCBridge(this); +} + +template +bool WrappedMTLCommandBuffer::Serialise_presentDrawable(SerialiserType &ser, MTL::Drawable *drawable) +{ + SERIALISE_ELEMENT_LOCAL(CommandBuffer, this); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLCommandBuffer::presentDrawable(MTL::Drawable *drawable) +{ + SERIALISE_TIME_CALL(Unwrap(this)->presentDrawable(drawable)); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLCommandBuffer_presentDrawable); + Serialise_presentDrawable(ser, drawable); + chunk = scope.Get(); + } + MetalResourceRecord *record = GetRecord(this); + record->AddChunk(chunk); + record->cmdInfo->present = true; + record->cmdInfo->drawable = drawable; + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLCommandBuffer::Serialise_commit(SerialiserType &ser) +{ + SERIALISE_ELEMENT_LOCAL(CommandBuffer, this); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + CommandBuffer->commit(); + } + return true; +} + +void WrappedMTLCommandBuffer::commit() +{ + SERIALISE_TIME_CALL(Unwrap(this)->commit()); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLCommandBuffer_commit); + Serialise_commit(ser); + chunk = scope.Get(); + } + GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_WrappedMTLCommandQueue), + eFrameRef_Read); + MetalResourceRecord *queueRecord = GetRecord(m_WrappedMTLCommandQueue); + MetalResourceRecord *record = GetRecord(this); + record->AddParent(queueRecord); + record->AddChunk(chunk); + + bool capframe = IsActiveCapturing(m_State); + if(capframe) + { + record->AddRef(); + } + } + else + { + // TODO: implement RD MTL replay + } +} + +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLCommandBuffer, void, presentDrawable, + MTL::Drawable *drawable); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLCommandBuffer, void, commit); diff --git a/renderdoc/driver/metal/metal_command_buffer.h b/renderdoc/driver/metal/metal_command_buffer.h new file mode 100644 index 000000000..434bf3e04 --- /dev/null +++ b/renderdoc/driver/metal/metal_command_buffer.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * 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_command_queue.h" +#include "metal_common.h" +#include "metal_device.h" +#include "metal_resources.h" + +class WrappedMTLCommandBuffer : public WrappedMTLObject +{ +public: + WrappedMTLCommandBuffer(MTL::CommandBuffer *realMTLCommandBuffer, ResourceId objId, + WrappedMTLDevice *wrappedMTLDevice); + + void SetWrappedMTLCommandQueue(WrappedMTLCommandQueue *wrappedMTLCommandQueue); + + MTL::CommandQueue *GetObjCBridgeMTLCommandQueue(); + + DECLARE_FUNCTION_SERIALISED(void, presentDrawable, MTL::Drawable *drawable); + DECLARE_FUNCTION_SERIALISED(void, commit); + + enum + { + TypeEnum = eResCommandBuffer + }; + +private: + WrappedMTLCommandQueue *m_WrappedMTLCommandQueue; +}; + +inline MTL::CommandQueue *WrappedMTLCommandBuffer::GetObjCBridgeMTLCommandQueue() +{ + return GetObjCBridge(m_WrappedMTLCommandQueue); +} + +inline void WrappedMTLCommandBuffer::SetWrappedMTLCommandQueue( + WrappedMTLCommandQueue *wrappedMTLCommandQueue) +{ + m_WrappedMTLCommandQueue = wrappedMTLCommandQueue; +} diff --git a/renderdoc/driver/metal/metal_command_buffer_bridge.mm b/renderdoc/driver/metal/metal_command_buffer_bridge.mm new file mode 100644 index 000000000..75611ede3 --- /dev/null +++ b/renderdoc/driver/metal/metal_command_buffer_bridge.mm @@ -0,0 +1,278 @@ +/****************************************************************************** + * 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_command_buffer.h" +#include "metal_types_bridge.h" + +// Bridge for MTLCommandBuffer +@implementation ObjCBridgeMTLCommandBuffer + +// ObjCBridgeMTLCommandBuffer specific +- (id)real +{ + return id(Unwrap(self.wrappedCPP)); +} + +- (void)dealloc +{ + self.wrappedCPP->Dealloc(); + [super dealloc]; +} + +// Use the real MTLCommandBuffer to find methods from messages +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + id fwd = self.real; + return [fwd methodSignatureForSelector:aSelector]; +} + +// Forward any unknown messages to the real MTLCommandBuffer +- (void)forwardInvocation:(NSInvocation *)invocation +{ + SEL aSelector = [invocation selector]; + + if([self.real respondsToSelector:aSelector]) + [invocation invokeWithTarget:self.real]; + else + [super forwardInvocation:invocation]; +} + +// MTLCommandBuffer : based on the protocol defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLCommandBuffer.h + +- (id)device +{ + return id(self.wrappedCPP->GetObjCBridgeMTLDevice()); +} + +- (id)commandQueue +{ + return id(self.wrappedCPP->GetObjCBridgeMTLCommandQueue()); +} + +- (BOOL)retainedReferences +{ + return self.real.retainedReferences; +} + +- (MTLCommandBufferErrorOption)errorOptions API_AVAILABLE(macos(11.0), ios(14.0)) +{ + return self.real.errorOptions; +} + +- (NSString *)label +{ + return self.real.label; +} + +- (void)setLabel:value +{ + self.real.label = value; +} + +- (CFTimeInterval)kernelStartTime API_AVAILABLE(macos(10.15), macCatalyst(13.0), ios(10.3)) +{ + return self.real.kernelStartTime; +} + +- (CFTimeInterval)kernelEndTime API_AVAILABLE(macos(10.15), macCatalyst(13.0), ios(10.3)) +{ + return self.real.kernelEndTime; +} + +- (id)logs API_AVAILABLE(macos(11.0), ios(14.0)) +{ + return self.real.logs; +} + +- (CFTimeInterval)GPUStartTime API_AVAILABLE(macos(10.15), macCatalyst(13.0), ios(10.3)) +{ + return self.real.GPUStartTime; +} + +- (CFTimeInterval)GPUEndTime API_AVAILABLE(macos(10.15), macCatalyst(13.0), ios(10.3)) +{ + return self.real.GPUEndTime; +} + +- (void)enqueue +{ + METAL_NOT_HOOKED(); + [self enqueue]; +} + +- (void)commit +{ + self.wrappedCPP->commit(); +} + +- (void)addScheduledHandler:(MTLCommandBufferHandler)block +{ + METAL_NOT_HOOKED(); + return [self.real addScheduledHandler:block]; +} + +- (void)presentDrawable:(id)drawable +{ + self.wrappedCPP->presentDrawable((MTL::Drawable *)drawable); +} + +- (void)presentDrawable:(id)drawable atTime:(CFTimeInterval)presentationTime +{ + METAL_NOT_HOOKED(); + return [self.real presentDrawable:drawable atTime:presentationTime]; +} + +- (void)presentDrawable:(id)drawable + afterMinimumDuration:(CFTimeInterval)duration + API_AVAILABLE(macos(10.15.4), ios(10.3), macCatalyst(13.4)) +{ + METAL_NOT_HOOKED(); + return [self.real presentDrawable:drawable afterMinimumDuration:duration]; +} + +- (void)waitUntilScheduled +{ + METAL_NOT_HOOKED(); + return [self.real waitUntilScheduled]; +} + +- (void)addCompletedHandler:(MTLCommandBufferHandler)block +{ + METAL_NOT_HOOKED(); + return [self.real addCompletedHandler:block]; +} + +- (void)waitUntilCompleted +{ + METAL_NOT_HOOKED(); + return [self.real waitUntilCompleted]; +} + +- (MTLCommandBufferStatus)status +{ + return self.real.status; +} + +- (NSError *)error +{ + return self.real.error; +} + +- (nullable id)blitCommandEncoder +{ + METAL_NOT_HOOKED(); + return [self.real blitCommandEncoder]; +} + +- (nullable id)renderCommandEncoderWithDescriptor: + (MTLRenderPassDescriptor *)renderPassDescriptor +{ + METAL_NOT_HOOKED(); + return [self.real renderCommandEncoderWithDescriptor:renderPassDescriptor]; +} + +- (nullable id)computeCommandEncoderWithDescriptor: + (MTLComputePassDescriptor *)computePassDescriptor API_AVAILABLE(macos(11.0), ios(14.0)) +{ + METAL_NOT_HOOKED(); + return [self.real computeCommandEncoderWithDescriptor:computePassDescriptor]; +} + +- (nullable id)blitCommandEncoderWithDescriptor: + (MTLBlitPassDescriptor *)blitPassDescriptor API_AVAILABLE(macos(11.0), ios(14.0)) +{ + METAL_NOT_HOOKED(); + return [self.real blitCommandEncoderWithDescriptor:blitPassDescriptor]; +} + +- (nullable id)computeCommandEncoder +{ + METAL_NOT_HOOKED(); + return [self.real computeCommandEncoder]; +} + +- (nullable id)computeCommandEncoderWithDispatchType: + (MTLDispatchType)dispatchType API_AVAILABLE(macos(10.14), ios(12.0)) +{ + METAL_NOT_HOOKED(); + return [self.real computeCommandEncoderWithDispatchType:dispatchType]; +} + +- (void)encodeWaitForEvent:(id)event + value:(uint64_t)value API_AVAILABLE(macos(10.14), ios(12.0)) +{ + METAL_NOT_HOOKED(); + return [self.real encodeWaitForEvent:event value:value]; +} + +- (void)encodeSignalEvent:(id)event + value:(uint64_t)value API_AVAILABLE(macos(10.14), ios(12.0)) +{ + METAL_NOT_HOOKED(); + return [self.real encodeSignalEvent:event value:value]; +} + +- (nullable id)parallelRenderCommandEncoderWithDescriptor: + (MTLRenderPassDescriptor *)renderPassDescriptor +{ + METAL_NOT_HOOKED(); + return [self.real parallelRenderCommandEncoderWithDescriptor:renderPassDescriptor]; +} + +- (nullable id)resourceStateCommandEncoder + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0)) +{ + METAL_NOT_HOOKED(); + return [self.real resourceStateCommandEncoder]; +} + +- (nullable id)resourceStateCommandEncoderWithDescriptor: + (MTLResourceStatePassDescriptor *)resourceStatePassDescriptor + API_AVAILABLE(macos(11.0), ios(14.0)) +{ + METAL_NOT_HOOKED(); + return [self.real resourceStateCommandEncoderWithDescriptor:resourceStatePassDescriptor]; +} + +- (nullable id)accelerationStructureCommandEncoder + API_AVAILABLE(macos(11.0), ios(14.0)) +{ + METAL_NOT_HOOKED(); + return [self.real accelerationStructureCommandEncoder]; +} + +- (void)pushDebugGroup:(NSString *)string API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real pushDebugGroup:string]; +} + +- (void)popDebugGroup API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real popDebugGroup]; +} + +@end diff --git a/renderdoc/driver/metal/metal_command_queue.cpp b/renderdoc/driver/metal/metal_command_queue.cpp index 78ab7e5ea..24c763ae6 100644 --- a/renderdoc/driver/metal/metal_command_queue.cpp +++ b/renderdoc/driver/metal/metal_command_queue.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "metal_command_queue.h" +#include "metal_command_buffer.h" #include "metal_device.h" WrappedMTLCommandQueue::WrappedMTLCommandQueue(MTL::CommandQueue *realMTLCommandQueue, @@ -31,3 +32,58 @@ WrappedMTLCommandQueue::WrappedMTLCommandQueue(MTL::CommandQueue *realMTLCommand { objcBridge = AllocateObjCBridge(this); } + +template +bool WrappedMTLCommandQueue::Serialise_commandBuffer(SerialiserType &ser, + WrappedMTLCommandBuffer *buffer) +{ + SERIALISE_ELEMENT_LOCAL(CommandQueue, this); + SERIALISE_ELEMENT_LOCAL(CommandBuffer, GetResID(buffer)).TypedAs("MTLCommandBuffer"_lit); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // TODO: implement RD MTL replay + } + return true; +} + +WrappedMTLCommandBuffer *WrappedMTLCommandQueue::commandBuffer() +{ + MTL::CommandBuffer *realMTLCommandBuffer; + SERIALISE_TIME_CALL(realMTLCommandBuffer = Unwrap(this)->commandBuffer()); + WrappedMTLCommandBuffer *wrappedMTLCommandBuffer; + ResourceId id = GetResourceManager()->WrapResource(realMTLCommandBuffer, wrappedMTLCommandBuffer); + wrappedMTLCommandBuffer->SetWrappedMTLCommandQueue(this); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLCommandQueue_commandBuffer); + Serialise_commandBuffer(ser, wrappedMTLCommandBuffer); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = + GetResourceManager()->AddResourceRecord(wrappedMTLCommandBuffer); + bufferRecord->AddChunk(chunk); + bufferRecord->cmdInfo = new MetalResources::CmdBufferRecordingInfo(); + bufferRecord->cmdInfo->queue = this; + bufferRecord->cmdInfo->device = m_WrappedMTLDevice; + bufferRecord->cmdInfo->present = false; + bufferRecord->cmdInfo->isEncoding = false; + bufferRecord->cmdInfo->drawable = NULL; + } + else + { + // TODO: implement RD MTL replay + GetResourceManager()->AddLiveResource(id, wrappedMTLCommandBuffer); + } + + return wrappedMTLCommandBuffer; +} + +INSTANTIATE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLCommandQueue, WrappedMTLCommandBuffer *, + commandBuffer); diff --git a/renderdoc/driver/metal/metal_command_queue.h b/renderdoc/driver/metal/metal_command_queue.h index ff41aade7..9fc4abc05 100644 --- a/renderdoc/driver/metal/metal_command_queue.h +++ b/renderdoc/driver/metal/metal_command_queue.h @@ -26,12 +26,16 @@ #include "metal_common.h" +class WrappedMTLCommandBuffer; + class WrappedMTLCommandQueue : public WrappedMTLObject { public: WrappedMTLCommandQueue(MTL::CommandQueue *realMTLCommandQueue, ResourceId objId, WrappedMTLDevice *wrappedMTLDevice); + DECLARE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLCommandBuffer *, commandBuffer); + enum { TypeEnum = eResCommandQueue diff --git a/renderdoc/driver/metal/metal_command_queue_bridge.mm b/renderdoc/driver/metal/metal_command_queue_bridge.mm index 09b90b859..d9505621c 100644 --- a/renderdoc/driver/metal/metal_command_queue_bridge.mm +++ b/renderdoc/driver/metal/metal_command_queue_bridge.mm @@ -78,8 +78,7 @@ - (nullable id)commandBuffer { - METAL_NOT_HOOKED(); - return [self.real commandBuffer]; + return id(GetObjCBridge(self.wrappedCPP->commandBuffer())); } - (nullable id)commandBufferWithDescriptor:(MTLCommandBufferDescriptor *)descriptor diff --git a/renderdoc/driver/metal/metal_common.h b/renderdoc/driver/metal/metal_common.h index 01c1a2bba..fd257de65 100644 --- a/renderdoc/driver/metal/metal_common.h +++ b/renderdoc/driver/metal/metal_common.h @@ -80,6 +80,29 @@ enum class MetalChunk : uint32_t MTLCommandQueue_commandBuffer, MTLCommandQueue_commandBufferWithDescriptor, MTLCommandQueue_commandBufferWithUnretainedReferences, + MTLCommandBuffer_enqueue, + MTLCommandBuffer_commit, + MTLCommandBuffer_addScheduledHandler, + MTLCommandBuffer_presentDrawable, + MTLCommandBuffer_presentDrawable_atTime, + MTLCommandBuffer_presentDrawable_afterMinimumDuration, + MTLCommandBuffer_waitUntilScheduled, + MTLCommandBuffer_addCompletedHandler, + MTLCommandBuffer_waitUntilCompleted, + MTLCommandBuffer_blitCommandEncoder, + MTLCommandBuffer_renderCommandEncoderWithDescriptor, + MTLCommandBuffer_computeCommandEncoderWithDescriptor, + MTLCommandBuffer_blitCommandEncoderWithDescriptor, + MTLCommandBuffer_computeCommandEncoder, + MTLCommandBuffer_computeCommandEncoderWithDispatchType, + MTLCommandBuffer_encodeWaitForEvent, + MTLCommandBuffer_encodeSignalEvent, + MTLCommandBuffer_parallelRenderCommandEncoderWithDescriptor, + MTLCommandBuffer_resourceStateCommandEncoder, + MTLCommandBuffer_resourceStateCommandEncoderWithDescriptor, + MTLCommandBuffer_accelerationStructureCommandEncoder, + MTLCommandBuffer_pushDebugGroup, + MTLCommandBuffer_popDebugGroup, Max }; diff --git a/renderdoc/driver/metal/metal_resources.cpp b/renderdoc/driver/metal/metal_resources.cpp index 7dfae74ce..2a4a30719 100644 --- a/renderdoc/driver/metal/metal_resources.cpp +++ b/renderdoc/driver/metal/metal_resources.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "metal_resources.h" +#include "metal_command_buffer.h" #include "metal_command_queue.h" #include "metal_device.h" #include "metal_function.h" @@ -63,4 +64,6 @@ MTL::Device *WrappedMTLObject::GetObjCBridgeMTLDevice() MetalResourceRecord::~MetalResourceRecord() { + if(resType == eResCommandBuffer) + SAFE_DELETE(cmdInfo); } diff --git a/renderdoc/driver/metal/metal_resources.h b/renderdoc/driver/metal/metal_resources.h index 4fe7cb524..01dedf951 100644 --- a/renderdoc/driver/metal/metal_resources.h +++ b/renderdoc/driver/metal/metal_resources.h @@ -35,6 +35,7 @@ class MetalResourceManager; enum MetalResourceType { eResUnknown = 0, + eResCommandBuffer, eResCommandQueue, eResDevice, eResLibrary, @@ -127,6 +128,28 @@ struct UnwrapHelper METALCPP_WRAPPED_PROTOCOLS(WRAPPED_TYPE_HELPERS) #undef WRAPPED_TYPE_HELPERS +namespace MetalResources +{ +struct CmdBufferRecordingInfo +{ + CmdBufferRecordingInfo() = default; + CmdBufferRecordingInfo(const CmdBufferRecordingInfo &) = delete; + CmdBufferRecordingInfo(CmdBufferRecordingInfo &&) = delete; + CmdBufferRecordingInfo &operator=(const CmdBufferRecordingInfo &) = delete; + ~CmdBufferRecordingInfo() {} + WrappedMTLCommandQueue *queue; + WrappedMTLDevice *device; + + // The drawable that present was called on + MTL::Drawable *drawable; + // AdvanceFrame/Present should be called after this buffer is committed. + bool present; + // an encoder is active : waiting for endEncoding to be called + bool isEncoding; +}; + +}; // namespace MetalResources + struct MetalResourceRecord : public ResourceRecord { public: @@ -146,6 +169,7 @@ public: // Each entry is only used by specific record types union { - void *ptrUnion; // for initialisation to NULL + void *ptrUnion; // for initialisation to NULL + MetalResources::CmdBufferRecordingInfo *cmdInfo; // only for command buffers }; }; diff --git a/renderdoc/driver/metal/metal_types.cpp b/renderdoc/driver/metal/metal_types.cpp index 27d2f558b..a577bc0e0 100644 --- a/renderdoc/driver/metal/metal_types.cpp +++ b/renderdoc/driver/metal/metal_types.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "metal_types.h" +#include "metal_command_buffer.h" #include "metal_command_queue.h" #include "metal_device.h" #include "metal_function.h" diff --git a/renderdoc/driver/metal/metal_types.h b/renderdoc/driver/metal/metal_types.h index 625910e3a..3fe7f2a12 100644 --- a/renderdoc/driver/metal/metal_types.h +++ b/renderdoc/driver/metal/metal_types.h @@ -29,6 +29,7 @@ #include "serialise/serialiser.h" #define METALCPP_WRAPPED_PROTOCOLS(FUNC) \ + FUNC(CommandBuffer); \ FUNC(CommandQueue); \ FUNC(Device); \ FUNC(Function); \ diff --git a/renderdoc/driver/metal/metal_types_bridge.mm b/renderdoc/driver/metal/metal_types_bridge.mm index b91f9bff8..6d6645bcf 100644 --- a/renderdoc/driver/metal/metal_types_bridge.mm +++ b/renderdoc/driver/metal/metal_types_bridge.mm @@ -23,6 +23,7 @@ ******************************************************************************/ #include "metal_types_bridge.h" +#include "metal_command_buffer.h" #include "metal_command_queue.h" #include "metal_device.h" #include "metal_function.h"