Skip to content

Commit

Permalink
allow software renderer to use the preferred hw_render interface, and to
Browse files Browse the repository at this point in the history
run in full software mode if none is available.
  • Loading branch information
aliaspider committed Apr 15, 2023
1 parent 76e9952 commit 89c46dd
Show file tree
Hide file tree
Showing 5 changed files with 411 additions and 41 deletions.
105 changes: 65 additions & 40 deletions libretro/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,12 @@ void retro_get_system_av_info(retro_system_av_info* info)
if (Options::renderer == "Software" || Options::renderer == "Null")
{
info->geometry.base_width = 640;
info->geometry.base_height = 480;
info->geometry.base_height = 448;
}
else
{
info->geometry.base_width = 640 * Options::upscale_multiplier;
info->geometry.base_height = 480 * Options::upscale_multiplier;
info->geometry.base_height = 448 * Options::upscale_multiplier;
}

info->geometry.max_width = info->geometry.base_width;
Expand Down Expand Up @@ -498,11 +498,11 @@ static bool set_hw_render(retro_hw_context_type type)

bool select_hw_render()
{
if (Options::renderer == "Auto")
if (Options::renderer == "Auto" || Options::renderer == "Software")
{
retro_hw_context_type context_type = RETRO_HW_CONTEXT_OPENGL_CORE;
retro_hw_context_type context_type = RETRO_HW_CONTEXT_NONE;
environ_cb(RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER, &context_type);
if (set_hw_render(context_type))
if (context_type != RETRO_HW_CONTEXT_NONE && set_hw_render(context_type))
return true;
}
#ifdef _WIN32
Expand Down Expand Up @@ -536,6 +536,8 @@ bool select_hw_render()
if (set_hw_render(RETRO_HW_CONTEXT_D3D12))
return true;
#endif
if (Options::renderer == "Software")
return set_hw_render(RETRO_HW_CONTEXT_NONE);

return false;
}
Expand Down Expand Up @@ -627,6 +629,9 @@ static const VkApplicationInfo *get_application_info_vulkan(void) {
#endif
bool retro_load_game(const struct retro_game_info* game)
{
int format = RETRO_PIXEL_FORMAT_XRGB8888;
environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &format);

const char* system_base = nullptr;
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_base);
std::string system = Path::Combine(system_base, "pcsx2");
Expand Down Expand Up @@ -670,41 +675,41 @@ bool retro_load_game(const struct retro_game_info* game)
if(!select_hw_render())
return false;

switch (hw_render.context_type)
{
case RETRO_HW_CONTEXT_D3D12:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX12);
break;
case RETRO_HW_CONTEXT_D3D11:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX11);
break;
if(Options::renderer == "Software")
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::SW);
else
switch (hw_render.context_type)
{
case RETRO_HW_CONTEXT_D3D12:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX12);
break;
case RETRO_HW_CONTEXT_D3D11:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX11);
break;
#ifdef ENABLE_VULKAN
case RETRO_HW_CONTEXT_VULKAN:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::VK);
{
static const struct retro_hw_render_context_negotiation_interface_vulkan iface = {
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN,
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION,
get_application_info_vulkan,
create_device_vulkan, // Callback above.
nullptr,
};
environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, (void *)&iface);
}
Vulkan::LoadVulkanLibrary();
vk_libretro_init_wraps();
break;
case RETRO_HW_CONTEXT_VULKAN:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::VK);
{
static const struct retro_hw_render_context_negotiation_interface_vulkan iface = {
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN,
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION,
get_application_info_vulkan,
create_device_vulkan, // Callback above.
nullptr,
};
environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, (void *)&iface);
}
Vulkan::LoadVulkanLibrary();
vk_libretro_init_wraps();
break;
#endif
case RETRO_HW_CONTEXT_NONE:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::Null);
break;
default:
if(Options::renderer == "Software")
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::SW);
else
case RETRO_HW_CONTEXT_NONE:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::Null);
break;
default:
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::OGL);
break;
}
break;
}

VMManager::ApplySettings();

Expand All @@ -719,6 +724,9 @@ bool retro_load_game(const struct retro_game_info* game)

cpu_thread = std::thread(cpu_thread_entry, boot_params);

if(hw_render.context_type == RETRO_HW_CONTEXT_NONE)
GetMTGS().TryOpenGS();

return true;
}

Expand All @@ -730,6 +738,12 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info* i

