mirror of
https://github.com/libretro/RetroArch
synced 2025-03-20 19:21:27 +00:00
(Metal common) Cleanups
This commit is contained in:
parent
86dccbf1d6
commit
13ac88c9df
@ -57,21 +57,12 @@
|
|||||||
@implementation MetalView
|
@implementation MetalView
|
||||||
|
|
||||||
#if !defined(HAVE_COCOATOUCH)
|
#if !defined(HAVE_COCOATOUCH)
|
||||||
- (void)keyDown:(NSEvent*)theEvent
|
- (void)keyDown:(NSEvent*)theEvent { }
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Stop the annoying sound when pressing a key. */
|
/* Stop the annoying sound when pressing a key. */
|
||||||
- (BOOL)acceptsFirstResponder
|
- (BOOL)acceptsFirstResponder { return YES; }
|
||||||
{
|
- (BOOL)isFlipped { return YES; }
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isFlipped
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#pragma mark - private categories
|
#pragma mark - private categories
|
||||||
@ -110,14 +101,14 @@
|
|||||||
|
|
||||||
CAMetalLayer *_layer;
|
CAMetalLayer *_layer;
|
||||||
|
|
||||||
// render target layer state
|
/* Render target layer state */
|
||||||
id<MTLRenderPipelineState> _t_pipelineState;
|
id<MTLRenderPipelineState> _t_pipelineState;
|
||||||
id<MTLRenderPipelineState> _t_pipelineStateNoAlpha;
|
id<MTLRenderPipelineState> _t_pipelineStateNoAlpha;
|
||||||
|
|
||||||
id<MTLSamplerState> _samplerStateLinear;
|
id<MTLSamplerState> _samplerStateLinear;
|
||||||
id<MTLSamplerState> _samplerStateNearest;
|
id<MTLSamplerState> _samplerStateNearest;
|
||||||
|
|
||||||
// other state
|
/* other state */
|
||||||
Uniforms _viewportMVP;
|
Uniforms _viewportMVP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,22 +118,20 @@
|
|||||||
{
|
{
|
||||||
if (self = [super init])
|
if (self = [super init])
|
||||||
{
|
{
|
||||||
_device = MTLCreateSystemDefaultDevice();
|
_device = MTLCreateSystemDefaultDevice();
|
||||||
MetalView *view = (MetalView *)apple_platform.renderView;
|
MetalView *view = (MetalView *)apple_platform.renderView;
|
||||||
view.device = _device;
|
view.device = _device;
|
||||||
view.delegate = self;
|
view.delegate = self;
|
||||||
_layer = (CAMetalLayer *)view.layer;
|
_layer = (CAMetalLayer *)view.layer;
|
||||||
|
|
||||||
if (![self _initMetal])
|
if (![self _initMetal])
|
||||||
{
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
|
||||||
|
|
||||||
_video = *video;
|
_video = *video;
|
||||||
_viewport = (video_viewport_t *)calloc(1, sizeof(video_viewport_t));
|
_viewport = (video_viewport_t *)calloc(1, sizeof(video_viewport_t));
|
||||||
_viewportMVP.projectionMatrix = matrix_proj_ortho(0, 1, 0, 1);
|
_viewportMVP.projectionMatrix = matrix_proj_ortho(0, 1, 0, 1);
|
||||||
|
|
||||||
_keepAspect = _video.force_aspect;
|
_keepAspect = _video.force_aspect;
|
||||||
|
|
||||||
gfx_ctx_mode_t mode = {
|
gfx_ctx_mode_t mode = {
|
||||||
.width = _video.width,
|
.width = _video.width,
|
||||||
@ -155,33 +144,31 @@
|
|||||||
// 0 indicates full screen, so we'll use the view's dimensions, which should already be full screen
|
// 0 indicates full screen, so we'll use the view's dimensions, which should already be full screen
|
||||||
// If this turns out to be the wrong assumption, we can use NSScreen to query the dimensions
|
// If this turns out to be the wrong assumption, we can use NSScreen to query the dimensions
|
||||||
CGSize size = view.frame.size;
|
CGSize size = view.frame.size;
|
||||||
mode.width = (unsigned int)size.width;
|
mode.width = (unsigned int)size.width;
|
||||||
mode.height = (unsigned int)size.height;
|
mode.height = (unsigned int)size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
[apple_platform setVideoMode:mode];
|
[apple_platform setVideoMode:mode];
|
||||||
|
|
||||||
*input = NULL;
|
*input = NULL;
|
||||||
*inputData = NULL;
|
*inputData = NULL;
|
||||||
|
/* graphics display driver */
|
||||||
|
_display = [[MenuDisplay alloc] initWithContext:_context];
|
||||||
|
/* menu view */
|
||||||
|
_menu = [[MetalMenu alloc] initWithContext:_context];
|
||||||
|
|
||||||
// graphics display driver
|
/* Framebuffer view */
|
||||||
_display = [[MenuDisplay alloc] initWithContext:_context];
|
|
||||||
|
|
||||||
// menu view
|
|
||||||
_menu = [[MetalMenu alloc] initWithContext:_context];
|
|
||||||
|
|
||||||
// frame buffer view
|
|
||||||
{
|
{
|
||||||
ViewDescriptor *vd = [ViewDescriptor new];
|
ViewDescriptor *vd = [ViewDescriptor new];
|
||||||
vd.format = _video.rgb32 ? RPixelFormatBGRX8Unorm : RPixelFormatB5G6R5Unorm;
|
vd.format = _video.rgb32 ? RPixelFormatBGRX8Unorm : RPixelFormatB5G6R5Unorm;
|
||||||
vd.size = CGSizeMake(video->width, video->height);
|
vd.size = CGSizeMake(video->width, video->height);
|
||||||
vd.filter = _video.smooth ? RTextureFilterLinear : RTextureFilterNearest;
|
vd.filter = _video.smooth ? RTextureFilterLinear : RTextureFilterNearest;
|
||||||
_frameView = [[FrameView alloc] initWithDescriptor:vd context:_context];
|
_frameView = [[FrameView alloc] initWithDescriptor:vd context:_context];
|
||||||
_frameView.viewport = _viewport;
|
_frameView.viewport = _viewport;
|
||||||
[_frameView setFilteringIndex:0 smooth:video->smooth];
|
[_frameView setFilteringIndex:0 smooth:video->smooth];
|
||||||
}
|
}
|
||||||
|
|
||||||
// overlay view
|
/* Overlay view */
|
||||||
_overlay = [[Overlay alloc] initWithContext:_context];
|
_overlay = [[Overlay alloc] initWithContext:_context];
|
||||||
|
|
||||||
font_driver_init_osd((__bridge void *)self,
|
font_driver_init_osd((__bridge void *)self,
|
||||||
@ -211,30 +198,33 @@
|
|||||||
library:_library];
|
library:_library];
|
||||||
|
|
||||||
{
|
{
|
||||||
MTLVertexDescriptor *vd = [MTLVertexDescriptor new];
|
|
||||||
vd.attributes[0].offset = 0;
|
|
||||||
vd.attributes[0].format = MTLVertexFormatFloat3;
|
|
||||||
vd.attributes[1].offset = offsetof(Vertex, texCoord);
|
|
||||||
vd.attributes[1].format = MTLVertexFormatFloat2;
|
|
||||||
vd.layouts[0].stride = sizeof(Vertex);
|
|
||||||
|
|
||||||
MTLRenderPipelineDescriptor *psd = [MTLRenderPipelineDescriptor new];
|
|
||||||
psd.label = @"Pipeline+Alpha";
|
|
||||||
|
|
||||||
MTLRenderPipelineColorAttachmentDescriptor *ca = psd.colorAttachments[0];
|
|
||||||
ca.pixelFormat = _layer.pixelFormat;
|
|
||||||
ca.blendingEnabled = YES;
|
|
||||||
ca.sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
|
|
||||||
ca.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
|
||||||
ca.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
|
||||||
ca.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
|
||||||
|
|
||||||
psd.sampleCount = 1;
|
|
||||||
psd.vertexDescriptor = vd;
|
|
||||||
psd.vertexFunction = [_library newFunctionWithName:@"basic_vertex_proj_tex"];
|
|
||||||
psd.fragmentFunction = [_library newFunctionWithName:@"basic_fragment_proj_tex"];
|
|
||||||
|
|
||||||
NSError *err;
|
NSError *err;
|
||||||
|
MTLRenderPipelineDescriptor *psd;
|
||||||
|
MTLRenderPipelineColorAttachmentDescriptor *ca;
|
||||||
|
MTLVertexDescriptor *vd = [MTLVertexDescriptor new];
|
||||||
|
vd.attributes[0].offset = 0;
|
||||||
|
vd.attributes[0].format = MTLVertexFormatFloat3;
|
||||||
|
vd.attributes[1].offset = offsetof(Vertex, texCoord);
|
||||||
|
vd.attributes[1].format = MTLVertexFormatFloat2;
|
||||||
|
vd.layouts[0].stride = sizeof(Vertex);
|
||||||
|
|
||||||
|
psd = [MTLRenderPipelineDescriptor new];
|
||||||
|
psd.label = @"Pipeline+Alpha";
|
||||||
|
|
||||||
|
ca = psd.colorAttachments[0];
|
||||||
|
ca.pixelFormat = _layer.pixelFormat;
|
||||||
|
ca.blendingEnabled = YES;
|
||||||
|
ca.sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
|
||||||
|
ca.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
||||||
|
ca.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||||
|
ca.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||||
|
|
||||||
|
psd.sampleCount = 1;
|
||||||
|
psd.vertexDescriptor = vd;
|
||||||
|
psd.vertexFunction = [_library newFunctionWithName:@"basic_vertex_proj_tex"];
|
||||||
|
psd.fragmentFunction = [_library newFunctionWithName:@"basic_fragment_proj_tex"];
|
||||||
|
|
||||||
|
|
||||||
_t_pipelineState = [_device newRenderPipelineStateWithDescriptor:psd error:&err];
|
_t_pipelineState = [_device newRenderPipelineStateWithDescriptor:psd error:&err];
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
@ -242,8 +232,8 @@
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
psd.label = @"Pipeline+No Alpha";
|
psd.label = @"Pipeline+No Alpha";
|
||||||
ca.blendingEnabled = NO;
|
ca.blendingEnabled = NO;
|
||||||
_t_pipelineStateNoAlpha = [_device newRenderPipelineStateWithDescriptor:psd error:&err];
|
_t_pipelineStateNoAlpha = [_device newRenderPipelineStateWithDescriptor:psd error:&err];
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
@ -254,11 +244,11 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
|
MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
|
||||||
_samplerStateNearest = [_device newSamplerStateWithDescriptor:sd];
|
_samplerStateNearest = [_device newSamplerStateWithDescriptor:sd];
|
||||||
|
|
||||||
sd.minFilter = MTLSamplerMinMagFilterLinear;
|
sd.minFilter = MTLSamplerMinMagFilterLinear;
|
||||||
sd.magFilter = MTLSamplerMinMagFilterLinear;
|
sd.magFilter = MTLSamplerMinMagFilterLinear;
|
||||||
_samplerStateLinear = [_device newSamplerStateWithDescriptor:sd];
|
_samplerStateLinear = [_device newSamplerStateWithDescriptor:sd];
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
@ -266,24 +256,18 @@
|
|||||||
|
|
||||||
- (void)setViewportWidth:(unsigned)width height:(unsigned)height forceFull:(BOOL)forceFull allowRotate:(BOOL)allowRotate
|
- (void)setViewportWidth:(unsigned)width height:(unsigned)height forceFull:(BOOL)forceFull allowRotate:(BOOL)allowRotate
|
||||||
{
|
{
|
||||||
_viewport->full_width = width;
|
_viewport->full_width = width;
|
||||||
_viewport->full_height = height;
|
_viewport->full_height = height;
|
||||||
video_driver_set_size(_viewport->full_width, _viewport->full_height);
|
video_driver_set_size(_viewport->full_width, _viewport->full_height);
|
||||||
_layer.drawableSize = CGSizeMake(width, height);
|
_layer.drawableSize = CGSizeMake(width, height);
|
||||||
video_driver_update_viewport(_viewport, forceFull, _keepAspect);
|
video_driver_update_viewport(_viewport, forceFull, _keepAspect);
|
||||||
|
_context.viewport = _viewport; /* Update matrix */
|
||||||
// update matrix
|
|
||||||
_context.viewport = _viewport;
|
|
||||||
|
|
||||||
_viewportMVP.outputSize = simd_make_float2(_viewport->full_width, _viewport->full_height);
|
_viewportMVP.outputSize = simd_make_float2(_viewport->full_width, _viewport->full_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - video
|
#pragma mark - video
|
||||||
|
|
||||||
- (void)setVideo:(const video_info_t *)video
|
- (void)setVideo:(const video_info_t *)video { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (bool)renderFrame:(const void *)frame
|
- (bool)renderFrame:(const void *)frame
|
||||||
data:(void*)data
|
data:(void*)data
|
||||||
@ -427,13 +411,9 @@
|
|||||||
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
|
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
|
||||||
[rce setRenderPipelineState:_t_pipelineStateNoAlpha];
|
[rce setRenderPipelineState:_t_pipelineStateNoAlpha];
|
||||||
if (_frameView.filter == RTextureFilterNearest)
|
if (_frameView.filter == RTextureFilterNearest)
|
||||||
{
|
|
||||||
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
|
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
|
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
|
||||||
}
|
|
||||||
[_frameView drawWithEncoder:rce];
|
[_frameView drawWithEncoder:rce];
|
||||||
}
|
}
|
||||||
[rce popDebugGroup];
|
[rce popDebugGroup];
|
||||||
@ -455,13 +435,9 @@
|
|||||||
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
|
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
|
||||||
[rce setRenderPipelineState:_t_pipelineState];
|
[rce setRenderPipelineState:_t_pipelineState];
|
||||||
if (_menu.view.filter == RTextureFilterNearest)
|
if (_menu.view.filter == RTextureFilterNearest)
|
||||||
{
|
|
||||||
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
|
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
|
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
|
||||||
}
|
|
||||||
[_menu.view drawWithEncoder:rce];
|
[_menu.view drawWithEncoder:rce];
|
||||||
[rce popDebugGroup];
|
[rce popDebugGroup];
|
||||||
}
|
}
|
||||||
@ -476,31 +452,16 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_endFrame
|
- (void)_endFrame { [_context end]; }
|
||||||
{
|
/* TODO/FIXME (sgc): resize*/
|
||||||
[_context end];
|
- (void)setNeedsResize { }
|
||||||
}
|
- (void)setRotation:(unsigned)rotation { [_context setRotation:rotation]; }
|
||||||
|
- (Uniforms *)viewportMVP { return &_viewportMVP; }
|
||||||
- (void)setNeedsResize
|
|
||||||
{
|
|
||||||
// TODO(sgc): resize all drawables
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setRotation:(unsigned)rotation
|
|
||||||
{
|
|
||||||
[_context setRotation:rotation];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (Uniforms *)viewportMVP
|
|
||||||
{
|
|
||||||
return &_viewportMVP;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - MTKViewDelegate
|
#pragma mark - MTKViewDelegate
|
||||||
|
|
||||||
- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size
|
- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||||
{
|
{
|
||||||
NSLog(@"mtkView drawableSizeWillChange to: %f x %f",size.width,size.height);
|
|
||||||
#ifdef HAVE_COCOATOUCH
|
#ifdef HAVE_COCOATOUCH
|
||||||
CGFloat scale = [[UIScreen mainScreen] scale];
|
CGFloat scale = [[UIScreen mainScreen] scale];
|
||||||
[self setViewportWidth:(unsigned int)view.bounds.size.width*scale height:(unsigned int)view.bounds.size.height*scale forceFull:NO allowRotate:YES];
|
[self setViewportWidth:(unsigned int)view.bounds.size.width*scale height:(unsigned int)view.bounds.size.height*scale forceFull:NO allowRotate:YES];
|
||||||
@ -509,11 +470,7 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)drawInMTKView:(MTKView *)view
|
- (void)drawInMTKView:(MTKView *)view { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MetalMenu
|
@implementation MetalMenu
|
||||||
@ -526,28 +483,21 @@
|
|||||||
- (instancetype)initWithContext:(Context *)context
|
- (instancetype)initWithContext:(Context *)context
|
||||||
{
|
{
|
||||||
if (self = [super init])
|
if (self = [super init])
|
||||||
{
|
|
||||||
_context = context;
|
_context = context;
|
||||||
}
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (bool)hasFrame
|
- (bool)hasFrame { return _view != nil; }
|
||||||
{
|
|
||||||
return _view != nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setEnabled:(bool)enabled
|
- (void)setEnabled:(bool)enabled
|
||||||
{
|
{
|
||||||
if (_enabled == enabled) return;
|
if (_enabled == enabled)
|
||||||
_enabled = enabled;
|
return;
|
||||||
|
_enabled = enabled;
|
||||||
_view.visible = enabled;
|
_view.visible = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (bool)enabled
|
- (bool)enabled { return _enabled; }
|
||||||
{
|
|
||||||
return _enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateWidth:(int)width
|
- (void)updateWidth:(int)width
|
||||||
height:(int)height
|
height:(int)height
|
||||||
@ -561,19 +511,17 @@
|
|||||||
if (!(CGSizeEqualToSize(_view.size, size) &&
|
if (!(CGSizeEqualToSize(_view.size, size) &&
|
||||||
_view.format == format &&
|
_view.format == format &&
|
||||||
_view.filter == filter))
|
_view.filter == filter))
|
||||||
{
|
|
||||||
_view = nil;
|
_view = nil;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_view)
|
if (!_view)
|
||||||
{
|
{
|
||||||
ViewDescriptor *vd = [ViewDescriptor new];
|
ViewDescriptor *vd = [ViewDescriptor new];
|
||||||
vd.format = format;
|
vd.format = format;
|
||||||
vd.filter = filter;
|
vd.filter = filter;
|
||||||
vd.size = size;
|
vd.size = size;
|
||||||
_view = [[TexturedView alloc] initWithDescriptor:vd context:_context];
|
_view = [[TexturedView alloc] initWithDescriptor:vd context:_context];
|
||||||
_view.visible = _enabled;
|
_view.visible = _enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,14 +580,14 @@ typedef struct MTLALIGN(16)
|
|||||||
@implementation FrameView
|
@implementation FrameView
|
||||||
{
|
{
|
||||||
Context *_context;
|
Context *_context;
|
||||||
id<MTLTexture> _texture; // final render texture
|
id<MTLTexture> _texture; /* final render texture */
|
||||||
Vertex _v[4];
|
Vertex _v[4];
|
||||||
VertexSlang _vertex[4];
|
VertexSlang _vertex[4];
|
||||||
CGSize _size; // size of view in pixels
|
CGSize _size; /* size of view in pixels */
|
||||||
CGRect _frame;
|
CGRect _frame;
|
||||||
NSUInteger _bpp;
|
NSUInteger _bpp;
|
||||||
|
|
||||||
id<MTLTexture> _src; // src texture
|
id<MTLTexture> _src; /* source texture */
|
||||||
bool _srcDirty;
|
bool _srcDirty;
|
||||||
|
|
||||||
id<MTLSamplerState> _samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX];
|
id<MTLSamplerState> _samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX];
|
||||||
@ -657,28 +605,24 @@ typedef struct MTLALIGN(16)
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_context = c;
|
_context = c;
|
||||||
_format = d.format;
|
_format = d.format;
|
||||||
_bpp = RPixelFormatToBPP(_format);
|
_bpp = RPixelFormatToBPP(_format);
|
||||||
_filter = d.filter;
|
_filter = d.filter;
|
||||||
if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm)
|
if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm)
|
||||||
{
|
_drawState = ViewDrawStateEncoder;
|
||||||
_drawState = ViewDrawStateEncoder;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
_drawState = ViewDrawStateAll;
|
||||||
_drawState = ViewDrawStateAll;
|
_visible = YES;
|
||||||
}
|
_engine.mvp = matrix_proj_ortho(0, 1, 0, 1);
|
||||||
_visible = YES;
|
|
||||||
_engine.mvp = matrix_proj_ortho(0, 1, 0, 1);
|
|
||||||
[self _initSamplers];
|
[self _initSamplers];
|
||||||
|
|
||||||
self.size = d.size;
|
self.size = d.size;
|
||||||
self.frame = CGRectMake(0, 0, 1, 1);
|
self.frame = CGRectMake(0, 0, 1, 1);
|
||||||
resize_render_targets = YES;
|
resize_render_targets = YES;
|
||||||
|
|
||||||
// init slang vertex buffer
|
/* Initialize slang vertex buffer */
|
||||||
VertexSlang v[4] = {
|
VertexSlang v[4] = {
|
||||||
{simd_make_float4(0, 1, 0, 1), simd_make_float2(0, 1)},
|
{simd_make_float4(0, 1, 0, 1), simd_make_float2(0, 1)},
|
||||||
{simd_make_float4(1, 1, 0, 1), simd_make_float2(1, 1)},
|
{simd_make_float4(1, 1, 0, 1), simd_make_float2(1, 1)},
|
||||||
{simd_make_float4(0, 0, 0, 1), simd_make_float2(0, 0)},
|
{simd_make_float4(0, 0, 0, 1), simd_make_float2(0, 0)},
|
||||||
@ -691,10 +635,11 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
- (void)_initSamplers
|
- (void)_initSamplers
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
|
MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
|
||||||
|
|
||||||
/* Initialize samplers */
|
/* Initialize samplers */
|
||||||
for (unsigned i = 0; i < RARCH_WRAP_MAX; i++)
|
for (i = 0; i < RARCH_WRAP_MAX; i++)
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
@ -721,25 +666,26 @@ typedef struct MTLALIGN(16)
|
|||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sd.tAddressMode = sd.sAddressMode;
|
sd.tAddressMode = sd.sAddressMode;
|
||||||
sd.rAddressMode = sd.sAddressMode;
|
sd.rAddressMode = sd.sAddressMode;
|
||||||
sd.minFilter = MTLSamplerMinMagFilterLinear;
|
sd.minFilter = MTLSamplerMinMagFilterLinear;
|
||||||
sd.magFilter = MTLSamplerMinMagFilterLinear;
|
sd.magFilter = MTLSamplerMinMagFilterLinear;
|
||||||
|
|
||||||
id<MTLSamplerState> ss = [_context.device newSamplerStateWithDescriptor:sd];
|
id<MTLSamplerState> ss = [_context.device newSamplerStateWithDescriptor:sd];
|
||||||
_samplers[RARCH_FILTER_LINEAR][i] = ss;
|
_samplers[RARCH_FILTER_LINEAR][i] = ss;
|
||||||
|
|
||||||
sd.minFilter = MTLSamplerMinMagFilterNearest;
|
sd.minFilter = MTLSamplerMinMagFilterNearest;
|
||||||
sd.magFilter = MTLSamplerMinMagFilterNearest;
|
sd.magFilter = MTLSamplerMinMagFilterNearest;
|
||||||
|
|
||||||
ss = [_context.device newSamplerStateWithDescriptor:sd];
|
ss = [_context.device newSamplerStateWithDescriptor:sd];
|
||||||
_samplers[RARCH_FILTER_NEAREST][i] = ss;
|
_samplers[RARCH_FILTER_NEAREST][i] = ss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setFilteringIndex:(int)index smooth:(bool)smooth
|
- (void)setFilteringIndex:(int)index smooth:(bool)smooth
|
||||||
{
|
{
|
||||||
for (int i = 0; i < RARCH_WRAP_MAX; i++)
|
int i;
|
||||||
|
for (i = 0; i < RARCH_WRAP_MAX; i++)
|
||||||
{
|
{
|
||||||
if (smooth)
|
if (smooth)
|
||||||
_samplers[RARCH_FILTER_UNSPEC][i] = _samplers[RARCH_FILTER_LINEAR][i];
|
_samplers[RARCH_FILTER_UNSPEC][i] = _samplers[RARCH_FILTER_LINEAR][i];
|
||||||
@ -753,11 +699,11 @@ typedef struct MTLALIGN(16)
|
|||||||
if (CGSizeEqualToSize(_size, size))
|
if (CGSizeEqualToSize(_size, size))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_size = size;
|
_size = size;
|
||||||
|
|
||||||
resize_render_targets = YES;
|
resize_render_targets = YES;
|
||||||
|
|
||||||
if (_format != RPixelFormatBGRA8Unorm && _format != RPixelFormatBGRX8Unorm)
|
if ( _format != RPixelFormatBGRA8Unorm
|
||||||
|
&& _format != RPixelFormatBGRX8Unorm)
|
||||||
{
|
{
|
||||||
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR16Uint
|
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatR16Uint
|
||||||
width:(NSUInteger)size.width
|
width:(NSUInteger)size.width
|
||||||
@ -767,26 +713,21 @@ typedef struct MTLALIGN(16)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGSize)size
|
- (CGSize)size { return _size; }
|
||||||
{
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setFrame:(CGRect)frame
|
- (void)setFrame:(CGRect)frame
|
||||||
{
|
{
|
||||||
if (CGRectEqualToRect(_frame, frame))
|
if (CGRectEqualToRect(_frame, frame))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_frame = frame;
|
/* update vertices */
|
||||||
|
CGPoint o = frame.origin;
|
||||||
|
CGSize s = frame.size;
|
||||||
|
|
||||||
// update vertices
|
CGFloat l = o.x;
|
||||||
CGPoint o = frame.origin;
|
CGFloat t = o.y;
|
||||||
CGSize s = frame.size;
|
CGFloat r = o.x + s.width;
|
||||||
|
CGFloat b = o.y + s.height;
|
||||||
CGFloat l = o.x;
|
|
||||||
CGFloat t = o.y;
|
|
||||||
CGFloat r = o.x + s.width;
|
|
||||||
CGFloat b = o.y + s.height;
|
|
||||||
|
|
||||||
Vertex v[4] = {
|
Vertex v[4] = {
|
||||||
{simd_make_float3(l, b, 0), simd_make_float2(0, 1)},
|
{simd_make_float3(l, b, 0), simd_make_float2(0, 1)},
|
||||||
@ -794,13 +735,12 @@ typedef struct MTLALIGN(16)
|
|||||||
{simd_make_float3(l, t, 0), simd_make_float2(0, 0)},
|
{simd_make_float3(l, t, 0), simd_make_float2(0, 0)},
|
||||||
{simd_make_float3(r, t, 0), simd_make_float2(1, 0)},
|
{simd_make_float3(r, t, 0), simd_make_float2(1, 0)},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_frame = frame;
|
||||||
memcpy(_v, v, sizeof(_v));
|
memcpy(_v, v, sizeof(_v));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)frame
|
- (CGRect)frame { return _frame; }
|
||||||
{
|
|
||||||
return _frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_convertFormat
|
- (void)_convertFormat
|
||||||
{
|
{
|
||||||
@ -837,13 +777,13 @@ typedef struct MTLALIGN(16)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* either no history, or we moved a texture of a different size in the front slot */
|
/* either no history, or we moved a texture of a different size in the front slot */
|
||||||
if (_engine.frame.texture[0].size_data.x != _size.width ||
|
if ( _engine.frame.texture[0].size_data.x != _size.width
|
||||||
_engine.frame.texture[0].size_data.y != _size.height)
|
|| _engine.frame.texture[0].size_data.y != _size.height)
|
||||||
{
|
{
|
||||||
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
|
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
|
||||||
width:(NSUInteger)_size.width
|
width:(NSUInteger)_size.width
|
||||||
height:(NSUInteger)_size.height
|
height:(NSUInteger)_size.height
|
||||||
mipmapped:false];
|
mipmapped:false];
|
||||||
td.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
|
td.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
|
||||||
[self _initTexture:&_engine.frame.texture[0] withDescriptor:td];
|
[self _initTexture:&_engine.frame.texture[0] withDescriptor:td];
|
||||||
}
|
}
|
||||||
@ -851,13 +791,14 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
- (bool)readViewport:(uint8_t *)buffer isIdle:(bool)isIdle
|
- (bool)readViewport:(uint8_t *)buffer isIdle:(bool)isIdle
|
||||||
{
|
{
|
||||||
|
bool res;
|
||||||
bool enabled = _context.captureEnabled;
|
bool enabled = _context.captureEnabled;
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
_context.captureEnabled = YES;
|
_context.captureEnabled = YES;
|
||||||
|
|
||||||
video_driver_cached_frame();
|
video_driver_cached_frame();
|
||||||
|
|
||||||
bool res = [_context readBackBuffer:buffer];
|
res = [_context readBackBuffer:buffer];
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
_context.captureEnabled = NO;
|
_context.captureEnabled = NO;
|
||||||
@ -869,7 +810,7 @@ typedef struct MTLALIGN(16)
|
|||||||
{
|
{
|
||||||
if (_shader && (_engine.frame.output_size.x != _viewport->width ||
|
if (_shader && (_engine.frame.output_size.x != _viewport->width ||
|
||||||
_engine.frame.output_size.y != _viewport->height))
|
_engine.frame.output_size.y != _viewport->height))
|
||||||
resize_render_targets = YES;
|
resize_render_targets = YES;
|
||||||
|
|
||||||
_engine.frame.viewport.originX = _viewport->x;
|
_engine.frame.viewport.originX = _viewport->x;
|
||||||
_engine.frame.viewport.originY = _viewport->y;
|
_engine.frame.viewport.originY = _viewport->y;
|
||||||
@ -887,7 +828,8 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
[self _updateHistory];
|
[self _updateHistory];
|
||||||
|
|
||||||
if (_format == RPixelFormatBGRA8Unorm || _format == RPixelFormatBGRX8Unorm)
|
if ( _format == RPixelFormatBGRA8Unorm
|
||||||
|
|| _format == RPixelFormatBGRX8Unorm)
|
||||||
{
|
{
|
||||||
id<MTLTexture> tex = _engine.frame.texture[0].view;
|
id<MTLTexture> tex = _engine.frame.texture[0].view;
|
||||||
[tex replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)_size.width, (NSUInteger)_size.height)
|
[tex replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)_size.width, (NSUInteger)_size.height)
|
||||||
@ -916,10 +858,12 @@ typedef struct MTLALIGN(16)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
|
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
|
||||||
width:(NSUInteger)_size.width
|
width:(NSUInteger)_size.width
|
||||||
height:(NSUInteger)_size.height
|
height:(NSUInteger)_size.height
|
||||||
mipmapped:false];
|
mipmapped:false];
|
||||||
td.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite | MTLTextureUsageRenderTarget;
|
td.usage = MTLTextureUsageShaderRead
|
||||||
|
| MTLTextureUsageShaderWrite
|
||||||
|
| MTLTextureUsageRenderTarget;
|
||||||
|
|
||||||
for (i = 0; i < _shader->history_size + 1; i++)
|
for (i = 0; i < _shader->history_size + 1; i++)
|
||||||
[self _initTexture:&_engine.frame.texture[i] withDescriptor:td];
|
[self _initTexture:&_engine.frame.texture[i] withDescriptor:td];
|
||||||
@ -939,7 +883,7 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
- (void)drawWithContext:(Context *)ctx
|
- (void)drawWithContext:(Context *)ctx
|
||||||
{
|
{
|
||||||
unsigned i;
|
int i;
|
||||||
_texture = _engine.frame.texture[0].view;
|
_texture = _engine.frame.texture[0].view;
|
||||||
[self _convertFormat];
|
[self _convertFormat];
|
||||||
|
|
||||||
@ -959,20 +903,21 @@ typedef struct MTLALIGN(16)
|
|||||||
id<MTLCommandBuffer> cb = ctx.blitCommandBuffer;
|
id<MTLCommandBuffer> cb = ctx.blitCommandBuffer;
|
||||||
[cb pushDebugGroup:@"shaders"];
|
[cb pushDebugGroup:@"shaders"];
|
||||||
|
|
||||||
MTLRenderPassDescriptor *rpd = [MTLRenderPassDescriptor new];
|
MTLRenderPassDescriptor *rpd = [MTLRenderPassDescriptor new];
|
||||||
rpd.colorAttachments[0].loadAction = MTLLoadActionDontCare;
|
rpd.colorAttachments[0].loadAction = MTLLoadActionDontCare;
|
||||||
rpd.colorAttachments[0].storeAction = MTLStoreActionStore;
|
rpd.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
|
|
||||||
for (unsigned i = 0; i < _shader->passes; i++)
|
for (i = 0; i < _shader->passes; i++)
|
||||||
{
|
{
|
||||||
id<MTLRenderCommandEncoder> rce = nil;
|
int j;
|
||||||
|
__unsafe_unretained id<MTLTexture> textures[SLANG_NUM_BINDINGS] = {NULL};
|
||||||
|
id<MTLSamplerState> samplers[SLANG_NUM_BINDINGS] = {NULL};
|
||||||
|
id<MTLRenderCommandEncoder> rce = nil;
|
||||||
|
|
||||||
BOOL backBuffer = (_engine.pass[i].rt.view == nil);
|
BOOL backBuffer = (_engine.pass[i].rt.view == nil);
|
||||||
|
|
||||||
if (backBuffer)
|
if (backBuffer)
|
||||||
{
|
|
||||||
rce = _context.rce;
|
rce = _context.rce;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rpd.colorAttachments[0].texture = _engine.pass[i].rt.view;
|
rpd.colorAttachments[0].texture = _engine.pass[i].rt.view;
|
||||||
@ -996,7 +941,7 @@ typedef struct MTLALIGN(16)
|
|||||||
_engine.pass[i].frame_direction = 1;
|
_engine.pass[i].frame_direction = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (unsigned j = 0; j < SLANG_CBUFFER_MAX; j++)
|
for (j = 0; j < SLANG_CBUFFER_MAX; j++)
|
||||||
{
|
{
|
||||||
id<MTLBuffer> buffer = _engine.pass[i].buffers[j];
|
id<MTLBuffer> buffer = _engine.pass[i].buffers[j];
|
||||||
cbuffer_sem_t *buffer_sem = &_engine.pass[i].semantics.cbuffers[j];
|
cbuffer_sem_t *buffer_sem = &_engine.pass[i].semantics.cbuffers[j];
|
||||||
@ -1024,9 +969,6 @@ typedef struct MTLALIGN(16)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__unsafe_unretained id<MTLTexture> textures[SLANG_NUM_BINDINGS] = {NULL};
|
|
||||||
id<MTLSamplerState> samplers[SLANG_NUM_BINDINGS] = {NULL};
|
|
||||||
|
|
||||||
texture_sem_t *texture_sem = _engine.pass[i].semantics.textures;
|
texture_sem_t *texture_sem = _engine.pass[i].semantics.textures;
|
||||||
while (texture_sem->stage_mask)
|
while (texture_sem->stage_mask)
|
||||||
{
|
{
|
||||||
@ -1038,13 +980,9 @@ typedef struct MTLALIGN(16)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (backBuffer)
|
if (backBuffer)
|
||||||
{
|
|
||||||
[rce setViewport:_engine.frame.viewport];
|
[rce setViewport:_engine.frame.viewport];
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
[rce setViewport:_engine.pass[i].viewport];
|
[rce setViewport:_engine.pass[i].viewport];
|
||||||
}
|
|
||||||
|
|
||||||
[rce setFragmentTextures:textures withRange:NSMakeRange(0, SLANG_NUM_BINDINGS)];
|
[rce setFragmentTextures:textures withRange:NSMakeRange(0, SLANG_NUM_BINDINGS)];
|
||||||
[rce setFragmentSamplerStates:samplers withRange:NSMakeRange(0, SLANG_NUM_BINDINGS)];
|
[rce setFragmentSamplerStates:samplers withRange:NSMakeRange(0, SLANG_NUM_BINDINGS)];
|
||||||
@ -1052,9 +990,7 @@ typedef struct MTLALIGN(16)
|
|||||||
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
||||||
|
|
||||||
if (!backBuffer)
|
if (!backBuffer)
|
||||||
{
|
|
||||||
[rce endEncoding];
|
[rce endEncoding];
|
||||||
}
|
|
||||||
|
|
||||||
_texture = _engine.pass[i].rt.view;
|
_texture = _engine.pass[i].rt.view;
|
||||||
}
|
}
|
||||||
@ -1069,10 +1005,12 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
- (void)_updateRenderTargets
|
- (void)_updateRenderTargets
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
NSUInteger width, height;
|
||||||
if (!_shader || !resize_render_targets) return;
|
if (!_shader || !resize_render_targets) return;
|
||||||
|
|
||||||
// release existing targets
|
// release existing targets
|
||||||
for (int i = 0; i < _shader->passes; i++)
|
for (i = 0; i < _shader->passes; i++)
|
||||||
{
|
{
|
||||||
STRUCT_ASSIGN(_engine.pass[i].rt.view, nil);
|
STRUCT_ASSIGN(_engine.pass[i].rt.view, nil);
|
||||||
STRUCT_ASSIGN(_engine.pass[i].feedback.view, nil);
|
STRUCT_ASSIGN(_engine.pass[i].feedback.view, nil);
|
||||||
@ -1080,9 +1018,10 @@ typedef struct MTLALIGN(16)
|
|||||||
memset(&_engine.pass[i].feedback, 0, sizeof(_engine.pass[i].feedback));
|
memset(&_engine.pass[i].feedback, 0, sizeof(_engine.pass[i].feedback));
|
||||||
}
|
}
|
||||||
|
|
||||||
NSUInteger width = (NSUInteger)_size.width, height = (NSUInteger)_size.height;
|
width = (NSUInteger)_size.width;
|
||||||
|
height = (NSUInteger)_size.height;
|
||||||
|
|
||||||
for (unsigned i = 0; i < _shader->passes; i++)
|
for (i = 0; i < _shader->passes; i++)
|
||||||
{
|
{
|
||||||
struct video_shader_pass *shader_pass = &_shader->pass[i];
|
struct video_shader_pass *shader_pass = &_shader->pass[i];
|
||||||
|
|
||||||
@ -1149,17 +1088,15 @@ typedef struct MTLALIGN(16)
|
|||||||
_engine.pass[i].viewport.zfar = 1.0;
|
_engine.pass[i].viewport.zfar = 1.0;
|
||||||
|
|
||||||
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:fmt
|
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:fmt
|
||||||
width:width
|
width:width height:height mipmapped:false];
|
||||||
height:height
|
|
||||||
mipmapped:false];
|
|
||||||
td.storageMode = MTLStorageModePrivate;
|
td.storageMode = MTLStorageModePrivate;
|
||||||
td.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
|
td.usage = MTLTextureUsageShaderRead
|
||||||
|
| MTLTextureUsageRenderTarget;
|
||||||
|
|
||||||
[self _initTexture:&_engine.pass[i].rt withDescriptor:td];
|
[self _initTexture:&_engine.pass[i].rt withDescriptor:td];
|
||||||
|
|
||||||
if (shader_pass->feedback)
|
if (shader_pass->feedback)
|
||||||
{
|
|
||||||
[self _initTexture:&_engine.pass[i].feedback withDescriptor:td];
|
[self _initTexture:&_engine.pass[i].feedback withDescriptor:td];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1175,11 +1112,13 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
- (void)_freeVideoShader:(struct video_shader *)shader
|
- (void)_freeVideoShader:(struct video_shader *)shader
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
if (!shader)
|
if (!shader)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < GFX_MAX_SHADERS; i++)
|
for (i = 0; i < GFX_MAX_SHADERS; i++)
|
||||||
{
|
{
|
||||||
|
int j;
|
||||||
STRUCT_ASSIGN(_engine.pass[i].rt.view, nil);
|
STRUCT_ASSIGN(_engine.pass[i].rt.view, nil);
|
||||||
STRUCT_ASSIGN(_engine.pass[i].feedback.view, nil);
|
STRUCT_ASSIGN(_engine.pass[i].feedback.view, nil);
|
||||||
memset(&_engine.pass[i].rt, 0, sizeof(_engine.pass[i].rt));
|
memset(&_engine.pass[i].rt, 0, sizeof(_engine.pass[i].rt));
|
||||||
@ -1187,13 +1126,13 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
STRUCT_ASSIGN(_engine.pass[i]._state, nil);
|
STRUCT_ASSIGN(_engine.pass[i]._state, nil);
|
||||||
|
|
||||||
for (unsigned j = 0; j < SLANG_CBUFFER_MAX; j++)
|
for (j = 0; j < SLANG_CBUFFER_MAX; j++)
|
||||||
{
|
{
|
||||||
STRUCT_ASSIGN(_engine.pass[i].buffers[j], nil);
|
STRUCT_ASSIGN(_engine.pass[i].buffers[j], nil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < GFX_MAX_TEXTURES; i++)
|
for (i = 0; i < GFX_MAX_TEXTURES; i++)
|
||||||
{
|
{
|
||||||
STRUCT_ASSIGN(_engine.luts[i].view, nil);
|
STRUCT_ASSIGN(_engine.luts[i].view, nil);
|
||||||
}
|
}
|
||||||
@ -1204,7 +1143,7 @@ typedef struct MTLALIGN(16)
|
|||||||
- (BOOL)setShaderFromPath:(NSString *)path
|
- (BOOL)setShaderFromPath:(NSString *)path
|
||||||
{
|
{
|
||||||
[self _freeVideoShader:_shader];
|
[self _freeVideoShader:_shader];
|
||||||
_shader = nil;
|
_shader = nil;
|
||||||
|
|
||||||
struct video_shader *shader = (struct video_shader *)calloc(1, sizeof(*shader));
|
struct video_shader *shader = (struct video_shader *)calloc(1, sizeof(*shader));
|
||||||
settings_t *settings = config_get_ptr();
|
settings_t *settings = config_get_ptr();
|
||||||
@ -1213,7 +1152,7 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
@try
|
@try
|
||||||
{
|
{
|
||||||
unsigned i;
|
int i;
|
||||||
texture_t *source = NULL;
|
texture_t *source = NULL;
|
||||||
if (!video_shader_load_preset_into_shader(path.UTF8String, shader))
|
if (!video_shader_load_preset_into_shader(path.UTF8String, shader))
|
||||||
return NO;
|
return NO;
|
||||||
@ -1265,9 +1204,9 @@ typedef struct MTLALIGN(16)
|
|||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool save_msl = true;
|
bool save_msl = true;
|
||||||
#else
|
#else
|
||||||
bool save_msl = false;
|
bool save_msl = false;
|
||||||
#endif
|
#endif
|
||||||
NSString *vs_src = [NSString stringWithUTF8String:shader->pass[i].source.string.vertex];
|
NSString *vs_src = [NSString stringWithUTF8String:shader->pass[i].source.string.vertex];
|
||||||
NSString *fs_src = [NSString stringWithUTF8String:shader->pass[i].source.string.fragment];
|
NSString *fs_src = [NSString stringWithUTF8String:shader->pass[i].source.string.fragment];
|
||||||
@ -1388,24 +1327,26 @@ typedef struct MTLALIGN(16)
|
|||||||
free(shader->pass[i].source.string.vertex);
|
free(shader->pass[i].source.string.vertex);
|
||||||
free(shader->pass[i].source.string.fragment);
|
free(shader->pass[i].source.string.fragment);
|
||||||
|
|
||||||
shader->pass[i].source.string.vertex = NULL;
|
shader->pass[i].source.string.vertex = NULL;
|
||||||
shader->pass[i].source.string.fragment = NULL;
|
shader->pass[i].source.string.fragment = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < shader->luts; i++)
|
for (i = 0; i < shader->luts; i++)
|
||||||
{
|
{
|
||||||
struct texture_image image = {0};
|
struct texture_image image;
|
||||||
|
image.pixels = NULL;
|
||||||
|
image.width = 0;
|
||||||
|
image.height = 0;
|
||||||
image.supports_rgba = true;
|
image.supports_rgba = true;
|
||||||
|
|
||||||
if (!image_texture_load(&image, shader->lut[i].path))
|
if (!image_texture_load(&image, shader->lut[i].path))
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
|
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
|
||||||
width:image.width
|
width:image.width height:image.height
|
||||||
height:image.height
|
mipmapped:shader->lut[i].mipmap];
|
||||||
mipmapped:shader->lut[i].mipmap];
|
td.usage = MTLTextureUsageShaderRead;
|
||||||
td.usage = MTLTextureUsageShaderRead;
|
|
||||||
[self _initTexture:&_engine.luts[i] withDescriptor:td];
|
[self _initTexture:&_engine.luts[i] withDescriptor:td];
|
||||||
|
|
||||||
[_engine.luts[i].view replaceRegion:MTLRegionMake2D(0, 0, image.width, image.height)
|
[_engine.luts[i].view replaceRegion:MTLRegionMake2D(0, 0, image.width, image.height)
|
||||||
@ -1421,13 +1362,11 @@ typedef struct MTLALIGN(16)
|
|||||||
@finally
|
@finally
|
||||||
{
|
{
|
||||||
if (shader)
|
if (shader)
|
||||||
{
|
|
||||||
[self _freeVideoShader:shader];
|
[self _freeVideoShader:shader];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resize_render_targets = YES;
|
resize_render_targets = YES;
|
||||||
init_history = YES;
|
init_history = YES;
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@ -1445,25 +1384,22 @@ typedef struct MTLALIGN(16)
|
|||||||
- (instancetype)initWithContext:(Context *)context
|
- (instancetype)initWithContext:(Context *)context
|
||||||
{
|
{
|
||||||
if (self = [super init])
|
if (self = [super init])
|
||||||
{
|
|
||||||
_context = context;
|
_context = context;
|
||||||
}
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (bool)loadImages:(const struct texture_image *)images count:(NSUInteger)count
|
- (bool)loadImages:(const struct texture_image *)images count:(NSUInteger)count
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
[self _freeImages];
|
[self _freeImages];
|
||||||
|
|
||||||
_images = [NSMutableArray arrayWithCapacity:count];
|
_images = [NSMutableArray arrayWithCapacity:count];
|
||||||
|
|
||||||
NSUInteger needed = sizeof(SpriteVertex) * count * 4;
|
NSUInteger needed = sizeof(SpriteVertex) * count * 4;
|
||||||
if (!_vert || _vert.length < needed)
|
if (!_vert || _vert.length < needed)
|
||||||
{
|
|
||||||
_vert = [_context.device newBufferWithLength:needed options:PLATFORM_METAL_RESOURCE_STORAGE_MODE];
|
_vert = [_context.device newBufferWithLength:needed options:PLATFORM_METAL_RESOURCE_STORAGE_MODE];
|
||||||
}
|
|
||||||
|
|
||||||
for (NSUInteger i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
_images[i] = [_context newTexture:images[i] mipmapped:NO];
|
_images[i] = [_context newTexture:images[i] mipmapped:NO];
|
||||||
[self updateVertexX:0 y:0 w:1 h:1 index:i];
|
[self updateVertexX:0 y:0 w:1 h:1 index:i];
|
||||||
@ -1478,6 +1414,8 @@ typedef struct MTLALIGN(16)
|
|||||||
|
|
||||||
- (void)drawWithEncoder:(id<MTLRenderCommandEncoder>)rce
|
- (void)drawWithEncoder:(id<MTLRenderCommandEncoder>)rce
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
NSUInteger count;
|
||||||
#if !defined(HAVE_COCOATOUCH)
|
#if !defined(HAVE_COCOATOUCH)
|
||||||
if (_vertDirty)
|
if (_vertDirty)
|
||||||
{
|
{
|
||||||
@ -1486,8 +1424,8 @@ typedef struct MTLALIGN(16)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NSUInteger count = _images.count;
|
count = _images.count;
|
||||||
for (NSUInteger i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
NSUInteger offset = sizeof(SpriteVertex) * 4 * i;
|
NSUInteger offset = sizeof(SpriteVertex) * 4 * i;
|
||||||
[rce setVertexBuffer:_vert offset:offset atIndex:BufferIndexPositions];
|
[rce setVertexBuffer:_vert offset:offset atIndex:BufferIndexPositions];
|
||||||
@ -1505,12 +1443,12 @@ typedef struct MTLALIGN(16)
|
|||||||
- (void)_updateColorRed:(float)r green:(float)g blue:(float)b alpha:(float)a index:(NSUInteger)index
|
- (void)_updateColorRed:(float)r green:(float)g blue:(float)b alpha:(float)a index:(NSUInteger)index
|
||||||
{
|
{
|
||||||
simd_float4 color = simd_make_float4(r, g, b, a);
|
simd_float4 color = simd_make_float4(r, g, b, a);
|
||||||
SpriteVertex *pv = [self _getForIndex:index];
|
SpriteVertex *pv = [self _getForIndex:index];
|
||||||
pv[0].color = color;
|
pv[0].color = color;
|
||||||
pv[1].color = color;
|
pv[1].color = color;
|
||||||
pv[2].color = color;
|
pv[2].color = color;
|
||||||
pv[3].color = color;
|
pv[3].color = color;
|
||||||
_vertDirty = YES;
|
_vertDirty = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateAlpha:(float)alpha index:(NSUInteger)index
|
- (void)updateAlpha:(float)alpha index:(NSUInteger)index
|
||||||
@ -1521,27 +1459,24 @@ typedef struct MTLALIGN(16)
|
|||||||
- (void)updateVertexX:(float)x y:(float)y w:(float)w h:(float)h index:(NSUInteger)index
|
- (void)updateVertexX:(float)x y:(float)y w:(float)w h:(float)h index:(NSUInteger)index
|
||||||
{
|
{
|
||||||
SpriteVertex *pv = [self _getForIndex:index];
|
SpriteVertex *pv = [self _getForIndex:index];
|
||||||
pv[0].position = simd_make_float2(x, y);
|
pv[0].position = simd_make_float2(x, y);
|
||||||
pv[1].position = simd_make_float2(x + w, y);
|
pv[1].position = simd_make_float2(x + w, y);
|
||||||
pv[2].position = simd_make_float2(x, y + h);
|
pv[2].position = simd_make_float2(x, y + h);
|
||||||
pv[3].position = simd_make_float2(x + w, y + h);
|
pv[3].position = simd_make_float2(x + w, y + h);
|
||||||
_vertDirty = YES;
|
_vertDirty = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateTextureCoordsX:(float)x y:(float)y w:(float)w h:(float)h index:(NSUInteger)index
|
- (void)updateTextureCoordsX:(float)x y:(float)y w:(float)w h:(float)h index:(NSUInteger)index
|
||||||
{
|
{
|
||||||
SpriteVertex *pv = [self _getForIndex:index];
|
SpriteVertex *pv = [self _getForIndex:index];
|
||||||
pv[0].texCoord = simd_make_float2(x, y);
|
pv[0].texCoord = simd_make_float2(x, y);
|
||||||
pv[1].texCoord = simd_make_float2(x + w, y);
|
pv[1].texCoord = simd_make_float2(x + w, y);
|
||||||
pv[2].texCoord = simd_make_float2(x, y + h);
|
pv[2].texCoord = simd_make_float2(x, y + h);
|
||||||
pv[3].texCoord = simd_make_float2(x + w, y + h);
|
pv[3].texCoord = simd_make_float2(x + w, y + h);
|
||||||
_vertDirty = YES;
|
_vertDirty = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_freeImages
|
- (void)_freeImages { _images = nil; }
|
||||||
{
|
|
||||||
_images = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user