diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index dca50380c8..1bce57238f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -802,14 +802,15 @@ std::unique_ptr PipelineCache::CreateComputePipeline( auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)}; - // Adreno have lower shared memory limits (32KB) - // Clamp shared memory usage to device maximum to avoid validation errors + // Adreno and mobile GPUs have lower shared memory limits (32KB vs Switch's 48KB) + // Skip shader compilation if it exceeds device limits to prevent GPU crashes const u32 max_shared_memory = device.GetMaxComputeSharedMemorySize(); if (program.shared_memory_size > max_shared_memory) { - LOG_WARNING(Render_Vulkan, - "Compute shader 0x{:016x} requests {}KB shared memory but device max is {}KB - clamping", - key.unique_hash, program.shared_memory_size / 1024, max_shared_memory / 1024); - program.shared_memory_size = max_shared_memory; + LOG_ERROR(Render_Vulkan, + "Compute shader 0x{:016x} requests {}KB shared memory but device max is {}KB - " + "SKIPPING compilation to prevent GPU crash. Visual effect will be missing.", + key.unique_hash, program.shared_memory_size / 1024, max_shared_memory / 1024); + return nullptr; } const std::vector code{EmitSPIRV(profile, program, this->optimize_spirv_output)}; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 508d8db4d9..0b91532953 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2120,26 +2120,13 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI } } const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format); - - // Workaround: Some Switch games incorrectly use R32_UINT textures with float samplers - // causing flickering/missing geometry. However, glyph atlases and lookup tables - // CORRECTLY use R32_UINT for integer data - reinterpreting breaks text rendering. - // Conservative heuristic: Only reinterpret large textures (likely geometry/effects) VkFormat view_format = format_info.format; - if (view_format == VK_FORMAT_R32_UINT && - !info.IsRenderTarget() && - (ImageUsageFlags(format_info, format) & VK_IMAGE_USAGE_SAMPLED_BIT)) { - // Skip small textures (likely atlases, lookup tables, or integer data) - const bool is_likely_atlas = image.info.size.width <= 1024 || image.info.size.height <= 1024; - const bool is_storage = (ImageUsageFlags(format_info, format) & VK_IMAGE_USAGE_STORAGE_BIT) != 0; - - // Only reinterpret large textures that are NOT storage and NOT likely atlases - if (!is_storage && !is_likely_atlas) { - view_format = VK_FORMAT_R32_SFLOAT; - LOG_DEBUG(Render_Vulkan, "Reinterpreting R32_UINT→R32_SFLOAT for {}x{} texture", - image.info.size.width, image.info.size.height); - } - } + + // 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 if (ImageUsageFlags(format_info, format) != image.UsageFlags()) { LOG_WARNING(Render_Vulkan,