Skip to content

Commit 0b690a2

Browse files
committed
allow software renderer to use the preferred hw_render interface, and to
run in full software mode if none is available.
1 parent 76e9952 commit 0b690a2

5 files changed

Lines changed: 403 additions & 41 deletions

File tree

libretro/main.cpp

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -368,12 +368,12 @@ void retro_get_system_av_info(retro_system_av_info* info)
368368
if (Options::renderer == "Software" || Options::renderer == "Null")
369369
{
370370
info->geometry.base_width = 640;
371-
info->geometry.base_height = 480;
371+
info->geometry.base_height = 448;
372372
}
373373
else
374374
{
375375
info->geometry.base_width = 640 * Options::upscale_multiplier;
376-
info->geometry.base_height = 480 * Options::upscale_multiplier;
376+
info->geometry.base_height = 448 * Options::upscale_multiplier;
377377
}
378378

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

499499
bool select_hw_render()
500500
{
501-
if (Options::renderer == "Auto")
501+
if (Options::renderer == "Auto" || Options::renderer == "Software")
502502
{
503-
retro_hw_context_type context_type = RETRO_HW_CONTEXT_OPENGL_CORE;
503+
retro_hw_context_type context_type = RETRO_HW_CONTEXT_NONE;
504504
environ_cb(RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER, &context_type);
505-
if (set_hw_render(context_type))
505+
if (context_type != RETRO_HW_CONTEXT_NONE && set_hw_render(context_type))
506506
return true;
507507
}
508508
#ifdef _WIN32
@@ -536,6 +536,8 @@ bool select_hw_render()
536536
if (set_hw_render(RETRO_HW_CONTEXT_D3D12))
537537
return true;
538538
#endif
539+
if (Options::renderer == "Software")
540+
return set_hw_render(RETRO_HW_CONTEXT_NONE);
539541

540542
return false;
541543
}
@@ -627,6 +629,9 @@ static const VkApplicationInfo *get_application_info_vulkan(void) {
627629
#endif
628630
bool retro_load_game(const struct retro_game_info* game)
629631
{
632+
int format = RETRO_PIXEL_FORMAT_XRGB8888;
633+
environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &format);
634+
630635
const char* system_base = nullptr;
631636
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_base);
632637
std::string system = Path::Combine(system_base, "pcsx2");
@@ -670,41 +675,41 @@ bool retro_load_game(const struct retro_game_info* game)
670675
if(!select_hw_render())
671676
return false;
672677

673-
switch (hw_render.context_type)
674-
{
675-
case RETRO_HW_CONTEXT_D3D12:
676-
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX12);
677-
break;
678-
case RETRO_HW_CONTEXT_D3D11:
679-
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX11);
680-
break;
678+
if(Options::renderer == "Software")
679+
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::SW);
680+
else
681+
switch (hw_render.context_type)
682+
{
683+
case RETRO_HW_CONTEXT_D3D12:
684+
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX12);
685+
break;
686+
case RETRO_HW_CONTEXT_D3D11:
687+
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::DX11);
688+
break;
681689
#ifdef ENABLE_VULKAN
682-
case RETRO_HW_CONTEXT_VULKAN:
683-
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::VK);
684-
{
685-
static const struct retro_hw_render_context_negotiation_interface_vulkan iface = {
686-
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN,
687-
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION,
688-
get_application_info_vulkan,
689-
create_device_vulkan, // Callback above.
690-
nullptr,
691-
};
692-
environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, (void *)&iface);
693-
}
694-
Vulkan::LoadVulkanLibrary();
695-
vk_libretro_init_wraps();
696-
break;
690+
case RETRO_HW_CONTEXT_VULKAN:
691+
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::VK);
692+
{
693+
static const struct retro_hw_render_context_negotiation_interface_vulkan iface = {
694+
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN,
695+
RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION,
696+
get_application_info_vulkan,
697+
create_device_vulkan, // Callback above.
698+
nullptr,
699+
};
700+
environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, (void *)&iface);
701+
}
702+
Vulkan::LoadVulkanLibrary();
703+
vk_libretro_init_wraps();
704+
break;
697705
#endif
698-
case RETRO_HW_CONTEXT_NONE:
699-
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::Null);
700-
break;
701-
default:
702-
if(Options::renderer == "Software")
703-
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::SW);
704-
else
706+
case RETRO_HW_CONTEXT_NONE:
707+
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::Null);
708+
break;
709+
default:
705710
s_settings_interface.SetIntValue("EmuCore/GS", "Renderer", (int)GSRendererType::OGL);
706-
break;
707-
}
711+
break;
712+
}
708713

709714
VMManager::ApplySettings();
710715

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

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

