├── .gitattributes ├── .gitignore ├── .vscode ├── c_cpp_properties.json ├── launch.json ├── settings.json └── tasks.json ├── 01-MetalAdder ├── MetalAdder.cpp ├── MetalAdder.h ├── MetalAdder.hpp ├── MetalAdder.m ├── add.metal ├── main.cpp └── main.m ├── 02-GeneralArrayOperations ├── CPUOperations.cpp ├── CPUOperations.hpp ├── MetalOperations.cpp ├── MetalOperations.hpp ├── main.cpp ├── main_chaining.cpp └── ops.metal ├── 03-2DKernels ├── CPUOperations.cpp ├── CPUOperations.hpp ├── MetalOperations.cpp ├── MetalOperations.hpp ├── main.cpp └── ops.metal ├── LICENSE ├── LICENSE-original.txt ├── Metal-Feature-Set-Tables.numbers ├── Metal-Shading-Language-Specification.pdf ├── README.md ├── metal-cpp ├── Foundation │ ├── Foundation.hpp │ ├── NSArray.hpp │ ├── NSAutoreleasePool.hpp │ ├── NSBundle.hpp │ ├── NSData.hpp │ ├── NSDate.hpp │ ├── NSDefines.hpp │ ├── NSDictionary.hpp │ ├── NSEnumerator.hpp │ ├── NSError.hpp │ ├── NSLock.hpp │ ├── NSNotification.hpp │ ├── NSNumber.hpp │ ├── NSObjCRuntime.hpp │ ├── NSObject.hpp │ ├── NSPrivate.hpp │ ├── NSProcessInfo.hpp │ ├── NSRange.hpp │ ├── NSString.hpp │ ├── NSTypes.hpp │ └── NSURL.hpp ├── LICENSE.txt ├── Metal │ ├── MTLAccelerationStructure.hpp │ ├── MTLAccelerationStructureCommandEncoder.hpp │ ├── MTLAccelerationStructureTypes.hpp │ ├── MTLArgument.hpp │ ├── MTLArgumentEncoder.hpp │ ├── MTLBinaryArchive.hpp │ ├── MTLBlitCommandEncoder.hpp │ ├── MTLBlitPass.hpp │ ├── MTLBuffer.hpp │ ├── MTLCaptureManager.hpp │ ├── MTLCaptureScope.hpp │ ├── MTLCommandBuffer.hpp │ ├── MTLCommandEncoder.hpp │ ├── MTLCommandQueue.hpp │ ├── MTLComputeCommandEncoder.hpp │ ├── MTLComputePass.hpp │ ├── MTLComputePipeline.hpp │ ├── MTLCounters.hpp │ ├── MTLDefines.hpp │ ├── MTLDepthStencil.hpp │ ├── MTLDevice.hpp │ ├── MTLDrawable.hpp │ ├── MTLDynamicLibrary.hpp │ ├── MTLEvent.hpp │ ├── MTLFence.hpp │ ├── MTLFunctionConstantValues.hpp │ ├── MTLFunctionDescriptor.hpp │ ├── MTLFunctionHandle.hpp │ ├── MTLFunctionLog.hpp │ ├── MTLFunctionStitching.hpp │ ├── MTLHeaderBridge.hpp │ ├── MTLHeap.hpp │ ├── MTLIndirectCommandBuffer.hpp │ ├── MTLIndirectCommandEncoder.hpp │ ├── MTLIntersectionFunctionTable.hpp │ ├── MTLLibrary.hpp │ ├── MTLLinkedFunctions.hpp │ ├── MTLParallelRenderCommandEncoder.hpp │ ├── MTLPipeline.hpp │ ├── MTLPixelFormat.hpp │ ├── MTLPrivate.hpp │ ├── MTLRasterizationRate.hpp │ ├── MTLRenderCommandEncoder.hpp │ ├── MTLRenderPass.hpp │ ├── MTLRenderPipeline.hpp │ ├── MTLResource.hpp │ ├── MTLResourceStateCommandEncoder.hpp │ ├── MTLResourceStatePass.hpp │ ├── MTLSampler.hpp │ ├── MTLStageInputOutputDescriptor.hpp │ ├── MTLTexture.hpp │ ├── MTLTypes.hpp │ ├── MTLVertexDescriptor.hpp │ ├── MTLVisibleFunctionTable.hpp │ └── Metal.hpp ├── QuartzCore │ ├── CADefines.hpp │ ├── CAMetalDrawable.hpp │ ├── CAPrivate.hpp │ └── QuartzCore.hpp ├── README.md └── SingleHeader │ └── MakeSingleHeader.py └── paper ├── combined_01.pdf ├── combined_01.png ├── combined_02.pdf ├── combined_02.png ├── paper_benchmark_02.cpp ├── paper_benchmark_03.cpp ├── plot_1d_operators.py └── plot_2d_operators.py /.gitattributes: -------------------------------------------------------------------------------- 1 | metal-cpp/** linguist-vendored 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Metal 35 | *.metallib 36 | *.air 37 | *.x 38 | *.dSYM 39 | .DS_Store 40 | 41 | *.csv -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [{ 3 | "name": "Mac M1 LLVM OpenMP", 4 | "includePath": [ 5 | "${workspaceFolder}/**", 6 | "/opt/homebrew/opt/libomp/lib" 7 | ], 8 | "defines": [], 9 | "macFrameworkPath": [], 10 | "compilerPath": "/opt/homebrew/opt/llvm/bin/clang++", 11 | "cStandard": "c17", 12 | "cppStandard": "c++20", 13 | "intelliSenseMode": "clang-x64", 14 | "compilerArgs": [] 15 | }], 16 | "version": 4 17 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [{ 3 | "name": "Python: Current File", 4 | "type": "python", 5 | "request": "launch", 6 | "program": "${file}", 7 | "console": "integratedTerminal", 8 | "justMyCode": true, 9 | "cwd": "${workspaceFolder}/paper", 10 | 11 | }, 12 | { 13 | "name": "MetalAdder benchmark debugging", 14 | "type": "cppdbg", 15 | "request": "launch", 16 | "program": "${workspaceFolder}/01-MetalAdder/benchmark.x", 17 | "args": [], 18 | "stopAtEntry": false, 19 | "cwd": "${workspaceFolder}/01-MetalAdder", 20 | "environment": [], 21 | "externalConsole": false, 22 | "MIMode": "lldb", 23 | "preLaunchTask": "Build 01" 24 | }, { 25 | "name": "MetalOperations debugging", 26 | "type": "cppdbg", 27 | "request": "launch", 28 | "program": "${workspaceFolder}/02-GeneralArrayOperations/benchmark.x", 29 | "args": [], 30 | "stopAtEntry": false, 31 | "cwd": "${workspaceFolder}/02-GeneralArrayOperations", 32 | "environment": [], 33 | "externalConsole": false, 34 | "MIMode": "lldb", 35 | "preLaunchTask": "Build 02" 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "iostream": "cpp", 4 | "complex": "cpp", 5 | "__bit_reference": "cpp", 6 | "__bits": "cpp", 7 | "__config": "cpp", 8 | "__debug": "cpp", 9 | "__errc": "cpp", 10 | "__hash_table": "cpp", 11 | "__locale": "cpp", 12 | "__mutex_base": "cpp", 13 | "__node_handle": "cpp", 14 | "__nullptr": "cpp", 15 | "__split_buffer": "cpp", 16 | "__string": "cpp", 17 | "__threading_support": "cpp", 18 | "__tuple": "cpp", 19 | "array": "cpp", 20 | "atomic": "cpp", 21 | "bit": "cpp", 22 | "bitset": "cpp", 23 | "cctype": "cpp", 24 | "chrono": "cpp", 25 | "clocale": "cpp", 26 | "cmath": "cpp", 27 | "compare": "cpp", 28 | "concepts": "cpp", 29 | "condition_variable": "cpp", 30 | "cstdarg": "cpp", 31 | "cstddef": "cpp", 32 | "cstdint": "cpp", 33 | "cstdio": "cpp", 34 | "cstdlib": "cpp", 35 | "cstring": "cpp", 36 | "ctime": "cpp", 37 | "cwchar": "cpp", 38 | "cwctype": "cpp", 39 | "deque": "cpp", 40 | "exception": "cpp", 41 | "initializer_list": "cpp", 42 | "ios": "cpp", 43 | "iosfwd": "cpp", 44 | "istream": "cpp", 45 | "limits": "cpp", 46 | "locale": "cpp", 47 | "memory": "cpp", 48 | "mutex": "cpp", 49 | "new": "cpp", 50 | "numbers": "cpp", 51 | "numeric": "cpp", 52 | "optional": "cpp", 53 | "ostream": "cpp", 54 | "queue": "cpp", 55 | "random": "cpp", 56 | "ratio": "cpp", 57 | "semaphore": "cpp", 58 | "sstream": "cpp", 59 | "stdexcept": "cpp", 60 | "streambuf": "cpp", 61 | "string": "cpp", 62 | "string_view": "cpp", 63 | "system_error": "cpp", 64 | "thread": "cpp", 65 | "tuple": "cpp", 66 | "type_traits": "cpp", 67 | "typeinfo": "cpp", 68 | "unordered_map": "cpp", 69 | "variant": "cpp", 70 | "vector": "cpp", 71 | "__functional_base": "cpp", 72 | "algorithm": "cpp", 73 | "functional": "cpp", 74 | "iterator": "cpp", 75 | "utility": "cpp", 76 | "__tree": "cpp", 77 | "list": "cpp", 78 | "map": "cpp", 79 | "__memory": "cpp", 80 | "iomanip": "cpp", 81 | "fstream": "cpp", 82 | "stack": "cpp" 83 | } 84 | } -------------------------------------------------------------------------------- /01-MetalAdder/MetalAdder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | CPP translation of original Objective-C MetalAdder.m. Some stuff has been moved over to 3 | the header. Source: https://developer.apple.com/documentation/metal/performing_calculations_on_a_gpu?language=objc 4 | 5 | Original distribution license: LICENSE-original.txt. 6 | 7 | Abstract: 8 | A class to manage all of the Metal objects this app creates. 9 | */ 10 | 11 | #include "MetalAdder.hpp" 12 | #include 13 | 14 | MetalAdder::MetalAdder(MTL::Device *device) 15 | { 16 | 17 | _mDevice = device; 18 | 19 | NS::Error *error = nullptr; 20 | 21 | // Load the shader files with a .metal file extension in the project 22 | MTL::Library *defaultLibrary = _mDevice->newDefaultLibrary(); 23 | 24 | if (defaultLibrary == nullptr) 25 | { 26 | std::cout << "Failed to find the default library." << std::endl; 27 | return; 28 | } 29 | 30 | auto str = NS::String::string("add_arrays", NS::ASCIIStringEncoding); 31 | MTL::Function *addFunction = defaultLibrary->newFunction(str); 32 | defaultLibrary->release(); 33 | 34 | if (addFunction == nullptr) 35 | { 36 | std::cout << "Failed to find the adder function." << std::endl; 37 | return; 38 | } 39 | 40 | // Create a compute pipeline state object. 41 | _mAddFunctionPSO = _mDevice->newComputePipelineState(addFunction, &error); 42 | addFunction->release(); 43 | 44 | if (_mAddFunctionPSO == nullptr) 45 | { 46 | // If the Metal API validation is enabled, you can find out more information about what 47 | // went wrong. (Metal API validation is enabled by default when a debug build is run 48 | // from Xcode) 49 | std::cout << "Failed to created pipeline state object, error " << error << "." << std::endl; 50 | return; 51 | } 52 | 53 | _mCommandQueue = _mDevice->newCommandQueue(); 54 | if (_mCommandQueue == nullptr) 55 | { 56 | std::cout << "Failed to find the command queue." << std::endl; 57 | return; 58 | } 59 | 60 | // Allocate three buffers to hold our initial data and the result. 61 | _mBufferA = _mDevice->newBuffer(bufferSize, MTL::ResourceStorageModeShared); 62 | _mBufferB = _mDevice->newBuffer(bufferSize, MTL::ResourceStorageModeShared); 63 | _mBufferResult = _mDevice->newBuffer(bufferSize, MTL::ResourceStorageModeShared); 64 | 65 | prepareData(); 66 | } 67 | 68 | void MetalAdder::prepareData() 69 | { 70 | 71 | generateRandomFloatData(_mBufferA); 72 | generateRandomFloatData(_mBufferB); 73 | } 74 | 75 | void MetalAdder::sendComputeCommand() 76 | { 77 | // Create a command buffer to hold commands. 78 | MTL::CommandBuffer *commandBuffer = _mCommandQueue->commandBuffer(); 79 | assert(commandBuffer != nullptr); 80 | 81 | // Start a compute pass. 82 | MTL::ComputeCommandEncoder *computeEncoder = commandBuffer->computeCommandEncoder(); 83 | assert(computeEncoder != nullptr); 84 | 85 | encodeAddCommand(computeEncoder); 86 | 87 | // End the compute pass. 88 | computeEncoder->endEncoding(); 89 | 90 | // Execute the command. 91 | commandBuffer->commit(); 92 | 93 | // Normally, you want to do other work in your app while the GPU is running, 94 | // but in this example, the code simply blocks until the calculation is complete. 95 | commandBuffer->waitUntilCompleted(); 96 | } 97 | 98 | void MetalAdder::encodeAddCommand(MTL::ComputeCommandEncoder *computeEncoder) 99 | { 100 | // Encode the pipeline state object and its parameters. 101 | computeEncoder->setComputePipelineState(_mAddFunctionPSO); 102 | computeEncoder->setBuffer(_mBufferA, 0, 0); 103 | computeEncoder->setBuffer(_mBufferB, 0, 1); 104 | computeEncoder->setBuffer(_mBufferResult, 0, 2); 105 | 106 | MTL::Size gridSize = MTL::Size::Make(arrayLength, 1, 1); 107 | 108 | // Calculate a threadgroup size. 109 | NS::UInteger threadGroupSize = _mAddFunctionPSO->maxTotalThreadsPerThreadgroup(); 110 | if (threadGroupSize > arrayLength) 111 | { 112 | threadGroupSize = arrayLength; 113 | } 114 | MTL::Size threadgroupSize = MTL::Size::Make(threadGroupSize, 1, 1); 115 | 116 | // Encode the compute command. 117 | computeEncoder->dispatchThreads(gridSize, threadgroupSize); 118 | } 119 | 120 | void MetalAdder::generateRandomFloatData(MTL::Buffer *buffer) 121 | { 122 | // The pointer needs to be explicitly cast in C++, a difference from 123 | // Objective-C. 124 | float *dataPtr = (float *)buffer->contents(); 125 | 126 | for (unsigned long index = 0; index < arrayLength; index++) 127 | { 128 | dataPtr[index] = (float)rand() / (float)(RAND_MAX); 129 | } 130 | } 131 | 132 | void MetalAdder::verifyResults() 133 | { 134 | float *a = (float *)_mBufferA->contents(); 135 | float *b = (float *)_mBufferB->contents(); 136 | float *result = (float *)_mBufferResult->contents(); 137 | 138 | for (unsigned long index = 0; index < arrayLength; index++) 139 | { 140 | if (result[index] != (a[index] + b[index])) 141 | { 142 | printf("Compute ERROR: index=%lu result=%g vs %g=a+b\n", 143 | index, result[index], a[index] + b[index]); 144 | assert(result[index] == (a[index] + b[index])); 145 | } 146 | } 147 | } 148 | 149 | MetalAdder::~MetalAdder() 150 | { 151 | _mBufferA->release(); 152 | _mBufferB->release(); 153 | _mBufferResult->release(); 154 | 155 | _mAddFunctionPSO->release(); 156 | _mCommandQueue->release(); 157 | } -------------------------------------------------------------------------------- /01-MetalAdder/MetalAdder.h: -------------------------------------------------------------------------------- 1 | /* 2 | See LICENSE folder for this sample’s licensing information. 3 | 4 | Abstract: 5 | A class to manage all of the Metal objects this app creates. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface MetalAdder : NSObject 14 | - (instancetype) initWithDevice: (id) device; 15 | - (void) prepareData; 16 | - (void) sendComputeCommand; 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /01-MetalAdder/MetalAdder.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | CPP translation of original Objective-C MetalAdder.h. Some stuff has been moved over 3 | here from the cpp file. Source: https://developer.apple.com/documentation/metal/performing_calculations_on_a_gpu?language=objc 4 | 5 | Original distribution license: LICENSE-original.txt. 6 | 7 | Abstract: 8 | A class to manage all of the Metal objects this app creates. 9 | */ 10 | #pragma once 11 | 12 | #include "Foundation/Foundation.hpp" 13 | #include "Metal/Metal.hpp" 14 | 15 | // The number of floats in each array, and the size of the arrays in bytes. 16 | const unsigned int arrayLength = 60 * 180 * 10000; 17 | 18 | const unsigned int bufferSize = arrayLength * sizeof(float); 19 | 20 | class MetalAdder 21 | { 22 | public: 23 | MTL::Device *_mDevice; 24 | 25 | // The compute pipeline generated from the compute kernel in the .metal shader file. 26 | MTL::ComputePipelineState *_mAddFunctionPSO; 27 | 28 | // The command queue used to pass commands to the device. 29 | MTL::CommandQueue *_mCommandQueue; 30 | 31 | // Buffers to hold data. 32 | MTL::Buffer *_mBufferA; 33 | MTL::Buffer *_mBufferB; 34 | MTL::Buffer *_mBufferResult; 35 | 36 | MetalAdder(MTL::Device *device); 37 | ~MetalAdder(); 38 | 39 | void prepareData(); 40 | void sendComputeCommand(); 41 | void verifyResults(); 42 | 43 | private: 44 | void encodeAddCommand(MTL::ComputeCommandEncoder *computeEncoder); 45 | void generateRandomFloatData(MTL::Buffer *buffer); 46 | }; 47 | -------------------------------------------------------------------------------- /01-MetalAdder/MetalAdder.m: -------------------------------------------------------------------------------- 1 | /* 2 | See LICENSE folder for this sample’s licensing information. 3 | 4 | Abstract: 5 | A class to manage all of the Metal objects this app creates. 6 | */ 7 | 8 | #import "MetalAdder.h" 9 | 10 | // The number of floats in each array, and the size of the arrays in bytes. 11 | const unsigned int arrayLength = 1 << 24; 12 | const unsigned int bufferSize = arrayLength * sizeof(float); 13 | 14 | @implementation MetalAdder 15 | { 16 | id _mDevice; 17 | 18 | // The compute pipeline generated from the compute kernel in the .metal shader file. 19 | id _mAddFunctionPSO; 20 | 21 | // The command queue used to pass commands to the device. 22 | id _mCommandQueue; 23 | 24 | // Buffers to hold data. 25 | id _mBufferA; 26 | id _mBufferB; 27 | id _mBufferResult; 28 | 29 | } 30 | 31 | - (instancetype) initWithDevice: (id) device 32 | { 33 | self = [super init]; 34 | if (self) 35 | { 36 | _mDevice = device; 37 | 38 | NSError* error = nil; 39 | 40 | // Load the shader files with a .metal file extension in the project 41 | 42 | id defaultLibrary = [_mDevice newDefaultLibrary]; 43 | if (defaultLibrary == nil) 44 | { 45 | NSLog(@"Failed to find the default library."); 46 | return nil; 47 | } 48 | 49 | id addFunction = [defaultLibrary newFunctionWithName:@"add_arrays"]; 50 | if (addFunction == nil) 51 | { 52 | NSLog(@"Failed to find the adder function."); 53 | return nil; 54 | } 55 | 56 | // Create a compute pipeline state object. 57 | _mAddFunctionPSO = [_mDevice newComputePipelineStateWithFunction: addFunction error:&error]; 58 | if (_mAddFunctionPSO == nil) 59 | { 60 | // If the Metal API validation is enabled, you can find out more information about what 61 | // went wrong. (Metal API validation is enabled by default when a debug build is run 62 | // from Xcode) 63 | NSLog(@"Failed to created pipeline state object, error %@.", error); 64 | return nil; 65 | } 66 | 67 | _mCommandQueue = [_mDevice newCommandQueue]; 68 | if (_mCommandQueue == nil) 69 | { 70 | NSLog(@"Failed to find the command queue."); 71 | return nil; 72 | } 73 | } 74 | 75 | return self; 76 | } 77 | 78 | - (void) prepareData 79 | { 80 | // Allocate three buffers to hold our initial data and the result. 81 | _mBufferA = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared]; 82 | _mBufferB = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared]; 83 | _mBufferResult = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared]; 84 | 85 | [self generateRandomFloatData:_mBufferA]; 86 | [self generateRandomFloatData:_mBufferB]; 87 | } 88 | 89 | - (void) sendComputeCommand 90 | { 91 | // Create a command buffer to hold commands. 92 | id commandBuffer = [_mCommandQueue commandBuffer]; 93 | assert(commandBuffer != nil); 94 | 95 | // Start a compute pass. 96 | id computeEncoder = [commandBuffer computeCommandEncoder]; 97 | assert(computeEncoder != nil); 98 | 99 | [self encodeAddCommand:computeEncoder]; 100 | 101 | // End the compute pass. 102 | [computeEncoder endEncoding]; 103 | 104 | // Execute the command. 105 | [commandBuffer commit]; 106 | 107 | // Normally, you want to do other work in your app while the GPU is running, 108 | // but in this example, the code simply blocks until the calculation is complete. 109 | [commandBuffer waitUntilCompleted]; 110 | 111 | [self verifyResults]; 112 | } 113 | 114 | - (void)encodeAddCommand:(id)computeEncoder { 115 | 116 | // Encode the pipeline state object and its parameters. 117 | [computeEncoder setComputePipelineState:_mAddFunctionPSO]; 118 | [computeEncoder setBuffer:_mBufferA offset:0 atIndex:0]; 119 | [computeEncoder setBuffer:_mBufferB offset:0 atIndex:1]; 120 | [computeEncoder setBuffer:_mBufferResult offset:0 atIndex:2]; 121 | 122 | MTLSize gridSize = MTLSizeMake(arrayLength, 1, 1); 123 | 124 | // Calculate a threadgroup size. 125 | NSUInteger threadGroupSize = _mAddFunctionPSO.maxTotalThreadsPerThreadgroup; 126 | if (threadGroupSize > arrayLength) 127 | { 128 | threadGroupSize = arrayLength; 129 | } 130 | MTLSize threadgroupSize = MTLSizeMake(threadGroupSize, 1, 1); 131 | 132 | // Encode the compute command. 133 | [computeEncoder dispatchThreads:gridSize 134 | threadsPerThreadgroup:threadgroupSize]; 135 | } 136 | 137 | - (void) generateRandomFloatData: (id) buffer 138 | { 139 | float* dataPtr = buffer.contents; 140 | 141 | for (unsigned long index = 0; index < arrayLength; index++) 142 | { 143 | dataPtr[index] = (float)rand()/(float)(RAND_MAX); 144 | } 145 | } 146 | - (void) verifyResults 147 | { 148 | float* a = _mBufferA.contents; 149 | float* b = _mBufferB.contents; 150 | float* result = _mBufferResult.contents; 151 | 152 | for (unsigned long index = 0; index < arrayLength; index++) 153 | { 154 | if (result[index] != (a[index] + b[index])) 155 | { 156 | printf("Compute ERROR: index=%lu result=%g vs %g=a+b\n", 157 | index, result[index], a[index] + b[index]); 158 | assert(result[index] == (a[index] + b[index])); 159 | } 160 | } 161 | printf("Compute results as expected\n"); 162 | } 163 | @end 164 | -------------------------------------------------------------------------------- /01-MetalAdder/add.metal: -------------------------------------------------------------------------------- 1 | /* 2 | See LICENSE-original.txt for this sample’s licensing information. 3 | 4 | Abstract: 5 | A shader that adds two arrays of floats. 6 | */ 7 | 8 | #include 9 | using namespace metal; 10 | /// This is a Metal Shading Language (MSL) function equivalent to the add_arrays() 11 | /// C function, used to perform the calculation on a GPU. 12 | kernel void add_arrays(device const float* inA, 13 | device const float* inB, 14 | device float* result, 15 | uint index [[thread_position_in_grid]]) 16 | { 17 | // the for-loop is replaced with a collection of threads, each of which 18 | // calls this function. 19 | result[index] = inA[index] + inB[index]; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /01-MetalAdder/main.cpp: -------------------------------------------------------------------------------- 1 | // Lars Gebraad, 20th of April, 2022 2 | // 3 | 4 | #include 5 | #include 6 | 7 | #define NS_PRIVATE_IMPLEMENTATION 8 | #define CA_PRIVATE_IMPLEMENTATION 9 | #define MTL_PRIVATE_IMPLEMENTATION 10 | #include "Foundation/Foundation.hpp" 11 | #include "Metal/Metal.hpp" 12 | #include "QuartzCore/QuartzCore.hpp" 13 | 14 | #include "MetalAdder.hpp" 15 | 16 | template 17 | void add_array_openmp(const T *a, const T *b, T *c, size_t length); 18 | template 19 | void add_array_serial(const T *a, const T *b, T *c, size_t length); 20 | int omp_thread_count(); 21 | template 22 | void statistics(T *array, size_t length, T &array_mean, T &array_std); 23 | 24 | typedef std::chrono::microseconds time_unit; 25 | auto unit_name = "microseconds"; 26 | 27 | int main(int argc, char *argv[]) 28 | { 29 | // Create GPU code / arrays -------------------------------------------------------- 30 | MTL::Device *device = MTL::CreateSystemDefaultDevice(); 31 | MetalAdder *adder = new MetalAdder(device); 32 | 33 | // Verify Metal code --------------------------------------------------------------- 34 | adder->sendComputeCommand(); // This computes the array sum 35 | adder->verifyResults(); 36 | 37 | // Profile Metal code -------------------------------------------------------------- 38 | int repeats = 100; 39 | auto durations = new float[repeats]; 40 | for (size_t repeat = 0; repeat < repeats; repeat++) 41 | { 42 | auto start = std::chrono::high_resolution_clock::now(); 43 | adder->sendComputeCommand(); 44 | auto stop = std::chrono::high_resolution_clock::now(); 45 | auto duration = std::chrono::duration_cast(stop - start).count(); 46 | durations[repeat] = duration; 47 | } 48 | float array_mean; 49 | float array_std; 50 | statistics(durations, repeats, array_mean, array_std); 51 | std::cout << "Metal (GPU) code performance: " << std::endl; 52 | std::cout << array_mean << unit_name << " \t +/- " << array_std << unit_name << std::endl 53 | << std::endl; 54 | 55 | // Verify serial code -------------------------------------------------------------- 56 | // Get buffers pointers for CPU code. Using MTL::ResourceStorageModeShared should 57 | // make them accessible to both GPU and CPU, perfect! 58 | auto array_a = ((float *)adder->_mBufferA->contents()); 59 | auto array_b = ((float *)adder->_mBufferB->contents()); 60 | auto array_c = ((float *)adder->_mBufferResult->contents()); 61 | 62 | // Let's randomize the data again, making sure that the result buffer starts out 63 | // incorrect 64 | adder->prepareData(); 65 | add_array_serial(array_a, array_b, array_c, arrayLength); 66 | adder->verifyResults(); 67 | 68 | // Profile serial code ------------------------------------------------------------- 69 | for (size_t repeat = 0; repeat < repeats; repeat++) 70 | { 71 | auto start = std::chrono::high_resolution_clock::now(); 72 | add_array_serial(array_a, array_b, array_c, arrayLength); 73 | auto stop = std::chrono::high_resolution_clock::now(); 74 | auto duration = std::chrono::duration_cast(stop - start).count(); 75 | durations[repeat] = duration; 76 | } 77 | statistics(durations, repeats, array_mean, array_std); 78 | std::cout << "Serial code performance: " << std::endl; 79 | std::cout << array_mean << unit_name << " \t +/- " << array_std << unit_name << std::endl 80 | << std::endl; 81 | 82 | size_t max_threads = 10; 83 | for (size_t threads = 1; threads <= max_threads; threads++) 84 | { 85 | 86 | // Verify OpenMP code -------------------------------------------------------------- 87 | omp_set_num_threads(threads); 88 | adder->prepareData(); 89 | add_array_openmp(array_a, array_b, array_c, arrayLength); 90 | adder->verifyResults(); 91 | 92 | // Profile OpenMP code ------------------------------------------------------------- 93 | for (size_t repeat = 0; repeat < repeats; repeat++) 94 | { 95 | auto start = std::chrono::high_resolution_clock::now(); 96 | add_array_openmp(array_a, array_b, array_c, arrayLength); 97 | auto stop = std::chrono::high_resolution_clock::now(); 98 | auto duration = std::chrono::duration_cast(stop - start).count(); 99 | durations[repeat] = duration; 100 | } 101 | statistics(durations, repeats, array_mean, array_std); 102 | std::cout << "OpenMP (" << omp_thread_count() << " threads) code performance: " << std::endl; 103 | std::cout << array_mean << unit_name << " \t +/- " << array_std << unit_name << std::endl 104 | << std::endl; 105 | } 106 | 107 | delete[] durations; 108 | delete adder; 109 | device->release(); 110 | } 111 | 112 | template 113 | void add_array_openmp(const T *a, const T *b, T *c, size_t length) 114 | { 115 | // Compute array sum a+b=c parallely using OpenMP, template function 116 | #pragma omp parallel for 117 | for ( 118 | size_t i = 0; i < length; i++) 119 | { 120 | c[i] = a[i] + b[i]; 121 | } 122 | } 123 | 124 | template 125 | void add_array_serial(const T *a, const T *b, T *c, size_t length) 126 | { 127 | // Compute array sum a+b=c serially, template function 128 | for (size_t i = 0; i < length; i++) 129 | { 130 | c[i] = a[i] + b[i]; 131 | } 132 | } 133 | 134 | int omp_thread_count() 135 | { 136 | int n = 0; 137 | #pragma omp parallel reduction(+ \ 138 | : n) 139 | n += 1; 140 | return n; 141 | } 142 | 143 | template 144 | void statistics(T *array, size_t length, T &array_mean, T &array_std) 145 | { 146 | // Compute mean and standard deviation serially, template function 147 | 148 | array_mean = 0; 149 | for (size_t repeat = 0; repeat < length; repeat++) 150 | { 151 | array_mean += array[repeat]; 152 | } 153 | array_mean /= length; 154 | 155 | array_std = 0; 156 | for (size_t repeat = 0; repeat < length; repeat++) 157 | { 158 | array_std += pow(array_mean - array[repeat], 2.0); 159 | } 160 | array_std /= length; 161 | array_std = pow(array_std, 0.5); 162 | } -------------------------------------------------------------------------------- /01-MetalAdder/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | See LICENSE folder for this sample’s licensing information. 3 | 4 | Abstract: 5 | An app that performs a simple calculation on a GPU. 6 | */ 7 | 8 | #import 9 | #import 10 | #import "MetalAdder.h" 11 | 12 | // This is the C version of the function that the sample 13 | // implements in Metal Shading Language. 14 | void add_arrays(const float* inA, 15 | const float* inB, 16 | float* result, 17 | int length) 18 | { 19 | for (int index = 0; index < length ; index++) 20 | { 21 | result[index] = inA[index] + inB[index]; 22 | } 23 | } 24 | 25 | int main(int argc, const char * argv[]) { 26 | @autoreleasepool { 27 | 28 | id device = MTLCreateSystemDefaultDevice(); 29 | 30 | // Create the custom object used to encapsulate the Metal code. 31 | // Initializes objects to communicate with the GPU. 32 | MetalAdder* adder = [[MetalAdder alloc] initWithDevice:device]; 33 | 34 | // Create buffers to hold data 35 | [adder prepareData]; 36 | 37 | // Send a command to the GPU to perform the calculation. 38 | [adder sendComputeCommand]; 39 | 40 | NSLog(@"Execution finished"); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /02-GeneralArrayOperations/CPUOperations.cpp: -------------------------------------------------------------------------------- 1 | #include "CPUOperations.hpp" 2 | #include 3 | 4 | void generateRandomFloatData(float *dataPtr, size_t arrayLength) 5 | { 6 | for (unsigned long index = 0; index < arrayLength; index++) 7 | { 8 | dataPtr[index] = (float)rand() / (float)(RAND_MAX); 9 | } 10 | } 11 | 12 | void setZeros(float *dataPtr, size_t arrayLength) 13 | { 14 | for (size_t i = 0; i < arrayLength; i++) 15 | { 16 | dataPtr[i] = 0; 17 | } 18 | } 19 | 20 | void add(const float *x, const float *y, float *r, size_t arrayLength) 21 | { 22 | for (unsigned long index = 0; index < arrayLength; index++) 23 | { 24 | r[index] = x[index] + y[index]; 25 | } 26 | } 27 | 28 | void multiply(const float *x, const float *y, float *r, size_t arrayLength) 29 | { 30 | for (unsigned long index = 0; index < arrayLength; index++) 31 | { 32 | r[index] = x[index] * y[index]; 33 | } 34 | } 35 | 36 | void saxpy(const float *a, const float *x, const float *y, float *r, size_t arrayLength) 37 | { 38 | for (unsigned long index = 0; index < arrayLength; index++) 39 | { 40 | r[index] = *a * x[index] + y[index]; 41 | } 42 | } 43 | 44 | void central_difference(const float *delta, const float *x, float *r, size_t arrayLength) 45 | { 46 | for (unsigned long index = 0; index < arrayLength; index++) 47 | { 48 | if (index == 0) 49 | { 50 | r[index] = (x[index + 1] - x[index]) / *delta; 51 | } 52 | else if (index == arrayLength - 1) 53 | { 54 | r[index] = (x[index] - x[index - 1]) / (*delta); 55 | } 56 | else 57 | { 58 | r[index] = (x[index + 1] - x[index - 1]) / (2 * *delta); 59 | } 60 | } 61 | } 62 | 63 | void add_openmp(const float *x, const float *y, float *r, size_t arrayLength) 64 | { 65 | unsigned long i; 66 | #pragma omp parallel for default(none) private(i) shared(x, y, arrayLength, r) 67 | 68 | for (i = 0; i < arrayLength; i++) 69 | { 70 | r[i] = x[i] + y[i]; 71 | } 72 | } 73 | 74 | void multiply_openmp(const float *x, const float *y, float *r, size_t arrayLength) 75 | { 76 | unsigned long i; 77 | #pragma omp parallel for default(none) private(i) shared(x, y, arrayLength, r) 78 | 79 | for (i = 0; i < arrayLength; i++) 80 | { 81 | r[i] = x[i] * y[i]; 82 | } 83 | } 84 | 85 | void saxpy_openmp(const float *a, const float *x, const float *y, float *r, size_t arrayLength) 86 | { 87 | unsigned long i; 88 | #pragma omp parallel for default(none) private(i) shared(a, x, y, arrayLength, r) 89 | for (i = 0; i < arrayLength; i++) 90 | { 91 | r[i] = *a * x[i] * y[i]; 92 | } 93 | } 94 | 95 | void central_difference_openmp(const float *delta, const float *x, float *r, size_t arrayLength) 96 | { 97 | unsigned long index; 98 | #pragma omp parallel for default(none) private(index) shared(delta, x, arrayLength, r) 99 | 100 | for (index = 0; index < arrayLength; index++) 101 | { 102 | if (index == 0) 103 | { 104 | r[index] = (x[index + 1] - x[index]) / *delta; 105 | } 106 | else if (index == arrayLength - 1) 107 | { 108 | r[index] = (x[index] - x[index - 1]) / (*delta); 109 | } 110 | else 111 | { 112 | r[index] = (x[index + 1] - x[index - 1]) / (2 * *delta); 113 | } 114 | } 115 | } 116 | 117 | bool equalFloat(float a, float b, float epsilon) 118 | { 119 | return fabs(a - b) <= ((fabs(a) > fabs(b) ? fabs(b) : fabs(a)) * epsilon); 120 | } 121 | 122 | bool equalArray(const float *x, const float *y, size_t arrayLength) 123 | { 124 | for (unsigned long index = 0; index < arrayLength; index++) 125 | { 126 | if (!equalFloat(x[index], y[index], std::numeric_limits::epsilon())) 127 | { 128 | 129 | printf("Compute ERROR: index=%lu x=%e vs y=%e\n", 130 | index, x[index], y[index]); 131 | return false; 132 | }; 133 | } 134 | return true; 135 | } 136 | 137 | void statistics(float *array, size_t length, float &array_mean, float &array_std) 138 | { 139 | // Compute mean and standard deviation serially, template function 140 | 141 | array_mean = 0; 142 | for (size_t repeat = 0; repeat < length; repeat++) 143 | { 144 | array_mean += array[repeat]; 145 | } 146 | array_mean /= length; 147 | 148 | array_std = 0; 149 | for (size_t repeat = 0; repeat < length; repeat++) 150 | { 151 | array_std += pow(array_mean - array[repeat], 2.0); 152 | } 153 | array_std /= length; 154 | array_std = pow(array_std, 0.5); 155 | } 156 | 157 | int omp_thread_count() 158 | { 159 | int n = 0; 160 | #pragma omp parallel reduction(+ \ 161 | : n) 162 | n += 1; 163 | return n; 164 | } 165 | -------------------------------------------------------------------------------- /02-GeneralArrayOperations/CPUOperations.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | void add(const float *x, const float *y, float *r, size_t arrayLength); 7 | void multiply(const float *x, const float *y, float *r, size_t arrayLength); 8 | void saxpy(const float *a, const float *x, const float *y, float *r, size_t arrayLength); 9 | void central_difference(const float *delta, const float *x, float *r, size_t arrayLength); 10 | 11 | void add_openmp(const float *x, const float *y, float *r, size_t arrayLength); 12 | void multiply_openmp(const float *x, const float *y, float *r, size_t arrayLength); 13 | void saxpy_openmp(const float *a, const float *x, const float *y, float *r, size_t arrayLength); 14 | void central_difference_openmp(const float *delta, const float *x, float *r, size_t arrayLength); 15 | 16 | bool equalArray(const float *x, const float *y, size_t arrayLength); 17 | void statistics(float *array, size_t length, float &array_mean, float &array_std); 18 | 19 | void generateRandomFloatData(float *dataPtr, size_t arrayLength); 20 | void setZeros(float *dataPtr, size_t arrayLength); 21 | int omp_thread_count(); -------------------------------------------------------------------------------- /02-GeneralArrayOperations/MetalOperations.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | CPP translation of original Objective-C MetalAdder.h. Some stuff has been moved over 3 | here from the cpp file. Source: https://developer.apple.com/documentation/metal/performing_calculations_on_a_gpu?language=objc 4 | 5 | Original distribution license: LICENSE-original.txt. 6 | 7 | Abstract: 8 | A class to manage all of the Metal objects this app creates. 9 | */ 10 | #pragma once 11 | 12 | #include "Foundation/Foundation.hpp" 13 | #include "Metal/Metal.hpp" 14 | 15 | #include "map" 16 | 17 | class MetalOperations 18 | { 19 | public: 20 | MTL::Device *_mDevice; 21 | 22 | MetalOperations(MTL::Device *device); 23 | 24 | void Blocking1D(std::vector buffers, 25 | size_t arrayLength, 26 | const char *method); 27 | 28 | void addArrays(MTL::Buffer *x_array, 29 | MTL::Buffer *y_array, 30 | MTL::Buffer *r_array, 31 | size_t arrayLength); 32 | 33 | void addMultiply(MTL::Buffer *x_array, 34 | MTL::Buffer *y_array, 35 | MTL::Buffer *r_array, 36 | size_t arrayLength); 37 | 38 | void multiplyArrays(MTL::Buffer *x_array, 39 | MTL::Buffer *y_array, 40 | MTL::Buffer *r_array, 41 | size_t arrayLength); 42 | 43 | void saxpyArrays(MTL::Buffer *alpha, 44 | MTL::Buffer *x_array, 45 | MTL::Buffer *y_array, 46 | MTL::Buffer *r_array, 47 | size_t arrayLength); 48 | 49 | void central_difference(MTL::Buffer *delta, 50 | MTL::Buffer *x_array, 51 | MTL::Buffer *r_array, 52 | size_t arrayLength); 53 | 54 | void inspector(MTL::Buffer *x_array, 55 | MTL::Buffer *r_array, 56 | MTL::Buffer *store, 57 | size_t arrayLength); 58 | 59 | private: 60 | std::map functionMap; 61 | std::map functionPipelineMap; 62 | 63 | // The command queue used to pass commands to the device. 64 | MTL::CommandQueue *_mCommandQueue; 65 | }; 66 | -------------------------------------------------------------------------------- /02-GeneralArrayOperations/main_chaining.cpp: -------------------------------------------------------------------------------- 1 | // Lars Gebraad, 20th of April, 2022 2 | // 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define NS_PRIVATE_IMPLEMENTATION 9 | #define CA_PRIVATE_IMPLEMENTATION 10 | #define MTL_PRIVATE_IMPLEMENTATION 11 | #include "Foundation/Foundation.hpp" 12 | #include "Metal/Metal.hpp" 13 | #include "QuartzCore/QuartzCore.hpp" 14 | 15 | #include "MetalOperations.hpp" 16 | #include "CPUOperations.hpp" 17 | 18 | // Configuration ----------------------------------------------------------------------- 19 | // Amount of repeats for benchmarking 20 | size_t repeats = 1000; 21 | // Length of array to test kernels on 22 | const unsigned int arrayLength = 1 << 26; 23 | // end --------------------------------------------------------------------------------- 24 | 25 | const unsigned int bufferSize = arrayLength * sizeof(float); 26 | 27 | typedef std::chrono::microseconds time_unit; 28 | auto unit_name = "microseconds"; 29 | 30 | int main(int argc, char *argv[]) 31 | { 32 | 33 | // Set up objects and buffers ------------------------------------------------------ 34 | 35 | MTL::Device *device = MTL::CreateSystemDefaultDevice(); 36 | 37 | std::cout << "Running on " << device->name()->utf8String() << std::endl; 38 | std::cout << "Array size " << arrayLength << ", tests repeated " << repeats 39 | << " times" << std::endl 40 | << std::endl; 41 | 42 | // MTL buffers to hold data. 43 | MTL::Buffer *a_MTL = device->newBuffer(bufferSize, MTL::ResourceStorageModeManaged); 44 | MTL::Buffer *b_MTL = device->newBuffer(bufferSize, MTL::ResourceStorageModeManaged); 45 | MTL::Buffer *c_MTL = device->newBuffer(bufferSize, MTL::ResourceStorageModeManaged); 46 | MTL::Buffer *k_MTL = device->newBuffer(sizeof(float), MTL::ResourceStorageModeManaged); // Scalar 47 | 48 | // Get a C++-style reference to the buffer 49 | auto a_CPP = (float *)a_MTL->contents(); 50 | auto b_CPP = (float *)b_MTL->contents(); 51 | auto c_CPP = (float *)c_MTL->contents(); 52 | auto k_CPP = (float *)k_MTL->contents(); 53 | 54 | // Array to store CPU result on for verification of kernels 55 | auto c_VER = new float[arrayLength]; 56 | 57 | generateRandomFloatData(a_CPP, arrayLength); 58 | generateRandomFloatData(b_CPP, arrayLength); 59 | setZeros(c_CPP, arrayLength); 60 | *k_CPP = 1.0f; 61 | 62 | // Create GPU object 63 | MetalOperations *arrayOps = new MetalOperations(device); 64 | 65 | // Compute verification result 66 | add(a_CPP, b_CPP, c_VER, arrayLength); 67 | multiply(c_VER, b_CPP, c_VER, arrayLength); 68 | 69 | // Verify serial gpu operations 70 | arrayOps->addArrays(a_MTL, b_MTL, c_MTL, arrayLength); 71 | arrayOps->multiplyArrays(c_MTL, b_MTL, c_MTL, arrayLength); 72 | assert(equalArray(c_VER, c_CPP, arrayLength)); 73 | setZeros(c_CPP, arrayLength); 74 | 75 | // Verify compound operation 76 | arrayOps->addMultiply(a_MTL, b_MTL, c_MTL, arrayLength); 77 | assert(equalArray(c_VER, c_CPP, arrayLength)); 78 | setZeros(c_CPP, arrayLength); 79 | 80 | std::cout << "Starting benchmarking ..." << std::endl; 81 | 82 | // Serial benchmarking ------------------------------------------------------------- 83 | 84 | float *durations = new float[repeats]; 85 | float array_mean; 86 | float array_std; 87 | 88 | for (size_t repeat = 0; repeat < repeats; repeat++) 89 | { 90 | auto start = std::chrono::high_resolution_clock::now(); 91 | arrayOps->addArrays(a_MTL, b_MTL, c_MTL, arrayLength); 92 | arrayOps->multiplyArrays(c_MTL, b_MTL, c_MTL, arrayLength); 93 | auto stop = std::chrono::high_resolution_clock::now(); 94 | auto duration = std::chrono::duration_cast(stop - start).count(); 95 | durations[repeat] = duration; 96 | } 97 | statistics(durations, repeats, array_mean, array_std); 98 | 99 | std::cout << "Serial operations: \t\t" 100 | << array_mean << unit_name << " \t +/- " << array_std << unit_name << std::endl; 101 | 102 | // Compound benchmarking ----------------------------------------------------------- 103 | 104 | for (size_t repeat = 0; repeat < repeats; repeat++) 105 | { 106 | auto start = std::chrono::high_resolution_clock::now(); 107 | arrayOps->addMultiply(a_MTL, b_MTL, c_MTL, arrayLength); 108 | auto stop = std::chrono::high_resolution_clock::now(); 109 | auto duration = std::chrono::duration_cast(stop - start).count(); 110 | durations[repeat] = duration; 111 | } 112 | statistics(durations, repeats, array_mean, array_std); 113 | 114 | std::cout << "Compound operations: \t\t" 115 | << array_mean << unit_name << " \t +/- " << array_std << unit_name << std::endl; 116 | } 117 | -------------------------------------------------------------------------------- /02-GeneralArrayOperations/ops.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | 5 | kernel void add_arrays(device const float* X [[buffer(0)]], 6 | device const float* Y [[buffer(1)]], 7 | device float* result [[buffer(2)]], 8 | uint index [[thread_position_in_grid]]) 9 | { 10 | result[index] = X[index] + Y[index]; 11 | } 12 | 13 | 14 | kernel void multiply_arrays(device const float* X [[buffer(0)]], 15 | device const float* Y [[buffer(1)]], 16 | device float* result [[buffer(2)]], 17 | uint index [[thread_position_in_grid]]) 18 | { 19 | result[index] = X[index] * Y[index]; 20 | } 21 | 22 | kernel void saxpy(device const float* a [[buffer(0)]], 23 | device const float* X [[buffer(1)]], 24 | device const float* Y [[buffer(2)]], 25 | device float* result [[buffer(3)]], 26 | uint index [[thread_position_in_grid]]) 27 | { 28 | result[index] = (*a) * X[index] + Y[index]; 29 | } 30 | 31 | kernel void central_difference( 32 | device const float* delta [[buffer(0)]], 33 | device const float* X [[buffer(1)]], 34 | device float* result [[buffer(2)]], 35 | uint index [[thread_position_in_grid]], 36 | uint arrayLength [[threads_per_grid]]) 37 | { 38 | if (index == 0) 39 | { 40 | result[index] = (X[index + 1] - X[index]) / *delta; 41 | } 42 | else if (index == arrayLength - 1) 43 | { 44 | result[index] = (X[index] - X[index - 1]) / *delta; 45 | } 46 | else 47 | { 48 | result[index] = (X[index + 1] - X[index - 1]) / (2 * *delta); 49 | } 50 | } 51 | 52 | kernel void inspector( 53 | device const float* X [[buffer(0)]], 54 | device float* result [[buffer(1)]], 55 | device uint* store [[buffer(2)]], 56 | uint thread_position_in_grid [[thread_position_in_grid]], 57 | uint threads_per_grid [[threads_per_grid]], 58 | uint dispatch_quadgroups_per_threadgroup [[dispatch_quadgroups_per_threadgroup]], 59 | uint dispatch_simdgroups_per_threadgroup [[dispatch_simdgroups_per_threadgroup]], 60 | uint dispatch_threads_per_threadgroup [[dispatch_threads_per_threadgroup]], 61 | uint grid_origin [[grid_origin]], 62 | uint grid_size [[grid_size]], 63 | uint quadgroup_index_in_threadgroup [[quadgroup_index_in_threadgroup]], 64 | uint quadgroups_per_threadgroup [[quadgroups_per_threadgroup]], 65 | uint simdgroup_index_in_threadgroup [[simdgroup_index_in_threadgroup]], 66 | uint simdgroups_per_threadgroup [[simdgroups_per_threadgroup]], 67 | uint thread_execution_width [[thread_execution_width]], 68 | uint thread_index_in_quadgroup [[thread_index_in_quadgroup]], 69 | uint thread_index_in_simdgroup [[thread_index_in_simdgroup]], 70 | uint thread_index_in_threadgroup [[thread_index_in_threadgroup]], 71 | uint thread_position_in_threadgroup [[thread_position_in_threadgroup]], 72 | uint threadgroup_position_in_grid [[threadgroup_position_in_grid]], 73 | uint threadgroups_per_grid [[threadgroups_per_grid]], 74 | uint threads_per_simdgroup [[threads_per_simdgroup]], 75 | uint threads_per_threadgroup [[threads_per_threadgroup]]) 76 | { 77 | result[thread_position_in_grid] = X[thread_position_in_grid] + 1.0; 78 | 79 | if (thread_position_in_grid == 200){ 80 | store[0] = thread_position_in_grid; 81 | store[1] = threads_per_grid; 82 | store[2] = dispatch_quadgroups_per_threadgroup; // quadgroup is 4 simd groups 83 | store[3] = dispatch_simdgroups_per_threadgroup; 84 | store[4] = dispatch_threads_per_threadgroup; 85 | store[5] = grid_origin; 86 | store[6] = grid_size; 87 | store[7] = quadgroup_index_in_threadgroup; 88 | store[8] = quadgroups_per_threadgroup; 89 | store[9] = simdgroup_index_in_threadgroup; 90 | store[10] = simdgroups_per_threadgroup; 91 | store[11] = thread_execution_width; 92 | store[12] = thread_index_in_quadgroup; 93 | store[13] = thread_index_in_simdgroup; 94 | store[14] = thread_index_in_threadgroup; 95 | store[15] = thread_position_in_threadgroup; 96 | store[16] = threadgroup_position_in_grid; 97 | store[17] = threadgroups_per_grid; 98 | store[18] = threads_per_simdgroup; 99 | store[19] = threads_per_threadgroup; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /03-2DKernels/CPUOperations.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | void add(const float *x, const float *y, float *r, size_t arrayLength); 7 | void multiply(const float *x, const float *y, float *r, size_t arrayLength); 8 | void saxpy(const float *a, const float *x, const float *y, float *r, size_t arrayLength); 9 | void central_difference(const float *delta, const float *x, float *r, size_t arrayLength); 10 | 11 | void add_openmp(const float *x, const float *y, float *r, size_t arrayLength); 12 | void multiply_openmp(const float *x, const float *y, float *r, size_t arrayLength); 13 | void saxpy_openmp(const float *a, const float *x, const float *y, float *r, size_t arrayLength); 14 | void central_difference_openmp(const float *delta, const float *x, float *r, size_t arrayLength); 15 | 16 | bool equalArray(const float *x, const float *y, size_t arrayLength); 17 | void statistics(float *array, size_t length, float &array_mean, float &array_std); 18 | 19 | void generateRandomFloatData(float *dataPtr, size_t arrayLength); 20 | void setZeros(float *dataPtr, size_t arrayLength); 21 | int omp_thread_count(); 22 | 23 | int linear_IDX(int pos1, int pos2, int shape1, int shape2); 24 | void quadratic2d(const float *X, const float *Y, float *result, int shape1, int shape2); 25 | void quadratic2d_openmp(const float *X, const float *Y, float *result, int shape1, int shape2); 26 | void laplacian2d(const float *X, float *result, int shape1, int shape2); 27 | void laplacian2d_openmp(const float *X, float *result, int shape1, int shape2); 28 | void laplacian2d9p(const float *X, float *result, int shape1, int shape2); 29 | void laplacian2d9p_openmp(const float *X, float *result, int shape1, int shape2); -------------------------------------------------------------------------------- /03-2DKernels/MetalOperations.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | CPP translation of original Objective-C MetalAdder.h. Some stuff has been moved over 3 | here from the cpp file. Source: https://developer.apple.com/documentation/metal/performing_calculations_on_a_gpu?language=objc 4 | 5 | Original distribution license: LICENSE-original.txt. 6 | 7 | Abstract: 8 | A class to manage all of the Metal objects this app creates. 9 | */ 10 | #pragma once 11 | 12 | #include "Foundation/Foundation.hpp" 13 | #include "Metal/Metal.hpp" 14 | 15 | #include "map" 16 | 17 | class MetalOperations 18 | { 19 | public: 20 | MTL::Device *_mDevice; 21 | 22 | MetalOperations(MTL::Device *device); 23 | 24 | void Blocking1D(std::vector buffers, 25 | size_t arrayLength, 26 | const char *method); 27 | 28 | void Blocking2D(std::vector buffers, 29 | size_t rows, 30 | size_t columns, 31 | const char *method); 32 | 33 | void addArrays(MTL::Buffer *x_array, 34 | MTL::Buffer *y_array, 35 | MTL::Buffer *r_array, 36 | size_t arrayLength); 37 | 38 | void addMultiply(MTL::Buffer *x_array, 39 | MTL::Buffer *y_array, 40 | MTL::Buffer *r_array, 41 | size_t arrayLength); 42 | 43 | void multiplyArrays(MTL::Buffer *x_array, 44 | MTL::Buffer *y_array, 45 | MTL::Buffer *r_array, 46 | size_t arrayLength); 47 | 48 | void saxpyArrays(MTL::Buffer *alpha, 49 | MTL::Buffer *x_array, 50 | MTL::Buffer *y_array, 51 | MTL::Buffer *r_array, 52 | size_t arrayLength); 53 | 54 | void central_difference(MTL::Buffer *delta, 55 | MTL::Buffer *x_array, 56 | MTL::Buffer *r_array, 57 | size_t arrayLength); 58 | 59 | void quadratic2d(MTL::Buffer *X, 60 | MTL::Buffer *Y, 61 | MTL::Buffer *R, 62 | size_t rows, 63 | size_t columns); 64 | 65 | void laplacian2d(MTL::Buffer *X, 66 | MTL::Buffer *R, 67 | size_t rows, 68 | size_t columns); 69 | 70 | void laplacian2d9p(MTL::Buffer *X, 71 | MTL::Buffer *R, 72 | size_t rows, 73 | size_t columns); 74 | 75 | void inspector(MTL::Buffer *x_array, 76 | MTL::Buffer *r_array, 77 | MTL::Buffer *store, 78 | size_t arrayLength); 79 | 80 | private: 81 | std::map functionMap; 82 | std::map functionPipelineMap; 83 | 84 | // The command queue used to pass commands to the device. 85 | MTL::CommandQueue *_mCommandQueue; 86 | }; 87 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 LARS GEBRAAD 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /LICENSE-original.txt: -------------------------------------------------------------------------------- 1 | Copyright © 2020 Apple Inc. 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. 8 | 9 | -------------------------------------------------------------------------------- /Metal-Feature-Set-Tables.numbers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsgeb/m1-gpu-cpp/3d8f8c587ab605ce32a39a01c847bfe53d71ef02/Metal-Feature-Set-Tables.numbers -------------------------------------------------------------------------------- /Metal-Shading-Language-Specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsgeb/m1-gpu-cpp/3d8f8c587ab605ce32a39a01c847bfe53d71ef02/Metal-Shading-Language-Specification.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # M1 GPUs for (scientific) computations in C++ 2 | 3 | In this repo, I explore the capabilities of the Metal Shading Language 4 | combined with C++, specifically for use of accelerating scientific codes. 5 | 6 | This repo accompaines "Seamless GPU acceleration for C++ based physics using the M1's 7 | unified processing units, a case study for elastic wave propagation and full-waveform 8 | inversion". If you use VSCode, all instructions to compile can be found in `.vscode`. 9 | 10 | I also wrote a few blog posts about the work in this repo: 11 | 12 | - [Getting started](https://larsgeb.github.io/2022/04/20/m1-gpu.html) 13 | - [SAXPY and FD](https://larsgeb.github.io/2022/04/22/m1-gpu.html) 14 | 15 | However, if you just want to try out the code, make sure you install `llvm` 16 | and `libomp` using brew and Xcode and its command line tools. By cloning the 17 | repo and opening it in VSCode you should have all build configurations. 18 | 19 | Additionally, I wrote a preprint (with the actual paper currently in peer-review) on how 20 | to use MSL for modelling of PDEs [available on arXiv](https://arxiv.org/abs/2206.01791). 21 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/Foundation.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/Foundation.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSArray.hpp" 26 | #include "NSAutoreleasePool.hpp" 27 | #include "NSBundle.hpp" 28 | #include "NSData.hpp" 29 | #include "NSDate.hpp" 30 | #include "NSDefines.hpp" 31 | #include "NSDictionary.hpp" 32 | #include "NSEnumerator.hpp" 33 | #include "NSError.hpp" 34 | #include "NSLock.hpp" 35 | #include "NSNotification.hpp" 36 | #include "NSNumber.hpp" 37 | #include "NSObject.hpp" 38 | #include "NSPrivate.hpp" 39 | #include "NSProcessInfo.hpp" 40 | #include "NSRange.hpp" 41 | #include "NSString.hpp" 42 | #include "NSTypes.hpp" 43 | #include "NSURL.hpp" 44 | 45 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 46 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSArray.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSArray.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSObject.hpp" 26 | #include "NSTypes.hpp" 27 | 28 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 29 | 30 | namespace NS 31 | { 32 | class Array : public Copying 33 | { 34 | public: 35 | static Array* array(); 36 | static Array* array(const Object* pObject); 37 | static Array* array(const Object* const* pObjects, UInteger count); 38 | 39 | static Array* alloc(); 40 | 41 | Array* init(); 42 | Array* init(const Object* const* pObjects, UInteger count); 43 | Array* init(const class Coder* pCoder); 44 | 45 | template 46 | _Object* object(UInteger index) const; 47 | UInteger count() const; 48 | }; 49 | } 50 | 51 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 52 | 53 | _NS_INLINE NS::Array* NS::Array::array() 54 | { 55 | return Object::sendMessage(_NS_PRIVATE_CLS(NSArray), _NS_PRIVATE_SEL(array)); 56 | } 57 | 58 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 59 | 60 | _NS_INLINE NS::Array* NS::Array::array(const Object* pObject) 61 | { 62 | return Object::sendMessage(_NS_PRIVATE_CLS(NSArray), _NS_PRIVATE_SEL(arrayWithObject_), pObject); 63 | } 64 | 65 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 66 | 67 | _NS_INLINE NS::Array* NS::Array::array(const Object* const* pObjects, UInteger count) 68 | { 69 | return Object::sendMessage(_NS_PRIVATE_CLS(NSArray), _NS_PRIVATE_SEL(arrayWithObjects_count_), pObjects, count); 70 | } 71 | 72 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 73 | 74 | _NS_INLINE NS::Array* NS::Array::alloc() 75 | { 76 | return NS::Object::alloc(_NS_PRIVATE_CLS(NSArray)); 77 | } 78 | 79 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 80 | 81 | _NS_INLINE NS::Array* NS::Array::init() 82 | { 83 | return NS::Object::init(); 84 | } 85 | 86 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 87 | 88 | _NS_INLINE NS::Array* NS::Array::init(const Object* const* pObjects, UInteger count) 89 | { 90 | return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithObjects_count_), pObjects, count); 91 | } 92 | 93 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 94 | 95 | _NS_INLINE NS::Array* NS::Array::init(const class Coder* pCoder) 96 | { 97 | return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithCoder_), pCoder); 98 | } 99 | 100 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 101 | 102 | _NS_INLINE NS::UInteger NS::Array::count() const 103 | { 104 | return Object::sendMessage(this, _NS_PRIVATE_SEL(count)); 105 | } 106 | 107 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 108 | 109 | template 110 | _NS_INLINE _Object* NS::Array::object(UInteger index) const 111 | { 112 | return Object::sendMessage<_Object*>(this, _NS_PRIVATE_SEL(objectAtIndex_), index); 113 | } 114 | 115 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 116 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSAutoreleasePool.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSAutoreleasePool.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSDefines.hpp" 26 | #include "NSObject.hpp" 27 | #include "NSPrivate.hpp" 28 | #include "NSTypes.hpp" 29 | 30 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 31 | 32 | namespace NS 33 | { 34 | class AutoreleasePool : public Object 35 | { 36 | public: 37 | static AutoreleasePool* alloc(); 38 | AutoreleasePool* init(); 39 | 40 | void drain(); 41 | 42 | void addObject(Object* pObject); 43 | 44 | static void showPools(); 45 | }; 46 | } 47 | 48 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 49 | 50 | _NS_INLINE NS::AutoreleasePool* NS::AutoreleasePool::alloc() 51 | { 52 | return NS::Object::alloc(_NS_PRIVATE_CLS(NSAutoreleasePool)); 53 | } 54 | 55 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 56 | 57 | _NS_INLINE NS::AutoreleasePool* NS::AutoreleasePool::init() 58 | { 59 | return NS::Object::init(); 60 | } 61 | 62 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 63 | 64 | _NS_INLINE void NS::AutoreleasePool::drain() 65 | { 66 | Object::sendMessage(this, _NS_PRIVATE_SEL(drain)); 67 | } 68 | 69 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 70 | 71 | _NS_INLINE void NS::AutoreleasePool::addObject(Object* pObject) 72 | { 73 | Object::sendMessage(this, _NS_PRIVATE_SEL(addObject_), pObject); 74 | } 75 | 76 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 77 | 78 | _NS_INLINE void NS::AutoreleasePool::showPools() 79 | { 80 | Object::sendMessage(_NS_PRIVATE_CLS(NSAutoreleasePool), _NS_PRIVATE_SEL(showPools)); 81 | } 82 | 83 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 84 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSData.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSData.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSObject.hpp" 26 | #include "NSTypes.hpp" 27 | 28 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 29 | 30 | namespace NS 31 | { 32 | class Data : public Copying 33 | { 34 | public: 35 | void* mutableBytes() const; 36 | UInteger length() const; 37 | }; 38 | } 39 | 40 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 41 | 42 | _NS_INLINE void* NS::Data::mutableBytes() const 43 | { 44 | return Object::sendMessage(this, _NS_PRIVATE_SEL(mutableBytes)); 45 | } 46 | 47 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 48 | 49 | _NS_INLINE NS::UInteger NS::Data::length() const 50 | { 51 | return Object::sendMessage(this, _NS_PRIVATE_SEL(length)); 52 | } 53 | 54 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 55 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSDate.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSDate.hpp 4 | // 5 | // See LICENSE.txt for this project licensing information. 6 | // 7 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 8 | 9 | #pragma once 10 | 11 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "NSDefines.hpp" 14 | #include "NSObject.hpp" 15 | #include "NSPrivate.hpp" 16 | #include "NSTypes.hpp" 17 | 18 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 19 | 20 | namespace NS 21 | { 22 | 23 | using TimeInterval = double; 24 | 25 | class Date : public Copying 26 | { 27 | public: 28 | static Date* dateWithTimeIntervalSinceNow(TimeInterval secs); 29 | }; 30 | 31 | } // NS 32 | 33 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 34 | 35 | _NS_INLINE NS::Date* NS::Date::dateWithTimeIntervalSinceNow(NS::TimeInterval secs) 36 | { 37 | return NS::Object::sendMessage(_NS_PRIVATE_CLS(NSDate), _NS_PRIVATE_SEL(dateWithTimeIntervalSinceNow_), secs); 38 | } 39 | 40 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSDefines.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSDefines.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #define _NS_WEAK_IMPORT __attribute__((weak_import)) 26 | #define _NS_EXPORT __attribute__((visibility("default"))) 27 | #define _NS_EXTERN extern "C" _NS_EXPORT 28 | #define _NS_INLINE inline __attribute__((always_inline)) 29 | #define _NS_PACKED __attribute__((packed)) 30 | 31 | #define _NS_CONST(type, name) _NS_EXTERN type const name; 32 | #define _NS_ENUM(type, name) enum name : type 33 | #define _NS_OPTIONS(type, name) \ 34 | using name = type; \ 35 | enum : name 36 | 37 | #define _NS_CAST_TO_UINT(value) static_cast(value) 38 | #define _NS_VALIDATE_SIZE(ns, name) static_assert(sizeof(ns::name) == sizeof(ns##name), "size mismatch " #ns "::" #name) 39 | #define _NS_VALIDATE_ENUM(ns, name) static_assert(_NS_CAST_TO_UINT(ns::name) == _NS_CAST_TO_UINT(ns##name), "value mismatch " #ns "::" #name) 40 | 41 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 42 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSDictionary.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSDictionary.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSEnumerator.hpp" 26 | #include "NSObject.hpp" 27 | #include "NSTypes.hpp" 28 | 29 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 30 | 31 | namespace NS 32 | { 33 | class Dictionary : public NS::Copying 34 | { 35 | public: 36 | static Dictionary* dictionary(); 37 | static Dictionary* dictionary(const Object* pObject, const Object* pKey); 38 | static Dictionary* dictionary(const Object* const* pObjects, const Object* const* pKeys, UInteger count); 39 | 40 | static Dictionary* alloc(); 41 | 42 | Dictionary* init(); 43 | Dictionary* init(const Object* const* pObjects, const Object* const* pKeys, UInteger count); 44 | Dictionary* init(const class Coder* pCoder); 45 | 46 | template 47 | Enumerator<_KeyType>* keyEnumerator() const; 48 | 49 | template 50 | _Object* object(const Object* pKey) const; 51 | UInteger count() const; 52 | }; 53 | } 54 | 55 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 56 | 57 | _NS_INLINE NS::Dictionary* NS::Dictionary::dictionary() 58 | { 59 | return Object::sendMessage(_NS_PRIVATE_CLS(NSDictionary), _NS_PRIVATE_SEL(dictionary)); 60 | } 61 | 62 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 63 | 64 | _NS_INLINE NS::Dictionary* NS::Dictionary::dictionary(const Object* pObject, const Object* pKey) 65 | { 66 | return Object::sendMessage(_NS_PRIVATE_CLS(NSDictionary), _NS_PRIVATE_SEL(dictionaryWithObject_forKey_), pObject, pKey); 67 | } 68 | 69 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 70 | 71 | _NS_INLINE NS::Dictionary* NS::Dictionary::dictionary(const Object* const* pObjects, const Object* const* pKeys, UInteger count) 72 | { 73 | return Object::sendMessage(_NS_PRIVATE_CLS(NSDictionary), _NS_PRIVATE_SEL(dictionaryWithObjects_forKeys_count_), 74 | pObjects, pKeys, count); 75 | } 76 | 77 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 78 | 79 | _NS_INLINE NS::Dictionary* NS::Dictionary::alloc() 80 | { 81 | return NS::Object::alloc(_NS_PRIVATE_CLS(NSDictionary)); 82 | } 83 | 84 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 85 | 86 | _NS_INLINE NS::Dictionary* NS::Dictionary::init() 87 | { 88 | return NS::Object::init(); 89 | } 90 | 91 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 92 | 93 | _NS_INLINE NS::Dictionary* NS::Dictionary::init(const Object* const* pObjects, const Object* const* pKeys, UInteger count) 94 | { 95 | return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithObjects_forKeys_count_), pObjects, pKeys, count); 96 | } 97 | 98 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 99 | 100 | _NS_INLINE NS::Dictionary* NS::Dictionary::init(const class Coder* pCoder) 101 | { 102 | return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithCoder_), pCoder); 103 | } 104 | 105 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 106 | 107 | template 108 | _NS_INLINE NS::Enumerator<_KeyType>* NS::Dictionary::keyEnumerator() const 109 | { 110 | return Object::sendMessage*>(this, _NS_PRIVATE_SEL(keyEnumerator)); 111 | } 112 | 113 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 114 | 115 | template 116 | _NS_INLINE _Object* NS::Dictionary::object(const Object* pKey) const 117 | { 118 | return Object::sendMessage<_Object*>(this, _NS_PRIVATE_SEL(objectForKey_), pKey); 119 | } 120 | 121 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 122 | 123 | _NS_INLINE NS::UInteger NS::Dictionary::count() const 124 | { 125 | return Object::sendMessage(this, _NS_PRIVATE_SEL(count)); 126 | } 127 | 128 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 129 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSEnumerator.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSEnumerator.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSObject.hpp" 26 | #include "NSTypes.hpp" 27 | 28 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 29 | 30 | namespace NS 31 | { 32 | struct FastEnumerationState 33 | { 34 | unsigned long state; 35 | Object** itemsPtr; 36 | unsigned long* mutationsPtr; 37 | unsigned long extra[5]; 38 | } _NS_PACKED; 39 | 40 | class FastEnumeration : public Referencing 41 | { 42 | public: 43 | NS::UInteger countByEnumerating(FastEnumerationState* pState, Object** pBuffer, NS::UInteger len); 44 | }; 45 | 46 | template 47 | class Enumerator : public Referencing, FastEnumeration> 48 | { 49 | public: 50 | _ObjectType* nextObject(); 51 | class Array* allObjects(); 52 | }; 53 | } 54 | 55 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 56 | 57 | _NS_INLINE NS::UInteger NS::FastEnumeration::countByEnumerating(FastEnumerationState* pState, Object** pBuffer, NS::UInteger len) 58 | { 59 | return Object::sendMessage(this, _NS_PRIVATE_SEL(countByEnumeratingWithState_objects_count_), pState, pBuffer, len); 60 | } 61 | 62 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 63 | 64 | template 65 | _NS_INLINE _ObjectType* NS::Enumerator<_ObjectType>::nextObject() 66 | { 67 | return Object::sendMessage<_ObjectType*>(this, _NS_PRIVATE_SEL(nextObject)); 68 | } 69 | 70 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 71 | 72 | template 73 | _NS_INLINE NS::Array* NS::Enumerator<_ObjectType>::allObjects() 74 | { 75 | return Object::sendMessage(this, _NS_PRIVATE_SEL(allObjects)); 76 | } 77 | 78 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 79 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSLock.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSLock.hpp 4 | // 5 | // See LICENSE.txt for this project licensing information. 6 | // 7 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 8 | 9 | #pragma once 10 | 11 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 12 | 13 | #include "NSDefines.hpp" 14 | #include "NSObject.hpp" 15 | #include "NSPrivate.hpp" 16 | #include "NSTypes.hpp" 17 | #include "NSDate.hpp" 18 | 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | namespace NS 22 | { 23 | 24 | template 25 | class Locking : public _Base 26 | { 27 | public: 28 | void lock(); 29 | void unlock(); 30 | }; 31 | 32 | class Condition : public Locking 33 | { 34 | public: 35 | static Condition* alloc(); 36 | 37 | Condition* init(); 38 | 39 | void wait(); 40 | bool waitUntilDate(Date* pLimit); 41 | void signal(); 42 | void broadcast(); 43 | }; 44 | 45 | } // NS 46 | 47 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 48 | 49 | template 50 | _NS_INLINE void NS::Locking<_Class, _Base>::lock() 51 | { 52 | NS::Object::sendMessage(this, _NS_PRIVATE_SEL(lock)); 53 | } 54 | 55 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 56 | 57 | template 58 | _NS_INLINE void NS::Locking<_Class, _Base>::unlock() 59 | { 60 | NS::Object::sendMessage(this, _NS_PRIVATE_SEL(unlock)); 61 | } 62 | 63 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 64 | 65 | _NS_INLINE NS::Condition* NS::Condition::alloc() 66 | { 67 | return NS::Object::alloc(_NS_PRIVATE_CLS(NSCondition)); 68 | } 69 | 70 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 71 | 72 | _NS_INLINE NS::Condition* NS::Condition::init() 73 | { 74 | return NS::Object::init(); 75 | } 76 | 77 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 78 | 79 | _NS_INLINE void NS::Condition::wait() 80 | { 81 | NS::Object::sendMessage(this, _NS_PRIVATE_SEL(wait)); 82 | } 83 | 84 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 85 | 86 | _NS_INLINE bool NS::Condition::waitUntilDate(NS::Date* pLimit) 87 | { 88 | return NS::Object::sendMessage(this, _NS_PRIVATE_SEL(waitUntilDate_), pLimit); 89 | } 90 | 91 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 92 | 93 | _NS_INLINE void NS::Condition::signal() 94 | { 95 | NS::Object::sendMessage(this, _NS_PRIVATE_SEL(signal)); 96 | } 97 | 98 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 99 | 100 | _NS_INLINE void NS::Condition::broadcast() 101 | { 102 | NS::Object::sendMessage(this, _NS_PRIVATE_SEL(broadcast)); 103 | } 104 | 105 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSNotification.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSNotification.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSDefines.hpp" 26 | #include "NSDictionary.hpp" 27 | #include "NSObject.hpp" 28 | #include "NSString.hpp" 29 | #include "NSTypes.hpp" 30 | 31 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 32 | 33 | namespace NS 34 | { 35 | using NotificationName = class String*; 36 | 37 | class Notification : public NS::Referencing 38 | { 39 | public: 40 | NS::String* name() const; 41 | NS::Object* object() const; 42 | NS::Dictionary* userInfo() const; 43 | }; 44 | } 45 | 46 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 47 | 48 | _NS_INLINE NS::String* NS::Notification::name() const 49 | { 50 | return Object::sendMessage(this, _NS_PRIVATE_SEL(name)); 51 | } 52 | 53 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 54 | 55 | _NS_INLINE NS::Object* NS::Notification::object() const 56 | { 57 | return Object::sendMessage(this, _NS_PRIVATE_SEL(object)); 58 | } 59 | 60 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 61 | 62 | _NS_INLINE NS::Dictionary* NS::Notification::userInfo() const 63 | { 64 | return Object::sendMessage(this, _NS_PRIVATE_SEL(userInfo)); 65 | } 66 | 67 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 68 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSObjCRuntime.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSObjCRuntime.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSDefines.hpp" 26 | #include "NSTypes.hpp" 27 | 28 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 29 | 30 | namespace NS 31 | { 32 | 33 | _NS_ENUM(Integer, ComparisonResult) { 34 | OrderedAscending = -1, 35 | OrderedSame = 0, 36 | OrderedDescending = 1, 37 | }; 38 | 39 | const Integer NotFound = IntegerMax; 40 | 41 | } 42 | 43 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 44 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSRange.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSRange.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSDefines.hpp" 26 | #include "NSTypes.hpp" 27 | 28 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 29 | 30 | namespace NS 31 | { 32 | struct Range 33 | { 34 | static Range Make(UInteger loc, UInteger len); 35 | 36 | Range(UInteger loc, UInteger len); 37 | 38 | bool Equal(const Range& range) const; 39 | bool LocationInRange(UInteger loc) const; 40 | UInteger Max() const; 41 | 42 | UInteger location; 43 | UInteger length; 44 | } _NS_PACKED; 45 | } 46 | 47 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 48 | 49 | _NS_INLINE NS::Range::Range(UInteger loc, UInteger len) 50 | : location(loc) 51 | , length(len) 52 | { 53 | } 54 | 55 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 56 | 57 | _NS_INLINE NS::Range NS::Range::Make(UInteger loc, UInteger len) 58 | { 59 | return Range(loc, len); 60 | } 61 | 62 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 63 | 64 | _NS_INLINE bool NS::Range::Equal(const Range& range) const 65 | { 66 | return (location == range.location) && (length == range.length); 67 | } 68 | 69 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 70 | 71 | _NS_INLINE bool NS::Range::LocationInRange(UInteger loc) const 72 | { 73 | return (!(loc < location)) && ((loc - location) < length); 74 | } 75 | 76 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 77 | 78 | _NS_INLINE NS::UInteger NS::Range::Max() const 79 | { 80 | return location + length; 81 | } 82 | 83 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 84 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSTypes.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSTypes.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSDefines.hpp" 26 | 27 | #include 28 | #include 29 | 30 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 31 | 32 | namespace NS 33 | { 34 | using TimeInterval = double; 35 | 36 | using Integer = std::intptr_t; 37 | using UInteger = std::uintptr_t; 38 | 39 | const Integer IntegerMax = INTPTR_MAX; 40 | const Integer IntegerMin = INTPTR_MIN; 41 | const UInteger UIntegerMax = UINTPTR_MAX; 42 | 43 | struct OperatingSystemVersion 44 | { 45 | Integer majorVersion; 46 | Integer minorVersion; 47 | Integer patchVersion; 48 | } _NS_PACKED; 49 | } 50 | 51 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 52 | -------------------------------------------------------------------------------- /metal-cpp/Foundation/NSURL.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Foundation/NSURL.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "NSDefines.hpp" 26 | #include "NSObject.hpp" 27 | #include "NSPrivate.hpp" 28 | #include "NSTypes.hpp" 29 | 30 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 31 | 32 | namespace NS 33 | { 34 | class URL : public Copying 35 | { 36 | public: 37 | static URL* fileURLWithPath(const class String* pPath); 38 | 39 | static URL* alloc(); 40 | URL* init(); 41 | URL* init(const class String* pString); 42 | URL* initFileURLWithPath(const class String* pPath); 43 | 44 | const char* fileSystemRepresentation() const; 45 | }; 46 | } 47 | 48 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 49 | 50 | _NS_INLINE NS::URL* NS::URL::fileURLWithPath(const String* pPath) 51 | { 52 | return Object::sendMessage(_NS_PRIVATE_CLS(NSURL), _NS_PRIVATE_SEL(fileURLWithPath_), pPath); 53 | } 54 | 55 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 56 | 57 | _NS_INLINE NS::URL* NS::URL::alloc() 58 | { 59 | return Object::alloc(_NS_PRIVATE_CLS(NSURL)); 60 | } 61 | 62 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 63 | 64 | _NS_INLINE NS::URL* NS::URL::init() 65 | { 66 | return Object::init(); 67 | } 68 | 69 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 70 | 71 | _NS_INLINE NS::URL* NS::URL::init(const String* pString) 72 | { 73 | return Object::sendMessage(this, _NS_PRIVATE_SEL(initWithString_), pString); 74 | } 75 | 76 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 77 | 78 | _NS_INLINE NS::URL* NS::URL::initFileURLWithPath(const String* pPath) 79 | { 80 | return Object::sendMessage(this, _NS_PRIVATE_SEL(initFileURLWithPath_), pPath); 81 | } 82 | 83 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 84 | 85 | _NS_INLINE const char* NS::URL::fileSystemRepresentation() const 86 | { 87 | return Object::sendMessage(this, _NS_PRIVATE_SEL(fileSystemRepresentation)); 88 | } 89 | 90 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 91 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLAccelerationStructureTypes.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLAccelerationStructureTypes.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "MTLDefines.hpp" 26 | #include "MTLPrivate.hpp" 27 | #include "MTLResource.hpp" 28 | #include "MTLStageInputOutputDescriptor.hpp" 29 | 30 | #include "../Foundation/NSRange.hpp" 31 | 32 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 33 | 34 | namespace MTL 35 | { 36 | struct PackedFloat3 37 | { 38 | PackedFloat3(); 39 | PackedFloat3(float x, float y, float z); 40 | 41 | float& operator[](int idx); 42 | float operator[](int idx) const; 43 | 44 | union 45 | { 46 | struct 47 | { 48 | float x; 49 | float y; 50 | float z; 51 | }; 52 | 53 | float elements[3]; 54 | }; 55 | } _MTL_PACKED; 56 | 57 | struct PackedFloat4x3 58 | { 59 | PackedFloat4x3(); 60 | PackedFloat4x3(const PackedFloat3& col0, const PackedFloat3& col1, const PackedFloat3& col2, const PackedFloat3& col3); 61 | 62 | PackedFloat3& operator[](int idx); 63 | const PackedFloat3& operator[](int idx) const; 64 | 65 | PackedFloat3 columns[4]; 66 | } _MTL_PACKED; 67 | 68 | struct AxisAlignedBoundingBox 69 | { 70 | AxisAlignedBoundingBox(); 71 | AxisAlignedBoundingBox(PackedFloat3 p); 72 | AxisAlignedBoundingBox(PackedFloat3 min, PackedFloat3 max); 73 | 74 | PackedFloat3 min; 75 | PackedFloat3 max; 76 | } _MTL_PACKED; 77 | } 78 | 79 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 80 | 81 | _MTL_INLINE MTL::PackedFloat3::PackedFloat3() 82 | : x(0.0f) 83 | , y(0.0f) 84 | , z(0.0f) 85 | { 86 | } 87 | 88 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 89 | 90 | _MTL_INLINE MTL::PackedFloat3::PackedFloat3(float _x, float _y, float _z) 91 | : x(_x) 92 | , y(_y) 93 | , z(_z) 94 | { 95 | } 96 | 97 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 98 | 99 | _MTL_INLINE float& MTL::PackedFloat3::operator[](int idx) 100 | { 101 | return elements[idx]; 102 | } 103 | 104 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 105 | 106 | _MTL_INLINE float MTL::PackedFloat3::operator[](int idx) const 107 | { 108 | return elements[idx]; 109 | } 110 | 111 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 112 | 113 | _MTL_INLINE MTL::PackedFloat4x3::PackedFloat4x3() 114 | { 115 | columns[0] = PackedFloat3(0.0f, 0.0f, 0.0f); 116 | columns[1] = PackedFloat3(0.0f, 0.0f, 0.0f); 117 | columns[2] = PackedFloat3(0.0f, 0.0f, 0.0f); 118 | columns[3] = PackedFloat3(0.0f, 0.0f, 0.0f); 119 | } 120 | 121 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 122 | 123 | _MTL_INLINE MTL::PackedFloat4x3::PackedFloat4x3(const PackedFloat3& col0, const PackedFloat3& col1, const PackedFloat3& col2, const PackedFloat3& col3) 124 | { 125 | columns[0] = col0; 126 | columns[1] = col1; 127 | columns[2] = col2; 128 | columns[3] = col3; 129 | } 130 | 131 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 132 | 133 | _MTL_INLINE MTL::PackedFloat3& MTL::PackedFloat4x3::operator[](int idx) 134 | { 135 | return columns[idx]; 136 | } 137 | 138 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 139 | 140 | _MTL_INLINE const MTL::PackedFloat3& MTL::PackedFloat4x3::operator[](int idx) const 141 | { 142 | return columns[idx]; 143 | } 144 | 145 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 146 | 147 | _MTL_INLINE MTL::AxisAlignedBoundingBox::AxisAlignedBoundingBox() 148 | : min(INFINITY, INFINITY, INFINITY) 149 | , max(-INFINITY, -INFINITY, -INFINITY) 150 | { 151 | } 152 | 153 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 154 | 155 | _MTL_INLINE MTL::AxisAlignedBoundingBox::AxisAlignedBoundingBox(PackedFloat3 p) 156 | : min(p) 157 | , max(p) 158 | { 159 | } 160 | 161 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 162 | 163 | _MTL_INLINE MTL::AxisAlignedBoundingBox::AxisAlignedBoundingBox(PackedFloat3 _min, PackedFloat3 _max) 164 | : min(_min) 165 | , max(_max) 166 | { 167 | } 168 | 169 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 170 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLBinaryArchive.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLBinaryArchive.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | _MTL_ENUM(NS::UInteger, BinaryArchiveError) { 32 | BinaryArchiveErrorNone = 0, 33 | BinaryArchiveErrorInvalidFile = 1, 34 | BinaryArchiveErrorUnexpectedElement = 2, 35 | BinaryArchiveErrorCompilationFailure = 3, 36 | }; 37 | 38 | class BinaryArchiveDescriptor : public NS::Copying 39 | { 40 | public: 41 | static class BinaryArchiveDescriptor* alloc(); 42 | 43 | class BinaryArchiveDescriptor* init(); 44 | 45 | NS::URL* url() const; 46 | void setUrl(const NS::URL* url); 47 | }; 48 | 49 | class BinaryArchive : public NS::Referencing 50 | { 51 | public: 52 | NS::String* label() const; 53 | void setLabel(const NS::String* label); 54 | 55 | class Device* device() const; 56 | 57 | bool addComputePipelineFunctions(const class ComputePipelineDescriptor* descriptor, NS::Error** error); 58 | 59 | bool addRenderPipelineFunctions(const class RenderPipelineDescriptor* descriptor, NS::Error** error); 60 | 61 | bool addTileRenderPipelineFunctions(const class TileRenderPipelineDescriptor* descriptor, NS::Error** error); 62 | 63 | bool serializeToURL(const NS::URL* url, NS::Error** error); 64 | 65 | bool addFunction(const class FunctionDescriptor* descriptor, const class Library* library, NS::Error** error); 66 | }; 67 | 68 | } 69 | 70 | // static method: alloc 71 | _MTL_INLINE MTL::BinaryArchiveDescriptor* MTL::BinaryArchiveDescriptor::alloc() 72 | { 73 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLBinaryArchiveDescriptor)); 74 | } 75 | 76 | // method: init 77 | _MTL_INLINE MTL::BinaryArchiveDescriptor* MTL::BinaryArchiveDescriptor::init() 78 | { 79 | return NS::Object::init(); 80 | } 81 | 82 | // property: url 83 | _MTL_INLINE NS::URL* MTL::BinaryArchiveDescriptor::url() const 84 | { 85 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(url)); 86 | } 87 | 88 | _MTL_INLINE void MTL::BinaryArchiveDescriptor::setUrl(const NS::URL* url) 89 | { 90 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setUrl_), url); 91 | } 92 | 93 | // property: label 94 | _MTL_INLINE NS::String* MTL::BinaryArchive::label() const 95 | { 96 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 97 | } 98 | 99 | _MTL_INLINE void MTL::BinaryArchive::setLabel(const NS::String* label) 100 | { 101 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 102 | } 103 | 104 | // property: device 105 | _MTL_INLINE MTL::Device* MTL::BinaryArchive::device() const 106 | { 107 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 108 | } 109 | 110 | // method: addComputePipelineFunctionsWithDescriptor:error: 111 | _MTL_INLINE bool MTL::BinaryArchive::addComputePipelineFunctions(const MTL::ComputePipelineDescriptor* descriptor, NS::Error** error) 112 | { 113 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(addComputePipelineFunctionsWithDescriptor_error_), descriptor, error); 114 | } 115 | 116 | // method: addRenderPipelineFunctionsWithDescriptor:error: 117 | _MTL_INLINE bool MTL::BinaryArchive::addRenderPipelineFunctions(const MTL::RenderPipelineDescriptor* descriptor, NS::Error** error) 118 | { 119 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(addRenderPipelineFunctionsWithDescriptor_error_), descriptor, error); 120 | } 121 | 122 | // method: addTileRenderPipelineFunctionsWithDescriptor:error: 123 | _MTL_INLINE bool MTL::BinaryArchive::addTileRenderPipelineFunctions(const MTL::TileRenderPipelineDescriptor* descriptor, NS::Error** error) 124 | { 125 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(addTileRenderPipelineFunctionsWithDescriptor_error_), descriptor, error); 126 | } 127 | 128 | // method: serializeToURL:error: 129 | _MTL_INLINE bool MTL::BinaryArchive::serializeToURL(const NS::URL* url, NS::Error** error) 130 | { 131 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(serializeToURL_error_), url, error); 132 | } 133 | 134 | // method: addFunctionWithDescriptor:library:error: 135 | _MTL_INLINE bool MTL::BinaryArchive::addFunction(const MTL::FunctionDescriptor* descriptor, const MTL::Library* library, NS::Error** error) 136 | { 137 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(addFunctionWithDescriptor_library_error_), descriptor, library, error); 138 | } 139 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLBuffer.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLBuffer.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLResource.hpp" 30 | 31 | namespace MTL 32 | { 33 | class Buffer : public NS::Referencing 34 | { 35 | public: 36 | NS::UInteger length() const; 37 | 38 | void* contents(); 39 | 40 | void didModifyRange(NS::Range range); 41 | 42 | class Texture* newTexture(const class TextureDescriptor* descriptor, NS::UInteger offset, NS::UInteger bytesPerRow); 43 | 44 | void addDebugMarker(const NS::String* marker, NS::Range range); 45 | 46 | void removeAllDebugMarkers(); 47 | 48 | class Buffer* remoteStorageBuffer() const; 49 | 50 | class Buffer* newRemoteBufferViewForDevice(const class Device* device); 51 | }; 52 | 53 | } 54 | 55 | // property: length 56 | _MTL_INLINE NS::UInteger MTL::Buffer::length() const 57 | { 58 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(length)); 59 | } 60 | 61 | // method: contents 62 | _MTL_INLINE void* MTL::Buffer::contents() 63 | { 64 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(contents)); 65 | } 66 | 67 | // method: didModifyRange: 68 | _MTL_INLINE void MTL::Buffer::didModifyRange(NS::Range range) 69 | { 70 | Object::sendMessage(this, _MTL_PRIVATE_SEL(didModifyRange_), range); 71 | } 72 | 73 | // method: newTextureWithDescriptor:offset:bytesPerRow: 74 | _MTL_INLINE MTL::Texture* MTL::Buffer::newTexture(const MTL::TextureDescriptor* descriptor, NS::UInteger offset, NS::UInteger bytesPerRow) 75 | { 76 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(newTextureWithDescriptor_offset_bytesPerRow_), descriptor, offset, bytesPerRow); 77 | } 78 | 79 | // method: addDebugMarker:range: 80 | _MTL_INLINE void MTL::Buffer::addDebugMarker(const NS::String* marker, NS::Range range) 81 | { 82 | Object::sendMessage(this, _MTL_PRIVATE_SEL(addDebugMarker_range_), marker, range); 83 | } 84 | 85 | // method: removeAllDebugMarkers 86 | _MTL_INLINE void MTL::Buffer::removeAllDebugMarkers() 87 | { 88 | Object::sendMessage(this, _MTL_PRIVATE_SEL(removeAllDebugMarkers)); 89 | } 90 | 91 | // property: remoteStorageBuffer 92 | _MTL_INLINE MTL::Buffer* MTL::Buffer::remoteStorageBuffer() const 93 | { 94 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(remoteStorageBuffer)); 95 | } 96 | 97 | // method: newRemoteBufferViewForDevice: 98 | _MTL_INLINE MTL::Buffer* MTL::Buffer::newRemoteBufferViewForDevice(const MTL::Device* device) 99 | { 100 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(newRemoteBufferViewForDevice_), device); 101 | } 102 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLCaptureScope.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLCaptureScope.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "MTLDefines.hpp" 26 | #include "MTLPrivate.hpp" 27 | 28 | #include "../Foundation/NSObject.hpp" 29 | #include "../Foundation/NSString.hpp" 30 | 31 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 32 | 33 | namespace MTL 34 | { 35 | class CaptureScope : public NS::Referencing 36 | { 37 | public: 38 | class Device* device() const; 39 | 40 | NS::String* label() const; 41 | void setLabel(const NS::String* pLabel); 42 | 43 | class CommandQueue* commandQueue() const; 44 | 45 | void beginScope(); 46 | void endScope(); 47 | }; 48 | } 49 | 50 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 51 | 52 | _MTL_INLINE MTL::Device* MTL::CaptureScope::device() const 53 | { 54 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 55 | } 56 | 57 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 58 | 59 | _MTL_INLINE NS::String* MTL::CaptureScope::label() const 60 | { 61 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 62 | } 63 | 64 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 65 | 66 | _MTL_INLINE void MTL::CaptureScope::setLabel(const NS::String* pLabel) 67 | { 68 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), pLabel); 69 | } 70 | 71 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 72 | 73 | _MTL_INLINE MTL::CommandQueue* MTL::CaptureScope::commandQueue() const 74 | { 75 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(commandQueue)); 76 | } 77 | 78 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 79 | 80 | _MTL_INLINE void MTL::CaptureScope::beginScope() 81 | { 82 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(beginScope)); 83 | } 84 | 85 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 86 | 87 | _MTL_INLINE void MTL::CaptureScope::endScope() 88 | { 89 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(endScope)); 90 | } 91 | 92 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 93 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLCommandEncoder.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLCommandEncoder.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | _MTL_OPTIONS(NS::UInteger, ResourceUsage) { 32 | ResourceUsageRead = 1, 33 | ResourceUsageWrite = 2, 34 | ResourceUsageSample = 4, 35 | }; 36 | 37 | _MTL_OPTIONS(NS::UInteger, BarrierScope) { 38 | BarrierScopeBuffers = 1, 39 | BarrierScopeTextures = 2, 40 | BarrierScopeRenderTargets = 4, 41 | }; 42 | 43 | class CommandEncoder : public NS::Referencing 44 | { 45 | public: 46 | class Device* device() const; 47 | 48 | NS::String* label() const; 49 | void setLabel(const NS::String* label); 50 | 51 | void endEncoding(); 52 | 53 | void insertDebugSignpost(const NS::String* string); 54 | 55 | void pushDebugGroup(const NS::String* string); 56 | 57 | void popDebugGroup(); 58 | }; 59 | 60 | } 61 | 62 | // property: device 63 | _MTL_INLINE MTL::Device* MTL::CommandEncoder::device() const 64 | { 65 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 66 | } 67 | 68 | // property: label 69 | _MTL_INLINE NS::String* MTL::CommandEncoder::label() const 70 | { 71 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 72 | } 73 | 74 | _MTL_INLINE void MTL::CommandEncoder::setLabel(const NS::String* label) 75 | { 76 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 77 | } 78 | 79 | // method: endEncoding 80 | _MTL_INLINE void MTL::CommandEncoder::endEncoding() 81 | { 82 | Object::sendMessage(this, _MTL_PRIVATE_SEL(endEncoding)); 83 | } 84 | 85 | // method: insertDebugSignpost: 86 | _MTL_INLINE void MTL::CommandEncoder::insertDebugSignpost(const NS::String* string) 87 | { 88 | Object::sendMessage(this, _MTL_PRIVATE_SEL(insertDebugSignpost_), string); 89 | } 90 | 91 | // method: pushDebugGroup: 92 | _MTL_INLINE void MTL::CommandEncoder::pushDebugGroup(const NS::String* string) 93 | { 94 | Object::sendMessage(this, _MTL_PRIVATE_SEL(pushDebugGroup_), string); 95 | } 96 | 97 | // method: popDebugGroup 98 | _MTL_INLINE void MTL::CommandEncoder::popDebugGroup() 99 | { 100 | Object::sendMessage(this, _MTL_PRIVATE_SEL(popDebugGroup)); 101 | } 102 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLCommandQueue.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLCommandQueue.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | class CommandQueue : public NS::Referencing 32 | { 33 | public: 34 | NS::String* label() const; 35 | void setLabel(const NS::String* label); 36 | 37 | class Device* device() const; 38 | 39 | class CommandBuffer* commandBuffer(); 40 | 41 | class CommandBuffer* commandBuffer(const class CommandBufferDescriptor* descriptor); 42 | 43 | class CommandBuffer* commandBufferWithUnretainedReferences(); 44 | 45 | void insertDebugCaptureBoundary(); 46 | }; 47 | 48 | } 49 | 50 | // property: label 51 | _MTL_INLINE NS::String* MTL::CommandQueue::label() const 52 | { 53 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 54 | } 55 | 56 | _MTL_INLINE void MTL::CommandQueue::setLabel(const NS::String* label) 57 | { 58 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 59 | } 60 | 61 | // property: device 62 | _MTL_INLINE MTL::Device* MTL::CommandQueue::device() const 63 | { 64 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 65 | } 66 | 67 | // method: commandBuffer 68 | _MTL_INLINE MTL::CommandBuffer* MTL::CommandQueue::commandBuffer() 69 | { 70 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(commandBuffer)); 71 | } 72 | 73 | // method: commandBufferWithDescriptor: 74 | _MTL_INLINE MTL::CommandBuffer* MTL::CommandQueue::commandBuffer(const MTL::CommandBufferDescriptor* descriptor) 75 | { 76 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(commandBufferWithDescriptor_), descriptor); 77 | } 78 | 79 | // method: commandBufferWithUnretainedReferences 80 | _MTL_INLINE MTL::CommandBuffer* MTL::CommandQueue::commandBufferWithUnretainedReferences() 81 | { 82 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(commandBufferWithUnretainedReferences)); 83 | } 84 | 85 | // method: insertDebugCaptureBoundary 86 | _MTL_INLINE void MTL::CommandQueue::insertDebugCaptureBoundary() 87 | { 88 | Object::sendMessage(this, _MTL_PRIVATE_SEL(insertDebugCaptureBoundary)); 89 | } 90 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLDefines.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLDefines.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "../Foundation/NSDefines.hpp" 26 | 27 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 28 | 29 | #define _MTL_EXPORT _NS_EXPORT 30 | #define _MTL_EXTERN _NS_EXTERN 31 | #define _MTL_INLINE _NS_INLINE 32 | #define _MTL_PACKED _NS_PACKED 33 | 34 | #define _MTL_CONST(type, name) _NS_CONST(type, name) 35 | #define _MTL_ENUM(type, name) _NS_ENUM(type, name) 36 | #define _MTL_OPTIONS(type, name) _NS_OPTIONS(type, name) 37 | 38 | #define _MTL_VALIDATE_SIZE(ns, name) _NS_VALIDATE_SIZE(ns, name) 39 | #define _MTL_VALIDATE_ENUM(ns, name) _NS_VALIDATE_ENUM(ns, name) 40 | 41 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 42 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLDrawable.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLDrawable.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | namespace MTL 33 | { 34 | using DrawablePresentedHandler = void (^)(class Drawable*); 35 | 36 | using DrawablePresentedHandlerFunction = std::function; 37 | 38 | class Drawable : public NS::Referencing 39 | { 40 | public: 41 | void addPresentedHandler(const MTL::DrawablePresentedHandlerFunction& function); 42 | 43 | void present(); 44 | 45 | void presentAtTime(CFTimeInterval presentationTime); 46 | 47 | void presentAfterMinimumDuration(CFTimeInterval duration); 48 | 49 | void addPresentedHandler(const MTL::DrawablePresentedHandler block); 50 | 51 | CFTimeInterval presentedTime() const; 52 | 53 | NS::UInteger drawableID() const; 54 | }; 55 | 56 | } 57 | 58 | _MTL_INLINE void MTL::Drawable::addPresentedHandler(const MTL::DrawablePresentedHandlerFunction& function) 59 | { 60 | __block DrawablePresentedHandlerFunction blockFunction = function; 61 | 62 | addPresentedHandler(^(Drawable* pDrawable) { blockFunction(pDrawable); }); 63 | } 64 | 65 | // method: present 66 | _MTL_INLINE void MTL::Drawable::present() 67 | { 68 | Object::sendMessage(this, _MTL_PRIVATE_SEL(present)); 69 | } 70 | 71 | // method: presentAtTime: 72 | _MTL_INLINE void MTL::Drawable::presentAtTime(CFTimeInterval presentationTime) 73 | { 74 | Object::sendMessage(this, _MTL_PRIVATE_SEL(presentAtTime_), presentationTime); 75 | } 76 | 77 | // method: presentAfterMinimumDuration: 78 | _MTL_INLINE void MTL::Drawable::presentAfterMinimumDuration(CFTimeInterval duration) 79 | { 80 | Object::sendMessage(this, _MTL_PRIVATE_SEL(presentAfterMinimumDuration_), duration); 81 | } 82 | 83 | // method: addPresentedHandler: 84 | _MTL_INLINE void MTL::Drawable::addPresentedHandler(const MTL::DrawablePresentedHandler block) 85 | { 86 | Object::sendMessage(this, _MTL_PRIVATE_SEL(addPresentedHandler_), block); 87 | } 88 | 89 | // property: presentedTime 90 | _MTL_INLINE CFTimeInterval MTL::Drawable::presentedTime() const 91 | { 92 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(presentedTime)); 93 | } 94 | 95 | // property: drawableID 96 | _MTL_INLINE NS::UInteger MTL::Drawable::drawableID() const 97 | { 98 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(drawableID)); 99 | } 100 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLDynamicLibrary.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLDynamicLibrary.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | _MTL_ENUM(NS::UInteger, DynamicLibraryError) { 32 | DynamicLibraryErrorNone = 0, 33 | DynamicLibraryErrorInvalidFile = 1, 34 | DynamicLibraryErrorCompilationFailure = 2, 35 | DynamicLibraryErrorUnresolvedInstallName = 3, 36 | DynamicLibraryErrorDependencyLoadFailure = 4, 37 | DynamicLibraryErrorUnsupported = 5, 38 | }; 39 | 40 | class DynamicLibrary : public NS::Referencing 41 | { 42 | public: 43 | NS::String* label() const; 44 | void setLabel(const NS::String* label); 45 | 46 | class Device* device() const; 47 | 48 | NS::String* installName() const; 49 | 50 | bool serializeToURL(const NS::URL* url, NS::Error** error); 51 | }; 52 | 53 | } 54 | 55 | // property: label 56 | _MTL_INLINE NS::String* MTL::DynamicLibrary::label() const 57 | { 58 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 59 | } 60 | 61 | _MTL_INLINE void MTL::DynamicLibrary::setLabel(const NS::String* label) 62 | { 63 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 64 | } 65 | 66 | // property: device 67 | _MTL_INLINE MTL::Device* MTL::DynamicLibrary::device() const 68 | { 69 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 70 | } 71 | 72 | // property: installName 73 | _MTL_INLINE NS::String* MTL::DynamicLibrary::installName() const 74 | { 75 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(installName)); 76 | } 77 | 78 | // method: serializeToURL:error: 79 | _MTL_INLINE bool MTL::DynamicLibrary::serializeToURL(const NS::URL* url, NS::Error** error) 80 | { 81 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(serializeToURL_error_), url, error); 82 | } 83 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLEvent.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLEvent.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLEvent.hpp" 30 | 31 | namespace MTL 32 | { 33 | class Event : public NS::Referencing 34 | { 35 | public: 36 | class Device* device() const; 37 | 38 | NS::String* label() const; 39 | void setLabel(const NS::String* label); 40 | }; 41 | 42 | class SharedEventListener : public NS::Referencing 43 | { 44 | public: 45 | static class SharedEventListener* alloc(); 46 | 47 | MTL::SharedEventListener* init(); 48 | 49 | MTL::SharedEventListener* init(const dispatch_queue_t dispatchQueue); 50 | 51 | dispatch_queue_t dispatchQueue() const; 52 | }; 53 | 54 | using SharedEventNotificationBlock = void (^)(SharedEvent* pEvent, std::uint64_t value); 55 | 56 | class SharedEvent : public NS::Referencing 57 | { 58 | public: 59 | void notifyListener(const class SharedEventListener* listener, uint64_t value, const MTL::SharedEventNotificationBlock block); 60 | 61 | class SharedEventHandle* newSharedEventHandle(); 62 | 63 | uint64_t signaledValue() const; 64 | void setSignaledValue(uint64_t signaledValue); 65 | }; 66 | 67 | class SharedEventHandle : public NS::Referencing 68 | { 69 | public: 70 | static class SharedEventHandle* alloc(); 71 | 72 | class SharedEventHandle* init(); 73 | 74 | NS::String* label() const; 75 | }; 76 | 77 | struct SharedEventHandlePrivate 78 | { 79 | } _MTL_PACKED; 80 | 81 | } 82 | 83 | // property: device 84 | _MTL_INLINE MTL::Device* MTL::Event::device() const 85 | { 86 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 87 | } 88 | 89 | // property: label 90 | _MTL_INLINE NS::String* MTL::Event::label() const 91 | { 92 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 93 | } 94 | 95 | _MTL_INLINE void MTL::Event::setLabel(const NS::String* label) 96 | { 97 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 98 | } 99 | 100 | // static method: alloc 101 | _MTL_INLINE MTL::SharedEventListener* MTL::SharedEventListener::alloc() 102 | { 103 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLSharedEventListener)); 104 | } 105 | 106 | // method: init 107 | _MTL_INLINE MTL::SharedEventListener* MTL::SharedEventListener::init() 108 | { 109 | return NS::Object::init(); 110 | } 111 | 112 | // method: initWithDispatchQueue: 113 | _MTL_INLINE MTL::SharedEventListener* MTL::SharedEventListener::init(const dispatch_queue_t dispatchQueue) 114 | { 115 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(initWithDispatchQueue_), dispatchQueue); 116 | } 117 | 118 | // property: dispatchQueue 119 | _MTL_INLINE dispatch_queue_t MTL::SharedEventListener::dispatchQueue() const 120 | { 121 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(dispatchQueue)); 122 | } 123 | 124 | // method: notifyListener:atValue:block: 125 | _MTL_INLINE void MTL::SharedEvent::notifyListener(const MTL::SharedEventListener* listener, uint64_t value, const MTL::SharedEventNotificationBlock block) 126 | { 127 | Object::sendMessage(this, _MTL_PRIVATE_SEL(notifyListener_atValue_block_), listener, value, block); 128 | } 129 | 130 | // method: newSharedEventHandle 131 | _MTL_INLINE MTL::SharedEventHandle* MTL::SharedEvent::newSharedEventHandle() 132 | { 133 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(newSharedEventHandle)); 134 | } 135 | 136 | // property: signaledValue 137 | _MTL_INLINE uint64_t MTL::SharedEvent::signaledValue() const 138 | { 139 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(signaledValue)); 140 | } 141 | 142 | _MTL_INLINE void MTL::SharedEvent::setSignaledValue(uint64_t signaledValue) 143 | { 144 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setSignaledValue_), signaledValue); 145 | } 146 | 147 | // static method: alloc 148 | _MTL_INLINE MTL::SharedEventHandle* MTL::SharedEventHandle::alloc() 149 | { 150 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLSharedEventHandle)); 151 | } 152 | 153 | // method: init 154 | _MTL_INLINE MTL::SharedEventHandle* MTL::SharedEventHandle::init() 155 | { 156 | return NS::Object::init(); 157 | } 158 | 159 | // property: label 160 | _MTL_INLINE NS::String* MTL::SharedEventHandle::label() const 161 | { 162 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 163 | } 164 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLFence.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLFence.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | class Fence : public NS::Referencing 32 | { 33 | public: 34 | class Device* device() const; 35 | 36 | NS::String* label() const; 37 | void setLabel(const NS::String* label); 38 | }; 39 | 40 | } 41 | 42 | // property: device 43 | _MTL_INLINE MTL::Device* MTL::Fence::device() const 44 | { 45 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 46 | } 47 | 48 | // property: label 49 | _MTL_INLINE NS::String* MTL::Fence::label() const 50 | { 51 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 52 | } 53 | 54 | _MTL_INLINE void MTL::Fence::setLabel(const NS::String* label) 55 | { 56 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 57 | } 58 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLFunctionConstantValues.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLFunctionConstantValues.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLArgument.hpp" 30 | 31 | namespace MTL 32 | { 33 | class FunctionConstantValues : public NS::Copying 34 | { 35 | public: 36 | static class FunctionConstantValues* alloc(); 37 | 38 | class FunctionConstantValues* init(); 39 | 40 | void setConstantValue(const void* value, MTL::DataType type, NS::UInteger index); 41 | 42 | void setConstantValues(const void* values, MTL::DataType type, NS::Range range); 43 | 44 | void setConstantValue(const void* value, MTL::DataType type, const NS::String* name); 45 | 46 | void reset(); 47 | }; 48 | 49 | } 50 | 51 | // static method: alloc 52 | _MTL_INLINE MTL::FunctionConstantValues* MTL::FunctionConstantValues::alloc() 53 | { 54 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLFunctionConstantValues)); 55 | } 56 | 57 | // method: init 58 | _MTL_INLINE MTL::FunctionConstantValues* MTL::FunctionConstantValues::init() 59 | { 60 | return NS::Object::init(); 61 | } 62 | 63 | // method: setConstantValue:type:atIndex: 64 | _MTL_INLINE void MTL::FunctionConstantValues::setConstantValue(const void* value, MTL::DataType type, NS::UInteger index) 65 | { 66 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setConstantValue_type_atIndex_), value, type, index); 67 | } 68 | 69 | // method: setConstantValues:type:withRange: 70 | _MTL_INLINE void MTL::FunctionConstantValues::setConstantValues(const void* values, MTL::DataType type, NS::Range range) 71 | { 72 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setConstantValues_type_withRange_), values, type, range); 73 | } 74 | 75 | // method: setConstantValue:type:withName: 76 | _MTL_INLINE void MTL::FunctionConstantValues::setConstantValue(const void* value, MTL::DataType type, const NS::String* name) 77 | { 78 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setConstantValue_type_withName_), value, type, name); 79 | } 80 | 81 | // method: reset 82 | _MTL_INLINE void MTL::FunctionConstantValues::reset() 83 | { 84 | Object::sendMessage(this, _MTL_PRIVATE_SEL(reset)); 85 | } 86 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLFunctionDescriptor.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLFunctionDescriptor.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLFunctionDescriptor.hpp" 30 | 31 | namespace MTL 32 | { 33 | _MTL_OPTIONS(NS::UInteger, FunctionOptions) { 34 | FunctionOptionNone = 0, 35 | FunctionOptionCompileToBinary = 1, 36 | }; 37 | 38 | class FunctionDescriptor : public NS::Copying 39 | { 40 | public: 41 | static class FunctionDescriptor* alloc(); 42 | 43 | class FunctionDescriptor* init(); 44 | 45 | static class FunctionDescriptor* functionDescriptor(); 46 | 47 | NS::String* name() const; 48 | void setName(const NS::String* name); 49 | 50 | NS::String* specializedName() const; 51 | void setSpecializedName(const NS::String* specializedName); 52 | 53 | class FunctionConstantValues* constantValues() const; 54 | void setConstantValues(const class FunctionConstantValues* constantValues); 55 | 56 | MTL::FunctionOptions options() const; 57 | void setOptions(MTL::FunctionOptions options); 58 | 59 | NS::Array* binaryArchives() const; 60 | void setBinaryArchives(const NS::Array* binaryArchives); 61 | }; 62 | 63 | class IntersectionFunctionDescriptor : public NS::Copying 64 | { 65 | public: 66 | static class IntersectionFunctionDescriptor* alloc(); 67 | 68 | class IntersectionFunctionDescriptor* init(); 69 | }; 70 | 71 | } 72 | 73 | // static method: alloc 74 | _MTL_INLINE MTL::FunctionDescriptor* MTL::FunctionDescriptor::alloc() 75 | { 76 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLFunctionDescriptor)); 77 | } 78 | 79 | // method: init 80 | _MTL_INLINE MTL::FunctionDescriptor* MTL::FunctionDescriptor::init() 81 | { 82 | return NS::Object::init(); 83 | } 84 | 85 | // static method: functionDescriptor 86 | _MTL_INLINE MTL::FunctionDescriptor* MTL::FunctionDescriptor::functionDescriptor() 87 | { 88 | return Object::sendMessage(_MTL_PRIVATE_CLS(MTLFunctionDescriptor), _MTL_PRIVATE_SEL(functionDescriptor)); 89 | } 90 | 91 | // property: name 92 | _MTL_INLINE NS::String* MTL::FunctionDescriptor::name() const 93 | { 94 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(name)); 95 | } 96 | 97 | _MTL_INLINE void MTL::FunctionDescriptor::setName(const NS::String* name) 98 | { 99 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setName_), name); 100 | } 101 | 102 | // property: specializedName 103 | _MTL_INLINE NS::String* MTL::FunctionDescriptor::specializedName() const 104 | { 105 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(specializedName)); 106 | } 107 | 108 | _MTL_INLINE void MTL::FunctionDescriptor::setSpecializedName(const NS::String* specializedName) 109 | { 110 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setSpecializedName_), specializedName); 111 | } 112 | 113 | // property: constantValues 114 | _MTL_INLINE MTL::FunctionConstantValues* MTL::FunctionDescriptor::constantValues() const 115 | { 116 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(constantValues)); 117 | } 118 | 119 | _MTL_INLINE void MTL::FunctionDescriptor::setConstantValues(const MTL::FunctionConstantValues* constantValues) 120 | { 121 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setConstantValues_), constantValues); 122 | } 123 | 124 | // property: options 125 | _MTL_INLINE MTL::FunctionOptions MTL::FunctionDescriptor::options() const 126 | { 127 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(options)); 128 | } 129 | 130 | _MTL_INLINE void MTL::FunctionDescriptor::setOptions(MTL::FunctionOptions options) 131 | { 132 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setOptions_), options); 133 | } 134 | 135 | // property: binaryArchives 136 | _MTL_INLINE NS::Array* MTL::FunctionDescriptor::binaryArchives() const 137 | { 138 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(binaryArchives)); 139 | } 140 | 141 | _MTL_INLINE void MTL::FunctionDescriptor::setBinaryArchives(const NS::Array* binaryArchives) 142 | { 143 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setBinaryArchives_), binaryArchives); 144 | } 145 | 146 | // static method: alloc 147 | _MTL_INLINE MTL::IntersectionFunctionDescriptor* MTL::IntersectionFunctionDescriptor::alloc() 148 | { 149 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLIntersectionFunctionDescriptor)); 150 | } 151 | 152 | // method: init 153 | _MTL_INLINE MTL::IntersectionFunctionDescriptor* MTL::IntersectionFunctionDescriptor::init() 154 | { 155 | return NS::Object::init(); 156 | } 157 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLFunctionHandle.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLFunctionHandle.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLLibrary.hpp" 30 | 31 | namespace MTL 32 | { 33 | class FunctionHandle : public NS::Referencing 34 | { 35 | public: 36 | MTL::FunctionType functionType() const; 37 | 38 | NS::String* name() const; 39 | 40 | class Device* device() const; 41 | }; 42 | 43 | } 44 | 45 | // property: functionType 46 | _MTL_INLINE MTL::FunctionType MTL::FunctionHandle::functionType() const 47 | { 48 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(functionType)); 49 | } 50 | 51 | // property: name 52 | _MTL_INLINE NS::String* MTL::FunctionHandle::name() const 53 | { 54 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(name)); 55 | } 56 | 57 | // property: device 58 | _MTL_INLINE MTL::Device* MTL::FunctionHandle::device() const 59 | { 60 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 61 | } 62 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLFunctionLog.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLFunctionLog.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLFunctionLog.hpp" 30 | 31 | namespace MTL 32 | { 33 | _MTL_ENUM(NS::UInteger, FunctionLogType) { 34 | FunctionLogTypeValidation = 0, 35 | }; 36 | 37 | class LogContainer : public NS::Referencing 38 | { 39 | public: 40 | }; 41 | 42 | class FunctionLogDebugLocation : public NS::Referencing 43 | { 44 | public: 45 | NS::String* functionName() const; 46 | 47 | NS::URL* URL() const; 48 | 49 | NS::UInteger line() const; 50 | 51 | NS::UInteger column() const; 52 | }; 53 | 54 | class FunctionLog : public NS::Referencing 55 | { 56 | public: 57 | MTL::FunctionLogType type() const; 58 | 59 | NS::String* encoderLabel() const; 60 | 61 | class Function* function() const; 62 | 63 | class FunctionLogDebugLocation* debugLocation() const; 64 | }; 65 | 66 | } 67 | 68 | // property: functionName 69 | _MTL_INLINE NS::String* MTL::FunctionLogDebugLocation::functionName() const 70 | { 71 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(functionName)); 72 | } 73 | 74 | // property: URL 75 | _MTL_INLINE NS::URL* MTL::FunctionLogDebugLocation::URL() const 76 | { 77 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(URL)); 78 | } 79 | 80 | // property: line 81 | _MTL_INLINE NS::UInteger MTL::FunctionLogDebugLocation::line() const 82 | { 83 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(line)); 84 | } 85 | 86 | // property: column 87 | _MTL_INLINE NS::UInteger MTL::FunctionLogDebugLocation::column() const 88 | { 89 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(column)); 90 | } 91 | 92 | // property: type 93 | _MTL_INLINE MTL::FunctionLogType MTL::FunctionLog::type() const 94 | { 95 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(type)); 96 | } 97 | 98 | // property: encoderLabel 99 | _MTL_INLINE NS::String* MTL::FunctionLog::encoderLabel() const 100 | { 101 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(encoderLabel)); 102 | } 103 | 104 | // property: function 105 | _MTL_INLINE MTL::Function* MTL::FunctionLog::function() const 106 | { 107 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(function)); 108 | } 109 | 110 | // property: debugLocation 111 | _MTL_INLINE MTL::FunctionLogDebugLocation* MTL::FunctionLog::debugLocation() const 112 | { 113 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(debugLocation)); 114 | } 115 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLLinkedFunctions.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLLinkedFunctions.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | class LinkedFunctions : public NS::Copying 32 | { 33 | public: 34 | static class LinkedFunctions* alloc(); 35 | 36 | class LinkedFunctions* init(); 37 | 38 | static class LinkedFunctions* linkedFunctions(); 39 | 40 | NS::Array* functions() const; 41 | void setFunctions(const NS::Array* functions); 42 | 43 | NS::Array* binaryFunctions() const; 44 | void setBinaryFunctions(const NS::Array* binaryFunctions); 45 | 46 | NS::Array* groups() const; 47 | void setGroups(const NS::Array* groups); 48 | 49 | NS::Array* privateFunctions() const; 50 | void setPrivateFunctions(const NS::Array* privateFunctions); 51 | }; 52 | 53 | } 54 | 55 | // static method: alloc 56 | _MTL_INLINE MTL::LinkedFunctions* MTL::LinkedFunctions::alloc() 57 | { 58 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLLinkedFunctions)); 59 | } 60 | 61 | // method: init 62 | _MTL_INLINE MTL::LinkedFunctions* MTL::LinkedFunctions::init() 63 | { 64 | return NS::Object::init(); 65 | } 66 | 67 | // static method: linkedFunctions 68 | _MTL_INLINE MTL::LinkedFunctions* MTL::LinkedFunctions::linkedFunctions() 69 | { 70 | return Object::sendMessage(_MTL_PRIVATE_CLS(MTLLinkedFunctions), _MTL_PRIVATE_SEL(linkedFunctions)); 71 | } 72 | 73 | // property: functions 74 | _MTL_INLINE NS::Array* MTL::LinkedFunctions::functions() const 75 | { 76 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(functions)); 77 | } 78 | 79 | _MTL_INLINE void MTL::LinkedFunctions::setFunctions(const NS::Array* functions) 80 | { 81 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setFunctions_), functions); 82 | } 83 | 84 | // property: binaryFunctions 85 | _MTL_INLINE NS::Array* MTL::LinkedFunctions::binaryFunctions() const 86 | { 87 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(binaryFunctions)); 88 | } 89 | 90 | _MTL_INLINE void MTL::LinkedFunctions::setBinaryFunctions(const NS::Array* binaryFunctions) 91 | { 92 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setBinaryFunctions_), binaryFunctions); 93 | } 94 | 95 | // property: groups 96 | _MTL_INLINE NS::Array* MTL::LinkedFunctions::groups() const 97 | { 98 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(groups)); 99 | } 100 | 101 | _MTL_INLINE void MTL::LinkedFunctions::setGroups(const NS::Array* groups) 102 | { 103 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setGroups_), groups); 104 | } 105 | 106 | // property: privateFunctions 107 | _MTL_INLINE NS::Array* MTL::LinkedFunctions::privateFunctions() const 108 | { 109 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(privateFunctions)); 110 | } 111 | 112 | _MTL_INLINE void MTL::LinkedFunctions::setPrivateFunctions(const NS::Array* privateFunctions) 113 | { 114 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setPrivateFunctions_), privateFunctions); 115 | } 116 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLParallelRenderCommandEncoder.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLParallelRenderCommandEncoder.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLCommandEncoder.hpp" 30 | #include "MTLRenderPass.hpp" 31 | 32 | namespace MTL 33 | { 34 | class ParallelRenderCommandEncoder : public NS::Referencing 35 | { 36 | public: 37 | class RenderCommandEncoder* renderCommandEncoder(); 38 | 39 | void setColorStoreAction(MTL::StoreAction storeAction, NS::UInteger colorAttachmentIndex); 40 | 41 | void setDepthStoreAction(MTL::StoreAction storeAction); 42 | 43 | void setStencilStoreAction(MTL::StoreAction storeAction); 44 | 45 | void setColorStoreActionOptions(MTL::StoreActionOptions storeActionOptions, NS::UInteger colorAttachmentIndex); 46 | 47 | void setDepthStoreActionOptions(MTL::StoreActionOptions storeActionOptions); 48 | 49 | void setStencilStoreActionOptions(MTL::StoreActionOptions storeActionOptions); 50 | }; 51 | 52 | } 53 | 54 | // method: renderCommandEncoder 55 | _MTL_INLINE MTL::RenderCommandEncoder* MTL::ParallelRenderCommandEncoder::renderCommandEncoder() 56 | { 57 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(renderCommandEncoder)); 58 | } 59 | 60 | // method: setColorStoreAction:atIndex: 61 | _MTL_INLINE void MTL::ParallelRenderCommandEncoder::setColorStoreAction(MTL::StoreAction storeAction, NS::UInteger colorAttachmentIndex) 62 | { 63 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setColorStoreAction_atIndex_), storeAction, colorAttachmentIndex); 64 | } 65 | 66 | // method: setDepthStoreAction: 67 | _MTL_INLINE void MTL::ParallelRenderCommandEncoder::setDepthStoreAction(MTL::StoreAction storeAction) 68 | { 69 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setDepthStoreAction_), storeAction); 70 | } 71 | 72 | // method: setStencilStoreAction: 73 | _MTL_INLINE void MTL::ParallelRenderCommandEncoder::setStencilStoreAction(MTL::StoreAction storeAction) 74 | { 75 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setStencilStoreAction_), storeAction); 76 | } 77 | 78 | // method: setColorStoreActionOptions:atIndex: 79 | _MTL_INLINE void MTL::ParallelRenderCommandEncoder::setColorStoreActionOptions(MTL::StoreActionOptions storeActionOptions, NS::UInteger colorAttachmentIndex) 80 | { 81 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setColorStoreActionOptions_atIndex_), storeActionOptions, colorAttachmentIndex); 82 | } 83 | 84 | // method: setDepthStoreActionOptions: 85 | _MTL_INLINE void MTL::ParallelRenderCommandEncoder::setDepthStoreActionOptions(MTL::StoreActionOptions storeActionOptions) 86 | { 87 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setDepthStoreActionOptions_), storeActionOptions); 88 | } 89 | 90 | // method: setStencilStoreActionOptions: 91 | _MTL_INLINE void MTL::ParallelRenderCommandEncoder::setStencilStoreActionOptions(MTL::StoreActionOptions storeActionOptions) 92 | { 93 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setStencilStoreActionOptions_), storeActionOptions); 94 | } 95 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLPipeline.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLPipeline.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLPipeline.hpp" 30 | 31 | namespace MTL 32 | { 33 | _MTL_ENUM(NS::UInteger, Mutability) { 34 | MutabilityDefault = 0, 35 | MutabilityMutable = 1, 36 | MutabilityImmutable = 2, 37 | }; 38 | 39 | class PipelineBufferDescriptor : public NS::Copying 40 | { 41 | public: 42 | static class PipelineBufferDescriptor* alloc(); 43 | 44 | class PipelineBufferDescriptor* init(); 45 | 46 | MTL::Mutability mutability() const; 47 | void setMutability(MTL::Mutability mutability); 48 | }; 49 | 50 | class PipelineBufferDescriptorArray : public NS::Referencing 51 | { 52 | public: 53 | static class PipelineBufferDescriptorArray* alloc(); 54 | 55 | class PipelineBufferDescriptorArray* init(); 56 | 57 | class PipelineBufferDescriptor* object(NS::UInteger bufferIndex); 58 | 59 | void setObject(const class PipelineBufferDescriptor* buffer, NS::UInteger bufferIndex); 60 | }; 61 | 62 | } 63 | 64 | // static method: alloc 65 | _MTL_INLINE MTL::PipelineBufferDescriptor* MTL::PipelineBufferDescriptor::alloc() 66 | { 67 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLPipelineBufferDescriptor)); 68 | } 69 | 70 | // method: init 71 | _MTL_INLINE MTL::PipelineBufferDescriptor* MTL::PipelineBufferDescriptor::init() 72 | { 73 | return NS::Object::init(); 74 | } 75 | 76 | // property: mutability 77 | _MTL_INLINE MTL::Mutability MTL::PipelineBufferDescriptor::mutability() const 78 | { 79 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(mutability)); 80 | } 81 | 82 | _MTL_INLINE void MTL::PipelineBufferDescriptor::setMutability(MTL::Mutability mutability) 83 | { 84 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setMutability_), mutability); 85 | } 86 | 87 | // static method: alloc 88 | _MTL_INLINE MTL::PipelineBufferDescriptorArray* MTL::PipelineBufferDescriptorArray::alloc() 89 | { 90 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLPipelineBufferDescriptorArray)); 91 | } 92 | 93 | // method: init 94 | _MTL_INLINE MTL::PipelineBufferDescriptorArray* MTL::PipelineBufferDescriptorArray::init() 95 | { 96 | return NS::Object::init(); 97 | } 98 | 99 | // method: objectAtIndexedSubscript: 100 | _MTL_INLINE MTL::PipelineBufferDescriptor* MTL::PipelineBufferDescriptorArray::object(NS::UInteger bufferIndex) 101 | { 102 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(objectAtIndexedSubscript_), bufferIndex); 103 | } 104 | 105 | // method: setObject:atIndexedSubscript: 106 | _MTL_INLINE void MTL::PipelineBufferDescriptorArray::setObject(const MTL::PipelineBufferDescriptor* buffer, NS::UInteger bufferIndex) 107 | { 108 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setObject_atIndexedSubscript_), buffer, bufferIndex); 109 | } 110 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLPixelFormat.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLPixelFormat.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | namespace MTL 30 | { 31 | _MTL_ENUM(NS::UInteger, PixelFormat) { 32 | PixelFormatInvalid = 0, 33 | PixelFormatA8Unorm = 1, 34 | PixelFormatR8Unorm = 10, 35 | PixelFormatR8Unorm_sRGB = 11, 36 | PixelFormatR8Snorm = 12, 37 | PixelFormatR8Uint = 13, 38 | PixelFormatR8Sint = 14, 39 | PixelFormatR16Unorm = 20, 40 | PixelFormatR16Snorm = 22, 41 | PixelFormatR16Uint = 23, 42 | PixelFormatR16Sint = 24, 43 | PixelFormatR16Float = 25, 44 | PixelFormatRG8Unorm = 30, 45 | PixelFormatRG8Unorm_sRGB = 31, 46 | PixelFormatRG8Snorm = 32, 47 | PixelFormatRG8Uint = 33, 48 | PixelFormatRG8Sint = 34, 49 | PixelFormatB5G6R5Unorm = 40, 50 | PixelFormatA1BGR5Unorm = 41, 51 | PixelFormatABGR4Unorm = 42, 52 | PixelFormatBGR5A1Unorm = 43, 53 | PixelFormatR32Uint = 53, 54 | PixelFormatR32Sint = 54, 55 | PixelFormatR32Float = 55, 56 | PixelFormatRG16Unorm = 60, 57 | PixelFormatRG16Snorm = 62, 58 | PixelFormatRG16Uint = 63, 59 | PixelFormatRG16Sint = 64, 60 | PixelFormatRG16Float = 65, 61 | PixelFormatRGBA8Unorm = 70, 62 | PixelFormatRGBA8Unorm_sRGB = 71, 63 | PixelFormatRGBA8Snorm = 72, 64 | PixelFormatRGBA8Uint = 73, 65 | PixelFormatRGBA8Sint = 74, 66 | PixelFormatBGRA8Unorm = 80, 67 | PixelFormatBGRA8Unorm_sRGB = 81, 68 | PixelFormatRGB10A2Unorm = 90, 69 | PixelFormatRGB10A2Uint = 91, 70 | PixelFormatRG11B10Float = 92, 71 | PixelFormatRGB9E5Float = 93, 72 | PixelFormatBGR10A2Unorm = 94, 73 | PixelFormatRG32Uint = 103, 74 | PixelFormatRG32Sint = 104, 75 | PixelFormatRG32Float = 105, 76 | PixelFormatRGBA16Unorm = 110, 77 | PixelFormatRGBA16Snorm = 112, 78 | PixelFormatRGBA16Uint = 113, 79 | PixelFormatRGBA16Sint = 114, 80 | PixelFormatRGBA16Float = 115, 81 | PixelFormatRGBA32Uint = 123, 82 | PixelFormatRGBA32Sint = 124, 83 | PixelFormatRGBA32Float = 125, 84 | PixelFormatBC1_RGBA = 130, 85 | PixelFormatBC1_RGBA_sRGB = 131, 86 | PixelFormatBC2_RGBA = 132, 87 | PixelFormatBC2_RGBA_sRGB = 133, 88 | PixelFormatBC3_RGBA = 134, 89 | PixelFormatBC3_RGBA_sRGB = 135, 90 | PixelFormatBC4_RUnorm = 140, 91 | PixelFormatBC4_RSnorm = 141, 92 | PixelFormatBC5_RGUnorm = 142, 93 | PixelFormatBC5_RGSnorm = 143, 94 | PixelFormatBC6H_RGBFloat = 150, 95 | PixelFormatBC6H_RGBUfloat = 151, 96 | PixelFormatBC7_RGBAUnorm = 152, 97 | PixelFormatBC7_RGBAUnorm_sRGB = 153, 98 | PixelFormatPVRTC_RGB_2BPP = 160, 99 | PixelFormatPVRTC_RGB_2BPP_sRGB = 161, 100 | PixelFormatPVRTC_RGB_4BPP = 162, 101 | PixelFormatPVRTC_RGB_4BPP_sRGB = 163, 102 | PixelFormatPVRTC_RGBA_2BPP = 164, 103 | PixelFormatPVRTC_RGBA_2BPP_sRGB = 165, 104 | PixelFormatPVRTC_RGBA_4BPP = 166, 105 | PixelFormatPVRTC_RGBA_4BPP_sRGB = 167, 106 | PixelFormatEAC_R11Unorm = 170, 107 | PixelFormatEAC_R11Snorm = 172, 108 | PixelFormatEAC_RG11Unorm = 174, 109 | PixelFormatEAC_RG11Snorm = 176, 110 | PixelFormatEAC_RGBA8 = 178, 111 | PixelFormatEAC_RGBA8_sRGB = 179, 112 | PixelFormatETC2_RGB8 = 180, 113 | PixelFormatETC2_RGB8_sRGB = 181, 114 | PixelFormatETC2_RGB8A1 = 182, 115 | PixelFormatETC2_RGB8A1_sRGB = 183, 116 | PixelFormatASTC_4x4_sRGB = 186, 117 | PixelFormatASTC_5x4_sRGB = 187, 118 | PixelFormatASTC_5x5_sRGB = 188, 119 | PixelFormatASTC_6x5_sRGB = 189, 120 | PixelFormatASTC_6x6_sRGB = 190, 121 | PixelFormatASTC_8x5_sRGB = 192, 122 | PixelFormatASTC_8x6_sRGB = 193, 123 | PixelFormatASTC_8x8_sRGB = 194, 124 | PixelFormatASTC_10x5_sRGB = 195, 125 | PixelFormatASTC_10x6_sRGB = 196, 126 | PixelFormatASTC_10x8_sRGB = 197, 127 | PixelFormatASTC_10x10_sRGB = 198, 128 | PixelFormatASTC_12x10_sRGB = 199, 129 | PixelFormatASTC_12x12_sRGB = 200, 130 | PixelFormatASTC_4x4_LDR = 204, 131 | PixelFormatASTC_5x4_LDR = 205, 132 | PixelFormatASTC_5x5_LDR = 206, 133 | PixelFormatASTC_6x5_LDR = 207, 134 | PixelFormatASTC_6x6_LDR = 208, 135 | PixelFormatASTC_8x5_LDR = 210, 136 | PixelFormatASTC_8x6_LDR = 211, 137 | PixelFormatASTC_8x8_LDR = 212, 138 | PixelFormatASTC_10x5_LDR = 213, 139 | PixelFormatASTC_10x6_LDR = 214, 140 | PixelFormatASTC_10x8_LDR = 215, 141 | PixelFormatASTC_10x10_LDR = 216, 142 | PixelFormatASTC_12x10_LDR = 217, 143 | PixelFormatASTC_12x12_LDR = 218, 144 | PixelFormatASTC_4x4_HDR = 222, 145 | PixelFormatASTC_5x4_HDR = 223, 146 | PixelFormatASTC_5x5_HDR = 224, 147 | PixelFormatASTC_6x5_HDR = 225, 148 | PixelFormatASTC_6x6_HDR = 226, 149 | PixelFormatASTC_8x5_HDR = 228, 150 | PixelFormatASTC_8x6_HDR = 229, 151 | PixelFormatASTC_8x8_HDR = 230, 152 | PixelFormatASTC_10x5_HDR = 231, 153 | PixelFormatASTC_10x6_HDR = 232, 154 | PixelFormatASTC_10x8_HDR = 233, 155 | PixelFormatASTC_10x10_HDR = 234, 156 | PixelFormatASTC_12x10_HDR = 235, 157 | PixelFormatASTC_12x12_HDR = 236, 158 | PixelFormatGBGR422 = 240, 159 | PixelFormatBGRG422 = 241, 160 | PixelFormatDepth16Unorm = 250, 161 | PixelFormatDepth32Float = 252, 162 | PixelFormatStencil8 = 253, 163 | PixelFormatDepth24Unorm_Stencil8 = 255, 164 | PixelFormatDepth32Float_Stencil8 = 260, 165 | PixelFormatX32_Stencil8 = 261, 166 | PixelFormatX24_Stencil8 = 262, 167 | PixelFormatBGRA10_XR = 552, 168 | PixelFormatBGRA10_XR_sRGB = 553, 169 | PixelFormatBGR10_XR = 554, 170 | PixelFormatBGR10_XR_sRGB = 555, 171 | }; 172 | 173 | } 174 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLPrivate.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLPrivate.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "MTLDefines.hpp" 26 | 27 | #include 28 | 29 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 30 | 31 | #define _MTL_PRIVATE_CLS(symbol) (Private::Class::s_k##symbol) 32 | #define _MTL_PRIVATE_SEL(accessor) (Private::Selector::s_k##accessor) 33 | 34 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 35 | 36 | #if defined(MTL_PRIVATE_IMPLEMENTATION) 37 | 38 | #define _MTL_PRIVATE_VISIBILITY __attribute__((visibility("default"))) 39 | #define _MTL_PRIVATE_IMPORT __attribute__((weak_import)) 40 | 41 | #if __OBJC__ 42 | #define _MTL_PRIVATE_OBJC_LOOKUP_CLASS(symbol) ((__bridge void*)objc_lookUpClass(#symbol)) 43 | #else 44 | #define _MTL_PRIVATE_OBJC_LOOKUP_CLASS(symbol) objc_lookUpClass(#symbol) 45 | #endif // __OBJC__ 46 | 47 | #define _MTL_PRIVATE_DEF_CLS(symbol) void* s_k##symbol _MTL_PRIVATE_VISIBILITY = _MTL_PRIVATE_OBJC_LOOKUP_CLASS(symbol); 48 | #define _MTL_PRIVATE_DEF_PRO(symbol) 49 | #define _MTL_PRIVATE_DEF_SEL(accessor, symbol) SEL s_k##accessor _MTL_PRIVATE_VISIBILITY = sel_registerName(symbol); 50 | 51 | #if defined(__MAC_10_16) || defined(__MAC_11_0) || defined(__MAC_12_0) || defined(__IPHONE_14_0) || defined(__IPHONE_15_0) || defined(__TVOS_14_0) || defined(__TVOS_15_0) 52 | 53 | #define _MTL_PRIVATE_DEF_STR(type, symbol) \ 54 | _MTL_EXTERN type const MTL##symbol _MTL_PRIVATE_IMPORT; \ 55 | type const MTL::symbol = (nullptr != &MTL##symbol) ? MTL##symbol : nullptr; 56 | 57 | #else 58 | 59 | #include 60 | 61 | namespace MTL 62 | { 63 | namespace Private 64 | { 65 | 66 | template 67 | inline _Type const LoadSymbol(const char* pSymbol) 68 | { 69 | const _Type* pAddress = static_cast<_Type*>(dlsym(RTLD_DEFAULT, pSymbol)); 70 | 71 | return pAddress ? *pAddress : nullptr; 72 | } 73 | 74 | } // Private 75 | } // MTL 76 | 77 | #define _MTL_PRIVATE_DEF_STR(type, symbol) \ 78 | _MTL_EXTERN type const MTL##symbol; \ 79 | type const MTL::symbol = Private::LoadSymbol("MTL" #symbol); 80 | 81 | #endif // defined(__MAC_10_16) || defined(__MAC_11_0) || defined(__MAC_12_0) || defined(__IPHONE_14_0) || defined(__IPHONE_15_0) || defined(__TVOS_14_0) || defined(__TVOS_15_0) 82 | 83 | #else 84 | 85 | #define _MTL_PRIVATE_DEF_CLS(symbol) extern void* s_k##symbol; 86 | #define _MTL_PRIVATE_DEF_PRO(symbol) 87 | #define _MTL_PRIVATE_DEF_SEL(accessor, symbol) extern SEL s_k##accessor; 88 | #define _MTL_PRIVATE_DEF_STR(type, symbol) 89 | 90 | #endif // MTL_PRIVATE_IMPLEMENTATION 91 | 92 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 93 | 94 | namespace MTL 95 | { 96 | namespace Private 97 | { 98 | namespace Class 99 | { 100 | 101 | } // Class 102 | } // Private 103 | } // MTL 104 | 105 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 106 | 107 | namespace MTL 108 | { 109 | namespace Private 110 | { 111 | namespace Protocol 112 | { 113 | 114 | } // Protocol 115 | } // Private 116 | } // MTL 117 | 118 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 119 | 120 | namespace MTL 121 | { 122 | namespace Private 123 | { 124 | namespace Selector 125 | { 126 | 127 | _MTL_PRIVATE_DEF_SEL(beginScope, 128 | "beginScope"); 129 | _MTL_PRIVATE_DEF_SEL(endScope, 130 | "endScope"); 131 | } // Class 132 | } // Private 133 | } // MTL 134 | 135 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 136 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLResource.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLResource.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLResource.hpp" 30 | 31 | namespace MTL 32 | { 33 | _MTL_ENUM(NS::UInteger, PurgeableState) { 34 | PurgeableStateKeepCurrent = 1, 35 | PurgeableStateNonVolatile = 2, 36 | PurgeableStateVolatile = 3, 37 | PurgeableStateEmpty = 4, 38 | }; 39 | 40 | _MTL_ENUM(NS::UInteger, CPUCacheMode) { 41 | CPUCacheModeDefaultCache = 0, 42 | CPUCacheModeWriteCombined = 1, 43 | }; 44 | 45 | _MTL_ENUM(NS::UInteger, StorageMode) { 46 | StorageModeShared = 0, 47 | StorageModeManaged = 1, 48 | StorageModePrivate = 2, 49 | StorageModeMemoryless = 3, 50 | }; 51 | 52 | _MTL_ENUM(NS::UInteger, HazardTrackingMode) { 53 | HazardTrackingModeDefault = 0, 54 | HazardTrackingModeUntracked = 1, 55 | HazardTrackingModeTracked = 2, 56 | }; 57 | 58 | _MTL_OPTIONS(NS::UInteger, ResourceOptions) { 59 | ResourceStorageModeShared = 0, 60 | ResourceHazardTrackingModeDefault = 0, 61 | ResourceCPUCacheModeDefaultCache = 0, 62 | ResourceOptionCPUCacheModeDefault = 0, 63 | ResourceCPUCacheModeWriteCombined = 1, 64 | ResourceOptionCPUCacheModeWriteCombined = 1, 65 | ResourceStorageModeManaged = 16, 66 | ResourceStorageModePrivate = 32, 67 | ResourceStorageModeMemoryless = 48, 68 | ResourceHazardTrackingModeUntracked = 256, 69 | ResourceHazardTrackingModeTracked = 512, 70 | }; 71 | 72 | class Resource : public NS::Referencing 73 | { 74 | public: 75 | NS::String* label() const; 76 | void setLabel(const NS::String* label); 77 | 78 | class Device* device() const; 79 | 80 | MTL::CPUCacheMode cpuCacheMode() const; 81 | 82 | MTL::StorageMode storageMode() const; 83 | 84 | MTL::HazardTrackingMode hazardTrackingMode() const; 85 | 86 | MTL::ResourceOptions resourceOptions() const; 87 | 88 | MTL::PurgeableState setPurgeableState(MTL::PurgeableState state); 89 | 90 | class Heap* heap() const; 91 | 92 | NS::UInteger heapOffset() const; 93 | 94 | NS::UInteger allocatedSize() const; 95 | 96 | void makeAliasable(); 97 | 98 | bool isAliasable(); 99 | }; 100 | 101 | } 102 | 103 | // property: label 104 | _MTL_INLINE NS::String* MTL::Resource::label() const 105 | { 106 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(label)); 107 | } 108 | 109 | _MTL_INLINE void MTL::Resource::setLabel(const NS::String* label) 110 | { 111 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setLabel_), label); 112 | } 113 | 114 | // property: device 115 | _MTL_INLINE MTL::Device* MTL::Resource::device() const 116 | { 117 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(device)); 118 | } 119 | 120 | // property: cpuCacheMode 121 | _MTL_INLINE MTL::CPUCacheMode MTL::Resource::cpuCacheMode() const 122 | { 123 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(cpuCacheMode)); 124 | } 125 | 126 | // property: storageMode 127 | _MTL_INLINE MTL::StorageMode MTL::Resource::storageMode() const 128 | { 129 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(storageMode)); 130 | } 131 | 132 | // property: hazardTrackingMode 133 | _MTL_INLINE MTL::HazardTrackingMode MTL::Resource::hazardTrackingMode() const 134 | { 135 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(hazardTrackingMode)); 136 | } 137 | 138 | // property: resourceOptions 139 | _MTL_INLINE MTL::ResourceOptions MTL::Resource::resourceOptions() const 140 | { 141 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(resourceOptions)); 142 | } 143 | 144 | // method: setPurgeableState: 145 | _MTL_INLINE MTL::PurgeableState MTL::Resource::setPurgeableState(MTL::PurgeableState state) 146 | { 147 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(setPurgeableState_), state); 148 | } 149 | 150 | // property: heap 151 | _MTL_INLINE MTL::Heap* MTL::Resource::heap() const 152 | { 153 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(heap)); 154 | } 155 | 156 | // property: heapOffset 157 | _MTL_INLINE NS::UInteger MTL::Resource::heapOffset() const 158 | { 159 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(heapOffset)); 160 | } 161 | 162 | // property: allocatedSize 163 | _MTL_INLINE NS::UInteger MTL::Resource::allocatedSize() const 164 | { 165 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(allocatedSize)); 166 | } 167 | 168 | // method: makeAliasable 169 | _MTL_INLINE void MTL::Resource::makeAliasable() 170 | { 171 | Object::sendMessage(this, _MTL_PRIVATE_SEL(makeAliasable)); 172 | } 173 | 174 | // method: isAliasable 175 | _MTL_INLINE bool MTL::Resource::isAliasable() 176 | { 177 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(isAliasable)); 178 | } 179 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLResourceStateCommandEncoder.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLResourceStateCommandEncoder.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLCommandEncoder.hpp" 30 | 31 | namespace MTL 32 | { 33 | _MTL_ENUM(NS::UInteger, SparseTextureMappingMode) { 34 | SparseTextureMappingModeMap = 0, 35 | SparseTextureMappingModeUnmap = 1, 36 | }; 37 | 38 | struct MapIndirectArguments 39 | { 40 | uint32_t regionOriginX; 41 | uint32_t regionOriginY; 42 | uint32_t regionOriginZ; 43 | uint32_t regionSizeWidth; 44 | uint32_t regionSizeHeight; 45 | uint32_t regionSizeDepth; 46 | uint32_t mipMapLevel; 47 | uint32_t sliceId; 48 | } _MTL_PACKED; 49 | 50 | class ResourceStateCommandEncoder : public NS::Referencing 51 | { 52 | public: 53 | void updateTextureMappings(const class Texture* texture, const MTL::SparseTextureMappingMode mode, const MTL::Region* regions, const NS::UInteger* mipLevels, const NS::UInteger* slices, NS::UInteger numRegions); 54 | 55 | void updateTextureMapping(const class Texture* texture, const MTL::SparseTextureMappingMode mode, const MTL::Region region, const NS::UInteger mipLevel, const NS::UInteger slice); 56 | 57 | void updateTextureMapping(const class Texture* texture, const MTL::SparseTextureMappingMode mode, const class Buffer* indirectBuffer, NS::UInteger indirectBufferOffset); 58 | 59 | void updateFence(const class Fence* fence); 60 | 61 | void waitForFence(const class Fence* fence); 62 | }; 63 | 64 | } 65 | 66 | // method: updateTextureMappings:mode:regions:mipLevels:slices:numRegions: 67 | _MTL_INLINE void MTL::ResourceStateCommandEncoder::updateTextureMappings(const MTL::Texture* texture, const MTL::SparseTextureMappingMode mode, const MTL::Region* regions, const NS::UInteger* mipLevels, const NS::UInteger* slices, NS::UInteger numRegions) 68 | { 69 | Object::sendMessage(this, _MTL_PRIVATE_SEL(updateTextureMappings_mode_regions_mipLevels_slices_numRegions_), texture, mode, regions, mipLevels, slices, numRegions); 70 | } 71 | 72 | // method: updateTextureMapping:mode:region:mipLevel:slice: 73 | _MTL_INLINE void MTL::ResourceStateCommandEncoder::updateTextureMapping(const MTL::Texture* texture, const MTL::SparseTextureMappingMode mode, const MTL::Region region, const NS::UInteger mipLevel, const NS::UInteger slice) 74 | { 75 | Object::sendMessage(this, _MTL_PRIVATE_SEL(updateTextureMapping_mode_region_mipLevel_slice_), texture, mode, region, mipLevel, slice); 76 | } 77 | 78 | // method: updateTextureMapping:mode:indirectBuffer:indirectBufferOffset: 79 | _MTL_INLINE void MTL::ResourceStateCommandEncoder::updateTextureMapping(const MTL::Texture* texture, const MTL::SparseTextureMappingMode mode, const MTL::Buffer* indirectBuffer, NS::UInteger indirectBufferOffset) 80 | { 81 | Object::sendMessage(this, _MTL_PRIVATE_SEL(updateTextureMapping_mode_indirectBuffer_indirectBufferOffset_), texture, mode, indirectBuffer, indirectBufferOffset); 82 | } 83 | 84 | // method: updateFence: 85 | _MTL_INLINE void MTL::ResourceStateCommandEncoder::updateFence(const MTL::Fence* fence) 86 | { 87 | Object::sendMessage(this, _MTL_PRIVATE_SEL(updateFence_), fence); 88 | } 89 | 90 | // method: waitForFence: 91 | _MTL_INLINE void MTL::ResourceStateCommandEncoder::waitForFence(const MTL::Fence* fence) 92 | { 93 | Object::sendMessage(this, _MTL_PRIVATE_SEL(waitForFence_), fence); 94 | } 95 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLTypes.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLTypes.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLTypes.hpp" 30 | 31 | namespace MTL 32 | { 33 | struct Origin 34 | { 35 | Origin() = default; 36 | 37 | Origin(NS::UInteger x, NS::UInteger y, NS::UInteger z); 38 | 39 | static Origin Make(NS::UInteger x, NS::UInteger y, NS::UInteger z); 40 | 41 | NS::UInteger x; 42 | NS::UInteger y; 43 | NS::UInteger z; 44 | } _MTL_PACKED; 45 | 46 | struct Size 47 | { 48 | Size() = default; 49 | 50 | Size(NS::UInteger width, NS::UInteger height, NS::UInteger depth); 51 | 52 | static Size Make(NS::UInteger width, NS::UInteger height, NS::UInteger depth); 53 | 54 | NS::UInteger width; 55 | NS::UInteger height; 56 | NS::UInteger depth; 57 | } _MTL_PACKED; 58 | 59 | struct Region 60 | { 61 | Region() = default; 62 | 63 | Region(NS::UInteger x, NS::UInteger width); 64 | 65 | Region(NS::UInteger x, NS::UInteger y, NS::UInteger width, NS::UInteger height); 66 | 67 | Region(NS::UInteger x, NS::UInteger y, NS::UInteger z, NS::UInteger width, NS::UInteger height, NS::UInteger depth); 68 | 69 | static Region Make1D(NS::UInteger x, NS::UInteger width); 70 | 71 | static Region Make2D(NS::UInteger x, NS::UInteger y, NS::UInteger width, NS::UInteger height); 72 | 73 | static Region Make3D(NS::UInteger x, NS::UInteger y, NS::UInteger z, NS::UInteger width, NS::UInteger height, NS::UInteger depth); 74 | 75 | MTL::Origin origin; 76 | MTL::Size size; 77 | } _MTL_PACKED; 78 | 79 | struct SamplePosition; 80 | 81 | using Coordinate2D = SamplePosition; 82 | 83 | struct SamplePosition 84 | { 85 | SamplePosition() = default; 86 | 87 | SamplePosition(float _x, float _y); 88 | 89 | static SamplePosition Make(float x, float y); 90 | 91 | float x; 92 | float y; 93 | } _MTL_PACKED; 94 | 95 | } 96 | 97 | _MTL_INLINE MTL::Origin::Origin(NS::UInteger _x, NS::UInteger _y, NS::UInteger _z) 98 | : x(_x) 99 | , y(_y) 100 | , z(_z) 101 | { 102 | } 103 | 104 | _MTL_INLINE MTL::Origin MTL::Origin::Make(NS::UInteger x, NS::UInteger y, NS::UInteger z) 105 | { 106 | return Origin(x, y, z); 107 | } 108 | 109 | _MTL_INLINE MTL::Size::Size(NS::UInteger _width, NS::UInteger _height, NS::UInteger _depth) 110 | : width(_width) 111 | , height(_height) 112 | , depth(_depth) 113 | { 114 | } 115 | 116 | _MTL_INLINE MTL::Size MTL::Size::Make(NS::UInteger width, NS::UInteger height, NS::UInteger depth) 117 | { 118 | return Size(width, height, depth); 119 | } 120 | 121 | _MTL_INLINE MTL::Region::Region(NS::UInteger x, NS::UInteger width) 122 | : origin(x, 0, 0) 123 | , size(width, 1, 1) 124 | { 125 | } 126 | 127 | _MTL_INLINE MTL::Region::Region(NS::UInteger x, NS::UInteger y, NS::UInteger width, NS::UInteger height) 128 | : origin(x, y, 0) 129 | , size(width, height, 1) 130 | { 131 | } 132 | 133 | _MTL_INLINE MTL::Region::Region(NS::UInteger x, NS::UInteger y, NS::UInteger z, NS::UInteger width, NS::UInteger height, NS::UInteger depth) 134 | : origin(x, y, z) 135 | , size(width, height, depth) 136 | { 137 | } 138 | 139 | _MTL_INLINE MTL::Region MTL::Region::Make1D(NS::UInteger x, NS::UInteger width) 140 | { 141 | return Region(x, width); 142 | } 143 | 144 | _MTL_INLINE MTL::Region MTL::Region::Make2D(NS::UInteger x, NS::UInteger y, NS::UInteger width, NS::UInteger height) 145 | { 146 | return Region(x, y, width, height); 147 | } 148 | 149 | _MTL_INLINE MTL::Region MTL::Region::Make3D(NS::UInteger x, NS::UInteger y, NS::UInteger z, NS::UInteger width, NS::UInteger height, NS::UInteger depth) 150 | { 151 | return Region(x, y, z, width, height, depth); 152 | } 153 | 154 | _MTL_INLINE MTL::SamplePosition::SamplePosition(float _x, float _y) 155 | : x(_x) 156 | , y(_y) 157 | { 158 | } 159 | 160 | _MTL_INLINE MTL::SamplePosition MTL::SamplePosition::Make(float x, float y) 161 | { 162 | return SamplePosition(x, y); 163 | } 164 | -------------------------------------------------------------------------------- /metal-cpp/Metal/MTLVisibleFunctionTable.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/MTLVisibleFunctionTable.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | #include "MTLDefines.hpp" 24 | #include "MTLHeaderBridge.hpp" 25 | #include "MTLPrivate.hpp" 26 | 27 | #include 28 | 29 | #include "MTLFunctionHandle.hpp" 30 | #include "MTLResource.hpp" 31 | 32 | namespace MTL 33 | { 34 | class VisibleFunctionTableDescriptor : public NS::Copying 35 | { 36 | public: 37 | static class VisibleFunctionTableDescriptor* alloc(); 38 | 39 | class VisibleFunctionTableDescriptor* init(); 40 | 41 | static class VisibleFunctionTableDescriptor* visibleFunctionTableDescriptor(); 42 | 43 | NS::UInteger functionCount() const; 44 | void setFunctionCount(NS::UInteger functionCount); 45 | }; 46 | 47 | class VisibleFunctionTable : public NS::Referencing 48 | { 49 | public: 50 | void setFunction(const class FunctionHandle* function, NS::UInteger index); 51 | 52 | void setFunctions(const class FunctionHandle* functions[], NS::Range range); 53 | }; 54 | 55 | } 56 | 57 | // static method: alloc 58 | _MTL_INLINE MTL::VisibleFunctionTableDescriptor* MTL::VisibleFunctionTableDescriptor::alloc() 59 | { 60 | return NS::Object::alloc(_MTL_PRIVATE_CLS(MTLVisibleFunctionTableDescriptor)); 61 | } 62 | 63 | // method: init 64 | _MTL_INLINE MTL::VisibleFunctionTableDescriptor* MTL::VisibleFunctionTableDescriptor::init() 65 | { 66 | return NS::Object::init(); 67 | } 68 | 69 | // static method: visibleFunctionTableDescriptor 70 | _MTL_INLINE MTL::VisibleFunctionTableDescriptor* MTL::VisibleFunctionTableDescriptor::visibleFunctionTableDescriptor() 71 | { 72 | return Object::sendMessage(_MTL_PRIVATE_CLS(MTLVisibleFunctionTableDescriptor), _MTL_PRIVATE_SEL(visibleFunctionTableDescriptor)); 73 | } 74 | 75 | // property: functionCount 76 | _MTL_INLINE NS::UInteger MTL::VisibleFunctionTableDescriptor::functionCount() const 77 | { 78 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(functionCount)); 79 | } 80 | 81 | _MTL_INLINE void MTL::VisibleFunctionTableDescriptor::setFunctionCount(NS::UInteger functionCount) 82 | { 83 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setFunctionCount_), functionCount); 84 | } 85 | 86 | // method: setFunction:atIndex: 87 | _MTL_INLINE void MTL::VisibleFunctionTable::setFunction(const MTL::FunctionHandle* function, NS::UInteger index) 88 | { 89 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setFunction_atIndex_), function, index); 90 | } 91 | 92 | // method: setFunctions:withRange: 93 | _MTL_INLINE void MTL::VisibleFunctionTable::setFunctions(const MTL::FunctionHandle* functions[], NS::Range range) 94 | { 95 | Object::sendMessage(this, _MTL_PRIVATE_SEL(setFunctions_withRange_), functions, range); 96 | } 97 | -------------------------------------------------------------------------------- /metal-cpp/Metal/Metal.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Metal/Metal.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "MTLAccelerationStructure.hpp" 26 | #include "MTLAccelerationStructureCommandEncoder.hpp" 27 | #include "MTLAccelerationStructureTypes.hpp" 28 | #include "MTLArgument.hpp" 29 | #include "MTLArgumentEncoder.hpp" 30 | #include "MTLBinaryArchive.hpp" 31 | #include "MTLBlitCommandEncoder.hpp" 32 | #include "MTLBlitPass.hpp" 33 | #include "MTLBuffer.hpp" 34 | #include "MTLCaptureManager.hpp" 35 | #include "MTLCaptureScope.hpp" 36 | #include "MTLCommandBuffer.hpp" 37 | #include "MTLCommandEncoder.hpp" 38 | #include "MTLCommandQueue.hpp" 39 | #include "MTLComputeCommandEncoder.hpp" 40 | #include "MTLComputePass.hpp" 41 | #include "MTLComputePipeline.hpp" 42 | #include "MTLCounters.hpp" 43 | #include "MTLDefines.hpp" 44 | #include "MTLDepthStencil.hpp" 45 | #include "MTLDevice.hpp" 46 | #include "MTLDrawable.hpp" 47 | #include "MTLDynamicLibrary.hpp" 48 | #include "MTLEvent.hpp" 49 | #include "MTLFence.hpp" 50 | #include "MTLFunctionConstantValues.hpp" 51 | #include "MTLFunctionDescriptor.hpp" 52 | #include "MTLFunctionHandle.hpp" 53 | #include "MTLFunctionLog.hpp" 54 | #include "MTLFunctionStitching.hpp" 55 | #include "MTLHeaderBridge.hpp" 56 | #include "MTLHeap.hpp" 57 | #include "MTLIndirectCommandBuffer.hpp" 58 | #include "MTLIndirectCommandEncoder.hpp" 59 | #include "MTLIntersectionFunctionTable.hpp" 60 | #include "MTLLibrary.hpp" 61 | #include "MTLLinkedFunctions.hpp" 62 | #include "MTLParallelRenderCommandEncoder.hpp" 63 | #include "MTLPipeline.hpp" 64 | #include "MTLPixelFormat.hpp" 65 | #include "MTLPrivate.hpp" 66 | #include "MTLRasterizationRate.hpp" 67 | #include "MTLRenderCommandEncoder.hpp" 68 | #include "MTLRenderPass.hpp" 69 | #include "MTLRenderPipeline.hpp" 70 | #include "MTLResource.hpp" 71 | #include "MTLResourceStateCommandEncoder.hpp" 72 | #include "MTLResourceStatePass.hpp" 73 | #include "MTLSampler.hpp" 74 | #include "MTLStageInputOutputDescriptor.hpp" 75 | #include "MTLTexture.hpp" 76 | #include "MTLTypes.hpp" 77 | #include "MTLVertexDescriptor.hpp" 78 | #include "MTLVisibleFunctionTable.hpp" 79 | 80 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 81 | -------------------------------------------------------------------------------- /metal-cpp/QuartzCore/CADefines.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // QuartzCore/CADefines.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "../Foundation/NSDefines.hpp" 26 | 27 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 28 | 29 | #define _CA_EXPORT _NS_EXPORT 30 | #define _CA_EXTERN _NS_EXTERN 31 | #define _CA_INLINE _NS_INLINE 32 | #define _CA_PACKED _NS_PACKED 33 | 34 | #define _CA_CONST(type, name) _NS_CONST(type, name) 35 | #define _CA_ENUM(type, name) _NS_ENUM(type, name) 36 | #define _CA_OPTIONS(type, name) _NS_OPTIONS(type, name) 37 | 38 | #define _CA_VALIDATE_SIZE(ns, name) _NS_VALIDATE_SIZE(ns, name) 39 | #define _CA_VALIDATE_ENUM(ns, name) _NS_VALIDATE_ENUM(ns, name) 40 | 41 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 42 | -------------------------------------------------------------------------------- /metal-cpp/QuartzCore/CAMetalDrawable.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // QuartzCore/CAMetalDrawable.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "../Metal/MTLDrawable.hpp" 26 | #include "../Metal/MTLTexture.hpp" 27 | 28 | #include "CADefines.hpp" 29 | #include "CAPrivate.hpp" 30 | 31 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 32 | 33 | namespace CA 34 | { 35 | class MetalDrawable : public NS::Referencing 36 | { 37 | public: 38 | class MetalLayer* layer() const; 39 | MTL::Texture* texture() const; 40 | }; 41 | } 42 | 43 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 44 | 45 | _CA_INLINE CA::MetalLayer* CA::MetalDrawable::layer() const 46 | { 47 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(layer)); 48 | } 49 | 50 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 51 | 52 | _CA_INLINE MTL::Texture* CA::MetalDrawable::texture() const 53 | { 54 | return Object::sendMessage(this, _MTL_PRIVATE_SEL(texture)); 55 | } 56 | 57 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 58 | -------------------------------------------------------------------------------- /metal-cpp/QuartzCore/CAPrivate.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // QuartzCore/CAPrivate.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "CADefines.hpp" 26 | 27 | #include 28 | 29 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 30 | 31 | #define _CA_PRIVATE_CLS(symbol) (Private::Class::s_k##symbol) 32 | #define _CA_PRIVATE_SEL(accessor) (Private::Selector::s_k##accessor) 33 | 34 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 35 | 36 | #if defined(CA_PRIVATE_IMPLEMENTATION) 37 | 38 | #define _CA_PRIVATE_VISIBILITY __attribute__((visibility("default"))) 39 | #define _CA_PRIVATE_IMPORT __attribute__((weak_import)) 40 | 41 | #if __OBJC__ 42 | #define _CA_PRIVATE_OBJC_LOOKUP_CLASS(symbol) ((__bridge void*)objc_lookUpClass(#symbol)) 43 | #else 44 | #define _CA_PRIVATE_OBJC_LOOKUP_CLASS(symbol) objc_lookUpClass(#symbol) 45 | #endif // __OBJC__ 46 | 47 | #define _CA_PRIVATE_DEF_CLS(symbol) void* s_k##symbol _CA_PRIVATE_VISIBILITY = _CA_PRIVATE_OBJC_LOOKUP_CLASS(symbol); 48 | #define _CA_PRIVATE_DEF_PRO(symbol) 49 | #define _CA_PRIVATE_DEF_SEL(accessor, symbol) SEL s_k##accessor _CA_PRIVATE_VISIBILITY = sel_registerName(symbol); 50 | #define _CA_PRIVATE_DEF_STR(type, symbol) \ 51 | _CA_EXTERN type const CA##symbol _CA_PRIVATE_IMPORT; \ 52 | type const CA::symbol = (nullptr != &CA##symbol) ? CA##symbol : nullptr; 53 | 54 | #else 55 | 56 | #define _CA_PRIVATE_DEF_CLS(symbol) extern void* s_k##symbol; 57 | #define _CA_PRIVATE_DEF_PRO(symbol) 58 | #define _CA_PRIVATE_DEF_SEL(accessor, symbol) extern SEL s_k##accessor; 59 | #define _CA_PRIVATE_DEF_STR(type, symbol) 60 | 61 | #endif // CA_PRIVATE_IMPLEMENTATION 62 | 63 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 64 | 65 | namespace CA 66 | { 67 | namespace Private 68 | { 69 | namespace Class 70 | { 71 | 72 | } // Class 73 | } // Private 74 | } // CA 75 | 76 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 77 | 78 | namespace CA 79 | { 80 | namespace Private 81 | { 82 | namespace Protocol 83 | { 84 | 85 | _CA_PRIVATE_DEF_PRO(CAMetalDrawable); 86 | 87 | } // Protocol 88 | } // Private 89 | } // CA 90 | 91 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 92 | 93 | namespace CA 94 | { 95 | namespace Private 96 | { 97 | namespace Selector 98 | { 99 | 100 | _CA_PRIVATE_DEF_SEL(layer, 101 | "layer"); 102 | _CA_PRIVATE_DEF_SEL(texture, 103 | "texture"); 104 | 105 | } // Class 106 | } // Private 107 | } // CA 108 | 109 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 110 | -------------------------------------------------------------------------------- /metal-cpp/QuartzCore/QuartzCore.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // QuartzCore/QuartzCore.hpp 4 | // 5 | // Copyright 2020-2021 Apple Inc. 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 20 | 21 | #pragma once 22 | 23 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 24 | 25 | #include "CAMetalDrawable.hpp" 26 | 27 | //------------------------------------------------------------------------------------------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- /paper/combined_01.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsgeb/m1-gpu-cpp/3d8f8c587ab605ce32a39a01c847bfe53d71ef02/paper/combined_01.pdf -------------------------------------------------------------------------------- /paper/combined_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsgeb/m1-gpu-cpp/3d8f8c587ab605ce32a39a01c847bfe53d71ef02/paper/combined_01.png -------------------------------------------------------------------------------- /paper/combined_02.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsgeb/m1-gpu-cpp/3d8f8c587ab605ce32a39a01c847bfe53d71ef02/paper/combined_02.pdf -------------------------------------------------------------------------------- /paper/combined_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larsgeb/m1-gpu-cpp/3d8f8c587ab605ce32a39a01c847bfe53d71ef02/paper/combined_02.png -------------------------------------------------------------------------------- /paper/plot_1d_operators.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import matplotlib.pyplot as plt 3 | import pandas 4 | 5 | prop_cycle = plt.rcParams["axes.prop_cycle"] 6 | colors = prop_cycle.by_key()["color"] 7 | 8 | fig, axes = plt.subplots(2, 1, sharex=True, sharey=True, figsize=(4, 3.75)) 9 | 10 | plt.subplot(2, 1, 1) 11 | results_laplacian = [] 12 | data_sizes = [16, 128, 1024, 8192, 65536, 524288, 4194304, 33554432, 268435456] 13 | for data_size in data_sizes: 14 | results_laplacian.append( 15 | pandas.read_csv( 16 | f"./results/runtimes_saxpy_{data_size}.csv", 17 | index_col=0, 18 | header=None, 19 | ).T 20 | ) 21 | categories = list(results_laplacian[0].columns.values) 22 | dataframes = {} 23 | for category in categories: 24 | dataframes[category] = {} 25 | for result, data_size in zip(results_laplacian, data_sizes): 26 | dataframes[category][data_size] = result[category] 27 | labels = [ 28 | "Metal (GPU)", 29 | "Serial", 30 | "OpenMP, 2 threads", 31 | "OpenMP, 4 threads", 32 | "OpenMP, 8 threads", 33 | "OpenMP, 10 threads", 34 | ] 35 | medians = [] 36 | for i, category in enumerate(categories): 37 | medians.append([]) 38 | color = colors[i] 39 | for data_size in data_sizes: 40 | data = dataframes[category][data_size] 41 | medians[i].append(numpy.mean(dataframes[category][data_size])) 42 | if data.size > 1000: 43 | data = data.copy()[:: int(data.size / 1000)] 44 | plt.scatter( 45 | data_size * numpy.ones_like(data), 46 | data, 47 | alpha=1.0 / data.size**0.5, 48 | s=1, 49 | color=color, 50 | ) 51 | 52 | saxpy_serial_speedup = (numpy.array(medians[0]) / numpy.array(medians[1]))[-1] 53 | saxpy_OpenMP_speedup = (numpy.array(medians[0]) / numpy.array(medians[-2]))[-1] 54 | 55 | for i, category in enumerate(categories): 56 | color = colors[i] 57 | plt.plot(data_sizes, medians[i], color=color, label=labels[i], linewidth=0.8) 58 | plt.scatter(data_sizes, medians[i], color=color, s=1) 59 | plt.grid() 60 | plt.grid(visible=True, which="major", color="k", linestyle="-", alpha=0.1) 61 | plt.grid(visible=True, which="minor", color="k", linestyle="--", alpha=0.1) 62 | 63 | 64 | plt.text( 65 | 0.05, 66 | 0.9, 67 | "SAXPY", 68 | horizontalalignment="left", 69 | verticalalignment="center", 70 | fontweight="bold", 71 | transform=axes[0].transAxes, 72 | ) 73 | plt.ylabel("runtime [ns]") 74 | 75 | plt.subplot(2, 1, 2) 76 | 77 | 78 | results_laplacian = [] 79 | data_sizes = [16, 128, 1024, 8192, 65536, 524288, 4194304, 33554432, 268435456] 80 | for data_size in data_sizes: 81 | results_laplacian.append( 82 | pandas.read_csv( 83 | f"./results/runtimes_centraldif_{data_size}.csv", 84 | index_col=0, 85 | header=None, 86 | ).T 87 | ) 88 | categories = list(results_laplacian[0].columns.values) 89 | dataframes = {} 90 | for category in categories: 91 | dataframes[category] = {} 92 | for result, data_size in zip(results_laplacian, data_sizes): 93 | dataframes[category][data_size] = result[category] 94 | labels = [ 95 | "Metal (GPU)", 96 | "Serial", 97 | "OpenMP, 2 threads", 98 | "OpenMP, 4 threads", 99 | "OpenMP, 8 threads", 100 | "OpenMP, 10 threads", 101 | ] 102 | medians = [] 103 | for i, category in enumerate(categories): 104 | medians.append([]) 105 | color = colors[i] 106 | for data_size in data_sizes: 107 | data = dataframes[category][data_size] 108 | medians[i].append(numpy.mean(dataframes[category][data_size])) 109 | if data.size > 1000: 110 | data = data.copy()[:: int(data.size / 1000)] 111 | plt.scatter( 112 | data_size * numpy.ones_like(data), 113 | data, 114 | alpha=1.0 / data.size**0.5, 115 | s=1, 116 | color=color, 117 | ) 118 | 119 | cd_serial_speedup = (numpy.array(medians[0]) / numpy.array(medians[1]))[-1] 120 | cd_OpenMP_speedup = (numpy.array(medians[0]) / numpy.array(medians[-2]))[-1] 121 | 122 | for i, category in enumerate(categories): 123 | color = colors[i] 124 | plt.plot(data_sizes, medians[i], color=color, label=labels[i], linewidth=0.8) 125 | plt.scatter(data_sizes, medians[i], color=color, s=1) 126 | plt.grid() 127 | plt.grid(visible=True, which="major", color="k", linestyle="-", alpha=0.1) 128 | plt.grid(visible=True, which="minor", color="k", linestyle="--", alpha=0.1) 129 | 130 | 131 | plt.text( 132 | 0.05, 133 | 0.9, 134 | "Central differencing 3-point", 135 | horizontalalignment="left", 136 | verticalalignment="center", 137 | fontweight="bold", 138 | transform=axes[1].transAxes, 139 | ) 140 | plt.ylabel("runtime [ns]") 141 | 142 | plt.subplot(2, 1, 1) 143 | 144 | plt.yscale("log") 145 | plt.xscale("log") 146 | 147 | 148 | plt.subplot(2, 1, 2) 149 | plt.legend(loc="lower right", ncol=2, fontsize=5) 150 | 151 | plt.yscale("log") 152 | plt.xscale("log") 153 | plt.gca().set_xticks( 154 | data_sizes, 155 | [f"2^{int(numpy.log2(data_size))}" for data_size in data_sizes], 156 | rotation=25, 157 | ) 158 | 159 | xlim = plt.xlim() 160 | plt.gca().set_xticks( 161 | [2 ** float(i) for i in range(int(numpy.log2(data_sizes[-1])))], 162 | minor=True, 163 | labels=[], 164 | ) 165 | plt.gca().set_xticks( 166 | data_sizes, 167 | [f"$2^{{{int(numpy.log2(data_size))}}}$" for data_size in data_sizes], 168 | rotation=0, 169 | ) 170 | 171 | plt.xlim(xlim) 172 | 173 | plt.xlabel("data size") 174 | plt.ylabel("runtime [ns]") 175 | 176 | # plt.ylim([1e1, 1e8]) 177 | plt.tight_layout() 178 | 179 | fig.subplots_adjust(wspace=0, hspace=0) 180 | plt.savefig("combined_01.png", dpi=300, format="png") 181 | plt.close() 182 | 183 | print(f"cd speedup w.r.t. serial: {cd_serial_speedup**-1:.1f}") 184 | print(f"saxpy speedup w.r.t. serial: {saxpy_serial_speedup**-1:.1f}") 185 | 186 | print(f"cd speedup w.r.t. OpenMP: {cd_OpenMP_speedup**-1:.1f}") 187 | print(f"saxpy speedup w.r.t. OpenMP: {saxpy_OpenMP_speedup**-1:.1f}") 188 | --------------------------------------------------------------------------------