formatting

This commit is contained in:
Stuart Carnie 2018-07-03 22:31:51 -07:00
parent a0900ec433
commit 44ca1062b0
10 changed files with 154 additions and 128 deletions

View File

@ -63,28 +63,28 @@
_library = l; _library = l;
_commandQueue = [_device newCommandQueue]; _commandQueue = [_device newCommandQueue];
_clearColor = MTLClearColorMake(0, 0, 0, 1); _clearColor = MTLClearColorMake(0, 0, 0, 1);
{ {
MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new]; MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
sd.label = @"NEAREST"; sd.label = @"NEAREST";
_samplers[TEXTURE_FILTER_NEAREST] = [d newSamplerStateWithDescriptor:sd]; _samplers[TEXTURE_FILTER_NEAREST] = [d newSamplerStateWithDescriptor:sd];
sd.mipFilter = MTLSamplerMipFilterNearest; sd.mipFilter = MTLSamplerMipFilterNearest;
sd.label = @"MIPMAP_NEAREST"; sd.label = @"MIPMAP_NEAREST";
_samplers[TEXTURE_FILTER_MIPMAP_NEAREST] = [d newSamplerStateWithDescriptor:sd]; _samplers[TEXTURE_FILTER_MIPMAP_NEAREST] = [d newSamplerStateWithDescriptor:sd];
sd.mipFilter = MTLSamplerMipFilterNotMipmapped; sd.mipFilter = MTLSamplerMipFilterNotMipmapped;
sd.minFilter = MTLSamplerMinMagFilterLinear; sd.minFilter = MTLSamplerMinMagFilterLinear;
sd.magFilter = MTLSamplerMinMagFilterLinear; sd.magFilter = MTLSamplerMinMagFilterLinear;
sd.label = @"LINEAR"; sd.label = @"LINEAR";
_samplers[TEXTURE_FILTER_LINEAR] = [d newSamplerStateWithDescriptor:sd]; _samplers[TEXTURE_FILTER_LINEAR] = [d newSamplerStateWithDescriptor:sd];
sd.mipFilter = MTLSamplerMipFilterLinear; sd.mipFilter = MTLSamplerMipFilterLinear;
sd.label = @"MIPMAP_LINEAR"; sd.label = @"MIPMAP_LINEAR";
_samplers[TEXTURE_FILTER_MIPMAP_LINEAR] = [d newSamplerStateWithDescriptor:sd]; _samplers[TEXTURE_FILTER_MIPMAP_LINEAR] = [d newSamplerStateWithDescriptor:sd];
} }
if (![self _initConversionFilters]) if (![self _initConversionFilters])
return nil; return nil;

View File

@ -10,7 +10,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
@protocol FilterDelegate @protocol FilterDelegate
-(void)configure:(id<MTLCommandEncoder>)encoder; - (void)configure:(id<MTLCommandEncoder>)encoder;
@end @end
@interface Filter : NSObject @interface Filter : NSObject
@ -18,9 +18,9 @@
@property (nonatomic, readwrite) id<FilterDelegate> delegate; @property (nonatomic, readwrite) id<FilterDelegate> delegate;
@property (nonatomic, readonly) id<MTLSamplerState> sampler; @property (nonatomic, readonly) id<MTLSamplerState> sampler;
-(void)apply:(id<MTLCommandBuffer>)cb in:(id<MTLTexture>)tin out:(id<MTLTexture>)tout; - (void)apply:(id<MTLCommandBuffer>)cb in:(id<MTLTexture>)tin out:(id<MTLTexture>)tout;
-(void)apply:(id<MTLCommandBuffer>)cb inBuf:(id<MTLBuffer>)tin outTex:(id<MTLTexture>)tout; - (void)apply:(id<MTLCommandBuffer>)cb inBuf:(id<MTLBuffer>)tin outTex:(id<MTLTexture>)tout;
+(instancetype)newFilterWithFunctionName:(NSString *)name device:(id<MTLDevice>)device library:(id<MTLLibrary>)library error:(NSError **)error; + (instancetype)newFilterWithFunctionName:(NSString *)name device:(id<MTLDevice>)device library:(id<MTLLibrary>)library error:(NSError **)error;
@end @end