727+
if(hw_render.context_type == RETRO_HW_CONTEXT_NONE)
728+
GetMTGS().TryOpenGS();
729+
722730
return true;
723731
}
724732

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

731739
void retro_unload_game(void)
732740
{
741+
if(GetMTGS().IsOpen())
742+
{
743+
cpu_thread_pause();
744+
GetMTGS().CloseGS();
745+
}
746+
733747
VMManager::Shutdown(false);
734748
cpu_thread.join();
735749
#ifdef ENABLE_VULKAN
@@ -804,6 +818,9 @@ void retro_run(void)
804818

805819
read_pos += samples;
806820
read_pos &= SOUND_BUFFER_MASK;
821+
822+
if (EmuConfig.GS.Renderer == GSRendererType::Null)
823+
video_cb(NULL, 0, 0, 0);
807824
}
808825

809826
void Host::BeginPresentFrame()
@@ -843,7 +860,7 @@ std::optional<WindowInfo> Host::AcquireRenderWindow(RenderAPI api)
843860
{
844861
WindowInfo wi;
845862
wi.surface_width = 640 * Options::upscale_multiplier;
846-
wi.surface_height = 480 * Options::upscale_multiplier;
863+
wi.surface_height = 448 * Options::upscale_multiplier;
847864
wi.surface_scale = 1.0f;
848865
wi.type = WindowInfo::Type::Libretro;
849866
if(api == RenderAPI::Vulkan)
@@ -856,7 +873,7 @@ std::optional<WindowInfo> Host::UpdateRenderWindow()
856873
{
857874
WindowInfo wi;
858875
wi.surface_width = 640 * Options::upscale_multiplier;
859-
wi.surface_height = 480 * Options::upscale_multiplier;
876+
wi.surface_height = 448 * Options::upscale_multiplier;
860877
wi.surface_scale = 1.0f;
861878
wi.type = WindowInfo::Type::Libretro;
862879
if(hw_render.context_type == RETRO_HW_CONTEXT_VULKAN)
@@ -1217,7 +1234,7 @@ std::optional<WindowInfo> Host::GetTopLevelWindowInfo()
12171234
{
12181235
WindowInfo wi;
12191236
wi.surface_width = 640;
1220-
wi.surface_height = 480;
1237+
wi.surface_height = 448;
12211238
wi.surface_scale = 1.0f;
12221239
wi.type = WindowInfo::Type::Libretro;
12231240

pcsx2/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,9 @@ if(LIBRETRO)
10741074
SPU2/Linux/Alsa.cpp
10751075
SPU2/Linux/Dialogs.cpp
10761076
)
1077+
LIST(APPEND pcsx2GSSources
1078+
GS/Renderers/Null/GSDeviceNull.cpp
1079+
)
10771080
endif()
10781081

10791082
# These ones benefit a lot from LTO

pcsx2/GS/GS.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ static HRESULT s_hr = E_FAIL;
6464

6565
#endif
6666

67+
#ifdef __LIBRETRO__
68+
#include "Renderers/Null/GSDeviceNull.h"
69+
#endif
70+
6771
#include <fstream>
6872

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

109113
static RenderAPI GetAPIForRenderer(GSRendererType renderer)
110114
{
115+
#ifdef __LIBRETRO__
116+
switch(hw_render.context_type)
117+
{
118+
case RETRO_HW_CONTEXT_D3D11:
119+
return RenderAPI::D3D11;
120+
case RETRO_HW_CONTEXT_D3D12:
121+
return RenderAPI::D3D12;
122+
case RETRO_HW_CONTEXT_VULKAN:
123+
return RenderAPI::Vulkan;
124+
case RETRO_HW_CONTEXT_NONE:
125+
return RenderAPI::None;
126+
default:
127+
break;
128+
}
129+
return RenderAPI::OpenGL;
130+
#else
111131
switch (renderer)
112132
{
113133
case GSRendererType::OGL:
@@ -132,6 +152,7 @@ static RenderAPI GetAPIForRenderer(GSRendererType renderer)
132152
default:
133153
return GetAPIForRenderer(GSUtil::GetPreferredRenderer());
134154
}
155+
#endif
135156
}
136157

137158
static void UpdateExclusiveFullscreen(bool force_off)
@@ -209,7 +230,11 @@ static bool OpenGSDevice(GSRendererType renderer, bool clear_state_on_fail)
209230
g_gs_device = std::make_unique<GSDeviceVK>();
210231
break;
211232
#endif
212-
233+
#ifdef __LIBRETRO__
234+
case RenderAPI::None:
235+
g_gs_device = std::make_unique<GSDeviceNull>();
236+
break;
237+
#endif
213238
default:
214239
Console.Error("Unsupported render API %s", GSDevice::RenderAPIToString(s_render_api));
215240
return false;

0 commit comments

Comments
 (0)