diff --git a/src/graphics/host_gpu/renderer/shaderSubgroup.cpp b/src/graphics/host_gpu/renderer/shaderSubgroup.cpp index 96c736d31..c301c65c7 100644 --- a/src/graphics/host_gpu/renderer/shaderSubgroup.cpp +++ b/src/graphics/host_gpu/renderer/shaderSubgroup.cpp @@ -6,9 +6,14 @@ namespace Libs::Graphics { ShaderLaneMaskMode SelectGraphicsLaneMaskMode(const GraphicContext& context, uint32_t guest_wave_size) { - return context.subgroup_size == 32u && guest_wave_size == 64u - ? ShaderLaneMaskMode::PerInvocation - : ShaderLaneMaskMode::NativeWave; + // A 64-wide guest wave can't assume the host GPU's lane layout matches + // GCN's. AMD RDNA also reports a 64-wide subgroup but uses a different + // lane/pixel layout, which corrupted rendering under "native wave" mode. + // Per-invocation emulation works regardless of the host's lane layout. + if (guest_wave_size == 64u) { + return ShaderLaneMaskMode::PerInvocation; + } + return ShaderLaneMaskMode::NativeWave; } ShaderSubgroupConfiguration ConfigureShaderSubgroup(const GraphicContext& context, diff --git a/src/graphics/presentation/window/vulkanWindow.cpp b/src/graphics/presentation/window/vulkanWindow.cpp index 271f50a50..ab96282b4 100644 --- a/src/graphics/presentation/window/vulkanWindow.cpp +++ b/src/graphics/presentation/window/vulkanWindow.cpp @@ -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(-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 = "?"; }