View File

@ -10,79 +10,87 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
@interface Filter() @interface Filter()
-( instancetype)initWithKernel:(id<MTLComputePipelineState>)kernel sampler:(id<MTLSamplerState>)sampler; - (instancetype)initWithKernel:(id<MTLComputePipelineState>)kernel sampler:(id<MTLSamplerState>)sampler;
@end @end
@implementation Filter { @implementation Filter
id<MTLComputePipelineState> _kernel; {
id<MTLComputePipelineState> _kernel;
} }
+(instancetype)newFilterWithFunctionName:(NSString *)name device:(id<MTLDevice>)device library:(id<MTLLibrary>)library error:(NSError **)error { + (instancetype)newFilterWithFunctionName:(NSString *)name device:(id<MTLDevice>)device library:(id<MTLLibrary>)library error:(NSError **)error
id<MTLFunction> function = [library newFunctionWithName:name]; {
id<MTLComputePipelineState> kernel = [device newComputePipelineStateWithFunction:function error:error]; id<MTLFunction> function = [library newFunctionWithName:name];
if (*error != nil) { id<MTLComputePipelineState> kernel = [device newComputePipelineStateWithFunction:function error:error];
return nil; if (*error != nil)
} {
return nil;
MTLSamplerDescriptor * sd = [MTLSamplerDescriptor new]; }
sd.minFilter = MTLSamplerMinMagFilterNearest;
sd.magFilter = MTLSamplerMinMagFilterNearest; MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
sd.sAddressMode = MTLSamplerAddressModeClampToEdge; sd.minFilter = MTLSamplerMinMagFilterNearest;
sd.tAddressMode = MTLSamplerAddressModeClampToEdge; sd.magFilter = MTLSamplerMinMagFilterNearest;
sd.mipFilter = MTLSamplerMipFilterNotMipmapped; sd.sAddressMode = MTLSamplerAddressModeClampToEdge;
id<MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:sd]; sd.tAddressMode = MTLSamplerAddressModeClampToEdge;
sd.mipFilter = MTLSamplerMipFilterNotMipmapped;
return [[Filter alloc] initWithKernel:kernel sampler:sampler]; id<MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:sd];
return [[Filter alloc] initWithKernel:kernel sampler:sampler];
} }
-( instancetype)initWithKernel:(id<MTLComputePipelineState>)kernel sampler:(id<MTLSamplerState>)sampler { - (instancetype)initWithKernel:(id<MTLComputePipelineState>)kernel sampler:(id<MTLSamplerState>)sampler
if (self = [super init]) { {
_kernel = kernel; if (self = [super init])
_sampler = sampler; {
} _kernel = kernel;
return self; _sampler = sampler;
}
return self;
} }
-(void)apply:(id<MTLCommandBuffer>)cb in:(id<MTLTexture>)tin out:(id<MTLTexture>)tout { - (void)apply:(id<MTLCommandBuffer>)cb in:(id<MTLTexture>)tin out:(id<MTLTexture>)tout
id<MTLComputeCommandEncoder> ce = [cb computeCommandEncoder]; {
ce.label = @"filter kernel"; id<MTLComputeCommandEncoder> ce = [cb computeCommandEncoder];
[ce pushDebugGroup:@"filter kernel"]; ce.label = @"filter kernel";
[ce pushDebugGroup:@"filter kernel"];
[ce setComputePipelineState:_kernel];
[ce setComputePipelineState:_kernel];
[ce setTexture:tin atIndex:0];
[ce setTexture:tout atIndex:1]; [ce setTexture:tin atIndex:0];
[ce setTexture:tout atIndex:1];
[self.delegate configure:ce];
[self.delegate configure:ce];
MTLSize size = MTLSizeMake(16, 16, 1);
MTLSize count = MTLSizeMake((tin.width + size.width + 1) / size.width, (tin.height + size.height + 1) / size.height, 1); MTLSize size = MTLSizeMake(16, 16, 1);
MTLSize count = MTLSizeMake((tin.width + size.width + 1) / size.width, (tin.height + size.height + 1) / size.height,
[ce dispatchThreadgroups:count threadsPerThreadgroup:size]; 1);
[ce popDebugGroup]; [ce dispatchThreadgroups:count threadsPerThreadgroup:size];
[ce endEncoding];
[ce popDebugGroup];
[ce endEncoding];
} }
-(void)apply:(id<MTLCommandBuffer>)cb inBuf:(id<MTLBuffer>)tin outTex:(id<MTLTexture>)tout { - (void)apply:(id<MTLCommandBuffer>)cb inBuf:(id<MTLBuffer>)tin outTex:(id<MTLTexture>)tout
id<MTLComputeCommandEncoder> ce = [cb computeCommandEncoder]; {
ce.label = @"filter kernel"; id<MTLComputeCommandEncoder> ce = [cb computeCommandEncoder];
[ce pushDebugGroup:@"filter kernel"]; ce.label = @"filter kernel";
[ce pushDebugGroup:@"filter kernel"];
[ce setComputePipelineState:_kernel];
[ce setComputePipelineState:_kernel];
[ce setBuffer:tin offset:0 atIndex:0];
[ce setTexture:tout atIndex:0]; [ce setBuffer:tin offset:0 atIndex:0];
[ce setTexture:tout atIndex:0];
[self.delegate configure:ce];
[self.delegate configure:ce];
MTLSize size = MTLSizeMake(32, 1, 1);
MTLSize count = MTLSizeMake((tin.length + 00) / 32, 1, 1); MTLSize size = MTLSizeMake(32, 1, 1);
MTLSize count = MTLSizeMake((tin.length + 00) / 32, 1, 1);
[ce dispatchThreadgroups:count threadsPerThreadgroup:size];
[ce dispatchThreadgroups:count threadsPerThreadgroup:size];
[ce popDebugGroup];
[ce endEncoding]; [ce popDebugGroup];
[ce endEncoding];
} }
@end @end