void retro_unload_game(void)
{
if(GetMTGS().IsOpen())
{
cpu_thread_pause();
GetMTGS().CloseGS();
}

VMManager::Shutdown(false);
cpu_thread.join();
#ifdef ENABLE_VULKAN
Expand Down Expand Up @@ -804,6 +818,17 @@ void retro_run(void)

read_pos += samples;
read_pos &= SOUND_BUFFER_MASK;

if (EmuConfig.GS.Renderer == GSRendererType::Null)
video_cb(NULL, 0, 0, 0);

// if(hw_render.context_type == RETRO_HW_CONTEXT_NONE)
// {
// if (EmuConfig.GS.Renderer == GSRendererType::SW)
// video_cb(NULL, 0, 0, 0);
// else
// video_cb(NULL, 0, 0, 0);
// }
}

void Host::BeginPresentFrame()
Expand Down Expand Up @@ -843,7 +868,7 @@ std::optional<WindowInfo> Host::AcquireRenderWindow(RenderAPI api)
{
WindowInfo wi;
wi.surface_width = 640 * Options::upscale_multiplier;
wi.surface_height = 480 * Options::upscale_multiplier;
wi.surface_height = 448 * Options::upscale_multiplier;
wi.surface_scale = 1.0f;
wi.type = WindowInfo::Type::Libretro;
if(api == RenderAPI::Vulkan)
Expand All @@ -856,7 +881,7 @@ std::optional<WindowInfo> Host::UpdateRenderWindow()
{
WindowInfo wi;
wi.surface_width = 640 * Options::upscale_multiplier;
wi.surface_height = 480 * Options::upscale_multiplier;
wi.surface_height = 448 * Options::upscale_multiplier;
wi.surface_scale = 1.0f;
wi.type = WindowInfo::Type::Libretro;
if(hw_render.context_type == RETRO_HW_CONTEXT_VULKAN)
Expand Down Expand Up @@ -1217,7 +1242,7 @@ std::optional<WindowInfo> Host::GetTopLevelWindowInfo()
{
WindowInfo wi;
wi.surface_width = 640;
wi.surface_height = 480;
wi.surface_height = 448;
wi.surface_scale = 1.0f;
wi.type = WindowInfo::Type::Libretro;

Expand Down
3 changes: 3 additions & 0 deletions pcsx2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,9 @@ if(LIBRETRO)
SPU2/Linux/Alsa.cpp
SPU2/Linux/Dialogs.cpp
)
LIST(APPEND pcsx2GSSources
GS/Renderers/Null/GSDeviceNull.cpp
)
endif()

# These ones benefit a lot from LTO
Expand Down
27 changes: 26 additions & 1 deletion pcsx2/GS/GS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ static HRESULT s_hr = E_FAIL;

#endif

#ifdef __LIBRETRO__
#include "Renderers/Null/GSDeviceNull.h"
#endif

#include <fstream>

// do NOT undefine this/put it above includes, as x11 people love to redefine
Expand Down Expand Up @@ -108,6 +112,22 @@ void GSshutdown()

static RenderAPI GetAPIForRenderer(GSRendererType renderer)
{
#ifdef __LIBRETRO__
switch(hw_render.context_type)
{
case RETRO_HW_CONTEXT_D3D11:
return RenderAPI::D3D11;
case RETRO_HW_CONTEXT_D3D12:
return RenderAPI::D3D12;
case RETRO_HW_CONTEXT_VULKAN:
return RenderAPI::Vulkan;
case RETRO_HW_CONTEXT_NONE:
return RenderAPI::None;
default:
break;
}
return RenderAPI::OpenGL;
#else
switch (renderer)
{
case GSRendererType::OGL:
Expand All @@ -132,6 +152,7 @@ static RenderAPI GetAPIForRenderer(GSRendererType renderer)
default:
return GetAPIForRenderer(GSUtil::GetPreferredRenderer());
}
#endif
}

static void UpdateExclusiveFullscreen(bool force_off)
Expand Down Expand Up @@ -209,7 +230,11 @@ static bool OpenGSDevice(GSRendererType renderer, bool clear_state_on_fail)
g_gs_device = std::make_unique<GSDeviceVK>();
break;
#endif

#ifdef __LIBRETRO__
case RenderAPI::None:
g_gs_device = std::make_unique<GSDeviceNull>();
break;
#endif
default:
Console.Error("Unsupported render API %s", GSDevice::RenderAPIToString(s_render_api));
return false;
Expand Down
Loading

0 comments on commit 89c46dd

Please sign in to comment.