mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
PostProcessing: Add compile progress indicator
This commit is contained in:
parent
7e2afe82b5
commit
57aa138808
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#include "host_interface_progress_callback.h"
|
#include "host_interface_progress_callback.h"
|
||||||
|
@ -60,6 +60,9 @@ void HostInterfaceProgressCallback::SetProgressValue(u32 value)
|
||||||
|
|
||||||
void HostInterfaceProgressCallback::Redraw(bool force)
|
void HostInterfaceProgressCallback::Redraw(bool force)
|
||||||
{
|
{
|
||||||
|
if (m_last_progress_percent < 0 && m_open_time.GetTimeSeconds() < m_open_delay)
|
||||||
|
return;
|
||||||
|
|
||||||
const int percent =
|
const int percent =
|
||||||
static_cast<int>((static_cast<float>(m_progress_value) / static_cast<float>(m_progress_range)) * 100.0f);
|
static_cast<int>((static_cast<float>(m_progress_value) / static_cast<float>(m_progress_range)) * 100.0f);
|
||||||
if (percent == m_last_progress_percent && !force)
|
if (percent == m_last_progress_percent && !force)
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/progress_callback.h"
|
#include "common/progress_callback.h"
|
||||||
|
#include "common/timer.h"
|
||||||
|
|
||||||
class HostInterfaceProgressCallback final : public BaseProgressCallback
|
class HostInterfaceProgressCallback final : public BaseProgressCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HostInterfaceProgressCallback();
|
HostInterfaceProgressCallback();
|
||||||
|
|
||||||
|
ALWAYS_INLINE void SetOpenDelay(float delay) { m_open_delay = delay; }
|
||||||
|
|
||||||
void PushState() override;
|
void PushState() override;
|
||||||
void PopState() override;
|
void PopState() override;
|
||||||
|
|
||||||
|
@ -30,5 +34,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void Redraw(bool force);
|
void Redraw(bool force);
|
||||||
|
|
||||||
|
Common::Timer m_open_time;
|
||||||
|
float m_open_delay = 1.0f;
|
||||||
int m_last_progress_percent = -1;
|
int m_last_progress_percent = -1;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
// TODO: Remove me
|
// TODO: Remove me
|
||||||
#include "core/host.h"
|
#include "core/host.h"
|
||||||
|
#include "core/host_interface_progress_callback.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
|
||||||
#include "IconsFontAwesome5.h"
|
#include "IconsFontAwesome5.h"
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
#include "common/file_system.h"
|
#include "common/file_system.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/path.h"
|
#include "common/path.h"
|
||||||
|
#include "common/progress_callback.h"
|
||||||
#include "common/small_string.h"
|
#include "common/small_string.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
|
@ -464,6 +466,8 @@ void PostProcessing::LoadStages()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
|
HostInterfaceProgressCallback progress;
|
||||||
|
progress.SetProgressRange(stage_count);
|
||||||
|
|
||||||
for (u32 i = 0; i < stage_count; i++)
|
for (u32 i = 0; i < stage_count; i++)
|
||||||
{
|
{
|
||||||
|
@ -476,6 +480,7 @@ void PostProcessing::LoadStages()
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
progress.SetFormattedStatusText("Loading shader %s...", stage_name.c_str());
|
||||||
|
|
||||||
std::unique_ptr<Shader> shader = TryLoadingShader(stage_name, false, &error);
|
std::unique_ptr<Shader> shader = TryLoadingShader(stage_name, false, &error);
|
||||||
if (!shader)
|
if (!shader)
|
||||||
|
@ -487,6 +492,8 @@ void PostProcessing::LoadStages()
|
||||||
lock.lock();
|
lock.lock();
|
||||||
shader->LoadOptions(si, GetStageConfigSection(i));
|
shader->LoadOptions(si, GetStageConfigSection(i));
|
||||||
s_stages.push_back(std::move(shader));
|
s_stages.push_back(std::move(shader));
|
||||||
|
|
||||||
|
progress.IncrementProgressValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage_count > 0)
|
if (stage_count > 0)
|
||||||
|
@ -494,6 +501,13 @@ void PostProcessing::LoadStages()
|
||||||
s_timer.Reset();
|
s_timer.Reset();
|
||||||
Log_DevPrintf("Loaded %u post-processing stages.", stage_count);
|
Log_DevPrintf("Loaded %u post-processing stages.", stage_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// precompile shaders
|
||||||
|
if (g_gpu_device && g_gpu_device->GetWindowFormat() != GPUTexture::Format::Unknown)
|
||||||
|
{
|
||||||
|
CheckTargets(g_gpu_device->GetWindowFormat(), g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(),
|
||||||
|
&progress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostProcessing::UpdateSettings()
|
void PostProcessing::UpdateSettings()
|
||||||
|
@ -514,6 +528,11 @@ void PostProcessing::UpdateSettings()
|
||||||
|
|
||||||
s_stages.resize(stage_count);
|
s_stages.resize(stage_count);
|
||||||
|
|
||||||
|
HostInterfaceProgressCallback progress;
|
||||||
|
progress.SetProgressRange(stage_count);
|
||||||
|
|
||||||
|
const GPUTexture::Format prev_format = s_target_format;
|
||||||
|
|
||||||
for (u32 i = 0; i < stage_count; i++)
|
for (u32 i = 0; i < stage_count; i++)
|
||||||
{
|
{
|
||||||
std::string stage_name = Config::GetStageShaderName(si, i);
|
std::string stage_name = Config::GetStageShaderName(si, i);
|
||||||
|
@ -552,6 +571,9 @@ void PostProcessing::UpdateSettings()
|
||||||
s_stages[i]->LoadOptions(si, GetStageConfigSection(i));
|
s_stages[i]->LoadOptions(si, GetStageConfigSection(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prev_format != GPUTexture::Format::Unknown)
|
||||||
|
CheckTargets(prev_format, s_target_width, s_target_height, &progress);
|
||||||
|
|
||||||
if (stage_count > 0)
|
if (stage_count > 0)
|
||||||
{
|
{
|
||||||
s_timer.Reset();
|
s_timer.Reset();
|
||||||
|
@ -645,7 +667,8 @@ GPUTexture* PostProcessing::GetDummyTexture()
|
||||||
return s_dummy_texture.get();
|
return s_dummy_texture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostProcessing::CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height)
|
bool PostProcessing::CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height,
|
||||||
|
ProgressCallback* progress)
|
||||||
{
|
{
|
||||||
if (s_target_format == target_format && s_target_width == target_width && s_target_height == target_height)
|
if (s_target_format == target_format && s_target_width == target_width && s_target_height == target_height)
|
||||||
return true;
|
return true;
|
||||||
|
@ -661,9 +684,19 @@ bool PostProcessing::CheckTargets(GPUTexture::Format target_format, u32 target_w
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& shader : s_stages)
|
if (!progress)
|
||||||
|
progress = ProgressCallback::NullProgressCallback;
|
||||||
|
|
||||||
|
progress->SetProgressRange(static_cast<u32>(s_stages.size()));
|
||||||
|
progress->SetProgressValue(0);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < s_stages.size(); i++)
|
||||||
{
|
{
|
||||||
if (!shader->CompilePipeline(target_format, target_width, target_height) ||
|
Shader* const shader = s_stages[i].get();
|
||||||
|
|
||||||
|
progress->SetFormattedStatusText("Compiling %s...", shader->GetName().c_str());
|
||||||
|
|
||||||
|
if (!shader->CompilePipeline(target_format, target_width, target_height, progress) ||
|
||||||
!shader->ResizeOutput(target_format, target_width, target_height))
|
!shader->ResizeOutput(target_format, target_width, target_height))
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to compile one or more post-processing shaders, disabling.");
|
Log_ErrorPrintf("Failed to compile one or more post-processing shaders, disabling.");
|
||||||
|
@ -673,6 +706,8 @@ bool PostProcessing::CheckTargets(GPUTexture::Format target_format, u32 target_w
|
||||||
s_enabled = false;
|
s_enabled = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress->SetProgressValue(static_cast<u32>(i + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
s_target_format = target_format;
|
s_target_format = target_format;
|
||||||
|
@ -696,12 +731,6 @@ bool PostProcessing::Apply(GPUTexture* final_target, s32 final_left, s32 final_t
|
||||||
{
|
{
|
||||||
GL_SCOPE("PostProcessing Apply");
|
GL_SCOPE("PostProcessing Apply");
|
||||||
|
|
||||||
const u32 target_width = final_target ? final_target->GetWidth() : g_gpu_device->GetWindowWidth();
|
|
||||||
const u32 target_height = final_target ? final_target->GetHeight() : g_gpu_device->GetWindowHeight();
|
|
||||||
const GPUTexture::Format target_format = final_target ? final_target->GetFormat() : g_gpu_device->GetWindowFormat();
|
|
||||||
if (!CheckTargets(target_format, target_width, target_height))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
GPUTexture* input = s_input_texture.get();
|
GPUTexture* input = s_input_texture.get();
|
||||||
GPUTexture* output = s_output_texture.get();
|
GPUTexture* output = s_output_texture.get();
|
||||||
input->MakeReadyForSampling();
|
input->MakeReadyForSampling();
|
||||||
|
|
|
@ -19,6 +19,7 @@ class GPUTexture;
|
||||||
|
|
||||||
class Error;
|
class Error;
|
||||||
class SettingsInterface;
|
class SettingsInterface;
|
||||||
|
class ProgressCallback;
|
||||||
|
|
||||||
namespace PostProcessing {
|
namespace PostProcessing {
|
||||||
struct ShaderOption
|
struct ShaderOption
|
||||||
|
@ -124,7 +125,7 @@ void Shutdown();
|
||||||
GPUTexture* GetInputTexture();
|
GPUTexture* GetInputTexture();
|
||||||
const Common::Timer& GetTimer();
|
const Common::Timer& GetTimer();
|
||||||
|
|
||||||
bool CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height);
|
bool CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height, ProgressCallback* progress = nullptr);
|
||||||
|
|
||||||
bool Apply(GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width, s32 final_height, s32 orig_width,
|
bool Apply(GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width, s32 final_height, s32 orig_width,
|
||||||
s32 orig_height);
|
s32 orig_height);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
class GPUPipeline;
|
class GPUPipeline;
|
||||||
class GPUTexture;
|
class GPUTexture;
|
||||||
|
class ProgressCallback;
|
||||||
|
|
||||||
namespace PostProcessing {
|
namespace PostProcessing {
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ public:
|
||||||
|
|
||||||
virtual bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) = 0;
|
virtual bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) = 0;
|
||||||
|
|
||||||
virtual bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height) = 0;
|
virtual bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) = 0;
|
||||||
|
|
||||||
virtual bool Apply(GPUTexture* input, GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width,
|
virtual bool Apply(GPUTexture* input, GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width,
|
||||||
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) = 0;
|
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) = 0;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "common/image.h"
|
#include "common/image.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/path.h"
|
#include "common/path.h"
|
||||||
|
#include "common/progress_callback.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
|
||||||
#include "effect_codegen.hpp"
|
#include "effect_codegen.hpp"
|
||||||
|
@ -1123,7 +1124,8 @@ GPUTexture* PostProcessing::ReShadeFXShader::GetTextureByID(TextureID id, GPUTex
|
||||||
return m_textures[static_cast<size_t>(id)].texture.get();
|
return m_textures[static_cast<size_t>(id)].texture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format, u32 width, u32 height)
|
bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format, u32 width, u32 height,
|
||||||
|
ProgressCallback* progress)
|
||||||
{
|
{
|
||||||
const RenderAPI api = g_gpu_device->GetRenderAPI();
|
const RenderAPI api = g_gpu_device->GetRenderAPI();
|
||||||
const bool needs_main_defn = (api != RenderAPI::D3D11 && api != RenderAPI::D3D12);
|
const bool needs_main_defn = (api != RenderAPI::D3D11 && api != RenderAPI::D3D12);
|
||||||
|
@ -1219,6 +1221,14 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
|
||||||
plconfig.samples = 1;
|
plconfig.samples = 1;
|
||||||
plconfig.per_sample_shading = false;
|
plconfig.per_sample_shading = false;
|
||||||
|
|
||||||
|
progress->PushState();
|
||||||
|
|
||||||
|
size_t total_passes = 0;
|
||||||
|
for (const reshadefx::technique_info& tech : mod.techniques)
|
||||||
|
total_passes += tech.passes.size();
|
||||||
|
progress->SetProgressRange(static_cast<u32>(total_passes));
|
||||||
|
progress->SetProgressValue(0);
|
||||||
|
|
||||||
u32 passnum = 0;
|
u32 passnum = 0;
|
||||||
for (const reshadefx::technique_info& tech : mod.techniques)
|
for (const reshadefx::technique_info& tech : mod.techniques)
|
||||||
{
|
{
|
||||||
|
@ -1230,7 +1240,10 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
|
||||||
auto vs = get_shader(info.vs_entry_point, pass.samplers, GPUShaderStage::Vertex);
|
auto vs = get_shader(info.vs_entry_point, pass.samplers, GPUShaderStage::Vertex);
|
||||||
auto fs = get_shader(info.ps_entry_point, pass.samplers, GPUShaderStage::Fragment);
|
auto fs = get_shader(info.ps_entry_point, pass.samplers, GPUShaderStage::Fragment);
|
||||||
if (!vs || !fs)
|
if (!vs || !fs)
|
||||||
|
{
|
||||||
|
progress->PopState();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < pass.render_targets.size(); i++)
|
for (size_t i = 0; i < pass.render_targets.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -1247,17 +1260,25 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
|
||||||
plconfig.fragment_shader = fs.get();
|
plconfig.fragment_shader = fs.get();
|
||||||
plconfig.geometry_shader = nullptr;
|
plconfig.geometry_shader = nullptr;
|
||||||
if (!plconfig.vertex_shader || !plconfig.fragment_shader)
|
if (!plconfig.vertex_shader || !plconfig.fragment_shader)
|
||||||
|
{
|
||||||
|
progress->PopState();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
pass.pipeline = g_gpu_device->CreatePipeline(plconfig);
|
pass.pipeline = g_gpu_device->CreatePipeline(plconfig);
|
||||||
if (!pass.pipeline)
|
if (!pass.pipeline)
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to create pipeline for pass '%s'", info.name.c_str());
|
Log_ErrorPrintf("Failed to create pipeline for pass '%s'", info.name.c_str());
|
||||||
|
progress->PopState();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress->SetProgressValue(passnum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress->PopState();
|
||||||
|
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
bool LoadFromString(std::string name, std::string filename, std::string code, bool only_config, Error* error);
|
bool LoadFromString(std::string name, std::string filename, std::string code, bool only_config, Error* error);
|
||||||
|
|
||||||
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
||||||
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height) override;
|
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) override;
|
||||||
bool Apply(GPUTexture* input, GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width,
|
bool Apply(GPUTexture* input, GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width,
|
||||||
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) override;
|
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) override;
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ void PostProcessing::GLSLShader::FillUniformBuffer(void* buffer, u32 texture_wid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostProcessing::GLSLShader::CompilePipeline(GPUTexture::Format format, u32 width, u32 height)
|
bool PostProcessing::GLSLShader::CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress)
|
||||||
{
|
{
|
||||||
if (m_pipeline)
|
if (m_pipeline)
|
||||||
m_pipeline.reset();
|
m_pipeline.reset();
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
bool LoadFromString(std::string name, std::string code, Error* error);
|
bool LoadFromString(std::string name, std::string code, Error* error);
|
||||||
|
|
||||||
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
||||||
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height) override;
|
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) override;
|
||||||
bool Apply(GPUTexture* input, GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width,
|
bool Apply(GPUTexture* input, GPUTexture* final_target, s32 final_left, s32 final_top, s32 final_width,
|
||||||
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) override;
|
s32 final_height, s32 orig_width, s32 orig_height, u32 target_width, u32 target_height) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue