Metal: basic hooking and MTLDevice wrapping

This commit is contained in:
Jake Turner
2022-03-09 10:29:03 +00:00
committed by Baldur Karlsson
parent 9d6526ff6e
commit b72bdb2b9a
13 changed files with 1353 additions and 0 deletions
+12
View File
@@ -1,4 +1,16 @@
set(sources
metal_dispatch_table_bridge.mm
metal_dispatch_table_bridge.h
metal_hook_bridge.mm
metal_hook.cpp
metal_hook.h
metal_device.cpp
metal_device.h
metal_device_bridge.mm
metal_resources.h
metal_types_bridge.mm
metal_types_bridge.h
metal_types.h
official/metal-cpp.h
official/metal-cpp.cpp)
+40
View File
@@ -0,0 +1,40 @@
/******************************************************************************
* 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_device.h"
WrappedMTLDevice::WrappedMTLDevice(MTL::Device *realMTLDevice, ResourceId objId)
: WrappedMTLObject(realMTLDevice, objId, this)
{
wrappedObjC = AllocateObjCWrapper(this);
m_WrappedMTLDevice = this;
}
MTL::Device *WrappedMTLDevice::MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice)
{
ResourceId objId = ResourceIDGen::GetNewUniqueID();
WrappedMTLDevice *wrappedMTLDevice = new WrappedMTLDevice(realMTLDevice, objId);
return UnwrapObjC<MTL::Device *>(wrappedMTLDevice);
}
+37
View File
@@ -0,0 +1,37 @@
/******************************************************************************
* 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_resources.h"
class WrappedMTLDevice : public WrappedMTLObject
{
public:
WrappedMTLDevice(MTL::Device *realMTLDevice, ResourceId objId);
~WrappedMTLDevice() {}
static MTL::Device *MTLCreateSystemDefaultDevice(MTL::Device *realMTLDevice);
private:
};
@@ -0,0 +1,790 @@
/******************************************************************************
* 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_device.h"
#include <Availability.h>
#include "metal_types_bridge.h"
// Define Mac SDK versions when compiling with earlier SDKs
#ifndef __MAC_12_0
#define __MAC_12_0 120000
#endif
// Wrapper for MTLDevice
@implementation ObjCWrappedMTLDevice
// ObjCWrappedMTLDevice specific
- (id<MTLDevice>)real
{
MTL::Device *real = Unwrap<MTL::Device *>(self.wrappedCPP);
return id<MTLDevice>(real);
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
id fwd = self.real;
return [fwd methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL aSelector = [invocation selector];
if([self.real respondsToSelector:aSelector])
[invocation invokeWithTarget:self.real];
else
[super forwardInvocation:invocation];
}
// MTLDevice : based on the protocol defined in
// Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLDevice.h
- (NSString *)name
{
return self.real.name;
}
- (uint64_t)registryID API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.registryID;
}
- (MTLSize)maxThreadsPerThreadgroup API_AVAILABLE(macos(10.11), ios(9.0))
{
return self.real.maxThreadsPerThreadgroup;
}
- (BOOL)isLowPower API_AVAILABLE(macos(10.11), macCatalyst(13.0))API_UNAVAILABLE(ios)
{
return self.real.lowPower;
}
- (BOOL)isHeadless API_AVAILABLE(macos(10.11), macCatalyst(13.0))API_UNAVAILABLE(ios)
{
return self.real.headless;
}
- (BOOL)isRemovable API_AVAILABLE(macos(10.13), macCatalyst(13.0))API_UNAVAILABLE(ios)
{
return self.real.removable;
}
- (BOOL)hasUnifiedMemory API_AVAILABLE(macos(10.15), ios(13.0))
{
return self.real.hasUnifiedMemory;
}
- (uint64_t)recommendedMaxWorkingSetSize API_AVAILABLE(macos(10.12), macCatalyst(13.0))
API_UNAVAILABLE(ios)
{
return self.real.recommendedMaxWorkingSetSize;
}
- (MTLDeviceLocation)location API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.location;
}
- (NSUInteger)locationNumber API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.locationNumber;
}
- (uint64_t)maxTransferRate API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.maxTransferRate;
}
- (BOOL)isDepth24Stencil8PixelFormatSupported API_AVAILABLE(macos(10.11), macCatalyst(13.0))
API_UNAVAILABLE(ios)
{
return self.real.depth24Stencil8PixelFormatSupported;
}
- (MTLReadWriteTextureTier)readWriteTextureSupport API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.readWriteTextureSupport;
}
- (MTLArgumentBuffersTier)argumentBuffersSupport API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.argumentBuffersSupport;
}
- (BOOL)areRasterOrderGroupsSupported API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.areRasterOrderGroupsSupported;
}
- (BOOL)supports32BitFloatFiltering API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supports32BitFloatFiltering;
}
- (BOOL)supports32BitMSAA API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supports32BitMSAA;
}
- (BOOL)supportsQueryTextureLOD API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supportsQueryTextureLOD;
}
- (BOOL)supportsBCTextureCompression API_AVAILABLE(macos(11.0))API_UNAVAILABLE(ios)
{
return self.real.supportsBCTextureCompression;
}
- (BOOL)supportsPullModelInterpolation API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supportsPullModelInterpolation;
}
- (BOOL)areBarycentricCoordsSupported API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.barycentricCoordsSupported;
}
- (BOOL)supportsShaderBarycentricCoordinates API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.supportsShaderBarycentricCoordinates;
}
- (NSUInteger)currentAllocatedSize API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.currentAllocatedSize;
}
- (nullable id<MTLCommandQueue>)newCommandQueue
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newCommandQueue];
}
- (nullable id<MTLCommandQueue>)newCommandQueueWithMaxCommandBufferCount:(NSUInteger)maxCommandBufferCount
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newCommandQueueWithMaxCommandBufferCount:maxCommandBufferCount];
}
- (MTLSizeAndAlign)heapTextureSizeAndAlignWithDescriptor:(MTLTextureDescriptor *)desc
API_AVAILABLE(macos(10.13), ios(10.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real heapTextureSizeAndAlignWithDescriptor:desc];
}
- (MTLSizeAndAlign)heapBufferSizeAndAlignWithLength:(NSUInteger)length
options:(MTLResourceOptions)options
API_AVAILABLE(macos(10.13), ios(10.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real heapBufferSizeAndAlignWithLength:length options:options];
}
- (nullable id<MTLHeap>)newHeapWithDescriptor:(MTLHeapDescriptor *)descriptor
API_AVAILABLE(macos(10.13), ios(10.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newHeapWithDescriptor:descriptor];
}
- (nullable id<MTLBuffer>)newBufferWithLength:(NSUInteger)length options:(MTLResourceOptions)options
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newBufferWithLength:length options:options];
}
- (nullable id<MTLBuffer>)newBufferWithBytes:(const void *)pointer
length:(NSUInteger)length
options:(MTLResourceOptions)options
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newBufferWithBytes:pointer length:length options:options];
}
- (nullable id<MTLBuffer>)newBufferWithBytesNoCopy:(void *)pointer
length:(NSUInteger)length
options:(MTLResourceOptions)options
deallocator:(void (^__nullable)(void *pointer,
NSUInteger length))deallocator
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newBufferWithBytesNoCopy:pointer
length:length
options:options
deallocator:deallocator];
}
- (nullable id<MTLDepthStencilState>)newDepthStencilStateWithDescriptor:
(MTLDepthStencilDescriptor *)descriptor
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newDepthStencilStateWithDescriptor:descriptor];
}
- (nullable id<MTLTexture>)newTextureWithDescriptor:(MTLTextureDescriptor *)descriptor
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newTextureWithDescriptor:descriptor];
}
- (nullable id<MTLTexture>)newTextureWithDescriptor:(MTLTextureDescriptor *)descriptor
iosurface:(IOSurfaceRef)iosurface
plane:(NSUInteger)plane
API_AVAILABLE(macos(10.11), ios(11.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newTextureWithDescriptor:descriptor iosurface:iosurface plane:plane];
}
- (nullable id<MTLTexture>)newSharedTextureWithDescriptor:(MTLTextureDescriptor *)descriptor
API_AVAILABLE(macos(10.14), ios(13.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newSharedTextureWithDescriptor:descriptor];
}
- (nullable id<MTLTexture>)newSharedTextureWithHandle:(MTLSharedTextureHandle *)sharedHandle
API_AVAILABLE(macos(10.14), ios(13.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newSharedTextureWithHandle:sharedHandle];
}
- (nullable id<MTLSamplerState>)newSamplerStateWithDescriptor:(MTLSamplerDescriptor *)descriptor
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newSamplerStateWithDescriptor:descriptor];
}
- (nullable id<MTLLibrary>)newDefaultLibrary
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newDefaultLibrary];
}
- (nullable id<MTLLibrary>)newDefaultLibraryWithBundle:(NSBundle *)bundle
error:(__autoreleasing NSError **)error
API_AVAILABLE(macos(10.12), ios(10.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newDefaultLibraryWithBundle:bundle error:error];
}
- (nullable id<MTLLibrary>)newLibraryWithFile:(NSString *)filepath
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newLibraryWithFile:filepath error:error];
}
- (nullable id<MTLLibrary>)newLibraryWithURL:(NSURL *)url
error:(__autoreleasing NSError **)error
API_AVAILABLE(macos(10.13), ios(11.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newLibraryWithURL:url error:error];
}
- (nullable id<MTLLibrary>)newLibraryWithData:(dispatch_data_t)data
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newLibraryWithData:data error:error];
}
- (nullable id<MTLLibrary>)newLibraryWithSource:(NSString *)source
options:(nullable MTLCompileOptions *)options
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newLibraryWithSource:source options:options error:error];
}
- (void)newLibraryWithSource:(NSString *)source
options:(nullable MTLCompileOptions *)options
completionHandler:(MTLNewLibraryCompletionHandler)completionHandler
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return
[self.real newLibraryWithSource:source options:options completionHandler:completionHandler];
}
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0
- (nullable id<MTLLibrary>)newLibraryWithStitchedDescriptor:(MTLStitchedLibraryDescriptor *)descriptor
error:(__autoreleasing NSError **)error
API_AVAILABLE(macos(12.0), ios(15.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newLibraryWithStitchedDescriptor:descriptor error:error];
}
#endif
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0
- (void)newLibraryWithStitchedDescriptor:(MTLStitchedLibraryDescriptor *)descriptor
completionHandler:(MTLNewLibraryCompletionHandler)completionHandler
API_AVAILABLE(macos(12.0), ios(15.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
[self.real newLibraryWithStitchedDescriptor:descriptor completionHandler:completionHandler];
}
#endif
- (nullable id<MTLRenderPipelineState>)
newRenderPipelineStateWithDescriptor:(MTLRenderPipelineDescriptor *)descriptor
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRenderPipelineStateWithDescriptor:descriptor error:error];
}
- (nullable id<MTLRenderPipelineState>)
newRenderPipelineStateWithDescriptor:(MTLRenderPipelineDescriptor *)descriptor
options:(MTLPipelineOption)options
reflection:(MTLAutoreleasedRenderPipelineReflection *__nullable)reflection
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRenderPipelineStateWithDescriptor:descriptor
options:options
reflection:reflection
error:error];
}
- (void)newRenderPipelineStateWithDescriptor:(MTLRenderPipelineDescriptor *)descriptor
completionHandler:(MTLNewRenderPipelineStateCompletionHandler)completionHandler
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRenderPipelineStateWithDescriptor:descriptor
completionHandler:completionHandler];
}
- (void)newRenderPipelineStateWithDescriptor:(MTLRenderPipelineDescriptor *)descriptor
options:(MTLPipelineOption)options
completionHandler:
(MTLNewRenderPipelineStateWithReflectionCompletionHandler)completionHandler
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRenderPipelineStateWithDescriptor:descriptor
options:options
completionHandler:completionHandler];
}
- (nullable id<MTLComputePipelineState>)
newComputePipelineStateWithFunction:(id<MTLFunction>)computeFunction
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newComputePipelineStateWithFunction:computeFunction error:error];
}
- (nullable id<MTLComputePipelineState>)
newComputePipelineStateWithFunction:(id<MTLFunction>)computeFunction
options:(MTLPipelineOption)options
reflection:(MTLAutoreleasedComputePipelineReflection *__nullable)reflection
error:(__autoreleasing NSError **)error
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newComputePipelineStateWithFunction:computeFunction
options:options
reflection:reflection
error:error];
}
- (void)newComputePipelineStateWithFunction:(id<MTLFunction>)computeFunction
completionHandler:(MTLNewComputePipelineStateCompletionHandler)completionHandler
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newComputePipelineStateWithFunction:computeFunction
completionHandler:completionHandler];
}
- (void)newComputePipelineStateWithFunction:(id<MTLFunction>)computeFunction
options:(MTLPipelineOption)options
completionHandler:
(MTLNewComputePipelineStateWithReflectionCompletionHandler)completionHandler
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newComputePipelineStateWithFunction:computeFunction
options:options
completionHandler:completionHandler];
}
- (nullable id<MTLComputePipelineState>)
newComputePipelineStateWithDescriptor:(MTLComputePipelineDescriptor *)descriptor
options:(MTLPipelineOption)options
reflection:(MTLAutoreleasedComputePipelineReflection *__nullable)reflection
error:(__autoreleasing NSError **)error
API_AVAILABLE(macos(10.11), ios(9.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newComputePipelineStateWithDescriptor:descriptor
options:options
reflection:reflection
error:error];
}
- (void)newComputePipelineStateWithDescriptor:(MTLComputePipelineDescriptor *)descriptor
options:(MTLPipelineOption)options
completionHandler:
(MTLNewComputePipelineStateWithReflectionCompletionHandler)completionHandler
API_AVAILABLE(macos(10.11), ios(9.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newComputePipelineStateWithDescriptor:descriptor
options:options
completionHandler:completionHandler];
}
- (nullable id<MTLFence>)newFence API_AVAILABLE(macos(10.13), ios(10.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newFence];
}
- (BOOL)supportsFeatureSet:(MTLFeatureSet)featureSet
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real supportsFeatureSet:featureSet];
}
- (BOOL)supportsFamily:(MTLGPUFamily)gpuFamily API_AVAILABLE(macos(10.15), ios(13.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real supportsFamily:gpuFamily];
}
- (BOOL)supportsTextureSampleCount:(NSUInteger)sampleCount API_AVAILABLE(macos(10.11), ios(9.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real supportsTextureSampleCount:sampleCount];
}
- (NSUInteger)minimumLinearTextureAlignmentForPixelFormat:(MTLPixelFormat)format
API_AVAILABLE(macos(10.13), ios(11.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real minimumLinearTextureAlignmentForPixelFormat:format];
}
- (NSUInteger)minimumTextureBufferAlignmentForPixelFormat:(MTLPixelFormat)format
API_AVAILABLE(macos(10.14), ios(12.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real minimumTextureBufferAlignmentForPixelFormat:format];
}
- (nullable id<MTLRenderPipelineState>)
newRenderPipelineStateWithTileDescriptor:(MTLTileRenderPipelineDescriptor *)descriptor
options:(MTLPipelineOption)options
reflection:(MTLAutoreleasedRenderPipelineReflection *__nullable)reflection
error:(__autoreleasing NSError **)error
API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRenderPipelineStateWithTileDescriptor:descriptor
options:options
reflection:reflection
error:error];
}
- (void)newRenderPipelineStateWithTileDescriptor:(MTLTileRenderPipelineDescriptor *)descriptor
options:(MTLPipelineOption)options
completionHandler:
(MTLNewRenderPipelineStateWithReflectionCompletionHandler)completionHandler
API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(11.0), tvos(14.5))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRenderPipelineStateWithTileDescriptor:descriptor
options:options
completionHandler:completionHandler];
}
- (NSUInteger)maxThreadgroupMemoryLength API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.maxThreadgroupMemoryLength;
}
- (NSUInteger)maxArgumentBufferSamplerCount API_AVAILABLE(macos(10.14), ios(12.0))
{
return self.real.maxArgumentBufferSamplerCount;
}
- (BOOL)areProgrammableSamplePositionsSupported API_AVAILABLE(macos(10.13), ios(11.0))
{
return self.real.programmableSamplePositionsSupported;
}
- (void)getDefaultSamplePositions:(MTLSamplePosition *)positions
count:(NSUInteger)count API_AVAILABLE(macos(10.13), ios(11.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real getDefaultSamplePositions:positions count:count];
}
- (nullable id<MTLArgumentEncoder>)newArgumentEncoderWithArguments:
(NSArray<MTLArgumentDescriptor *> *)arguments API_AVAILABLE(macos(10.13), ios(11.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newArgumentEncoderWithArguments:arguments];
}
- (BOOL)supportsRasterizationRateMapWithLayerCount:(NSUInteger)layerCount
API_AVAILABLE(macos(10.15.4), ios(13.0), macCatalyst(13.4))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real supportsRasterizationRateMapWithLayerCount:layerCount];
}
- (nullable id<MTLRasterizationRateMap>)newRasterizationRateMapWithDescriptor:
(MTLRasterizationRateMapDescriptor *)descriptor
API_AVAILABLE(macos(10.15.4), ios(13.0), macCatalyst(13.4))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newRasterizationRateMapWithDescriptor:descriptor];
}
- (nullable id<MTLIndirectCommandBuffer>)
newIndirectCommandBufferWithDescriptor:(MTLIndirectCommandBufferDescriptor *)descriptor
maxCommandCount:(NSUInteger)maxCount
options:(MTLResourceOptions)options
API_AVAILABLE(macos(10.14), ios(12.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newIndirectCommandBufferWithDescriptor:descriptor
maxCommandCount:maxCount
options:options];
}
- (nullable id<MTLEvent>)newEvent API_AVAILABLE(macos(10.14), ios(12.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newEvent];
}
- (nullable id<MTLSharedEvent>)newSharedEvent API_AVAILABLE(macos(10.14), ios(12.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newSharedEvent];
}
- (nullable id<MTLSharedEvent>)newSharedEventWithHandle:(MTLSharedEventHandle *)sharedEventHandle
API_AVAILABLE(macos(10.14), ios(12.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newSharedEventWithHandle:sharedEventHandle];
}
- (uint64_t)peerGroupID API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.peerGroupID;
}
- (uint32_t)peerIndex API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.peerIndex;
}
- (uint32_t)peerCount API_AVAILABLE(macos(10.15))API_UNAVAILABLE(ios)
{
return self.real.peerCount;
}
- (MTLSize)sparseTileSizeWithTextureType:(MTLTextureType)textureType
pixelFormat:(MTLPixelFormat)pixelFormat
sampleCount:(NSUInteger)sampleCount
API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real sparseTileSizeWithTextureType:textureType
pixelFormat:pixelFormat
sampleCount:sampleCount];
}
- (NSUInteger)sparseTileSizeInBytes API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0))
{
return self.real.sparseTileSizeInBytes;
}
- (void)convertSparsePixelRegions:(const MTLRegion[_Nonnull])pixelRegions
toTileRegions:(MTLRegion[_Nonnull])tileRegions
withTileSize:(MTLSize)tileSize
alignmentMode:(MTLSparseTextureRegionAlignmentMode)mode
numRegions:(NSUInteger)numRegions
API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real convertSparsePixelRegions:pixelRegions
toTileRegions:tileRegions
withTileSize:tileSize
alignmentMode:mode
numRegions:numRegions];
}
- (void)convertSparseTileRegions:(const MTLRegion[_Nonnull])tileRegions
toPixelRegions:(MTLRegion[_Nonnull])pixelRegions
withTileSize:(MTLSize)tileSize
numRegions:(NSUInteger)numRegions
API_AVAILABLE(macos(11.0), macCatalyst(14.0), ios(13.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real convertSparseTileRegions:tileRegions
toPixelRegions:pixelRegions
withTileSize:tileSize
numRegions:numRegions];
}
- (NSUInteger)maxBufferLength API_AVAILABLE(macos(10.14), ios(12.0))
{
return self.real.maxBufferLength;
}
- (NSArray<id<MTLCounterSet>> *)counterSets API_AVAILABLE(macos(10.15), ios(14.0))
{
return self.real.counterSets;
}
- (nullable id<MTLCounterSampleBuffer>)newCounterSampleBufferWithDescriptor:
(MTLCounterSampleBufferDescriptor *)descriptor
error:(NSError **)error
API_AVAILABLE(macos(10.15), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newCounterSampleBufferWithDescriptor:descriptor error:error];
}
- (void)sampleTimestamps:(MTLTimestamp *)cpuTimestamp
gpuTimestamp:(MTLTimestamp *)gpuTimestamp API_AVAILABLE(macos(10.15), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real sampleTimestamps:cpuTimestamp gpuTimestamp:gpuTimestamp];
}
- (BOOL)supportsCounterSampling:(MTLCounterSamplingPoint)samplingPoint
API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real supportsCounterSampling:samplingPoint];
}
- (BOOL)supportsVertexAmplificationCount:(NSUInteger)count
API_AVAILABLE(macos(10.15.4), ios(13.0), macCatalyst(13.4))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real supportsVertexAmplificationCount:count];
}
- (BOOL)supportsDynamicLibraries API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supportsDynamicLibraries;
}
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0
- (BOOL)supportsRenderDynamicLibraries API_AVAILABLE(macos(12.0), ios(15.0))
{
return self.real.supportsRenderDynamicLibraries;
}
#endif
- (nullable id<MTLDynamicLibrary>)newDynamicLibrary:(id<MTLLibrary>)library
error:(NSError **)error
API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newDynamicLibrary:library error:error];
}
- (nullable id<MTLDynamicLibrary>)newDynamicLibraryWithURL:(NSURL *)url
error:(NSError **)error
API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newDynamicLibraryWithURL:url error:error];
}
- (nullable id<MTLBinaryArchive>)newBinaryArchiveWithDescriptor:(MTLBinaryArchiveDescriptor *)descriptor
error:(NSError **)error
API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newBinaryArchiveWithDescriptor:descriptor error:error];
}
- (BOOL)supportsRaytracing API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supportsRaytracing;
}
- (MTLAccelerationStructureSizes)accelerationStructureSizesWithDescriptor:
(MTLAccelerationStructureDescriptor *)descriptor API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real accelerationStructureSizesWithDescriptor:descriptor];
}
- (nullable id<MTLAccelerationStructure>)newAccelerationStructureWithSize:(NSUInteger)size
API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newAccelerationStructureWithSize:size];
}
- (nullable id<MTLAccelerationStructure>)newAccelerationStructureWithDescriptor:
(MTLAccelerationStructureDescriptor *)descriptor API_AVAILABLE(macos(11.0), ios(14.0))
{
NSLog(@"Not hooked %@", NSStringFromSelector(_cmd));
return [self.real newAccelerationStructureWithDescriptor:descriptor];
}
- (BOOL)supportsFunctionPointers API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supportsFunctionPointers;
}
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0
- (BOOL)supportsFunctionPointersFromRender API_AVAILABLE(macos(12.0), ios(15.0))
{
return self.real.supportsFunctionPointersFromRender;
}
#endif
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0
- (BOOL)supportsRaytracingFromRender API_AVAILABLE(macos(12.0), ios(15.0))
{
return self.real.supportsRaytracingFromRender;
}
#endif
// Treat as if the API is available from SDK 12.0
// It is marked as available from SDK 11.0, however it was not present in SDK 11.1 MTLDevice.h
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0
- (BOOL)supportsPrimitiveMotionBlur API_AVAILABLE(macos(11.0), ios(14.0))
{
return self.real.supportsPrimitiveMotionBlur;
}
#endif
@end
@@ -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
#import <Metal/MTLDevice.h>
#include "common/common.h"
// Global scope Metal functions from MTLDevice.h
typedef id<MTLDevice> (*PFN_MTLCreateSystemDefaultDevice)(void);
typedef NSArray<id<MTLDevice>> *(*PFN_MTLCopyAllDevices)(void);
typedef NSArray<id<MTLDevice>> *(*PFN_MTLCopyAllDevicesWithObserver)(
id<NSObject> *observer, MTLDeviceNotificationHandler handler);
typedef void (*PFN_MTLRemoveDeviceObserver)(id<NSObject> observer);
// TODO: Global scope Metal device method from CGDirectDisplayMetal.h
// CG_EXTERN id<MTLDevice> __nullable CGDirectDisplayCopyCurrentMetalDevice(CGDirectDisplayID
// display)
// NS_RETURNS_RETAINED CG_AVAILABLE_STARTING(10.11);
#define METAL_HOOKED_SYMBOLS(FUNC) FUNC(MTLCreateSystemDefaultDevice);
#define METAL_NONHOOKED_SYMBOLS(FUNC) \
FUNC(MTLCopyAllDevices); \
FUNC(MTLCopyAllDevicesWithObserver); \
FUNC(MTLRemoveDeviceObserver);
struct MetalDispatchTable
{
bool PopulateForReplay();
#define METAL_PTR_GEN(func) CONCAT(PFN_, func) func;
METAL_HOOKED_SYMBOLS(METAL_PTR_GEN)
METAL_NONHOOKED_SYMBOLS(METAL_PTR_GEN)
#undef METAL_PTR_GEN
};
extern MetalDispatchTable METAL;
@@ -0,0 +1,47 @@
/******************************************************************************
* 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_dispatch_table_bridge.h"
MetalDispatchTable METAL = {};
bool MetalDispatchTable::PopulateForReplay()
{
bool symbols_ok = true;
#define LOAD_FUNC(func) \
if(!this->func) \
this->func = &::func; \
\
if(!this->func) \
{ \
symbols_ok = false; \
RDCWARN("Unable to load '%s'", STRINGIZE(func)); \
}
METAL_HOOKED_SYMBOLS(LOAD_FUNC)
METAL_NONHOOKED_SYMBOLS(LOAD_FUNC)
#undef LOAD_FUNC
return symbols_ok;
}
+54
View File
@@ -0,0 +1,54 @@
/******************************************************************************
* 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_hook.h"
#include "core/core.h"
static MetalHook metalhook;
static void MetalHooked(void *handle)
{
RDCDEBUG("Metal library hooked");
// store the handle for any pass-through implementations that need to look up their onward
// pointers
metalhook.handle = handle;
// as a hook callback this is only called while capturing
RDCASSERT(!RenderDoc::Inst().IsReplayApp());
MetalHook::RegisterGlobalNonHookedMetalFunctions();
}
void MetalHook::RegisterHooks()
{
RDCLOG("Registering Metal hooks");
// Library hooks : this should be framework hooks?
LibraryHooks::RegisterLibraryHook(
"/System/Library/Frameworks/Metal.framework/Versions/Current/Metal", &MetalHooked);
// Function hooks
MetalHook::RegisterGlobalHookedMetalFunctions();
}
+41
View File
@@ -0,0 +1,41 @@
/******************************************************************************
* 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 <dlfcn.h>
#include "hooks/hooks.h"
class MetalHook : LibraryHook
{
public:
MetalHook() {}
void RegisterHooks();
static void RegisterGlobalNonHookedMetalFunctions();
static void RegisterGlobalHookedMetalFunctions();
// default to RTLD_NEXT if we haven't gotten a more specific library handle
void *handle = RTLD_NEXT;
};
@@ -0,0 +1,93 @@
/******************************************************************************
* 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_hook.h"
#include "core/core.h"
#include "hooks/hooks.h"
#include "metal_device.h"
#include "metal_dispatch_table_bridge.h"
#include "metal_types_bridge.h"
#define METAL_EXPORT_NAME(function) CONCAT(interposed_, function)
#define DECL_HOOK_EXPORT(function) \
__attribute__((used)) static struct \
{ \
const void *replacment; \
const void *replacee; \
} _interpose_def_##function __attribute__((section("__DATA,__interpose"))) = { \
(const void *)(unsigned long)&METAL_EXPORT_NAME(function), \
(const void *)(unsigned long)&function, \
};
#define ForEachMetalSupported() METAL_FUNC(MTLCreateSystemDefaultDevice)
id<MTLDevice> METAL_EXPORT_NAME(MTLCreateSystemDefaultDevice)(void)
{
if(RenderDoc::Inst().IsReplayApp())
{
if(!METAL.MTLCreateSystemDefaultDevice)
METAL.PopulateForReplay();
return METAL.MTLCreateSystemDefaultDevice();
}
id<MTLDevice> device = METAL.MTLCreateSystemDefaultDevice();
return id<MTLDevice>(WrappedMTLDevice::MTLCreateSystemDefaultDevice((MTL::Device *)device));
}
/*
APIs not currently hooked
*** MTLDevice.h ***
NSArray <id<MTLDevice>> *METAL_EXPORT_NAME(MTLCopyAllDevices)(void);
NSArray <id<MTLDevice>> *METAL_EXPORT_NAME(MTLCopyAllDevicesWithObserver)(id<NSObject>* observer,
MTLDeviceNotificationHandler handler);
void METAL_EXPORT_NAME(MTLRemoveDeviceObserver)(id <NSObject> observer);
*** CGDirectDisplayMetal.h ***
CG_EXTERN id<MTLDevice> __nullable CGDirectDisplayCopyCurrentMetalDevice(CGDirectDisplayID display)
NS_RETURNS_RETAINED CG_AVAILABLE_STARTING(10.11);
*/
void MetalHook::RegisterGlobalNonHookedMetalFunctions()
{
// fetch non-hooked functions into our dispatch table
#define METAL_FETCH(func) METAL.func = &::func;
METAL_NONHOOKED_SYMBOLS(METAL_FETCH)
#undef METAL_FETCH
}
void MetalHook::RegisterGlobalHookedMetalFunctions()
{
#define METAL_FUNC(func) METAL.func = &::func;
ForEachMetalSupported();
#undef METAL_FUNC
}
#define METAL_FUNC(function) DECL_HOOK_EXPORT(function)
ForEachMetalSupported();
#undef METAL_FUNC
+61
View File
@@ -0,0 +1,61 @@
/******************************************************************************
* 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 "core/resource_manager.h"
#include "metal_types.h"
struct WrappedMTLObject
{
WrappedMTLObject() = delete;
WrappedMTLObject(void *mtlObject, ResourceId objId, WrappedMTLDevice *wrappedMTLDevice)
: wrappedObjC(NULL), real(mtlObject), id(objId), m_WrappedMTLDevice(wrappedMTLDevice)
{
}
~WrappedMTLObject() = default;
void *wrappedObjC;
void *real;
ResourceId id;
WrappedMTLDevice *m_WrappedMTLDevice;
};
template <typename RealType>
RealType Unwrap(WrappedMTLObject *obj)
{
if(obj == NULL)
return RealType();
return (RealType)obj->real;
}
template <typename RealType>
RealType UnwrapObjC(WrappedMTLObject *obj)
{
if(obj == NULL)
return RealType();
return (RealType)obj->wrappedObjC;
}
+36
View File
@@ -0,0 +1,36 @@
/******************************************************************************
* 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 "official/metal-cpp.h"
#define METALCPP_WRAPPED_PROTOCOLS(FUNC) FUNC(Device);
#define DECLARE_OBJC_HELPERS(CPPTYPE) \
class WrappedMTL##CPPTYPE; \
extern MTL::CPPTYPE *AllocateObjCWrapper(WrappedMTL##CPPTYPE *wrapped);
METALCPP_WRAPPED_PROTOCOLS(DECLARE_OBJC_HELPERS)
#undef DECLARE_OBJC_HELPERS
@@ -0,0 +1,40 @@
/******************************************************************************
* 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_types.h"
#import <Metal/MTLDevice.h>
// clang-format off
#define DECLARE_OBJC_WRAPPED_INTERFACES(CPPTYPE) \
@interface ObjCWrappedMTL##CPPTYPE : NSObject<MTL##CPPTYPE> \
@property(assign) WrappedMTL##CPPTYPE *wrappedCPP; \
@property(readonly) id<MTL##CPPTYPE> real; \
@end
// clang-format on
METALCPP_WRAPPED_PROTOCOLS(DECLARE_OBJC_WRAPPED_INTERFACES)
#undef DECLARE_OBJC_WRAPPED_INTERFACES
@@ -0,0 +1,43 @@
/******************************************************************************
* 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_types_bridge.h"
#include "metal_device.h"
#define DEFINE_OBJC_HELPERS(CPPTYPE) \
MTL::CPPTYPE *AllocateObjCWrapper(WrappedMTL##CPPTYPE *wrappedCPP) \
{ \
ObjCWrappedMTL##CPPTYPE *objC = [ObjCWrappedMTL##CPPTYPE alloc]; \
objC.wrappedCPP = wrappedCPP; \
MTL::CPPTYPE *real = (MTL::CPPTYPE *)objC.real; \
if(real) \
{ \
objc_setAssociatedObject((id)real, objC, (id)objC, OBJC_ASSOCIATION_RETAIN); \
[objC release]; \
} \
return (MTL::CPPTYPE *)objC; \
}
METALCPP_WRAPPED_PROTOCOLS(DEFINE_OBJC_HELPERS)
#undef DEFINE_OBJC_HELPERS