From e97c0490037bc3f3139a47a1a678a9483723a78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 May 2026 11:12:21 +0200 Subject: [PATCH 1/3] Add ArenaAnywhere status page link --- assets/adhoc-servers.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/adhoc-servers.json b/assets/adhoc-servers.json index 43e90747e4..61c7ba160c 100644 --- a/assets/adhoc-servers.json +++ b/assets/adhoc-servers.json @@ -61,7 +61,7 @@ "host": "relay-sa.arenaanywhere.site", "discord": "https://discord.gg/GdsXWmNHq5", "ip": "34.35.138.175", - "web": "", + "web": "https://arenaanywhere.site/lobby-status.html", "location": "South Africa", "location-emoji": "πŸ‡ΏπŸ‡¦", "description": "For players looking to play any games", @@ -72,7 +72,7 @@ "host": "relay.arenaanywhere.site", "discord": "https://discord.gg/GdsXWmNHq5", "ip": "34.91.25.46", - "web": "", + "web": "https://arenaanywhere.site/lobby-status.html", "location": "Europe", "location-emoji": "πŸ‡ͺπŸ‡Ί", "description": "For players looking to play any games", @@ -83,7 +83,7 @@ "host": "relay-dubai.arenaanywhere.site", "discord": "https://discord.gg/GdsXWmNHq5", "ip": "34.165.197.39", - "web": "", + "web": "https://arenaanywhere.site/lobby-status.html", "location": "Dubai", "location-emoji": "πŸ‡¦πŸ‡ͺ", "description": "For players looking to play any games", @@ -94,7 +94,7 @@ "host": "relay-asia.arenaanywhere.site", "ip": "35.198.217.43", "discord": "https://discord.gg/GdsXWmNHq5", - "web": "", + "web": "https://arenaanywhere.site/lobby-status.html", "location": "Singapore", "location-emoji": "πŸ‡ΈπŸ‡¬", "description": "For players looking to play any games", From 4a420c95c2c7a10b44bb900a9950b9c7895e7bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 May 2026 11:46:42 +0200 Subject: [PATCH 2/3] Remove some redundant device caps, show clip/cull/depth-clamp in system info --- Common/GPU/D3D11/thin3d_d3d11.cpp | 7 ++++--- Common/GPU/OpenGL/GLFeatures.cpp | 26 +++++++++++++++++++++----- Common/GPU/OpenGL/GLFeatures.h | 4 +++- Common/GPU/OpenGL/thin3d_gl.cpp | 11 +++-------- Common/GPU/Vulkan/thin3d_vulkan.cpp | 11 ++++++----- Common/GPU/thin3d.h | 8 +++++--- Common/UI/View.cpp | 3 +++ Common/UI/View.h | 1 + GPU/GPUCommonHW.cpp | 6 +++--- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- UI/GameSettingsScreen.cpp | 2 +- UI/SystemInfoScreen.cpp | 1 + 12 files changed, 52 insertions(+), 30 deletions(-) diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index c3cc5d3d3c..8f1ad3032d 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -316,14 +316,15 @@ D3D11DrawContext::D3D11DrawContext(ComPtr device, ComPtr= D3D_FEATURE_LEVEL_10_0; caps_.depthClampSupported = featureLevel_ >= D3D_FEATURE_LEVEL_10_0; // SV_ClipDistance# seems to be 10+. - caps_.clipDistanceSupported = featureLevel_ >= D3D_FEATURE_LEVEL_10_0; - caps_.cullDistanceSupported = featureLevel_ >= D3D_FEATURE_LEVEL_10_0; + if (featureLevel_ >= D3D_FEATURE_LEVEL_10_0) { + caps_.maxClipDistances = 8; + caps_.maxCullDistances = 8; + } caps_.depthRangeMinusOneToOne = false; caps_.framebufferBlitSupported = false; diff --git a/Common/GPU/OpenGL/GLFeatures.cpp b/Common/GPU/OpenGL/GLFeatures.cpp index 0c4137cffe..cad9846731 100644 --- a/Common/GPU/OpenGL/GLFeatures.cpp +++ b/Common/GPU/OpenGL/GLFeatures.cpp @@ -208,9 +208,6 @@ bool CheckGLExtensions() { gl_extensions.model[sizeof(gl_extensions.model) - 1] = 0; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_extensions.maxTextureSize); -#ifndef USING_GLES2 - glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_extensions.maxClipPlanes); -#endif // Start by assuming we're at 2.0. int parsed[2] = {2, 0}; @@ -239,7 +236,6 @@ bool CheckGLExtensions() { } } - if (!gl_extensions.IsGLES) { // For desktop GL gl_extensions.ver[0] = parsed[0]; gl_extensions.ver[1] = parsed[1]; @@ -582,13 +578,33 @@ bool CheckGLExtensions() { } } - // Force off clip for a cmomon buggy Samsung version. + // Force off clip for a common buggy Samsung version. if (!strcmp(versionStr, "OpenGL ES 3.2 ANGLE git hash: aa8f94c52952")) { // Maybe could use bugs, but for now let's just force it back off. // Seeing errors that gl_ClipDistance is undefined. gl_extensions.EXT_clip_cull_distance = false; } + bool clipDistanceSupported = false; + bool cullDistanceSupported = false; + + if (gl_extensions.IsGLES) { + clipDistanceSupported = gl_extensions.EXT_clip_cull_distance || gl_extensions.APPLE_clip_distance; + cullDistanceSupported = gl_extensions.EXT_clip_cull_distance; + } else { + clipDistanceSupported = gl_extensions.VersionGEThan(3, 0); + cullDistanceSupported = gl_extensions.ARB_cull_distance; + } + + gl_extensions.maxClipDistances = 0; + gl_extensions.maxCullDistances = 0; + if (clipDistanceSupported) { + glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &gl_extensions.maxClipDistances); + } + if (cullDistanceSupported) { + glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &gl_extensions.maxCullDistances); + } + // Check the old query API. It doesn't seem to be very reliable (can miss stuff). GLint numCompressedFormats = 0; glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedFormats); diff --git a/Common/GPU/OpenGL/GLFeatures.h b/Common/GPU/OpenGL/GLFeatures.h index bdcfa4565a..540aef1df3 100644 --- a/Common/GPU/OpenGL/GLFeatures.h +++ b/Common/GPU/OpenGL/GLFeatures.h @@ -45,7 +45,8 @@ struct GLExtensions { bool GLES3; // true if the full OpenGL ES 3.0 is supported int maxTextureSize; - int maxClipPlanes; + int maxClipDistances; + int maxCullDistances; // OES bool OES_depth24; @@ -73,6 +74,7 @@ struct GLExtensions { bool ARB_texture_float; bool ARB_draw_instanced; bool ARB_buffer_storage; + bool ARB_clip_distance; bool ARB_cull_distance; bool ARB_depth_clamp; bool ARB_uniform_buffer_object; diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 046ab99f64..64e7e2235f 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -579,7 +579,6 @@ OpenGLContext::OpenGLContext(bool canChangeSwapInterval) : renderManager_(frameT } caps_.maxTextureSize = gl_extensions.maxTextureSize; - caps_.maxClipPlanes = gl_extensions.IsGLES ? 0 : gl_extensions.maxClipPlanes; caps_.coordConvention = CoordConvention::OpenGL; caps_.setMaxFrameLatencySupported = true; caps_.dualSourceBlend = gl_extensions.ARB_blend_func_extended || gl_extensions.EXT_blend_func_extended; @@ -592,13 +591,9 @@ OpenGLContext::OpenGLContext(bool canChangeSwapInterval) : renderManager_(frameT caps_.blendMinMaxSupported = gl_extensions.EXT_blend_minmax; caps_.multiSampleLevelsMask = 1; // More could be supported with some work. - if (gl_extensions.IsGLES) { - caps_.clipDistanceSupported = gl_extensions.EXT_clip_cull_distance || gl_extensions.APPLE_clip_distance; - caps_.cullDistanceSupported = gl_extensions.EXT_clip_cull_distance; - } else { - caps_.clipDistanceSupported = gl_extensions.VersionGEThan(3, 0); - caps_.cullDistanceSupported = gl_extensions.ARB_cull_distance; - } + caps_.maxClipDistances = gl_extensions.maxClipDistances; + caps_.maxCullDistances = gl_extensions.maxCullDistances; + caps_.textureNPOTFullySupported = (!gl_extensions.IsGLES && gl_extensions.VersionGEThan(2, 0, 0)) || gl_extensions.IsCoreContext || gl_extensions.GLES3 || diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index d0f2fd37f4..93ce8ca9bf 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -924,11 +924,12 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread) caps_.depthClampSupported = vulkan->GetDeviceFeatures().enabled.standard.depthClamp != 0; caps_.maxTextureSize = vulkan->GetPhysicalDeviceProperties().properties.limits.maxImageDimension2D; - caps_.maxClipPlanes = vulkan->GetPhysicalDeviceProperties().properties.limits.maxClipDistances; - - // Comment out these two to test geometry shader culling on any geometry shader-supporting hardware. - caps_.clipDistanceSupported = vulkan->GetDeviceFeatures().enabled.standard.shaderClipDistance != 0; - caps_.cullDistanceSupported = vulkan->GetDeviceFeatures().enabled.standard.shaderCullDistance != 0; + if (vulkan->GetDeviceFeatures().enabled.standard.shaderClipDistance) { + caps_.maxClipDistances = vulkan->GetPhysicalDeviceProperties().properties.limits.maxClipDistances; + } + if (vulkan->GetDeviceFeatures().enabled.standard.shaderCullDistance) { + caps_.maxCullDistances = vulkan->GetPhysicalDeviceProperties().properties.limits.maxCullDistances; + } caps_.framebufferBlitSupported = true; caps_.framebufferCopySupported = true; diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index 476878fb4f..a4f2081579 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -595,12 +595,16 @@ struct DeviceCaps { uint32_t deviceID; // use caution! uint32_t maxTextureSize; // largest side. - uint32_t maxClipPlanes; + + // You can check these for > 0 to see if they're supported. + uint32_t maxClipDistances; + uint32_t maxCullDistances; CoordConvention coordConvention; DataFormat preferredDepthBufferFormat; DataFormat preferredShadowMapFormatLow; DataFormat preferredShadowMapFormatHigh; + bool anisoSupported; bool depthRangeMinusOneToOne; // OpenGL style depth bool geometryShaderSupported; @@ -608,8 +612,6 @@ struct DeviceCaps { bool dualSourceBlend; bool logicOpSupported; bool depthClampSupported; - bool clipDistanceSupported; - bool cullDistanceSupported; bool framebufferCopySupported; bool framebufferBlitSupported; bool framebufferDepthCopySupported; diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 9b12e72e5b..f9bce6ab57 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -558,6 +558,9 @@ InfoItem::InfoItem(std::string_view text, std::string_view rightText, LayoutPara // We set the colors later once we have a UIContext. } +InfoItem::InfoItem(std::string_view text, int rightValue, LayoutParams *layoutParams) + : InfoItem(text, std::to_string(rightValue), layoutParams) {} + void InfoItem::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { float w1, h1, w2, h2; dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text_, &w1, &h1, 0); diff --git a/Common/UI/View.h b/Common/UI/View.h index e732cb2487..8782e36243 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -839,6 +839,7 @@ protected: class InfoItem : public Item { public: InfoItem(std::string_view text, std::string_view rightText, LayoutParams *layoutParams = nullptr); + InfoItem(std::string_view text, int rightValue, LayoutParams *layoutParams = nullptr); void Draw(UIContext &dc) override; std::string DescribeText() const override; diff --git a/GPU/GPUCommonHW.cpp b/GPU/GPUCommonHW.cpp index 14694e34be..f54d99cda6 100644 --- a/GPU/GPUCommonHW.cpp +++ b/GPU/GPUCommonHW.cpp @@ -595,11 +595,11 @@ u32 GPUCommonHW::CheckGPUFeatures() const { features |= GPU_USE_BLEND_MINMAX; } - if (draw_->GetDeviceCaps().clipDistanceSupported) { + if (draw_->GetDeviceCaps().maxClipDistances >= 2) { features |= GPU_USE_CLIP_DISTANCE; } - if (draw_->GetDeviceCaps().cullDistanceSupported) { + if (draw_->GetDeviceCaps().maxCullDistances >= 1) { features |= GPU_USE_CULL_DISTANCE; } @@ -612,7 +612,7 @@ u32 GPUCommonHW::CheckGPUFeatures() const { features |= GPU_USE_DEPTH_CLAMP | GPU_USE_ACCURATE_DEPTH; } - bool canClipOrCull = draw_->GetDeviceCaps().clipDistanceSupported || draw_->GetDeviceCaps().cullDistanceSupported; + bool canClipOrCull = draw_->GetDeviceCaps().maxClipDistances >= 2 || draw_->GetDeviceCaps().maxCullDistances >= 1; bool canDiscardVertex = !draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL); if ((canClipOrCull || canDiscardVertex) && !g_Config.bDisableRangeCulling) { // We'll dynamically use the parts that are supported, to reduce artifacts as much as possible. diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index dd2db802bc..0f8246b506 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -262,7 +262,7 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { // Checking accurate depth here because the old depth path is uncommon and not well tested for this. if (draw_->GetDeviceCaps().geometryShaderSupported && (features & GPU_USE_ACCURATE_DEPTH) != 0) { const bool useGeometry = g_Config.bUseGeometryShader && !draw_->GetBugs().Has(Draw::Bugs::GEOMETRY_SHADERS_SLOW_OR_BROKEN); - const bool vertexSupported = draw_->GetDeviceCaps().clipDistanceSupported && draw_->GetDeviceCaps().cullDistanceSupported; + const bool vertexSupported = draw_->GetDeviceCaps().maxClipDistances >= 2 && draw_->GetDeviceCaps().maxCullDistances >= 1; if (useGeometry && (!vertexSupported || (features & GPU_USE_VS_RANGE_CULLING) == 0)) { // Switch to culling via the geometry shader if not fully supported in vertex. features |= GPU_USE_GS_CULLING; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 60687ad9dd..b16e2a0125 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -542,7 +542,7 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) if (GetGPUBackend() == GPUBackend::VULKAN) { const bool usable = draw->GetDeviceCaps().geometryShaderSupported && !draw->GetBugs().Has(Draw::Bugs::GEOMETRY_SHADERS_SLOW_OR_BROKEN); - const bool vertexSupported = draw->GetDeviceCaps().clipDistanceSupported && draw->GetDeviceCaps().cullDistanceSupported; + const bool vertexSupported = draw->GetDeviceCaps().maxClipDistances >= 2 && draw->GetDeviceCaps().maxCullDistances >= 1; if (usable && !vertexSupported) { CheckBox *geometryCulling = graphicsSettings->Add(new CheckBox(&g_Config.bUseGeometryShader, gr->T("Geometry shader culling"))); geometryCulling->SetDisabledPtr(&g_Config.bSoftwareRendering); diff --git a/UI/SystemInfoScreen.cpp b/UI/SystemInfoScreen.cpp index b9f8f22e57..9c56946120 100644 --- a/UI/SystemInfoScreen.cpp +++ b/UI/SystemInfoScreen.cpp @@ -196,6 +196,7 @@ void SystemInfoScreen::CreateDeviceInfoTab(UI::LinearLayout *deviceSpecs) { } } gpuInfo->Add(new InfoItem(si->T("Depth buffer format"), DataFormatToString(draw->GetDeviceCaps().preferredDepthBufferFormat))); + gpuInfo->Add(new InfoItem(si->T("Clip/cull distances (depth clamp)"), StringFromFormat("%d/%d (%s)", draw->GetDeviceCaps().maxClipDistances, draw->GetDeviceCaps().maxCullDistances, draw->GetDeviceCaps().depthClampSupported ? "true" : "false"))); std::string texCompressionFormats; // Simple non-detailed summary of supported tex compression formats. From 2a745bc98db408781da41affb2a10e6210fe2098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 May 2026 16:36:32 +0200 Subject: [PATCH 3/3] Apple buildfix --- Common/GPU/OpenGL/GLFeatures.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Common/GPU/OpenGL/GLFeatures.cpp b/Common/GPU/OpenGL/GLFeatures.cpp index cad9846731..390e2be911 100644 --- a/Common/GPU/OpenGL/GLFeatures.cpp +++ b/Common/GPU/OpenGL/GLFeatures.cpp @@ -598,12 +598,20 @@ bool CheckGLExtensions() { gl_extensions.maxClipDistances = 0; gl_extensions.maxCullDistances = 0; + +#if PPSSPP_PLATFORM(IOS) + if (clipDistanceSupported) { + glGetIntegerv(GL_MAX_CLIP_DISTANCES_APPLE, &gl_extensions.maxClipDistances); + } + // Apple doesn't support cull distances. +#else if (clipDistanceSupported) { glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &gl_extensions.maxClipDistances); } if (cullDistanceSupported) { glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &gl_extensions.maxCullDistances); } +#endif // Check the old query API. It doesn't seem to be very reliable (can miss stuff). GLint numCompressedFormats = 0;