libretro: Revised software rendering option

This commit is contained in:
sonninnos 2024-06-03 00:08:32 +03:00
parent 55943ed95c
commit 49b9319570
6 changed files with 134 additions and 76 deletions

View File

@ -90,8 +90,8 @@ LibretroGraphicsContext *LibretroGraphicsContext::CreateGraphicsContext() {
if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER, &preferred))
preferred = RETRO_HW_CONTEXT_DUMMY;
if (Libretro::renderer != RETRO_HW_CONTEXT_DUMMY)
preferred = Libretro::renderer;
if (Libretro::backend != RETRO_HW_CONTEXT_DUMMY)
preferred = Libretro::backend;
#ifndef USING_GLES2
if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_OPENGL_CORE) {

View File

@ -14,6 +14,7 @@
#define NATIVEWIDTH 480
#define NATIVEHEIGHT 272
#define SOFT_BMP_SIZE NATIVEWIDTH * NATIVEHEIGHT * 4
class LibretroGraphicsContext : public GraphicsContext {
public:
@ -89,19 +90,25 @@ public:
bool Init() override { return true; }
void SwapBuffers() override {
GPUDebugBuffer buf;
u16 w = NATIVEWIDTH;
u16 h = NATIVEHEIGHT;
gpuDebug->GetOutputFramebuffer(buf);
const std::vector<u32> pixels = TranslateDebugBufferToCompare(&buf, NATIVEWIDTH, NATIVEHEIGHT);
u32 offset = g_Config.bDisplayCropTo16x9 ? NATIVEWIDTH : 0;
video_cb(pixels.data() + offset, NATIVEWIDTH, PSP_CoreParameter().pixelHeight, NATIVEWIDTH << 2);
const std::vector<u32> pixels = TranslateDebugBufferToCompare(&buf, w, h);
memcpy(soft_bmp, pixels.data(), SOFT_BMP_SIZE);
u32 offset = g_Config.bDisplayCropTo16x9 ? w << 1 : 0;
h -= g_Config.bDisplayCropTo16x9 ? 2 : 0;
video_cb(soft_bmp + offset, w, h, w << 2);
}
GPUCore GetGPUCore() override { return GPUCORE_SOFTWARE; }
const char *Ident() override { return "Software"; }
u16 soft_bmp[SOFT_BMP_SIZE] = {0};
};
namespace Libretro {
extern LibretroGraphicsContext *ctx;
extern retro_environment_t environ_cb;
extern retro_hw_context_type renderer;
extern retro_hw_context_type backend;
enum class EmuThreadState {
DISABLED,

View File

@ -100,7 +100,7 @@ namespace Libretro
{
LibretroGraphicsContext *ctx;
retro_environment_t environ_cb;
retro_hw_context_type renderer = RETRO_HW_CONTEXT_DUMMY;
retro_hw_context_type backend = RETRO_HW_CONTEXT_DUMMY;
static retro_audio_sample_batch_t audio_batch_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;
@ -108,6 +108,7 @@ namespace Libretro
static bool detectVsyncSwapInterval = false;
static bool detectVsyncSwapIntervalOptShown = true;
static bool softwareRenderInitHack = false;
static s64 expectedTimeUsPerRun = 0;
static uint32_t vsyncSwapInterval = 1;
@ -681,6 +682,26 @@ static void check_variables(CoreParameter &coreParam)
g_Config.iInternalResolution = 9;
else if (!strcmp(var.value, "4800x2720"))
g_Config.iInternalResolution = 10;
// Force resolution to 1x without hardware context
if (backend == RETRO_HW_CONTEXT_NONE)
g_Config.iInternalResolution = 1;
}
var.key = "ppsspp_software_rendering";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!PSP_IsInited())
{
if (!strcmp(var.value, "disabled") && backend != RETRO_HW_CONTEXT_NONE)
g_Config.bSoftwareRendering = false;
else
g_Config.bSoftwareRendering = true;
}
// Force resolution to 1x with software rendering
if (g_Config.bSoftwareRendering)
g_Config.iInternalResolution = 1;
}
#if 0 // see issue #16786
@ -1104,7 +1125,7 @@ static void check_variables(CoreParameter &coreParam)
updateAvInfo = true;
}
if (g_Config.iInternalResolution != iInternalResolution_prev && !PSP_IsInited())
if (g_Config.iInternalResolution != iInternalResolution_prev && backend != RETRO_HW_CONTEXT_NONE)
{
coreParam.pixelWidth = coreParam.renderWidth = g_Config.iInternalResolution * NATIVEWIDTH;
coreParam.pixelHeight = coreParam.renderHeight = g_Config.iInternalResolution * NATIVEHEIGHT;
@ -1122,6 +1143,8 @@ static void check_variables(CoreParameter &coreParam)
if (g_Config.bDisplayCropTo16x9 != bDisplayCropTo16x9_prev && PSP_IsInited())
{
updateGeometry = true;
if (gpu)
gpu->NotifyDisplayResized();
}
#if 0 // see issue #16786
@ -1290,12 +1313,12 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
info->geometry.aspect_ratio = (float)info->geometry.base_width / (float)info->geometry.base_height;
PSP_CoreParameter().pixelWidth = info->geometry.base_width;
PSP_CoreParameter().pixelHeight = info->geometry.base_height;
PSP_CoreParameter().pixelWidth = PSP_CoreParameter().renderWidth = info->geometry.base_width;
PSP_CoreParameter().pixelHeight = PSP_CoreParameter().renderHeight = info->geometry.base_height;
/* Must reset context to resize render area properly while running,
* but not necessary with software, and not working with Vulkan.. (TODO) */
if (PSP_IsInited() && ctx && ctx->GetGPUCore() != GPUCORE_SOFTWARE && ctx->GetGPUCore() != GPUCORE_VULKAN)
if (PSP_IsInited() && ctx && backend != RETRO_HW_CONTEXT_NONE && ctx->GetGPUCore() != GPUCORE_VULKAN)
((LibretroHWRenderContext *)Libretro::ctx)->ContextReset();
}
@ -1398,23 +1421,23 @@ namespace Libretro
} // namespace Libretro
static void retro_check_renderer(void)
static void retro_check_backend(void)
{
struct retro_variable var = {0};
var.key = "ppsspp_renderer";
var.key = "ppsspp_backend";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "hardware"))
renderer = RETRO_HW_CONTEXT_DUMMY;
else if (!strcmp(var.value, "hardware_gl"))
renderer = RETRO_HW_CONTEXT_OPENGL;
else if (!strcmp(var.value, "hardware_vk"))
renderer = RETRO_HW_CONTEXT_VULKAN;
else if (!strcmp(var.value, "hardware_d3d"))
renderer = RETRO_HW_CONTEXT_DIRECT3D;
else if (!strcmp(var.value, "software"))
renderer = RETRO_HW_CONTEXT_NONE;
if (!strcmp(var.value, "auto"))
backend = RETRO_HW_CONTEXT_DUMMY;
else if (!strcmp(var.value, "opengl"))
backend = RETRO_HW_CONTEXT_OPENGL;
else if (!strcmp(var.value, "vulkan"))
backend = RETRO_HW_CONTEXT_VULKAN;
else if (!strcmp(var.value, "d3d11"))
backend = RETRO_HW_CONTEXT_DIRECT3D;
else if (!strcmp(var.value, "none"))
backend = RETRO_HW_CONTEXT_NONE;
}
}
@ -1427,7 +1450,7 @@ bool retro_load_game(const struct retro_game_info *game)
return false;
}
retro_check_renderer();
retro_check_backend();
coreState = CORE_POWERUP;
ctx = LibretroGraphicsContext::CreateGraphicsContext();
@ -1451,6 +1474,12 @@ bool retro_load_game(const struct retro_game_info *game)
coreParam.gpuCore = ctx->GetGPUCore();
check_variables(coreParam);
// TODO: OpenGL goes black when inited with software rendering,
// therefore start without, set back after init, and reset.
softwareRenderInitHack = ctx->GetGPUCore() == GPUCORE_GLES && g_Config.bSoftwareRendering;
if (softwareRenderInitHack)
g_Config.bSoftwareRendering = false;
// set cpuCore from libretro setting variable
coreParam.cpuCore = (CPUCore)g_Config.iCpuCore;
@ -1607,6 +1636,14 @@ void retro_run(void)
environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr);
return;
}
if (softwareRenderInitHack)
{
log_cb(RETRO_LOG_DEBUG, "Software rendering init hack for opengl triggered.\n");
softwareRenderInitHack = false;
g_Config.bSoftwareRendering = true;
retro_reset();
}
}
check_variables(PSP_CoreParameter());

