From e97893157408153b371a09d686ae2f84b950dc81 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 13 Nov 2022 15:29:16 +0200 Subject: [PATCH] renderer_vulkan: Fix LMDM crashes * Cache vertex format lookups to avoid crashing the driver when the game does too many lookups * Increase watcher count. For some reason the game uses way too many watchers * Fix other misc SPIRV bugs and don't crash when shadow is requested --- src/core/hw/gpu.h | 2 +- src/video_core/rasterizer_cache/surface_base.h | 8 +++----- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 12 ++++++++++-- src/video_core/renderer_vulkan/vk_shader_gen.cpp | 1 - src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index b865dcd6e..49d487b4b 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -21,7 +21,7 @@ class MemorySystem; namespace GPU { // Measured on hardware to be 2240568 timer cycles or 4481136 ARM11 cycles -constexpr u64 frame_ticks = 4481136ull; +constexpr u64 frame_ticks = /*4481136ull*/2240568ull; // Refresh rate defined by ratio of ARM11 frequency to ARM11 ticks per frame // (268,111,856) / (4,481,136) = 59.83122493939037Hz diff --git a/src/video_core/rasterizer_cache/surface_base.h b/src/video_core/rasterizer_cache/surface_base.h index d083c63ba..ee8d8e3b7 100644 --- a/src/video_core/rasterizer_cache/surface_base.h +++ b/src/video_core/rasterizer_cache/surface_base.h @@ -91,8 +91,7 @@ public: u32 fill_size = 0; public: - u32 watcher_count = 0; - std::array, 8> watchers; + std::vector> watchers; }; template @@ -190,7 +189,7 @@ template auto SurfaceBase::CreateWatcher() -> std::shared_ptr { auto weak_ptr = reinterpret_cast(this)->weak_from_this(); auto watcher = std::make_shared(std::move(weak_ptr)); - watchers[watcher_count++] = watcher; + watchers.push_back(watcher); return watcher; } @@ -212,8 +211,7 @@ void SurfaceBase::UnlinkAllWatcher() { } } - watchers = {}; - watcher_count = 0; + watchers.clear(); } } // namespace VideoCore diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index ead00442e..c6d2f6fb6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -63,10 +63,18 @@ vk::ShaderStageFlagBits ToVkShaderStage(std::size_t index) { } [[nodiscard]] bool IsAttribFormatSupported(const VertexAttribute& attrib, const Instance& instance) { + static std::unordered_map format_support_cache; + vk::PhysicalDevice physical_device = instance.GetPhysicalDevice(); const vk::Format format = ToVkAttributeFormat(attrib.type, attrib.size); - const vk::FormatFeatureFlags features = physical_device.getFormatProperties(format).bufferFeatures; - return (features & vk::FormatFeatureFlagBits::eVertexBuffer) == vk::FormatFeatureFlagBits::eVertexBuffer; + auto [it, new_format] = format_support_cache.try_emplace(format, false); + if (new_format) { + LOG_INFO(Render_Vulkan, "Quering support for format {}", vk::to_string(format)); + const vk::FormatFeatureFlags features = physical_device.getFormatProperties(format).bufferFeatures; + it->second = (features & vk::FormatFeatureFlagBits::eVertexBuffer) == vk::FormatFeatureFlagBits::eVertexBuffer; + } + + return it->second; }; PipelineCache::PipelineCache(const Instance& instance, Scheduler& scheduler, diff --git a/src/video_core/renderer_vulkan/vk_shader_gen.cpp b/src/video_core/renderer_vulkan/vk_shader_gen.cpp index b605dc9f9..b3c952fed 100644 --- a/src/video_core/renderer_vulkan/vk_shader_gen.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_gen.cpp @@ -1541,7 +1541,6 @@ do { } while ((old = imageAtomicCompSwap(shadow_buffer, image_coord, old, new)) != old2); )"; - LOG_INFO(Render_Vulkan, "{}", out); } else { out += "gl_FragDepth = depth;\n"; // Round the final fragment color to maintain the PICA's 8 bits of precision diff --git a/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp b/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp index 57c7b059e..dc9273d0c 100644 --- a/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp @@ -423,7 +423,7 @@ void FragmentModule::WriteLighting() { // Apply shadow attenuation to alpha components if enabled if (lighting.shadow_alpha) { - const Id shadow_a{OpCompositeExtract(vec_ids.Get(4), shadow, 3)}; + const Id shadow_a{OpCompositeExtract(f32_id, shadow, 3)}; const Id shadow_a_vec{OpCompositeConstruct(vec_ids.Get(4), ConstF32(1.f, 1.f, 1.f), shadow_a)}; if (lighting.enable_primary_alpha) { diffuse_sum = OpFMul(vec_ids.Get(4), diffuse_sum, shadow_a_vec);