From a78514c0c01128c8bd50a3dcec3bc2e3fc43a827 Mon Sep 17 00:00:00 2001 From: Salvador Cipolla Date: Thu, 13 Aug 2026 19:06:17 -0300 Subject: [PATCH 1/4] Check for S3TC support in Vulkan --- code/graphics/vulkan/VulkanRenderer.cpp | 27 +++++++++++++++++++++++++ code/graphics/vulkan/VulkanRenderer.h | 5 +++++ code/graphics/vulkan/gr_vulkan.cpp | 3 ++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/code/graphics/vulkan/VulkanRenderer.cpp b/code/graphics/vulkan/VulkanRenderer.cpp index a0e1f426051..2fc386e6126 100644 --- a/code/graphics/vulkan/VulkanRenderer.cpp +++ b/code/graphics/vulkan/VulkanRenderer.cpp @@ -800,6 +800,33 @@ bool VulkanRenderer::isTextureCompressionBCSupported() const return m_deviceFeatures.textureCompressionBC == VK_TRUE; } +bool VulkanRenderer::isTextureCompressionS3TCSupported() const +{ + if (!m_physicalDevice) { + return false; + } + + if (m_deviceFeatures.textureCompressionBC == VK_TRUE) + return true; + + constexpr std::array formats = { + vk::Format::eBc1RgbaUnormBlock, // DXT1 + vk::Format::eBc2UnormBlock, // DXT3 + vk::Format::eBc3UnormBlock, // DXT5 + }; + + constexpr vk::FormatFeatureFlags required = vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eSampledImageFilterLinear; + + for (auto fmt : formats) { + const auto props = m_physicalDevice.getFormatProperties(fmt); + if ((props.optimalTilingFeatures & required) != required) { + return false; + } + } + + return true; +} + bool VulkanRenderer::isDepthClampSupported() const { if (!m_physicalDevice) { diff --git a/code/graphics/vulkan/VulkanRenderer.h b/code/graphics/vulkan/VulkanRenderer.h index 3d890b18a84..7610b0d551f 100644 --- a/code/graphics/vulkan/VulkanRenderer.h +++ b/code/graphics/vulkan/VulkanRenderer.h @@ -192,6 +192,11 @@ class VulkanRenderer { */ bool isTextureCompressionBCSupported() const; + /** + * @brief Check if BC 1/2/3 texture compression is supported + */ + bool isTextureCompressionS3TCSupported() const; + /** * @brief Check if depth clamping is supported (used by the shadow pass) */ diff --git a/code/graphics/vulkan/gr_vulkan.cpp b/code/graphics/vulkan/gr_vulkan.cpp index 8fb01daa2a0..c3f5dd52765 100644 --- a/code/graphics/vulkan/gr_vulkan.cpp +++ b/code/graphics/vulkan/gr_vulkan.cpp @@ -140,7 +140,8 @@ bool vulkan_is_capable(gr_capability capability) return getRendererInstance()->isTextureCompressionBCSupported(); case gr_capability::CAPABILITY_S3TC: // Vulkan always supports BC1/BC2/BC3 (S3TC equivalent) as core features - return true; + // But this is optional on mobile gpus, so check anyway + return getRendererInstance()->isTextureCompressionS3TCSupported(); case gr_capability::CAPABILITY_LARGE_SHADER: // Same troubleshooting switch as OpenGL: -no_large_shaders splits the model // ubershader into per-flag-combination variants for drivers that choke on the From aec48254aff0efbc9946ab5ae1bdbf53fcf4f6e9 Mon Sep 17 00:00:00 2001 From: Salvador Cipolla Date: Thu, 13 Aug 2026 19:30:32 -0300 Subject: [PATCH 2/4] use std::all_of --- code/graphics/vulkan/VulkanRenderer.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/code/graphics/vulkan/VulkanRenderer.cpp b/code/graphics/vulkan/VulkanRenderer.cpp index 2fc386e6126..9c085cbaa03 100644 --- a/code/graphics/vulkan/VulkanRenderer.cpp +++ b/code/graphics/vulkan/VulkanRenderer.cpp @@ -817,14 +817,10 @@ bool VulkanRenderer::isTextureCompressionS3TCSupported() const constexpr vk::FormatFeatureFlags required = vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eSampledImageFilterLinear; - for (auto fmt : formats) { + return std::all_of(formats.begin(), formats.end(), [this](vk::Format fmt) { const auto props = m_physicalDevice.getFormatProperties(fmt); - if ((props.optimalTilingFeatures & required) != required) { - return false; - } - } - - return true; + return (props.optimalTilingFeatures & required) == required; + }); } bool VulkanRenderer::isDepthClampSupported() const From 5074b698682d06f27691652ecaa8e27d44019a86 Mon Sep 17 00:00:00 2001 From: Salvador Cipolla Date: Thu, 13 Aug 2026 19:37:40 -0300 Subject: [PATCH 3/4] add missing include --- code/graphics/vulkan/VulkanRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/graphics/vulkan/VulkanRenderer.cpp b/code/graphics/vulkan/VulkanRenderer.cpp index 9c085cbaa03..6c975270af0 100644 --- a/code/graphics/vulkan/VulkanRenderer.cpp +++ b/code/graphics/vulkan/VulkanRenderer.cpp @@ -17,6 +17,7 @@ #include "mod_table/mod_table.h" #include +#include VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE From 81fea249690de857de2c9aa371c11d32bef9c318 Mon Sep 17 00:00:00 2001 From: Salvador Cipolla Date: Thu, 13 Aug 2026 19:45:55 -0300 Subject: [PATCH 4/4] fix lambda scope --- code/graphics/vulkan/VulkanRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/graphics/vulkan/VulkanRenderer.cpp b/code/graphics/vulkan/VulkanRenderer.cpp index 6c975270af0..902a8042b8b 100644 --- a/code/graphics/vulkan/VulkanRenderer.cpp +++ b/code/graphics/vulkan/VulkanRenderer.cpp @@ -818,7 +818,7 @@ bool VulkanRenderer::isTextureCompressionS3TCSupported() const constexpr vk::FormatFeatureFlags required = vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eSampledImageFilterLinear; - return std::all_of(formats.begin(), formats.end(), [this](vk::Format fmt) { + return std::all_of(formats.begin(), formats.end(), [this, required](vk::Format fmt) { const auto props = m_physicalDevice.getFormatProperties(fmt); return (props.optimalTilingFeatures & required) == required; });