View File

@ -110,8 +110,8 @@ struct retro_core_option_v2_category option_cats_us[] = {
},
{
"hacks",
"Speed Hacks",
"Configure speed hacks. Can cause rendering errors!"
"Hacks",
"Configure speed and emulation hacks. Can cause rendering errors!"
},
{
"network",
@ -236,9 +236,9 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
{
"ppsspp_language",
"Language",
"Game Language",
NULL,
"Choose language, 'Automatic' will use the frontend language.",
"'Automatic' will use the frontend language.",
NULL,
"system",
{
@ -274,44 +274,54 @@ struct retro_core_option_v2_definition option_defs_us[] = {
"psp_2000_3000"
},
{
"ppsspp_renderer",
"Renderer",
"ppsspp_backend",
"Backend",
NULL,
"'Hardware (Auto)' selects the renderer depending upon the current libretro frontend video driver. Restart required.",
"'Automatic' will use the frontend video driver. Core restart required.",
NULL,
"video",
{
{ "hardware", "Hardware (Auto)" },
{ "hardware_gl", "Hardware (OpenGL)" },
{ "auto", "Automatic" },
{ "opengl", "OpenGL" },
#ifndef HAVE_LIBNX
{ "hardware_vk", "Hardware (Vulkan)" },
{ "vulkan", "Vulkan" },
#endif
#ifdef _WIN32
{ "hardware_d3d", "Hardware (D3D11)" },
{ "d3d11", "D3D11" },
#endif
{ "software", "Software" },
{ "none", "None" },
{ NULL, NULL },
},
"hardware"
"auto"
},
{
"ppsspp_software_rendering",
"Software Rendering",
NULL,
"Slow, accurate. Core restart required.",
NULL,
"video",
BOOL_OPTIONS,
"disabled"
},
{
"ppsspp_internal_resolution",
"Internal Resolution",
"Rendering Resolution",
NULL,
"Restart required.",
"Core restart required with Vulkan.",
NULL,
"video",
{
{ "480x272", NULL },
{ "960x544", NULL },
{ "1440x816", NULL },
{ "1920x1088", NULL },
{ "2400x1360", NULL },
{ "2880x1632", NULL },
{ "3360x1904", NULL },
{ "3840x2176", NULL },
{ "4320x2448", NULL },
{ "4800x2720", NULL },
{ "480x272", "1x (480x272)" },
{ "960x544", "2x (960x544)" },
{ "1440x816", "3x (1440x816)" },
{ "1920x1088", "4x (1920x1088)" },
{ "2400x1360", "5x (2400x1360)" },
{ "2880x1632", "6x (2880x1632)" },
{ "3360x1904", "7x (3360x1904)" },
{ "3840x2176", "8x (3840x2176)" },
{ "4320x2448", "9x (4320x2448)" },
{ "4800x2720", "10x (4800x2720)" },
{ NULL, NULL },
},
"480x272"
@ -338,7 +348,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
"ppsspp_cropto16x9",
"Crop to 16x9",
NULL,
"Remove one line from top and bottom to get exact 16:9. Restart required with Vulkan!",
"Remove one line from top and bottom to get exact 16:9. Core restart required with Vulkan.",
NULL,
"video",
BOOL_OPTIONS,
@ -411,7 +421,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
{
"ppsspp_inflight_frames",
"Buffered Frames",
"Buffer Graphics Commands",
NULL,
"GL/Vulkan only, slower, less lag, restart.",
NULL,
@ -503,6 +513,22 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
"High"
},
{
"ppsspp_lower_resolution_for_effects",
"Lower Resolution for Effects",
NULL,
"Reduces artifacts.",
NULL,
"hacks",
{
{ "disabled", NULL },
{ "Safe", NULL },
{ "Balanced", NULL },
{ "Aggressive", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"ppsspp_gpu_hardware_transform",
"Hardware Transform",
@ -543,25 +569,9 @@ struct retro_core_option_v2_definition option_defs_us[] = {
BOOL_OPTIONS,
"disabled"
},
{
"ppsspp_lower_resolution_for_effects",
"Lower Resolution for Effects",
NULL,
NULL,
NULL,
"video",
{
{ "disabled", NULL },
{ "Safe", NULL },
{ "Balanced", NULL },
{ "Aggressive", NULL },
{ NULL, NULL },
},
"disabled"
},
{
"ppsspp_texture_scaling_type",
"Texture Scaling Type",
"Texture Upscale Type",
NULL,
NULL,
NULL,
@ -577,7 +587,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
},
{
"ppsspp_texture_scaling_level",
"Texture Scaling Level",
"Texture Upscaling Level",
NULL,
"CPU heavy, some scaling may be delayed to avoid stutter.",
NULL,

View File

@ -125,8 +125,11 @@ static VKAPI_ATTR VkResult VKAPI_CALL vkCreateLibretroSurfaceKHR(VkInstance inst
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR_libretro(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR_org(physicalDevice, surface, pSurfaceCapabilities);
if (res == VK_SUCCESS) {
int w = g_Config.iInternalResolution * 480;
int h = g_Config.iInternalResolution * 272;
int w = g_Config.iInternalResolution * NATIVEWIDTH;
int h = g_Config.iInternalResolution * NATIVEHEIGHT;
if (g_Config.bDisplayCropTo16x9)
h -= g_Config.iInternalResolution * 2;
pSurfaceCapabilities->minImageExtent.width = w;
pSurfaceCapabilities->minImageExtent.height = h;

View File

@ -29,6 +29,7 @@
#include "ext/vulkan/vulkan.h"
#include "libretro.h"
#include "LibretroGraphicsContext.h"
#define RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION 5
#define RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION 1