formatting
This commit is contained in:
parent
a0900ec433
commit
44ca1062b0
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"];
|
||||||
|
|
Loading…
Reference in New Issue