Allow to interrupt shader precompilation by stopping emulation
This commit is contained in:
parent
aad42de6c9
commit
dcad3ec892
|
@ -9,6 +9,8 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
|
|
||||||
|
#include "Core/Core.h"
|
||||||
|
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
AsyncShaderCompiler::AsyncShaderCompiler()
|
AsyncShaderCompiler::AsyncShaderCompiler()
|
||||||
|
@ -65,17 +67,11 @@ bool AsyncShaderCompiler::HasCompletedWork()
|
||||||
return !m_completed_work.empty();
|
return !m_completed_work.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncShaderCompiler::WaitUntilCompletion()
|
bool AsyncShaderCompiler::WaitUntilCompletion(
|
||||||
{
|
|
||||||
while (HasPendingWork())
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncShaderCompiler::WaitUntilCompletion(
|
|
||||||
const std::function<void(size_t, size_t)>& progress_callback)
|
const std::function<void(size_t, size_t)>& progress_callback)
|
||||||
{
|
{
|
||||||
if (!HasPendingWork())
|
if (!HasPendingWork())
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
// Wait a second before opening a progress dialog.
|
// Wait a second before opening a progress dialog.
|
||||||
// This way, if the operation completes quickly, we don't annoy the user.
|
// This way, if the operation completes quickly, we don't annoy the user.
|
||||||
|
@ -85,11 +81,11 @@ void AsyncShaderCompiler::WaitUntilCompletion(
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(CHECK_INTERVAL));
|
std::this_thread::sleep_for(std::chrono::milliseconds(CHECK_INTERVAL));
|
||||||
if (!HasPendingWork())
|
if (!HasPendingWork())
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the number of pending items. We use this to work out how many are left.
|
// Grab the number of pending items. We use this to work out how many are left.
|
||||||
size_t total_items = 0;
|
size_t total_items;
|
||||||
{
|
{
|
||||||
// Safe to hold both locks here, since nowhere else does.
|
// Safe to hold both locks here, since nowhere else does.
|
||||||
std::lock_guard<std::mutex> pending_guard(m_pending_work_lock);
|
std::lock_guard<std::mutex> pending_guard(m_pending_work_lock);
|
||||||
|
@ -100,6 +96,9 @@ void AsyncShaderCompiler::WaitUntilCompletion(
|
||||||
// Update progress while the compiles complete.
|
// Update progress while the compiles complete.
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
if (Core::GetState() == Core::State::Stopping)
|
||||||
|
return false;
|
||||||
|
|
||||||
size_t remaining_items;
|
size_t remaining_items;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> pending_guard(m_pending_work_lock);
|
std::lock_guard<std::mutex> pending_guard(m_pending_work_lock);
|
||||||
|
@ -111,6 +110,7 @@ void AsyncShaderCompiler::WaitUntilCompletion(
|
||||||
progress_callback(total_items - remaining_items, total_items);
|
progress_callback(total_items - remaining_items, total_items);
|
||||||
std::this_thread::sleep_for(CHECK_INTERVAL);
|
std::this_thread::sleep_for(CHECK_INTERVAL);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsyncShaderCompiler::StartWorkerThreads(u32 num_worker_threads)
|
bool AsyncShaderCompiler::StartWorkerThreads(u32 num_worker_threads)
|
||||||
|
|
|
@ -49,11 +49,9 @@ public:
|
||||||
bool HasPendingWork();
|
bool HasPendingWork();
|
||||||
bool HasCompletedWork();
|
bool HasCompletedWork();
|
||||||
|
|
||||||
// Simpler version without progress updates.
|
|
||||||
void WaitUntilCompletion();
|
|
||||||
|
|
||||||
// Calls progress_callback periodically, with completed_items, and total_items.
|
// Calls progress_callback periodically, with completed_items, and total_items.
|
||||||
void WaitUntilCompletion(const std::function<void(size_t, size_t)>& progress_callback);
|
// Returns false if interrupted.
|
||||||
|
bool WaitUntilCompletion(const std::function<void(size_t, size_t)>& progress_callback);
|
||||||
|
|
||||||
// Needed because of calling virtual methods in shutdown procedure.
|
// Needed because of calling virtual methods in shutdown procedure.
|
||||||
bool StartWorkerThreads(u32 num_worker_threads);
|
bool StartWorkerThreads(u32 num_worker_threads);
|
||||||
|
|
|
@ -157,9 +157,12 @@ const AbstractPipeline* ShaderCache::GetUberPipelineForUid(const GXUberPipelineU
|
||||||
|
|
||||||
void ShaderCache::WaitForAsyncCompiler()
|
void ShaderCache::WaitForAsyncCompiler()
|
||||||
{
|
{
|
||||||
while (m_async_shader_compiler->HasPendingWork() || m_async_shader_compiler->HasCompletedWork())
|
bool running = true;
|
||||||
|
|
||||||
|
while (running &&
|
||||||
|
(m_async_shader_compiler->HasPendingWork() || m_async_shader_compiler->HasCompletedWork()))
|
||||||
{
|
{
|
||||||
m_async_shader_compiler->WaitUntilCompletion([](size_t completed, size_t total) {
|
running = m_async_shader_compiler->WaitUntilCompletion([](size_t completed, size_t total) {
|
||||||
g_renderer->BeginUIFrame();
|
g_renderer->BeginUIFrame();
|
||||||
|
|
||||||
const float center_x = ImGui::GetIO().DisplaySize.x * 0.5f;
|
const float center_x = ImGui::GetIO().DisplaySize.x * 0.5f;
|
||||||
|
|
Loading…
Reference in New Issue