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:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
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,
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user