menu: add a Direct SPIR-V Support (Hint) toggle for the glcore driver

Adds video_gl_direct_spirv, a boolean gating the GL_ARB_gl_spirv path in
gl3_spirv_binary_supported(). The row only appears when glcore is the
running video driver, since the extension is an OpenGL (Core) feature and
the entry would be inert anywhere else.

Worded as a hint on purpose. The extension may be absent, and a shader
whose SPIR-V cannot be lowered to the OpenGL environment falls back to
cross compilation on its own, so switching this on is a request rather
than a guarantee. The sublabel names the extension and says as much.

The setting is read on every call rather than latched alongside the
capability probe, so toggling it takes effect on the next preset load
without a driver reinit.

Defaulting to off, on the strength of the numbers rather than caution:
measured on llvmpipe over 146 presets, the SPIR-V path builds programs
about 4x faster against a cold driver shader cache, but Mesa's on-disk
cache serves the cross compiled path and not the SPIR-V one, so once the
cache is warm the GLSL path drops to ~11ms per program while SPIR-V stays
at ~120ms. That is a ~4x median regression on every load after the first,
which is the common case for a user reloading presets. Whether it holds
for other drivers is unknown, so this stays opt-in until there is data to
key a per-driver default off. RETROARCH_GL3_DISABLE_SPIRV still forces
the old path regardless of the setting.

Wired through the single-source descriptor mechanism:
settings/settings_def_video_gl_direct_spirv.h feeds configuration.c,
msg_hash.h, intl/msg_hash_us.{c,h} and menu/menu_setting.c.
tools/settings_table.reference regenerated.

Verified: settings_check.py table and unity both clean; the three enums,
both strings and the config key all appear after preprocessing;
menu_setting.c compiles both with and without HAVE_OPENGL_CORE/HAVE_SLANG
with no unused-const-variable warning when the guard is off; gl3.c error
counts identical to HEAD for desktop and GLES3.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-08-10 03:37:26 +02:00
1 parent 05db1e0766
commit 282ca43c0e
10 files changed
+56

No files matched your search

