From d257b5016dbece42c4a7ad8b1564f3d80374e725 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Mon, 27 Jun 2022 14:19:07 +0100 Subject: [PATCH] Wrapped MtlBlitCommandEncoder Added temporary implementation of GetWrapped() and Unwrap() for the unimplemented Metal types used by MTLBlitCommandEncoder APIs (MTLFence, MTLIndirectCommandBuffer, MTLCounterSampleBuffer). The API synchronizeResource uses ObjC inheritance for MTLResource, which uses new helper methods for MTLResource without implementing the complete type. MTLResource helper methods: GetResID(), Unwrap(), GetWrapped(). The WrappedMTLResource* is cast to WrappedMTLObject* to get the ID and real resource. For the unimplemented Metal types: MTLFence, MTLIndirectCommandBuffer, MTLCounterSampleBuffer have added temporary implementations of GetWrapped() and Unwrap(). These temporary implementations perform the appropriate casting. There is no actual implementation of the unimplemented wrapped types. These unimplemented wrapped types are a temporary solution to enable the ObjC bridge to be implemented. The APIs related to retrieving GPU counters have been hooked with basic serialization. It is expected the replay and capture will need to be specific ie. capture & serialize the buffer data, then at replay upload the serialized buffer data to the GPU buffer. --- renderdoc/driver/metal/CMakeLists.txt | 3 + .../metal/metal_blit_command_encoder.cpp | 1350 +++++++++++++++++ .../driver/metal/metal_blit_command_encoder.h | 113 ++ .../metal_blit_command_encoder_bridge.mm | 338 +++++ .../driver/metal/metal_command_buffer.cpp | 52 + renderdoc/driver/metal/metal_command_buffer.h | 1 + .../metal/metal_command_buffer_bridge.mm | 3 +- renderdoc/driver/metal/metal_common.h | 36 + renderdoc/driver/metal/metal_resources.cpp | 1 + renderdoc/driver/metal/metal_resources.h | 11 + renderdoc/driver/metal/metal_serialise.cpp | 2 + renderdoc/driver/metal/metal_stringise.cpp | 64 +- renderdoc/driver/metal/metal_types.cpp | 1 + renderdoc/driver/metal/metal_types.h | 16 +- renderdoc/driver/metal/metal_types_bridge.h | 14 + 15 files changed, 2000 insertions(+), 5 deletions(-) create mode 100644 renderdoc/driver/metal/metal_blit_command_encoder.cpp create mode 100644 renderdoc/driver/metal/metal_blit_command_encoder.h create mode 100644 renderdoc/driver/metal/metal_blit_command_encoder_bridge.mm diff --git a/renderdoc/driver/metal/CMakeLists.txt b/renderdoc/driver/metal/CMakeLists.txt index 862032ebb..b84fce41d 100644 --- a/renderdoc/driver/metal/CMakeLists.txt +++ b/renderdoc/driver/metal/CMakeLists.txt @@ -35,6 +35,9 @@ set(sources metal_buffer.cpp metal_buffer.h metal_buffer_bridge.mm + metal_blit_command_encoder.cpp + metal_blit_command_encoder.h + metal_blit_command_encoder_bridge.mm metal_render_command_encoder.cpp metal_render_command_encoder.h metal_render_command_encoder_bridge.mm diff --git a/renderdoc/driver/metal/metal_blit_command_encoder.cpp b/renderdoc/driver/metal/metal_blit_command_encoder.cpp new file mode 100644 index 000000000..1d3eb37c0 --- /dev/null +++ b/renderdoc/driver/metal/metal_blit_command_encoder.cpp @@ -0,0 +1,1350 @@ +/****************************************************************************** + * 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_blit_command_encoder.h" +#include "metal_command_buffer.h" + +WrappedMTLBlitCommandEncoder::WrappedMTLBlitCommandEncoder( + MTL::BlitCommandEncoder *realMTLBlitCommandEncoder, ResourceId objId, + WrappedMTLDevice *wrappedMTLDevice) + : WrappedMTLObject(realMTLBlitCommandEncoder, objId, wrappedMTLDevice, + wrappedMTLDevice->GetStateRef()) +{ + AllocateObjCBridge(this); +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_setLabel(SerialiserType &ser, NS::String *value) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(value).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::setLabel(NS::String *value) +{ + SERIALISE_TIME_CALL(Unwrap(this)->setLabel(value)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_setLabel); + Serialise_setLabel(ser, value); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_endEncoding(SerialiserType &ser) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::endEncoding() +{ + SERIALISE_TIME_CALL(Unwrap(this)->endEncoding()); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_endEncoding); + Serialise_endEncoding(ser); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_insertDebugSignpost(SerialiserType &ser, + NS::String *string) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(string).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::insertDebugSignpost(NS::String *string) +{ + SERIALISE_TIME_CALL(Unwrap(this)->insertDebugSignpost(string)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_insertDebugSignpost); + Serialise_insertDebugSignpost(ser, string); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_pushDebugGroup(SerialiserType &ser, NS::String *string) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(string).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::pushDebugGroup(NS::String *string) +{ + SERIALISE_TIME_CALL(Unwrap(this)->pushDebugGroup(string)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_pushDebugGroup); + Serialise_pushDebugGroup(ser, string); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_popDebugGroup(SerialiserType &ser) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::popDebugGroup() +{ + SERIALISE_TIME_CALL(Unwrap(this)->popDebugGroup()); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_popDebugGroup); + Serialise_popDebugGroup(ser); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_synchronizeResource(SerialiserType &ser, + WrappedMTLResource *resource) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(resource).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::synchronizeResource(WrappedMTLResource *resource) +{ + SERIALISE_TIME_CALL(Unwrap(this)->synchronizeResource(Unwrap(resource))); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_synchronizeResource); + Serialise_synchronizeResource(ser, resource); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_synchronizeTexture(SerialiserType &ser, + WrappedMTLTexture *texture, + NS::UInteger slice, + NS::UInteger level) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + SERIALISE_ELEMENT(slice); + SERIALISE_ELEMENT(level); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::synchronizeTexture(WrappedMTLTexture *texture, + NS::UInteger slice, NS::UInteger level) +{ + SERIALISE_TIME_CALL(Unwrap(this)->synchronizeTexture(Unwrap(texture), slice, level)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_synchronizeTexture); + Serialise_synchronizeTexture(ser, texture, slice, level); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyFromBuffer( + SerialiserType &ser, WrappedMTLBuffer *sourceBuffer, NS::UInteger sourceOffset, + WrappedMTLBuffer *destinationBuffer, NS::UInteger destinationOffset, NS::UInteger size) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(sourceBuffer).Important(); + SERIALISE_ELEMENT(sourceOffset); + SERIALISE_ELEMENT(destinationBuffer).Important(); + SERIALISE_ELEMENT(destinationOffset); + SERIALISE_ELEMENT(size); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::copyFromBuffer(WrappedMTLBuffer *sourceBuffer, + NS::UInteger sourceOffset, + WrappedMTLBuffer *destinationBuffer, + NS::UInteger destinationOffset, NS::UInteger size) +{ + SERIALISE_TIME_CALL(Unwrap(this)->copyFromBuffer( + Unwrap(sourceBuffer), sourceOffset, Unwrap(destinationBuffer), destinationOffset, size)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_copyFromBuffer_toBuffer); + Serialise_endEncoding(ser); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyFromBuffer( + SerialiserType &ser, WrappedMTLBuffer *sourceBuffer, NS::UInteger sourceOffset, + NS::UInteger sourceBytesPerRow, NS::UInteger sourceBytesPerImage, MTL::Size &sourceSize, + WrappedMTLTexture *destinationTexture, NS::UInteger destinationSlice, + NS::UInteger destinationLevel, MTL::Origin &destinationOrigin, MTL::BlitOption options) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(sourceBuffer).Important(); + SERIALISE_ELEMENT(sourceOffset); + SERIALISE_ELEMENT(sourceBytesPerRow); + SERIALISE_ELEMENT(sourceBytesPerImage); + SERIALISE_ELEMENT(sourceSize); + SERIALISE_ELEMENT(destinationTexture).Important(); + SERIALISE_ELEMENT(destinationSlice); + SERIALISE_ELEMENT(destinationLevel); + SERIALISE_ELEMENT(destinationOrigin); + SERIALISE_ELEMENT(options); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::copyFromBuffer( + WrappedMTLBuffer *sourceBuffer, NS::UInteger sourceOffset, NS::UInteger sourceBytesPerRow, + NS::UInteger sourceBytesPerImage, MTL::Size &sourceSize, WrappedMTLTexture *destinationTexture, + NS::UInteger destinationSlice, NS::UInteger destinationLevel, MTL::Origin &destinationOrigin, + MTL::BlitOption options) +{ + SERIALISE_TIME_CALL(Unwrap(this)->copyFromBuffer( + Unwrap(sourceBuffer), sourceOffset, sourceBytesPerRow, sourceBytesPerImage, sourceSize, + Unwrap(destinationTexture), destinationSlice, destinationLevel, destinationOrigin, options)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_copyFromBuffer_toTexture_options); + Serialise_copyFromBuffer(ser, sourceBuffer, sourceOffset, sourceBytesPerRow, + sourceBytesPerImage, sourceSize, destinationTexture, + destinationSlice, destinationLevel, destinationOrigin, options); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyFromTexture( + SerialiserType &ser, WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, + NS::UInteger sourceLevel, MTL::Origin &sourceOrigin, MTL::Size &sourceSize, + WrappedMTLTexture *destinationTexture, NS::UInteger destinationSlice, + NS::UInteger destinationLevel, MTL::Origin &destinationOrigin) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(sourceTexture).Important(); + SERIALISE_ELEMENT(sourceSlice); + SERIALISE_ELEMENT(sourceLevel); + SERIALISE_ELEMENT(sourceOrigin); + SERIALISE_ELEMENT(sourceSize); + SERIALISE_ELEMENT(destinationTexture).Important(); + SERIALISE_ELEMENT(destinationSlice); + SERIALISE_ELEMENT(destinationLevel); + SERIALISE_ELEMENT(destinationOrigin); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::copyFromTexture( + WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, NS::UInteger sourceLevel, + MTL::Origin &sourceOrigin, MTL::Size &sourceSize, WrappedMTLTexture *destinationTexture, + NS::UInteger destinationSlice, NS::UInteger destinationLevel, MTL::Origin &destinationOrigin) +{ + SERIALISE_TIME_CALL(Unwrap(this)->copyFromTexture( + Unwrap(sourceTexture), sourceSlice, sourceLevel, sourceOrigin, sourceSize, + Unwrap(destinationTexture), destinationSlice, destinationLevel, destinationOrigin)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK( + MetalChunk::MTLBlitCommandEncoder_copyFromTexture_toTexture_slice_level_origin); + Serialise_copyFromTexture(ser, sourceTexture, sourceSlice, sourceLevel, sourceOrigin, + sourceSize, destinationTexture, destinationSlice, destinationLevel, + destinationOrigin); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyFromTexture( + SerialiserType &ser, WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, + NS::UInteger sourceLevel, MTL::Origin &sourceOrigin, MTL::Size &sourceSize, + WrappedMTLBuffer *destinationBuffer, NS::UInteger destinationOffset, + NS::UInteger destinationBytesPerRow, NS::UInteger destinationBytesPerImage, + MTL::BlitOption options) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(sourceTexture).Important(); + SERIALISE_ELEMENT(sourceSlice); + SERIALISE_ELEMENT(sourceLevel); + SERIALISE_ELEMENT(sourceOrigin); + SERIALISE_ELEMENT(sourceSize); + SERIALISE_ELEMENT(destinationBuffer).Important(); + SERIALISE_ELEMENT(destinationOffset); + SERIALISE_ELEMENT(destinationBytesPerRow); + SERIALISE_ELEMENT(destinationBytesPerImage); + SERIALISE_ELEMENT(options); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::copyFromTexture( + WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, NS::UInteger sourceLevel, + MTL::Origin &sourceOrigin, MTL::Size &sourceSize, WrappedMTLBuffer *destinationBuffer, + NS::UInteger destinationOffset, NS::UInteger destinationBytesPerRow, + NS::UInteger destinationBytesPerImage, MTL::BlitOption options) +{ + SERIALISE_TIME_CALL( + Unwrap(this)->copyFromTexture(Unwrap(sourceTexture), sourceSlice, sourceLevel, sourceOrigin, + sourceSize, Unwrap(destinationBuffer), destinationOffset, + destinationBytesPerRow, destinationBytesPerImage, options)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_copyFromTexture_toBuffer_options); + Serialise_copyFromTexture(ser, sourceTexture, sourceSlice, sourceLevel, sourceOrigin, + sourceSize, destinationBuffer, destinationOffset, + destinationBytesPerRow, destinationBytesPerImage, options); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyFromTexture(SerialiserType &ser, + WrappedMTLTexture *sourceTexture, + WrappedMTLTexture *destinationTexture) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(sourceTexture).Important(); + SERIALISE_ELEMENT(destinationTexture).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::copyFromTexture(WrappedMTLTexture *sourceTexture, + WrappedMTLTexture *destinationTexture) +{ + SERIALISE_TIME_CALL( + Unwrap(this)->copyFromTexture(Unwrap(sourceTexture), Unwrap(destinationTexture))); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_copyFromTexture_toTexture); + Serialise_copyFromTexture(ser, sourceTexture, destinationTexture); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyFromTexture( + SerialiserType &ser, WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, + NS::UInteger sourceLevel, WrappedMTLTexture *destinationTexture, NS::UInteger destinationSlice, + NS::UInteger destinationLevel, NS::UInteger sliceCount, NS::UInteger levelCount) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(sourceTexture).Important(); + SERIALISE_ELEMENT(sourceSlice); + SERIALISE_ELEMENT(sourceLevel); + SERIALISE_ELEMENT(destinationTexture).Important(); + SERIALISE_ELEMENT(destinationSlice); + SERIALISE_ELEMENT(destinationLevel); + SERIALISE_ELEMENT(sliceCount); + SERIALISE_ELEMENT(levelCount); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::copyFromTexture(WrappedMTLTexture *sourceTexture, + NS::UInteger sourceSlice, NS::UInteger sourceLevel, + WrappedMTLTexture *destinationTexture, + NS::UInteger destinationSlice, + NS::UInteger destinationLevel, + NS::UInteger sliceCount, NS::UInteger levelCount) +{ + SERIALISE_TIME_CALL(Unwrap(this)->copyFromTexture(Unwrap(sourceTexture), sourceSlice, sourceLevel, + Unwrap(destinationTexture), destinationSlice, + destinationLevel, sliceCount, levelCount)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK( + MetalChunk::MTLBlitCommandEncoder_copyFromTexture_toTexture_slice_level_count); + Serialise_copyFromTexture(ser, sourceTexture, sourceSlice, sourceLevel, destinationTexture, + destinationSlice, destinationLevel, sliceCount, levelCount); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_generateMipmapsForTexture(SerialiserType &ser, + WrappedMTLTexture *texture) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::generateMipmapsForTexture(WrappedMTLTexture *texture) +{ + SERIALISE_TIME_CALL(Unwrap(this)->generateMipmaps(Unwrap(texture))); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_generateMipmapsForTexture); + Serialise_generateMipmapsForTexture(ser, texture); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_fillBuffer(SerialiserType &ser, WrappedMTLBuffer *buffer, + NS::Range &range, uint8_t value) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(buffer).Important(); + SERIALISE_ELEMENT(range); + SERIALISE_ELEMENT(value).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::fillBuffer(WrappedMTLBuffer *buffer, NS::Range &range, + uint8_t value) +{ + SERIALISE_TIME_CALL(Unwrap(this)->fillBuffer(Unwrap(buffer), range, value)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_fillBuffer); + Serialise_fillBuffer(ser, buffer, range, value); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_updateFence(SerialiserType &ser, WrappedMTLFence *fence) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // TODO: when WrappedMTLFence exists + // SERIALISE_ELEMENT(fence).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::updateFence(WrappedMTLFence *fence) +{ + SERIALISE_TIME_CALL(Unwrap(this)->updateFence(Unwrap(fence))); + + // TODO: when WrappedMTLFence exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_updateFence); + Serialise_updateFence(ser, fence); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_waitForFence(SerialiserType &ser, WrappedMTLFence *fence) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // TODO: when WrappedMTLFence exists + // SERIALISE_ELEMENT(fence).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::waitForFence(WrappedMTLFence *fence) +{ + SERIALISE_TIME_CALL(Unwrap(this)->waitForFence(Unwrap(fence))); + + // TODO: when WrappedMTLFence exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_waitForFence); + Serialise_waitForFence(ser, fence); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_getTextureAccessCounters( + SerialiserType &ser, WrappedMTLTexture *texture, MTL::Region ®ion, NS::UInteger mipLevel, + NS::UInteger slice, bool resetCounters, WrappedMTLBuffer *countersBuffer, + NS::UInteger countersBufferOffset) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + SERIALISE_ELEMENT(region); + SERIALISE_ELEMENT(mipLevel); + SERIALISE_ELEMENT(slice); + SERIALISE_ELEMENT(resetCounters); + SERIALISE_ELEMENT(countersBuffer); + SERIALISE_ELEMENT(countersBufferOffset); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::getTextureAccessCounters( + WrappedMTLTexture *texture, MTL::Region ®ion, NS::UInteger mipLevel, NS::UInteger slice, + bool resetCounters, WrappedMTLBuffer *countersBuffer, NS::UInteger countersBufferOffset) +{ + SERIALISE_TIME_CALL(Unwrap(this)->getTextureAccessCounters( + Unwrap(texture), region, mipLevel, slice, resetCounters, Unwrap(countersBuffer), + countersBufferOffset)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_getTextureAccessCounters); + Serialise_getTextureAccessCounters(ser, texture, region, mipLevel, slice, resetCounters, + countersBuffer, countersBufferOffset); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_resetTextureAccessCounters(SerialiserType &ser, + WrappedMTLTexture *texture, + MTL::Region ®ion, + NS::UInteger mipLevel, + NS::UInteger slice) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + SERIALISE_ELEMENT(region); + SERIALISE_ELEMENT(mipLevel); + SERIALISE_ELEMENT(slice); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::resetTextureAccessCounters(WrappedMTLTexture *texture, + MTL::Region ®ion, + NS::UInteger mipLevel, + NS::UInteger slice) +{ + SERIALISE_TIME_CALL( + Unwrap(this)->resetTextureAccessCounters(Unwrap(texture), region, mipLevel, slice)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_resetTextureAccessCounters); + Serialise_resetTextureAccessCounters(ser, texture, region, mipLevel, slice); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_optimizeContentsForGPUAccess(SerialiserType &ser, + WrappedMTLTexture *texture) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::optimizeContentsForGPUAccess(WrappedMTLTexture *texture) +{ + SERIALISE_TIME_CALL(Unwrap(this)->optimizeContentsForGPUAccess(Unwrap(texture))); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_optimizeContentsForGPUAccess); + Serialise_optimizeContentsForGPUAccess(ser, texture); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_optimizeContentsForGPUAccess(SerialiserType &ser, + WrappedMTLTexture *texture, + NS::UInteger slice, + NS::UInteger level) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + SERIALISE_ELEMENT(slice); + SERIALISE_ELEMENT(level); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::optimizeContentsForGPUAccess(WrappedMTLTexture *texture, + NS::UInteger slice, + NS::UInteger level) +{ + SERIALISE_TIME_CALL(Unwrap(this)->optimizeContentsForGPUAccess(Unwrap(texture), slice, level)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK( + MetalChunk::MTLBlitCommandEncoder_optimizeContentsForGPUAccess_slice_level); + Serialise_optimizeContentsForGPUAccess(ser, texture, slice, level); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_optimizeContentsForCPUAccess(SerialiserType &ser, + WrappedMTLTexture *texture) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::optimizeContentsForCPUAccess(WrappedMTLTexture *texture) +{ + SERIALISE_TIME_CALL(Unwrap(this)->optimizeContentsForCPUAccess(Unwrap(texture))); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_optimizeContentsForCPUAccess); + Serialise_optimizeContentsForCPUAccess(ser, texture); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_optimizeContentsForCPUAccess(SerialiserType &ser, + WrappedMTLTexture *texture, + NS::UInteger slice, + NS::UInteger level) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + SERIALISE_ELEMENT(slice); + SERIALISE_ELEMENT(level); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLBlitCommandEncoder::optimizeContentsForCPUAccess(WrappedMTLTexture *texture, + NS::UInteger slice, + NS::UInteger level) +{ + SERIALISE_TIME_CALL(Unwrap(this)->optimizeContentsForCPUAccess(Unwrap(texture), slice, level)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_optimizeContentsForCPUAccess); + Serialise_optimizeContentsForCPUAccess(ser, texture, slice, level); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_resetCommandsInBuffer( + SerialiserType &ser, WrappedMTLIndirectCommandBuffer *buffer, NS::Range &range) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // TODO: when WrappedMTLIndirectCommandBuffer exists + // SERIALISE_ELEMENT(buffer).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::resetCommandsInBuffer(WrappedMTLIndirectCommandBuffer *buffer, + NS::Range &range) +{ + SERIALISE_TIME_CALL(Unwrap(this)->resetCommandsInBuffer(Unwrap(buffer), range)); + + // TODO: when WrappedMTLIndirectCommandBuffer exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_resetCommandsInBuffer); + Serialise_resetCommandsInBuffer(ser, buffer, range); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_copyIndirectCommandBuffer( + SerialiserType &ser, WrappedMTLIndirectCommandBuffer *source, NS::Range &sourceRange, + WrappedMTLIndirectCommandBuffer *destination, NS::UInteger destinationIndex) +{ + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // TODO: when WrappedMTLIndirectCommandBuffer exists + // SERIALISE_ELEMENT(source).Important(); + SERIALISE_ELEMENT(sourceRange); + // SERIALISE_ELEMENT(destination).Important(); + SERIALISE_ELEMENT(destinationIndex); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::copyIndirectCommandBuffer( + WrappedMTLIndirectCommandBuffer *source, NS::Range &sourceRange, + WrappedMTLIndirectCommandBuffer *destination, NS::UInteger destinationIndex) +{ + SERIALISE_TIME_CALL(Unwrap(this)->copyIndirectCommandBuffer( + Unwrap(source), sourceRange, Unwrap(destination), destinationIndex)); + + // TODO: when WrappedMTLIndirectCommandBuffer exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_copyIndirectCommandBuffer); + Serialise_copyIndirectCommandBuffer(ser, source, sourceRange, destination, destinationIndex); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_optimizeIndirectCommandBuffer( + SerialiserType &ser, WrappedMTLIndirectCommandBuffer *indirectCommandBuffer, NS::Range &range) +{ + // TODO: when WrappedMTLIndirectCommandBuffer exists + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // SERIALISE_ELEMENT(indirectCommandBuffer).Important(); + SERIALISE_ELEMENT(range); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::optimizeIndirectCommandBuffer( + WrappedMTLIndirectCommandBuffer *indirectCommandBuffer, NS::Range &range) +{ + SERIALISE_TIME_CALL( + Unwrap(this)->optimizeIndirectCommandBuffer(Unwrap(indirectCommandBuffer), range)); + + // TODO: when WrappedMTLIndirectCommandBuffer exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_optimizeIndirectCommandBuffer); + Serialise_optimizeIndirectCommandBuffer(ser, indirectCommandBuffer, range); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_sampleCountersInBuffer( + SerialiserType &ser, WrappedMTLCounterSampleBuffer *sampleBuffer, NS::UInteger sampleIndex, + bool barrier) +{ + // TODO: when WrappedMTLCounterSampleBuffer exists + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // SERIALISE_ELEMENT(sampleBuffer).Important(); + SERIALISE_ELEMENT(sampleIndex); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::sampleCountersInBuffer(WrappedMTLCounterSampleBuffer *sampleBuffer, + NS::UInteger sampleIndex, bool barrier) +{ + SERIALISE_TIME_CALL( + Unwrap(this)->sampleCountersInBuffer(Unwrap(sampleBuffer), sampleIndex, barrier)); + + // TODO: when WrappedMTLCounterSampleBuffer exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_sampleCountersInBuffer); + Serialise_sampleCountersInBuffer(ser, sampleBuffer, sampleIndex, barrier); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLBlitCommandEncoder::Serialise_resolveCounters( + SerialiserType &ser, WrappedMTLCounterSampleBuffer *sampleBuffer, NS::Range &range, + WrappedMTLBuffer *destinationBuffer, NS::UInteger destinationOffset) +{ + // TODO: when WrappedMTLCounterSampleBuffer exists + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, this); + // SERIALISE_ELEMENT(sampleBuffer).Important(); + SERIALISE_ELEMENT(range); + SERIALISE_ELEMENT(destinationBuffer).Important(); + SERIALISE_ELEMENT(destinationOffset); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return false; +} + +void WrappedMTLBlitCommandEncoder::resolveCounters(WrappedMTLCounterSampleBuffer *sampleBuffer, + NS::Range &range, + WrappedMTLBuffer *destinationBuffer, + NS::UInteger destinationOffset) +{ + SERIALISE_TIME_CALL(Unwrap(this)->resolveCounters(Unwrap(sampleBuffer), range, + Unwrap(destinationBuffer), destinationOffset)); + + // TODO: when WrappedMTLCounterSampleBuffer exists + METAL_CAPTURE_NOT_IMPLEMENTED(); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLBlitCommandEncoder_resolveCounters); + Serialise_resolveCounters(ser, sampleBuffer, range, destinationBuffer, destinationOffset); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, setLabel, NS::String *value); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, endEncoding); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, insertDebugSignpost, + NS::String *string); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, pushDebugGroup, + NS::String *string); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, popDebugGroup); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, synchronizeResource, + WrappedMTLResource *resource); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, synchronizeTexture, + WrappedMTLTexture *texture, NS::UInteger slice, NS::UInteger level); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyFromBuffer, + WrappedMTLBuffer *sourceBuffer, NS::UInteger sourceOffset, + WrappedMTLBuffer *destinationBuffer, NS::UInteger destinationOffset, + NS::UInteger size); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyFromBuffer, + WrappedMTLBuffer *sourceBuffer, NS::UInteger sourceOffset, + NS::UInteger sourceBytesPerRow, NS::UInteger sourceBytesPerImage, + MTL::Size &sourceSize, WrappedMTLTexture *destinationTexture, + NS::UInteger destinationSlice, NS::UInteger destinationLevel, + MTL::Origin &destinationOrigin, MTL::BlitOption options); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyFromTexture, + WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, + NS::UInteger sourceLevel, MTL::Origin &sourceOrigin, + MTL::Size &sourceSize, WrappedMTLTexture *destinationTexture, + NS::UInteger destinationSlice, NS::UInteger destinationLevel, + MTL::Origin &destinationOrigin); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyFromTexture, + WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, + NS::UInteger sourceLevel, MTL::Origin &sourceOrigin, + MTL::Size &sourceSize, WrappedMTLBuffer *destinationBuffer, + NS::UInteger destinationOffset, NS::UInteger destinationBytesPerRow, + NS::UInteger destinationBytesPerImage, MTL::BlitOption options); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyFromTexture, + WrappedMTLTexture *sourceTexture, + WrappedMTLTexture *destinationTexture); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyFromTexture, + WrappedMTLTexture *sourceTexture, NS::UInteger sourceSlice, + NS::UInteger sourceLevel, WrappedMTLTexture *destinationTexture, + NS::UInteger destinationSlice, NS::UInteger destinationLevel, + NS::UInteger sliceCount, NS::UInteger levelCount); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, generateMipmapsForTexture, + WrappedMTLTexture *texture); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, fillBuffer, + WrappedMTLBuffer *buffer, NS::Range &range, uint8_t value); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, updateFence, + WrappedMTLFence *fence); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, waitForFence, + WrappedMTLFence *fence); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, getTextureAccessCounters, + WrappedMTLTexture *texture, MTL::Region ®ion, + NS::UInteger mipLevel, NS::UInteger slice, bool resetCounters, + WrappedMTLBuffer *countersBuffer, NS::UInteger countersBufferOffset); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, resetTextureAccessCounters, + WrappedMTLTexture *texture, MTL::Region ®ion, + NS::UInteger mipLevel, NS::UInteger slice); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, optimizeContentsForGPUAccess, + WrappedMTLTexture *texture); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, optimizeContentsForGPUAccess, + WrappedMTLTexture *texture, NS::UInteger slice, NS::UInteger level); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, optimizeContentsForCPUAccess, + WrappedMTLTexture *texture); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, optimizeContentsForCPUAccess, + WrappedMTLTexture *texture, NS::UInteger slice, NS::UInteger level); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, resetCommandsInBuffer, + WrappedMTLIndirectCommandBuffer *buffer, NS::Range &range); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, copyIndirectCommandBuffer, + WrappedMTLIndirectCommandBuffer *source, NS::Range &sourceRange, + WrappedMTLIndirectCommandBuffer *destination, + NS::UInteger destinationIndex); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, optimizeIndirectCommandBuffer, + WrappedMTLIndirectCommandBuffer *indirectCommandBuffer, + NS::Range &range); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, sampleCountersInBuffer, + WrappedMTLCounterSampleBuffer *sampleBuffer, + NS::UInteger sampleIndex, bool barrier); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLBlitCommandEncoder, void, resolveCounters, + WrappedMTLCounterSampleBuffer *sampleBuffer, NS::Range &range, + WrappedMTLBuffer *destinationBuffer, NS::UInteger destinationOffset); diff --git a/renderdoc/driver/metal/metal_blit_command_encoder.h b/renderdoc/driver/metal/metal_blit_command_encoder.h new file mode 100644 index 000000000..e4c3d6c6a --- /dev/null +++ b/renderdoc/driver/metal/metal_blit_command_encoder.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * 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" +#include "metal_device.h" +#include "metal_resources.h" + +class WrappedMTLBlitCommandEncoder : public WrappedMTLObject +{ +public: + WrappedMTLBlitCommandEncoder(MTL::BlitCommandEncoder *realMTLBlitCommandEncoder, ResourceId objId, + WrappedMTLDevice *wrappedMTLDevice); + + void SetCommandBuffer(WrappedMTLCommandBuffer *commandBuffer) { m_CommandBuffer = commandBuffer; } + DECLARE_FUNCTION_SERIALISED(void, setLabel, NS::String *value); + DECLARE_FUNCTION_SERIALISED(void, endEncoding); + DECLARE_FUNCTION_SERIALISED(void, insertDebugSignpost, NS::String *string); + DECLARE_FUNCTION_SERIALISED(void, pushDebugGroup, NS::String *string); + DECLARE_FUNCTION_SERIALISED(void, popDebugGroup); + DECLARE_FUNCTION_SERIALISED(void, synchronizeResource, WrappedMTLResource *resource); + DECLARE_FUNCTION_SERIALISED(void, synchronizeTexture, WrappedMTLTexture *texture, + NS::UInteger slice, NS::UInteger level); + DECLARE_FUNCTION_SERIALISED(void, copyFromBuffer, WrappedMTLBuffer *sourceBuffer, + NS::UInteger sourceOffset, WrappedMTLBuffer *destinationBuffer, + NS::UInteger destinationOffset, NS::UInteger size); + DECLARE_FUNCTION_SERIALISED(void, copyFromBuffer, WrappedMTLBuffer *sourceBuffer, + NS::UInteger sourceOffset, NS::UInteger sourceBytesPerRow, + NS::UInteger sourceBytesPerImage, MTL::Size &sourceSize, + WrappedMTLTexture *destinationTexture, NS::UInteger destinationSlice, + NS::UInteger destinationLevel, MTL::Origin &destinationOrigin, + MTL::BlitOption options); + DECLARE_FUNCTION_SERIALISED(void, copyFromTexture, WrappedMTLTexture *sourceTexture, + NS::UInteger sourceSlice, NS::UInteger sourceLevel, + MTL::Origin &sourceOrigin, MTL::Size &sourceSize, + WrappedMTLTexture *destinationTexture, NS::UInteger destinationSlice, + NS::UInteger destinationLevel, MTL::Origin &destinationOrigin); + DECLARE_FUNCTION_SERIALISED(void, copyFromTexture, WrappedMTLTexture *sourceTexture, + NS::UInteger sourceSlice, NS::UInteger sourceLevel, + MTL::Origin &sourceOrigin, MTL::Size &sourceSize, + WrappedMTLBuffer *destinationBuffer, NS::UInteger destinationOffset, + NS::UInteger destinationBytesPerRow, + NS::UInteger destinationBytesPerImage, MTL::BlitOption options); + DECLARE_FUNCTION_SERIALISED(void, copyFromTexture, WrappedMTLTexture *sourceTexture, + WrappedMTLTexture *destinationTexture); + DECLARE_FUNCTION_SERIALISED(void, copyFromTexture, WrappedMTLTexture *sourceTexture, + NS::UInteger sourceSlice, NS::UInteger sourceLevel, + WrappedMTLTexture *destinationTexture, NS::UInteger destinationSlice, + NS::UInteger destinationLevel, NS::UInteger sliceCount, + NS::UInteger levelCount); + DECLARE_FUNCTION_SERIALISED(void, generateMipmapsForTexture, WrappedMTLTexture *texture); + DECLARE_FUNCTION_SERIALISED(void, fillBuffer, WrappedMTLBuffer *buffer, NS::Range &range, + uint8_t value); + DECLARE_FUNCTION_SERIALISED(void, updateFence, WrappedMTLFence *fence); + DECLARE_FUNCTION_SERIALISED(void, waitForFence, WrappedMTLFence *fence); + DECLARE_FUNCTION_SERIALISED(void, getTextureAccessCounters, WrappedMTLTexture *texture, + MTL::Region ®ion, NS::UInteger mipLevel, NS::UInteger slice, + bool resetCounters, WrappedMTLBuffer *countersBuffer, + NS::UInteger countersBufferOffset); + DECLARE_FUNCTION_SERIALISED(void, resetTextureAccessCounters, WrappedMTLTexture *texture, + MTL::Region ®ion, NS::UInteger mipLevel, NS::UInteger slice); + DECLARE_FUNCTION_SERIALISED(void, optimizeContentsForGPUAccess, WrappedMTLTexture *texture); + DECLARE_FUNCTION_SERIALISED(void, optimizeContentsForGPUAccess, WrappedMTLTexture *texture, + NS::UInteger slice, NS::UInteger level); + DECLARE_FUNCTION_SERIALISED(void, optimizeContentsForCPUAccess, WrappedMTLTexture *texture); + DECLARE_FUNCTION_SERIALISED(void, optimizeContentsForCPUAccess, WrappedMTLTexture *texture, + NS::UInteger slice, NS::UInteger level); + DECLARE_FUNCTION_SERIALISED(void, resetCommandsInBuffer, WrappedMTLIndirectCommandBuffer *buffer, + NS::Range &range); + DECLARE_FUNCTION_SERIALISED(void, copyIndirectCommandBuffer, + WrappedMTLIndirectCommandBuffer *source, NS::Range &sourceRange, + WrappedMTLIndirectCommandBuffer *destination, + NS::UInteger destinationIndex); + DECLARE_FUNCTION_SERIALISED(void, optimizeIndirectCommandBuffer, + WrappedMTLIndirectCommandBuffer *indirectCommandBuffer, + NS::Range &range); + DECLARE_FUNCTION_SERIALISED(void, sampleCountersInBuffer, + WrappedMTLCounterSampleBuffer *sampleBuffer, NS::UInteger sampleIndex, + bool barrier); + DECLARE_FUNCTION_SERIALISED(void, resolveCounters, WrappedMTLCounterSampleBuffer *sampleBuffer, + NS::Range &range, WrappedMTLBuffer *destinationBuffer, + NS::UInteger destinationOffset); + + enum + { + TypeEnum = eResBlitCommandEncoder + }; + +private: + WrappedMTLCommandBuffer *m_CommandBuffer; +}; diff --git a/renderdoc/driver/metal/metal_blit_command_encoder_bridge.mm b/renderdoc/driver/metal/metal_blit_command_encoder_bridge.mm new file mode 100644 index 000000000..71913b8f6 --- /dev/null +++ b/renderdoc/driver/metal/metal_blit_command_encoder_bridge.mm @@ -0,0 +1,338 @@ +/****************************************************************************** + * 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_blit_command_encoder.h" +#include "metal_types_bridge.h" + +// Wrapper for MTLBlitCommandEncoder +@implementation ObjCBridgeMTLBlitCommandEncoder + +// ObjCWrappedMTLBlitCommandEncoder specific +- (id)real +{ + return id(Unwrap(GetWrapped(self))); +} + +// Silence compiler warning +// error: method possibly missing a [super dealloc] call [-Werror,-Wobjc-missing-super-calls] +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-missing-super-calls" +- (void)dealloc +{ + GetWrapped(self)->Dealloc(); +} +#pragma clang diagnostic pop + +// Use the real MTLBlitCommandEncoder to find methods from messages +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + id fwd = self.real; + return [fwd methodSignatureForSelector:aSelector]; +} + +// Forward any unknown messages to the real MTLBlitCommandEncoder +- (void)forwardInvocation:(NSInvocation *)invocation +{ + SEL aSelector = [invocation selector]; + + if([self.real respondsToSelector:aSelector]) + [invocation invokeWithTarget:self.real]; + else + [super forwardInvocation:invocation]; +} + +// MTLCommandEncoder : based on the protocol defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLCommandEncoder.h + +- (id)device +{ + return id(GetWrapped(self)->GetDevice()); +} + +- (nullable NSString *)label +{ + return self.real.label; +} + +- (void)setLabel:value +{ + GetWrapped(self)->setLabel((NS::String *)value); +} + +- (void)endEncoding +{ + GetWrapped(self)->endEncoding(); +} + +- (void)insertDebugSignpost:(NSString *)string +{ + GetWrapped(self)->insertDebugSignpost((NS::String *)string); +} + +- (void)pushDebugGroup:(NSString *)string +{ + GetWrapped(self)->pushDebugGroup((NS::String *)string); +} + +- (void)popDebugGroup +{ + GetWrapped(self)->popDebugGroup(); +} + +// MTLBlitCommandEncoder : based on the protocol defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLBlitCommandEncoder.h + +- (void)synchronizeResource:(id)resource API_AVAILABLE(macos(10.11), macCatalyst(13.0)) + API_UNAVAILABLE(ios) +{ + GetWrapped(self)->synchronizeResource(GetWrapped(resource)); +} + +- (void)synchronizeTexture:(id)texture + slice:(NSUInteger)slice + level:(NSUInteger)level API_AVAILABLE(macos(10.11), macCatalyst(13.0)) + API_UNAVAILABLE(ios) +{ + GetWrapped(self)->synchronizeTexture(GetWrapped(texture), slice, level); +} + +- (void)copyFromTexture:(id)sourceTexture + sourceSlice:(NSUInteger)sourceSlice + sourceLevel:(NSUInteger)sourceLevel + sourceOrigin:(MTLOrigin)sourceOrigin + sourceSize:(MTLSize)sourceSize + toTexture:(id)destinationTexture + destinationSlice:(NSUInteger)destinationSlice + destinationLevel:(NSUInteger)destinationLevel + destinationOrigin:(MTLOrigin)destinationOrigin +{ + GetWrapped(self)->copyFromTexture(GetWrapped(sourceTexture), sourceSlice, sourceSlice, + (MTL::Origin &)sourceOrigin, (MTL::Size &)sourceSize, + GetWrapped(destinationTexture), destinationSlice, + destinationLevel, (MTL::Origin &)destinationOrigin); +} + +- (void)copyFromBuffer:(id)sourceBuffer + sourceOffset:(NSUInteger)sourceOffset + sourceBytesPerRow:(NSUInteger)sourceBytesPerRow + sourceBytesPerImage:(NSUInteger)sourceBytesPerImage + sourceSize:(MTLSize)sourceSize + toTexture:(id)destinationTexture + destinationSlice:(NSUInteger)destinationSlice + destinationLevel:(NSUInteger)destinationLevel + destinationOrigin:(MTLOrigin)destinationOrigin +{ + GetWrapped(self)->copyFromBuffer( + GetWrapped(sourceBuffer), sourceOffset, sourceBytesPerRow, sourceBytesPerImage, + (MTL::Size &)sourceSize, GetWrapped(destinationTexture), destinationSlice, destinationLevel, + (MTL::Origin &)destinationOrigin, MTL::BlitOptionNone); +} + +- (void)copyFromBuffer:(id)sourceBuffer + sourceOffset:(NSUInteger)sourceOffset + sourceBytesPerRow:(NSUInteger)sourceBytesPerRow + sourceBytesPerImage:(NSUInteger)sourceBytesPerImage + sourceSize:(MTLSize)sourceSize + toTexture:(id)destinationTexture + destinationSlice:(NSUInteger)destinationSlice + destinationLevel:(NSUInteger)destinationLevel + destinationOrigin:(MTLOrigin)destinationOrigin + options:(MTLBlitOption)options API_AVAILABLE(macos(10.11), ios(9.0)) +{ + GetWrapped(self)->copyFromBuffer( + GetWrapped(sourceBuffer), sourceOffset, sourceBytesPerRow, sourceBytesPerImage, + (MTL::Size &)sourceSize, GetWrapped(destinationTexture), destinationSlice, destinationLevel, + (MTL::Origin &)destinationOrigin, (MTL::BlitOption)options); +} + +- (void)copyFromTexture:(id)sourceTexture + sourceSlice:(NSUInteger)sourceSlice + sourceLevel:(NSUInteger)sourceLevel + sourceOrigin:(MTLOrigin)sourceOrigin + sourceSize:(MTLSize)sourceSize + toBuffer:(id)destinationBuffer + destinationOffset:(NSUInteger)destinationOffset + destinationBytesPerRow:(NSUInteger)destinationBytesPerRow + destinationBytesPerImage:(NSUInteger)destinationBytesPerImage +{ + GetWrapped(self)->copyFromTexture( + GetWrapped(sourceTexture), sourceSlice, sourceLevel, (MTL::Origin &)sourceOrigin, + (MTL::Size &)sourceSize, GetWrapped(destinationBuffer), destinationOffset, + destinationBytesPerRow, destinationBytesPerImage, MTL::BlitOptionNone); +} + +- (void)copyFromTexture:(id)sourceTexture + sourceSlice:(NSUInteger)sourceSlice + sourceLevel:(NSUInteger)sourceLevel + sourceOrigin:(MTLOrigin)sourceOrigin + sourceSize:(MTLSize)sourceSize + toBuffer:(id)destinationBuffer + destinationOffset:(NSUInteger)destinationOffset + destinationBytesPerRow:(NSUInteger)destinationBytesPerRow + destinationBytesPerImage:(NSUInteger)destinationBytesPerImage + options:(MTLBlitOption)options API_AVAILABLE(macos(10.11), ios(9.0)) +{ + GetWrapped(self)->copyFromTexture( + GetWrapped(sourceTexture), sourceSlice, sourceLevel, (MTL::Origin &)sourceOrigin, + (MTL::Size &)sourceSize, GetWrapped(destinationBuffer), destinationOffset, + destinationBytesPerRow, destinationBytesPerImage, (MTL::BlitOption)options); +} + +- (void)generateMipmapsForTexture:(id)texture +{ + GetWrapped(self)->generateMipmapsForTexture(GetWrapped(texture)); +} + +- (void)fillBuffer:(id)buffer range:(NSRange)range value:(uint8_t)value +{ + GetWrapped(self)->fillBuffer(GetWrapped(buffer), (NS::Range &)range, value); +} + +- (void)copyFromTexture:(id)sourceTexture + sourceSlice:(NSUInteger)sourceSlice + sourceLevel:(NSUInteger)sourceLevel + toTexture:(id)destinationTexture + destinationSlice:(NSUInteger)destinationSlice + destinationLevel:(NSUInteger)destinationLevel + sliceCount:(NSUInteger)sliceCount + levelCount:(NSUInteger)levelCount API_AVAILABLE(macos(10.15), ios(13.0)) +{ + GetWrapped(self)->copyFromTexture(GetWrapped(sourceTexture), sourceSlice, sourceLevel, + GetWrapped(destinationTexture), destinationSlice, + destinationLevel, sliceCount, levelCount); +} + +- (void)copyFromTexture:(id)sourceTexture + toTexture:(id)destinationTexture API_AVAILABLE(macos(10.15), ios(13.0)) +{ + GetWrapped(self)->copyFromTexture(GetWrapped(sourceTexture), GetWrapped(destinationTexture)); +} + +- (void)copyFromBuffer:(id)sourceBuffer + sourceOffset:(NSUInteger)sourceOffset + toBuffer:(id)destinationBuffer + destinationOffset:(NSUInteger)destinationOffset + size:(NSUInteger)size +{ + GetWrapped(self)->copyFromBuffer(GetWrapped(sourceBuffer), sourceOffset, + GetWrapped(destinationBuffer), destinationOffset, size); +} + +- (void)updateFence:(id)fence API_AVAILABLE(macos(10.13), ios(10.0)) +{ + GetWrapped(self)->updateFence(GetWrapped(fence)); +} + +- (void)waitForFence:(id)fence API_AVAILABLE(macos(10.13), ios(10.0)) +{ + GetWrapped(self)->waitForFence(GetWrapped(fence)); +} + +- (void)getTextureAccessCounters:(id)texture + region:(MTLRegion)region + mipLevel:(NSUInteger)mipLevel + slice:(NSUInteger)slice + resetCounters:(BOOL)resetCounters + countersBuffer:(id)countersBuffer + countersBufferOffset:(NSUInteger)countersBufferOffset + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0)) +{ + GetWrapped(self)->getTextureAccessCounters(GetWrapped(texture), (MTL::Region &)region, mipLevel, + slice, resetCounters, GetWrapped(countersBuffer), + countersBufferOffset); +} + +- (void)resetTextureAccessCounters:(id)texture + region:(MTLRegion)region + mipLevel:(NSUInteger)mipLevel + slice:(NSUInteger)slice + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0)) +{ + GetWrapped(self)->resetTextureAccessCounters(GetWrapped(texture), (MTL::Region &)region, mipLevel, + slice); +} + +- (void)optimizeContentsForGPUAccess:(id)texture API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->optimizeContentsForGPUAccess(GetWrapped(texture)); +} + +- (void)optimizeContentsForGPUAccess:(id)texture + slice:(NSUInteger)slice + level:(NSUInteger)level API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->optimizeContentsForGPUAccess(GetWrapped(texture), slice, level); +} + +- (void)optimizeContentsForCPUAccess:(id)texture API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->optimizeContentsForCPUAccess(GetWrapped(texture)); +} + +- (void)optimizeContentsForCPUAccess:(id)texture + slice:(NSUInteger)slice + level:(NSUInteger)level API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->optimizeContentsForCPUAccess(GetWrapped(texture), slice, level); +} + +- (void)resetCommandsInBuffer:(id)buffer + withRange:(NSRange)range API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->resetCommandsInBuffer(GetWrapped(buffer), (NS::Range &)range); +} + +- (void)copyIndirectCommandBuffer:(id)source + sourceRange:(NSRange)sourceRange + destination:(id)destination + destinationIndex:(NSUInteger)destinationIndex API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->copyIndirectCommandBuffer(GetWrapped(source), (NS::Range &)sourceRange, + GetWrapped(destination), destinationIndex); +} + +- (void)optimizeIndirectCommandBuffer:(id)indirectCommandBuffer + withRange:(NSRange)range API_AVAILABLE(macos(10.14), ios(12.0)) +{ + GetWrapped(self)->optimizeIndirectCommandBuffer(GetWrapped(indirectCommandBuffer), + (NS::Range &)range); +} + +- (void)sampleCountersInBuffer:(id)sampleBuffer + atSampleIndex:(NSUInteger)sampleIndex + withBarrier:(BOOL)barrier API_AVAILABLE(macos(10.15), ios(14.0)) +{ + GetWrapped(self)->sampleCountersInBuffer(GetWrapped(sampleBuffer), sampleIndex, barrier); +} + +- (void)resolveCounters:(id)sampleBuffer + inRange:(NSRange)range + destinationBuffer:(id)destinationBuffer + destinationOffset:(NSUInteger)destinationOffset API_AVAILABLE(macos(10.15), ios(14.0)) +{ + GetWrapped(self)->resolveCounters(GetWrapped(sampleBuffer), (NS::Range &)range, + GetWrapped(destinationBuffer), destinationOffset); +} + +@end diff --git a/renderdoc/driver/metal/metal_command_buffer.cpp b/renderdoc/driver/metal/metal_command_buffer.cpp index 37d1c51e8..917ff6e4f 100644 --- a/renderdoc/driver/metal/metal_command_buffer.cpp +++ b/renderdoc/driver/metal/metal_command_buffer.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "metal_command_buffer.h" +#include "metal_blit_command_encoder.h" #include "metal_device.h" #include "metal_render_command_encoder.h" #include "metal_resources.h" @@ -35,6 +36,54 @@ WrappedMTLCommandBuffer::WrappedMTLCommandBuffer(MTL::CommandBuffer *realMTLComm AllocateObjCBridge(this); } +template +bool WrappedMTLCommandBuffer::Serialise_blitCommandEncoder(SerialiserType &ser, + WrappedMTLBlitCommandEncoder *encoder) +{ + SERIALISE_ELEMENT_LOCAL(CommandBuffer, this); + SERIALISE_ELEMENT_LOCAL(BlitCommandEncoder, GetResID(encoder)) + .TypedAs("MTLBlitCommandEncoder"_lit); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // TODO: implement RD MTL replay + } + return true; +} + +WrappedMTLBlitCommandEncoder *WrappedMTLCommandBuffer::blitCommandEncoder() +{ + MTL::BlitCommandEncoder *realMTLBlitCommandEncoder; + SERIALISE_TIME_CALL(realMTLBlitCommandEncoder = Unwrap(this)->blitCommandEncoder()); + WrappedMTLBlitCommandEncoder *wrappedMTLBlitCommandEncoder; + ResourceId id = + GetResourceManager()->WrapResource(realMTLBlitCommandEncoder, wrappedMTLBlitCommandEncoder); + wrappedMTLBlitCommandEncoder->SetCommandBuffer(this); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLCommandBuffer_blitCommandEncoder); + Serialise_blitCommandEncoder(ser, wrappedMTLBlitCommandEncoder); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(this); + bufferRecord->AddChunk(chunk); + + MetalResourceRecord *encoderRecord = + GetResourceManager()->AddResourceRecord(wrappedMTLBlitCommandEncoder); + } + else + { + // TODO: implement RD MTL replay + // GetResourceManager()->AddLiveResource(id, *wrappedMTLLibrary); + } + return wrappedMTLBlitCommandEncoder; +} + template bool WrappedMTLCommandBuffer::Serialise_renderCommandEncoderWithDescriptor( SerialiserType &ser, WrappedMTLRenderCommandEncoder *encoder, @@ -180,6 +229,9 @@ void WrappedMTLCommandBuffer::commit() } } +INSTANTIATE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLCommandBuffer, + WrappedMTLBlitCommandEncoder *encoder, + blitCommandEncoder); INSTANTIATE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLCommandBuffer, WrappedMTLRenderCommandEncoder *encoder, renderCommandEncoderWithDescriptor, diff --git a/renderdoc/driver/metal/metal_command_buffer.h b/renderdoc/driver/metal/metal_command_buffer.h index 2082a9052..8e4ef67d7 100644 --- a/renderdoc/driver/metal/metal_command_buffer.h +++ b/renderdoc/driver/metal/metal_command_buffer.h @@ -37,6 +37,7 @@ public: void SetCommandQueue(WrappedMTLCommandQueue *commandQueue) { m_CommandQueue = commandQueue; } MTL::CommandQueue *GetCommandQueue() { return (MTL::CommandQueue *)m_CommandQueue; } + DECLARE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLBlitCommandEncoder *, blitCommandEncoder); DECLARE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLRenderCommandEncoder *, renderCommandEncoderWithDescriptor, RDMTL::RenderPassDescriptor &descriptor); diff --git a/renderdoc/driver/metal/metal_command_buffer_bridge.mm b/renderdoc/driver/metal/metal_command_buffer_bridge.mm index 8ad86bb26..97777e03b 100644 --- a/renderdoc/driver/metal/metal_command_buffer_bridge.mm +++ b/renderdoc/driver/metal/metal_command_buffer_bridge.mm @@ -186,8 +186,7 @@ - (nullable id)blitCommandEncoder { - METAL_NOT_HOOKED(); - return [self.real blitCommandEncoder]; + return id(GetWrapped(self)->blitCommandEncoder()); } - (nullable id)renderCommandEncoderWithDescriptor: diff --git a/renderdoc/driver/metal/metal_common.h b/renderdoc/driver/metal/metal_common.h index eca41002e..ee1b81a1a 100644 --- a/renderdoc/driver/metal/metal_common.h +++ b/renderdoc/driver/metal/metal_common.h @@ -233,6 +233,36 @@ enum class MetalChunk : uint32_t MTLBuffer_remoteStorageBuffer, MTLBuffer_newRemoteBufferViewForDevice, MTLBuffer_InternalModifyCPUContents, + MTLBlitCommandEncoder_setLabel, + MTLBlitCommandEncoder_endEncoding, + MTLBlitCommandEncoder_insertDebugSignpost, + MTLBlitCommandEncoder_pushDebugGroup, + MTLBlitCommandEncoder_popDebugGroup, + MTLBlitCommandEncoder_synchronizeResource, + MTLBlitCommandEncoder_synchronizeTexture, + MTLBlitCommandEncoder_copyFromBuffer_toBuffer, + MTLBlitCommandEncoder_copyFromBuffer_toTexture, + MTLBlitCommandEncoder_copyFromBuffer_toTexture_options, + MTLBlitCommandEncoder_copyFromTexture_toBuffer, + MTLBlitCommandEncoder_copyFromTexture_toBuffer_options, + MTLBlitCommandEncoder_copyFromTexture_toTexture, + MTLBlitCommandEncoder_copyFromTexture_toTexture_slice_level_origin, + MTLBlitCommandEncoder_copyFromTexture_toTexture_slice_level_count, + MTLBlitCommandEncoder_generateMipmapsForTexture, + MTLBlitCommandEncoder_fillBuffer, + MTLBlitCommandEncoder_updateFence, + MTLBlitCommandEncoder_waitForFence, + MTLBlitCommandEncoder_getTextureAccessCounters, + MTLBlitCommandEncoder_resetTextureAccessCounters, + MTLBlitCommandEncoder_optimizeContentsForGPUAccess, + MTLBlitCommandEncoder_optimizeContentsForGPUAccess_slice_level, + MTLBlitCommandEncoder_optimizeContentsForCPUAccess, + MTLBlitCommandEncoder_optimizeContentsForCPUAccess_slice_level, + MTLBlitCommandEncoder_resetCommandsInBuffer, + MTLBlitCommandEncoder_copyIndirectCommandBuffer, + MTLBlitCommandEncoder_optimizeIndirectCommandBuffer, + MTLBlitCommandEncoder_sampleCountersInBuffer, + MTLBlitCommandEncoder_resolveCounters, Max }; @@ -282,6 +312,12 @@ DECLARE_REFLECTION_ENUM(MetalChunk); } while((void)0, 0) #endif +#define METAL_CAPTURE_NOT_IMPLEMENTED() \ + do \ + { \ + RDCERR("Metal '%s' capture not implemented", __PRETTY_FUNCTION__); \ + } while((void)0, 0) + // similar to RDCUNIMPLEMENTED but without the debugbreak #define METAL_NOT_IMPLEMENTED(...) \ do \ diff --git a/renderdoc/driver/metal/metal_resources.cpp b/renderdoc/driver/metal/metal_resources.cpp index 3c5571f4e..6c31c9d66 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_blit_command_encoder.h" #include "metal_buffer.h" #include "metal_command_buffer.h" #include "metal_command_queue.h" diff --git a/renderdoc/driver/metal/metal_resources.h b/renderdoc/driver/metal/metal_resources.h index 94c909e4c..b4d3513b5 100644 --- a/renderdoc/driver/metal/metal_resources.h +++ b/renderdoc/driver/metal/metal_resources.h @@ -44,6 +44,7 @@ enum MetalResourceType eResRenderPipelineState, eResTexture, eResRenderCommandEncoder, + eResBlitCommandEncoder, eResMax }; @@ -78,6 +79,11 @@ struct WrappedMTLObject ResourceId GetResID(WrappedMTLObject *obj); +inline ResourceId GetResID(WrappedMTLResource *obj) +{ + return GetResID((WrappedMTLObject *)obj); +} + template MetalResourceRecord *GetRecord(WrappedType *obj) { @@ -113,6 +119,11 @@ struct UnwrapHelper METALCPP_WRAPPED_PROTOCOLS(WRAPPED_TYPE_HELPERS) #undef WRAPPED_TYPE_HELPERS +inline MTL::Resource *Unwrap(WrappedMTLResource *obj) +{ + return Unwrap((WrappedMTLObject *)obj); +} + struct MetalCmdBufferRecordingInfo { MetalCmdBufferRecordingInfo(WrappedMTLCommandQueue *parentQueue) diff --git a/renderdoc/driver/metal/metal_serialise.cpp b/renderdoc/driver/metal/metal_serialise.cpp index 837421f2d..aaf6461ed 100644 --- a/renderdoc/driver/metal/metal_serialise.cpp +++ b/renderdoc/driver/metal/metal_serialise.cpp @@ -22,6 +22,7 @@ * THE SOFTWARE. ******************************************************************************/ +#include "metal_blit_command_encoder.h" #include "metal_buffer.h" #include "metal_command_buffer.h" #include "metal_command_queue.h" @@ -77,6 +78,7 @@ void DoSerialiseViaResourceId(SerialiserType &ser, type &el) INSTANTIATE_SERIALISE_TYPE(WrappedMTL##CPPTYPE *); METALCPP_WRAPPED_PROTOCOLS(IMPLEMENT_WRAPPED_TYPE_SERIALISE); +IMPLEMENT_WRAPPED_TYPE_SERIALISE(Resource); #undef IMPLEMENT_WRAPPED_TYPE_SERIALISE template diff --git a/renderdoc/driver/metal/metal_stringise.cpp b/renderdoc/driver/metal/metal_stringise.cpp index a37ea8257..f89538e22 100644 --- a/renderdoc/driver/metal/metal_stringise.cpp +++ b/renderdoc/driver/metal/metal_stringise.cpp @@ -31,7 +31,7 @@ template <> rdcstr DoStringise(const MetalChunk &el) { - RDCCOMPILE_ASSERT((uint32_t)MetalChunk::Max == 1199, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)MetalChunk::Max == 1229, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(MetalChunk) { @@ -400,6 +400,65 @@ rdcstr DoStringise(const MetalChunk &el) "MTLBuffer::newRemoteBufferViewForDevice"); STRINGISE_ENUM_CLASS_NAMED(MTLBuffer_InternalModifyCPUContents, "Internal_MTLBufferModifyCPUContents"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_setLabel, "MTLBlitCommandEncoder::setLabel"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_endEncoding, + "MTLBlitCommandEncoder::endEncoding"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_insertDebugSignpost, + "MTLBlitCommandEncoder::insertDebugSignpost"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_pushDebugGroup, + "MTLBlitCommandEncoder::pushDebugGroup"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_popDebugGroup, + "MTLBlitCommandEncoder::popDebugGroup"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_synchronizeResource, + "MTLBlitCommandEncoder::synchronizeResource"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_synchronizeTexture, + "MTLBlitCommandEncoder::synchronizeTexture"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromBuffer_toBuffer, + "MTLBlitCommandEncoder::copyFromBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromBuffer_toTexture, + "MTLBlitCommandEncoder::copyFromBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromBuffer_toTexture_options, + "MTLBlitCommandEncoder::copyFromBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromTexture_toBuffer, + "MTLBlitCommandEncoder::copyFromTexture_toBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromTexture_toBuffer_options, + "MTLBlitCommandEncoder::copyFromTexture"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromTexture_toTexture, + "MTLBlitCommandEncoder::copyFromTexture_toTexture"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromTexture_toTexture_slice_level_origin, + "MTLBlitCommandEncoder::copyFromTexture"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyFromTexture_toTexture_slice_level_count, + "MTLBlitCommandEncoder::copyFromTexture"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_generateMipmapsForTexture, + "MTLBlitCommandEncoder::generateMipmapsForTexture"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_fillBuffer, + "MTLBlitCommandEncoder::fillBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_updateFence, + "MTLBlitCommandEncoder::updateFence"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_waitForFence, + "MTLBlitCommandEncoder::waitForFence"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_getTextureAccessCounters, + "MTLBlitCommandEncoder::getTextureAccessCounters"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_resetTextureAccessCounters, + "MTLBlitCommandEncoder::resetTextureAccessCounters"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_optimizeContentsForGPUAccess, + "MTLBlitCommandEncoder::optimizeContentsForGPUAccess"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_optimizeContentsForGPUAccess_slice_level, + "MTLBlitCommandEncoder::optimizeContentsForGPUAccess"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_optimizeContentsForCPUAccess, + "MTLBlitCommandEncoder::optimizeContentsForCPUAccess"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_optimizeContentsForCPUAccess_slice_level, + "MTLBlitCommandEncoder::optimizeContentsForCPUAccess"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_resetCommandsInBuffer, + "MTLBlitCommandEncoder::resetCommandsInBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_copyIndirectCommandBuffer, + "MTLBlitCommandEncoder::copyIndirectCommandBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_optimizeIndirectCommandBuffer, + "MTLBlitCommandEncoder::optimizeIndirectCommandBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_sampleCountersInBuffer, + "MTLBlitCommandEncoder::sampleCountersInBuffer"); + STRINGISE_ENUM_CLASS_NAMED(MTLBlitCommandEncoder_resolveCounters, + "MTLBlitCommandEncoder::resolveCounters"); STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk"); } END_ENUM_STRINGISE() @@ -1069,7 +1128,7 @@ rdcstr DoStringise(const MTL::CullMode &el) template <> rdcstr DoStringise(const MetalResourceType &el) { - RDCCOMPILE_ASSERT((uint32_t)MetalResourceType::eResMax == 10, "MetalResourceType changed"); + RDCCOMPILE_ASSERT((uint32_t)MetalResourceType::eResMax == 11, "MetalResourceType changed"); BEGIN_ENUM_STRINGISE(MetalResourceType); { STRINGISE_ENUM(eResUnknown); @@ -1082,6 +1141,7 @@ rdcstr DoStringise(const MetalResourceType &el) STRINGISE_ENUM(eResRenderPipelineState); STRINGISE_ENUM(eResTexture); STRINGISE_ENUM(eResRenderCommandEncoder); + STRINGISE_ENUM(eResBlitCommandEncoder); } END_ENUM_STRINGISE(); } diff --git a/renderdoc/driver/metal/metal_types.cpp b/renderdoc/driver/metal/metal_types.cpp index 10981dbbf..40640747e 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_blit_command_encoder.h" #include "metal_buffer.h" #include "metal_command_buffer.h" #include "metal_command_queue.h" diff --git a/renderdoc/driver/metal/metal_types.h b/renderdoc/driver/metal/metal_types.h index e291659ca..a0d50a30f 100644 --- a/renderdoc/driver/metal/metal_types.h +++ b/renderdoc/driver/metal/metal_types.h @@ -48,7 +48,8 @@ const uint32_t MAX_RENDER_PASS_SAMPLE_BUFFER_ATTACHMENTS = 4; FUNC(Library); \ FUNC(RenderPipelineState); \ FUNC(Texture); \ - FUNC(RenderCommandEncoder); + FUNC(RenderCommandEncoder); \ + FUNC(BlitCommandEncoder); // 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. @@ -63,6 +64,7 @@ const uint32_t MAX_RENDER_PASS_SAMPLE_BUFFER_ATTACHMENTS = 4; void DoSerialise(SerialiserType &ser, WrappedMTL##CPPTYPE *&el); METALCPP_WRAPPED_PROTOCOLS(DECLARE_WRAPPED_TYPE_SERIALISE); +DECLARE_WRAPPED_TYPE_SERIALISE(Resource) #undef DECLARE_WRAPPED_TYPE_SERIALISE #define DECLARE_OBJC_HELPERS(CPPTYPE) \ @@ -76,6 +78,18 @@ METALCPP_WRAPPED_PROTOCOLS(DECLARE_WRAPPED_TYPE_SERIALISE); METALCPP_WRAPPED_PROTOCOLS(DECLARE_OBJC_HELPERS) #undef DECLARE_OBJC_HELPERS +// TODO: Wrapped types that need implementing +#define METALCPP_UNIMPLEMENTED_WRAPPED_PROTOCOLS(FUNC) \ + FUNC(Fence); \ + FUNC(IndirectCommandBuffer); \ + FUNC(CounterSampleBuffer); + +#define DECLARE_UNIMPLEMENTED_WRAPPED_CPP_HELPERS(CPPTYPE) \ + class WrappedMTL##CPPTYPE; \ + inline MTL::CPPTYPE *Unwrap(WrappedMTL##CPPTYPE *obj) { return (MTL::CPPTYPE *)obj; } +METALCPP_UNIMPLEMENTED_WRAPPED_PROTOCOLS(DECLARE_UNIMPLEMENTED_WRAPPED_CPP_HELPERS) +#undef DECLARE_UNIMPLEMENTED_WRAPPED_CPP_HELPERS + #define MTL_DECLARE_REFLECTION_TYPE(TYPE) \ template <> \ inline rdcliteral TypeName() \ diff --git a/renderdoc/driver/metal/metal_types_bridge.h b/renderdoc/driver/metal/metal_types_bridge.h index ec795cca1..69491f157 100644 --- a/renderdoc/driver/metal/metal_types_bridge.h +++ b/renderdoc/driver/metal/metal_types_bridge.h @@ -41,6 +41,20 @@ METALCPP_WRAPPED_PROTOCOLS(DECLARE_OBJC_WRAPPED_INTERFACES) #undef DECLARE_OBJC_WRAPPED_INTERFACES +#define DECLARE_UNIMPLEMENTED_WRAPPED_OBJC_HELPERS(CPPTYPE) \ + inline WrappedMTL##CPPTYPE *GetWrapped(id objC) \ + { \ + return (WrappedMTL##CPPTYPE *)objC; \ + } + +METALCPP_UNIMPLEMENTED_WRAPPED_PROTOCOLS(DECLARE_UNIMPLEMENTED_WRAPPED_OBJC_HELPERS) +#undef DECLARE_UNIMPLEMENTED_WRAPPED_OBJC_HELPERS + +inline WrappedMTLResource *GetWrapped(id objC) +{ + return (WrappedMTLResource *)objC; +} + // Define Mac SDK versions when compiling with earlier SDKs #ifndef __MAC_12_0 #define __MAC_12_0 120000