Browse Source

[vk, texture_cache] Handling for integer formats with float samplers

pull/3049/head
CamilleLaVey 2 months ago
parent
commit
69bd1d5c8a
  1. 6
      src/common/settings.h
  2. 3
      src/common/settings_common.h
  3. 1
      src/common/settings_enums.h
  4. 33
      src/video_core/renderer_vulkan/vk_texture_cache.cpp

6
src/common/settings.h

@ -69,6 +69,7 @@ SWITCHABLE(AstcRecompression, true);
SWITCHABLE(AudioMode, true); SWITCHABLE(AudioMode, true);
SWITCHABLE(CpuBackend, true); SWITCHABLE(CpuBackend, true);
SWITCHABLE(CpuAccuracy, true); SWITCHABLE(CpuAccuracy, true);
SWITCHABLE(FormatReinterpretation, true);
SWITCHABLE(FullscreenMode, true); SWITCHABLE(FullscreenMode, true);
SWITCHABLE(GpuAccuracy, true); SWITCHABLE(GpuAccuracy, true);
SWITCHABLE(Language, true); SWITCHABLE(Language, true);
@ -451,6 +452,11 @@ struct Values {
AstcRecompression::Uncompressed, AstcRecompression::Uncompressed,
"astc_recompression", "astc_recompression",
Category::RendererAdvanced}; Category::RendererAdvanced};
SwitchableSetting<FormatReinterpretation, true> format_reinterpretation{
linkage,
FormatReinterpretation::Disabled,
"format_reinterpretation",
Category::RendererAdvanced};
SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage, SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage,
VramUsageMode::Conservative, VramUsageMode::Conservative,
"vram_usage_mode", "vram_usage_mode",

3
src/common/settings_common.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

1
src/common/settings_enums.h

@ -151,6 +151,7 @@ ENUM(AppletMode, HLE, LLE);
ENUM(SpirvOptimizeMode, Never, OnLoad, Always); ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
ENUM(GpuOverclock, Low, Medium, High) ENUM(GpuOverclock, Low, Medium, High)
ENUM(TemperatureUnits, Celsius, Fahrenheit) ENUM(TemperatureUnits, Celsius, Fahrenheit)
ENUM(FormatReinterpretation, Disabled, R32UintToR32Sfloat, R32SintToR32Uint, R32SfloatToR32Sint)
// Shader Float Controls behavior modes // Shader Float Controls behavior modes
// These control how floating-point denormals and special values are handled in shaders // These control how floating-point denormals and special values are handled in shaders

33
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -2122,11 +2122,34 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
VkFormat view_format = format_info.format; VkFormat view_format = format_info.format;
// TODO: Format reinterpretation toggles (per-game settings)
// Some games incorrectly use integer formats with float samplers:
// - R32_UINT with texture() instead of texelFetch() causes flickering
// - R8_UINT with LINEAR filter causes validation errors
// Cannot auto-detect: need user toggles to force format reinterpretation
// Format reinterpretation for games with incorrect format usage
// Some games declare render targets as R32_UINT but sample them
// as float textures.
const auto reinterpretation_mode = Settings::values.format_reinterpretation.GetValue();
if (reinterpretation_mode != Settings::FormatReinterpretation::Disabled) {
switch (reinterpretation_mode) {
case Settings::FormatReinterpretation::R32UintToR32Sfloat:
if (view_format == VK_FORMAT_R32_UINT) {
view_format = VK_FORMAT_R32_SFLOAT;
LOG_DEBUG(Render_Vulkan, "Reinterpreting R32_UINT -> R32_SFLOAT for texture view");
}
break;
case Settings::FormatReinterpretation::R32SintToR32Uint:
if (view_format == VK_FORMAT_R32_SINT) {
view_format = VK_FORMAT_R32_UINT;
LOG_DEBUG(Render_Vulkan, "Reinterpreting R32_SINT -> R32_UINT for texture view");
}
break;
case Settings::FormatReinterpretation::R32SfloatToR32Sint:
if (view_format == VK_FORMAT_R32_SFLOAT) {
view_format = VK_FORMAT_R32_SINT;
LOG_DEBUG(Render_Vulkan, "Reinterpreting R32_SFLOAT -> R32_SINT for texture view");
}
break;
default:
break;
}
}
if (ImageUsageFlags(format_info, format) != image.UsageFlags()) { if (ImageUsageFlags(format_info, format) != image.UsageFlags()) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,

Loading…
Cancel
Save