mirror of
https://github.com/libretro/RetroArch
synced 2024-12-28 09:29:16 +00:00
feat(metal): Add native rotation support for Metal driver
* fix crash when frame or frame size is 0
This commit is contained in:
parent
1caf10e1e9
commit
0e295716b9
@ -76,6 +76,7 @@ typedef struct
|
||||
/*! @brief end commits the command buffer */
|
||||
- (void)end;
|
||||
|
||||
- (void)setRotation:(unsigned)rotation;
|
||||
- (bool)readBackBuffer:(uint8_t *)buffer;
|
||||
|
||||
@end
|
||||
|
@ -53,10 +53,16 @@
|
||||
|
||||
id<MTLRenderPipelineState> _states[GFX_MAX_SHADERS][2];
|
||||
id<MTLRenderPipelineState> _clearState;
|
||||
Uniforms _uniforms;
|
||||
|
||||
bool _captureEnabled;
|
||||
id<MTLTexture> _backBuffer;
|
||||
|
||||
unsigned _rotation;
|
||||
matrix_float4x4 _mvp_no_rot;
|
||||
matrix_float4x4 _mvp;
|
||||
|
||||
Uniforms _uniforms;
|
||||
Uniforms _uniformsNoRotate;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDevice:(id<MTLDevice>)d
|
||||
@ -75,6 +81,11 @@
|
||||
_commandQueue = [_device newCommandQueue];
|
||||
_clearColor = MTLClearColorMake(0, 0, 0, 1);
|
||||
_uniforms.projectionMatrix = matrix_proj_ortho(0, 1, 0, 1);
|
||||
|
||||
_rotation = 0;
|
||||
[self setRotation:0];
|
||||
_mvp_no_rot = matrix_proj_ortho(0, 1, 0, 1);
|
||||
_mvp = matrix_proj_ortho(0, 1, 0, 1);
|
||||
|
||||
{
|
||||
MTLSamplerDescriptor *sd = [MTLSamplerDescriptor new];
|
||||
@ -130,6 +141,27 @@
|
||||
return &_uniforms;
|
||||
}
|
||||
|
||||
- (void)setRotation:(unsigned)rotation
|
||||
{
|
||||
_rotation = 270 * rotation;
|
||||
|
||||
/* Calculate projection. */
|
||||
_mvp_no_rot = matrix_proj_ortho(0, 1, 0, 1);
|
||||
|
||||
bool allow_rotate = true;
|
||||
if (!allow_rotate)
|
||||
{
|
||||
_mvp = _mvp_no_rot;
|
||||
return;
|
||||
}
|
||||
|
||||
matrix_float4x4 rot = matrix_rotate_z((float)(M_PI * _rotation / 180.0f));
|
||||
_mvp = simd_mul(rot, _mvp_no_rot);
|
||||
|
||||
_uniforms.projectionMatrix = _mvp;
|
||||
_uniformsNoRotate.projectionMatrix = _mvp_no_rot;
|
||||
}
|
||||
|
||||
- (void)setDisplaySyncEnabled:(bool)displaySyncEnabled
|
||||
{
|
||||
#if TARGET_OS_OSX
|
||||
|
@ -55,6 +55,7 @@ typedef NS_ENUM(NSUInteger, RTextureFilter)
|
||||
};
|
||||
|
||||
extern matrix_float4x4 matrix_proj_ortho(float left, float right, float top, float bottom);
|
||||
extern matrix_float4x4 matrix_rotate_z(float rot);
|
||||
extern matrix_float4x4 make_matrix_float4x4(const float *v);
|
||||
|
||||
#endif /* RendererCommon_h */
|
||||
|
@ -86,3 +86,17 @@ matrix_float4x4 matrix_proj_ortho(float left, float right, float top, float bott
|
||||
matrix_float4x4 mat = {P, Q, R, S};
|
||||
return mat;
|
||||
}
|
||||
|
||||
matrix_float4x4 matrix_rotate_z(float rot)
|
||||
{
|
||||
float cz, sz;
|
||||
__sincosf(rot, &sz, &cz);
|
||||
|
||||
simd_float4 P = simd_make_float4(cz, -sz, 0, 0);
|
||||
simd_float4 Q = simd_make_float4(sz, cz, 0, 0);
|
||||
simd_float4 R = simd_make_float4( 0, 0, 1, 0);
|
||||
simd_float4 S = simd_make_float4( 0, 0, 0, 1);
|
||||
|
||||
matrix_float4x4 mat = {P, Q, R, S};
|
||||
return mat;
|
||||
}
|
||||
|
@ -96,6 +96,8 @@ extern MTLPixelFormat SelectOptimalPixelFormat(MTLPixelFormat fmt);
|
||||
|
||||
/*! @brief setNeedsResize triggers a display resize */
|
||||
- (void)setNeedsResize;
|
||||
- (void)setViewportWidth:(unsigned)width height:(unsigned)height forceFull:(BOOL)forceFull allowRotate:(BOOL)allowRotate;
|
||||
- (void)setRotation:(unsigned)rotation;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -216,21 +216,19 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)_updateUniforms
|
||||
- (void)setViewportWidth:(unsigned)width height:(unsigned)height forceFull:(BOOL)forceFull allowRotate:(BOOL)allowRotate
|
||||
{
|
||||
_uniforms.projectionMatrix = matrix_proj_ortho(0, 1, 0, 1);
|
||||
}
|
||||
|
||||
- (void)_updateViewport:(CGSize)size
|
||||
{
|
||||
RARCH_LOG("[Metal]: _updateViewport size %.0fx%.0f\n", size.width, size.height);
|
||||
#if 0
|
||||
RARCH_LOG("[Metal]: setViewportWidth size %dx%d\n", width, height);
|
||||
#endif
|
||||
|
||||
_viewport->full_width = (unsigned int)size.width;
|
||||
_viewport->full_height = (unsigned int)size.height;
|
||||
_viewport->full_width = width;
|
||||
_viewport->full_height = height;
|
||||
video_driver_set_size(&_viewport->full_width, &_viewport->full_height);
|
||||
_layer.drawableSize = size;
|
||||
video_driver_update_viewport(_viewport, NO, _keepAspect);
|
||||
_layer.drawableSize = CGSizeMake(width, height);
|
||||
video_driver_update_viewport(_viewport, forceFull, _keepAspect);
|
||||
|
||||
// update matrix
|
||||
_context.viewport = _viewport;
|
||||
|
||||
_viewportMVP.outputSize = simd_make_float2(_viewport->full_width, _viewport->full_height);
|
||||
@ -256,8 +254,10 @@
|
||||
[self _beginFrame];
|
||||
|
||||
_frameView.frameCount = frameCount;
|
||||
_frameView.size = CGSizeMake(width, height);
|
||||
[_frameView updateFrame:data pitch:pitch];
|
||||
if (data && width && height) {
|
||||
_frameView.size = CGSizeMake(width, height);
|
||||
[_frameView updateFrame:data pitch:pitch];
|
||||
}
|
||||
|
||||
[self _drawViews:video_info];
|
||||
|
||||
@ -277,7 +277,7 @@
|
||||
id<MTLRenderCommandEncoder> rce = _context.rce;
|
||||
[rce pushDebugGroup:@"overlay"];
|
||||
[rce setRenderPipelineState:[_context getStockShader:VIDEO_SHADER_STOCK_BLEND blend:YES]];
|
||||
[rce setVertexBytes:&_uniforms length:sizeof(_uniforms) atIndex:BufferIndexUniforms];
|
||||
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
|
||||
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
|
||||
[_overlay drawWithEncoder:rce];
|
||||
[rce popDebugGroup];
|
||||
@ -338,7 +338,6 @@
|
||||
_context.viewport = _viewport;
|
||||
}
|
||||
[_context begin];
|
||||
[self _updateUniforms];
|
||||
}
|
||||
|
||||
- (void)_drawViews:(video_frame_info_t *)video_info
|
||||
@ -351,7 +350,7 @@
|
||||
|
||||
if ((_frameView.drawState & ViewDrawStateEncoder) != 0)
|
||||
{
|
||||
[rce setVertexBytes:&_uniforms length:sizeof(_uniforms) atIndex:BufferIndexUniforms];
|
||||
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
|
||||
[rce setRenderPipelineState:_t_pipelineStateNoAlpha];
|
||||
if (_frameView.filter == RTextureFilterNearest)
|
||||
{
|
||||
@ -410,6 +409,11 @@
|
||||
// TODO(sgc): resize all drawables
|
||||
}
|
||||
|
||||
- (void)setRotation:(unsigned)rotation
|
||||
{
|
||||
[_context setRotation:rotation];
|
||||
}
|
||||
|
||||
- (Uniforms *)viewportMVP
|
||||
{
|
||||
return &_viewportMVP;
|
||||
@ -419,7 +423,7 @@
|
||||
|
||||
- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||
{
|
||||
[self _updateViewport:size];
|
||||
[self setViewportWidth:(unsigned int)size.width height:(unsigned int)size.height forceFull:NO allowRotate:YES];
|
||||
}
|
||||
|
||||
- (void)drawInMTKView:(MTKView *)view
|
||||
@ -897,7 +901,7 @@ typedef struct MTLALIGN(16)
|
||||
rce = [cb renderCommandEncoderWithDescriptor:rpd];
|
||||
}
|
||||
|
||||
#if METAL_DEBUG
|
||||
#if DEBUG && METAL_DEBUG
|
||||
rce.label = [NSString stringWithFormat:@"pass %d", i];
|
||||
#endif
|
||||
|
||||
@ -1126,6 +1130,8 @@ typedef struct MTLALIGN(16)
|
||||
texture_t *source = &_engine.frame.texture[0];
|
||||
for (unsigned i = 0; i < shader->passes; source = &_engine.pass[i++].rt)
|
||||
{
|
||||
matrix_float4x4 *mvp = (i == shader->passes-1) ? &_context.uniforms->projectionMatrix : &_engine.mvp;
|
||||
|
||||
/* clang-format off */
|
||||
semantics_map_t semantics_map = {
|
||||
{
|
||||
@ -1154,7 +1160,7 @@ typedef struct MTLALIGN(16)
|
||||
&_engine.luts[0].size_data, sizeof(*_engine.luts)},
|
||||
},
|
||||
{
|
||||
&_engine.mvp, /* MVP */
|
||||
mvp, /* MVP */
|
||||
&_engine.pass[i].rt.size_data, /* OutputSize */
|
||||
&_engine.frame.output_size, /* FinalViewportSize */
|
||||
&_engine.pass[i].frame_count, /* FrameCount */
|
||||
|
@ -151,16 +151,22 @@ static void metal_free(void *data)
|
||||
static void metal_set_viewport(void *data, unsigned viewport_width,
|
||||
unsigned viewport_height, bool force_full, bool allow_rotate)
|
||||
{
|
||||
#if 0
|
||||
RARCH_LOG("[Metal]: set_viewport size: %dx%d full: %s rotate: %s\n",
|
||||
viewport_width, viewport_height,
|
||||
force_full ? "YES" : "NO",
|
||||
allow_rotate ? "YES" : "NO");
|
||||
#endif
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
[md setViewportWidth:viewport_width height:viewport_height forceFull:force_full allowRotate:allow_rotate];
|
||||
}
|
||||
|
||||
static void metal_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
[md setRotation:rotation];
|
||||
}
|
||||
|
||||
static void metal_viewport_info(void *data, struct video_viewport *vp)
|
||||
|
@ -88,6 +88,17 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
05132C6621A74D7A00379846 /* ozone_texture.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone_texture.c; sourceTree = "<group>"; };
|
||||
05132C6721A74D7B00379846 /* ozone_theme.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ozone_theme.h; sourceTree = "<group>"; };
|
||||
05132C6821A74D7B00379846 /* ozone.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ozone.h; sourceTree = "<group>"; };
|
||||
05132C6921A74D7B00379846 /* ozone_entries.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone_entries.c; sourceTree = "<group>"; };
|
||||
05132C6A21A74D7B00379846 /* ozone.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone.c; sourceTree = "<group>"; };
|
||||
05132C6B21A74D7B00379846 /* ozone_theme.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone_theme.c; sourceTree = "<group>"; };
|
||||
05132C6C21A74D7B00379846 /* ozone_sidebar.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone_sidebar.c; sourceTree = "<group>"; };
|
||||
05132C6D21A74D7B00379846 /* ozone_sidebar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ozone_sidebar.h; sourceTree = "<group>"; };
|
||||
05132C6E21A74D7B00379846 /* ozone_display.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone_display.c; sourceTree = "<group>"; };
|
||||
05132C6F21A74D7B00379846 /* ozone_texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ozone_texture.h; sourceTree = "<group>"; };
|
||||
05132C7021A74D7B00379846 /* ozone_display.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ozone_display.h; sourceTree = "<group>"; };
|
||||
05269A6120ABF20500C29F1E /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
|
||||
05366512213F8BE5007E7EA0 /* thumbnailpackdownload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thumbnailpackdownload.cpp; sourceTree = "<group>"; };
|
||||
05366513213F8BE5007E7EA0 /* ui_qt_application.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ui_qt_application.cpp; sourceTree = "<group>"; };
|
||||
@ -514,7 +525,6 @@
|
||||
05D7753320A5678300646447 /* griffin_cpp.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = griffin_cpp.cpp; path = ../../griffin/griffin_cpp.cpp; sourceTree = "<group>"; };
|
||||
05D7753420A5678400646447 /* griffin_glslang.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = griffin_glslang.cpp; path = ../../griffin/griffin_glslang.cpp; sourceTree = "<group>"; };
|
||||
05EFAFC22191D64200D27059 /* stripes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stripes.c; sourceTree = "<group>"; };
|
||||
05EFAFC32191D64200D27059 /* ozone.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ozone.c; sourceTree = "<group>"; };
|
||||
05F2872F20F2BEEA00632D47 /* task_autodetect.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = task_autodetect.c; sourceTree = "<group>"; };
|
||||
05F2873020F2BEEA00632D47 /* task_netplay_find_content.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = task_netplay_find_content.c; sourceTree = "<group>"; };
|
||||
05F2873120F2BEEA00632D47 /* task_netplay_nat_traversal.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = task_netplay_nat_traversal.c; sourceTree = "<group>"; };
|
||||
@ -610,6 +620,24 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
05132C6521A74D5100379846 /* ozone */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05132C6E21A74D7B00379846 /* ozone_display.c */,
|
||||
05132C7021A74D7B00379846 /* ozone_display.h */,
|
||||
05132C6921A74D7B00379846 /* ozone_entries.c */,
|
||||
05132C6C21A74D7B00379846 /* ozone_sidebar.c */,
|
||||
05132C6D21A74D7B00379846 /* ozone_sidebar.h */,
|
||||
05132C6621A74D7A00379846 /* ozone_texture.c */,
|
||||
05132C6F21A74D7B00379846 /* ozone_texture.h */,
|
||||
05132C6B21A74D7B00379846 /* ozone_theme.c */,
|
||||
05132C6721A74D7B00379846 /* ozone_theme.h */,
|
||||
05132C6A21A74D7B00379846 /* ozone.c */,
|
||||
05132C6821A74D7B00379846 /* ozone.h */,
|
||||
);
|
||||
path = ozone;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
05366511213F8BE5007E7EA0 /* qt */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -801,12 +829,12 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05A8C53520DB72F000FF7857 /* nuklear */,
|
||||
05132C6521A74D5100379846 /* ozone */,
|
||||
05A8C54020DB72F000FF7857 /* materialui.c */,
|
||||
05A8C53420DB72F000FF7857 /* menu_generic.c */,
|
||||
05A8C53320DB72F000FF7857 /* menu_generic.h */,
|
||||
05A8C53D20DB72F000FF7857 /* nuklear.c */,
|
||||
05A8C53E20DB72F000FF7857 /* null.c */,
|
||||
05EFAFC32191D64200D27059 /* ozone.c */,
|
||||
05A8C53C20DB72F000FF7857 /* rgui.c */,
|
||||
05EFAFC22191D64200D27059 /* stripes.c */,
|
||||
05A8C53220DB72F000FF7857 /* xmb.c */,
|
||||
|
Loading…
Reference in New Issue
Block a user