mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
Say which way an abandoned occlusion query was failing
Upstream now bounds this wait itself: warn at one second, abandon at three and use whatever the query holds. That replaces the fatal timeout this commit previously carried, and it is the better answer -- the throw could end a session over a driver that was merely slow, at worst wrong culling for a frame was the actual cost. What remains here is the part the bound does not cover: - On abandonment, ask the driver once more directly with VK_QUERY_RESULT_WITH_AVAILABILITY_BIT and log which way it is stalling: VK_NOT_READY, or VK_SUCCESS with the availability word still clear. The two are indistinguishable through poke_query and need different conversations with whoever maintains the driver. - Leave the loop when emulation is aborting. A driver that never answers must not also wedge the exit path, and the value is irrelevant once the session is going away. Found chasing a Skate 3 freeze on an Adreno 830, where stevenmxz's gen8 driver builds accept occlusion queries and never complete them; the system driver completes them in microseconds.
This commit is contained in:
@@ -196,6 +196,14 @@ namespace vk
|
||||
|
||||
for (u32 spins = 0; !query_info.ready; spins++)
|
||||
{
|
||||
// Emulation is going away; a driver that never answers must not also wedge
|
||||
// the exit path. The value is irrelevant once we are aborting.
|
||||
if (thread_ctrl::state() == thread_state::aborting)
|
||||
{
|
||||
rsx_log.warning("Occlusion query %u abandoned: emulation is shutting down.", index);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((spins & 0xffff) == 0xffff)
|
||||
{
|
||||
const auto waited = std::chrono::steady_clock::now() - wait_started;
|
||||
@@ -208,7 +216,18 @@ namespace vk
|
||||
|
||||
if (waited > std::chrono::seconds(3))
|
||||
{
|
||||
rsx_log.error("Occlusion query %u never completed; abandoning the wait and using result=%u.", index, query_info.data);
|
||||
// Ask once more directly before giving up, to record WHICH way the
|
||||
// driver is stalling: VK_NOT_READY, or VK_SUCCESS with the
|
||||
// availability word still clear. The two are indistinguishable
|
||||
// through poke_query and need different conversations with whoever
|
||||
// maintains the driver.
|
||||
u32 probe[2] = { 0, 0 };
|
||||
const VkResult status = vkGetQueryPoolResults(*owner, *query_info.pool, index, 1, 8, probe, 8,
|
||||
result_flags | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
|
||||
|
||||
rsx_log.error("Occlusion query %u never completed (last VkResult %d, result %u, availability %u); "
|
||||
"abandoning the wait and using result=%u.",
|
||||
index, static_cast<int>(status), probe[0], probe[1], query_info.data);
|
||||
query_info.ready = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user