+7
View File
@@ -403,6 +403,13 @@
/* GL specific */
#define DEFAULT_ADAPTIVE_VSYNC false
/* Hands SPIR-V shaders straight to the driver through GL_ARB_gl_spirv
* rather than cross compiling them to GLSL. Off by default: the win is
* on a cold driver shader cache, and at least one implementation caches
* the cross compiled path far more effectively than the SPIR-V one, so
* this is opt-in until there is per-driver data to key off. */
#define DEFAULT_VIDEO_GL_DIRECT_SPIRV false
/* Attempts to hard-synchronize CPU and GPU.
* Can reduce latency at cost of performance. */
#define DEFAULT_HARD_SYNC false
+5
View File
@@ -2366,6 +2366,7 @@ static struct config_bool_setting *populate_settings_bool(
#endif
#include "settings/settings_def_video_frame_time_sample.h"
#include "settings/settings_def_video_adaptive_vsync.h"
#include "settings/settings_def_video_gl_direct_spirv.h"
#include "settings/settings_def_video_smooth.h"
#include "settings/settings_def_frame_time_counter.h"
#include "settings/settings_def_menu_filebrowser.h"
@@ -3077,6 +3078,7 @@ static struct config_float_setting *populate_settings_float(
#endif
#include "settings/settings_def_video_frame_time_sample.h"
#include "settings/settings_def_video_adaptive_vsync.h"
#include "settings/settings_def_video_gl_direct_spirv.h"
#include "settings/settings_def_video_smooth.h"
#include "settings/settings_def_frame_time_counter.h"
#include "settings/settings_def_menu_filebrowser.h"
@@ -3740,6 +3742,7 @@ static struct config_uint_setting *populate_settings_uint(
#endif
#include "settings/settings_def_video_frame_time_sample.h"
#include "settings/settings_def_video_adaptive_vsync.h"
#include "settings/settings_def_video_gl_direct_spirv.h"
#include "settings/settings_def_video_smooth.h"
#include "settings/settings_def_frame_time_counter.h"
#include "settings/settings_def_menu_filebrowser.h"
@@ -4451,6 +4454,7 @@ static struct config_int_setting *populate_settings_int(
#endif
#include "settings/settings_def_video_frame_time_sample.h"
#include "settings/settings_def_video_adaptive_vsync.h"
#include "settings/settings_def_video_gl_direct_spirv.h"
#include "settings/settings_def_video_smooth.h"
#include "settings/settings_def_frame_time_counter.h"
#include "settings/settings_def_menu_filebrowser.h"
@@ -5043,6 +5047,7 @@ static struct config_int_setting *populate_settings_int(
#endif
#include "settings/settings_def_video_frame_time_sample.h"
#include "settings/settings_def_video_adaptive_vsync.h"
#include "settings/settings_def_video_gl_direct_spirv.h"
#include "settings/settings_def_video_smooth.h"
#include "settings/settings_def_frame_time_counter.h"
#include "settings/settings_def_menu_filebrowser.h"
+1
View File
@@ -542,6 +542,7 @@ typedef struct settings
bool video_windowed_fullscreen;
bool video_vsync;
bool video_adaptive_vsync;
bool video_gl_direct_spirv;
bool video_scanline_sync;
bool video_hard_sync;
bool video_waitable_swapchains;
+6
View File
@@ -501,6 +501,7 @@ bool gl3_spirv_binary_supported(void)
return false;
#else
static int supported = -1;
settings_t *settings = config_get_ptr();
GLint num_formats = 0;
GLint num_extensions = 0;
GLint i;
@@ -508,6 +509,11 @@ bool gl3_spirv_binary_supported(void)
unsigned minor = 0;
bool have_extension = false;
/* Checked on every call rather than latched with the capability, so
* toggling the menu entry takes effect on the next preset load. */
if (!settings || !settings->bools.video_gl_direct_spirv)
return false;
if (supported >= 0)
return supported > 0;
+2
View File
@@ -786,6 +786,7 @@ static const char *const msg_hash_us_lbl_strs[] = {
#include "../settings/settings_def_input_android_workaround.h"
#include "../settings/settings_def_video_frame_time_sample.h"
#include "../settings/settings_def_video_adaptive_vsync.h"
#include "../settings/settings_def_video_gl_direct_spirv.h"
#include "../settings/settings_def_video_smooth.h"
#include "../settings/settings_def_frame_time_counter.h"
#include "../settings/settings_def_menu_filebrowser.h"
@@ -1161,6 +1162,7 @@ static const uint32_t msg_hash_us_lbl_ids[] = {
#include "../settings/settings_def_input_android_workaround.h"
#include "../settings/settings_def_video_frame_time_sample.h"
#include "../settings/settings_def_video_adaptive_vsync.h"
#include "../settings/settings_def_video_gl_direct_spirv.h"
#include "../settings/settings_def_video_smooth.h"
#include "../settings/settings_def_frame_time_counter.h"
#include "../settings/settings_def_menu_filebrowser.h"
+1
View File
@@ -7373,6 +7373,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_##T, sub)
#define S_FLOAT_NS(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us) \
MSG_HASH(MENU_ENUM_LABEL_VALUE_##T, us)
#include "../settings/settings_def_video_adaptive_vsync.h"
#include "../settings/settings_def_video_gl_direct_spirv.h"
#undef S_BOOL
#undef S_BOOL_NS
#undef S_UINT
+19
View File
@@ -11712,6 +11712,13 @@ static const setting_desc_t avsync_desc[] = {
#include "../settings/settings_def_video_adaptive_vsync.h"
};
#if defined(HAVE_OPENGL_CORE) && defined(HAVE_SLANG)
static const setting_desc_t glspirv_desc[] = {
/* GENERATED: rows come from settings_def_video_gl_direct_spirv.h in order. */
#include "../settings/settings_def_video_gl_direct_spirv.h"
};
#endif
static const setting_desc_t fdelay_desc[] = {
/* GENERATED: rows come from settings_def_frame_delay.h in order. */
#include "../settings/settings_def_frame_delay.h"
@@ -14578,6 +14585,15 @@ static void settings_build_video(
if (video_driver_test_all_flags(GFX_CTX_FLAGS_ADAPTIVE_VSYNC))
ADD_DESC(avsync_desc);
#if defined(HAVE_OPENGL_CORE) && defined(HAVE_SLANG)
/* GL_ARB_gl_spirv is an OpenGL (Core) driver feature; the entry
* would be inert under any other video driver. */
if (string_is_equal(settings->arrays.video_driver, "glcore"))
{
ADD_DESC(glspirv_desc);
}
#endif
ADD_DESC(fdelay_desc);
/* Unlike all other shader-related menu entries
@@ -17778,6 +17794,9 @@ static const settings_desc_table_t settings_desc_registry[] = {
{ vid_desc_20, (uint16_t)ARRAY_SIZE(vid_desc_20) },
{ sync_desc, (uint16_t)ARRAY_SIZE(sync_desc) },
{ avsync_desc, (uint16_t)ARRAY_SIZE(avsync_desc) },
#if defined(HAVE_OPENGL_CORE) && defined(HAVE_SLANG)
{ glspirv_desc, (uint16_t)ARRAY_SIZE(glspirv_desc) },
#endif
{ fdelay_desc, (uint16_t)ARRAY_SIZE(fdelay_desc) },
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
{ sdelay_desc, (uint16_t)ARRAY_SIZE(sdelay_desc) },
+1
View File
@@ -6706,6 +6706,7 @@ enum msg_hash_enums
#define S_ACTION_EX_H(T, n, sd, ok, rp, c, us, sub) MENU_LBL_H(T),
#define S_ACTION_EX_NS_H(T, n, sd, ok, rp, c, us) MENU_LBL_H(T),
#include "settings/settings_def_video_adaptive_vsync.h"
#include "settings/settings_def_video_gl_direct_spirv.h"
#undef S_BOOL
#undef S_BOOL_NS
#undef S_BOOL_H
@@ -0,0 +1,11 @@
/* Single-source definitions: direct SPIR-V shader ingestion setting.
* Grammar identical to settings_def_video_sync.h plus S_FLOAT and
* the _NS no-sublabel variants; the descriptor argument span
* matches SDESC_<kind>_ROW; row order is menu display order;
* h2json.py parses these rows for the Crowdin source upload. */
S_BOOL(video_gl_direct_spirv, VIDEO_GL_DIRECT_SPIRV,
"video_gl_direct_spirv",
DEFAULT_VIDEO_GL_DIRECT_SPIRV, SD_FLAG_NONE, 0, CMD_EVENT_NONE,
"Direct SPIR-V Support (Hint)",
"Hand shaders to the graphics driver as SPIR-V instead of cross-compiling them to GLSL first, which can shorten shader preset loading times. This is only a hint: it requires the 'GL_ARB_gl_spirv' driver extension, and any shader or driver that cannot use it silently falls back to cross-compilation. Takes effect the next time a shader preset is loaded.")
+3
View File
@@ -257,6 +257,7 @@ bool video_shader_remember_last_dir 1 0
bool android_input_disconnect_workaround 1 0
bool video_frame_time_sample_gated 1 0
bool video_adaptive_vsync 1 0
bool video_gl_direct_spirv 1 0
bool video_smooth 1 0
bool frame_time_counter_auto_reset 1 0
bool menu_navigation_browser_filter_supported_extensions_enable 1 1
@@ -899,6 +900,7 @@ bool video_shader_watch_files 1 0
bool video_shader_remember_last_dir 1 0
bool video_frame_time_sample_gated 1 0
bool video_adaptive_vsync 1 0
bool video_gl_direct_spirv 1 0
bool video_smooth 1 0
bool frame_time_counter_auto_reset 1 0
bool menu_navigation_browser_filter_supported_extensions_enable 1 1
@@ -1541,6 +1543,7 @@ bool video_shader_watch_files 1 0
bool video_shader_remember_last_dir 1 0
bool video_frame_time_sample_gated 1 0
bool video_adaptive_vsync 1 0
bool video_gl_direct_spirv 1 0
bool video_smooth 1 0
bool frame_time_counter_auto_reset 1 0
bool menu_navigation_browser_filter_supported_extensions_enable 1 1