You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
NoiseTorch/vendor/dmitri.shuralyov.com/gpu/mtl/mtl.m

194 lines
8.6 KiB
Objective-C

// +build darwin
#import <Metal/Metal.h>
#include <stdlib.h>
#include "mtl.h"
struct Device CreateSystemDefaultDevice() {
id<MTLDevice> 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<id<MTLDevice>> * 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<MTLDevice>)device supportsFeatureSet:featureSet];
}
void * Device_MakeCommandQueue(void * device) {
return [(id<MTLDevice>)device newCommandQueue];
}
struct Library Device_MakeLibrary(void * device, const char * source, size_t sourceLength) {
NSError * error;
id<MTLLibrary> library = [(id<MTLDevice>)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<MTLRenderPipelineState> renderPipelineState = [(id<MTLDevice>)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<MTLDevice>)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<MTLDevice>)device newTextureWithDescriptor:textureDescriptor];
}
void * CommandQueue_MakeCommandBuffer(void * commandQueue) {
return [(id<MTLCommandQueue>)commandQueue commandBuffer];
}
void CommandBuffer_PresentDrawable(void * commandBuffer, void * drawable) {
[(id<MTLCommandBuffer>)commandBuffer presentDrawable:(id<MTLDrawable>)drawable];
}
void CommandBuffer_Commit(void * commandBuffer) {
[(id<MTLCommandBuffer>)commandBuffer commit];
}
void CommandBuffer_WaitUntilCompleted(void * commandBuffer) {
[(id<MTLCommandBuffer>)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<MTLTexture>)descriptor.ColorAttachment0Texture;
return [(id<MTLCommandBuffer>)commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
}
void * CommandBuffer_MakeBlitCommandEncoder(void * commandBuffer) {
return [(id<MTLCommandBuffer>)commandBuffer blitCommandEncoder];
}
void CommandEncoder_EndEncoding(void * commandEncoder) {
[(id<MTLCommandEncoder>)commandEncoder endEncoding];
}
void RenderCommandEncoder_SetRenderPipelineState(void * renderCommandEncoder, void * renderPipelineState) {
[(id<MTLRenderCommandEncoder>)renderCommandEncoder setRenderPipelineState:(id<MTLRenderPipelineState>)renderPipelineState];
}
void RenderCommandEncoder_SetVertexBuffer(void * renderCommandEncoder, void * buffer, uint_t offset, uint_t index) {
[(id<MTLRenderCommandEncoder>)renderCommandEncoder setVertexBuffer:(id<MTLBuffer>)buffer
offset:(NSUInteger)offset
atIndex:(NSUInteger)index];
}
void RenderCommandEncoder_SetVertexBytes(void * renderCommandEncoder, const void * bytes, size_t length, uint_t index) {
[(id<MTLRenderCommandEncoder>)renderCommandEncoder setVertexBytes:bytes
length:(NSUInteger)length
atIndex:(NSUInteger)index];
}
void RenderCommandEncoder_DrawPrimitives(void * renderCommandEncoder, uint8_t primitiveType, uint_t vertexStart, uint_t vertexCount) {
[(id<MTLRenderCommandEncoder>)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<MTLBlitCommandEncoder>)blitCommandEncoder copyFromTexture:(id<MTLTexture>)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<MTLTexture>)dstTexture
destinationSlice:(NSUInteger)dstSlice
destinationLevel:(NSUInteger)dstLevel
destinationOrigin:(MTLOrigin){dstOrigin.X, dstOrigin.Y, dstOrigin.Z}];
}
void BlitCommandEncoder_Synchronize(void * blitCommandEncoder, void * resource) {
[(id<MTLBlitCommandEncoder>)blitCommandEncoder synchronizeResource:(id<MTLResource>)resource];
}
void * Library_MakeFunction(void * library, const char * name) {
return [(id<MTLLibrary>)library newFunctionWithName:[NSString stringWithUTF8String:name]];
}
void Texture_ReplaceRegion(void * texture, struct Region region, uint_t level, void * pixelBytes, size_t bytesPerRow) {
[(id<MTLTexture>)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<MTLTexture>)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];
}