mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-03 11:23:49 +00:00
Fix AMD RDNA startup crash and rendering corruption
# What changed - Drop the unused VK_FORMAT_D24_UNORM_S8_UINT device check that rejected some AMD GPUs. - Only treat VALIDATION-type Vulkan messages as fatal, not GENERAL-type ones. - Restrict compute queues to the graphics queue's family. - Force per-invocation lane mask emulation for 64-wide waves, since RDNA's lane layout differs from GCN despite matching wave size. # Why On AMD Radeon GPUs the emulator failed to find a suitable device, crashed during queue setup, or rendered corrupted output, while NVIDIA was unaffected. Each change removes an assumption in device selection, debug message handling, queue selection, or shader lane-mask emulation that happened to hold for NVIDIA but not for AMD. # Validation - Built on Windows with clang-cl. Note: the latest Vulkan SDK (1.4.350) fails to build against the pinned Vulkan-Headers submodule; used 1.4.328.1 instead, which matches it. - Tested on a Radeon RX 9070 XT + Ryzen 7 9800X3D. - Alex Kidd in Miracle World DX and Dreaming Sarah now boot and render correctly (previously failed to start or rendered corrupted). - Not yet verified for regressions on NVIDIA hardware; testing from someone with an NVIDIA GPU would help confirm no regression there. # AI assistance disclosure AI assistance was used to diagnose the root cause of each issue and prepare the initial patch. The contributor reviewed the complete diff and tested it on the affected AMD hardware before opening this pull request.
This commit is contained in:
@@ -230,7 +230,22 @@ static VulkanQueues VulkanFindQueues(VkPhysicalDevice device, VkSurfaceKHR surfa
|
||||
};
|
||||
|
||||
select_queues(graphics_num, [](const auto& q) { return q.graphics; }, qs.graphics);
|
||||
select_queues(compute_num, [](const auto& q) { return q.compute; }, qs.compute);
|
||||
|
||||
const uint32_t graphics_family =
|
||||
qs.graphics.empty() ? static_cast<uint32_t>(-1) : qs.graphics.front().family;
|
||||
select_queues(
|
||||
compute_num,
|
||||
[graphics_family](const auto& q) { return q.compute && q.family == graphics_family; },
|
||||
qs.compute);
|
||||
if (compute_num != 0 && qs.compute.empty()) {
|
||||
auto graphics_compute = std::find_if(qs.graphics.begin(), qs.graphics.end(),
|
||||
[](const auto& q) { return q.compute; });
|
||||
if (graphics_compute != qs.graphics.end()) {
|
||||
// Reuse the universal graphics queue when Intel GPUs expose no spare compute queue.
|
||||
qs.compute.push_back(*graphics_compute);
|
||||
}
|
||||
}
|
||||
|
||||
select_queues(transfer_num, [](const auto& q) { return q.transfer; }, qs.transfer);
|
||||
select_queues(present_num, [](const auto& q) { return q.present; }, qs.present);
|
||||
|
||||
@@ -433,12 +448,6 @@ static void VulkanFindPhysicalDevice(VkInstance instance, VkSurfaceKHR surface,
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_D24_UNORM_S8_UINT, true,
|
||||
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
||||
LOGF("Format VK_FORMAT_D24_UNORM_S8_UINT cannot be used as depth buffer\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_BC3_SRGB_BLOCK, true,
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
|
||||
VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
|
||||
@@ -831,7 +840,9 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugMessengerCallback(
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||
severity_str = "E";
|
||||
severity_style = Log::Color::BrightRed;
|
||||
error = true;
|
||||
// Only validation errors are fatal; GENERAL-type errors can come
|
||||
// from unrelated loader/layer issues (e.g. a broken overlay).
|
||||
error = (message_types & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) != 0;
|
||||
break;
|
||||
default: severity_str = "?";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user