Rewrite host GPU abstraction

- Don't have to repeat the same thing for 4 renderers.
 - Add native Metal renderer.
This commit is contained in:
Stenzek
2023-08-13 13:42:02 +10:00
parent bfa792ddbf
commit e3d9ba4c99
249 changed files with 28851 additions and 32222 deletions
-29
View File
@@ -125,35 +125,6 @@ target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_link_libraries(core PUBLIC Threads::Threads common util zlib)
target_link_libraries(core PRIVATE stb xxhash imgui rapidjson)
if(WIN32)
target_sources(core PRIVATE
gpu_hw_d3d12.cpp
gpu_hw_d3d12.h
gpu_hw_d3d11.cpp
gpu_hw_d3d11.h
)
target_link_libraries(core PRIVATE winmm.lib)
endif()
if(ENABLE_CUBEB)
target_compile_definitions(core PUBLIC "WITH_CUBEB=1")
endif()
if(ENABLE_OPENGL)
target_sources(core PRIVATE
gpu_hw_opengl.cpp
gpu_hw_opengl.h
)
target_link_libraries(core PRIVATE glad)
endif()
if(ENABLE_VULKAN)
target_sources(core PRIVATE
gpu_hw_vulkan.cpp
gpu_hw_vulkan.h
)
endif()
if(${CPU_ARCH} STREQUAL "x64")
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../dep/xbyak/xbyak")
target_compile_definitions(core PUBLIC "WITH_RECOMPILER=1" "WITH_MMAP_FASTMEM=1")
+93 -55
View File
@@ -19,6 +19,7 @@
#include "resources.h"
#include "save_state_version.h"
#include "settings.h"
#include "shader_cache_version.h"
#include "spu.h"
#include "system.h"
#include "texture_replacements.h"
@@ -27,7 +28,7 @@
#include "scmversion/scmversion.h"
#include "util/audio_stream.h"
#include "util/host_display.h"
#include "util/gpu_device.h"
#include "util/imgui_fullscreen.h"
#include "util/imgui_manager.h"
#include "util/ini_settings_interface.h"
@@ -60,21 +61,11 @@
#ifdef _WIN32
#include "common/windows_headers.h"
#include "util/d3d11_host_display.h"
#include "util/d3d12_host_display.h"
#include <KnownFolders.h>
#include <ShlObj.h>
#include <mmsystem.h>
#endif
#ifdef WITH_OPENGL
#include "util/opengl_host_display.h"
#endif
#ifdef WITH_VULKAN
#include "util/vulkan_host_display.h"
#endif
Log_SetChannel(CommonHostInterface);
namespace CommonHost {
@@ -144,52 +135,89 @@ void CommonHost::PumpMessagesOnCPUThread()
#endif
}
std::unique_ptr<HostDisplay> Host::CreateDisplayForAPI(RenderAPI api)
bool Host::CreateGPUDevice(RenderAPI api)
{
switch (api)
DebugAssert(!g_gpu_device);
Log_InfoPrintf("Trying to create a %s GPU device...", GPUDevice::RenderAPIToString(api));
g_gpu_device = GPUDevice::CreateDeviceForAPI(api);
// TODO: FSUI should always use vsync..
const bool vsync = System::IsValid() ? System::ShouldUseVSync() : g_settings.video_sync_enabled;
if (!g_gpu_device || !g_gpu_device->Create(g_settings.gpu_adapter,
g_settings.gpu_disable_shader_cache ? std::string_view() :
std::string_view(EmuFolders::Cache),
SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, vsync,
g_settings.gpu_threaded_presentation))
{
#ifdef WITH_VULKAN
case RenderAPI::Vulkan:
return std::make_unique<VulkanHostDisplay>();
#endif
#ifdef WITH_OPENGL
case RenderAPI::OpenGL:
case RenderAPI::OpenGLES:
return std::make_unique<OpenGLHostDisplay>();
#endif
#ifdef _WIN32
case RenderAPI::D3D12:
return std::make_unique<D3D12HostDisplay>();
case RenderAPI::D3D11:
return std::make_unique<D3D11HostDisplay>();
#endif
default:
#if defined(_WIN32) && defined(_M_ARM64)
return std::make_unique<D3D12HostDisplay>();
#elif defined(_WIN32)
return std::make_unique<D3D11HostDisplay>();
#elif defined(WITH_OPENGL)
return std::make_unique<OpenGLHostDisplay>();
#elif defined(WITH_VULKAN)
return std::make_unique<VulkanHostDisplay>();
#else
return {};
#endif
Log_ErrorPrintf("Failed to initialize GPU device.");
if (g_gpu_device)
g_gpu_device->Destroy();
g_gpu_device.reset();
return false;
}
if (!ImGuiManager::Initialize())
{
Log_ErrorPrintf("Failed to initialize ImGuiManager.");
g_gpu_device->Destroy();
g_gpu_device.reset();
return false;
}
}
bool CommonHost::CreateHostDisplayResources()
{
return true;
}
void CommonHost::ReleaseHostDisplayResources()
void Host::UpdateDisplayWindow()
{
if (!g_gpu_device)
return;
if (!g_gpu_device->UpdateWindow())
{
Host::ReportErrorAsync("Error", "Failed to change window after update. The log may contain more information.");
return;
}
ImGuiManager::WindowResized();
// If we're paused, re-present the current frame at the new window size.
if (System::IsValid() && System::IsPaused())
RenderDisplay(false);
}
void Host::ResizeDisplayWindow(s32 width, s32 height, float scale)
{
if (!g_gpu_device)
return;
Log_DevPrintf("Display window resized to %dx%d", width, height);
g_gpu_device->ResizeWindow(width, height, scale);
ImGuiManager::WindowResized();
// If we're paused, re-present the current frame at the new window size.
if (System::IsValid())
{
if (System::IsPaused())
RenderDisplay(false);
System::HostDisplayResized();
}
}
void Host::ReleaseGPUDevice()
{
if (!g_gpu_device)
return;
SaveStateSelectorUI::DestroyTextures();
FullscreenUI::Shutdown();
ImGuiManager::Shutdown();
Log_InfoPrintf("Destroying %s GPU device...", GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()));
g_gpu_device->Destroy();
g_gpu_device.reset();
}
#ifndef __ANDROID__
@@ -458,7 +486,10 @@ void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/,
}
ImGui::End();
ImGui::SetNextWindowSize(ImVec2(width, (has_progress ? 50.0f : 30.0f) * scale), ImGuiCond_Always);
const float padding_and_rounding = 15.0f * scale;
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, padding_and_rounding);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(padding_and_rounding, padding_and_rounding));
ImGui::SetNextWindowSize(ImVec2(width, (has_progress ? 80.0f : 50.0f) * scale), ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) + (100.0f * scale)),
ImGuiCond_Always, ImVec2(0.5f, 0.0f));
if (ImGui::Begin("LoadingScreen", nullptr,
@@ -468,7 +499,17 @@ void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/,
{
if (has_progress)
{
ImGui::Text("%s: %d/%d", message, progress_value, progress_max);
ImGui::TextUnformatted(message);
TinyString buf;
buf.Fmt("{}/{}", progress_value, progress_max);
const ImVec2 prog_size = ImGui::CalcTextSize(buf.GetCharArray(), buf.GetCharArray() + buf.GetLength());
ImGui::SameLine();
ImGui::SetCursorPosX(width - padding_and_rounding - prog_size.x);
ImGui::TextUnformatted(buf.GetCharArray(), buf.GetCharArray() + buf.GetLength());
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5.0f);
ImGui::ProgressBar(static_cast<float>(progress_value) / static_cast<float>(progress_max - progress_min),
ImVec2(-1.0f, 0.0f), "");
Log_InfoPrintf("%s: %d/%d", message, progress_value, progress_max);
@@ -482,9 +523,10 @@ void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/,
}
}
ImGui::End();
ImGui::PopStyleVar(2);
ImGui::EndFrame();
g_host_display->Render(false);
g_gpu_device->Render(false);
ImGui::NewFrame();
}
@@ -628,7 +670,6 @@ static void HotkeyModifyResolutionScale(s32 increment)
{
g_gpu->RestoreGraphicsAPIState();
g_gpu->UpdateSettings();
g_gpu->ResetGraphicsAPIState();
System::ClearMemorySaveStates();
Host::InvalidateDisplay();
}
@@ -888,7 +929,6 @@ DEFINE_HOTKEY("TogglePGXP", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_NOO
g_settings.gpu_pgxp_enable = !g_settings.gpu_pgxp_enable;
g_gpu->RestoreGraphicsAPIState();
g_gpu->UpdateSettings();
g_gpu->ResetGraphicsAPIState();
System::ClearMemorySaveStates();
Host::AddKeyedOSDMessage("TogglePGXP",
g_settings.gpu_pgxp_enable ?
@@ -957,7 +997,6 @@ DEFINE_HOTKEY("TogglePGXPDepth", TRANSLATE_NOOP("Hotkeys", "Graphics"),
g_gpu->RestoreGraphicsAPIState();
g_gpu->UpdateSettings();
g_gpu->ResetGraphicsAPIState();
System::ClearMemorySaveStates();
Host::AddKeyedOSDMessage("TogglePGXPDepth",
g_settings.gpu_pgxp_depth_buffer ?
@@ -977,7 +1016,6 @@ DEFINE_HOTKEY("TogglePGXPCPU", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_
g_gpu->RestoreGraphicsAPIState();
g_gpu->UpdateSettings();
g_gpu->ResetGraphicsAPIState();
System::ClearMemorySaveStates();
Host::AddKeyedOSDMessage("TogglePGXPCPU",
g_settings.gpu_pgxp_cpu ?
-2
View File
@@ -35,8 +35,6 @@ void OnSystemPaused();
void OnSystemResumed();
void OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name);
void PumpMessagesOnCPUThread();
bool CreateHostDisplayResources();
void ReleaseHostDisplayResources();
/// Returns the time elapsed in the current play session.
u64 GetSessionPlayedTime();
-16
View File
@@ -39,12 +39,7 @@
<ClCompile Include="game_list.cpp" />
<ClCompile Include="gpu_backend.cpp" />
<ClCompile Include="gpu_commands.cpp" />
<ClCompile Include="gpu_hw_d3d11.cpp" />
<ClCompile Include="gpu_hw_d3d12.cpp" />
<ClCompile Include="gpu_hw_shadergen.cpp" />
<ClCompile Include="gpu_hw_vulkan.cpp">
<ExcludedFromBuild Condition="'$(Platform)'=='ARM64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="gpu_sw.cpp" />
<ClCompile Include="gpu_sw_backend.cpp" />
<ClCompile Include="gte.cpp" />
@@ -52,9 +47,6 @@
<ClCompile Include="gdb_protocol.cpp" />
<ClCompile Include="gpu.cpp" />
<ClCompile Include="gpu_hw.cpp" />
<ClCompile Include="gpu_hw_opengl.cpp">
<ExcludedFromBuild Condition="'$(Platform)'=='ARM64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="host.cpp" />
<ClCompile Include="host_interface_progress_callback.cpp" />
<ClCompile Include="host_settings.cpp" />
@@ -113,12 +105,7 @@
<ClInclude Include="game_database.h" />
<ClInclude Include="game_list.h" />
<ClInclude Include="gpu_backend.h" />
<ClInclude Include="gpu_hw_d3d11.h" />
<ClInclude Include="gpu_hw_d3d12.h" />
<ClInclude Include="gpu_hw_shadergen.h" />
<ClInclude Include="gpu_hw_vulkan.h">
<ExcludedFromBuild Condition="'$(Platform)'=='ARM64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="gpu_sw.h" />
<ClInclude Include="gpu_sw_backend.h" />
<ClInclude Include="gpu_types.h" />
@@ -128,9 +115,6 @@
<ClInclude Include="gdb_protocol.h" />
<ClInclude Include="gpu.h" />
<ClInclude Include="gpu_hw.h" />
<ClInclude Include="gpu_hw_opengl.h">
<ExcludedFromBuild Condition="'$(Platform)'=='ARM64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="gte_types.h" />
<ClInclude Include="host.h" />
<ClInclude Include="host_interface_progress_callback.h" />
+1 -9
View File
@@ -8,7 +8,6 @@
<ClCompile Include="dma.cpp" />
<ClCompile Include="gdb_protocol.cpp" />
<ClCompile Include="gpu.cpp" />
<ClCompile Include="gpu_hw_opengl.cpp" />
<ClCompile Include="gpu_hw.cpp" />
<ClCompile Include="interrupt_controller.cpp" />
<ClCompile Include="cdrom.cpp" />
@@ -23,7 +22,6 @@
<ClCompile Include="gpu_commands.cpp" />
<ClCompile Include="gpu_sw.cpp" />
<ClCompile Include="gpu_hw_shadergen.cpp" />
<ClCompile Include="gpu_hw_d3d11.cpp" />
<ClCompile Include="bios.cpp" />
<ClCompile Include="cpu_code_cache.cpp" />
<ClCompile Include="cpu_recompiler_register_cache.cpp" />
@@ -41,7 +39,6 @@
<ClCompile Include="guncon.cpp" />
<ClCompile Include="playstation_mouse.cpp" />
<ClCompile Include="negcon.cpp" />
<ClCompile Include="gpu_hw_vulkan.cpp" />
<ClCompile Include="resources.cpp" />
<ClCompile Include="host_interface_progress_callback.cpp" />
<ClCompile Include="pgxp.cpp" />
@@ -53,7 +50,6 @@
<ClCompile Include="gpu_sw_backend.cpp" />
<ClCompile Include="texture_replacements.cpp" />
<ClCompile Include="multitap.cpp" />
<ClCompile Include="gpu_hw_d3d12.cpp" />
<ClCompile Include="host.cpp" />
<ClCompile Include="game_database.cpp" />
<ClCompile Include="pcdrv.cpp" />
@@ -74,7 +70,6 @@
<ClInclude Include="bus.h" />
<ClInclude Include="dma.h" />
<ClInclude Include="gpu.h" />
<ClInclude Include="gpu_hw_opengl.h" />
<ClInclude Include="gpu_hw.h" />
<ClInclude Include="interrupt_controller.h" />
<ClInclude Include="cdrom.h" />
@@ -88,7 +83,6 @@
<ClInclude Include="settings.h" />
<ClInclude Include="gpu_sw.h" />
<ClInclude Include="gpu_hw_shadergen.h" />
<ClInclude Include="gpu_hw_d3d11.h" />
<ClInclude Include="bios.h" />
<ClInclude Include="cpu_recompiler_types.h" />
<ClInclude Include="cpu_code_cache.h" />
@@ -104,7 +98,6 @@
<ClInclude Include="guncon.h" />
<ClInclude Include="playstation_mouse.h" />
<ClInclude Include="negcon.h" />
<ClInclude Include="gpu_hw_vulkan.h" />
<ClInclude Include="resources.h" />
<ClInclude Include="host_interface_progress_callback.h" />
<ClInclude Include="gte_types.h" />
@@ -117,9 +110,7 @@
<ClInclude Include="gpu_backend.h" />
<ClInclude Include="gpu_sw_backend.h" />
<ClInclude Include="texture_replacements.h" />
<ClInclude Include="shader_cache_version.h" />
<ClInclude Include="multitap.h" />
<ClInclude Include="gpu_hw_d3d12.h" />
<ClInclude Include="gdb_protocol.h" />
<ClInclude Include="host.h" />
<ClInclude Include="host_settings.h" />
@@ -132,5 +123,6 @@
<ClInclude Include="fullscreen_ui.h" />
<ClInclude Include="common_host.h" />
<ClInclude Include="achievements_private.h" />
<ClInclude Include="shader_cache_version.h" />
</ItemGroup>
</Project>
+26 -23
View File
@@ -18,10 +18,10 @@
#include "resources.h"
#include "settings.h"
#include "system.h"
#include "util/host_display.h"
#include "scmversion/scmversion.h"
#include "util/gpu_device.h"
#include "util/imgui_fullscreen.h"
#include "util/imgui_manager.h"
#include "util/ini_settings_interface.h"
@@ -404,7 +404,7 @@ static std::unique_ptr<GameList::Entry> s_game_settings_entry;
static std::vector<std::pair<std::string, bool>> s_game_list_directories_cache;
static std::vector<std::string> s_graphics_adapter_list_cache;
static std::vector<std::string> s_fullscreen_mode_list_cache;
static FrontendCommon::PostProcessingChain s_postprocessing_chain;
static PostProcessingChain s_postprocessing_chain;
static std::vector<const HotkeyInfo*> s_hotkey_list_cache;
static std::atomic_bool s_settings_changed{false};
static std::atomic_bool s_game_settings_changed{false};
@@ -2394,7 +2394,7 @@ void FullscreenUI::SwitchToGameSettings(const GameList::Entry* entry)
void FullscreenUI::PopulateGraphicsAdapterList()
{
HostDisplay::AdapterAndModeList ml(g_host_display->GetAdapterAndModeList());
GPUDevice::AdapterAndModeList ml(g_gpu_device->GetAdapterAndModeList());
s_graphics_adapter_list_cache = std::move(ml.adapter_names);
s_fullscreen_mode_list_cache = std::move(ml.fullscreen_modes);
s_fullscreen_mode_list_cache.insert(s_fullscreen_mode_list_cache.begin(), FSUI_STR("Borderless Fullscreen"));
@@ -3653,7 +3653,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
adapter.has_value() ? (adapter->empty() ? FSUI_CSTR("Default") : adapter->c_str()) :
FSUI_CSTR("Use Global Setting")))
{
HostDisplay::AdapterAndModeList aml(g_host_display->GetAdapterAndModeList());
GPUDevice::AdapterAndModeList aml(g_gpu_device->GetAdapterAndModeList());
ImGuiFullscreen::ChoiceDialogOptions options;
options.reserve(aml.adapter_names.size() + 2);
@@ -3698,7 +3698,7 @@ void FullscreenUI::DrawDisplaySettingsPage()
fsmode.has_value() ? (fsmode->empty() ? FSUI_CSTR("Borderless Fullscreen") : fsmode->c_str()) :
FSUI_CSTR("Use Global Setting")))
{
HostDisplay::AdapterAndModeList aml(g_host_display->GetAdapterAndModeList());
GPUDevice::AdapterAndModeList aml(g_gpu_device->GetAdapterAndModeList());
ImGuiFullscreen::ChoiceDialogOptions options;
options.reserve(aml.fullscreen_modes.size() + 2);
@@ -3939,7 +3939,7 @@ void FullscreenUI::SavePostProcessingChain()
const std::string config(s_postprocessing_chain.GetConfigString());
bsi->SetStringValue("Display", "PostProcessChain", config.c_str());
if (bsi->GetBoolValue("Display", "PostProcessing", false))
g_host_display->SetPostProcessingChain(config);
g_gpu_device->SetPostProcessingChain(config);
if (IsEditingGameSettings(bsi))
{
s_game_settings_interface->Save();
@@ -3975,7 +3975,7 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
bsi->GetBoolValue("Display", "PostProcessing", false)))
{
const std::string chain(bsi->GetStringValue("Display", "PostProcessChain", ""));
g_host_display->SetPostProcessingChain(chain);
g_gpu_device->SetPostProcessingChain(chain);
if (chain.empty())
ShowToast(std::string(), FSUI_STR("Post-processing chain is empty."));
else
@@ -3987,7 +3987,7 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
if (MenuButton(FSUI_ICONSTR(ICON_FA_PLUS, "Add Shader"), FSUI_CSTR("Adds a new shader to the chain.")))
{
ImGuiFullscreen::ChoiceDialogOptions options;
for (std::string& name : FrontendCommon::PostProcessingChain::GetAvailableShaderNames())
for (std::string& name : PostProcessingChain::GetAvailableShaderNames())
options.emplace_back(std::move(name), false);
OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_PLUS, "Add Shader"), false, std::move(options),
@@ -4034,8 +4034,8 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
for (u32 stage_index = 0; stage_index < s_postprocessing_chain.GetStageCount(); stage_index++)
{
ImGui::PushID(stage_index);
FrontendCommon::PostProcessingShader& stage = s_postprocessing_chain.GetShaderStage(stage_index);
str.Fmt(FSUI_FSTR("Stage {}: {}"), stage_index + 1, stage.GetName());
PostProcessingShader* stage = s_postprocessing_chain.GetShaderStage(stage_index);
str.Fmt(FSUI_FSTR("Stage {}: {}"), stage_index + 1, stage->GetName());
MenuHeading(str);
if (MenuButton(FSUI_ICONSTR(ICON_FA_TIMES, "Remove From Chain"), FSUI_CSTR("Removes this shader from the chain.")))
@@ -4059,11 +4059,11 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
postprocessing_action_index = stage_index;
}
for (FrontendCommon::PostProcessingShader::Option& opt : stage.GetOptions())
for (PostProcessingShader::Option& opt : stage->GetOptions())
{
switch (opt.type)
{
case FrontendCommon::PostProcessingShader::Option::Type::Bool:
case PostProcessingShader::Option::Type::Bool:
{
bool value = (opt.value[0].int_value != 0);
tstr.Fmt(ICON_FA_COGS "{}", opt.ui_name);
@@ -4078,7 +4078,7 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
}
break;
case FrontendCommon::PostProcessingShader::Option::Type::Float:
case PostProcessingShader::Option::Type::Float:
{
tstr.Fmt(ICON_FA_RULER_VERTICAL "{}##{}", opt.ui_name, opt.name);
str.Fmt(FSUI_FSTR("Value: {} | Default: {} | Minimum: {} | Maximum: {}"), opt.value[0].float_value,
@@ -4181,7 +4181,7 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
}
break;
case FrontendCommon::PostProcessingShader::Option::Type::Int:
case PostProcessingShader::Option::Type::Int:
{
tstr.Fmt(ICON_FA_RULER_VERTICAL "{}##{}", opt.ui_name, opt.name);
str.Fmt(FSUI_FSTR("Value: {} | Default: {} | Minimum: {} | Maximum: {}"), opt.value[0].int_value,
@@ -4293,9 +4293,9 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
{
case POSTPROCESSING_ACTION_REMOVE:
{
FrontendCommon::PostProcessingShader& stage = s_postprocessing_chain.GetShaderStage(postprocessing_action_index);
PostProcessingShader* stage = s_postprocessing_chain.GetShaderStage(postprocessing_action_index);
ShowToast(std::string(),
fmt::format(FSUI_FSTR("Removed stage {} ({})."), postprocessing_action_index + 1, stage.GetName()));
fmt::format(FSUI_FSTR("Removed stage {} ({})."), postprocessing_action_index + 1, stage->GetName()));
s_postprocessing_chain.RemoveStage(postprocessing_action_index);
SavePostProcessingChain();
}
@@ -4598,7 +4598,9 @@ void FullscreenUI::DrawAchievementsSettingsPage()
EndMenuButtons();
}
void FullscreenUI::DrawAchievementsLoginWindow() {}
void FullscreenUI::DrawAchievementsLoginWindow()
{
}
#endif
@@ -5016,15 +5018,16 @@ void FullscreenUI::PopulateSaveStateScreenshot(SaveStateListEntry* li, const Ext
li->preview_texture.reset();
if (ssi && !ssi->screenshot_data.empty())
{
li->preview_texture =
g_host_display->CreateTexture(ssi->screenshot_width, ssi->screenshot_height, 1, 1, 1, GPUTexture::Format::RGBA8,
ssi->screenshot_data.data(), sizeof(u32) * ssi->screenshot_width, false);
li->preview_texture = g_gpu_device->CreateTexture(
ssi->screenshot_width, ssi->screenshot_height, 1, 1, 1, GPUTexture::Type::Texture, GPUTexture::Format::RGBA8,
ssi->screenshot_data.data(), sizeof(u32) * ssi->screenshot_width, false);
}
else
{
li->preview_texture = g_host_display->CreateTexture(
Resources::PLACEHOLDER_ICON_WIDTH, Resources::PLACEHOLDER_ICON_HEIGHT, 1, 1, 1, GPUTexture::Format::RGBA8,
Resources::PLACEHOLDER_ICON_DATA, sizeof(u32) * Resources::PLACEHOLDER_ICON_WIDTH, false);
li->preview_texture = g_gpu_device->CreateTexture(
Resources::PLACEHOLDER_ICON_WIDTH, Resources::PLACEHOLDER_ICON_HEIGHT, 1, 1, 1, GPUTexture::Type::Texture,
GPUTexture::Format::RGBA8, Resources::PLACEHOLDER_ICON_DATA, sizeof(u32) * Resources::PLACEHOLDER_ICON_WIDTH,
false);
}
if (!li->preview_texture)
+34 -24
View File
@@ -8,13 +8,13 @@
#include "common/string_util.h"
#include "dma.h"
#include "host.h"
#include "util/host_display.h"
#include "imgui.h"
#include "interrupt_controller.h"
#include "settings.h"
#include "stb_image_write.h"
#include "system.h"
#include "timers.h"
#include "util/gpu_device.h"
#include "util/state_wrapper.h"
#include <cmath>
Log_SetChannel(GPU);
@@ -27,8 +27,8 @@ GPU::GPU() = default;
GPU::~GPU()
{
if (g_host_display)
g_host_display->SetGPUTimingEnabled(false);
if (g_gpu_device)
g_gpu_device->SetGPUTimingEnabled(false);
}
bool GPU::Initialize()
@@ -49,12 +49,12 @@ bool GPU::Initialize()
UpdateCRTCConfig();
if (g_settings.display_post_processing && !g_settings.display_post_process_chain.empty() &&
!g_host_display->SetPostProcessingChain(g_settings.display_post_process_chain))
!g_gpu_device->SetPostProcessingChain(g_settings.display_post_process_chain))
{
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
}
g_host_display->SetGPUTimingEnabled(g_settings.display_show_gpu);
g_gpu_device->SetGPUTimingEnabled(g_settings.display_show_gpu);
return true;
}
@@ -75,13 +75,7 @@ void GPU::UpdateSettings()
// Crop mode calls this, so recalculate the display area
UpdateCRTCDisplayParameters();
g_host_display->SetGPUTimingEnabled(g_settings.display_show_gpu);
}
bool GPU::IsHardwareRenderer()
{
const GPURenderer renderer = GetRendererType();
return (renderer != GPURenderer::Software);
g_gpu_device->SetGPUTimingEnabled(g_settings.display_show_gpu);
}
void GPU::CPUClockChanged()
@@ -89,7 +83,9 @@ void GPU::CPUClockChanged()
UpdateCRTCConfig();
}
void GPU::UpdateResolutionScale() {}
void GPU::UpdateResolutionScale()
{
}
std::tuple<u32, u32> GPU::GetEffectiveDisplayResolution(bool scaled /* = true */)
{
@@ -168,6 +164,8 @@ void GPU::SoftReset()
bool GPU::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
{
FlushRender();
if (sw.IsReading())
{
// perform a reset to discard all pending draws/fb state
@@ -293,9 +291,9 @@ bool GPU::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_displ
return !sw.HasError();
}
void GPU::ResetGraphicsAPIState() {}
void GPU::RestoreGraphicsAPIState() {}
void GPU::RestoreGraphicsAPIState()
{
}
void GPU::UpdateDMARequest()
{
@@ -980,8 +978,8 @@ void GPU::UpdateCommandTickEvent()
bool GPU::ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, float x_scale, u32* out_tick,
u32* out_line) const
{
auto [display_x, display_y] = g_host_display->ConvertWindowCoordinatesToDisplayCoordinates(
window_x, window_y, g_host_display->GetWindowWidth(), g_host_display->GetWindowHeight());
auto [display_x, display_y] = g_gpu_device->ConvertWindowCoordinatesToDisplayCoordinates(
window_x, window_y, g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight());
if (x_scale != 1.0f)
{
@@ -1284,11 +1282,17 @@ void GPU::HandleGetGPUInfoCommand(u32 value)
}
}
void GPU::ClearDisplay() {}
void GPU::ClearDisplay()
{
}
void GPU::UpdateDisplay() {}
void GPU::UpdateDisplay()
{
}
void GPU::ReadVRAM(u32 x, u32 y, u32 width, u32 height) {}
void GPU::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
{
}
void GPU::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
{
@@ -1446,9 +1450,13 @@ void GPU::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 he
}
}
void GPU::DispatchRenderCommand() {}
void GPU::DispatchRenderCommand()
{
}
void GPU::FlushRender() {}
void GPU::FlushRender()
{
}
void GPU::SetDrawMode(u16 value)
{
@@ -1687,4 +1695,6 @@ void GPU::DrawDebugStateWindow()
ImGui::End();
}
void GPU::DrawRendererStats(bool is_idle_frame) {}
void GPU::DrawRendererStats(bool is_idle_frame)
{
}
+8 -26
View File
@@ -17,13 +17,12 @@
class StateWrapper;
class HostDisplay;
class GPUDevice;
class GPUTexture;
class TimingEvent;
namespace Threading
{
namespace Threading {
class Thread;
}
@@ -80,21 +79,20 @@ public:
GPU();
virtual ~GPU();
virtual GPURenderer GetRendererType() const = 0;
virtual const Threading::Thread* GetSWThread() const = 0;
virtual bool IsHardwareRenderer() const = 0;
virtual bool Initialize();
virtual void Reset(bool clear_vram);
virtual bool DoState(StateWrapper& sw, GPUTexture** save_to_texture, bool update_display);
// Graphics API state reset/restore - call when drawing the UI etc.
virtual void ResetGraphicsAPIState();
// TODO: replace with "invalidate cached state"
virtual void RestoreGraphicsAPIState();
// Render statistics debug window.
void DrawDebugStateWindow();
bool IsHardwareRenderer();
void CPUClockChanged();
// MMIO access
@@ -161,25 +159,7 @@ public:
float ComputeVerticalFrequency() const;
float GetDisplayAspectRatio() const;
#ifdef _WIN32
// gpu_hw_d3d11.cpp
static std::unique_ptr<GPU> CreateHardwareD3D11Renderer();
// gpu_hw_d3d12.cpp
static std::unique_ptr<GPU> CreateHardwareD3D12Renderer();
#endif
#ifdef WITH_OPENGL
// gpu_hw_opengl.cpp
static std::unique_ptr<GPU> CreateHardwareOpenGLRenderer();
#endif
#ifdef WITH_VULKAN
// gpu_hw_vulkan.cpp
static std::unique_ptr<GPU> CreateHardwareVulkanRenderer();
#endif
// gpu_sw.cpp
static std::unique_ptr<GPU> CreateHardwareRenderer();
static std::unique_ptr<GPU> CreateSoftwareRenderer();
// Converts window coordinates into horizontal ticks and scanlines. Returns false if out of range. Used for lightguns.
@@ -192,6 +172,9 @@ public:
// Dumps raw VRAM to a file.
bool DumpVRAMToFile(const char* filename);
// Ensures all buffered vertices are drawn.
virtual void FlushRender();
protected:
TickCount CRTCTicksToSystemTicks(TickCount crtc_ticks, TickCount fractional_ticks) const;
TickCount SystemTicksToCRTCTicks(TickCount sysclk_ticks, TickCount* fractional_ticks) const;
@@ -291,7 +274,6 @@ protected:
virtual void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask);
virtual void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
virtual void DispatchRenderCommand();
virtual void FlushRender();
virtual void ClearDisplay();
virtual void UpdateDisplay();
virtual void DrawRendererStats(bool is_idle_frame);
+1354 -187
View File
File diff suppressed because it is too large Load Diff
+108 -187
View File
@@ -2,9 +2,15 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/heap_array.h"
#include "gpu.h"
#include "util/host_display.h"
#include "texture_replacements.h"
#include "util/gpu_device.h"
#include "common/dimensional_array.h"
#include "common/heap_array.h"
#include <sstream>
#include <string>
#include <tuple>
@@ -15,7 +21,7 @@ class GPU_SW_Backend;
struct GPUBackendCommand;
struct GPUBackendDrawCommand;
class GPU_HW : public GPU
class GPU_HW final : public GPU
{
public:
enum class BatchRenderMode : u8
@@ -34,24 +40,26 @@ public:
};
GPU_HW();
virtual ~GPU_HW();
~GPU_HW() override;
const Threading::Thread* GetSWThread() const override;
bool IsHardwareRenderer() const override;
virtual bool Initialize() override;
virtual void Reset(bool clear_vram) override;
virtual bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
bool Initialize() override;
void Reset(bool clear_vram) override;
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
void RestoreGraphicsAPIState() override;
void UpdateSettings() 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;
protected:
private:
enum : u32
{
VRAM_UPDATE_TEXTURE_BUFFER_SIZE = 4 * 1024 * 1024,
VERTEX_BUFFER_SIZE = 4 * 1024 * 1024,
UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024,
MAX_BATCH_VERTEX_COUNTER_IDS = 65536 - 2,
MAX_VERTICES_FOR_RECTANGLE = 6 * (((MAX_PRIMITIVE_WIDTH + (TEXTURE_PAGE_WIDTH - 1)) / TEXTURE_PAGE_WIDTH) + 1u) *
(((MAX_PRIMITIVE_HEIGHT + (TEXTURE_PAGE_HEIGHT - 1)) / TEXTURE_PAGE_HEIGHT) + 1u)
@@ -129,43 +137,6 @@ protected:
u32 u_set_mask_while_drawing;
};
struct VRAMFillUBOData
{
u32 u_dst_x;
u32 u_dst_y;
u32 u_end_x;
u32 u_end_y;
float u_fill_color[4];
u32 u_interlaced_displayed_field;
};
struct VRAMWriteUBOData
{
u32 u_dst_x;
u32 u_dst_y;
u32 u_end_x;
u32 u_end_y;
u32 u_width;
u32 u_height;
u32 u_buffer_base_offset;
u32 u_mask_or_bits;
float u_depth_value;
};
struct VRAMCopyUBOData
{
u32 u_src_x;
u32 u_src_y;
u32 u_dst_x;
u32 u_dst_y;
u32 u_end_x;
u32 u_end_y;
u32 u_width;
u32 u_height;
u32 u_set_mask_bit;
float u_depth_value;
};
struct RendererStats
{
u32 num_batches;
@@ -173,63 +144,42 @@ protected:
u32 num_uniform_buffer_updates;
};
class ShaderCompileProgressTracker
{
public:
ShaderCompileProgressTracker(std::string title, u32 total);
bool CreateBuffers();
void ClearFramebuffer();
void DestroyBuffers();
void Increment();
bool CompilePipelines();
void DestroyPipelines();
private:
std::string m_title;
u64 m_min_time;
u64 m_update_interval;
u64 m_start_time;
u64 m_last_update_time;
u32 m_progress;
u32 m_total;
};
static constexpr std::tuple<float, float, float, float> RGBA8ToFloat(u32 rgba)
{
return std::make_tuple(static_cast<float>(rgba & UINT32_C(0xFF)) * (1.0f / 255.0f),
static_cast<float>((rgba >> 8) & UINT32_C(0xFF)) * (1.0f / 255.0f),
static_cast<float>((rgba >> 16) & UINT32_C(0xFF)) * (1.0f / 255.0f),
static_cast<float>(rgba >> 24) * (1.0f / 255.0f));
}
void UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed);
virtual void UpdateVRAMReadTexture();
virtual void UpdateDepthBufferFromMaskBit() = 0;
virtual void ClearDepthBuffer() = 0;
virtual void SetScissorFromDrawingArea() = 0;
virtual void MapBatchVertexPointer(u32 required_vertices) = 0;
virtual void UnmapBatchVertexPointer(u32 used_vertices) = 0;
virtual void UploadUniformBuffer(const void* uniforms, u32 uniforms_size) = 0;
virtual void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) = 0;
void UpdateVRAMReadTexture();
void UpdateDepthBufferFromMaskBit();
void ClearDepthBuffer();
void SetScissor();
void MapBatchVertexPointer(u32 required_vertices);
void UnmapBatchVertexPointer(u32 used_vertices);
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices);
void ClearDisplay() override;
void UpdateDisplay() override;
u32 CalculateResolutionScale() const;
GPUDownsampleMode GetDownsampleMode(u32 resolution_scale) const;
ALWAYS_INLINE bool IsUsingMultisampling() const { return m_multisamples > 1; }
ALWAYS_INLINE bool IsUsingDownsampling() const
{
return (m_downsample_mode != GPUDownsampleMode::Disabled && !m_GPUSTAT.display_area_color_depth_24);
}
bool IsUsingMultisampling() const;
bool IsUsingDownsampling() const;
void SetFullVRAMDirtyRectangle()
{
m_vram_dirty_rect.Set(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
m_draw_mode.SetTexturePageChanged();
}
void ClearVRAMDirtyRectangle() { m_vram_dirty_rect.SetInvalid(); }
void SetFullVRAMDirtyRectangle();
void ClearVRAMDirtyRectangle();
void IncludeVRAMDirtyRectangle(const Common::Rectangle<u32>& rect);
bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
u32 GetBatchVertexSpace() const { return static_cast<u32>(m_batch_end_vertex_ptr - m_batch_current_vertex_ptr); }
u32 GetBatchVertexCount() const { return static_cast<u32>(m_batch_current_vertex_ptr - m_batch_start_vertex_ptr); }
ALWAYS_INLINE bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
ALWAYS_INLINE u32 GetBatchVertexSpace() const
{
return static_cast<u32>(m_batch_end_vertex_ptr - m_batch_current_vertex_ptr);
}
ALWAYS_INLINE u32 GetBatchVertexCount() const
{
return static_cast<u32>(m_batch_current_vertex_ptr - m_batch_start_vertex_ptr);
}
void EnsureVertexBufferSpace(u32 required_vertices);
void EnsureVertexBufferSpaceForCurrentCommand();
void ResetBatchVertexDepth();
@@ -241,91 +191,31 @@ protected:
}
/// Returns the interlaced mode to use when scanning out/displaying.
ALWAYS_INLINE InterlacedRenderMode GetInterlacedRenderMode() const
{
if (IsInterlacedDisplayEnabled())
{
return m_GPUSTAT.vertical_resolution ? InterlacedRenderMode::InterleavedFields :
InterlacedRenderMode::SeparateFields;
}
else
{
return InterlacedRenderMode::None;
}
}
/// Returns true if the specified texture filtering mode requires dual-source blending.
ALWAYS_INLINE bool TextureFilterRequiresDualSourceBlend(GPUTextureFilter filter)
{
return (filter == GPUTextureFilter::Bilinear || filter == GPUTextureFilter::JINC2 ||
filter == GPUTextureFilter::xBR);
}
/// Returns true if alpha blending should be enabled for drawing the current batch.
ALWAYS_INLINE bool UseAlphaBlending(GPUTransparencyMode transparency_mode, BatchRenderMode render_mode) const
{
if (m_texture_filtering == GPUTextureFilter::Bilinear || m_texture_filtering == GPUTextureFilter::JINC2 ||
m_texture_filtering == GPUTextureFilter::xBR)
{
return true;
}
if (transparency_mode == GPUTransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque)
return false;
return true;
}
InterlacedRenderMode GetInterlacedRenderMode() const;
/// We need two-pass rendering when using BG-FG blending and texturing, as the transparency can be enabled
/// on a per-pixel basis, and the opaque pixels shouldn't be blended at all.
ALWAYS_INLINE bool NeedsTwoPassRendering() const
{
// TODO: see if there's a better way we can do this. definitely can with fbfetch.
return (m_batch.texture_mode != GPUTextureMode::Disabled &&
(m_batch.transparency_mode == GPUTransparencyMode::BackgroundMinusForeground ||
(!m_supports_dual_source_blend && m_batch.transparency_mode != GPUTransparencyMode::Disabled)));
}
/// Returns true if the specified VRAM fill is oversized.
ALWAYS_INLINE static bool IsVRAMFillOversized(u32 x, u32 y, u32 width, u32 height)
{
return ((x + width) > VRAM_WIDTH || (y + height) > VRAM_HEIGHT);
}
ALWAYS_INLINE bool IsUsingSoftwareRendererForReadbacks() { return static_cast<bool>(m_sw_renderer); }
void FillBackendCommandParameters(GPUBackendCommand* cmd) const;
void FillDrawCommand(GPUBackendDrawCommand* cmd, GPURenderCommand rc) const;
void UpdateSoftwareRenderer(bool copy_vram_from_hw);
void ReadSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height);
void UpdateSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask,
bool check_mask);
void FillSoftwareRendererVRAM(u32 x, u32 y, u32 width, u32 height, u32 color);
void CopySoftwareRendererVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
void DispatchRenderCommand() override;
void FlushRender() override;
void DrawRendererStats(bool is_idle_frame) override;
void CalcScissorRect(int* left, int* top, int* right, int* bottom);
std::tuple<s32, s32> ScaleVRAMCoordinates(s32 x, s32 y) const
{
return std::make_tuple(x * s32(m_resolution_scale), y * s32(m_resolution_scale));
}
/// Computes the area affected by a VRAM transfer, including wrap-around of X.
Common::Rectangle<u32> GetVRAMTransferBounds(u32 x, u32 y, u32 width, u32 height) const;
/// Returns true if the VRAM copy shader should be used (oversized copies, masking).
bool UseVRAMCopyShader(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) const;
VRAMFillUBOData GetVRAMFillUBOData(u32 x, u32 y, u32 width, u32 height, u32 color) const;
VRAMWriteUBOData GetVRAMWriteUBOData(u32 x, u32 y, u32 width, u32 height, u32 buffer_offset, bool set_mask,
bool check_mask) const;
VRAMCopyUBOData GetVRAMCopyUBOData(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) const;
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
/// Expands a line into two triangles.
void DrawLine(float x0, float y0, u32 col0, float x1, float y1, u32 col1, float depth);
@@ -340,22 +230,31 @@ protected:
void SetBatchDepthBuffer(bool enabled);
void CheckForDepthClear(const BatchVertex* vertices, u32 num_vertices);
/// UBO data for adaptive smoothing.
struct SmoothingUBOData
{
float min_uv[2];
float max_uv[2];
float rcp_size[2];
};
/// Returns the number of mipmap levels used for adaptive smoothing.
u32 GetAdaptiveDownsamplingMipLevels() const;
/// Returns the UBO data for an adaptive smoothing pass.
SmoothingUBOData GetSmoothingUBO(u32 level, u32 left, u32 top, u32 width, u32 height, u32 tex_width,
u32 tex_height) const;
void DownsampleFramebuffer(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferAdaptive(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferBoxFilter(GPUTexture* source, u32 left, u32 top, u32 width, u32 height);
std::unique_ptr<GPUTexture> m_vram_texture;
std::unique_ptr<GPUTexture> m_vram_depth_texture;
std::unique_ptr<GPUTexture> m_vram_depth_view;
std::unique_ptr<GPUTexture> m_vram_read_texture;
std::unique_ptr<GPUTexture> m_vram_readback_texture;
std::unique_ptr<GPUTexture> m_vram_replacement_texture;
std::unique_ptr<GPUTexture> m_display_texture;
std::unique_ptr<GPUFramebuffer> m_vram_framebuffer;
std::unique_ptr<GPUFramebuffer> m_vram_update_depth_framebuffer;
std::unique_ptr<GPUFramebuffer> m_vram_readback_framebuffer;
std::unique_ptr<GPUFramebuffer> m_display_framebuffer;
std::unique_ptr<GPUTextureBuffer> m_vram_upload_buffer;
std::unique_ptr<GPUTexture> m_vram_write_texture;
FixedHeapArray<u16, VRAM_WIDTH * VRAM_HEIGHT> m_vram_shadow;
std::unique_ptr<GPU_SW_Backend> m_sw_renderer;
BatchVertex* m_batch_start_vertex_ptr = nullptr;
@@ -368,20 +267,17 @@ protected:
u32 m_resolution_scale = 1;
u32 m_multisamples = 1;
u32 m_max_resolution_scale = 1;
u32 m_max_multisamples = 1;
RenderAPI m_render_api = RenderAPI::None;
bool m_true_color = true;
union
{
BitField<u8, bool, 0, 1> m_supports_per_sample_shading;
BitField<u8, bool, 1, 1> m_supports_dual_source_blend;
BitField<u8, bool, 2, 1> m_supports_adaptive_downsampling;
BitField<u8, bool, 3, 1> m_supports_disable_color_perspective;
BitField<u8, bool, 4, 1> m_per_sample_shading;
BitField<u8, bool, 5, 1> m_scaled_dithering;
BitField<u8, bool, 6, 1> m_chroma_smoothing;
BitField<u8, bool, 7, 1> m_disable_color_perspective;
BitField<u8, bool, 2, 1> m_supports_disable_color_perspective;
BitField<u8, bool, 3, 1> m_per_sample_shading;
BitField<u8, bool, 4, 1> m_scaled_dithering;
BitField<u8, bool, 5, 1> m_chroma_smoothing;
BitField<u8, bool, 6, 1> m_disable_color_perspective;
u8 bits = 0;
};
@@ -397,20 +293,45 @@ protected:
// Bounding box of VRAM area that the GPU has drawn into.
Common::Rectangle<u32> m_vram_dirty_rect;
// Changed state
bool m_batch_ubo_dirty = true;
// [depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing]
DimensionalArray<std::unique_ptr<GPUPipeline>, 2, 2, 5, 9, 4, 3> m_batch_pipelines{};
// [wrapped][interlaced]
DimensionalArray<std::unique_ptr<GPUPipeline>, 2, 2> m_vram_fill_pipelines{};
// [depth_test]
std::array<std::unique_ptr<GPUPipeline>, 2> m_vram_write_pipelines{};
std::array<std::unique_ptr<GPUPipeline>, 2> m_vram_copy_pipelines{};
std::unique_ptr<GPUPipeline> m_vram_readback_pipeline;
std::unique_ptr<GPUPipeline> m_vram_update_depth_pipeline;
// [depth_24][interlace_mode]
DimensionalArray<std::unique_ptr<GPUPipeline>, 3, 2> m_display_pipelines{};
// TODO: get rid of this, and use image blits instead where supported
std::unique_ptr<GPUPipeline> m_copy_pipeline;
std::unique_ptr<GPUTexture> m_downsample_texture;
std::unique_ptr<GPUTexture> m_downsample_render_texture;
std::unique_ptr<GPUFramebuffer> m_downsample_framebuffer;
std::unique_ptr<GPUTexture> m_downsample_weight_texture;
std::unique_ptr<GPUFramebuffer> m_downsample_weight_framebuffer;
std::unique_ptr<GPUPipeline> m_downsample_first_pass_pipeline;
std::unique_ptr<GPUPipeline> m_downsample_mid_pass_pipeline;
std::unique_ptr<GPUPipeline> m_downsample_blur_pass_pipeline;
std::unique_ptr<GPUPipeline> m_downsample_composite_pass_pipeline;
std::unique_ptr<GPUSampler> m_downsample_lod_sampler;
std::unique_ptr<GPUSampler> m_downsample_composite_sampler;
// Statistics
RendererStats m_renderer_stats = {};
RendererStats m_last_renderer_stats = {};
// Changed state
bool m_batch_ubo_dirty = true;
private:
enum : u32
{
MIN_BATCH_VERTEX_COUNT = 6,
MAX_BATCH_VERTEX_COUNT = VERTEX_BUFFER_SIZE / sizeof(BatchVertex)
};
void LoadVertices();
ALWAYS_INLINE void AddVertex(const BatchVertex& v)
File diff suppressed because it is too large Load Diff
-143
View File
@@ -1,143 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/d3d11/shader_cache.h"
#include "common/d3d11/stream_buffer.h"
#include "common/d3d11/texture.h"
#include "gpu_hw.h"
#include "texture_replacements.h"
#include <array>
#include <d3d11.h>
#include <memory>
#include <tuple>
#include <wrl/client.h>
class GPU_HW_D3D11 final : public GPU_HW
{
public:
template<typename T>
using ComPtr = Microsoft::WRL::ComPtr<T>;
GPU_HW_D3D11(ID3D11Device* device, ID3D11DeviceContext* context);
~GPU_HW_D3D11() override;
GPURenderer GetRendererType() const override;
bool Initialize() override;
void Reset(bool clear_vram) override;
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
void ResetGraphicsAPIState() override;
void RestoreGraphicsAPIState() override;
void UpdateSettings() override;
protected:
void ClearDisplay() override;
void UpdateDisplay() override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
void UpdateVRAMReadTexture() override;
void UpdateDepthBufferFromMaskBit() override;
void ClearDepthBuffer() override;
void SetScissorFromDrawingArea() override;
void MapBatchVertexPointer(u32 required_vertices) override;
void UnmapBatchVertexPointer(u32 used_vertices) override;
void UploadUniformBuffer(const void* data, u32 data_size) override;
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
private:
enum : u32
{
// Currently we don't stream uniforms, instead just re-map the buffer every time and let the driver take care of it.
MAX_UNIFORM_BUFFER_SIZE = 64
};
void SetCapabilities();
bool CreateFramebuffer();
void ClearFramebuffer();
void DestroyFramebuffer();
bool CreateVertexBuffer();
bool CreateUniformBuffer();
bool CreateTextureBuffer();
bool CreateStateObjects();
void DestroyStateObjects();
bool CompileShaders();
void DestroyShaders();
void SetViewport(u32 x, u32 y, u32 width, u32 height);
void SetScissor(u32 x, u32 y, u32 width, u32 height);
void SetViewportAndScissor(u32 x, u32 y, u32 width, u32 height);
void DrawUtilityShader(ID3D11PixelShader* shader, const void* uniforms, u32 uniforms_size);
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
void DownsampleFramebuffer(D3D11::Texture& source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferAdaptive(D3D11::Texture& source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferBoxFilter(D3D11::Texture& source, u32 left, u32 top, u32 width, u32 height);
ComPtr<ID3D11Device> m_device;
ComPtr<ID3D11DeviceContext> m_context;
// downsample texture - used for readbacks at >1xIR.
D3D11::Texture m_vram_texture;
D3D11::Texture m_vram_depth_texture;
ComPtr<ID3D11DepthStencilView> m_vram_depth_view;
D3D11::Texture m_vram_read_texture;
D3D11::Texture m_vram_encoding_texture;
D3D11::Texture m_display_texture;
D3D11::StreamBuffer m_vertex_stream_buffer;
D3D11::StreamBuffer m_uniform_stream_buffer;
D3D11::StreamBuffer m_texture_stream_buffer;
ComPtr<ID3D11ShaderResourceView> m_texture_stream_buffer_srv_r16ui;
ComPtr<ID3D11RasterizerState> m_cull_none_rasterizer_state;
ComPtr<ID3D11RasterizerState> m_cull_none_rasterizer_state_no_msaa;
ComPtr<ID3D11DepthStencilState> m_depth_disabled_state;
ComPtr<ID3D11DepthStencilState> m_depth_test_always_state;
ComPtr<ID3D11DepthStencilState> m_depth_test_less_state;
ComPtr<ID3D11DepthStencilState> m_depth_test_greater_state;
ComPtr<ID3D11BlendState> m_blend_disabled_state;
ComPtr<ID3D11BlendState> m_blend_no_color_writes_state;
ComPtr<ID3D11SamplerState> m_point_sampler_state;
ComPtr<ID3D11SamplerState> m_linear_sampler_state;
ComPtr<ID3D11SamplerState> m_trilinear_sampler_state;
std::array<ComPtr<ID3D11BlendState>, 5> m_batch_blend_states; // [transparency_mode]
ComPtr<ID3D11InputLayout> m_batch_input_layout;
std::array<ComPtr<ID3D11VertexShader>, 2> m_batch_vertex_shaders; // [textured]
std::array<std::array<std::array<std::array<ComPtr<ID3D11PixelShader>, 2>, 2>, 9>, 4>
m_batch_pixel_shaders; // [render_mode][texture_mode][dithering][interlacing]
ComPtr<ID3D11VertexShader> m_screen_quad_vertex_shader;
ComPtr<ID3D11VertexShader> m_uv_quad_vertex_shader;
ComPtr<ID3D11PixelShader> m_copy_pixel_shader;
std::array<std::array<ComPtr<ID3D11PixelShader>, 2>, 2> m_vram_fill_pixel_shaders; // [wrapped][interlaced]
ComPtr<ID3D11PixelShader> m_vram_read_pixel_shader;
ComPtr<ID3D11PixelShader> m_vram_write_pixel_shader;
ComPtr<ID3D11PixelShader> m_vram_copy_pixel_shader;
ComPtr<ID3D11PixelShader> m_vram_update_depth_pixel_shader;
std::array<std::array<ComPtr<ID3D11PixelShader>, 3>, 2> m_display_pixel_shaders; // [depth_24][interlaced]
D3D11::Texture m_vram_replacement_texture;
// downsampling
ComPtr<ID3D11PixelShader> m_downsample_first_pass_pixel_shader;
ComPtr<ID3D11PixelShader> m_downsample_mid_pass_pixel_shader;
ComPtr<ID3D11PixelShader> m_downsample_blur_pass_pixel_shader;
ComPtr<ID3D11PixelShader> m_downsample_composite_pixel_shader;
D3D11::Texture m_downsample_texture;
D3D11::Texture m_downsample_weight_texture;
std::vector<std::pair<ComPtr<ID3D11ShaderResourceView>, ComPtr<ID3D11RenderTargetView>>> m_downsample_mip_views;
};
File diff suppressed because it is too large Load Diff
-114
View File
@@ -1,114 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/d3d12/staging_texture.h"
#include "common/d3d12/stream_buffer.h"
#include "common/d3d12/texture.h"
#include "common/dimensional_array.h"
#include "gpu_hw.h"
#include "texture_replacements.h"
#include <array>
#include <memory>
#include <tuple>
class GPU_HW_D3D12 final : public GPU_HW
{
public:
template<typename T>
using ComPtr = Microsoft::WRL::ComPtr<T>;
GPU_HW_D3D12();
~GPU_HW_D3D12() override;
GPURenderer GetRendererType() const override;
bool Initialize() override;
void Reset(bool clear_vram) override;
void ResetGraphicsAPIState() override;
void RestoreGraphicsAPIState() override;
void UpdateSettings() override;
protected:
void ClearDisplay() override;
void UpdateDisplay() override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
void UpdateVRAMReadTexture() override;
void UpdateDepthBufferFromMaskBit() override;
void ClearDepthBuffer() override;
void SetScissorFromDrawingArea() override;
void MapBatchVertexPointer(u32 required_vertices) override;
void UnmapBatchVertexPointer(u32 used_vertices) override;
void UploadUniformBuffer(const void* data, u32 data_size) override;
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
private:
enum : u32
{
MAX_PUSH_CONSTANTS_SIZE = 64,
TEXTURE_REPLACEMENT_BUFFER_SIZE = 64 * 1024 * 1024,
};
void SetCapabilities();
void DestroyResources();
bool CreateRootSignatures();
bool CreateSamplers();
bool CreateFramebuffer();
void ClearFramebuffer();
void DestroyFramebuffer();
bool CreateVertexBuffer();
bool CreateUniformBuffer();
bool CreateTextureBuffer();
bool CompilePipelines();
void DestroyPipelines();
bool CreateTextureReplacementStreamBuffer();
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
ComPtr<ID3D12RootSignature> m_batch_root_signature;
ComPtr<ID3D12RootSignature> m_single_sampler_root_signature;
D3D12::Texture m_vram_texture;
D3D12::Texture m_vram_depth_texture;
D3D12::Texture m_vram_read_texture;
D3D12::Texture m_vram_readback_texture;
D3D12::StagingTexture m_vram_readback_staging_texture;
D3D12::Texture m_display_texture;
D3D12::DescriptorHandle m_point_sampler;
D3D12::DescriptorHandle m_linear_sampler;
D3D12::StreamBuffer m_vertex_stream_buffer;
D3D12::StreamBuffer m_uniform_stream_buffer;
D3D12::StreamBuffer m_texture_stream_buffer;
D3D12::DescriptorHandle m_texture_stream_buffer_srv;
u32 m_current_uniform_buffer_offset = 0;
// [depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing]
DimensionalArray<ComPtr<ID3D12PipelineState>, 2, 2, 5, 9, 4, 2> m_batch_pipelines;
// [wrapped][interlaced]
DimensionalArray<ComPtr<ID3D12PipelineState>, 2, 2> m_vram_fill_pipelines;
// [depth_test]
std::array<ComPtr<ID3D12PipelineState>, 2> m_vram_write_pipelines;
std::array<ComPtr<ID3D12PipelineState>, 2> m_vram_copy_pipelines;
ComPtr<ID3D12PipelineState> m_vram_readback_pipeline;
ComPtr<ID3D12PipelineState> m_vram_update_depth_pipeline;
// [depth_24][interlace_mode]
DimensionalArray<ComPtr<ID3D12PipelineState>, 3, 2> m_display_pipelines;
ComPtr<ID3D12PipelineState> m_copy_pipeline;
D3D12::Texture m_vram_write_replacement_texture;
D3D12::StreamBuffer m_texture_replacment_stream_buffer;
};
File diff suppressed because it is too large Load Diff
-121
View File
@@ -1,121 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/gl/loader.h"
#include "common/gl/program.h"
#include "common/gl/shader_cache.h"
#include "common/gl/stream_buffer.h"
#include "common/gl/texture.h"
#include "gpu_hw.h"
#include "texture_replacements.h"
#include <array>
#include <memory>
#include <tuple>
class GPU_HW_OpenGL final : public GPU_HW
{
public:
GPU_HW_OpenGL();
~GPU_HW_OpenGL() override;
GPURenderer GetRendererType() const override;
bool Initialize() override;
void Reset(bool clear_vram) override;
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
void ResetGraphicsAPIState() override;
void RestoreGraphicsAPIState() override;
void UpdateSettings() override;
protected:
void ClearDisplay() override;
void UpdateDisplay() override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
void UpdateVRAMReadTexture() override;
void UpdateDepthBufferFromMaskBit() override;
void ClearDepthBuffer() override;
void SetScissorFromDrawingArea() override;
void MapBatchVertexPointer(u32 required_vertices) override;
void UnmapBatchVertexPointer(u32 used_vertices) override;
void UploadUniformBuffer(const void* data, u32 data_size) override;
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
private:
struct GLStats
{
u32 num_batches;
u32 num_vertices;
u32 num_vram_reads;
u32 num_vram_writes;
u32 num_vram_read_texture_updates;
u32 num_uniform_buffer_updates;
};
ALWAYS_INLINE bool IsGLES() const { return (m_render_api == RenderAPI::OpenGLES); }
void SetCapabilities();
bool CreateFramebuffer();
void ClearFramebuffer();
void CopyFramebufferForState(GLenum target, GLuint src_texture, u32 src_fbo, u32 src_x, u32 src_y, GLuint dst_texture,
u32 dst_fbo, u32 dst_x, u32 dst_y, u32 width, u32 height);
bool CreateVertexBuffer();
bool CreateUniformBuffer();
bool CreateTextureBuffer();
bool CompilePrograms();
void SetDepthFunc();
void SetDepthFunc(GLenum func);
void SetBlendMode();
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
void DownsampleFramebuffer(GL::Texture& source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferBoxFilter(GL::Texture& source, u32 left, u32 top, u32 width, u32 height);
// downsample texture - used for readbacks at >1xIR.
GL::Texture m_vram_texture;
GL::Texture m_vram_depth_texture;
GL::Texture m_vram_read_texture;
GL::Texture m_vram_encoding_texture;
GL::Texture m_display_texture;
GL::Texture m_vram_write_replacement_texture;
std::unique_ptr<GL::StreamBuffer> m_vertex_stream_buffer;
GLuint m_vram_fbo_id = 0;
GLuint m_vao_id = 0;
GLuint m_attributeless_vao_id = 0;
GLuint m_state_copy_fbo_id = 0;
std::unique_ptr<GL::StreamBuffer> m_uniform_stream_buffer;
std::unique_ptr<GL::StreamBuffer> m_texture_stream_buffer;
GLuint m_texture_buffer_r16ui_texture = 0;
std::array<std::array<std::array<std::array<GL::Program, 2>, 2>, 9>, 4>
m_render_programs; // [render_mode][texture_mode][dithering][interlacing]
std::array<std::array<GL::Program, 3>, 2> m_display_programs; // [depth_24][interlaced]
std::array<std::array<GL::Program, 2>, 2> m_vram_fill_programs;
GL::Program m_vram_read_program;
GL::Program m_vram_write_program;
GL::Program m_vram_copy_program;
GL::Program m_vram_update_depth_program;
u32 m_uniform_buffer_alignment = 1;
u32 m_texture_stream_buffer_size = 0;
bool m_use_texture_buffer_for_vram_writes = false;
bool m_use_ssbo_for_vram_writes = false;
GLenum m_current_depth_test = 0;
GPUTransparencyMode m_current_transparency_mode = GPUTransparencyMode::Disabled;
BatchRenderMode m_current_render_mode = BatchRenderMode::TransparencyDisabled;
GL::Texture m_downsample_texture;
GL::Program m_downsample_program;
};
+36 -11
View File
@@ -1162,6 +1162,8 @@ std::string GPU_HW_ShaderGen::GenerateVRAMWriteFragmentShader(bool use_ssbo)
ss << "layout(std430";
if (IsVulkan())
ss << ", set = 0, binding = 0";
else if (IsMetal())
ss << ", set = 0, binding = 1";
else if (m_use_glsl_binding_layout)
ss << ", binding = 0";
@@ -1327,13 +1329,37 @@ std::string GPU_HW_ShaderGen::GenerateVRAMUpdateDepthFragmentShader()
return ss.str();
}
void GPU_HW_ShaderGen::WriteAdaptiveDownsampleUniformBuffer(std::stringstream& ss)
{
DeclareUniformBuffer(ss, {"float2 u_uv_min", "float2 u_uv_max", "float2 u_rcp_resolution", "float u_lod"}, true);
}
std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleVertexShader()
{
std::stringstream ss;
WriteHeader(ss);
WriteAdaptiveDownsampleUniformBuffer(ss);
DeclareVertexEntryPoint(ss, {}, 0, 1, {}, true);
ss << R"(
{
v_tex0 = float2(float((v_id << 1) & 2u), float(v_id & 2u));
v_pos = float4(v_tex0 * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
v_tex0 = u_uv_min + (u_uv_max - u_uv_min) * v_tex0;
#if API_OPENGL || API_OPENGL_ES || API_VULKAN
v_pos.y = -v_pos.y;
#endif
}
)";
return ss.str();
}
std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleMipFragmentShader(bool first_pass)
{
std::stringstream ss;
WriteHeader(ss);
WriteCommonFunctions(ss);
WriteAdaptiveDownsampleUniformBuffer(ss);
DeclareTexture(ss, "samp0", 0, false);
DeclareUniformBuffer(ss, {"float2 u_uv_min", "float2 u_uv_max", "float2 u_rcp_resolution"}, true);
DefineMacro(ss, "FIRST_PASS", first_pass);
// mipmap_energy.glsl ported from parallel-rsx.
@@ -1368,16 +1394,16 @@ float4 get_bias(float4 c00, float4 c01, float4 c10, float4 c11)
{
float2 uv = v_tex0 - (u_rcp_resolution * 0.25);
#ifdef FIRST_PASS
vec3 c00 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(0, 0)).rgb;
vec3 c01 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(0, 1)).rgb;
vec3 c10 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(1, 0)).rgb;
vec3 c11 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(1, 1)).rgb;
vec3 c00 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(0, 0)).rgb;
vec3 c01 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(0, 1)).rgb;
vec3 c10 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(1, 0)).rgb;
vec3 c11 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(1, 1)).rgb;
o_col0 = get_bias(c00, c01, c10, c11);
#else
vec4 c00 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(0, 0));
vec4 c01 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(0, 1));
vec4 c10 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(1, 0));
vec4 c11 = SAMPLE_TEXTURE_OFFSET(samp0, uv, int2(1, 1));
vec4 c00 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(0, 0));
vec4 c01 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(0, 1));
vec4 c10 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(1, 0));
vec4 c11 = SAMPLE_TEXTURE_LEVEL_OFFSET(samp0, uv, u_lod, int2(1, 1));
o_col0 = get_bias(c00, c01, c10, c11);
#endif
}
@@ -1391,9 +1417,8 @@ std::string GPU_HW_ShaderGen::GenerateAdaptiveDownsampleBlurFragmentShader()
std::stringstream ss;
WriteHeader(ss);
WriteCommonFunctions(ss);
WriteAdaptiveDownsampleUniformBuffer(ss);
DeclareTexture(ss, "samp0", 0, false);
DeclareUniformBuffer(ss, {"float2 u_uv_min", "float2 u_uv_max", "float2 u_rcp_resolution", "float sample_level"},
true);
// mipmap_blur.glsl ported from parallel-rsx.
DeclareFragmentEntryPoint(ss, 0, 1, {}, false, 1, false, false, false, false);
+2
View File
@@ -24,6 +24,7 @@ public:
std::string GenerateVRAMFillFragmentShader(bool wrapped, bool interlaced);
std::string GenerateVRAMUpdateDepthFragmentShader();
std::string GenerateAdaptiveDownsampleVertexShader();
std::string GenerateAdaptiveDownsampleMipFragmentShader(bool first_pass);
std::string GenerateAdaptiveDownsampleBlurFragmentShader();
std::string GenerateAdaptiveDownsampleCompositeFragmentShader();
@@ -36,6 +37,7 @@ private:
void WriteCommonFunctions(std::stringstream& ss);
void WriteBatchUniformBuffer(std::stringstream& ss);
void WriteBatchTextureFilter(std::stringstream& ss, GPUTextureFilter texture_filter);
void WriteAdaptiveDownsampleUniformBuffer(std::stringstream& ss);
u32 m_resolution_scale;
u32 m_multisamples;
File diff suppressed because it is too large Load Diff
-169
View File
@@ -1,169 +0,0 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/dimensional_array.h"
#include "common/vulkan/stream_buffer.h"
#include "common/vulkan/texture.h"
#include "gpu_hw.h"
#include "texture_replacements.h"
#include <array>
#include <memory>
#include <tuple>
class GPU_HW_Vulkan final : public GPU_HW
{
public:
GPU_HW_Vulkan();
~GPU_HW_Vulkan() override;
GPURenderer GetRendererType() const override;
bool Initialize() override;
void Reset(bool clear_vram) override;
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
void ResetGraphicsAPIState() override;
void RestoreGraphicsAPIState() override;
void UpdateSettings() override;
protected:
void ClearDisplay() override;
void UpdateDisplay() override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
void UpdateVRAMReadTexture() override;
void UpdateDepthBufferFromMaskBit() override;
void ClearDepthBuffer() override;
void SetScissorFromDrawingArea() override;
void MapBatchVertexPointer(u32 required_vertices) override;
void UnmapBatchVertexPointer(u32 used_vertices) override;
void UploadUniformBuffer(const void* data, u32 data_size) override;
void DrawBatchVertices(BatchRenderMode render_mode, u32 base_vertex, u32 num_vertices) override;
private:
enum : u32
{
MAX_PUSH_CONSTANTS_SIZE = 64,
};
void SetCapabilities();
void DestroyResources();
ALWAYS_INLINE bool InRenderPass() const { return (m_current_render_pass != VK_NULL_HANDLE); }
void BeginRenderPass(VkRenderPass render_pass, VkFramebuffer framebuffer, u32 x, u32 y, u32 width, u32 height,
const VkClearValue* clear_value = nullptr);
void BeginVRAMRenderPass();
void EndRenderPass();
void ExecuteCommandBuffer(bool wait_for_completion, bool restore_state);
bool CreatePipelineLayouts();
bool CreateSamplers();
bool CreateFramebuffer();
void ClearFramebuffer();
void DestroyFramebuffer();
bool CreateVertexBuffer();
bool CreateUniformBuffer();
bool CreateTextureBuffer();
bool CompilePipelines();
void DestroyPipelines();
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
void DownsampleFramebuffer(Vulkan::Texture& source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferBoxFilter(Vulkan::Texture& source, u32 left, u32 top, u32 width, u32 height);
void DownsampleFramebufferAdaptive(Vulkan::Texture& source, u32 left, u32 top, u32 width, u32 height);
VkRenderPass m_current_render_pass = VK_NULL_HANDLE;
VkRenderPass m_vram_render_pass = VK_NULL_HANDLE;
VkRenderPass m_vram_update_depth_render_pass = VK_NULL_HANDLE;
VkRenderPass m_display_load_render_pass = VK_NULL_HANDLE;
VkRenderPass m_display_discard_render_pass = VK_NULL_HANDLE;
VkRenderPass m_vram_readback_render_pass = VK_NULL_HANDLE;
VkDescriptorSetLayout m_batch_descriptor_set_layout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_single_sampler_descriptor_set_layout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_vram_write_descriptor_set_layout = VK_NULL_HANDLE;
VkPipelineLayout m_batch_pipeline_layout = VK_NULL_HANDLE;
VkPipelineLayout m_no_samplers_pipeline_layout = VK_NULL_HANDLE;
VkPipelineLayout m_single_sampler_pipeline_layout = VK_NULL_HANDLE;
VkPipelineLayout m_vram_write_pipeline_layout = VK_NULL_HANDLE;
Vulkan::Texture m_vram_texture;
Vulkan::Texture m_vram_depth_texture;
Vulkan::Texture m_vram_read_texture;
Vulkan::Texture m_vram_readback_texture;
Vulkan::Texture m_display_texture;
bool m_use_ssbos_for_vram_writes = false;
VkFramebuffer m_vram_framebuffer = VK_NULL_HANDLE;
VkFramebuffer m_vram_update_depth_framebuffer = VK_NULL_HANDLE;
VkFramebuffer m_vram_readback_framebuffer = VK_NULL_HANDLE;
VkFramebuffer m_display_framebuffer = VK_NULL_HANDLE;
VkSampler m_point_sampler = VK_NULL_HANDLE;
VkSampler m_linear_sampler = VK_NULL_HANDLE;
VkSampler m_trilinear_sampler = VK_NULL_HANDLE;
VkDescriptorSet m_batch_descriptor_set = VK_NULL_HANDLE;
VkDescriptorSet m_vram_copy_descriptor_set = VK_NULL_HANDLE;
VkDescriptorSet m_vram_read_descriptor_set = VK_NULL_HANDLE;
VkDescriptorSet m_vram_write_descriptor_set = VK_NULL_HANDLE;
VkDescriptorSet m_display_descriptor_set = VK_NULL_HANDLE;
Vulkan::StreamBuffer m_vertex_stream_buffer;
Vulkan::StreamBuffer m_uniform_stream_buffer;
Vulkan::StreamBuffer m_texture_stream_buffer;
u32 m_current_uniform_buffer_offset = 0;
VkBufferView m_texture_stream_buffer_view = VK_NULL_HANDLE;
// [depth_test][render_mode][texture_mode][transparency_mode][dithering][interlacing]
DimensionalArray<VkPipeline, 2, 2, 5, 9, 4, 3> m_batch_pipelines{};
// [wrapped][interlaced]
DimensionalArray<VkPipeline, 2, 2> m_vram_fill_pipelines{};
// [depth_test]
std::array<VkPipeline, 2> m_vram_write_pipelines{};
std::array<VkPipeline, 2> m_vram_copy_pipelines{};
VkPipeline m_vram_readback_pipeline = VK_NULL_HANDLE;
VkPipeline m_vram_update_depth_pipeline = VK_NULL_HANDLE;
// [depth_24][interlace_mode]
DimensionalArray<VkPipeline, 3, 2> m_display_pipelines{};
// texture replacements
Vulkan::Texture m_vram_write_replacement_texture;
// downsampling
Vulkan::Texture m_downsample_texture;
VkRenderPass m_downsample_render_pass = VK_NULL_HANDLE;
Vulkan::Texture m_downsample_weight_texture;
VkRenderPass m_downsample_weight_render_pass = VK_NULL_HANDLE;
VkFramebuffer m_downsample_weight_framebuffer = VK_NULL_HANDLE;
struct SmoothMipView
{
VkImageView image_view = VK_NULL_HANDLE;
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
VkFramebuffer framebuffer = VK_NULL_HANDLE;
};
std::vector<SmoothMipView> m_downsample_mip_views;
VkPipelineLayout m_downsample_pipeline_layout = VK_NULL_HANDLE;
VkDescriptorSetLayout m_downsample_composite_descriptor_set_layout = VK_NULL_HANDLE;
VkPipelineLayout m_downsample_composite_pipeline_layout = VK_NULL_HANDLE;
VkDescriptorSet m_downsample_composite_descriptor_set = VK_NULL_HANDLE;
VkPipeline m_downsample_first_pass_pipeline = VK_NULL_HANDLE;
VkPipeline m_downsample_mid_pass_pipeline = VK_NULL_HANDLE;
VkPipeline m_downsample_blur_pass_pipeline = VK_NULL_HANDLE;
VkPipeline m_downsample_composite_pass_pipeline = VK_NULL_HANDLE;
};
+28 -27
View File
@@ -2,14 +2,18 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "gpu_sw.h"
#include "system.h"
#include "util/gpu_device.h"
#include "common/align.h"
#include "common/assert.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/platform.h"
#include "util/host_display.h"
#include "system.h"
#include <algorithm>
Log_SetChannel(GPU_SW);
#if defined(CPU_X64)
@@ -39,12 +43,7 @@ GPU_SW::GPU_SW()
GPU_SW::~GPU_SW()
{
m_backend.Shutdown();
g_host_display->ClearDisplayTexture();
}
GPURenderer GPU_SW::GetRendererType() const
{
return GPURenderer::Software;
g_gpu_device->ClearDisplayTexture();
}
const Threading::Thread* GPU_SW::GetSWThread() const
@@ -52,6 +51,11 @@ const Threading::Thread* GPU_SW::GetSWThread() const
return m_backend.GetThread();
}
bool GPU_SW::IsHardwareRenderer() const
{
return false;
}
bool GPU_SW::Initialize()
{
if (!GPU::Initialize() || !m_backend.Initialize(false))
@@ -63,7 +67,7 @@ bool GPU_SW::Initialize()
GPUTexture::Format::RGB565, GPUTexture::Format::RGBA5551);
for (const GPUTexture::Format format : formats_for_16bit)
{
if (g_host_display->SupportsTextureFormat(format))
if (g_gpu_device->SupportsTextureFormat(format))
{
m_16bit_display_format = format;
break;
@@ -71,7 +75,7 @@ bool GPU_SW::Initialize()
}
for (const GPUTexture::Format format : formats_for_24bit)
{
if (g_host_display->SupportsTextureFormat(format))
if (g_gpu_device->SupportsTextureFormat(format))
{
m_24bit_display_format = format;
break;
@@ -105,9 +109,10 @@ GPUTexture* GPU_SW::GetDisplayTexture(u32 width, u32 height, GPUTexture::Format
if (!m_display_texture || m_display_texture->GetWidth() != width || m_display_texture->GetHeight() != height ||
m_display_texture->GetFormat() != format)
{
g_host_display->ClearDisplayTexture();
g_gpu_device->ClearDisplayTexture();
m_display_texture.reset();
m_display_texture = g_host_display->CreateTexture(width, height, 1, 1, 1, format, nullptr, 0, true);
m_display_texture =
g_gpu_device->CreateTexture(width, height, 1, 1, 1, GPUTexture::Type::Texture, format, nullptr, 0, true);
if (!m_display_texture)
Log_ErrorPrintf("Failed to create %ux%u %u texture", width, height, static_cast<u32>(format));
}
@@ -264,7 +269,7 @@ void GPU_SW::CopyOut15Bit(u32 src_x, u32 src_y, u32 width, u32 height, u32 field
if (!interlaced)
{
if (!g_host_display->BeginTextureUpdate(texture, width, height, reinterpret_cast<void**>(&dst_ptr), &dst_stride))
if (!texture->Map(reinterpret_cast<void**>(&dst_ptr), &dst_stride, 0, 0, width, height))
return;
}
else
@@ -312,11 +317,11 @@ void GPU_SW::CopyOut15Bit(u32 src_x, u32 src_y, u32 width, u32 height, u32 field
}
if (!interlaced)
g_host_display->EndTextureUpdate(texture, 0, 0, width, height);
texture->Unmap();
else
g_host_display->UpdateTexture(texture, 0, 0, width, height, m_display_texture_buffer.data(), output_stride);
texture->Update(0, 0, width, height, m_display_texture_buffer.data(), output_stride);
g_host_display->SetDisplayTexture(texture, 0, 0, width, height);
g_gpu_device->SetDisplayTexture(texture, 0, 0, width, height);
}
void GPU_SW::CopyOut15Bit(GPUTexture::Format display_format, u32 src_x, u32 src_y, u32 width, u32 height, u32 field,
@@ -358,7 +363,7 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 heigh
if (!interlaced)
{
if (!g_host_display->BeginTextureUpdate(texture, width, height, reinterpret_cast<void**>(&dst_ptr), &dst_stride))
if (!texture->Map(reinterpret_cast<void**>(&dst_ptr), &dst_stride, 0, 0, width, height))
return;
}
else
@@ -470,11 +475,11 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 heigh
}
if (!interlaced)
g_host_display->EndTextureUpdate(texture, 0, 0, width, height);
texture->Unmap();
else
g_host_display->UpdateTexture(texture, 0, 0, width, height, m_display_texture_buffer.data(), output_stride);
texture->Update(0, 0, width, height, m_display_texture_buffer.data(), output_stride);
g_host_display->SetDisplayTexture(texture, 0, 0, width, height);
g_gpu_device->SetDisplayTexture(texture, 0, 0, width, height);
}
void GPU_SW::CopyOut24Bit(GPUTexture::Format display_format, u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 height,
@@ -511,14 +516,14 @@ void GPU_SW::UpdateDisplay()
if (!g_settings.debugging.show_vram)
{
g_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
g_gpu_device->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
GetDisplayAspectRatio());
if (IsDisplayDisabled())
{
g_host_display->ClearDisplayTexture();
g_gpu_device->ClearDisplayTexture();
return;
}
@@ -559,7 +564,7 @@ void GPU_SW::UpdateDisplay()
else
{
CopyOut15Bit(m_16bit_display_format, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 0, false, false);
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
g_gpu_device->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
}
}
@@ -894,10 +899,6 @@ void GPU_SW::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32
std::unique_ptr<GPU> GPU::CreateSoftwareRenderer()
{
// we need something to draw in.. but keep the current api if we have one
if (!g_host_display && !Host::AcquireHostDisplay(HostDisplay::GetPreferredAPI()))
return nullptr;
std::unique_ptr<GPU_SW> gpu(std::make_unique<GPU_SW>());
if (!gpu->Initialize())
return nullptr;
+7 -5
View File
@@ -2,16 +2,18 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/heap_array.h"
#include "gpu.h"
#include "gpu_sw_backend.h"
#include "util/host_display.h"
#include "util/gpu_device.h"
#include "common/heap_array.h"
#include <array>
#include <memory>
#include <vector>
namespace Threading
{
namespace Threading {
class Thread;
}
@@ -25,8 +27,8 @@ public:
ALWAYS_INLINE const GPU_SW_Backend& GetBackend() const { return m_backend; }
GPURenderer GetRendererType() const override;
const Threading::Thread* GetSWThread() const override;
bool IsHardwareRenderer() const override;
bool Initialize() override;
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
+5 -3
View File
@@ -2,11 +2,13 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "gpu_sw_backend.h"
#include "system.h"
#include "util/gpu_device.h"
#include "common/assert.h"
#include "common/log.h"
#include "gpu_sw_backend.h"
#include "util/host_display.h"
#include "system.h"
#include <algorithm>
Log_SetChannel(GPU_SW_Backend);
+10 -6
View File
@@ -2,15 +2,19 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "gte.h"
#include "common/assert.h"
#include "common/bitutils.h"
#include "cpu_core.h"
#include "cpu_core_private.h"
#include "util/host_display.h"
#include "pgxp.h"
#include "settings.h"
#include "timing_event.h"
#include "util/gpu_device.h"
#include "util/state_wrapper.h"
#include "common/assert.h"
#include "common/bitutils.h"
#include <algorithm>
#include <array>
#include <numeric>
@@ -190,14 +194,14 @@ void UpdateAspectRatio()
{
case DisplayAspectRatio::MatchWindow:
{
if (!g_host_display)
if (!g_gpu_device)
{
s_aspect_ratio = DisplayAspectRatio::R4_3;
return;
}
num = g_host_display->GetWindowWidth();
denom = g_host_display->GetWindowHeight();
num = g_gpu_device->GetWindowWidth();
denom = g_gpu_device->GetWindowHeight();
}
break;
+9 -5
View File
@@ -2,15 +2,19 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "guncon.h"
#include "common/assert.h"
#include "common/log.h"
#include "gpu.h"
#include "host.h"
#include "resources.h"
#include "system.h"
#include "util/host_display.h"
#include "util/gpu_device.h"
#include "util/state_wrapper.h"
#include "common/assert.h"
#include "common/log.h"
#include <array>
Log_SetChannel(GunCon);
static constexpr std::array<u8, static_cast<size_t>(GunCon::Button::Count)> s_button_indices = {{13, 3, 14}};
@@ -177,8 +181,8 @@ bool GunCon::Transfer(const u8 data_in, u8* data_out)
void GunCon::UpdatePosition()
{
// get screen coordinates
const s32 mouse_x = g_host_display->GetMousePositionX();
const s32 mouse_y = g_host_display->GetMousePositionY();
const s32 mouse_x = g_gpu_device->GetMousePositionX();
const s32 mouse_y = g_gpu_device->GetMousePositionY();
// are we within the active display area?
u32 tick, line;
+34
View File
@@ -2,6 +2,12 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "host.h"
#include "common_host.h"
#include "fullscreen_ui.h"
#include "imgui_overlays.h"
#include "util/gpu_device.h"
#include "util/imgui_manager.h"
#include "common/assert.h"
#include "common/heterogeneous_containers.h"
@@ -155,3 +161,31 @@ void Host::ReportFormattedDebuggerMessage(const char* format, ...)
ReportDebuggerMessage(message);
}
void Host::RenderDisplay(bool skip_present)
{
Host::BeginPresentFrame();
// acquire for IO.MousePos.
std::atomic_thread_fence(std::memory_order_acquire);
if (!skip_present)
{
FullscreenUI::Render();
ImGuiManager::RenderTextOverlays();
ImGuiManager::RenderOSDMessages();
}
// Debug windows are always rendered, otherwise mouse input breaks on skip.
ImGuiManager::RenderOverlayWindows();
ImGuiManager::RenderDebugWindows();
g_gpu_device->Render(skip_present);
ImGuiManager::NewFrame();
}
void Host::InvalidateDisplay()
{
RenderDisplay(false);
}
+11
View File
@@ -101,6 +101,17 @@ void OpenURL(const std::string_view& url);
/// Copies the provided text to the host's clipboard, if present.
bool CopyTextToClipboard(const std::string_view& text);
/// Requests shut down and exit of the hosting application. This may not actually exit,
/// if the user cancels the shutdown confirmation.
void RequestExit(bool allow_confirm);
/// Called before drawing the OSD and other display elements.
void BeginPresentFrame();
/// Provided by the host; renders the display.
void RenderDisplay(bool skip_present);
void InvalidateDisplay();
namespace Internal {
/// Implementation to retrieve a translated string.
s32 GetTranslatedStringImpl(const std::string_view& context, const std::string_view& msg, char* tbuf,
+19 -15
View File
@@ -13,7 +13,7 @@
#include "system.h"
#include "util/audio_stream.h"
#include "util/host_display.h"
#include "util/gpu_device.h"
#include "util/imgui_fullscreen.h"
#include "util/imgui_manager.h"
#include "util/input_manager.h"
@@ -240,6 +240,7 @@ void ImGuiManager::DrawPerformanceOverlay()
if (g_settings.display_show_resolution)
{
// TODO: this seems wrong?
const auto [effective_width, effective_height] = g_gpu->GetEffectiveDisplayResolution();
const bool interlaced = g_gpu->IsInterlacedDisplayEnabled();
const bool pal = g_gpu->IsInPALMode();
@@ -317,7 +318,7 @@ void ImGuiManager::DrawPerformanceOverlay()
#endif
}
if (g_settings.display_show_gpu && g_host_display->IsGPUTimingEnabled())
if (g_settings.display_show_gpu && g_gpu_device->IsGPUTimingEnabled())
{
text.Assign("GPU: ");
FormatProcessorStat(text, System::GetGPUUsage(), System::GetGPUAverageTime());
@@ -411,8 +412,9 @@ void ImGuiManager::DrawPerformanceOverlay()
void ImGuiManager::DrawEnhancementsOverlay()
{
LargeString text;
text.AppendFmtString("{} {}", Settings::GetConsoleRegionName(System::GetRegion()),
Settings::GetRendererName(g_gpu->GetRendererType()));
text.AppendFmtString("{} {}-{}", Settings::GetConsoleRegionName(System::GetRegion()),
GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()),
g_gpu->IsHardwareRenderer() ? "HW" : "SW");
if (g_settings.rewind_enable)
text.AppendFormattedString(" RW=%g/%u", g_settings.rewind_save_frequency, g_settings.rewind_save_slots);
@@ -722,19 +724,20 @@ void SaveStateSelectorUI::InitializeListEntry(ListEntry* li, ExtendedSaveStateIn
li->preview_texture.reset();
// Might not have a display yet, we're called at startup..
if (g_host_display)
if (g_gpu_device)
{
if (ssi && !ssi->screenshot_data.empty())
{
li->preview_texture =
g_host_display->CreateTexture(ssi->screenshot_width, ssi->screenshot_height, 1, 1, 1, GPUTexture::Format::RGBA8,
ssi->screenshot_data.data(), sizeof(u32) * ssi->screenshot_width, false);
li->preview_texture = g_gpu_device->CreateTexture(
ssi->screenshot_width, ssi->screenshot_height, 1, 1, 1, GPUTexture::Type::Texture, GPUTexture::Format::RGBA8,
ssi->screenshot_data.data(), sizeof(u32) * ssi->screenshot_width, false);
}
else
{
li->preview_texture = g_host_display->CreateTexture(
Resources::PLACEHOLDER_ICON_WIDTH, Resources::PLACEHOLDER_ICON_HEIGHT, 1, 1, 1, GPUTexture::Format::RGBA8,
Resources::PLACEHOLDER_ICON_DATA, sizeof(u32) * Resources::PLACEHOLDER_ICON_WIDTH, false);
li->preview_texture = g_gpu_device->CreateTexture(
Resources::PLACEHOLDER_ICON_WIDTH, Resources::PLACEHOLDER_ICON_HEIGHT, 1, 1, 1, GPUTexture::Type::Texture,
GPUTexture::Format::RGBA8, Resources::PLACEHOLDER_ICON_DATA, sizeof(u32) * Resources::PLACEHOLDER_ICON_WIDTH,
false);
}
if (!li->preview_texture)
@@ -751,11 +754,12 @@ void SaveStateSelectorUI::InitializePlaceholderListEntry(ListEntry* li, std::str
li->slot = slot;
li->global = global;
if (g_host_display)
if (g_gpu_device)
{
li->preview_texture = g_host_display->CreateTexture(
Resources::PLACEHOLDER_ICON_WIDTH, Resources::PLACEHOLDER_ICON_HEIGHT, 1, 1, 1, GPUTexture::Format::RGBA8,
Resources::PLACEHOLDER_ICON_DATA, sizeof(u32) * Resources::PLACEHOLDER_ICON_WIDTH, false);
li->preview_texture = g_gpu_device->CreateTexture(
Resources::PLACEHOLDER_ICON_WIDTH, Resources::PLACEHOLDER_ICON_HEIGHT, 1, 1, 1, GPUTexture::Type::Texture,
GPUTexture::Format::RGBA8, Resources::PLACEHOLDER_ICON_DATA, sizeof(u32) * Resources::PLACEHOLDER_ICON_WIDTH,
false);
if (!li->preview_texture)
Log_ErrorPrintf("Failed to upload save state image to GPU");
}
+11 -7
View File
@@ -2,22 +2,26 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "playstation_mouse.h"
#include "common/assert.h"
#include "common/log.h"
#include "gpu.h"
#include "host.h"
#include "util/host_display.h"
#include "system.h"
#include "util/gpu_device.h"
#include "util/state_wrapper.h"
#include "common/assert.h"
#include "common/log.h"
#include <array>
Log_SetChannel(PlayStationMouse);
static constexpr std::array<u8, static_cast<size_t>(PlayStationMouse::Button::Count)> s_button_indices = {{11, 10}};
PlayStationMouse::PlayStationMouse(u32 index) : Controller(index)
{
m_last_host_position_x = g_host_display->GetMousePositionX();
m_last_host_position_y = g_host_display->GetMousePositionY();
m_last_host_position_x = g_gpu_device->GetMousePositionX();
m_last_host_position_y = g_gpu_device->GetMousePositionY();
}
PlayStationMouse::~PlayStationMouse() = default;
@@ -157,8 +161,8 @@ bool PlayStationMouse::Transfer(const u8 data_in, u8* data_out)
void PlayStationMouse::UpdatePosition()
{
// get screen coordinates
const s32 mouse_x = g_host_display->GetMousePositionX();
const s32 mouse_y = g_host_display->GetMousePositionY();
const s32 mouse_x = g_gpu_device->GetMousePositionX();
const s32 mouse_y = g_gpu_device->GetMousePositionY();
const s32 delta_x = mouse_x - m_last_host_position_x;
const s32 delta_y = mouse_y - m_last_host_position_y;
m_last_host_position_x = mouse_x;
+23 -9
View File
@@ -3,21 +3,25 @@
#include "settings.h"
#include "achievements.h"
#include "controller.h"
#include "host.h"
#include "host_settings.h"
#include "system.h"
#include "util/gpu_device.h"
#include "common/assert.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/path.h"
#include "common/string_util.h"
#include "controller.h"
#include "host.h"
#include "host_settings.h"
#include "system.h"
#include "util/host_display.h"
#include <algorithm>
#include <array>
#include <cctype>
#include <numeric>
Log_SetChannel(Settings);
Settings g_settings;
@@ -204,6 +208,7 @@ void Settings::Load(SettingsInterface& si)
gpu_resolution_scale = static_cast<u32>(si.GetIntValue("GPU", "ResolutionScale", 1));
gpu_multisamples = static_cast<u32>(si.GetIntValue("GPU", "Multisamples", 1));
gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false);
gpu_disable_shader_cache = si.GetBoolValue("GPU", "DisableShaderCache", false);
gpu_per_sample_shading = si.GetBoolValue("GPU", "PerSampleShading", false);
gpu_use_thread = si.GetBoolValue("GPU", "UseThread", true);
gpu_use_software_renderer_for_readbacks = si.GetBoolValue("GPU", "UseSoftwareRendererForReadbacks", false);
@@ -440,6 +445,7 @@ void Settings::Save(SettingsInterface& si) const
si.SetIntValue("GPU", "ResolutionScale", static_cast<long>(gpu_resolution_scale));
si.SetIntValue("GPU", "Multisamples", static_cast<long>(gpu_multisamples));
si.SetBoolValue("GPU", "UseDebugDevice", gpu_use_debug_device);
si.SetBoolValue("GPU", "DisableShaderCache", gpu_disable_shader_cache);
si.SetBoolValue("GPU", "PerSampleShading", gpu_per_sample_shading);
si.SetBoolValue("GPU", "UseThread", gpu_use_thread);
si.SetBoolValue("GPU", "ThreadedPresentation", gpu_threaded_presentation);
@@ -877,6 +883,9 @@ static constexpr auto s_gpu_renderer_names = make_array(
#ifdef _WIN32
"D3D11", "D3D12",
#endif
#ifdef __APPLE__
"Metal",
#endif
#ifdef WITH_VULKAN
"Vulkan",
#endif
@@ -888,6 +897,9 @@ static constexpr auto s_gpu_renderer_display_names = make_array(
#ifdef _WIN32
TRANSLATE_NOOP("GPURenderer", "Hardware (D3D11)"), TRANSLATE_NOOP("GPURenderer", "Hardware (D3D12)"),
#endif
#ifdef __APPLE__
TRANSLATE_NOOP("GPURenderer", "Hardware (Metal)"),
#endif
#ifdef WITH_VULKAN
TRANSLATE_NOOP("GPURenderer", "Hardware (Vulkan)"),
#endif
@@ -930,6 +942,9 @@ RenderAPI Settings::GetRenderAPIForRenderer(GPURenderer renderer)
case GPURenderer::HardwareD3D12:
return RenderAPI::D3D12;
#endif
#ifdef __APPLE__
return RenderAPI::Metal;
#endif
#ifdef WITH_VULKAN
case GPURenderer::HardwareVulkan:
return RenderAPI::Vulkan;
@@ -940,7 +955,7 @@ RenderAPI Settings::GetRenderAPIForRenderer(GPURenderer renderer)
#endif
case GPURenderer::Software:
default:
return HostDisplay::GetPreferredAPI();
return GPUDevice::GetPreferredAPI();
}
}
@@ -1073,11 +1088,10 @@ float Settings::GetDisplayAspectRatioValue() const
{
case DisplayAspectRatio::MatchWindow:
{
if (!g_host_display)
if (!g_gpu_device)
return s_display_aspect_ratio_values[static_cast<int>(DEFAULT_DISPLAY_ASPECT_RATIO)];
return static_cast<float>(g_host_display->GetWindowWidth()) /
static_cast<float>(g_host_display->GetWindowHeight());
return static_cast<float>(g_gpu_device->GetWindowWidth()) / static_cast<float>(g_gpu_device->GetWindowHeight());
}
case DisplayAspectRatio::Custom:
+4 -1
View File
@@ -100,6 +100,7 @@ struct Settings
bool gpu_use_software_renderer_for_readbacks = false;
bool gpu_threaded_presentation = true;
bool gpu_use_debug_device = false;
bool gpu_disable_shader_cache = false;
bool gpu_per_sample_shading = false;
bool gpu_true_color = true;
bool gpu_scaled_dithering = true;
@@ -401,7 +402,9 @@ struct Settings
static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareD3D12;
#elif defined(_WIN32)
static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareD3D11;
#elif defined(WITH_OPENGL) && (!defined(__APPLE__) || !defined(WITH_VULKAN))
#elif defined(__APPLE__)
static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareMetal;
#elif defined(WITH_OPENGL)
static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareOpenGL;
#elif defined(WITH_VULKAN)
static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareVulkan;
+2 -2
View File
@@ -2,6 +2,6 @@
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "types.h"
#include "common/types.h"
static constexpr u32 SHADER_CACHE_VERSION = 7;
static constexpr u32 SHADER_CACHE_VERSION = 9;
+85 -87
View File
@@ -8,13 +8,6 @@
#include "bus.h"
#include "cdrom.h"
#include "cheats.h"
#include "common/error.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/path.h"
#include "common/string_util.h"
#include "common/threading.h"
#include "controller.h"
#include "cpu_code_cache.h"
#include "cpu_core.h"
@@ -40,13 +33,24 @@
#include "spu.h"
#include "texture_replacements.h"
#include "timers.h"
#include "util/audio_stream.h"
#include "util/cd_image.h"
#include "util/host_display.h"
#include "util/gpu_device.h"
#include "util/ini_settings_interface.h"
#include "util/iso_reader.h"
#include "util/state_wrapper.h"
#include "common/error.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/path.h"
#include "common/string_util.h"
#include "common/threading.h"
#include "xxhash.h"
#include <cctype>
#include <cinttypes>
#include <cmath>
@@ -55,6 +59,7 @@
#include <fstream>
#include <limits>
#include <thread>
Log_SetChannel(System);
#ifdef _WIN32
@@ -70,7 +75,9 @@ SystemBootParameters::SystemBootParameters(const SystemBootParameters&) = defaul
SystemBootParameters::SystemBootParameters(SystemBootParameters&& other) = default;
SystemBootParameters::SystemBootParameters(std::string filename_) : filename(std::move(filename_)) {}
SystemBootParameters::SystemBootParameters(std::string filename_) : filename(std::move(filename_))
{
}
SystemBootParameters::~SystemBootParameters() = default;
@@ -135,6 +142,7 @@ static std::string s_input_profile_name;
static System::State s_state = System::State::Shutdown;
static std::atomic_bool s_startup_cancelled{false};
static bool s_keep_gpu_device_on_shutdown = false;
static ConsoleRegion s_region = ConsoleRegion::NTSC_U;
TickCount System::g_ticks_per_second = System::MASTER_CLOCK;
@@ -799,12 +807,10 @@ bool System::RecreateGPU(GPURenderer renderer, bool force_recreate_display, bool
if (!state_valid)
Log_ErrorPrintf("Failed to save old GPU state when switching renderers");
g_gpu->ResetGraphicsAPIState();
// create new renderer
g_gpu.reset();
if (force_recreate_display)
Host::ReleaseHostDisplay();
Host::ReleaseGPUDevice();
if (!CreateGPU(renderer))
{
@@ -822,7 +828,6 @@ bool System::RecreateGPU(GPURenderer renderer, bool force_recreate_display, bool
g_gpu->RestoreGraphicsAPIState();
g_gpu->DoState(sw, nullptr, update_display);
TimingEvents::DoState(sw);
g_gpu->ResetGraphicsAPIState();
}
// fix up vsync etc
@@ -1062,6 +1067,7 @@ bool System::LoadState(const char* filename)
ResetPerformanceCounters();
ResetThrottler();
Host::RenderDisplay(false);
g_gpu->RestoreGraphicsAPIState();
Log_VerbosePrintf("Loading state took %.2f msec", load_timer.GetTimeMilliseconds());
return true;
}
@@ -1135,6 +1141,7 @@ bool System::BootSystem(SystemBootParameters parameters)
Assert(s_state == State::Shutdown);
s_state = State::Starting;
s_startup_cancelled.store(false);
s_keep_gpu_device_on_shutdown = static_cast<bool>(g_gpu_device);
s_region = g_settings.region;
Host::OnSystemStarting();
@@ -1437,7 +1444,11 @@ bool System::Initialize(bool force_software_renderer)
if (IsStartupCancelled())
{
g_gpu.reset();
Host::ReleaseHostDisplay();
if (!s_keep_gpu_device_on_shutdown)
{
Host::ReleaseGPUDevice();
Host::ReleaseRenderWindow();
}
if (g_settings.gpu_pgxp_enable)
PGXP::Shutdown();
CPU::Shutdown();
@@ -1519,8 +1530,6 @@ void System::DestroySystem()
Timers::Shutdown();
Pad::Shutdown();
CDROM::Shutdown();
if (g_gpu)
g_gpu->ResetGraphicsAPIState();
g_gpu.reset();
InterruptController::Shutdown();
DMA::Shutdown();
@@ -1532,11 +1541,15 @@ void System::DestroySystem()
ClearRunningGame();
// Restore present-all-frames behavior.
if (g_host_display)
if (s_keep_gpu_device_on_shutdown && g_gpu_device)
{
g_host_display->SetDisplayMaxFPS(0.0f);
g_gpu_device->SetDisplayMaxFPS(0.0f);
UpdateSoftwareCursor();
Host::ReleaseHostDisplay();
}
else
{
Host::ReleaseGPUDevice();
Host::ReleaseRenderWindow();
}
s_bios_hash = {};
@@ -1601,8 +1614,6 @@ void System::Execute()
else
CPU::Execute();
g_gpu->ResetGraphicsAPIState();
s_system_executing = false;
continue;
}
@@ -1624,6 +1635,9 @@ void System::FrameDone()
{
s_frame_number++;
// Vertex buffer is shared, need to flush what we have.
g_gpu->FlushRender();
// Generate any pending samples from the SPU before sleeping, this way we reduce the chances of underruns.
SPU::GeneratePendingSamples();
@@ -1680,14 +1694,11 @@ void System::FrameDone()
{
s_last_frame_skipped = false;
// TODO: Purge reset/restore
g_gpu->ResetGraphicsAPIState();
const bool skip_present = g_host_display->ShouldSkipDisplayingFrame();
const bool skip_present = g_gpu_device->ShouldSkipDisplayingFrame();
Host::RenderDisplay(skip_present);
if (!skip_present && g_host_display->IsGPUTimingEnabled())
if (!skip_present && g_gpu_device->IsGPUTimingEnabled())
{
s_accumulated_gpu_time += g_host_display->GetAndResetAccumulatedGPUTime();
s_accumulated_gpu_time += g_gpu_device->GetAndResetAccumulatedGPUTime();
s_presents_since_last_update++;
}
@@ -1784,10 +1795,9 @@ void System::SingleStepCPU()
CPU::SingleStep();
g_gpu->FlushRender();
SPU::GeneratePendingSamples();
g_gpu->ResetGraphicsAPIState();
s_system_executing = false;
}
@@ -1834,35 +1844,29 @@ void System::RecreateSystem()
bool System::CreateGPU(GPURenderer renderer)
{
switch (renderer)
const RenderAPI api = Settings::GetRenderAPIForRenderer(renderer);
if (!g_gpu_device || (renderer != GPURenderer::Software && g_gpu_device->GetRenderAPI() != api))
{
#ifdef WITH_OPENGL
case GPURenderer::HardwareOpenGL:
g_gpu = GPU::CreateHardwareOpenGLRenderer();
break;
#endif
if (g_gpu_device)
{
Log_WarningPrintf("Recreating GPU device, expecting %s got %s", GPUDevice::RenderAPIToString(api),
GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()));
}
#ifdef WITH_VULKAN
case GPURenderer::HardwareVulkan:
g_gpu = GPU::CreateHardwareVulkanRenderer();
break;
#endif
#ifdef _WIN32
case GPURenderer::HardwareD3D11:
g_gpu = GPU::CreateHardwareD3D11Renderer();
break;
case GPURenderer::HardwareD3D12:
g_gpu = GPU::CreateHardwareD3D12Renderer();
break;
#endif
case GPURenderer::Software:
default:
g_gpu = GPU::CreateSoftwareRenderer();
break;
Host::ReleaseGPUDevice();
if (!Host::CreateGPUDevice(api))
{
Host::ReleaseRenderWindow();
return false;
}
}
if (renderer == GPURenderer::Software)
g_gpu = GPU::CreateSoftwareRenderer();
else
g_gpu = GPU::CreateHardwareRenderer();
if (!g_gpu)
{
Log_ErrorPrintf("Failed to initialize %s renderer, falling back to software renderer",
@@ -1875,6 +1879,11 @@ bool System::CreateGPU(GPURenderer renderer)
if (!g_gpu)
{
Log_ErrorPrintf("Failed to create fallback software renderer.");
if (!s_keep_gpu_device_on_shutdown)
{
Host::ReleaseGPUDevice();
Host::ReleaseRenderWindow();
}
return false;
}
}
@@ -1934,9 +1943,7 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
return false;
g_gpu->RestoreGraphicsAPIState();
const bool gpu_result = sw.DoMarker("GPU") && g_gpu->DoState(sw, host_texture, update_display);
g_gpu->ResetGraphicsAPIState();
if (!gpu_result)
if (!sw.DoMarker("GPU") || !g_gpu->DoState(sw, host_texture, update_display))
return false;
if (!sw.DoMarker("CDROM") || !CDROM::DoState(sw))
@@ -2071,8 +2078,6 @@ void System::InternalReset()
#ifdef WITH_CHEEVOS
Achievements::ResetRuntime();
#endif
g_gpu->ResetGraphicsAPIState();
}
std::string System::GetMediaPathFromSaveState(const char* path)
@@ -2283,7 +2288,7 @@ bool System::InternalSaveState(ByteStream* state, u32 screenshot_size /* = 256 *
if (screenshot_size > 0)
{
// assume this size is the width
const float display_aspect_ratio = g_host_display->GetDisplayAspectRatio();
const float display_aspect_ratio = g_gpu_device->GetDisplayAspectRatio();
const u32 screenshot_width = screenshot_size;
const u32 screenshot_height =
std::max(1u, static_cast<u32>(static_cast<float>(screenshot_width) /
@@ -2293,7 +2298,7 @@ bool System::InternalSaveState(ByteStream* state, u32 screenshot_size /* = 256 *
std::vector<u32> screenshot_buffer;
u32 screenshot_stride;
GPUTexture::Format screenshot_format;
if (g_host_display->RenderScreenshot(screenshot_width, screenshot_height,
if (g_gpu_device->RenderScreenshot(screenshot_width, screenshot_height,
Common::Rectangle<s32>::FromExtents(0, 0, screenshot_width, screenshot_height),
&screenshot_buffer, &screenshot_stride, &screenshot_format) &&
GPUTexture::ConvertTextureDataToRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride,
@@ -2306,7 +2311,7 @@ bool System::InternalSaveState(ByteStream* state, u32 screenshot_size /* = 256 *
}
else
{
if (g_host_display->UsesLowerLeftOrigin())
if (g_gpu_device->UsesLowerLeftOrigin())
{
GPUTexture::FlipTextureDataRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride);
}
@@ -2350,8 +2355,6 @@ bool System::InternalSaveState(ByteStream* state, u32 screenshot_size /* = 256 *
header.data_compressed_size = static_cast<u32>(state->GetPosition() - header.offset_to_data);
}
g_gpu->ResetGraphicsAPIState();
if (!result)
return false;
}
@@ -2427,7 +2430,7 @@ void System::UpdatePerformanceCounters()
s_fps_timer.ResetTo(now_ticks);
if (g_host_display->IsGPUTimingEnabled())
if (g_gpu_device->IsGPUTimingEnabled())
{
s_average_gpu_time = s_accumulated_gpu_time / static_cast<float>(std::max(s_presents_since_last_update, 1u));
s_gpu_usage = s_accumulated_gpu_time / (time * 10.0f);
@@ -2474,7 +2477,7 @@ void System::UpdateSpeedLimiterState()
s_target_speed == 1.0f && IsValid())
{
float host_refresh_rate;
if (g_host_display->GetHostRefreshRate(&host_refresh_rate))
if (g_gpu_device->GetHostRefreshRate(&host_refresh_rate))
{
const float ratio = host_refresh_rate / System::GetThrottleFrequency();
s_syncing_to_host = (ratio >= 0.95f && ratio <= 1.05f);
@@ -2530,8 +2533,8 @@ void System::UpdateDisplaySync()
Log_VerbosePrintf("Max display fps: %f (%s)", max_display_fps,
s_display_all_frames ? "displaying all frames" : "skipping displaying frames when needed");
g_host_display->SetDisplayMaxFPS(max_display_fps);
g_host_display->SetVSync(video_sync_enabled);
g_gpu_device->SetDisplayMaxFPS(max_display_fps);
g_gpu_device->SetVSync(video_sync_enabled);
}
bool System::ShouldUseVSync()
@@ -3038,10 +3041,7 @@ bool System::DumpVRAM(const char* filename)
return false;
g_gpu->RestoreGraphicsAPIState();
const bool result = g_gpu->DumpVRAMToFile(filename);
g_gpu->ResetGraphicsAPIState();
return result;
return g_gpu->DumpVRAMToFile(filename);
}
bool System::DumpSPURAM(const char* filename)
@@ -3492,12 +3492,12 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
{
if (g_settings.display_post_processing && !g_settings.display_post_process_chain.empty())
{
if (!g_host_display->SetPostProcessingChain(g_settings.display_post_process_chain))
if (!g_gpu_device->SetPostProcessingChain(g_settings.display_post_process_chain))
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
}
else
{
g_host_display->SetPostProcessingChain({});
g_gpu_device->SetPostProcessingChain({});
}
}
}
@@ -3708,8 +3708,6 @@ void System::DoRewind()
s_next_frame_time += s_frame_period;
// TODO: Purge reset/restore
g_gpu->ResetGraphicsAPIState();
Host::RenderDisplay(false);
g_gpu->RestoreGraphicsAPIState();
@@ -3989,7 +3987,7 @@ bool System::SaveScreenshot(const char* filename /* = nullptr */, bool full_reso
return false;
}
const bool screenshot_saved = g_host_display->WriteScreenshotToFile(
const bool screenshot_saved = g_gpu_device->WriteScreenshotToFile(
filename, g_settings.display_internal_resolution_screenshots, compress_on_thread);
if (!screenshot_saved)
@@ -4340,13 +4338,13 @@ void System::TogglePostProcessing()
{
Host::AddKeyedOSDMessage("PostProcessing", TRANSLATE_STR("OSDMessage", "Post-processing is now enabled."), 10.0f);
if (!g_host_display->SetPostProcessingChain(g_settings.display_post_process_chain))
if (!g_gpu_device->SetPostProcessingChain(g_settings.display_post_process_chain))
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
}
else
{
Host::AddKeyedOSDMessage("PostProcessing", TRANSLATE_STR("OSDMessage", "Post-processing is now disabled."), 10.0f);
g_host_display->SetPostProcessingChain({});
g_gpu_device->SetPostProcessingChain({});
}
}
@@ -4355,7 +4353,7 @@ void System::ReloadPostProcessingShaders()
if (!IsValid() || !g_settings.display_post_processing)
return;
if (!g_host_display->SetPostProcessingChain(g_settings.display_post_process_chain))
if (!g_gpu_device->SetPostProcessingChain(g_settings.display_post_process_chain))
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Failed to load post-processing shader chain."), 20.0f);
else
Host::AddOSDMessage(TRANSLATE_STR("OSDMessage", "Post-processing shaders reloaded."), 10.0f);
@@ -4421,7 +4419,7 @@ void System::UpdateSoftwareCursor()
if (!IsValid())
{
Host::SetMouseMode(false, false);
g_host_display->ClearSoftwareCursor();
g_gpu_device->ClearSoftwareCursor();
return;
}
@@ -4444,12 +4442,12 @@ void System::UpdateSoftwareCursor()
if (image && image->IsValid())
{
g_host_display->SetSoftwareCursor(image->GetPixels(), image->GetWidth(), image->GetHeight(), image->GetPitch(),
g_gpu_device->SetSoftwareCursor(image->GetPixels(), image->GetWidth(), image->GetHeight(), image->GetPitch(),
image_scale);
}
else
{
g_host_display->ClearSoftwareCursor();
g_gpu_device->ClearSoftwareCursor();
}
}
@@ -4462,13 +4460,13 @@ void System::RequestDisplaySize(float scale /*= 0.0f*/)
scale = g_gpu->IsHardwareRenderer() ? static_cast<float>(g_settings.gpu_resolution_scale) : 1.0f;
const float y_scale =
(static_cast<float>(g_host_display->GetDisplayWidth()) / static_cast<float>(g_host_display->GetDisplayHeight())) /
g_host_display->GetDisplayAspectRatio();
(static_cast<float>(g_gpu_device->GetDisplayWidth()) / static_cast<float>(g_gpu_device->GetDisplayHeight())) /
g_gpu_device->GetDisplayAspectRatio();
const u32 requested_width =
std::max<u32>(static_cast<u32>(std::ceil(static_cast<float>(g_host_display->GetDisplayWidth()) * scale)), 1);
std::max<u32>(static_cast<u32>(std::ceil(static_cast<float>(g_gpu_device->GetDisplayWidth()) * scale)), 1);
const u32 requested_height = std::max<u32>(
static_cast<u32>(std::ceil(static_cast<float>(g_host_display->GetDisplayHeight()) * y_scale * scale)), 1);
static_cast<u32>(std::ceil(static_cast<float>(g_gpu_device->GetDisplayHeight()) * y_scale * scale)), 1);
Host::RequestResizeHostDisplay(static_cast<s32>(requested_width), static_cast<s32>(requested_height));
}
+10 -8
View File
@@ -489,16 +489,18 @@ void PumpMessagesOnCPUThread();
/// Requests a specific display window size.
void RequestResizeHostDisplay(s32 width, s32 height);
/// Requests shut down and exit of the hosting application. This may not actually exit,
/// if the user cancels the shutdown confirmation.
void RequestExit(bool allow_confirm);
/// Requests shut down of the current virtual machine.
void RequestSystemShutdown(bool allow_confirm, bool save_state);
/// Returns true if the hosting application is currently fullscreen.
bool IsFullscreen();
/// Attempts to create the rendering device backend.
bool CreateGPUDevice(RenderAPI api);
/// Alters fullscreen state of hosting application.
void SetFullscreen(bool enabled);
/// Handles fullscreen transitions and such.
void UpdateDisplayWindow();
/// Called when the window is resized.
void ResizeDisplayWindow(s32 width, s32 height, float scale);
/// Destroys any active rendering device.
void ReleaseGPUDevice();
} // namespace Host
+3
View File
@@ -62,6 +62,9 @@ enum class GPURenderer : u8
HardwareD3D11,
HardwareD3D12,
#endif
#ifdef __APPLE__
HardwareMetal,
#endif
#ifdef WITH_VULKAN
HardwareVulkan,
#endif