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