Metal changes

This commit is contained in:
Stenzek 2023-08-07 20:42:20 +10:00
parent 4cdeb2b5a6
commit 3291675e54
3 changed files with 51 additions and 8 deletions

View File

@ -192,7 +192,7 @@ public:
AdapterAndModeList GetAdapterAndModeList() override;
void DestroySurface() override;
std::string GetShaderCacheBaseName(const std::string_view& type, bool debug) const override;
std::string GetShaderCacheBaseName(const std::string_view& type) const override;
std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
GPUTexture::Type type, GPUTexture::Format format,
@ -274,7 +274,7 @@ public:
static AdapterAndModeList StaticGetAdapterAndModeList();
protected:
bool CreateDevice(const std::string_view& adapter, bool debug_device) override;
bool CreateDevice(const std::string_view& adapter) override;
void DestroyDevice() override;
private:
@ -319,6 +319,7 @@ private:
bool CreateLayer();
void DestroyLayer();
void RenderBlankFrame();
bool CreateBuffers();
void DestroyBuffers();

View File

@ -113,7 +113,7 @@ void MetalDevice::SetVSync(bool enabled)
[m_layer setDisplaySyncEnabled:enabled];
}
bool MetalDevice::CreateDevice(const std::string_view& adapter, bool debug_device)
bool MetalDevice::CreateDevice(const std::string_view& adapter)
{
@autoreleasepool
{
@ -142,8 +142,7 @@ bool MetalDevice::CreateDevice(const std::string_view& adapter, bool debug_devic
return false;
CreateCommandBuffer();
Panic("Render blank frame!");
RenderBlankFrame();
if (!CreateBuffers())
{
@ -277,6 +276,23 @@ void MetalDevice::DestroyLayer()
});
}
void MetalDevice::RenderBlankFrame()
{
DebugAssert(!InRenderPass());
if (m_layer == nil)
return;
@autoreleasepool
{
id<MTLDrawable> drawable = [m_layer nextDrawable];
m_layer_pass_desc.colorAttachments[0].texture = [drawable texture];
id<MTLRenderCommandEncoder> encoder = [m_render_cmdbuf renderCommandEncoderWithDescriptor:m_layer_pass_desc];
[encoder endEncoding];
[m_render_cmdbuf presentDrawable:drawable];
SubmitCommandBuffer();
}
}
bool MetalDevice::UpdateWindow()
{
if (InRenderPass())
@ -300,9 +316,9 @@ void MetalDevice::DestroySurface()
DestroyLayer();
}
std::string MetalDevice::GetShaderCacheBaseName(const std::string_view& type, bool debug) const
std::string MetalDevice::GetShaderCacheBaseName(const std::string_view& type) const
{
return fmt::format("metal_{}{}", type, debug ? "_debug" : "");
return fmt::format("metal_{}{}", type, m_debug_device ? "_debug" : "");
}
void MetalDevice::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
@ -1374,6 +1390,30 @@ void MetalDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u3
#endif
}
void MetalDevice::ClearRenderTarget(GPUTexture* t, u32 c)
{
GPUDevice::ClearRenderTarget(t, c);
if (InRenderPass() && m_current_framebuffer && m_current_framebuffer->GetRT() == t)
EndRenderPass();
}
void MetalDevice::ClearDepth(GPUTexture* t, float d)
{
GPUDevice::ClearDepth(t, d);
if (InRenderPass() && m_current_framebuffer && m_current_framebuffer->GetDS() == t)
EndRenderPass();
}
void MetalDevice::InvalidateRenderTarget(GPUTexture* t)
{
GPUDevice::InvalidateRenderTarget(t);
if (InRenderPass() && m_current_framebuffer &&
(m_current_framebuffer->GetRT() == t || m_current_framebuffer->GetDS() == t))
{
EndRenderPass();
}
}
void MetalDevice::CommitClear(MetalTexture* tex)
{
if (tex->GetState() == GPUTexture::State::Dirty)
@ -1881,6 +1921,7 @@ void MetalDevice::EndPresent()
[m_render_cmdbuf presentDrawable:m_layer_drawable];
[m_layer_drawable release];
m_layer_drawable = nil;
SubmitCommandBuffer();
}

View File

@ -2211,6 +2211,7 @@ void System::DoRunFrame()
// Generate any pending samples from the SPU before sleeping, this way we reduce the chances of underruns.
SPU::GeneratePendingSamples();
g_gpu->RestoreGraphicsAPIState();
g_gpu->FlushRender();
if (s_cheat_list)
@ -2283,7 +2284,7 @@ void System::Throttle()
// Use a spinwait if we undersleep for all platforms except android.. don't want to burn battery.
// Linux also seems to do a much better job of waking up at the requested time.
#if !defined(__linux__) && !defined(__ANDROID__)
#if !defined(__linux__) && !defined(__ANDROID__) && !defined(__APPLE__)
Common::Timer::SleepUntil(s_next_frame_time, g_settings.display_all_frames);
#else
Common::Timer::SleepUntil(s_next_frame_time, false);