Rewrite host GPU abstraction
- Don't have to repeat the same thing for 4 renderers. - Add native Metal renderer.
This commit is contained in:
@@ -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
@@ -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 ?
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+108
-187
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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,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
@@ -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
@@ -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
|
||||
|
||||
@@ -62,6 +62,9 @@ enum class GPURenderer : u8
|
||||
HardwareD3D11,
|
||||
HardwareD3D12,
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
HardwareMetal,
|
||||
#endif
|
||||
#ifdef WITH_VULKAN
|
||||
HardwareVulkan,
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user