WIP
This commit is contained in:
parent
a04490d569
commit
1298246ed7
|
@ -72,6 +72,7 @@ public:
|
|||
virtual bool CreateResources() = 0;
|
||||
virtual void DestroyResources() = 0;
|
||||
|
||||
virtual bool SetScalingShader(const std::string_view& config) = 0;
|
||||
virtual bool SetPostProcessingChain(const std::string_view& config) = 0;
|
||||
|
||||
/// Call when the window size changes externally to recreate any resources.
|
||||
|
|
|
@ -461,6 +461,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
|
|||
si.SetBoolValue("Display", "ShowResolution", false);
|
||||
si.SetBoolValue("Display", "Fullscreen", false);
|
||||
si.SetBoolValue("Display", "VSync", true);
|
||||
si.SetStringValue("Display", "ScaleShader", "");
|
||||
si.SetStringValue("Display", "PostProcessChain", "");
|
||||
|
||||
si.SetBoolValue("CDROM", "ReadThread", true);
|
||||
|
|
|
@ -175,6 +175,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
display_show_speed = si.GetBoolValue("Display", "ShowSpeed", false);
|
||||
display_show_resolution = si.GetBoolValue("Display", "ShowResolution", false);
|
||||
video_sync_enabled = si.GetBoolValue("Display", "VSync", true);
|
||||
display_scale_shader = si.GetStringValue("Display", "ScaleShader", "");
|
||||
display_post_process_chain = si.GetStringValue("Display", "PostProcessChain", "");
|
||||
|
||||
cdrom_read_thread = si.GetBoolValue("CDROM", "ReadThread", true);
|
||||
|
@ -298,6 +299,11 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("Display", "ShowSpeed", display_show_speed);
|
||||
si.SetBoolValue("Display", "ShowResolution", display_show_speed);
|
||||
si.SetBoolValue("Display", "VSync", video_sync_enabled);
|
||||
if (display_scale_shader.empty())
|
||||
si.DeleteValue("Display", "ScaleShader");
|
||||
else
|
||||
si.SetStringValue("Display", "ScaleShader", display_scale_shader.c_str());
|
||||
|
||||
if (display_post_process_chain.empty())
|
||||
si.DeleteValue("Display", "PostProcessChain");
|
||||
else
|
||||
|
|
|
@ -91,6 +91,7 @@ struct Settings
|
|||
|
||||
GPURenderer gpu_renderer = GPURenderer::Software;
|
||||
std::string gpu_adapter;
|
||||
std::string display_scale_shader;
|
||||
std::string display_post_process_chain;
|
||||
u32 gpu_resolution_scale = 1;
|
||||
u32 gpu_multisamples = 1;
|
||||
|
|
|
@ -177,6 +177,7 @@ void CommonHostInterface::DestroySystem()
|
|||
SetTimerResolutionIncreased(false);
|
||||
m_save_state_selector_ui->Close();
|
||||
m_display->SetPostProcessingChain({});
|
||||
m_display->SetScalingShader({});
|
||||
|
||||
HostInterface::DestroySystem();
|
||||
}
|
||||
|
@ -715,6 +716,9 @@ void CommonHostInterface::OnSystemCreated()
|
|||
{
|
||||
HostInterface::OnSystemCreated();
|
||||
|
||||
if (!g_settings.display_scale_shader.empty() && !m_display->SetScalingShader(g_settings.display_scale_shader))
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load scaling shader."), 20.0f);
|
||||
|
||||
if (g_settings.display_post_processing && !m_display->SetPostProcessingChain(g_settings.display_post_process_chain))
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
|
||||
}
|
||||
|
@ -2082,6 +2086,12 @@ void CommonHostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
|||
UpdateSpeedLimiterState();
|
||||
}
|
||||
|
||||
if (g_settings.display_scale_shader != old_settings.display_scale_shader)
|
||||
{
|
||||
if (!m_display->SetScalingShader(g_settings.display_post_process_chain))
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load scaling shader."), 20.0f);
|
||||
}
|
||||
|
||||
if (g_settings.display_post_processing != old_settings.display_post_processing ||
|
||||
g_settings.display_post_process_chain != old_settings.display_post_process_chain)
|
||||
{
|
||||
|
@ -2469,13 +2479,24 @@ void CommonHostInterface::TogglePostProcessing()
|
|||
|
||||
void CommonHostInterface::ReloadPostProcessingShaders()
|
||||
{
|
||||
if (!m_display || !g_settings.display_post_processing)
|
||||
if (!m_display)
|
||||
return;
|
||||
|
||||
if (!m_display->SetPostProcessingChain(g_settings.display_post_process_chain))
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post-processing shader chain."), 20.0f);
|
||||
else
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Post-processing shaders reloaded."), 10.0f);
|
||||
if (!g_settings.display_scale_shader.empty())
|
||||
{
|
||||
if (!m_display->SetScalingShader(g_settings.display_scale_shader))
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load scaling shader."), 20.0f);
|
||||
else
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Scaling shader reloaded."), 10.0f);
|
||||
}
|
||||
|
||||
if (g_settings.display_post_processing)
|
||||
{
|
||||
if (!m_display->SetPostProcessingChain(g_settings.display_post_process_chain))
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post-processing shader chain."), 20.0f);
|
||||
else
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Post-processing shaders reloaded."), 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
bool CommonHostInterface::ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height,
|
||||
|
|
|
@ -724,19 +724,38 @@ void D3D11HostDisplay::RenderDisplay(s32 left, s32 top, s32 width, s32 height, v
|
|||
s32 texture_view_height, bool linear_filter)
|
||||
{
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->VSSetShader(m_display_vertex_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_display_pixel_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetShaderResources(0, 1, reinterpret_cast<ID3D11ShaderResourceView**>(&texture_handle));
|
||||
m_context->PSSetSamplers(0, 1, linear_filter ? m_linear_sampler.GetAddressOf() : m_point_sampler.GetAddressOf());
|
||||
m_context->PSSetSamplers(0, 1,
|
||||
(linear_filter && !m_scale_stage.has_value()) ? m_linear_sampler.GetAddressOf() :
|
||||
m_point_sampler.GetAddressOf());
|
||||
|
||||
if (!m_scale_stage)
|
||||
{
|
||||
const float uniforms[4] = {static_cast<float>(texture_view_x) / static_cast<float>(texture_width),
|
||||
static_cast<float>(texture_view_y) / static_cast<float>(texture_height),
|
||||
(static_cast<float>(texture_view_width) - 0.5f) / static_cast<float>(texture_width),
|
||||
(static_cast<float>(texture_view_height) - 0.5f) / static_cast<float>(texture_height)};
|
||||
const auto map =
|
||||
m_display_uniform_buffer.Map(m_context.Get(), m_display_uniform_buffer.GetSize(), sizeof(uniforms));
|
||||
std::memcpy(map.pointer, uniforms, sizeof(uniforms));
|
||||
m_display_uniform_buffer.Unmap(m_context.Get(), sizeof(uniforms));
|
||||
m_context->VSSetShader(m_display_vertex_shader.Get(), nullptr, 0);
|
||||
m_context->VSSetConstantBuffers(0, 1, m_display_uniform_buffer.GetD3DBufferArray());
|
||||
m_context->PSSetShader(m_display_pixel_shader.Get(), nullptr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto map =
|
||||
m_display_uniform_buffer.Map(m_context.Get(), m_display_uniform_buffer.GetSize(), m_scale_stage->uniforms_size);
|
||||
m_scale_shader->FillUniformBuffer(map.pointer, texture_width, texture_height, texture_view_x, texture_view_y,
|
||||
texture_view_width, texture_view_height, width, height, 0.0f);
|
||||
m_display_uniform_buffer.Unmap(m_context.Get(), m_scale_stage->uniforms_size);
|
||||
m_context->VSSetShader(m_scale_stage->vertex_shader.Get(), nullptr, 0);
|
||||
m_context->VSSetConstantBuffers(0, 1, m_display_uniform_buffer.GetD3DBufferArray());
|
||||
m_context->PSSetShader(m_scale_stage->pixel_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetConstantBuffers(0, 1, m_display_uniform_buffer.GetD3DBufferArray());
|
||||
}
|
||||
|
||||
const float uniforms[4] = {static_cast<float>(texture_view_x) / static_cast<float>(texture_width),
|
||||
static_cast<float>(texture_view_y) / static_cast<float>(texture_height),
|
||||
(static_cast<float>(texture_view_width) - 0.5f) / static_cast<float>(texture_width),
|
||||
(static_cast<float>(texture_view_height) - 0.5f) / static_cast<float>(texture_height)};
|
||||
const auto map = m_display_uniform_buffer.Map(m_context.Get(), m_display_uniform_buffer.GetSize(), sizeof(uniforms));
|
||||
std::memcpy(map.pointer, uniforms, sizeof(uniforms));
|
||||
m_display_uniform_buffer.Unmap(m_context.Get(), sizeof(uniforms));
|
||||
m_context->VSSetConstantBuffers(0, 1, m_display_uniform_buffer.GetD3DBufferArray());
|
||||
|
||||
const CD3D11_VIEWPORT vp(static_cast<float>(left), static_cast<float>(top), static_cast<float>(width),
|
||||
static_cast<float>(height));
|
||||
|
@ -862,6 +881,43 @@ D3D11HostDisplay::AdapterInfo D3D11HostDisplay::GetAdapterInfo(IDXGIFactory* dxg
|
|||
return adapter_info;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::SetScalingShader(const std::string_view& config)
|
||||
{
|
||||
if (config.empty())
|
||||
{
|
||||
m_scale_shader.reset();
|
||||
m_scale_stage.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
m_scale_shader = PostProcessingShader();
|
||||
if (!PostProcessingChain::CreateSingleShader(&m_scale_shader.value(), config))
|
||||
{
|
||||
m_scale_shader.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_scale_stage = PostProcessingStage();
|
||||
if (!CompilePostProcessingStage(m_scale_shader.value(), &m_scale_stage.value()))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to compile resize shader");
|
||||
m_scale_stage.reset();
|
||||
m_scale_shader.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_display_uniform_buffer.GetSize() < m_scale_stage->uniforms_size &&
|
||||
!m_display_uniform_buffer.Create(m_device.Get(), D3D11_BIND_CONSTANT_BUFFER, m_scale_stage->uniforms_size))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to allocate %u byte constant buffer for scaling", m_scale_stage->uniforms_size);
|
||||
m_scale_stage.reset();
|
||||
m_scale_shader.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::SetPostProcessingChain(const std::string_view& config)
|
||||
{
|
||||
if (config.empty())
|
||||
|
@ -882,17 +938,10 @@ bool D3D11HostDisplay::SetPostProcessingChain(const std::string_view& config)
|
|||
|
||||
for (u32 i = 0; i < m_post_processing_chain.GetStageCount(); i++)
|
||||
{
|
||||
const PostProcessingShader& shader = m_post_processing_chain.GetShaderStage(i);
|
||||
const std::string vs = shadergen.GeneratePostProcessingVertexShader(shader);
|
||||
const std::string ps = shadergen.GeneratePostProcessingFragmentShader(shader);
|
||||
|
||||
PostProcessingStage stage;
|
||||
stage.uniforms_size = shader.GetUniformsSize();
|
||||
stage.vertex_shader =
|
||||
D3D11::ShaderCompiler::CompileAndCreateVertexShader(m_device.Get(), vs, g_settings.gpu_use_debug_device);
|
||||
stage.pixel_shader =
|
||||
D3D11::ShaderCompiler::CompileAndCreatePixelShader(m_device.Get(), ps, g_settings.gpu_use_debug_device);
|
||||
if (!stage.vertex_shader || !stage.pixel_shader)
|
||||
|
||||
const PostProcessingShader& shader = m_post_processing_chain.GetShaderStage(i);
|
||||
if (!CompilePostProcessingStage(shader, &stage))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to compile one or more post-processing shaders, disabling.");
|
||||
m_post_processing_stages.clear();
|
||||
|
@ -944,6 +993,21 @@ bool D3D11HostDisplay::CheckPostProcessingRenderTargets(u32 target_width, u32 ta
|
|||
return true;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::CompilePostProcessingStage(const PostProcessingShader& shader, PostProcessingStage* stage)
|
||||
{
|
||||
FrontendCommon::PostProcessingShaderGen shadergen(HostDisplay::RenderAPI::D3D11, true);
|
||||
|
||||
const std::string vs = shadergen.GeneratePostProcessingVertexShader(shader);
|
||||
const std::string ps = shadergen.GeneratePostProcessingFragmentShader(shader);
|
||||
|
||||
stage->uniforms_size = shader.GetUniformsSize();
|
||||
stage->vertex_shader =
|
||||
D3D11::ShaderCompiler::CompileAndCreateVertexShader(m_device.Get(), vs, g_settings.gpu_use_debug_device);
|
||||
stage->pixel_shader =
|
||||
D3D11::ShaderCompiler::CompileAndCreatePixelShader(m_device.Get(), ps, g_settings.gpu_use_debug_device);
|
||||
return stage->vertex_shader && stage->pixel_shader;
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::ApplyPostProcessingChain(ID3D11RenderTargetView* final_target, s32 final_left, s32 final_top,
|
||||
s32 final_width, s32 final_height, void* texture_handle,
|
||||
u32 texture_width, s32 texture_height, s32 texture_view_x,
|
||||
|
@ -1013,6 +1077,11 @@ void D3D11HostDisplay::ApplyPostProcessingChain(ID3D11RenderTargetView* final_ta
|
|||
|
||||
#else // LIBRETRO
|
||||
|
||||
bool D3D11HostDisplay::SetScalingShader(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::SetPostProcessingChain(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <d3d11.h>
|
||||
#include <dxgi.h>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
@ -49,6 +50,7 @@ public:
|
|||
virtual bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||
virtual void DestroyRenderSurface() override;
|
||||
|
||||
virtual bool SetScalingShader(const std::string_view& config) override;
|
||||
virtual bool SetPostProcessingChain(const std::string_view& config) override;
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* initial_data,
|
||||
|
@ -108,6 +110,7 @@ protected:
|
|||
};
|
||||
|
||||
bool CheckPostProcessingRenderTargets(u32 target_width, u32 target_height);
|
||||
bool CompilePostProcessingStage(const PostProcessingShader& shader, PostProcessingStage* stage);
|
||||
void ApplyPostProcessingChain(ID3D11RenderTargetView* final_target, s32 final_left, s32 final_top, s32 final_width,
|
||||
s32 final_height, void* texture_handle, u32 texture_width, s32 texture_height,
|
||||
s32 texture_view_x, s32 texture_view_y, s32 texture_view_width,
|
||||
|
@ -142,6 +145,8 @@ protected:
|
|||
bool m_using_allow_tearing = false;
|
||||
bool m_vsync = true;
|
||||
|
||||
std::optional<PostProcessingShader> m_scale_shader;
|
||||
std::optional<PostProcessingStage> m_scale_stage;
|
||||
PostProcessingChain m_post_processing_chain;
|
||||
D3D11::Texture m_post_processing_input_texture;
|
||||
std::vector<PostProcessingStage> m_post_processing_stages;
|
||||
|
|
|
@ -572,6 +572,11 @@ void OpenGLHostDisplay::RenderSoftwareCursor(s32 left, s32 bottom, s32 width, s3
|
|||
|
||||
#ifndef LIBRETRO
|
||||
|
||||
bool OpenGLHostDisplay::SetScalingShader(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::SetPostProcessingChain(const std::string_view& config)
|
||||
{
|
||||
if (config.empty())
|
||||
|
@ -742,6 +747,11 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_
|
|||
|
||||
#else
|
||||
|
||||
bool OpenGLHostDisplay::SetScalingShader(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::SetPostProcessingChain(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
virtual bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||
virtual void DestroyRenderSurface() override;
|
||||
|
||||
virtual bool SetScalingShader(const std::string_view& config) override;
|
||||
virtual bool SetPostProcessingChain(const std::string_view& config) override;
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* initial_data,
|
||||
|
|
|
@ -128,6 +128,25 @@ bool PostProcessingChain::CreateFromString(const std::string_view& chain_config)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PostProcessingChain::CreateSingleShader(PostProcessingShader* shader, const std::string_view& shader_config)
|
||||
{
|
||||
size_t first_shader_sep = shader_config.find(';');
|
||||
if (first_shader_sep == std::string::npos)
|
||||
first_shader_sep = shader_config.size();
|
||||
|
||||
const std::string_view shader_name = shader_config.substr(0, first_shader_sep);
|
||||
if (shader_name.empty())
|
||||
return false;
|
||||
|
||||
if (!TryLoadingShader(shader, shader_name))
|
||||
return false;
|
||||
|
||||
if (first_shader_sep < shader_config.size())
|
||||
shader->SetConfigString(shader_config.substr(first_shader_sep + 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> PostProcessingChain::GetAvailableShaderNames()
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
bool CreateFromString(const std::string_view& chain_config);
|
||||
|
||||
static std::vector<std::string> GetAvailableShaderNames();
|
||||
static bool CreateSingleShader(PostProcessingShader* shader, const std::string_view& shader_config);
|
||||
|
||||
private:
|
||||
std::vector<PostProcessingShader> m_shaders;
|
||||
|
|
|
@ -750,6 +750,11 @@ VulkanHostDisplay::PostProcessingStage::~PostProcessingStage()
|
|||
g_vulkan_context->DeferPipelineDestruction(pipeline);
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::SetScalingShader(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::SetPostProcessingChain(const std::string_view& config)
|
||||
{
|
||||
g_vulkan_context->ExecuteCommandBuffer(true);
|
||||
|
@ -991,6 +996,11 @@ void VulkanHostDisplay::ApplyPostProcessingChain(s32 final_left, s32 final_top,
|
|||
|
||||
#else // LIBRETRO
|
||||
|
||||
bool VulkanHostDisplay::SetScalingShader(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::SetPostProcessingChain(const std::string_view& config)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
virtual bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override;
|
||||
virtual void DestroyRenderSurface() override;
|
||||
|
||||
virtual bool SetScalingShader(const std::string_view& config) override;
|
||||
virtual bool SetPostProcessingChain(const std::string_view& config) override;
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* initial_data,
|
||||
|
|
Loading…
Reference in New Issue