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
This commit is contained in:
GPUCode
2022-11-13 15:29:16 +02:00
parent facddbfc8c
commit e978931574
5 changed files with 15 additions and 10 deletions

View File

@@ -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

View File

@@ -91,8 +91,7 @@ public:
u32 fill_size = 0;
public:
u32 watcher_count = 0;
std::array<std::weak_ptr<Watcher>, 8> watchers;
std::vector<std::weak_ptr<Watcher>> watchers;
};
template <class S>
@@ -190,7 +189,7 @@ template <class S>
auto SurfaceBase<S>::CreateWatcher() -> std::shared_ptr<Watcher> {
auto weak_ptr = reinterpret_cast<S*>(this)->weak_from_this();
auto watcher = std::make_shared<Watcher>(std::move(weak_ptr));
watchers[watcher_count++] = watcher;
watchers.push_back(watcher);
return watcher;
}
@@ -212,8 +211,7 @@ void SurfaceBase<S>::UnlinkAllWatcher() {
}
}
watchers = {};
watcher_count = 0;
watchers.clear();
}
} // namespace VideoCore

View File

@@ -63,10 +63,18 @@ vk::ShaderStageFlagBits ToVkShaderStage(std::size_t index) {
}
[[nodiscard]] bool IsAttribFormatSupported(const VertexAttribute& attrib, const Instance& instance) {
static std::unordered_map<vk::Format, bool> format_support_cache;
vk::PhysicalDevice physical_device = instance.GetPhysicalDevice();
const vk::Format format = ToVkAttributeFormat(attrib.type, attrib.size);
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;
return (features & vk::FormatFeatureFlagBits::eVertexBuffer) == vk::FormatFeatureFlagBits::eVertexBuffer;
it->second = (features & vk::FormatFeatureFlagBits::eVertexBuffer) == vk::FormatFeatureFlagBits::eVertexBuffer;
}
return it->second;
};
PipelineCache::PipelineCache(const Instance& instance, Scheduler& scheduler,

View File

@@ -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

View File

@@ -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);