// +build darwin #import #include #include "mtl.h" struct Device CreateSystemDefaultDevice() { id device = MTLCreateSystemDefaultDevice(); if (!device) { struct Device d; d.Device = NULL; return d; } struct Device d; d.Device = device; d.Headless = device.headless; d.LowPower = device.lowPower; d.Removable = device.removable; d.RegistryID = device.registryID; d.Name = device.name.UTF8String; return d; } // Caller must call free(d.devices). struct Devices CopyAllDevices() { NSArray> * devices = MTLCopyAllDevices(); struct Devices d; d.Devices = malloc(devices.count * sizeof(struct Device)); for (int i = 0; i < devices.count; i++) { d.Devices[i].Device = devices[i]; d.Devices[i].Headless = devices[i].headless; d.Devices[i].LowPower = devices[i].lowPower; d.Devices[i].Removable = devices[i].removable; d.Devices[i].RegistryID = devices[i].registryID; d.Devices[i].Name = devices[i].name.UTF8String; } d.Length = devices.count; return d; } BOOL Device_SupportsFeatureSet(void * device, uint16_t featureSet) { return [(id)device supportsFeatureSet:featureSet]; } void * Device_MakeCommandQueue(void * device) { return [(id)device newCommandQueue]; } struct Library Device_MakeLibrary(void * device, const char * source, size_t sourceLength) { NSError * error; id library = [(id)device newLibraryWithSource:[[NSString alloc] initWithBytes:source length:sourceLength encoding:NSUTF8StringEncoding] options:NULL // TODO. error:&error]; struct Library l; l.Library = library; if (!library) { l.Error = error.localizedDescription.UTF8String; } return l; } struct RenderPipelineState Device_MakeRenderPipelineState(void * device, struct RenderPipelineDescriptor descriptor) { MTLRenderPipelineDescriptor * renderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; renderPipelineDescriptor.vertexFunction = descriptor.VertexFunction; renderPipelineDescriptor.fragmentFunction = descriptor.FragmentFunction; renderPipelineDescriptor.colorAttachments[0].pixelFormat = descriptor.ColorAttachment0PixelFormat; NSError * error; id renderPipelineState = [(id)device newRenderPipelineStateWithDescriptor:renderPipelineDescriptor error:&error]; struct RenderPipelineState rps; rps.RenderPipelineState = renderPipelineState; if (!renderPipelineState) { rps.Error = error.localizedDescription.UTF8String; } return rps; } void * Device_MakeBuffer(void * device, const void * bytes, size_t length, uint16_t options) { return [(id)device newBufferWithBytes:(const void *)bytes length:(NSUInteger)length options:(MTLResourceOptions)options]; } void * Device_MakeTexture(void * device, struct TextureDescriptor descriptor) { MTLTextureDescriptor * textureDescriptor = [[MTLTextureDescriptor alloc] init]; textureDescriptor.pixelFormat = descriptor.PixelFormat; textureDescriptor.width = descriptor.Width; textureDescriptor.height = descriptor.Height; textureDescriptor.storageMode = descriptor.StorageMode; return [(id)device newTextureWithDescriptor:textureDescriptor]; } void * CommandQueue_MakeCommandBuffer(void * commandQueue) { return [(id)commandQueue commandBuffer]; } void CommandBuffer_PresentDrawable(void * commandBuffer, void * drawable) { [(id)commandBuffer presentDrawable:(id)drawable]; } void CommandBuffer_Commit(void * commandBuffer) { [(id)commandBuffer commit]; } void CommandBuffer_WaitUntilCompleted(void * commandBuffer) { [(id)commandBuffer waitUntilCompleted]; } void * CommandBuffer_MakeRenderCommandEncoder(void * commandBuffer, struct RenderPassDescriptor descriptor) { MTLRenderPassDescriptor * renderPassDescriptor = [[MTLRenderPassDescriptor alloc] init]; renderPassDescriptor.colorAttachments[0].loadAction = descriptor.ColorAttachment0LoadAction; renderPassDescriptor.colorAttachments[0].storeAction = descriptor.ColorAttachment0StoreAction; renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake( descriptor.ColorAttachment0ClearColor.Red, descriptor.ColorAttachment0ClearColor.Green, descriptor.ColorAttachment0ClearColor.Blue, descriptor.ColorAttachment0ClearColor.Alpha ); renderPassDescriptor.colorAttachments[0].texture = (id)descriptor.ColorAttachment0Texture; return [(id)commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; } void * CommandBuffer_MakeBlitCommandEncoder(void * commandBuffer) { return [(id)commandBuffer blitCommandEncoder]; } void CommandEncoder_EndEncoding(void * commandEncoder) { [(id)commandEncoder endEncoding]; } void RenderCommandEncoder_SetRenderPipelineState(void * renderCommandEncoder, void * renderPipelineState) { [(id)renderCommandEncoder setRenderPipelineState:(id)renderPipelineState]; } void RenderCommandEncoder_SetVertexBuffer(void * renderCommandEncoder, void * buffer, uint_t offset, uint_t index) { [(id)renderCommandEncoder setVertexBuffer:(id)buffer offset:(NSUInteger)offset atIndex:(NSUInteger)index]; } void RenderCommandEncoder_SetVertexBytes(void * renderCommandEncoder, const void * bytes, size_t length, uint_t index) { [(id)renderCommandEncoder setVertexBytes:bytes length:(NSUInteger)length atIndex:(NSUInteger)index]; } void RenderCommandEncoder_DrawPrimitives(void * renderCommandEncoder, uint8_t primitiveType, uint_t vertexStart, uint_t vertexCount) { [(id)renderCommandEncoder drawPrimitives:(MTLPrimitiveType)primitiveType vertexStart:(NSUInteger)vertexStart vertexCount:(NSUInteger)vertexCount]; } void BlitCommandEncoder_CopyFromTexture(void * blitCommandEncoder, void * srcTexture, uint_t srcSlice, uint_t srcLevel, struct Origin srcOrigin, struct Size srcSize, void * dstTexture, uint_t dstSlice, uint_t dstLevel, struct Origin dstOrigin) { [(id)blitCommandEncoder copyFromTexture:(id)srcTexture sourceSlice:(NSUInteger)srcSlice sourceLevel:(NSUInteger)srcLevel sourceOrigin:(MTLOrigin){srcOrigin.X, srcOrigin.Y, srcOrigin.Z} sourceSize:(MTLSize){srcSize.Width, srcSize.Height, srcSize.Depth} toTexture:(id)dstTexture destinationSlice:(NSUInteger)dstSlice destinationLevel:(NSUInteger)dstLevel destinationOrigin:(MTLOrigin){dstOrigin.X, dstOrigin.Y, dstOrigin.Z}]; } void BlitCommandEncoder_Synchronize(void * blitCommandEncoder, void * resource) { [(id)blitCommandEncoder synchronizeResource:(id)resource]; } void * Library_MakeFunction(void * library, const char * name) { return [(id)library newFunctionWithName:[NSString stringWithUTF8String:name]]; } void Texture_ReplaceRegion(void * texture, struct Region region, uint_t level, void * pixelBytes, size_t bytesPerRow) { [(id)texture replaceRegion:(MTLRegion){{region.Origin.X, region.Origin.Y, region.Origin.Z}, {region.Size.Width, region.Size.Height, region.Size.Depth}} mipmapLevel:(NSUInteger)level withBytes:(void *)pixelBytes bytesPerRow:(NSUInteger)bytesPerRow]; } void Texture_GetBytes(void * texture, void * pixelBytes, size_t bytesPerRow, struct Region region, uint_t level) { [(id)texture getBytes:(void *)pixelBytes bytesPerRow:(NSUInteger)bytesPerRow fromRegion:(MTLRegion){{region.Origin.X, region.Origin.Y, region.Origin.Z}, {region.Size.Width, region.Size.Height, region.Size.Depth}} mipmapLevel:(NSUInteger)level]; }