diff --git a/renderdoc/driver/metal/CMakeLists.txt b/renderdoc/driver/metal/CMakeLists.txt index 7bb293370..a5cce8fe0 100644 --- a/renderdoc/driver/metal/CMakeLists.txt +++ b/renderdoc/driver/metal/CMakeLists.txt @@ -31,6 +31,9 @@ set(sources metal_texture.cpp metal_texture.h metal_texture_bridge.mm + metal_render_command_encoder.cpp + metal_render_command_encoder.h + metal_render_command_encoder_bridge.mm metal_core.cpp metal_core.h metal_manager.cpp diff --git a/renderdoc/driver/metal/metal_command_buffer.cpp b/renderdoc/driver/metal/metal_command_buffer.cpp index 482649eb5..37d1c51e8 100644 --- a/renderdoc/driver/metal/metal_command_buffer.cpp +++ b/renderdoc/driver/metal/metal_command_buffer.cpp @@ -23,9 +23,10 @@ ******************************************************************************/ #include "metal_command_buffer.h" -#include "core/settings.h" #include "metal_device.h" +#include "metal_render_command_encoder.h" #include "metal_resources.h" +#include "metal_texture.h" WrappedMTLCommandBuffer::WrappedMTLCommandBuffer(MTL::CommandBuffer *realMTLCommandBuffer, ResourceId objId, WrappedMTLDevice *wrappedMTLDevice) @@ -34,6 +35,69 @@ WrappedMTLCommandBuffer::WrappedMTLCommandBuffer(MTL::CommandBuffer *realMTLComm AllocateObjCBridge(this); } +template +bool WrappedMTLCommandBuffer::Serialise_renderCommandEncoderWithDescriptor( + SerialiserType &ser, WrappedMTLRenderCommandEncoder *encoder, + RDMTL::RenderPassDescriptor &descriptor) +{ + SERIALISE_ELEMENT_LOCAL(CommandBuffer, this); + SERIALISE_ELEMENT_LOCAL(RenderCommandEncoder, GetResID(encoder)) + .TypedAs("MTLRenderCommandEncoder"_lit); + SERIALISE_ELEMENT(descriptor).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // TODO: implement RD MTL replay + } + return true; +} + +WrappedMTLRenderCommandEncoder *WrappedMTLCommandBuffer::renderCommandEncoderWithDescriptor( + RDMTL::RenderPassDescriptor &descriptor) +{ + MTL::RenderCommandEncoder *realMTLRenderCommandEncoder; + MTL::RenderPassDescriptor *mtlDescriptor(descriptor); + SERIALISE_TIME_CALL(realMTLRenderCommandEncoder = + Unwrap(this)->renderCommandEncoder(mtlDescriptor)); + mtlDescriptor->release(); + WrappedMTLRenderCommandEncoder *wrappedMTLRenderCommandEncoder; + ResourceId id = GetResourceManager()->WrapResource(realMTLRenderCommandEncoder, + wrappedMTLRenderCommandEncoder); + wrappedMTLRenderCommandEncoder->SetCommandBuffer(this); + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLCommandBuffer_renderCommandEncoderWithDescriptor); + Serialise_renderCommandEncoderWithDescriptor(ser, wrappedMTLRenderCommandEncoder, descriptor); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(this); + bufferRecord->AddChunk(chunk); + + MetalResourceRecord *encoderRecord = + GetResourceManager()->AddResourceRecord(wrappedMTLRenderCommandEncoder); + + for(int i = 0; i < descriptor.colorAttachments.count(); ++i) + { + WrappedMTLTexture *texture = descriptor.colorAttachments[i].texture; + if(texture != NULL) + { + bufferRecord->MarkResourceFrameReferenced(GetResID(texture), eFrameRef_Read); + } + } + } + else + { + // TODO: implement RD MTL replay + // GetResourceManager()->AddLiveResource(id, *wrappedMTLLibrary); + } + return wrappedMTLRenderCommandEncoder; +} + template bool WrappedMTLCommandBuffer::Serialise_presentDrawable(SerialiserType &ser, MTL::Drawable *drawable) { @@ -116,6 +180,10 @@ void WrappedMTLCommandBuffer::commit() } } +INSTANTIATE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLCommandBuffer, + WrappedMTLRenderCommandEncoder *encoder, + renderCommandEncoderWithDescriptor, + RDMTL::RenderPassDescriptor &descriptor); INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLCommandBuffer, void, presentDrawable, MTL::Drawable *drawable); INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLCommandBuffer, void, commit); diff --git a/renderdoc/driver/metal/metal_command_buffer.h b/renderdoc/driver/metal/metal_command_buffer.h index 2706c0e47..2082a9052 100644 --- a/renderdoc/driver/metal/metal_command_buffer.h +++ b/renderdoc/driver/metal/metal_command_buffer.h @@ -37,6 +37,9 @@ public: void SetCommandQueue(WrappedMTLCommandQueue *commandQueue) { m_CommandQueue = commandQueue; } MTL::CommandQueue *GetCommandQueue() { return (MTL::CommandQueue *)m_CommandQueue; } + DECLARE_FUNCTION_WITH_RETURN_SERIALISED(WrappedMTLRenderCommandEncoder *, + renderCommandEncoderWithDescriptor, + RDMTL::RenderPassDescriptor &descriptor); DECLARE_FUNCTION_SERIALISED(void, presentDrawable, MTL::Drawable *drawable); DECLARE_FUNCTION_SERIALISED(void, commit); diff --git a/renderdoc/driver/metal/metal_command_buffer_bridge.mm b/renderdoc/driver/metal/metal_command_buffer_bridge.mm index acd837209..8ad86bb26 100644 --- a/renderdoc/driver/metal/metal_command_buffer_bridge.mm +++ b/renderdoc/driver/metal/metal_command_buffer_bridge.mm @@ -193,8 +193,9 @@ - (nullable id)renderCommandEncoderWithDescriptor: (MTLRenderPassDescriptor *)renderPassDescriptor { - METAL_NOT_HOOKED(); - return [self.real renderCommandEncoderWithDescriptor:renderPassDescriptor]; + RDMTL::RenderPassDescriptor rdDescriptor((MTL::RenderPassDescriptor *)renderPassDescriptor); + return id( + GetWrapped(self)->renderCommandEncoderWithDescriptor(rdDescriptor)); } - (nullable id)computeCommandEncoderWithDescriptor: diff --git a/renderdoc/driver/metal/metal_common.h b/renderdoc/driver/metal/metal_common.h index e8b2c95cb..16a8d738a 100644 --- a/renderdoc/driver/metal/metal_common.h +++ b/renderdoc/driver/metal/metal_common.h @@ -120,6 +120,109 @@ enum class MetalChunk : uint32_t MTLRenderPipelineState_newVisibleFunctionTableWithDescriptor, MTLRenderPipelineState_newIntersectionFunctionTableWithDescriptor, MTLRenderPipelineState_newRenderPipelineStateWithAdditionalBinaryFunctions, + MTLRenderCommandEncoder_endEncoding, + MTLRenderCommandEncoder_insertDebugSignpost, + MTLRenderCommandEncoder_pushDebugGroup, + MTLRenderCommandEncoder_popDebugGroup, + MTLRenderCommandEncoder_setRenderPipelineState, + MTLRenderCommandEncoder_setVertexBytes, + MTLRenderCommandEncoder_setVertexBuffer, + MTLRenderCommandEncoder_setVertexBufferOffset, + MTLRenderCommandEncoder_setVertexBuffers, + MTLRenderCommandEncoder_setVertexTexture, + MTLRenderCommandEncoder_setVertexTextures, + MTLRenderCommandEncoder_setVertexSamplerState, + MTLRenderCommandEncoder_setVertexSamplerState_lodclamp, + MTLRenderCommandEncoder_setVertexSamplerStates, + MTLRenderCommandEncoder_setVertexSamplerStates_lodclamp, + MTLRenderCommandEncoder_setVertexVisibleFunctionTable, + MTLRenderCommandEncoder_setVertexVisibleFunctionTables, + MTLRenderCommandEncoder_setVertexIntersectionFunctionTable, + MTLRenderCommandEncoder_setVertexIntersectionFunctionTables, + MTLRenderCommandEncoder_setVertexAccelerationStructure, + MTLRenderCommandEncoder_setViewport, + MTLRenderCommandEncoder_setViewports, + MTLRenderCommandEncoder_setFrontFacingWinding, + MTLRenderCommandEncoder_setVertexAmplificationCount, + MTLRenderCommandEncoder_setCullMode, + MTLRenderCommandEncoder_setDepthClipMode, + MTLRenderCommandEncoder_setDepthBias, + MTLRenderCommandEncoder_setScissorRect, + MTLRenderCommandEncoder_setScissorRects, + MTLRenderCommandEncoder_setTriangleFillMode, + MTLRenderCommandEncoder_setFragmentBytes, + MTLRenderCommandEncoder_setFragmentBuffer, + MTLRenderCommandEncoder_setFragmentBufferOffset, + MTLRenderCommandEncoder_setFragmentBuffers, + MTLRenderCommandEncoder_setFragmentTexture, + MTLRenderCommandEncoder_setFragmentTextures, + MTLRenderCommandEncoder_setFragmentSamplerState, + MTLRenderCommandEncoder_setFragmentSamplerState_lodclamp, + MTLRenderCommandEncoder_setFragmentSamplerStates, + MTLRenderCommandEncoder_setFragmentSamplerStates_lodclamp, + MTLRenderCommandEncoder_setFragmentVisibleFunctionTable, + MTLRenderCommandEncoder_setFragmentVisibleFunctionTables, + MTLRenderCommandEncoder_setFragmentIntersectionFunctionTable, + MTLRenderCommandEncoder_setFragmentIntersectionFunctionTables, + MTLRenderCommandEncoder_setFragmentAccelerationStructure, + MTLRenderCommandEncoder_setBlendColor, + MTLRenderCommandEncoder_setDepthStencilState, + MTLRenderCommandEncoder_setStencilReferenceValue, + MTLRenderCommandEncoder_setStencilFrontReferenceValue, + MTLRenderCommandEncoder_setVisibilityResultMode, + MTLRenderCommandEncoder_setColorStoreAction, + MTLRenderCommandEncoder_setDepthStoreAction, + MTLRenderCommandEncoder_setStencilStoreAction, + MTLRenderCommandEncoder_setColorStoreActionOptions, + MTLRenderCommandEncoder_setDepthStoreActionOptions, + MTLRenderCommandEncoder_setStencilStoreActionOptions, + MTLRenderCommandEncoder_drawPrimitives, + MTLRenderCommandEncoder_drawPrimitives_instanced, + MTLRenderCommandEncoder_drawPrimitives_instanced_base, + MTLRenderCommandEncoder_drawPrimitives_indirect, + MTLRenderCommandEncoder_drawIndexedPrimitives, + MTLRenderCommandEncoder_drawIndexedPrimitives_instanced, + MTLRenderCommandEncoder_drawIndexedPrimitives_instanced_base, + MTLRenderCommandEncoder_drawIndexedPrimitives_indirect, + MTLRenderCommandEncoder_textureBarrier, + MTLRenderCommandEncoder_updateFence, + MTLRenderCommandEncoder_waitForFence, + MTLRenderCommandEncoder_setTessellationFactorBuffer, + MTLRenderCommandEncoder_setTessellationFactorScale, + MTLRenderCommandEncoder_drawPatches, + MTLRenderCommandEncoder_drawPatches_indirect, + MTLRenderCommandEncoder_drawIndexedPatches, + MTLRenderCommandEncoder_drawIndexedPatches_indirect, + MTLRenderCommandEncoder_setTileBytes, + MTLRenderCommandEncoder_setTileBuffer, + MTLRenderCommandEncoder_setTileBufferOffset, + MTLRenderCommandEncoder_setTileBuffers, + MTLRenderCommandEncoder_setTileTexture, + MTLRenderCommandEncoder_setTileTextures, + MTLRenderCommandEncoder_setTileSamplerState, + MTLRenderCommandEncoder_setTileSamplerState_lodclamp, + MTLRenderCommandEncoder_setTileSamplerStates, + MTLRenderCommandEncoder_setTileSamplerStates_lodclamp, + MTLRenderCommandEncoder_setTileVisibleFunctionTable, + MTLRenderCommandEncoder_setTileVisibleFunctionTables, + MTLRenderCommandEncoder_setTileIntersectionFunctionTable, + MTLRenderCommandEncoder_setTileIntersectionFunctionTables, + MTLRenderCommandEncoder_setTileAccelerationStructure, + MTLRenderCommandEncoder_dispatchThreadsPerTile, + MTLRenderCommandEncoder_setThreadgroupMemoryLength, + MTLRenderCommandEncoder_useResource, + MTLRenderCommandEncoder_useResource_stages, + MTLRenderCommandEncoder_useResources, + MTLRenderCommandEncoder_useResources_stages, + MTLRenderCommandEncoder_useHeap, + MTLRenderCommandEncoder_useHeap_stages, + MTLRenderCommandEncoder_useHeaps, + MTLRenderCommandEncoder_useHeaps_stages, + MTLRenderCommandEncoder_executeCommandsInBuffer, + MTLRenderCommandEncoder_executeCommandsInBuffer_indirect, + MTLRenderCommandEncoder_memoryBarrierWithScope, + MTLRenderCommandEncoder_memoryBarrierWithResources, + MTLRenderCommandEncoder_sampleCountersInBuffer, Max }; diff --git a/renderdoc/driver/metal/metal_device.cpp b/renderdoc/driver/metal/metal_device.cpp index af77e9c8d..2f676b307 100644 --- a/renderdoc/driver/metal/metal_device.cpp +++ b/renderdoc/driver/metal/metal_device.cpp @@ -128,6 +128,7 @@ WrappedMTLCommandQueue *WrappedMTLDevice::newCommandQueue() Serialise_newCommandQueue(ser, wrappedMTLCommandQueue); chunk = scope.Get(); } + MetalResourceRecord *record = GetResourceManager()->AddResourceRecord(wrappedMTLCommandQueue); record->AddChunk(chunk); } @@ -177,9 +178,9 @@ WrappedMTLLibrary *WrappedMTLDevice::newDefaultLibrary() Serialise_newDefaultLibrary(ser, wrappedMTLLibrary); chunk = scope.Get(); } + MetalResourceRecord *record = GetResourceManager()->AddResourceRecord(wrappedMTLLibrary); record->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Read); } else { @@ -225,9 +226,9 @@ WrappedMTLLibrary *WrappedMTLDevice::newLibraryWithSource(NS::String *source, Serialise_newLibraryWithSource(ser, wrappedMTLLibrary, source, options, error); chunk = scope.Get(); } + MetalResourceRecord *record = GetResourceManager()->AddResourceRecord(wrappedMTLLibrary); record->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Read); } else { diff --git a/renderdoc/driver/metal/metal_library.cpp b/renderdoc/driver/metal/metal_library.cpp index 10454b065..6e2302605 100644 --- a/renderdoc/driver/metal/metal_library.cpp +++ b/renderdoc/driver/metal/metal_library.cpp @@ -70,7 +70,6 @@ WrappedMTLFunction *WrappedMTLLibrary::newFunctionWithName(NS::String *functionN } MetalResourceRecord *record = GetResourceManager()->AddResourceRecord(wrappedMTLFunction); record->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Read); record->AddParent(GetRecord(this)); } else diff --git a/renderdoc/driver/metal/metal_render_command_encoder.cpp b/renderdoc/driver/metal/metal_render_command_encoder.cpp new file mode 100644 index 000000000..8b92b9eec --- /dev/null +++ b/renderdoc/driver/metal/metal_render_command_encoder.cpp @@ -0,0 +1,268 @@ +/****************************************************************************** + * 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_render_command_encoder.h" +#include "metal_command_buffer.h" +#include "metal_manager.h" +#include "metal_render_pipeline_state.h" +#include "metal_texture.h" + +WrappedMTLRenderCommandEncoder::WrappedMTLRenderCommandEncoder( + MTL::RenderCommandEncoder *realMTLRenderCommandEncoder, ResourceId objId, + WrappedMTLDevice *wrappedMTLDevice) + : WrappedMTLObject(realMTLRenderCommandEncoder, objId, wrappedMTLDevice, + wrappedMTLDevice->GetStateRef()) +{ + AllocateObjCBridge(this); +} + +template +bool WrappedMTLRenderCommandEncoder::Serialise_setRenderPipelineState( + SerialiserType &ser, WrappedMTLRenderPipelineState *pipelineState) +{ + SERIALISE_ELEMENT_LOCAL(RenderCommandEncoder, this); + SERIALISE_ELEMENT(pipelineState).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLRenderCommandEncoder::setRenderPipelineState(WrappedMTLRenderPipelineState *pipelineState) +{ + SERIALISE_TIME_CALL(Unwrap(this)->setRenderPipelineState(Unwrap(pipelineState))); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLRenderCommandEncoder_setRenderPipelineState); + Serialise_setRenderPipelineState(ser, pipelineState); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + bufferRecord->MarkResourceFrameReferenced(GetResID(pipelineState), eFrameRef_Read); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLRenderCommandEncoder::Serialise_setFragmentTexture(SerialiserType &ser, + WrappedMTLTexture *texture, + NS::UInteger index) +{ + SERIALISE_ELEMENT_LOCAL(RenderCommandEncoder, this); + SERIALISE_ELEMENT(texture).Important(); + SERIALISE_ELEMENT(index).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLRenderCommandEncoder::setFragmentTexture(WrappedMTLTexture *texture, NS::UInteger index) +{ + SERIALISE_TIME_CALL(Unwrap(this)->setFragmentTexture(Unwrap(texture), index)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLRenderCommandEncoder_setFragmentTexture); + Serialise_setFragmentTexture(ser, texture, index); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + bufferRecord->MarkResourceFrameReferenced(GetResID(texture), eFrameRef_Read); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLRenderCommandEncoder::Serialise_setViewport(SerialiserType &ser, + MTL::Viewport &viewport) +{ + SERIALISE_ELEMENT_LOCAL(RenderCommandEncoder, this); + SERIALISE_ELEMENT(viewport).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLRenderCommandEncoder::setViewport(MTL::Viewport &viewport) +{ + SERIALISE_TIME_CALL(Unwrap(this)->setViewport(viewport)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLRenderCommandEncoder_setViewport); + Serialise_setViewport(ser, viewport); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +template +bool WrappedMTLRenderCommandEncoder::Serialise_drawPrimitives( + SerialiserType &ser, MTL::PrimitiveType primitiveType, NS::UInteger vertexStart, + NS::UInteger vertexCount, NS::UInteger instanceCount, NS::UInteger baseInstance) +{ + SERIALISE_ELEMENT_LOCAL(RenderCommandEncoder, this); + SERIALISE_ELEMENT(primitiveType); + SERIALISE_ELEMENT(vertexStart); + SERIALISE_ELEMENT(vertexCount).Important(); + SERIALISE_ELEMENT(instanceCount); + SERIALISE_ELEMENT(baseInstance); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLRenderCommandEncoder::drawPrimitives(MTL::PrimitiveType primitiveType, + NS::UInteger vertexStart, + NS::UInteger vertexCount, + NS::UInteger instanceCount, + NS::UInteger baseInstance) +{ + SERIALISE_TIME_CALL(Unwrap(this)->drawPrimitives(primitiveType, vertexStart, vertexCount, + instanceCount, baseInstance)); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLRenderCommandEncoder_drawPrimitives_instanced); + Serialise_drawPrimitives(ser, primitiveType, vertexStart, vertexCount, instanceCount, + baseInstance); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +void WrappedMTLRenderCommandEncoder::drawPrimitives(MTL::PrimitiveType primitiveType, + NS::UInteger vertexStart, + NS::UInteger vertexCount) +{ + drawPrimitives(primitiveType, vertexStart, vertexCount, 1, 0); +} + +void WrappedMTLRenderCommandEncoder::drawPrimitives(MTL::PrimitiveType primitiveType, + NS::UInteger vertexStart, + NS::UInteger vertexCount, + NS::UInteger instanceCount) +{ + drawPrimitives(primitiveType, vertexStart, vertexCount, instanceCount, 0); +} + +template +bool WrappedMTLRenderCommandEncoder::Serialise_endEncoding(SerialiserType &ser) +{ + SERIALISE_ELEMENT_LOCAL(RenderCommandEncoder, this); + + SERIALISE_CHECK_READ_ERRORS(); + + // TODO: implement RD MTL replay + if(IsReplayingAndReading()) + { + } + return true; +} + +void WrappedMTLRenderCommandEncoder::endEncoding() +{ + SERIALISE_TIME_CALL(Unwrap(this)->endEncoding()); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(MetalChunk::MTLRenderCommandEncoder_endEncoding); + Serialise_endEncoding(ser); + chunk = scope.Get(); + } + MetalResourceRecord *bufferRecord = GetRecord(m_CommandBuffer); + bufferRecord->AddChunk(chunk); + } + else + { + // TODO: implement RD MTL replay + } +} + +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLRenderCommandEncoder, void, endEncoding); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLRenderCommandEncoder, void, setRenderPipelineState, + WrappedMTLRenderPipelineState *pipelineState); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLRenderCommandEncoder, void, setFragmentTexture, + WrappedMTLTexture *texture, NS::UInteger index); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLRenderCommandEncoder, void, setViewport, + MTL::Viewport &viewport); +INSTANTIATE_FUNCTION_SERIALISED(WrappedMTLRenderCommandEncoder, void, drawPrimitives, + MTL::PrimitiveType primitiveType, NS::UInteger vertexStart, + NS::UInteger vertexCount, NS::UInteger instanceCount, + NS::UInteger baseInstance); diff --git a/renderdoc/driver/metal/metal_render_command_encoder.h b/renderdoc/driver/metal/metal_render_command_encoder.h new file mode 100644 index 000000000..d7f7677a2 --- /dev/null +++ b/renderdoc/driver/metal/metal_render_command_encoder.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * 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 WrappedMTLRenderCommandEncoder : public WrappedMTLObject +{ +public: + WrappedMTLRenderCommandEncoder(MTL::RenderCommandEncoder *realMTLRenderCommandEncoder, + ResourceId objId, WrappedMTLDevice *wrappedMTLDevice); + + void SetCommandBuffer(WrappedMTLCommandBuffer *commandBuffer) { m_CommandBuffer = commandBuffer; } + DECLARE_FUNCTION_SERIALISED(void, setRenderPipelineState, + WrappedMTLRenderPipelineState *pipelineState); + DECLARE_FUNCTION_SERIALISED(void, setFragmentTexture, WrappedMTLTexture *texture, + NS::UInteger index); + DECLARE_FUNCTION_SERIALISED(void, setViewport, MTL::Viewport &viewport); + DECLARE_FUNCTION_SERIALISED(void, drawPrimitives, MTL::PrimitiveType primitiveType, + NS::UInteger vertexStart, NS::UInteger vertexCount, + NS::UInteger instanceCount, NS::UInteger baseInstance); + void drawPrimitives(MTL::PrimitiveType primitiveType, NS::UInteger vertexStart, + NS::UInteger vertexCount); + void drawPrimitives(MTL::PrimitiveType primitiveType, NS::UInteger vertexStart, + NS::UInteger vertexCount, NS::UInteger instanceCount); + DECLARE_FUNCTION_SERIALISED(void, endEncoding); + + enum + { + TypeEnum = eResRenderCommandEncoder + }; + +private: + WrappedMTLCommandBuffer *m_CommandBuffer; +}; diff --git a/renderdoc/driver/metal/metal_render_command_encoder_bridge.mm b/renderdoc/driver/metal/metal_render_command_encoder_bridge.mm new file mode 100644 index 000000000..1bc99272b --- /dev/null +++ b/renderdoc/driver/metal/metal_render_command_encoder_bridge.mm @@ -0,0 +1,1009 @@ +/****************************************************************************** + * 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_render_command_encoder.h" +#include "metal_types_bridge.h" + +// Wrapper for MTLRenderCommandEncoder +@implementation ObjCBridgeMTLRenderCommandEncoder + +// ObjCWrappedMTLRenderCommandEncoder 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 MTLRenderCommandEncoder to find methods from messages +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + id fwd = self.real; + return [fwd methodSignatureForSelector:aSelector]; +} + +// Forward any unknown messages to the real MTLRenderCommandEncoder +- (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 +{ + self.real.label = value; +} + +- (void)endEncoding +{ + GetWrapped(self)->endEncoding(); +} + +- (void)insertDebugSignpost:(NSString *)string +{ + METAL_NOT_HOOKED(); + return [self.real insertDebugSignpost:string]; +} + +- (void)pushDebugGroup:(NSString *)string +{ + METAL_NOT_HOOKED(); + return [self.real pushDebugGroup:string]; +} + +- (void)popDebugGroup +{ + METAL_NOT_HOOKED(); + return [self.real popDebugGroup]; +} + +// MTLRenderCommandEncoder : based on the protocol defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLRenderCommandEncoder.h + +- (void)setRenderPipelineState:(id)pipelineState +{ + GetWrapped(self)->setRenderPipelineState(GetWrapped(pipelineState)); +} + +- (void)setVertexBytes:(const void *)bytes + length:(NSUInteger)length + atIndex:(NSUInteger)index API_AVAILABLE(macos(10.11), ios(8.3)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexBytes:bytes length:length atIndex:index]; +} + +- (void)setVertexBuffer:(nullable id)buffer + offset:(NSUInteger)offset + atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + return [self.real setVertexBuffer:buffer offset:offset atIndex:index]; +} + +- (void)setVertexBufferOffset:(NSUInteger)offset + atIndex:(NSUInteger)index API_AVAILABLE(macos(10.11), ios(8.3)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexBufferOffset:offset atIndex:index]; +} + +- (void)setVertexBuffers:(const id __nullable[__nonnull])buffers + offsets:(const NSUInteger[__nonnull])offsets + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setVertexBuffers:buffers offsets:offsets withRange:range]; +} + +- (void)setVertexTexture:(nullable id)texture atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + return [self.real setVertexTexture:texture atIndex:index]; +} + +- (void)setVertexTextures:(const id __nullable[__nonnull])textures + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setVertexTextures:textures withRange:range]; +} + +- (void)setVertexSamplerState:(nullable id)sampler atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + return [self.real setVertexSamplerState:sampler atIndex:index]; +} + +- (void)setVertexSamplerStates:(const id __nullable[__nonnull])samplers + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setVertexSamplerStates:samplers withRange:range]; +} + +- (void)setVertexSamplerState:(nullable id)sampler + lodMinClamp:(float)lodMinClamp + lodMaxClamp:(float)lodMaxClamp + atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + return [self.real setVertexSamplerState:sampler + lodMinClamp:lodMinClamp + lodMaxClamp:lodMaxClamp + atIndex:index]; +} + +- (void)setVertexSamplerStates:(const id __nullable[__nonnull])samplers + lodMinClamps:(const float[__nonnull])lodMinClamps + lodMaxClamps:(const float[__nonnull])lodMaxClamps + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setVertexSamplerStates:samplers + lodMinClamps:lodMinClamps + lodMaxClamps:lodMaxClamps + withRange:range]; +} + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setVertexVisibleFunctionTable:(nullable id)functionTable + atBufferIndex:(NSUInteger)bufferIndex API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexVisibleFunctionTable:functionTable atBufferIndex:bufferIndex]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setVertexVisibleFunctionTables: + (const id __nullable[__nonnull])functionTables + withBufferRange:(NSRange)range API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexVisibleFunctionTables:functionTables withBufferRange:range]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setVertexIntersectionFunctionTable: + (nullable id)intersectionFunctionTable + atBufferIndex:(NSUInteger)bufferIndex + API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexIntersectionFunctionTable:intersectionFunctionTable + atBufferIndex:bufferIndex]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setVertexIntersectionFunctionTables: + (const id __nullable[__nonnull])intersectionFunctionTable + withBufferRange:(NSRange)range API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexIntersectionFunctionTables:intersectionFunctionTable + withBufferRange:range]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setVertexAccelerationStructure:(nullable id)accelerationStructure + atBufferIndex:(NSUInteger)bufferIndex API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexAccelerationStructure:accelerationStructure atBufferIndex:bufferIndex]; +} +#endif + +- (void)setViewport:(MTLViewport)viewport +{ + GetWrapped(self)->setViewport((MTL::Viewport &)viewport); +} + +- (void)setViewports:(const MTLViewport[__nonnull])viewports + count:(NSUInteger)count API_AVAILABLE(macos(10.13), ios(12.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setViewports:viewports count:count]; +} + +- (void)setFrontFacingWinding:(MTLWinding)frontFacingWinding +{ + METAL_NOT_HOOKED(); + return [self.real setFrontFacingWinding:frontFacingWinding]; +} + +- (void)setVertexAmplificationCount:(NSUInteger)count + viewMappings:(nullable const MTLVertexAmplificationViewMapping *)viewMappings + API_AVAILABLE(macos(10.15.4), ios(13.0), macCatalyst(13.4)) +{ + METAL_NOT_HOOKED(); + return [self.real setVertexAmplificationCount:count viewMappings:viewMappings]; +} + +- (void)setCullMode:(MTLCullMode)cullMode +{ + METAL_NOT_HOOKED(); + return [self.real setCullMode:cullMode]; +} + +- (void)setDepthClipMode:(MTLDepthClipMode)depthClipMode API_AVAILABLE(macos(10.11), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setDepthClipMode:depthClipMode]; +} + +- (void)setDepthBias:(float)depthBias slopeScale:(float)slopeScale clamp:(float)clamp +{ + METAL_NOT_HOOKED(); + return [self.real setDepthBias:depthBias slopeScale:slopeScale clamp:clamp]; +} + +- (void)setScissorRect:(MTLScissorRect)rect +{ + METAL_NOT_HOOKED(); + return [self.real setScissorRect:rect]; +} + +- (void)setScissorRects:(const MTLScissorRect[__nonnull])scissorRects + count:(NSUInteger)count API_AVAILABLE(macos(10.13), ios(12.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setScissorRects:scissorRects count:count]; +} + +- (void)setTriangleFillMode:(MTLTriangleFillMode)fillMode +{ + METAL_NOT_HOOKED(); + return [self.real setTriangleFillMode:fillMode]; +} + +- (void)setFragmentBytes:(const void *)bytes + length:(NSUInteger)length + atIndex:(NSUInteger)index API_AVAILABLE(macos(10.11), ios(8.3)) +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentBytes:bytes length:length atIndex:index]; +} + +- (void)setFragmentBuffer:(nullable id)buffer + offset:(NSUInteger)offset + atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + [self.real setFragmentBuffer:buffer offset:offset atIndex:index]; +} + +- (void)setFragmentBufferOffset:(NSUInteger)offset + atIndex:(NSUInteger)index API_AVAILABLE(macos(10.11), ios(8.3)) +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentBufferOffset:offset atIndex:index]; +} + +- (void)setFragmentBuffers:(const id __nullable[__nonnull])buffers + offsets:(const NSUInteger[__nonnull])offsets + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentBuffers:buffers offsets:offsets withRange:range]; +} + +- (void)setFragmentTexture:(nullable id)texture atIndex:(NSUInteger)index +{ + GetWrapped(self)->setFragmentTexture(GetWrapped(texture), index); +} + +- (void)setFragmentTextures:(const id __nullable[__nonnull])textures + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentTextures:textures withRange:range]; +} + +- (void)setFragmentSamplerState:(nullable id)sampler atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentSamplerState:sampler atIndex:index]; +} + +- (void)setFragmentSamplerStates:(const id __nullable[__nonnull])samplers + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentSamplerStates:samplers withRange:range]; +} + +- (void)setFragmentSamplerState:(nullable id)sampler + lodMinClamp:(float)lodMinClamp + lodMaxClamp:(float)lodMaxClamp + atIndex:(NSUInteger)index +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentSamplerState:sampler + lodMinClamp:lodMinClamp + lodMaxClamp:lodMaxClamp + atIndex:index]; +} + +- (void)setFragmentSamplerStates:(const id __nullable[__nonnull])samplers + lodMinClamps:(const float[__nonnull])lodMinClamps + lodMaxClamps:(const float[__nonnull])lodMaxClamps + withRange:(NSRange)range +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentSamplerStates:samplers + lodMinClamps:lodMinClamps + lodMaxClamps:lodMaxClamps + withRange:range]; +} + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setFragmentVisibleFunctionTable:(nullable id)functionTable + atBufferIndex:(NSUInteger)bufferIndex API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentVisibleFunctionTable:functionTable atBufferIndex:bufferIndex]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setFragmentVisibleFunctionTables: + (const id __nullable[__nonnull])functionTables + withBufferRange:(NSRange)range API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentVisibleFunctionTables:functionTables withBufferRange:range]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setFragmentIntersectionFunctionTable: + (nullable id)intersectionFunctionTable + atBufferIndex:(NSUInteger)bufferIndex + API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentIntersectionFunctionTable:intersectionFunctionTable + atBufferIndex:bufferIndex]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setFragmentIntersectionFunctionTables: + (const id __nullable[__nonnull])intersectionFunctionTable + withBufferRange:(NSRange)range API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setFragmentIntersectionFunctionTables:intersectionFunctionTable + withBufferRange:range]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setFragmentAccelerationStructure:(nullable id)accelerationStructure + atBufferIndex:(NSUInteger)bufferIndex + API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return + [self.real setFragmentAccelerationStructure:accelerationStructure atBufferIndex:bufferIndex]; +} +#endif + +- (void)setBlendColorRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha +{ + METAL_NOT_HOOKED(); + return [self.real setBlendColorRed:red green:green blue:blue alpha:alpha]; +} + +- (void)setDepthStencilState:(nullable id)depthStencilState +{ + METAL_NOT_HOOKED(); + return [self.real setDepthStencilState:depthStencilState]; +} + +- (void)setStencilReferenceValue:(uint32_t)referenceValue +{ + METAL_NOT_HOOKED(); + return [self.real setStencilReferenceValue:referenceValue]; +} + +- (void)setStencilFrontReferenceValue:(uint32_t)frontReferenceValue + backReferenceValue:(uint32_t)backReferenceValue + API_AVAILABLE(macos(10.11), ios(9.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setStencilFrontReferenceValue:frontReferenceValue + backReferenceValue:backReferenceValue]; +} + +- (void)setVisibilityResultMode:(MTLVisibilityResultMode)mode offset:(NSUInteger)offset +{ + METAL_NOT_HOOKED(); + return [self.real setVisibilityResultMode:mode offset:offset]; +} + +- (void)setColorStoreAction:(MTLStoreAction)storeAction + atIndex:(NSUInteger)colorAttachmentIndex API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setColorStoreAction:storeAction atIndex:colorAttachmentIndex]; +} + +- (void)setDepthStoreAction:(MTLStoreAction)storeAction API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setDepthStoreAction:storeAction]; +} + +- (void)setStencilStoreAction:(MTLStoreAction)storeAction API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setStencilStoreAction:storeAction]; +} + +- (void)setColorStoreActionOptions:(MTLStoreActionOptions)storeActionOptions + atIndex:(NSUInteger)colorAttachmentIndex + API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setColorStoreActionOptions:storeActionOptions atIndex:colorAttachmentIndex]; +} + +- (void)setDepthStoreActionOptions:(MTLStoreActionOptions)storeActionOptions + API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setDepthStoreActionOptions:storeActionOptions]; +} + +- (void)setStencilStoreActionOptions:(MTLStoreActionOptions)storeActionOptions + API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setStencilStoreActionOptions:storeActionOptions]; +} + +- (void)drawPrimitives:(MTLPrimitiveType)primitiveType + vertexStart:(NSUInteger)vertexStart + vertexCount:(NSUInteger)vertexCount + instanceCount:(NSUInteger)instanceCount +{ + GetWrapped(self)->drawPrimitives((MTL::PrimitiveType)primitiveType, vertexStart, vertexCount, + instanceCount); +} + +- (void)drawPrimitives:(MTLPrimitiveType)primitiveType + vertexStart:(NSUInteger)vertexStart + vertexCount:(NSUInteger)vertexCount +{ + GetWrapped(self)->drawPrimitives((MTL::PrimitiveType)primitiveType, vertexStart, vertexCount); +} + +- (void)drawIndexedPrimitives:(MTLPrimitiveType)primitiveType + indexCount:(NSUInteger)indexCount + indexType:(MTLIndexType)indexType + indexBuffer:(id)indexBuffer + indexBufferOffset:(NSUInteger)indexBufferOffset + instanceCount:(NSUInteger)instanceCount +{ + METAL_NOT_HOOKED(); + return [self.real drawIndexedPrimitives:primitiveType + indexCount:indexCount + indexType:indexType + indexBuffer:indexBuffer + indexBufferOffset:indexBufferOffset + instanceCount:instanceCount]; +} + +- (void)drawIndexedPrimitives:(MTLPrimitiveType)primitiveType + indexCount:(NSUInteger)indexCount + indexType:(MTLIndexType)indexType + indexBuffer:(id)indexBuffer + indexBufferOffset:(NSUInteger)indexBufferOffset +{ + METAL_NOT_HOOKED(); + return [self.real drawIndexedPrimitives:primitiveType + indexCount:indexCount + indexType:indexType + indexBuffer:indexBuffer + indexBufferOffset:indexBufferOffset]; +} + +- (void)drawPrimitives:(MTLPrimitiveType)primitiveType + vertexStart:(NSUInteger)vertexStart + vertexCount:(NSUInteger)vertexCount + instanceCount:(NSUInteger)instanceCount + baseInstance:(NSUInteger)baseInstance API_AVAILABLE(macos(10.11), ios(9.0)) +{ + GetWrapped(self)->drawPrimitives((MTL::PrimitiveType)primitiveType, vertexStart, vertexCount, + instanceCount, baseInstance); +} + +- (void)drawIndexedPrimitives:(MTLPrimitiveType)primitiveType + indexCount:(NSUInteger)indexCount + indexType:(MTLIndexType)indexType + indexBuffer:(id)indexBuffer + indexBufferOffset:(NSUInteger)indexBufferOffset + instanceCount:(NSUInteger)instanceCount + baseVertex:(NSInteger)baseVertex + baseInstance:(NSUInteger)baseInstance API_AVAILABLE(macos(10.11), ios(9.0)) +{ + METAL_NOT_HOOKED(); + return [self.real drawIndexedPrimitives:primitiveType + indexCount:indexCount + indexType:indexType + indexBuffer:indexBuffer + indexBufferOffset:indexBufferOffset + instanceCount:instanceCount + baseVertex:baseVertex + baseInstance:baseInstance]; +} + +- (void)drawPrimitives:(MTLPrimitiveType)primitiveType + indirectBuffer:(id)indirectBuffer + indirectBufferOffset:(NSUInteger)indirectBufferOffset API_AVAILABLE(macos(10.11), ios(9.0)) +{ + METAL_NOT_HOOKED(); + return [self.real drawPrimitives:primitiveType + indirectBuffer:indirectBuffer + indirectBufferOffset:indirectBufferOffset]; +} + +- (void)drawIndexedPrimitives:(MTLPrimitiveType)primitiveType + indexType:(MTLIndexType)indexType + indexBuffer:(id)indexBuffer + indexBufferOffset:(NSUInteger)indexBufferOffset + indirectBuffer:(id)indirectBuffer + indirectBufferOffset:(NSUInteger)indirectBufferOffset API_AVAILABLE(macos(10.11), ios(9.0)) +{ + METAL_NOT_HOOKED(); + return [self.real drawIndexedPrimitives:primitiveType + indexType:indexType + indexBuffer:indexBuffer + indexBufferOffset:indexBufferOffset + indirectBuffer:indirectBuffer + indirectBufferOffset:indirectBufferOffset]; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +- (void)textureBarrier + API_DEPRECATED_WITH_REPLACEMENT("memoryBarrierWithScope:MTLBarrierScopeRenderTargets", + macos(10.11, 10.14))API_UNAVAILABLE(ios) +{ + METAL_NOT_HOOKED(); + return [self.real textureBarrier]; +} +#pragma clang diagnostic pop + +- (void)updateFence:(id)fence + afterStages:(MTLRenderStages)stages API_AVAILABLE(macos(10.13), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real updateFence:fence afterStages:stages]; +} + +- (void)waitForFence:(id)fence + beforeStages:(MTLRenderStages)stages API_AVAILABLE(macos(10.13), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real waitForFence:fence beforeStages:stages]; +} + +- (void)setTessellationFactorBuffer:(nullable id)buffer + offset:(NSUInteger)offset + instanceStride:(NSUInteger)instanceStride API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTessellationFactorBuffer:buffer offset:offset instanceStride:instanceStride]; +} + +- (void)setTessellationFactorScale:(float)scale API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTessellationFactorScale:scale]; +} + +- (void)drawPatches:(NSUInteger)numberOfPatchControlPoints + patchStart:(NSUInteger)patchStart + patchCount:(NSUInteger)patchCount + patchIndexBuffer:(nullable id)patchIndexBuffer + patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset + instanceCount:(NSUInteger)instanceCount + baseInstance:(NSUInteger)baseInstance API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real drawPatches:numberOfPatchControlPoints + patchStart:patchStart + patchCount:patchCount + patchIndexBuffer:patchIndexBuffer + patchIndexBufferOffset:patchIndexBufferOffset + instanceCount:instanceCount + baseInstance:baseInstance]; +} + +- (void)drawPatches:(NSUInteger)numberOfPatchControlPoints + patchIndexBuffer:(nullable id)patchIndexBuffer + patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset + indirectBuffer:(id)indirectBuffer + indirectBufferOffset:(NSUInteger)indirectBufferOffset + API_AVAILABLE(macos(10.12), ios(12.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real drawPatches:numberOfPatchControlPoints + patchIndexBuffer:patchIndexBuffer + patchIndexBufferOffset:patchIndexBufferOffset + indirectBuffer:indirectBuffer + indirectBufferOffset:indirectBufferOffset]; +} + +- (void)drawIndexedPatches:(NSUInteger)numberOfPatchControlPoints + patchStart:(NSUInteger)patchStart + patchCount:(NSUInteger)patchCount + patchIndexBuffer:(nullable id)patchIndexBuffer + patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset + controlPointIndexBuffer:(id)controlPointIndexBuffer + controlPointIndexBufferOffset:(NSUInteger)controlPointIndexBufferOffset + instanceCount:(NSUInteger)instanceCount + baseInstance:(NSUInteger)baseInstance API_AVAILABLE(macos(10.12), ios(10.0)) +{ + METAL_NOT_HOOKED(); + return [self.real drawIndexedPatches:numberOfPatchControlPoints + patchStart:patchStart + patchCount:patchCount + patchIndexBuffer:patchIndexBuffer + patchIndexBufferOffset:patchIndexBufferOffset + controlPointIndexBuffer:controlPointIndexBuffer + controlPointIndexBufferOffset:controlPointIndexBufferOffset + instanceCount:instanceCount + baseInstance:baseInstance]; +} + +- (void)drawIndexedPatches:(NSUInteger)numberOfPatchControlPoints + patchIndexBuffer:(nullable id)patchIndexBuffer + patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset + controlPointIndexBuffer:(id)controlPointIndexBuffer + controlPointIndexBufferOffset:(NSUInteger)controlPointIndexBufferOffset + indirectBuffer:(id)indirectBuffer + indirectBufferOffset:(NSUInteger)indirectBufferOffset + API_AVAILABLE(macos(10.12), ios(12.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real drawIndexedPatches:numberOfPatchControlPoints + patchIndexBuffer:patchIndexBuffer + patchIndexBufferOffset:patchIndexBufferOffset + controlPointIndexBuffer:controlPointIndexBuffer + controlPointIndexBufferOffset:controlPointIndexBufferOffset + indirectBuffer:indirectBuffer + indirectBufferOffset:indirectBufferOffset]; +} + +- (NSUInteger)tileWidth API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + return self.real.tileWidth; +} + +- (NSUInteger)tileHeight API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + return self.real.tileHeight; +} + +- (void)setTileBytes:(const void *)bytes + length:(NSUInteger)length + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileBytes:bytes length:length atIndex:index]; +} + +- (void)setTileBuffer:(nullable id)buffer + offset:(NSUInteger)offset + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileBuffer:buffer offset:offset atIndex:index]; +} + +- (void)setTileBufferOffset:(NSUInteger)offset + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileBufferOffset:offset atIndex:index]; +} + +- (void)setTileBuffers:(const id __nullable[__nonnull])buffers + offsets:(const NSUInteger[__nonnull])offsets + withRange:(NSRange)range + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileBuffers:buffers offsets:offsets withRange:range]; +} + +- (void)setTileTexture:(nullable id)texture + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileTexture:texture atIndex:index]; +} + +- (void)setTileTextures:(const id __nullable[__nonnull])textures + withRange:(NSRange)range + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileTextures:textures withRange:range]; +} + +- (void)setTileSamplerState:(nullable id)sampler + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileSamplerState:sampler atIndex:index]; +} + +- (void)setTileSamplerStates:(const id __nullable[__nonnull])samplers + withRange:(NSRange)range + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileSamplerStates:samplers withRange:range]; +} + +- (void)setTileSamplerState:(nullable id)sampler + lodMinClamp:(float)lodMinClamp + lodMaxClamp:(float)lodMaxClamp + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileSamplerState:sampler + lodMinClamp:lodMinClamp + lodMaxClamp:lodMaxClamp + atIndex:index]; +} + +- (void)setTileSamplerStates:(const id __nullable[__nonnull])samplers + lodMinClamps:(const float[__nonnull])lodMinClamps + lodMaxClamps:(const float[__nonnull])lodMaxClamps + withRange:(NSRange)range + API_AVAILABLE(ios(11.0), tvos(14.5), macos(11.0), macCatalyst(14.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileSamplerStates:samplers + lodMinClamps:lodMinClamps + lodMaxClamps:lodMaxClamps + withRange:range]; +} + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setTileVisibleFunctionTable:(nullable id)functionTable + atBufferIndex:(NSUInteger)bufferIndex API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileVisibleFunctionTable:functionTable atBufferIndex:bufferIndex]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setTileVisibleFunctionTables:(const id __nullable[__nonnull])functionTables + withBufferRange:(NSRange)range API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileVisibleFunctionTables:functionTables withBufferRange:range]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setTileIntersectionFunctionTable: + (nullable id)intersectionFunctionTable + atBufferIndex:(NSUInteger)bufferIndex + API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileIntersectionFunctionTable:intersectionFunctionTable + atBufferIndex:bufferIndex]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setTileIntersectionFunctionTables: + (const id __nullable[__nonnull])intersectionFunctionTable + withBufferRange:(NSRange)range API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return + [self.real setTileIntersectionFunctionTables:intersectionFunctionTable withBufferRange:range]; +} +#endif + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0 +- (void)setTileAccelerationStructure:(nullable id)accelerationStructure + atBufferIndex:(NSUInteger)bufferIndex API_AVAILABLE(macos(12.0), ios(15.0)) +{ + METAL_NOT_HOOKED(); + return [self.real setTileAccelerationStructure:accelerationStructure atBufferIndex:bufferIndex]; +} +#endif + +- (void)dispatchThreadsPerTile:(MTLSize)threadsPerTile + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real dispatchThreadsPerTile:threadsPerTile]; +} + +- (void)setThreadgroupMemoryLength:(NSUInteger)length + offset:(NSUInteger)offset + atIndex:(NSUInteger)index + API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5)) +{ + METAL_NOT_HOOKED(); + return [self.real setThreadgroupMemoryLength:length offset:offset atIndex:index]; +} + +- (void)useResource:(id)resource + usage:(MTLResourceUsage)usage API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useResource:resource usage:usage]; +} + +- (void)useResources:(const id __nonnull[__nonnull])resources + count:(NSUInteger)count + usage:(MTLResourceUsage)usage API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useResources:resources count:count usage:usage]; +} + +- (void)useResource:(id)resource + usage:(MTLResourceUsage)usage + stages:(MTLRenderStages)stages API_AVAILABLE(macos(10.15), ios(13.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useResource:resource usage:usage stages:stages]; +} + +- (void)useResources:(const id __nonnull[__nonnull])resources + count:(NSUInteger)count + usage:(MTLResourceUsage)usage + stages:(MTLRenderStages)stages API_AVAILABLE(macos(10.15), ios(13.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useResources:resources count:count usage:usage stages:stages]; +} + +- (void)useHeap:(id)heap API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useHeap:heap]; +} + +- (void)useHeaps:(const id __nonnull[__nonnull])heaps + count:(NSUInteger)count API_AVAILABLE(macos(10.13), ios(11.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useHeaps:heaps count:count]; +} + +- (void)useHeap:(id)heap + stages:(MTLRenderStages)stages API_AVAILABLE(macos(10.15), ios(13.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useHeap:heap stages:stages]; +} + +- (void)useHeaps:(const id __nonnull[__nonnull])heaps + count:(NSUInteger)count + stages:(MTLRenderStages)stages API_AVAILABLE(macos(10.15), ios(13.0)) +{ + METAL_NOT_HOOKED(); + return [self.real useHeaps:heaps count:count stages:stages]; +} + +- (void)executeCommandsInBuffer:(id)indirectCommandBuffer + withRange:(NSRange)executionRange API_AVAILABLE(macos(10.14), ios(12.0)) +{ + METAL_NOT_HOOKED(); + return [self.real executeCommandsInBuffer:indirectCommandBuffer withRange:executionRange]; +} + +- (void)executeCommandsInBuffer:(id)indirectCommandbuffer + indirectBuffer:(id)indirectRangeBuffer + indirectBufferOffset:(NSUInteger)indirectBufferOffset + API_AVAILABLE(macos(10.14), macCatalyst(13.0), ios(13.0)) +{ + METAL_NOT_HOOKED(); + return [self.real executeCommandsInBuffer:indirectCommandbuffer + indirectBuffer:indirectRangeBuffer + indirectBufferOffset:indirectBufferOffset]; +} + +- (void)memoryBarrierWithScope:(MTLBarrierScope)scope + afterStages:(MTLRenderStages)after + beforeStages:(MTLRenderStages)before + API_AVAILABLE(macos(10.14), macCatalyst(13.0))API_UNAVAILABLE(ios) +{ + METAL_NOT_HOOKED(); + return [self.real memoryBarrierWithScope:scope afterStages:after beforeStages:before]; +} + +- (void)memoryBarrierWithResources:(const id __nonnull[__nonnull])resources + count:(NSUInteger)count + afterStages:(MTLRenderStages)after + beforeStages:(MTLRenderStages)before + API_AVAILABLE(macos(10.14), macCatalyst(13.0))API_UNAVAILABLE(ios) +{ + METAL_NOT_HOOKED(); + return [self.real memoryBarrierWithResources:resources + count:count + afterStages:after + beforeStages:before]; +} + +- (void)sampleCountersInBuffer:(id)sampleBuffer + atSampleIndex:(NSUInteger)sampleIndex + withBarrier:(BOOL)barrier API_AVAILABLE(macos(10.15), ios(14.0)) +{ + METAL_NOT_HOOKED(); + return + [self.real sampleCountersInBuffer:sampleBuffer atSampleIndex:sampleIndex withBarrier:barrier]; +} + +@end diff --git a/renderdoc/driver/metal/metal_resources.cpp b/renderdoc/driver/metal/metal_resources.cpp index 4f22ce23b..8a4c71cbc 100644 --- a/renderdoc/driver/metal/metal_resources.cpp +++ b/renderdoc/driver/metal/metal_resources.cpp @@ -28,6 +28,7 @@ #include "metal_device.h" #include "metal_function.h" #include "metal_library.h" +#include "metal_render_command_encoder.h" #include "metal_render_pipeline_state.h" #include "metal_texture.h" diff --git a/renderdoc/driver/metal/metal_resources.h b/renderdoc/driver/metal/metal_resources.h index 7ab6db884..ca9096fb0 100644 --- a/renderdoc/driver/metal/metal_resources.h +++ b/renderdoc/driver/metal/metal_resources.h @@ -41,7 +41,8 @@ enum MetalResourceType eResLibrary, eResFunction, eResRenderPipelineState, - eResTexture + eResTexture, + eResRenderCommandEncoder, }; DECLARE_REFLECTION_ENUM(MetalResourceType); @@ -113,7 +114,7 @@ METALCPP_WRAPPED_PROTOCOLS(WRAPPED_TYPE_HELPERS) struct MetalCmdBufferRecordingInfo { MetalCmdBufferRecordingInfo(WrappedMTLCommandQueue *parentQueue) - : queue(parentQueue), present(false), isEncoding(false), drawable(NULL) + : queue(parentQueue), present(false), drawable(NULL) { } MetalCmdBufferRecordingInfo() = delete; @@ -127,8 +128,6 @@ struct MetalCmdBufferRecordingInfo MTL::Drawable *drawable; // AdvanceFrame/Present should be called after this buffer is committed. bool present; - // an encoder is active : waiting for endEncoding to be called - bool isEncoding; }; struct MetalResourceRecord : public ResourceRecord diff --git a/renderdoc/driver/metal/metal_serialise.cpp b/renderdoc/driver/metal/metal_serialise.cpp index bfb811df7..e0dd78833 100644 --- a/renderdoc/driver/metal/metal_serialise.cpp +++ b/renderdoc/driver/metal/metal_serialise.cpp @@ -28,6 +28,7 @@ #include "metal_function.h" #include "metal_library.h" #include "metal_manager.h" +#include "metal_render_command_encoder.h" #include "metal_render_pipeline_state.h" #include "metal_resources.h" #include "metal_texture.h" @@ -102,6 +103,33 @@ void DoSerialise(SerialiserType &ser, MTL::TextureSwizzleChannels &el) SERIALISE_MEMBER(alpha); } +template +void DoSerialise(SerialiserType &ser, MTL::ClearColor &el) +{ + SERIALISE_MEMBER(red); + SERIALISE_MEMBER(green); + SERIALISE_MEMBER(blue); + SERIALISE_MEMBER(alpha); +} + +template +void DoSerialise(SerialiserType &ser, MTL::Viewport &el) +{ + SERIALISE_MEMBER(originX); + SERIALISE_MEMBER(originY); + SERIALISE_MEMBER(width); + SERIALISE_MEMBER(height); + SERIALISE_MEMBER(znear); + SERIALISE_MEMBER(zfar); +} + +template +void DoSerialise(SerialiserType &ser, MTL::SamplePosition &el) +{ + SERIALISE_MEMBER(x); + SERIALISE_MEMBER(y); +} + template void DoSerialise(SerialiserType &ser, RDMTL::TextureDescriptor &el) { @@ -221,8 +249,83 @@ void DoSerialise(SerialiserType &ser, RDMTL::RenderPipelineDescriptor &el) SERIALISE_MEMBER(maxFragmentCallStackDepth); } +template +void DoSerialise(SerialiserType &ser, RDMTL::RenderPassAttachmentDescriptor &el) +{ + SERIALISE_MEMBER(texture); + SERIALISE_MEMBER(level); + SERIALISE_MEMBER(slice); + SERIALISE_MEMBER(depthPlane); + SERIALISE_MEMBER(resolveTexture); + SERIALISE_MEMBER(resolveLevel); + SERIALISE_MEMBER(resolveSlice); + SERIALISE_MEMBER(resolveDepthPlane); + SERIALISE_MEMBER(loadAction); + SERIALISE_MEMBER(storeAction); + SERIALISE_MEMBER(storeActionOptions); +}; + +template +void DoSerialise(SerialiserType &ser, RDMTL::RenderPassColorAttachmentDescriptor &el) +{ + DoSerialise(ser, (RDMTL::RenderPassAttachmentDescriptor &)el); + SERIALISE_MEMBER(clearColor); +}; + +template +void DoSerialise(SerialiserType &ser, RDMTL::RenderPassDepthAttachmentDescriptor &el) +{ + DoSerialise(ser, (RDMTL::RenderPassAttachmentDescriptor &)el); + SERIALISE_MEMBER(clearDepth); + SERIALISE_MEMBER(depthResolveFilter); +}; + +template +void DoSerialise(SerialiserType &ser, RDMTL::RenderPassStencilAttachmentDescriptor &el) +{ + DoSerialise(ser, (RDMTL::RenderPassAttachmentDescriptor &)el); + SERIALISE_MEMBER(clearStencil); + SERIALISE_MEMBER(stencilResolveFilter); +}; + +template +void DoSerialise(SerialiserType &ser, RDMTL::RenderPassSampleBufferAttachmentDescriptor &el) +{ + // TODO: when WrappedMTLCounterSampleBuffer exists + // SERIALISE_MEMBER(sampleBuffer); + SERIALISE_MEMBER(startOfVertexSampleIndex); + SERIALISE_MEMBER(endOfVertexSampleIndex); + SERIALISE_MEMBER(startOfFragmentSampleIndex); + SERIALISE_MEMBER(endOfFragmentSampleIndex); +}; + +template +void DoSerialise(SerialiserType &ser, RDMTL::RenderPassDescriptor &el) +{ + SERIALISE_MEMBER(colorAttachments); + SERIALISE_MEMBER(depthAttachment); + SERIALISE_MEMBER(stencilAttachment); + // TODO: when WrappedMTLBuffer exists + // WrappedMTLBuffer *visibilityResultBuffer; + SERIALISE_MEMBER(renderTargetArrayLength); + SERIALISE_MEMBER(imageblockSampleLength); + SERIALISE_MEMBER(threadgroupMemoryLength); + SERIALISE_MEMBER(tileWidth); + SERIALISE_MEMBER(tileHeight); + SERIALISE_MEMBER(defaultRasterSampleCount); + SERIALISE_MEMBER(renderTargetWidth); + SERIALISE_MEMBER(renderTargetHeight); + SERIALISE_MEMBER(samplePositions); + // TODO: when WrappedRasterizationRateMap exists + // SERIALISE_MEMBER(rasterizationRateMap); + SERIALISE_MEMBER(sampleBufferAttachments); +}; + INSTANTIATE_SERIALISE_TYPE(NS::String *); INSTANTIATE_SERIALISE_TYPE(MTL::TextureSwizzleChannels); +INSTANTIATE_SERIALISE_TYPE(MTL::ClearColor); +INSTANTIATE_SERIALISE_TYPE(MTL::SamplePosition); +INSTANTIATE_SERIALISE_TYPE(MTL::Viewport); INSTANTIATE_SERIALISE_TYPE(RDMTL::TextureDescriptor); INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPipelineColorAttachmentDescriptor); INSTANTIATE_SERIALISE_TYPE(RDMTL::PipelineBufferDescriptor); @@ -232,3 +335,8 @@ INSTANTIATE_SERIALISE_TYPE(RDMTL::VertexDescriptor); INSTANTIATE_SERIALISE_TYPE(RDMTL::FunctionGroup); INSTANTIATE_SERIALISE_TYPE(RDMTL::LinkedFunctions); INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPipelineDescriptor); +INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPassAttachmentDescriptor); +INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPassColorAttachmentDescriptor); +INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPassDepthAttachmentDescriptor); +INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPassStencilAttachmentDescriptor); +INSTANTIATE_SERIALISE_TYPE(RDMTL::RenderPassDescriptor); diff --git a/renderdoc/driver/metal/metal_stringise.cpp b/renderdoc/driver/metal/metal_stringise.cpp index 82e6a5214..0eaadae0d 100644 --- a/renderdoc/driver/metal/metal_stringise.cpp +++ b/renderdoc/driver/metal/metal_stringise.cpp @@ -486,6 +486,58 @@ rdcstr DoStringise(const MTL::TextureSwizzle &el) END_ENUM_STRINGISE() } +template <> +rdcstr DoStringise(const MTL::PrimitiveType &el) +{ + BEGIN_ENUM_STRINGISE(MTL::PrimitiveType) + { + MTL_STRINGISE_ENUM(PrimitiveTypePoint); + MTL_STRINGISE_ENUM(PrimitiveTypeLine); + MTL_STRINGISE_ENUM(PrimitiveTypeLineStrip); + MTL_STRINGISE_ENUM(PrimitiveTypeTriangle); + MTL_STRINGISE_ENUM(PrimitiveTypeTriangleStrip); + } + END_ENUM_STRINGISE() +} + +template <> +rdcstr DoStringise(const MTL::LoadAction &el) +{ + BEGIN_ENUM_STRINGISE(MTL::LoadAction) + { + MTL_STRINGISE_ENUM(LoadActionDontCare); + MTL_STRINGISE_ENUM(LoadActionLoad); + MTL_STRINGISE_ENUM(LoadActionClear); + } + END_ENUM_STRINGISE() +} + +template <> +rdcstr DoStringise(const MTL::StoreAction &el) +{ + BEGIN_ENUM_STRINGISE(MTL::StoreAction) + { + MTL_STRINGISE_ENUM(StoreActionDontCare); + MTL_STRINGISE_ENUM(StoreActionStore); + MTL_STRINGISE_ENUM(StoreActionMultisampleResolve); + MTL_STRINGISE_ENUM(StoreActionStoreAndMultisampleResolve); + MTL_STRINGISE_ENUM(StoreActionUnknown); + MTL_STRINGISE_ENUM(StoreActionCustomSampleDepthStore); + } + END_ENUM_STRINGISE() +} + +template <> +rdcstr DoStringise(const MTL::StoreActionOptions &el) +{ + BEGIN_BITFIELD_STRINGISE(MTL::StoreActionOptions) + { + MTL_STRINGISE_BITFIELD_VALUE(StoreActionOptionNone); + MTL_STRINGISE_BITFIELD_BIT(StoreActionOptionCustomSamplePositions); + } + END_BITFIELD_STRINGISE() +} + template <> rdcstr DoStringise(const MTL::BlendFactor &el) { @@ -542,3 +594,26 @@ rdcstr DoStringise(const MTL::ColorWriteMask &el) } END_BITFIELD_STRINGISE() } + +template <> +rdcstr DoStringise(const MTL::MultisampleDepthResolveFilter &el) +{ + BEGIN_ENUM_STRINGISE(MTL::MultisampleDepthResolveFilter) + { + MTL_STRINGISE_ENUM(MultisampleDepthResolveFilterSample0); + MTL_STRINGISE_ENUM(MultisampleDepthResolveFilterMin); + MTL_STRINGISE_ENUM(MultisampleDepthResolveFilterMax); + } + END_ENUM_STRINGISE() +} + +template <> +rdcstr DoStringise(const MTL::MultisampleStencilResolveFilter &el) +{ + BEGIN_ENUM_STRINGISE(MTL::MultisampleStencilResolveFilter) + { + MTL_STRINGISE_ENUM(MultisampleStencilResolveFilterSample0); + MTL_STRINGISE_ENUM(MultisampleStencilResolveFilterDepthResolvedSample); + } + END_ENUM_STRINGISE() +} diff --git a/renderdoc/driver/metal/metal_types.cpp b/renderdoc/driver/metal/metal_types.cpp index e0bd7ef01..a21fff023 100644 --- a/renderdoc/driver/metal/metal_types.cpp +++ b/renderdoc/driver/metal/metal_types.cpp @@ -29,6 +29,7 @@ #include "metal_function.h" #include "metal_library.h" #include "metal_manager.h" +#include "metal_render_command_encoder.h" #include "metal_render_pipeline_state.h" #include "metal_resources.h" #include "metal_texture.h" @@ -93,6 +94,21 @@ static bool ValidData(MTL::RenderPipelineColorAttachmentDescriptor *descriptor) return true; } +static bool ValidData(MTL::RenderPassColorAttachmentDescriptor *descriptor) +{ + MTL::RenderPassAttachmentDescriptor *base = (MTL::RenderPassAttachmentDescriptor *)descriptor; + if(!base->texture() && !base->resolveTexture()) + return false; + return true; +} + +static bool ValidData(MTL::RenderPassSampleBufferAttachmentDescriptor *descriptor) +{ + if(!descriptor->sampleBuffer()) + return false; + return true; +} + template static void GetWrappedNSArray(rdcarray::Outer *> &to, NS::Array *from) { @@ -406,4 +422,150 @@ RenderPipelineDescriptor::operator MTL::RenderPipelineDescriptor *() return objc; } +RenderPassAttachmentDescriptor::RenderPassAttachmentDescriptor(MTL::RenderPassAttachmentDescriptor *objc) + : texture(GetWrapped(objc->texture())), + level(objc->level()), + slice(objc->slice()), + depthPlane(objc->depthPlane()), + resolveTexture(GetWrapped(objc->resolveTexture())), + resolveLevel(objc->resolveLevel()), + resolveSlice(objc->resolveSlice()), + resolveDepthPlane(objc->resolveDepthPlane()), + loadAction(objc->loadAction()), + storeAction(objc->storeAction()), + storeActionOptions(objc->storeActionOptions()) +{ +} + +void RenderPassAttachmentDescriptor::CopyTo(MTL::RenderPassAttachmentDescriptor *objc) +{ + objc->setTexture(Unwrap(texture)); + objc->setLevel(level); + objc->setSlice(slice); + objc->setDepthPlane(depthPlane); + objc->setResolveTexture(Unwrap(resolveTexture)); + objc->setResolveLevel(resolveLevel); + objc->setResolveSlice(resolveSlice); + objc->setResolveDepthPlane(resolveDepthPlane); + objc->setLoadAction(loadAction); + objc->setStoreAction(storeAction); + objc->setStoreActionOptions(storeActionOptions); +} + +RenderPassColorAttachmentDescriptor::RenderPassColorAttachmentDescriptor( + MTL::RenderPassColorAttachmentDescriptor *objc) + : RenderPassAttachmentDescriptor((MTL::RenderPassAttachmentDescriptor *)objc), + clearColor(objc->clearColor()) +{ +} + +void RenderPassColorAttachmentDescriptor::CopyTo(MTL::RenderPassColorAttachmentDescriptor *objc) +{ + ((RenderPassAttachmentDescriptor *)this)->CopyTo((MTL::RenderPassAttachmentDescriptor *)objc); + objc->setClearColor(clearColor); +} + +RenderPassDepthAttachmentDescriptor::RenderPassDepthAttachmentDescriptor( + MTL::RenderPassDepthAttachmentDescriptor *objc) + : RenderPassAttachmentDescriptor((MTL::RenderPassAttachmentDescriptor *)objc), + clearDepth(objc->clearDepth()), + depthResolveFilter(objc->depthResolveFilter()) +{ +} + +void RenderPassDepthAttachmentDescriptor::CopyTo(MTL::RenderPassDepthAttachmentDescriptor *objc) +{ + ((RenderPassAttachmentDescriptor *)this)->CopyTo((MTL::RenderPassAttachmentDescriptor *)objc); + objc->setClearDepth(clearDepth); + objc->setDepthResolveFilter(depthResolveFilter); +} + +RenderPassStencilAttachmentDescriptor::RenderPassStencilAttachmentDescriptor( + MTL::RenderPassStencilAttachmentDescriptor *objc) + : RenderPassAttachmentDescriptor((MTL::RenderPassAttachmentDescriptor *)objc), + clearStencil(objc->clearStencil()), + stencilResolveFilter(objc->stencilResolveFilter()) +{ +} + +void RenderPassStencilAttachmentDescriptor::CopyTo(MTL::RenderPassStencilAttachmentDescriptor *objc) +{ + ((RenderPassAttachmentDescriptor *)this)->CopyTo((MTL::RenderPassAttachmentDescriptor *)objc); + objc->setClearStencil(clearStencil); + objc->setStencilResolveFilter(stencilResolveFilter); +} + +RenderPassSampleBufferAttachmentDescriptor::RenderPassSampleBufferAttachmentDescriptor( + MTL::RenderPassSampleBufferAttachmentDescriptor *objc) + : // TODO: when WrappedMTLCounterSampleBuffer exists + // sampleBuffer(GetWrapped(objc->sampleBuffer())), + startOfVertexSampleIndex(objc->startOfVertexSampleIndex()), + endOfVertexSampleIndex(objc->endOfVertexSampleIndex()), + startOfFragmentSampleIndex(objc->startOfFragmentSampleIndex()), + endOfFragmentSampleIndex(objc->endOfFragmentSampleIndex()) +{ +} + +void RenderPassSampleBufferAttachmentDescriptor::CopyTo( + MTL::RenderPassSampleBufferAttachmentDescriptor *objc) +{ + // TODO: when WrappedMTLCounterSampleBuffer exists + // objc->setSampleBuffer(Unwrap(sampleBuffer)); + objc->setStartOfVertexSampleIndex(startOfVertexSampleIndex); + objc->setEndOfVertexSampleIndex(endOfVertexSampleIndex); + objc->setStartOfFragmentSampleIndex(startOfFragmentSampleIndex); + objc->setEndOfFragmentSampleIndex(endOfFragmentSampleIndex); +} + +RenderPassDescriptor::RenderPassDescriptor(MTL::RenderPassDescriptor *objc) + : depthAttachment(objc->depthAttachment()), + stencilAttachment(objc->stencilAttachment()), + // TODO: when WrappedMTLBuffer exists + // visibilityResultBuffer(GetWrapped(objc->visibilityResultBuffer())), + renderTargetArrayLength(objc->renderTargetArrayLength()), + imageblockSampleLength(objc->imageblockSampleLength()), + threadgroupMemoryLength(objc->threadgroupMemoryLength()), + tileWidth(objc->tileWidth()), + tileHeight(objc->tileHeight()), + defaultRasterSampleCount(objc->defaultRasterSampleCount()), + renderTargetWidth(objc->renderTargetWidth()), + renderTargetHeight(objc->renderTargetHeight()) +// TODO: when WrappedRasterizationRateMap exists +// rasterizationRateMap(objc->rasterizationRateMap()) +{ + GETOBJCARRAY(RenderPassColorAttachmentDescriptor, MAX_RENDER_PASS_COLOR_ATTACHMENTS, + colorAttachments, ValidData); + uint32_t count = objc->getSamplePositions(NULL, 0); + if(count) + { + samplePositions.resize(count); + objc->getSamplePositions(samplePositions.data(), count); + } + GETOBJCARRAY(RenderPassSampleBufferAttachmentDescriptor, + MAX_RENDER_PASS_SAMPLE_BUFFER_ATTACHMENTS, sampleBufferAttachments, ValidData); +} + +RenderPassDescriptor::operator MTL::RenderPassDescriptor *() +{ + MTL::RenderPassDescriptor *objc = MTL::RenderPassDescriptor::alloc()->init(); + COPYTOOBJCARRAY(RenderPassColorAttachmentDescriptor, colorAttachments); + depthAttachment.CopyTo(objc->depthAttachment()); + stencilAttachment.CopyTo(objc->stencilAttachment()); + // TODO: when WrappedMTLBuffer exists + // objc->setVisibilityResultBuffer(Unwrap(visibilityResultBuffer)); + objc->setRenderTargetArrayLength(renderTargetArrayLength); + objc->setImageblockSampleLength(imageblockSampleLength); + objc->setThreadgroupMemoryLength(threadgroupMemoryLength); + objc->setTileWidth(tileWidth); + objc->setTileHeight(tileHeight); + objc->setDefaultRasterSampleCount(defaultRasterSampleCount); + objc->setRenderTargetWidth(renderTargetWidth); + objc->setRenderTargetHeight(renderTargetHeight); + objc->setSamplePositions(samplePositions.data(), samplePositions.count()); + // TODO: when WrappedRasterizationRateMap exists + // objc->setRasterizationRateMap(Unwrap(rasterizationRateMap)); + COPYTOOBJCARRAY(RenderPassSampleBufferAttachmentDescriptor, sampleBufferAttachments); + return objc; +} + } // namespace RDMTL diff --git a/renderdoc/driver/metal/metal_types.h b/renderdoc/driver/metal/metal_types.h index e7d9f7d2e..d0f1afc47 100644 --- a/renderdoc/driver/metal/metal_types.h +++ b/renderdoc/driver/metal/metal_types.h @@ -32,6 +32,12 @@ const uint32_t MAX_RENDER_PASS_COLOR_ATTACHMENTS = 8; const uint32_t MAX_RENDER_PASS_BUFFER_ATTACHMENTS = 31; const uint32_t MAX_VERTEX_SHADER_ATTRIBUTES = 31; +const uint32_t MAX_RENDER_PASS_SAMPLE_BUFFER_ATTACHMENTS = 4; + +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLCounters.h +#ifndef MTLCounterDontSample +#define MTLCounterDontSample ((NS::UInteger)-1) +#endif // #ifndef MTLCounterDontSample #define METALCPP_WRAPPED_PROTOCOLS(FUNC) \ FUNC(CommandBuffer); \ @@ -40,7 +46,8 @@ const uint32_t MAX_VERTEX_SHADER_ATTRIBUTES = 31; FUNC(Function); \ FUNC(Library); \ FUNC(RenderPipelineState); \ - FUNC(Texture); + FUNC(Texture); \ + FUNC(RenderCommandEncoder); // 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. @@ -98,6 +105,15 @@ MTL_DECLARE_REFLECTION_TYPE(TessellationFactorFormat); MTL_DECLARE_REFLECTION_TYPE(TessellationControlPointIndexType); MTL_DECLARE_REFLECTION_TYPE(TessellationFactorStepFunction); MTL_DECLARE_REFLECTION_TYPE(Winding); +MTL_DECLARE_REFLECTION_TYPE(PrimitiveType); +MTL_DECLARE_REFLECTION_TYPE(StoreActionOptions); +MTL_DECLARE_REFLECTION_TYPE(LoadAction); +MTL_DECLARE_REFLECTION_TYPE(StoreAction); +MTL_DECLARE_REFLECTION_TYPE(ClearColor); +MTL_DECLARE_REFLECTION_TYPE(Viewport); +MTL_DECLARE_REFLECTION_TYPE(MultisampleDepthResolveFilter); +MTL_DECLARE_REFLECTION_TYPE(MultisampleStencilResolveFilter); +MTL_DECLARE_REFLECTION_TYPE(SamplePosition); namespace RDMTL { @@ -254,6 +270,110 @@ struct RenderPipelineDescriptor NS::UInteger maxFragmentCallStackDepth = 1; }; +// MTLRenderPassAttachmentDescriptor : based on the interface defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLRenderPass.h +struct RenderPassAttachmentDescriptor +{ + RenderPassAttachmentDescriptor(MTL::LoadAction load, MTL::StoreAction store) + : loadAction(load), storeAction(store) + { + } + RenderPassAttachmentDescriptor(MTL::RenderPassAttachmentDescriptor *objc); + void CopyTo(MTL::RenderPassAttachmentDescriptor *objc); + WrappedMTLTexture *texture = NULL; + NS::UInteger level = 0; + NS::UInteger slice = 0; + NS::UInteger depthPlane = 0; + WrappedMTLTexture *resolveTexture = NULL; + NS::UInteger resolveLevel = 0; + NS::UInteger resolveSlice = 0; + NS::UInteger resolveDepthPlane = 0; + MTL::LoadAction loadAction; + MTL::StoreAction storeAction; + MTL::StoreActionOptions storeActionOptions = MTL::StoreActionOptionNone; +}; + +// MTLRenderPassColorAttachmentDescriptor : based on the interface defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLRenderPass.h +struct RenderPassColorAttachmentDescriptor : RenderPassAttachmentDescriptor +{ + RenderPassColorAttachmentDescriptor() + : RenderPassAttachmentDescriptor(MTL::LoadActionDontCare, MTL::StoreActionStore) + { + } + RenderPassColorAttachmentDescriptor(MTL::RenderPassColorAttachmentDescriptor *objc); + void CopyTo(MTL::RenderPassColorAttachmentDescriptor *objc); + MTL::ClearColor clearColor = MTL::ClearColor::Make(0.0, 0.0, 0.0, 1.0); +}; + +// MTLRenderPassDepthAttachmentDescriptor : based on the interface defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLRenderPass.h +struct RenderPassDepthAttachmentDescriptor : RenderPassAttachmentDescriptor +{ + RenderPassDepthAttachmentDescriptor() + : RenderPassAttachmentDescriptor(MTL::LoadActionClear, MTL::StoreActionDontCare) + { + } + RenderPassDepthAttachmentDescriptor(MTL::RenderPassDepthAttachmentDescriptor *objc); + void CopyTo(MTL::RenderPassDepthAttachmentDescriptor *objc); + double clearDepth = 1.0; + MTL::MultisampleDepthResolveFilter depthResolveFilter = MTL::MultisampleDepthResolveFilterSample0; +}; + +// MTLRenderPassStencilAttachmentDescriptor : based on the interface defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLRenderPass.h +struct RenderPassStencilAttachmentDescriptor : RenderPassAttachmentDescriptor +{ + RenderPassStencilAttachmentDescriptor() + : RenderPassAttachmentDescriptor(MTL::LoadActionClear, MTL::StoreActionDontCare) + { + } + RenderPassStencilAttachmentDescriptor(MTL::RenderPassStencilAttachmentDescriptor *objc); + void CopyTo(MTL::RenderPassStencilAttachmentDescriptor *objc); + uint32_t clearStencil = 0; + MTL::MultisampleStencilResolveFilter stencilResolveFilter = + MTL::MultisampleStencilResolveFilterSample0; +}; + +// MTLRenderPassSampleBufferAttachmentDescriptor : based on the interface defined in +// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLRenderPass.h +struct RenderPassSampleBufferAttachmentDescriptor +{ + RenderPassSampleBufferAttachmentDescriptor() = default; + RenderPassSampleBufferAttachmentDescriptor(MTL::RenderPassSampleBufferAttachmentDescriptor *objc); + void CopyTo(MTL::RenderPassSampleBufferAttachmentDescriptor *objc); + // TODO: when WrappedMTLCounterSampleBuffer exists + // WrappedMTLCounterSampleBuffer *sampleBuffer = NULL; + NS::UInteger startOfVertexSampleIndex = MTLCounterDontSample; + NS::UInteger endOfVertexSampleIndex = MTLCounterDontSample; + NS::UInteger startOfFragmentSampleIndex = MTLCounterDontSample; + NS::UInteger endOfFragmentSampleIndex = MTLCounterDontSample; +}; + +struct RenderPassDescriptor +{ + RenderPassDescriptor() = default; + RenderPassDescriptor(MTL::RenderPassDescriptor *objc); + explicit operator MTL::RenderPassDescriptor *(); + rdcarray colorAttachments; + RenderPassDepthAttachmentDescriptor depthAttachment; + RenderPassStencilAttachmentDescriptor stencilAttachment; + // TODO: when WrappedMTLBuffer exists + // WrappedMTLBuffer *visibilityResultBuffer; + NS::UInteger renderTargetArrayLength = 0; + NS::UInteger imageblockSampleLength = 0; + NS::UInteger threadgroupMemoryLength = 0; + NS::UInteger tileWidth = 0; + NS::UInteger tileHeight = 0; + NS::UInteger defaultRasterSampleCount = 0; + NS::UInteger renderTargetWidth = 0; + NS::UInteger renderTargetHeight = 0; + rdcarray samplePositions; + // TODO: when WrappedRasterizationRateMap exists + // WrappedRasterizationRateMap *rasterizationRateMap = NULL; + rdcarray sampleBufferAttachments; +}; + } // namespace RDMTL template <> @@ -282,3 +402,9 @@ RDMTL_DECLARE_REFLECTION_STRUCT(VertexDescriptor); RDMTL_DECLARE_REFLECTION_STRUCT(FunctionGroup); RDMTL_DECLARE_REFLECTION_STRUCT(LinkedFunctions); RDMTL_DECLARE_REFLECTION_STRUCT(RenderPipelineDescriptor); +RDMTL_DECLARE_REFLECTION_STRUCT(RenderPassAttachmentDescriptor); +RDMTL_DECLARE_REFLECTION_STRUCT(RenderPassColorAttachmentDescriptor); +RDMTL_DECLARE_REFLECTION_STRUCT(RenderPassDepthAttachmentDescriptor); +RDMTL_DECLARE_REFLECTION_STRUCT(RenderPassStencilAttachmentDescriptor); +RDMTL_DECLARE_REFLECTION_STRUCT(RenderPassSampleBufferAttachmentDescriptor); +RDMTL_DECLARE_REFLECTION_STRUCT(RenderPassDescriptor);