View File

@ -27,7 +27,8 @@
#pragma mark - Pixel Formats #pragma mark - Pixel Formats
typedef NS_ENUM(NSUInteger, RPixelFormat) { typedef NS_ENUM(NSUInteger, RPixelFormat)
{
RPixelFormatInvalid, RPixelFormatInvalid,
@ -44,7 +45,8 @@ typedef NS_ENUM(NSUInteger, RPixelFormat) {
extern NSUInteger RPixelFormatToBPP(RPixelFormat format); extern NSUInteger RPixelFormatToBPP(RPixelFormat format);
extern NSString *NSStringFromRPixelFormat(RPixelFormat format); extern NSString *NSStringFromRPixelFormat(RPixelFormat format);
typedef NS_ENUM(NSUInteger, RTextureFilter) { typedef NS_ENUM(NSUInteger, RTextureFilter)
{
RTextureFilterNearest, RTextureFilterNearest,
RTextureFilterLinear, RTextureFilterLinear,

View File

@ -11,15 +11,16 @@
NSUInteger RPixelFormatToBPP(RPixelFormat format) NSUInteger RPixelFormatToBPP(RPixelFormat format)
{ {
switch (format) { switch (format)
{
case RPixelFormatBGRA8Unorm: case RPixelFormatBGRA8Unorm:
case RPixelFormatBGRX8Unorm: case RPixelFormatBGRX8Unorm:
return 4; return 4;
case RPixelFormatB5G6R5Unorm: case RPixelFormatB5G6R5Unorm:
case RPixelFormatBGRA4Unorm: case RPixelFormatBGRA4Unorm:
return 2; return 2;
default: default:
RARCH_ERR("[Metal]: unknown RPixel format: %d\n", format); RARCH_ERR("[Metal]: unknown RPixel format: %d\n", format);
return 4; return 4;
@ -40,13 +41,14 @@ NSString *NSStringFromRPixelFormat(RPixelFormat format)
STRING(RPixelFormatBGRA8Unorm); STRING(RPixelFormatBGRA8Unorm);
STRING(RPixelFormatBGRX8Unorm); STRING(RPixelFormatBGRX8Unorm);
#undef STRING #undef STRING
}); });
if (format >= RPixelFormatCount) { if (format >= RPixelFormatCount)
{
format = RPixelFormatInvalid; format = RPixelFormatInvalid;
} }
return RPixelStrings[format]; return RPixelStrings[format];
} }
@ -54,19 +56,19 @@ matrix_float4x4 matrix_proj_ortho(float left, float right, float top, float bott
{ {
float near = 0; float near = 0;
float far = 1; float far = 1;
float sx = 2 / (right - left); float sx = 2 / (right - left);
float sy = 2 / (top - bottom); float sy = 2 / (top - bottom);
float sz = 1 / (far - near); float sz = 1 / (far - near);
float tx = (right + left) / (left - right); float tx = (right + left) / (left - right);
float ty = (top + bottom) / (bottom - top); float ty = (top + bottom) / (bottom - top);
float tz = near / (far - near); float tz = near / (far - near);
simd_float4 P = simd_make_float4(sx, 0, 0, 0); simd_float4 P = simd_make_float4(sx, 0, 0, 0);
simd_float4 Q = simd_make_float4(0, sy, 0, 0); simd_float4 Q = simd_make_float4(0, sy, 0, 0);
simd_float4 R = simd_make_float4(0, 0, sz, 0); simd_float4 R = simd_make_float4(0, 0, sz, 0);
simd_float4 S = simd_make_float4(tx, ty, tz, 1); simd_float4 S = simd_make_float4(tx, ty, tz, 1);
matrix_float4x4 mat = {P, Q, R, S}; matrix_float4x4 mat = {P, Q, R, S};
return mat; return mat;
} }

View File

@ -17,7 +17,7 @@
CGSize _size; // size of view in pixels CGSize _size; // size of view in pixels
CGRect _frame; CGRect _frame;
NSUInteger _bpp; NSUInteger _bpp;
id<MTLBuffer> _pixels; // frame buffer in _srcFmt id<MTLBuffer> _pixels; // frame buffer in _srcFmt
bool _pixelsDirty; bool _pixelsDirty;
} }
@ -25,15 +25,19 @@
- (instancetype)initWithDescriptor:(ViewDescriptor *)d context:(Context *)c - (instancetype)initWithDescriptor:(ViewDescriptor *)d context:(Context *)c
{ {
self = [super init]; self = [super init];
if (self) { if (self)
{
_format = d.format; _format = d.format;
_bpp = RPixelFormatToBPP(_format); _bpp = RPixelFormatToBPP(_format);
_filter = d.filter; _filter = d.filter;
_context = c; _context = c;
_visible = YES; _visible = YES;
if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm) { if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm)
{
_drawState = ViewDrawStateEncoder; _drawState = ViewDrawStateEncoder;
} else { }
else
{
_drawState = ViewDrawStateAll; _drawState = ViewDrawStateAll;
} }
self.size = d.size; self.size = d.size;
@ -44,12 +48,13 @@
- (void)setSize:(CGSize)size - (void)setSize:(CGSize)size
{ {
if (CGSizeEqualToSize(_size, size)) { if (CGSizeEqualToSize(_size, size))
{
return; return;
} }
_size = size; _size = size;
// create new texture // create new texture
{ {
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
@ -59,8 +64,9 @@
td.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite; td.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
_texture = [_context.device newTextureWithDescriptor:td]; _texture = [_context.device newTextureWithDescriptor:td];
} }
if (_format != RPixelFormatBGRA8Unorm && _format != RPixelFormatBGRX8Unorm) { if (_format != RPixelFormatBGRA8Unorm && _format != RPixelFormatBGRX8Unorm)
{
_pixels = [_context.device newBufferWithLength:(NSUInteger)(size.width * size.height * 2) _pixels = [_context.device newBufferWithLength:(NSUInteger)(size.width * size.height * 2)
options:MTLResourceStorageModeManaged]; options:MTLResourceStorageModeManaged];
} }
@ -73,21 +79,22 @@
- (void)setFrame:(CGRect)frame - (void)setFrame:(CGRect)frame
{ {
if (CGRectEqualToRect(_frame, frame)) { if (CGRectEqualToRect(_frame, frame))
{
return; return;
} }
_frame = frame; _frame = frame;
// update vertices // update vertices
CGPoint o = frame.origin; CGPoint o = frame.origin;
CGSize s = frame.size; CGSize s = frame.size;
float l = o.x; float l = o.x;
float t = o.y; float t = o.y;
float r = o.x + s.width; float r = o.x + s.width;
float b = o.y + s.height; float b = o.y + s.height;
Vertex v[4] = { Vertex v[4] = {
{{l, b, 0}, {0, 1}}, {{l, b, 0}, {0, 1}},
{{r, b, 0}, {1, 1}}, {{r, b, 0}, {1, 1}},
@ -106,15 +113,16 @@
{ {
if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm) if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm)
return; return;
if (!_pixelsDirty) if (!_pixelsDirty)
return; return;
[_context convertFormat:_format from:_pixels to:_texture]; [_context convertFormat:_format from:_pixels to:_texture];
_pixelsDirty = NO; _pixelsDirty = NO;
} }
- (void)drawWithContext:(Context *)ctx { - (void)drawWithContext:(Context *)ctx
{
[self _convertFormat]; [self _convertFormat];
} }
@ -127,27 +135,32 @@
- (void)updateFrame:(void const *)src pitch:(NSUInteger)pitch - (void)updateFrame:(void const *)src pitch:(NSUInteger)pitch
{ {
if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm) { if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm)
{
[_texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)_size.width, (NSUInteger)_size.height) [_texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)_size.width, (NSUInteger)_size.height)
mipmapLevel:0 withBytes:src mipmapLevel:0 withBytes:src
bytesPerRow:(NSUInteger)(4 * pitch)]; bytesPerRow:(NSUInteger)(4 * pitch)];
} }
else { else
{
void *dst = _pixels.contents; void *dst = _pixels.contents;
size_t len = (size_t)(_bpp * _size.width); size_t len = (size_t)(_bpp * _size.width);
assert(len <= pitch); // the length can't be larger? assert(len <= pitch); // the length can't be larger?
if (len < pitch) { if (len < pitch)
for (int i = 0; i < _size.height; i++) { {
for (int i = 0; i < _size.height; i++)
{
memcpy(dst, src, len); memcpy(dst, src, len);
dst += len; dst += len;
src += pitch; src += pitch;
} }
} }
else { else
{
memcpy(dst, src, _pixels.length); memcpy(dst, src, _pixels.length);
} }
[_pixels didModifyRange:NSMakeRange(0, _pixels.length)]; [_pixels didModifyRange:NSMakeRange(0, _pixels.length)];
_pixelsDirty = YES; _pixelsDirty = YES;
} }

View File

@ -12,11 +12,11 @@
typedef NS_ENUM(NSInteger, ViewDrawState) typedef NS_ENUM(NSInteger, ViewDrawState)
{ {
ViewDrawStateNone = 0x00, ViewDrawStateNone = 0x00,
ViewDrawStateContext = 0x01, ViewDrawStateContext = 0x01,
ViewDrawStateEncoder = 0x02, ViewDrawStateEncoder = 0x02,
ViewDrawStateAll = 0x03, ViewDrawStateAll = 0x03,
}; };
@interface ViewDescriptor : NSObject @interface ViewDescriptor : NSObject

View File

@ -14,7 +14,8 @@
- (instancetype)init - (instancetype)init
{ {
self = [super init]; self = [super init];
if (self) { if (self)
{
_format = RPixelFormatBGRA8Unorm; _format = RPixelFormatBGRA8Unorm;
} }
return self; return self;

View File

@ -34,8 +34,8 @@ extern MTLPixelFormat SelectOptimalPixelFormat(MTLPixelFormat fmt);
@property (nonatomic, readwrite) CGRect frame; @property (nonatomic, readwrite) CGRect frame;
@property (nonatomic, readwrite) CGSize size; @property (nonatomic, readwrite) CGSize size;
@property (nonatomic, readonly) ViewDrawState drawState; @property (nonatomic, readonly) ViewDrawState drawState;
@property (nonatomic, readonly) struct video_shader* shader; @property (nonatomic, readonly) struct video_shader *shader;
@property (nonatomic, readwrite) uint64_t frameCount; @property (nonatomic, readwrite) uint64_t frameCount;
- (void)setFilteringIndex:(int)index smooth:(bool)smooth; - (void)setFilteringIndex:(int)index smooth:(bool)smooth;
- (BOOL)setShaderFromPath:(NSString *)path; - (BOOL)setShaderFromPath:(NSString *)path;
@ -60,14 +60,14 @@ extern MTLPixelFormat SelectOptimalPixelFormat(MTLPixelFormat fmt);
@interface MetalDriver : NSObject<MTKViewDelegate> @interface MetalDriver : NSObject<MTKViewDelegate>
@property (nonatomic, readonly) video_viewport_t* viewport; @property (nonatomic, readonly) video_viewport_t *viewport;
@property (nonatomic, readwrite) bool keepAspect; @property (nonatomic, readwrite) bool keepAspect;
@property (nonatomic, readonly) MetalMenu* menu; @property (nonatomic, readonly) MetalMenu *menu;
@property (nonatomic, readonly) FrameView* frameView; @property (nonatomic, readonly) FrameView *frameView;
@property (nonatomic, readonly) MenuDisplay* display; @property (nonatomic, readonly) MenuDisplay *display;
@property (nonatomic, readonly) Context* context; @property (nonatomic, readonly) Context *context;
@property (nonatomic, readonly) Uniforms* viewportMVP; @property (nonatomic, readonly) Uniforms *viewportMVP;
@property (nonatomic, readonly) Uniforms* viewportMVPNormalized; @property (nonatomic, readonly) Uniforms *viewportMVPNormalized;
- (instancetype)initWithVideo:(const video_info_t *)video - (instancetype)initWithVideo:(const video_info_t *)video
input:(const input_driver_t **)input input:(const input_driver_t **)input

View File

@ -249,9 +249,9 @@
RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String); RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String);
return NO; return NO;
} }
MTLFunctionConstantValues *vals; MTLFunctionConstantValues *vals;
psd.label = @"snow_simple"; psd.label = @"snow_simple";
ca.blendingEnabled = YES; ca.blendingEnabled = YES;
{ {
@ -272,7 +272,7 @@
RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String); RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String);
return NO; return NO;
} }
psd.label = @"snow"; psd.label = @"snow";
ca.blendingEnabled = YES; ca.blendingEnabled = YES;
{ {
@ -293,7 +293,7 @@
RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String); RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String);
return NO; return NO;
} }
psd.label = @"bokeh"; psd.label = @"bokeh";
ca.blendingEnabled = YES; ca.blendingEnabled = YES;
psd.fragmentFunction = [_library newFunctionWithName:@"bokeh_fragment"]; psd.fragmentFunction = [_library newFunctionWithName:@"bokeh_fragment"];
@ -303,7 +303,7 @@
RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String); RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String);
return NO; return NO;
} }
psd.label = @"snowflake"; psd.label = @"snowflake";
ca.blendingEnabled = YES; ca.blendingEnabled = YES;
psd.fragmentFunction = [_library newFunctionWithName:@"snowflake_fragment"]; psd.fragmentFunction = [_library newFunctionWithName:@"snowflake_fragment"];
@ -313,7 +313,7 @@
RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String); RARCH_ERR("[Metal]: error creating pipeline state %s\n", err.localizedDescription.UTF8String);
return NO; return NO;
} }
psd.label = @"ribbon"; psd.label = @"ribbon";
ca.blendingEnabled = NO; ca.blendingEnabled = NO;
psd.vertexFunction = [_library newFunctionWithName:@"ribbon_vertex"]; psd.vertexFunction = [_library newFunctionWithName:@"ribbon_vertex"];