mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 05:45:38 +00:00
GPU: Add scaling shader support
Currently only Bilinear (Sharp).
This commit is contained in:
parent
9439cf65a3
commit
09e7a5843f
|
@ -46,6 +46,8 @@ add_library(core
|
|||
gpu_hw.h
|
||||
gpu_hw_shadergen.cpp
|
||||
gpu_hw_shadergen.h
|
||||
gpu_shadergen.cpp
|
||||
gpu_shadergen.h
|
||||
gpu_sw.cpp
|
||||
gpu_sw.h
|
||||
gpu_sw_backend.cpp
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<ClCompile Include="gpu_backend.cpp" />
|
||||
<ClCompile Include="gpu_commands.cpp" />
|
||||
<ClCompile Include="gpu_hw_shadergen.cpp" />
|
||||
<ClCompile Include="gpu_shadergen.cpp" />
|
||||
<ClCompile Include="gpu_sw.cpp" />
|
||||
<ClCompile Include="gpu_sw_backend.cpp" />
|
||||
<ClCompile Include="gte.cpp" />
|
||||
|
@ -103,6 +104,7 @@
|
|||
<ClInclude Include="game_list.h" />
|
||||
<ClInclude Include="gpu_backend.h" />
|
||||
<ClInclude Include="gpu_hw_shadergen.h" />
|
||||
<ClInclude Include="gpu_shadergen.h" />
|
||||
<ClInclude Include="gpu_sw.h" />
|
||||
<ClInclude Include="gpu_sw_backend.h" />
|
||||
<ClInclude Include="gpu_types.h" />
|
||||
|
@ -190,4 +192,4 @@
|
|||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="..\..\dep\msvc\vsprops\Targets.props" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -58,6 +58,7 @@
|
|||
<ClCompile Include="fullscreen_ui.cpp" />
|
||||
<ClCompile Include="achievements.cpp" />
|
||||
<ClCompile Include="hotkeys.cpp" />
|
||||
<ClCompile Include="gpu_shadergen.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="types.h" />
|
||||
|
@ -120,5 +121,6 @@
|
|||
<ClInclude Include="imgui_overlays.h" />
|
||||
<ClInclude Include="fullscreen_ui.h" />
|
||||
<ClInclude Include="shader_cache_version.h" />
|
||||
<ClInclude Include="gpu_shadergen.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -3883,7 +3883,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
DrawEnumSetting(
|
||||
bsi, FSUI_CSTR("Position"), FSUI_CSTR("Determines the position on the screen when black borders must be added."),
|
||||
"Display", "Alignment", Settings::DEFAULT_DISPLAY_ALIGNMENT, &Settings::ParseDisplayAlignment,
|
||||
&Settings::GetDisplayAlignmentDisplayName, &Settings::GetDisplayAlignmentDisplayName, DisplayAlignment::Count);
|
||||
&Settings::GetDisplayAlignmentName, &Settings::GetDisplayAlignmentDisplayName, DisplayAlignment::Count);
|
||||
|
||||
DrawEnumSetting(bsi, FSUI_CSTR("Downsampling"),
|
||||
FSUI_CSTR("Downsamples the rendered image prior to displaying it. Can improve "
|
||||
|
@ -3892,17 +3892,11 @@ void FullscreenUI::DrawDisplaySettingsPage()
|
|||
&Settings::GetDownsampleModeName, &Settings::GetDownsampleModeDisplayName, GPUDownsampleMode::Count,
|
||||
(renderer != GPURenderer::Software));
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Linear Upscaling"),
|
||||
FSUI_CSTR("Uses a bilinear filter when upscaling to display, smoothing out the image."), "Display",
|
||||
"LinearFiltering", true);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Integer Upscaling"),
|
||||
FSUI_CSTR("Adds padding to ensure pixels are a whole number in size."), "Display", "IntegerScaling",
|
||||
false);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Stretch To Fit"),
|
||||
FSUI_CSTR("Fills the window with the active display area, regardless of the aspect ratio."),
|
||||
"Display", "Stretch", false);
|
||||
DrawEnumSetting(
|
||||
bsi, FSUI_CSTR("Scaling"),
|
||||
FSUI_CSTR("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution."),
|
||||
"Display", "Scaling", Settings::DEFAULT_DISPLAY_SCALING, &Settings::ParseDisplayScaling,
|
||||
&Settings::GetDisplayScalingName, &Settings::GetDisplayScalingDisplayName, DisplayScalingMode::Count);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Internal Resolution Screenshots"),
|
||||
FSUI_CSTR("Saves screenshots at internal render resolution and without postprocessing."), "Display",
|
||||
|
|
146
src/core/gpu.cpp
146
src/core/gpu.cpp
|
@ -1,8 +1,9 @@
|
|||
// 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)
|
||||
|
||||
#include "gpu.h"
|
||||
#include "dma.h"
|
||||
#include "gpu_shadergen.h"
|
||||
#include "host.h"
|
||||
#include "imgui.h"
|
||||
#include "interrupt_controller.h"
|
||||
|
@ -59,7 +60,7 @@ bool GPU::Initialize()
|
|||
m_console_is_pal = System::IsPALRegion();
|
||||
UpdateCRTCConfig();
|
||||
|
||||
if (!CompilePipelines())
|
||||
if (!CompileDisplayPipeline())
|
||||
{
|
||||
Host::ReportErrorAsync("Error", "Failed to compile base GPU pipelines.");
|
||||
return false;
|
||||
|
@ -70,7 +71,7 @@ bool GPU::Initialize()
|
|||
return true;
|
||||
}
|
||||
|
||||
void GPU::UpdateSettings()
|
||||
void GPU::UpdateSettings(const Settings& old_settings)
|
||||
{
|
||||
m_force_progressive_scan = g_settings.gpu_disable_interlacing;
|
||||
m_fifo_size = g_settings.gpu_fifo_size;
|
||||
|
@ -86,6 +87,12 @@ void GPU::UpdateSettings()
|
|||
// Crop mode calls this, so recalculate the display area
|
||||
UpdateCRTCDisplayParameters();
|
||||
|
||||
if (g_settings.display_scaling != old_settings.display_scaling)
|
||||
{
|
||||
if (!CompileDisplayPipeline())
|
||||
Panic("Failed to compile display pipeline on settings change.");
|
||||
}
|
||||
|
||||
g_gpu_device->SetGPUTimingEnabled(g_settings.display_show_gpu);
|
||||
}
|
||||
|
||||
|
@ -1540,9 +1547,9 @@ void GPU::SetTextureWindow(u32 value)
|
|||
m_draw_mode.texture_window_changed = true;
|
||||
}
|
||||
|
||||
bool GPU::CompilePipelines()
|
||||
bool GPU::CompileDisplayPipeline()
|
||||
{
|
||||
ShaderGen shadergen(g_gpu_device->GetRenderAPI(), g_gpu_device->GetFeatures().dual_source_blend);
|
||||
GPUShaderGen shadergen(g_gpu_device->GetRenderAPI(), g_gpu_device->GetFeatures().dual_source_blend);
|
||||
|
||||
GPUPipeline::GraphicsConfig plconfig;
|
||||
plconfig.layout = GPUPipeline::Layout::SingleTextureAndPushConstants;
|
||||
|
@ -1556,20 +1563,35 @@ bool GPU::CompilePipelines()
|
|||
plconfig.samples = 1;
|
||||
plconfig.per_sample_shading = false;
|
||||
|
||||
std::unique_ptr<GPUShader> display_vs =
|
||||
g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GenerateDisplayVertexShader());
|
||||
std::unique_ptr<GPUShader> display_fs =
|
||||
g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GenerateDisplayFragmentShader(true));
|
||||
if (!display_vs || !display_fs)
|
||||
return false;
|
||||
GL_OBJECT_NAME(display_vs, "Display Vertex Shader");
|
||||
GL_OBJECT_NAME(display_fs, "Display Fragment Shader");
|
||||
std::string vs = shadergen.GenerateDisplayVertexShader();
|
||||
std::string fs;
|
||||
switch (g_settings.display_scaling)
|
||||
{
|
||||
case DisplayScalingMode::BilinearSharp:
|
||||
fs = shadergen.GenerateDisplaySharpBilinearFragmentShader();
|
||||
break;
|
||||
|
||||
plconfig.vertex_shader = display_vs.get();
|
||||
plconfig.fragment_shader = display_fs.get();
|
||||
case DisplayScalingMode::Nearest:
|
||||
case DisplayScalingMode::BilinearSmooth:
|
||||
case DisplayScalingMode::NearestInteger:
|
||||
default:
|
||||
fs = shadergen.GenerateDisplayFragmentShader();
|
||||
break;
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUShader> vso = g_gpu_device->CreateShader(GPUShaderStage::Vertex, vs);
|
||||
std::unique_ptr<GPUShader> fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, fs);
|
||||
if (!vso || !fso)
|
||||
return false;
|
||||
GL_OBJECT_NAME(vso, "Display Vertex Shader");
|
||||
GL_OBJECT_NAME(fso, "Display Fragment Shader [%s]", Settings::GetDisplayScalingName(g_settings.display_scaling));
|
||||
|
||||
plconfig.vertex_shader = vso.get();
|
||||
plconfig.fragment_shader = fso.get();
|
||||
if (!(m_display_pipeline = g_gpu_device->CreatePipeline(plconfig)))
|
||||
return false;
|
||||
GL_OBJECT_NAME(m_display_pipeline, "Display Pipeline");
|
||||
GL_OBJECT_NAME(m_display_pipeline, "Display Pipeline [%s]",
|
||||
Settings::GetDisplayScalingName(g_settings.display_scaling));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1620,17 +1642,56 @@ bool GPU::PresentDisplay()
|
|||
|
||||
const Common::Rectangle<s32> draw_rect =
|
||||
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight());
|
||||
return RenderDisplay(nullptr, draw_rect, g_settings.display_linear_filtering, true);
|
||||
return RenderDisplay(nullptr, draw_rect, true);
|
||||
}
|
||||
|
||||
bool GPU::RenderDisplay(GPUFramebuffer* target, const Common::Rectangle<s32>& draw_rect, bool linear_filter,
|
||||
bool postfx)
|
||||
bool GPU::RenderDisplay(GPUFramebuffer* target, const Common::Rectangle<s32>& draw_rect, bool postfx)
|
||||
{
|
||||
GL_SCOPE("RenderDisplay: %dx%d at %d,%d", draw_rect.left, draw_rect.top, draw_rect.GetWidth(), draw_rect.GetHeight());
|
||||
|
||||
if (m_display_texture)
|
||||
m_display_texture->MakeReadyForSampling();
|
||||
|
||||
bool texture_filter_linear = false;
|
||||
bool bilinear_adjust = false;
|
||||
|
||||
struct Uniforms
|
||||
{
|
||||
float src_rect[4];
|
||||
float src_size[4];
|
||||
float params[4];
|
||||
} uniforms;
|
||||
std::memset(uniforms.params, 0, sizeof(uniforms.params));
|
||||
|
||||
switch (g_settings.display_scaling)
|
||||
{
|
||||
case DisplayScalingMode::Nearest:
|
||||
case DisplayScalingMode::NearestInteger:
|
||||
break;
|
||||
|
||||
case DisplayScalingMode::BilinearSmooth:
|
||||
texture_filter_linear = true;
|
||||
bilinear_adjust = true;
|
||||
break;
|
||||
|
||||
case DisplayScalingMode::BilinearSharp:
|
||||
{
|
||||
texture_filter_linear = true;
|
||||
uniforms.params[0] = std::max(
|
||||
std::floor(static_cast<float>(draw_rect.GetWidth()) / static_cast<float>(m_display_texture_view_width)), 1.0f);
|
||||
uniforms.params[1] = std::max(
|
||||
std::floor(static_cast<float>(draw_rect.GetHeight()) / static_cast<float>(m_display_texture_view_height)),
|
||||
1.0f);
|
||||
uniforms.params[2] = 0.5f - 0.5f / uniforms.params[0];
|
||||
uniforms.params[3] = 0.5f - 0.5f / uniforms.params[1];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
UnreachableCode();
|
||||
break;
|
||||
}
|
||||
|
||||
const GPUTexture::Format hdformat =
|
||||
(target && target->GetRT()) ? target->GetRT()->GetFormat() : g_gpu_device->GetWindowFormat();
|
||||
const u32 target_width = target ? target->GetWidth() : g_gpu_device->GetWindowWidth();
|
||||
|
@ -1654,29 +1715,30 @@ bool GPU::RenderDisplay(GPUFramebuffer* target, const Common::Rectangle<s32>& dr
|
|||
return true;
|
||||
|
||||
g_gpu_device->SetPipeline(m_display_pipeline.get());
|
||||
g_gpu_device->SetTextureSampler(0, m_display_texture,
|
||||
linear_filter ? g_gpu_device->GetLinearSampler() : g_gpu_device->GetNearestSampler());
|
||||
g_gpu_device->SetTextureSampler(
|
||||
0, m_display_texture, texture_filter_linear ? g_gpu_device->GetLinearSampler() : g_gpu_device->GetNearestSampler());
|
||||
|
||||
const float position_adjust = linear_filter ? 0.5f : 0.0f;
|
||||
const float size_adjust = linear_filter ? 1.0f : 0.0f;
|
||||
const float uniforms[4] = {(static_cast<float>(m_display_texture_view_x) + position_adjust) /
|
||||
static_cast<float>(m_display_texture->GetWidth()),
|
||||
(static_cast<float>(m_display_texture_view_y) + position_adjust) /
|
||||
static_cast<float>(m_display_texture->GetHeight()),
|
||||
(static_cast<float>(m_display_texture_view_width) - size_adjust) /
|
||||
static_cast<float>(m_display_texture->GetWidth()),
|
||||
(static_cast<float>(m_display_texture_view_height) - size_adjust) /
|
||||
static_cast<float>(m_display_texture->GetHeight())};
|
||||
g_gpu_device->PushUniformBuffer(uniforms, sizeof(uniforms));
|
||||
const float position_adjust = bilinear_adjust ? 0.5f : 0.0f;
|
||||
const float size_adjust = bilinear_adjust ? 1.0f : 0.0f;
|
||||
const float rcp_width = 1.0f / static_cast<float>(m_display_texture->GetWidth());
|
||||
const float rcp_height = 1.0f / static_cast<float>(m_display_texture->GetHeight());
|
||||
uniforms.src_rect[0] = (static_cast<float>(m_display_texture_view_x) + position_adjust) * rcp_width;
|
||||
uniforms.src_rect[1] = (static_cast<float>(m_display_texture_view_y) + position_adjust) * rcp_height;
|
||||
uniforms.src_rect[2] = (static_cast<float>(m_display_texture_view_width) - size_adjust) * rcp_width;
|
||||
uniforms.src_rect[3] = (static_cast<float>(m_display_texture_view_height) - size_adjust) * rcp_height;
|
||||
uniforms.src_size[0] = static_cast<float>(m_display_texture->GetWidth());
|
||||
uniforms.src_size[1] = static_cast<float>(m_display_texture->GetHeight());
|
||||
uniforms.src_size[2] = rcp_width;
|
||||
uniforms.src_size[3] = rcp_height;
|
||||
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
||||
|
||||
g_gpu_device->SetViewportAndScissor(draw_rect.left, draw_rect.top, draw_rect.GetWidth(), draw_rect.GetHeight());
|
||||
g_gpu_device->Draw(3, 0);
|
||||
|
||||
if (really_postfx)
|
||||
{
|
||||
return PostProcessing::Apply(target, draw_rect.left, draw_rect.top, draw_rect.GetWidth(),
|
||||
draw_rect.GetHeight(), m_display_texture_view_width,
|
||||
m_display_texture_view_height);
|
||||
return PostProcessing::Apply(target, draw_rect.left, draw_rect.top, draw_rect.GetWidth(), draw_rect.GetHeight(),
|
||||
m_display_texture_view_width, m_display_texture_view_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1689,10 +1751,9 @@ Common::Rectangle<float> GPU::CalculateDrawRect(s32 window_width, s32 window_hei
|
|||
bool apply_aspect_ratio /* = true */) const
|
||||
{
|
||||
const float window_ratio = static_cast<float>(window_width) / static_cast<float>(window_height);
|
||||
const float display_aspect_ratio = g_settings.display_stretch ? window_ratio : m_display_aspect_ratio;
|
||||
const float x_scale =
|
||||
apply_aspect_ratio ?
|
||||
(display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height))) :
|
||||
(m_display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height))) :
|
||||
1.0f;
|
||||
const float display_width = g_settings.display_stretch_vertically ? static_cast<float>(m_display_width) :
|
||||
static_cast<float>(m_display_width) * x_scale;
|
||||
|
@ -1717,12 +1778,12 @@ Common::Rectangle<float> GPU::CalculateDrawRect(s32 window_width, s32 window_hei
|
|||
{
|
||||
// align in middle vertically
|
||||
scale = static_cast<float>(window_width) / display_width;
|
||||
if (g_settings.display_integer_scaling)
|
||||
if (g_settings.display_scaling == DisplayScalingMode::NearestInteger)
|
||||
scale = std::max(std::floor(scale), 1.0f);
|
||||
|
||||
if (out_left_padding)
|
||||
{
|
||||
if (g_settings.display_integer_scaling)
|
||||
if (g_settings.display_scaling == DisplayScalingMode::NearestInteger)
|
||||
*out_left_padding = std::max<float>((static_cast<float>(window_width) - display_width * scale) / 2.0f, 0.0f);
|
||||
else
|
||||
*out_left_padding = 0.0f;
|
||||
|
@ -1751,7 +1812,7 @@ Common::Rectangle<float> GPU::CalculateDrawRect(s32 window_width, s32 window_hei
|
|||
{
|
||||
// align in middle horizontally
|
||||
scale = static_cast<float>(window_height) / display_height;
|
||||
if (g_settings.display_integer_scaling)
|
||||
if (g_settings.display_scaling == DisplayScalingMode::NearestInteger)
|
||||
scale = std::max(std::floor(scale), 1.0f);
|
||||
|
||||
if (out_left_padding)
|
||||
|
@ -1776,7 +1837,7 @@ Common::Rectangle<float> GPU::CalculateDrawRect(s32 window_width, s32 window_hei
|
|||
|
||||
if (out_top_padding)
|
||||
{
|
||||
if (g_settings.display_integer_scaling)
|
||||
if (g_settings.display_scaling == DisplayScalingMode::NearestInteger)
|
||||
*out_top_padding = std::max<float>((static_cast<float>(window_height) - (display_height * scale)) / 2.0f, 0.0f);
|
||||
else
|
||||
*out_top_padding = 0.0f;
|
||||
|
@ -1974,7 +2035,8 @@ bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const Common::Rectangl
|
|||
|
||||
g_gpu_device->ClearRenderTarget(render_texture.get(), 0);
|
||||
|
||||
RenderDisplay(render_fb.get(), draw_rect, g_settings.display_linear_filtering, postfx);
|
||||
// TODO: this should use copy shader instead.
|
||||
RenderDisplay(render_fb.get(), draw_rect, postfx);
|
||||
|
||||
g_gpu_device->SetFramebuffer(nullptr);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ class GPUFramebuffer;
|
|||
class GPUTexture;
|
||||
class GPUPipeline;
|
||||
|
||||
struct Settings;
|
||||
class TimingEvent;
|
||||
|
||||
namespace Threading {
|
||||
|
@ -151,7 +152,7 @@ public:
|
|||
void SynchronizeCRTC();
|
||||
|
||||
/// Recompile shaders/recreate framebuffers when needed.
|
||||
virtual void UpdateSettings();
|
||||
virtual void UpdateSettings(const Settings& old_settings);
|
||||
|
||||
/// Updates the resolution scale when it's set to automatic.
|
||||
virtual void UpdateResolutionScale();
|
||||
|
@ -582,7 +583,7 @@ protected:
|
|||
float* out_top_padding, float* out_scale, float* out_x_scale,
|
||||
bool apply_aspect_ratio = true) const;
|
||||
|
||||
bool RenderDisplay(GPUFramebuffer* target, const Common::Rectangle<s32>& draw_rect, bool linear_filter, bool postfx);
|
||||
bool RenderDisplay(GPUFramebuffer* target, const Common::Rectangle<s32>& draw_rect, bool postfx);
|
||||
|
||||
s32 m_display_width = 0;
|
||||
s32 m_display_height = 0;
|
||||
|
@ -612,7 +613,7 @@ protected:
|
|||
Stats m_last_stats = {};
|
||||
|
||||
private:
|
||||
bool CompilePipelines();
|
||||
bool CompileDisplayPipeline();
|
||||
|
||||
using GP0CommandHandler = bool (GPU::*)();
|
||||
using GP0CommandHandlerTable = std::array<GP0CommandHandler, 256>;
|
||||
|
|
|
@ -286,9 +286,9 @@ void GPU_HW::RestoreGraphicsAPIState()
|
|||
m_batch_ubo_dirty = true;
|
||||
}
|
||||
|
||||
void GPU_HW::UpdateSettings()
|
||||
void GPU_HW::UpdateSettings(const Settings& old_settings)
|
||||
{
|
||||
GPU::UpdateSettings();
|
||||
GPU::UpdateSettings(old_settings);
|
||||
|
||||
const u32 resolution_scale = CalculateResolutionScale();
|
||||
const u32 multisamples = std::min(g_settings.gpu_multisamples, g_gpu_device->GetMaxMultisamples());
|
||||
|
@ -297,6 +297,7 @@ void GPU_HW::UpdateSettings()
|
|||
const bool use_uv_limits = ShouldUseUVLimits();
|
||||
const bool disable_color_perspective = m_supports_disable_color_perspective && ShouldDisableColorPerspective();
|
||||
|
||||
// TODO: Use old_settings
|
||||
const bool framebuffer_changed =
|
||||
(m_resolution_scale != resolution_scale || m_multisamples != multisamples || m_downsample_mode != downsample_mode);
|
||||
const bool shaders_changed =
|
||||
|
@ -429,7 +430,7 @@ void GPU_HW::UpdateResolutionScale()
|
|||
GPU::UpdateResolutionScale();
|
||||
|
||||
if (CalculateResolutionScale() != m_resolution_scale)
|
||||
UpdateSettings();
|
||||
UpdateSettings(g_settings);
|
||||
}
|
||||
|
||||
GPUDownsampleMode GPU_HW::GetDownsampleMode(u32 resolution_scale) const
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
void RestoreGraphicsAPIState() override;
|
||||
|
||||
void UpdateSettings() override;
|
||||
void UpdateSettings(const Settings& old_settings) override;
|
||||
void UpdateResolutionScale() override final;
|
||||
std::tuple<u32, u32> GetEffectiveDisplayResolution(bool scaled = true) override final;
|
||||
std::tuple<u32, u32> GetFullDisplayResolution(bool scaled = true) override final;
|
||||
|
|
79
src/core/gpu_shadergen.cpp
Normal file
79
src/core/gpu_shadergen.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include "gpu_shadergen.h"
|
||||
|
||||
GPUShaderGen::GPUShaderGen(RenderAPI render_api, bool supports_dual_source_blend)
|
||||
: ShaderGen(render_api, supports_dual_source_blend)
|
||||
{
|
||||
}
|
||||
|
||||
GPUShaderGen::~GPUShaderGen() = default;
|
||||
|
||||
void GPUShaderGen::WriteDisplayUniformBuffer(std::stringstream& ss)
|
||||
{
|
||||
DeclareUniformBuffer(ss, {"float4 u_src_rect", "float4 u_src_size", "float4 u_params"}, true);
|
||||
}
|
||||
|
||||
std::string GPUShaderGen::GenerateDisplayVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteDisplayUniformBuffer(ss);
|
||||
DeclareVertexEntryPoint(ss, {}, 0, 1, {}, true);
|
||||
ss << R"(
|
||||
{
|
||||
float2 pos = float2(float((v_id << 1) & 2u), float(v_id & 2u));
|
||||
v_tex0 = u_src_rect.xy + pos * u_src_rect.zw;
|
||||
v_pos = float4(pos * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
#if API_VULKAN
|
||||
v_pos.y = -v_pos.y;
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string GPUShaderGen::GenerateDisplayFragmentShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteDisplayUniformBuffer(ss);
|
||||
DeclareTexture(ss, "samp0", 0);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1);
|
||||
ss << R"(
|
||||
{
|
||||
o_col0 = float4(SAMPLE_TEXTURE(samp0, v_tex0).rgb, 1.0f);
|
||||
})";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string GPUShaderGen::GenerateDisplaySharpBilinearFragmentShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
WriteDisplayUniformBuffer(ss);
|
||||
DeclareTexture(ss, "samp0", 0, false);
|
||||
|
||||
// Based on https://github.com/rsn8887/Sharp-Bilinear-Shaders/blob/master/Copy_To_RetroPie/shaders/sharp-bilinear-simple.glsl
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, false, false, false, false);
|
||||
ss << R"(
|
||||
{
|
||||
float2 scale = u_params.xy;
|
||||
float2 region_range = u_params.zw;
|
||||
|
||||
float2 texel = v_tex0 * u_src_size.xy;
|
||||
float2 texel_floored = floor(texel);
|
||||
float2 s = frac(texel);
|
||||
|
||||
float2 center_dist = s - 0.5;
|
||||
float2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
|
||||
float2 mod_texel = texel_floored + f;
|
||||
|
||||
o_col0 = float4(SAMPLE_TEXTURE(samp0, mod_texel * u_src_size.zw).rgb, 1.0f);
|
||||
})";
|
||||
|
||||
return ss.str();
|
||||
}
|
20
src/core/gpu_shadergen.h
Normal file
20
src/core/gpu_shadergen.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/shadergen.h"
|
||||
|
||||
class GPUShaderGen : public ShaderGen
|
||||
{
|
||||
public:
|
||||
GPUShaderGen(RenderAPI render_api, bool supports_dual_source_blend);
|
||||
~GPUShaderGen();
|
||||
|
||||
std::string GenerateDisplayVertexShader();
|
||||
std::string GenerateDisplayFragmentShader();
|
||||
std::string GenerateDisplaySharpBilinearFragmentShader();
|
||||
|
||||
private:
|
||||
void WriteDisplayUniformBuffer(std::stringstream& ss);
|
||||
};
|
|
@ -97,9 +97,9 @@ void GPU_SW::Reset(bool clear_vram)
|
|||
m_backend.Reset(clear_vram);
|
||||
}
|
||||
|
||||
void GPU_SW::UpdateSettings()
|
||||
void GPU_SW::UpdateSettings(const Settings& old_settings)
|
||||
{
|
||||
GPU::UpdateSettings();
|
||||
GPU::UpdateSettings(old_settings);
|
||||
m_backend.UpdateSettings();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
bool Initialize() override;
|
||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
||||
void Reset(bool clear_vram) override;
|
||||
void UpdateSettings() override;
|
||||
void UpdateSettings(const Settings& old_settings) override;
|
||||
|
||||
protected:
|
||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
|
||||
|
|
|
@ -48,12 +48,13 @@ static void HotkeyModifyResolutionScale(s32 increment)
|
|||
if (new_resolution_scale == g_settings.gpu_resolution_scale)
|
||||
return;
|
||||
|
||||
const Settings old_settings = g_settings;
|
||||
g_settings.gpu_resolution_scale = new_resolution_scale;
|
||||
|
||||
if (System::IsValid())
|
||||
{
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
g_gpu->UpdateSettings();
|
||||
g_gpu->UpdateSettings(old_settings);
|
||||
System::ClearMemorySaveStates();
|
||||
}
|
||||
}
|
||||
|
@ -309,9 +310,10 @@ DEFINE_HOTKEY("TogglePGXP", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_NOO
|
|||
[](s32 pressed) {
|
||||
if (!pressed && System::IsValid())
|
||||
{
|
||||
Settings old_settings = g_settings;
|
||||
g_settings.gpu_pgxp_enable = !g_settings.gpu_pgxp_enable;
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
g_gpu->UpdateSettings();
|
||||
g_gpu->UpdateSettings(old_settings);
|
||||
System::ClearMemorySaveStates();
|
||||
Host::AddKeyedOSDMessage("TogglePGXP",
|
||||
g_settings.gpu_pgxp_enable ?
|
||||
|
@ -374,12 +376,14 @@ DEFINE_HOTKEY("TogglePGXPDepth", TRANSLATE_NOOP("Hotkeys", "Graphics"),
|
|||
TRANSLATE_NOOP("Hotkeys", "Toggle PGXP Depth Buffer"), [](s32 pressed) {
|
||||
if (!pressed && System::IsValid())
|
||||
{
|
||||
g_settings.gpu_pgxp_depth_buffer = !g_settings.gpu_pgxp_depth_buffer;
|
||||
if (!g_settings.gpu_pgxp_enable)
|
||||
return;
|
||||
|
||||
const Settings old_settings = g_settings;
|
||||
g_settings.gpu_pgxp_depth_buffer = !g_settings.gpu_pgxp_depth_buffer;
|
||||
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
g_gpu->UpdateSettings();
|
||||
g_gpu->UpdateSettings(old_settings);
|
||||
System::ClearMemorySaveStates();
|
||||
Host::AddKeyedOSDMessage("TogglePGXPDepth",
|
||||
g_settings.gpu_pgxp_depth_buffer ?
|
||||
|
@ -393,12 +397,14 @@ DEFINE_HOTKEY("TogglePGXPCPU", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_
|
|||
[](s32 pressed) {
|
||||
if (pressed && System::IsValid())
|
||||
{
|
||||
g_settings.gpu_pgxp_cpu = !g_settings.gpu_pgxp_cpu;
|
||||
if (!g_settings.gpu_pgxp_enable)
|
||||
return;
|
||||
|
||||
const Settings old_settings = g_settings;
|
||||
g_settings.gpu_pgxp_cpu = !g_settings.gpu_pgxp_cpu;
|
||||
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
g_gpu->UpdateSettings();
|
||||
g_gpu->UpdateSettings(old_settings);
|
||||
System::ClearMemorySaveStates();
|
||||
Host::AddKeyedOSDMessage("TogglePGXPCPU",
|
||||
g_settings.gpu_pgxp_cpu ?
|
||||
|
|
|
@ -161,7 +161,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
region =
|
||||
ParseConsoleRegionName(
|
||||
si.GetStringValue("Console", "Region", Settings::GetConsoleRegionName(Settings::DEFAULT_CONSOLE_REGION)).c_str())
|
||||
.value_or(DEFAULT_CONSOLE_REGION);
|
||||
.value_or(DEFAULT_CONSOLE_REGION);
|
||||
enable_8mb_ram = si.GetBoolValue("Console", "Enable8MBRAM", false);
|
||||
|
||||
emulation_speed = si.GetFloatValue("Main", "EmulationSpeed", 1.0f);
|
||||
|
@ -192,7 +192,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
cpu_execution_mode =
|
||||
ParseCPUExecutionMode(
|
||||
si.GetStringValue("CPU", "ExecutionMode", GetCPUExecutionModeName(DEFAULT_CPU_EXECUTION_MODE)).c_str())
|
||||
.value_or(DEFAULT_CPU_EXECUTION_MODE);
|
||||
.value_or(DEFAULT_CPU_EXECUTION_MODE);
|
||||
cpu_overclock_numerator = std::max(si.GetIntValue("CPU", "OverclockNumerator", 1), 1);
|
||||
cpu_overclock_denominator = std::max(si.GetIntValue("CPU", "OverclockDenominator", 1), 1);
|
||||
cpu_overclock_enable = si.GetBoolValue("CPU", "OverclockEnable", false);
|
||||
|
@ -201,11 +201,11 @@ void Settings::Load(SettingsInterface& si)
|
|||
cpu_recompiler_block_linking = si.GetBoolValue("CPU", "RecompilerBlockLinking", true);
|
||||
cpu_recompiler_icache = si.GetBoolValue("CPU", "RecompilerICache", false);
|
||||
cpu_fastmem_mode = ParseCPUFastmemMode(
|
||||
si.GetStringValue("CPU", "FastmemMode", GetCPUFastmemModeName(DEFAULT_CPU_FASTMEM_MODE)).c_str())
|
||||
.value_or(DEFAULT_CPU_FASTMEM_MODE);
|
||||
si.GetStringValue("CPU", "FastmemMode", GetCPUFastmemModeName(DEFAULT_CPU_FASTMEM_MODE)).c_str())
|
||||
.value_or(DEFAULT_CPU_FASTMEM_MODE);
|
||||
|
||||
gpu_renderer = ParseRendererName(si.GetStringValue("GPU", "Renderer", GetRendererName(DEFAULT_GPU_RENDERER)).c_str())
|
||||
.value_or(DEFAULT_GPU_RENDERER);
|
||||
.value_or(DEFAULT_GPU_RENDERER);
|
||||
gpu_adapter = si.GetStringValue("GPU", "Adapter", "");
|
||||
gpu_resolution_scale = static_cast<u32>(si.GetIntValue("GPU", "ResolutionScale", 1));
|
||||
gpu_multisamples = static_cast<u32>(si.GetIntValue("GPU", "Multisamples", 1));
|
||||
|
@ -220,11 +220,11 @@ void Settings::Load(SettingsInterface& si)
|
|||
gpu_texture_filter =
|
||||
ParseTextureFilterName(
|
||||
si.GetStringValue("GPU", "TextureFilter", GetTextureFilterName(DEFAULT_GPU_TEXTURE_FILTER)).c_str())
|
||||
.value_or(DEFAULT_GPU_TEXTURE_FILTER);
|
||||
.value_or(DEFAULT_GPU_TEXTURE_FILTER);
|
||||
gpu_downsample_mode =
|
||||
ParseDownsampleModeName(
|
||||
si.GetStringValue("GPU", "DownsampleMode", GetDownsampleModeName(DEFAULT_GPU_DOWNSAMPLE_MODE)).c_str())
|
||||
.value_or(DEFAULT_GPU_DOWNSAMPLE_MODE);
|
||||
.value_or(DEFAULT_GPU_DOWNSAMPLE_MODE);
|
||||
gpu_disable_interlacing = si.GetBoolValue("GPU", "DisableInterlacing", true);
|
||||
gpu_force_ntsc_timings = si.GetBoolValue("GPU", "ForceNTSCTimings", false);
|
||||
gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false);
|
||||
|
@ -243,11 +243,11 @@ void Settings::Load(SettingsInterface& si)
|
|||
display_crop_mode =
|
||||
ParseDisplayCropMode(
|
||||
si.GetStringValue("Display", "CropMode", GetDisplayCropModeName(DEFAULT_DISPLAY_CROP_MODE)).c_str())
|
||||
.value_or(DEFAULT_DISPLAY_CROP_MODE);
|
||||
.value_or(DEFAULT_DISPLAY_CROP_MODE);
|
||||
display_aspect_ratio =
|
||||
ParseDisplayAspectRatio(
|
||||
si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DEFAULT_DISPLAY_ASPECT_RATIO)).c_str())
|
||||
.value_or(DEFAULT_DISPLAY_ASPECT_RATIO);
|
||||
.value_or(DEFAULT_DISPLAY_ASPECT_RATIO);
|
||||
display_aspect_ratio_custom_numerator = static_cast<u16>(
|
||||
std::clamp<int>(si.GetIntValue("Display", "CustomAspectRatioNumerator", 4), 1, std::numeric_limits<u16>::max()));
|
||||
display_aspect_ratio_custom_denominator = static_cast<u16>(
|
||||
|
@ -255,15 +255,15 @@ void Settings::Load(SettingsInterface& si)
|
|||
display_alignment =
|
||||
ParseDisplayAlignment(
|
||||
si.GetStringValue("Display", "Alignment", GetDisplayAlignmentName(DEFAULT_DISPLAY_ALIGNMENT)).c_str())
|
||||
.value_or(DEFAULT_DISPLAY_ALIGNMENT);
|
||||
.value_or(DEFAULT_DISPLAY_ALIGNMENT);
|
||||
display_scaling =
|
||||
ParseDisplayScaling(si.GetStringValue("Display", "Scaling", GetDisplayScalingName(DEFAULT_DISPLAY_SCALING)).c_str())
|
||||
.value_or(DEFAULT_DISPLAY_SCALING);
|
||||
display_force_4_3_for_24bit = si.GetBoolValue("Display", "Force4_3For24Bit", false);
|
||||
display_active_start_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveStartOffset", 0));
|
||||
display_active_end_offset = static_cast<s16>(si.GetIntValue("Display", "ActiveEndOffset", 0));
|
||||
display_line_start_offset = static_cast<s8>(si.GetIntValue("Display", "LineStartOffset", 0));
|
||||
display_line_end_offset = static_cast<s8>(si.GetIntValue("Display", "LineEndOffset", 0));
|
||||
display_linear_filtering = si.GetBoolValue("Display", "LinearFiltering", true);
|
||||
display_integer_scaling = si.GetBoolValue("Display", "IntegerScaling", false);
|
||||
display_stretch = si.GetBoolValue("Display", "Stretch", false);
|
||||
display_show_osd_messages = si.GetBoolValue("Display", "ShowOSDMessages", true);
|
||||
display_show_fps = si.GetBoolValue("Display", "ShowFPS", false);
|
||||
display_show_speed = si.GetBoolValue("Display", "ShowSpeed", false);
|
||||
|
@ -292,13 +292,13 @@ void Settings::Load(SettingsInterface& si)
|
|||
|
||||
audio_backend =
|
||||
ParseAudioBackend(si.GetStringValue("Audio", "Backend", GetAudioBackendName(DEFAULT_AUDIO_BACKEND)).c_str())
|
||||
.value_or(DEFAULT_AUDIO_BACKEND);
|
||||
.value_or(DEFAULT_AUDIO_BACKEND);
|
||||
audio_driver = si.GetStringValue("Audio", "Driver");
|
||||
audio_output_device = si.GetStringValue("Audio", "OutputDevice");
|
||||
audio_stretch_mode =
|
||||
AudioStream::ParseStretchMode(
|
||||
si.GetStringValue("Audio", "StretchMode", AudioStream::GetStretchModeName(DEFAULT_AUDIO_STRETCH_MODE)).c_str())
|
||||
.value_or(DEFAULT_AUDIO_STRETCH_MODE);
|
||||
.value_or(DEFAULT_AUDIO_STRETCH_MODE);
|
||||
audio_output_latency_ms = si.GetUIntValue("Audio", "OutputLatencyMS", DEFAULT_AUDIO_OUTPUT_LATENCY_MS);
|
||||
audio_buffer_ms = si.GetUIntValue("Audio", "BufferMS", DEFAULT_AUDIO_BUFFER_MS);
|
||||
audio_output_volume = si.GetUIntValue("Audio", "OutputVolume", 100);
|
||||
|
@ -323,14 +323,14 @@ void Settings::Load(SettingsInterface& si)
|
|||
multitap_mode =
|
||||
ParseMultitapModeName(
|
||||
si.GetStringValue("ControllerPorts", "MultitapMode", GetMultitapModeName(DEFAULT_MULTITAP_MODE)).c_str())
|
||||
.value_or(DEFAULT_MULTITAP_MODE);
|
||||
.value_or(DEFAULT_MULTITAP_MODE);
|
||||
|
||||
controller_types[0] = ParseControllerTypeName(si.GetStringValue(Controller::GetSettingsSection(0).c_str(), "Type",
|
||||
GetControllerTypeName(DEFAULT_CONTROLLER_1_TYPE))
|
||||
.c_str())
|
||||
.value_or(DEFAULT_CONTROLLER_1_TYPE);
|
||||
GetControllerTypeName(DEFAULT_CONTROLLER_1_TYPE))
|
||||
.c_str())
|
||||
.value_or(DEFAULT_CONTROLLER_1_TYPE);
|
||||
|
||||
const std::array<bool, 2> mtap_enabled = {{IsPort1MultitapEnabled(), IsPort2MultitapEnabled()}};
|
||||
const std::array<bool, 2> mtap_enabled = { {IsPort1MultitapEnabled(), IsPort2MultitapEnabled()} };
|
||||
for (u32 i = 1; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||
{
|
||||
// Ignore types when multitap not enabled
|
||||
|
@ -342,19 +342,19 @@ void Settings::Load(SettingsInterface& si)
|
|||
}
|
||||
|
||||
controller_types[i] = ParseControllerTypeName(si.GetStringValue(Controller::GetSettingsSection(i).c_str(), "Type",
|
||||
GetControllerTypeName(DEFAULT_CONTROLLER_2_TYPE))
|
||||
.c_str())
|
||||
.value_or(DEFAULT_CONTROLLER_2_TYPE);
|
||||
GetControllerTypeName(DEFAULT_CONTROLLER_2_TYPE))
|
||||
.c_str())
|
||||
.value_or(DEFAULT_CONTROLLER_2_TYPE);
|
||||
}
|
||||
|
||||
memory_card_types[0] =
|
||||
ParseMemoryCardTypeName(
|
||||
si.GetStringValue("MemoryCards", "Card1Type", GetMemoryCardTypeName(DEFAULT_MEMORY_CARD_1_TYPE)).c_str())
|
||||
.value_or(DEFAULT_MEMORY_CARD_1_TYPE);
|
||||
.value_or(DEFAULT_MEMORY_CARD_1_TYPE);
|
||||
memory_card_types[1] =
|
||||
ParseMemoryCardTypeName(
|
||||
si.GetStringValue("MemoryCards", "Card2Type", GetMemoryCardTypeName(DEFAULT_MEMORY_CARD_2_TYPE)).c_str())
|
||||
.value_or(DEFAULT_MEMORY_CARD_2_TYPE);
|
||||
.value_or(DEFAULT_MEMORY_CARD_2_TYPE);
|
||||
memory_card_paths[0] = si.GetStringValue("MemoryCards", "Card1Path", "");
|
||||
memory_card_paths[1] = si.GetStringValue("MemoryCards", "Card2Path", "");
|
||||
memory_card_use_playlist_title = si.GetBoolValue("MemoryCards", "UsePlaylistTitle", true);
|
||||
|
@ -372,7 +372,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
achievements_use_raintegration = si.GetBoolValue("Cheevos", "UseRAIntegration", false);
|
||||
|
||||
log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str())
|
||||
.value_or(DEFAULT_LOG_LEVEL);
|
||||
.value_or(DEFAULT_LOG_LEVEL);
|
||||
log_filter = si.GetStringValue("Logging", "LogFilter", "");
|
||||
log_to_console = si.GetBoolValue("Logging", "LogToConsole", DEFAULT_LOG_TO_CONSOLE);
|
||||
log_to_debug = si.GetBoolValue("Logging", "LogToDebug", false);
|
||||
|
@ -401,6 +401,12 @@ void Settings::Load(SettingsInterface& si)
|
|||
si.GetIntValue("TextureReplacements", "DumpVRAMWriteWidthThreshold", 128);
|
||||
texture_replacements.dump_vram_write_height_threshold =
|
||||
si.GetIntValue("TextureReplacements", "DumpVRAMWriteHeightThreshold", 128);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
// Android users are incredibly silly and don't understand that stretch is in the aspect ratio list...
|
||||
if (si.GetBoolValue("Display", "Stretch", false))
|
||||
display_aspect_ratio = DisplayAspectRatio::MatchWindow;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Settings::Save(SettingsInterface& si) const
|
||||
|
@ -479,11 +485,9 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("Display", "Force4_3For24Bit", display_force_4_3_for_24bit);
|
||||
si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio));
|
||||
si.SetStringValue("Display", "Alignment", GetDisplayAlignmentName(display_alignment));
|
||||
si.SetBoolValue("Display", "Scaling", GetDisplayScalingName(display_scaling));
|
||||
si.SetIntValue("Display", "CustomAspectRatioNumerator", display_aspect_ratio_custom_numerator);
|
||||
si.GetIntValue("Display", "CustomAspectRatioDenominator", display_aspect_ratio_custom_denominator);
|
||||
si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering);
|
||||
si.SetBoolValue("Display", "IntegerScaling", display_integer_scaling);
|
||||
si.SetBoolValue("Display", "Stretch", display_stretch);
|
||||
si.SetBoolValue("Display", "ShowOSDMessages", display_show_osd_messages);
|
||||
si.SetBoolValue("Display", "ShowFPS", display_show_fps);
|
||||
si.SetBoolValue("Display", "ShowSpeed", display_show_speed);
|
||||
|
@ -628,18 +632,6 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
|
|||
g_settings.pcdrv_enable = false;
|
||||
}
|
||||
|
||||
if (g_settings.display_integer_scaling && g_settings.display_linear_filtering)
|
||||
{
|
||||
Log_WarningPrintf("Disabling linear filter due to integer upscaling.");
|
||||
g_settings.display_linear_filtering = false;
|
||||
}
|
||||
|
||||
if (g_settings.display_integer_scaling && g_settings.display_stretch)
|
||||
{
|
||||
Log_WarningPrintf("Disabling stretch due to integer upscaling.");
|
||||
g_settings.display_stretch = false;
|
||||
}
|
||||
|
||||
if (g_settings.gpu_pgxp_enable)
|
||||
{
|
||||
if (g_settings.gpu_renderer == GPURenderer::Software)
|
||||
|
@ -1091,7 +1083,7 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode)
|
|||
|
||||
static std::array<const char*, static_cast<size_t>(DisplayAspectRatio::Count)> s_display_aspect_ratio_names = {
|
||||
{TRANSLATE_NOOP("DisplayAspectRatio", "Auto (Game Native)"),
|
||||
TRANSLATE_NOOP("DisplayAspectRatio", "Auto (Match Window)"), TRANSLATE_NOOP("DisplayAspectRatio", "Custom"), "4:3",
|
||||
TRANSLATE_NOOP("DisplayAspectRatio", "Stretch To Fill"), TRANSLATE_NOOP("DisplayAspectRatio", "Custom"), "4:3",
|
||||
"16:9", "19:9", "20:9", "PAR 1:1"}};
|
||||
static constexpr std::array<float, static_cast<size_t>(DisplayAspectRatio::Count)> s_display_aspect_ratio_values = {
|
||||
{-1.0f, -1.0f, -1.0f, 4.0f / 3.0f, 16.0f / 9.0f, 19.0f / 9.0f, 20.0f / 9.0f, -1.0f}};
|
||||
|
@ -1172,7 +1164,44 @@ const char* Settings::GetDisplayAlignmentName(DisplayAlignment alignment)
|
|||
|
||||
const char* Settings::GetDisplayAlignmentDisplayName(DisplayAlignment alignment)
|
||||
{
|
||||
return s_display_alignment_display_names[static_cast<int>(alignment)];
|
||||
return Host::TranslateToCString("DisplayAlignment", s_display_alignment_display_names[static_cast<int>(alignment)]);
|
||||
}
|
||||
|
||||
static std::array<const char*, static_cast<size_t>(DisplayScalingMode::Count)> s_display_scaling_names = {{
|
||||
"Nearest",
|
||||
"BilinearSmooth",
|
||||
"NearestInteger",
|
||||
"BilinearSharp",
|
||||
}};
|
||||
static std::array<const char*, static_cast<size_t>(DisplayScalingMode::Count)> s_display_scaling_display_names = {{
|
||||
TRANSLATE_NOOP("DisplayScalingMode", "Nearest-Neighbor"),
|
||||
TRANSLATE_NOOP("DisplayScalingMode", "Bilinear (Smooth)"),
|
||||
TRANSLATE_NOOP("DisplayScalingMode", "Nearest-Neighbor (Integer)"),
|
||||
TRANSLATE_NOOP("DisplayScalingMode", "Bilinear (Sharp)"),
|
||||
}};
|
||||
|
||||
std::optional<DisplayScalingMode> Settings::ParseDisplayScaling(const char* str)
|
||||
{
|
||||
int index = 0;
|
||||
for (const char* name : s_display_scaling_names)
|
||||
{
|
||||
if (StringUtil::Strcasecmp(name, str) == 0)
|
||||
return static_cast<DisplayScalingMode>(index);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const char* Settings::GetDisplayScalingName(DisplayScalingMode mode)
|
||||
{
|
||||
return s_display_scaling_names[static_cast<int>(mode)];
|
||||
}
|
||||
|
||||
const char* Settings::GetDisplayScalingDisplayName(DisplayScalingMode mode)
|
||||
{
|
||||
return Host::TranslateToCString("DisplayScalingMode", s_display_scaling_display_names[static_cast<int>(mode)]);
|
||||
}
|
||||
|
||||
static constexpr const char* s_audio_backend_names[] = {
|
||||
|
@ -1470,8 +1499,12 @@ bool EmuFolders::EnsureFoldersExist()
|
|||
result = FileSystem::EnsureDirectoryExists(Screenshots.c_str(), false) && result;
|
||||
result = FileSystem::EnsureDirectoryExists(Shaders.c_str(), false) && result;
|
||||
result = FileSystem::EnsureDirectoryExists(Path::Combine(Shaders, "reshade").c_str(), false) && result;
|
||||
result = FileSystem::EnsureDirectoryExists(Path::Combine(Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Shaders").c_str(), false) && result;
|
||||
result = FileSystem::EnsureDirectoryExists(Path::Combine(Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Textures").c_str(), false) && result;
|
||||
result = FileSystem::EnsureDirectoryExists(
|
||||
Path::Combine(Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Shaders").c_str(), false) &&
|
||||
result;
|
||||
result = FileSystem::EnsureDirectoryExists(
|
||||
Path::Combine(Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Textures").c_str(), false) &&
|
||||
result;
|
||||
result = FileSystem::EnsureDirectoryExists(Textures.c_str(), false) && result;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ struct Settings
|
|||
DisplayCropMode display_crop_mode = DEFAULT_DISPLAY_CROP_MODE;
|
||||
DisplayAspectRatio display_aspect_ratio = DEFAULT_DISPLAY_ASPECT_RATIO;
|
||||
DisplayAlignment display_alignment = DEFAULT_DISPLAY_ALIGNMENT;
|
||||
DisplayScalingMode display_scaling = DEFAULT_DISPLAY_SCALING;
|
||||
u16 display_aspect_ratio_custom_numerator = 0;
|
||||
u16 display_aspect_ratio_custom_denominator = 0;
|
||||
s16 display_active_start_offset = 0;
|
||||
|
@ -128,9 +129,6 @@ struct Settings
|
|||
s8 display_line_end_offset = 0;
|
||||
bool display_force_4_3_for_24bit = false;
|
||||
bool gpu_24bit_chroma_smoothing = false;
|
||||
bool display_linear_filtering = true;
|
||||
bool display_integer_scaling = false;
|
||||
bool display_stretch = false;
|
||||
bool display_show_osd_messages = true;
|
||||
bool display_show_fps = false;
|
||||
bool display_show_speed = false;
|
||||
|
@ -387,6 +385,10 @@ struct Settings
|
|||
static const char* GetDisplayAlignmentName(DisplayAlignment alignment);
|
||||
static const char* GetDisplayAlignmentDisplayName(DisplayAlignment alignment);
|
||||
|
||||
static std::optional<DisplayScalingMode> ParseDisplayScaling(const char* str);
|
||||
static const char* GetDisplayScalingName(DisplayScalingMode mode);
|
||||
static const char* GetDisplayScalingDisplayName(DisplayScalingMode mode);
|
||||
|
||||
static std::optional<AudioBackend> ParseAudioBackend(const char* str);
|
||||
static const char* GetAudioBackendName(AudioBackend backend);
|
||||
static const char* GetAudioBackendDisplayName(AudioBackend backend);
|
||||
|
@ -448,6 +450,7 @@ struct Settings
|
|||
static constexpr DisplayCropMode DEFAULT_DISPLAY_CROP_MODE = DisplayCropMode::Overscan;
|
||||
static constexpr DisplayAspectRatio DEFAULT_DISPLAY_ASPECT_RATIO = DisplayAspectRatio::Auto;
|
||||
static constexpr DisplayAlignment DEFAULT_DISPLAY_ALIGNMENT = DisplayAlignment::Center;
|
||||
static constexpr DisplayScalingMode DEFAULT_DISPLAY_SCALING = DisplayScalingMode::BilinearSmooth;
|
||||
static constexpr float DEFAULT_OSD_SCALE = 100.0f;
|
||||
|
||||
static constexpr u8 DEFAULT_CDROM_READAHEAD_SECTORS = 8;
|
||||
|
|
|
@ -2267,7 +2267,7 @@ bool System::LoadStateFromStream(ByteStream* state, bool update_display, bool ig
|
|||
{
|
||||
media_filename.resize(header.media_filename_length);
|
||||
if (!state->SeekAbsolute(header.offset_to_media_filename) ||
|
||||
!state->Read2(media_filename.data(), header.media_filename_length))
|
||||
!state->Read2(media_filename.data(), header.media_filename_length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2288,7 +2288,7 @@ bool System::LoadStateFromStream(ByteStream* state, bool update_display, bool ig
|
|||
Host::AddFormattedOSDMessage(
|
||||
30.0f,
|
||||
TRANSLATE("OSDMessage", "Failed to open CD image from save state '%s': %s. Using "
|
||||
"existing image '%s', this may result in instability."),
|
||||
"existing image '%s', this may result in instability."),
|
||||
media_filename.c_str(), error.GetDescription().c_str(), old_media->GetFileName().c_str());
|
||||
media = std::move(old_media);
|
||||
header.media_subimage_index = media->GetCurrentSubImage();
|
||||
|
@ -2296,8 +2296,8 @@ bool System::LoadStateFromStream(ByteStream* state, bool update_display, bool ig
|
|||
else
|
||||
{
|
||||
Host::ReportFormattedErrorAsync("Error",
|
||||
TRANSLATE("System", "Failed to open CD image '%s' used by save state: %s."),
|
||||
media_filename.c_str(), error.GetDescription().c_str());
|
||||
TRANSLATE("System", "Failed to open CD image '%s' used by save state: %s."),
|
||||
media_filename.c_str(), error.GetDescription().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2310,8 +2310,8 @@ bool System::LoadStateFromStream(ByteStream* state, bool update_display, bool ig
|
|||
{
|
||||
const u32 num_subimages = media->HasSubImages() ? media->GetSubImageCount() : 1;
|
||||
if (header.media_subimage_index >= num_subimages ||
|
||||
(media->HasSubImages() && media->GetCurrentSubImage() != header.media_subimage_index &&
|
||||
!media->SwitchSubImage(header.media_subimage_index, &error)))
|
||||
(media->HasSubImages() && media->GetCurrentSubImage() != header.media_subimage_index &&
|
||||
!media->SwitchSubImage(header.media_subimage_index, &error)))
|
||||
{
|
||||
Host::ReportFormattedErrorAsync(
|
||||
"Error", TRANSLATE("System", "Failed to switch to subimage %u in CD image '%s' used by save state: %s."),
|
||||
|
@ -3592,6 +3592,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
g_settings.display_crop_mode != old_settings.display_crop_mode ||
|
||||
g_settings.display_aspect_ratio != old_settings.display_aspect_ratio ||
|
||||
g_settings.display_alignment != old_settings.display_alignment ||
|
||||
g_settings.display_scaling != old_settings.display_scaling ||
|
||||
g_settings.display_show_gpu != old_settings.display_show_gpu ||
|
||||
g_settings.gpu_pgxp_enable != old_settings.gpu_pgxp_enable ||
|
||||
g_settings.gpu_pgxp_texture_correction != old_settings.gpu_pgxp_texture_correction ||
|
||||
|
@ -3604,7 +3605,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
g_settings.rewind_enable != old_settings.rewind_enable ||
|
||||
g_settings.runahead_frames != old_settings.runahead_frames)
|
||||
{
|
||||
g_gpu->UpdateSettings();
|
||||
g_gpu->UpdateSettings(old_settings);
|
||||
InvalidateDisplay();
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ enum class DisplayAspectRatio : u8
|
|||
Count
|
||||
};
|
||||
|
||||
enum class DisplayAlignment
|
||||
enum class DisplayAlignment : u8
|
||||
{
|
||||
LeftOrTop,
|
||||
Center,
|
||||
|
@ -124,6 +124,15 @@ enum class DisplayAlignment
|
|||
Count
|
||||
};
|
||||
|
||||
enum class DisplayScalingMode : u8
|
||||
{
|
||||
Nearest,
|
||||
BilinearSmooth,
|
||||
NearestInteger,
|
||||
BilinearSharp,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class AudioBackend : u8
|
||||
{
|
||||
Null,
|
||||
|
|
|
@ -41,9 +41,9 @@ DisplaySettingsWidget::DisplaySettingsWidget(SettingsDialog* dialog, QWidget* pa
|
|||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayAlignment, "Display", "Alignment",
|
||||
&Settings::ParseDisplayAlignment, &Settings::GetDisplayAlignmentName,
|
||||
Settings::DEFAULT_DISPLAY_ALIGNMENT);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.displayLinearFiltering, "Display", "LinearFiltering", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.displayIntegerScaling, "Display", "IntegerScaling", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.displayStretch, "Display", "Stretch", false);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.displayScaling, "Display", "Scaling",
|
||||
&Settings::ParseDisplayScaling, &Settings::GetDisplayScalingName,
|
||||
Settings::DEFAULT_DISPLAY_SCALING);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.internalResolutionScreenshots, "Display",
|
||||
"InternalResolutionScreenshots", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vsync, "Display", "VSync", false);
|
||||
|
@ -66,10 +66,7 @@ DisplaySettingsWidget::DisplaySettingsWidget(SettingsDialog* dialog, QWidget* pa
|
|||
&DisplaySettingsWidget::onGPUFullscreenModeIndexChanged);
|
||||
connect(m_ui.displayAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DisplaySettingsWidget::onAspectRatioChanged);
|
||||
connect(m_ui.displayIntegerScaling, &QCheckBox::stateChanged, this,
|
||||
&DisplaySettingsWidget::onIntegerFilteringChanged);
|
||||
populateGPUAdaptersAndResolutions();
|
||||
onIntegerFilteringChanged();
|
||||
onAspectRatioChanged();
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
|
@ -100,18 +97,9 @@ DisplaySettingsWidget::DisplaySettingsWidget(SettingsDialog* dialog, QWidget* pa
|
|||
m_ui.displayAlignment, tr("Position"),
|
||||
QString::fromUtf8(Settings::GetDisplayAlignmentDisplayName(Settings::DEFAULT_DISPLAY_ALIGNMENT)),
|
||||
tr("Determines the position on the screen when black borders must be added."));
|
||||
dialog->registerWidgetHelp(m_ui.displayLinearFiltering, tr("Linear Upscaling"), tr("Checked"),
|
||||
tr("Uses bilinear texture filtering when displaying the console's framebuffer to the "
|
||||
"screen. <br>Disabling filtering "
|
||||
"will producer a sharper, blockier/pixelated image. Enabling will smooth out the "
|
||||
"image. <br>The option will be less "
|
||||
"noticable the higher the resolution scale."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.displayIntegerScaling, tr("Integer Upscaling"), tr("Unchecked"),
|
||||
tr("Adds padding to the display area to ensure that the ratio between pixels on the host to "
|
||||
"pixels in the console is an integer number. <br>May result in a sharper image in some 2D games."));
|
||||
dialog->registerWidgetHelp(m_ui.displayStretch, tr("Stretch To Fill"), tr("Unchecked"),
|
||||
tr("Fills the window with the active display area, regardless of the aspect ratio."));
|
||||
m_ui.displayScaling, tr("Scaling"), tr("Bilinear (Smooth)"),
|
||||
tr("Determines how the emulated console's output is upscaled or downscaled to your monitor's resolution."));
|
||||
dialog->registerWidgetHelp(m_ui.internalResolutionScreenshots, tr("Internal Resolution Screenshots"), tr("Unchecked"),
|
||||
tr("Saves screenshots at internal render resolution and without postprocessing. If this "
|
||||
"option is disabled, the screenshots will be taken at the window's resolution. "
|
||||
|
@ -177,6 +165,12 @@ void DisplaySettingsWidget::setupAdditionalUi()
|
|||
QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayScalingMode::Count); i++)
|
||||
{
|
||||
m_ui.displayScaling->addItem(
|
||||
QString::fromUtf8(Settings::GetDisplayScalingDisplayName(static_cast<DisplayScalingMode>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayAlignment::Count); i++)
|
||||
{
|
||||
m_ui.displayAlignment->addItem(
|
||||
|
@ -289,13 +283,6 @@ void DisplaySettingsWidget::onGPUFullscreenModeIndexChanged()
|
|||
m_dialog->setStringSettingValue("GPU", "FullscreenMode", m_ui.fullscreenMode->currentText().toUtf8().constData());
|
||||
}
|
||||
|
||||
void DisplaySettingsWidget::onIntegerFilteringChanged()
|
||||
{
|
||||
const bool integer_scaling = m_dialog->getEffectiveBoolValue("Display", "IntegerScaling", false);
|
||||
m_ui.displayLinearFiltering->setEnabled(!integer_scaling);
|
||||
m_ui.displayStretch->setEnabled(!integer_scaling);
|
||||
}
|
||||
|
||||
void DisplaySettingsWidget::onAspectRatioChanged()
|
||||
{
|
||||
const DisplayAspectRatio ratio =
|
||||
|
|
|
@ -22,7 +22,6 @@ private Q_SLOTS:
|
|||
void populateGPUAdaptersAndResolutions();
|
||||
void onGPUAdapterIndexChanged();
|
||||
void onGPUFullscreenModeIndexChanged();
|
||||
void onIntegerFilteringChanged();
|
||||
void onAspectRatioChanged();
|
||||
|
||||
private:
|
||||
|
|
|
@ -154,40 +154,19 @@
|
|||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="displayCropMode"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="displayAlignment"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="displayIntegerScaling">
|
||||
<property name="text">
|
||||
<string>Integer Upscaling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="displayStretch">
|
||||
<property name="text">
|
||||
<string>Stretch To Fill</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="displayLinearFiltering">
|
||||
<property name="text">
|
||||
<string>Linear Upscaling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="internalResolutionScreenshots">
|
||||
<property name="text">
|
||||
<string>Internal Resolution Screenshots</string>
|
||||
|
@ -196,6 +175,16 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Scaling:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="displayScaling"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -426,6 +426,7 @@ bool GPUDevice::CreateResources()
|
|||
plconfig.rasterization = GPUPipeline::RasterizationState::GetNoCullState();
|
||||
plconfig.depth = GPUPipeline::DepthState::GetNoTestsState();
|
||||
plconfig.blend = GPUPipeline::BlendState::GetAlphaBlendingState();
|
||||
plconfig.blend.write_mask = 0x7;
|
||||
plconfig.color_format = HasSurface() ? m_window_info.surface_format : GPUTexture::Format::RGBA8;
|
||||
plconfig.depth_format = GPUTexture::Format::Unknown;
|
||||
plconfig.samples = 1;
|
||||
|
|
|
@ -210,7 +210,8 @@ void ShaderGen::WriteHeader(std::stringstream& ss)
|
|||
ss << "#define SAMPLE_TEXTURE(name, coords) texture(name, coords)\n";
|
||||
ss << "#define SAMPLE_TEXTURE_OFFSET(name, coords, offset) textureOffset(name, coords, offset)\n";
|
||||
ss << "#define SAMPLE_TEXTURE_LEVEL(name, coords, level) textureLod(name, coords, level)\n";
|
||||
ss << "#define SAMPLE_TEXTURE_LEVEL_OFFSET(name, coords, level, offset) textureLodOffset(name, coords, level, offset)\n";
|
||||
ss << "#define SAMPLE_TEXTURE_LEVEL_OFFSET(name, coords, level, offset) textureLodOffset(name, coords, level, "
|
||||
"offset)\n";
|
||||
ss << "#define LOAD_TEXTURE(name, coords, mip) texelFetch(name, coords, mip)\n";
|
||||
ss << "#define LOAD_TEXTURE_MS(name, coords, sample) texelFetch(name, coords, int(sample))\n";
|
||||
ss << "#define LOAD_TEXTURE_OFFSET(name, coords, mip, offset) texelFetchOffset(name, coords, mip, offset)\n";
|
||||
|
@ -303,7 +304,6 @@ void ShaderGen::WriteUniformBufferDeclaration(std::stringstream& ss, bool push_c
|
|||
ss << "cbuffer UBOBlock : register(b0)\n";
|
||||
m_has_uniform_buffer = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members,
|
||||
|
@ -680,44 +680,6 @@ std::string ShaderGen::GenerateCopyFragmentShader()
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ShaderGen::GenerateDisplayVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
DeclareUniformBuffer(ss, {"float4 u_src_rect"}, true);
|
||||
DeclareVertexEntryPoint(ss, {}, 0, 1, {}, true);
|
||||
ss << R"(
|
||||
{
|
||||
float2 pos = float2(float((v_id << 1) & 2u), float(v_id & 2u));
|
||||
v_tex0 = u_src_rect.xy + pos * u_src_rect.zw;
|
||||
v_pos = float4(pos * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
#if API_VULKAN
|
||||
v_pos.y = -v_pos.y;
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ShaderGen::GenerateDisplayFragmentShader(bool set_alpha_to_one /* = false */)
|
||||
{
|
||||
std::stringstream ss;
|
||||
WriteHeader(ss);
|
||||
DeclareTexture(ss, "samp0", 0);
|
||||
DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1);
|
||||
ss << "{\n";
|
||||
|
||||
if (set_alpha_to_one)
|
||||
ss << "o_col0 = float4(SAMPLE_TEXTURE(samp0, v_tex0).rgb, 1.0f);";
|
||||
else
|
||||
ss << "o_col0 = SAMPLE_TEXTURE(samp0, v_tex0);";
|
||||
|
||||
ss << "\n}\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ShaderGen::GenerateImGuiVertexShader()
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -20,8 +20,6 @@ public:
|
|||
std::string GenerateUVQuadVertexShader();
|
||||
std::string GenerateFillFragmentShader();
|
||||
std::string GenerateCopyFragmentShader();
|
||||
std::string GenerateDisplayVertexShader();
|
||||
std::string GenerateDisplayFragmentShader(bool set_alpha_to_one = false);
|
||||
|
||||
std::string GenerateImGuiVertexShader();
|
||||
std::string GenerateImGuiFragmentShader();
|
||||
|
|
Loading…
Reference in a new issue