GS:MTL: Use presentDrawable on Ventura and during vsync

This commit is contained in:
TellowKrinkle 2022-11-12 22:34:50 -06:00 committed by tellowkrinkle
parent 656f0f7b16
commit 08f503748e
2 changed files with 25 additions and 3 deletions

View File

@ -31,6 +31,12 @@
class MetalHostDisplay final : public HostDisplay
{
enum class UsePresentDrawable : u8
{
Never = 0,
Always = 1,
IfVsync = 2,
};
MRCOwned<NSView*> m_view;
MRCOwned<CAMetalLayer*> m_layer;
GSMTLDevice m_dev;
@ -39,6 +45,7 @@ class MetalHostDisplay final : public HostDisplay
MRCOwned<id<CAMetalDrawable>> m_current_drawable;
MRCOwned<MTLRenderPassDescriptor*> m_pass_desc;
u32 m_capture_start_frame;
UsePresentDrawable m_use_present_drawable;
bool m_gpu_timing_enabled = false;
double m_accumulated_gpu_time = 0;
double m_last_gpu_time_end = 0;

View File

@ -129,6 +129,13 @@ bool MetalHostDisplay::CreateDevice(const WindowInfo& wi)
[m_pass_desc colorAttachments][0].clearColor = MTLClearColorMake(0, 0, 0, 0);
[m_pass_desc colorAttachments][0].storeAction = MTLStoreActionStore;
if (char* env = getenv("MTL_USE_PRESENT_DRAWABLE"))
m_use_present_drawable = static_cast<UsePresentDrawable>(atoi(env));
else if (@available(macOS 13.0, *))
m_use_present_drawable = UsePresentDrawable::Always;
else // Before Ventura, presentDrawable acts like vsync is on when windowed
m_use_present_drawable = UsePresentDrawable::IfVsync;
m_capture_start_frame = 0;
if (char* env = getenv("MTL_CAPTURE"))
{
@ -294,9 +301,17 @@ void MetalHostDisplay::EndPresent()
dev->RenderImGui(ImGui::GetDrawData());
dev->EndRenderPass();
if (m_current_drawable)
[dev->m_current_render_cmdbuf addScheduledHandler:[drawable = std::move(m_current_drawable)](id<MTLCommandBuffer>){
[drawable present];
}];
{
const bool use_present_drawable = m_use_present_drawable == UsePresentDrawable::Always ||
(m_use_present_drawable == UsePresentDrawable::IfVsync && m_vsync_mode != VsyncMode::Off);
if (use_present_drawable)
[dev->m_current_render_cmdbuf presentDrawable:m_current_drawable];
else
[dev->m_current_render_cmdbuf addScheduledHandler:[drawable = std::move(m_current_drawable)](id<MTLCommandBuffer>){
[drawable present];
}];
}
dev->FlushEncoders();
dev->FrameCompleted();
m_current_drawable = nullptr;