From 9f3803c986687a8aa90adb3437ac0605d7a7fb5d Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Wed, 3 Dec 2025 15:12:42 -0400 Subject: [PATCH] [vk] Hotfix for DepthBounds and StencilMask. --- .../renderer_vulkan/maxwell_to_vk.cpp | 4 +- .../renderer_vulkan/vk_rasterizer.cpp | 11 +++++ .../vulkan_common/vulkan_device.cpp | 41 +++++++++++++++---- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index c993e19ad4..1c619b3044 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -168,7 +168,7 @@ struct FormatTuple { {VK_FORMAT_R16G16_SINT, Attachable | Storage}, // R16G16_SINT {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM {VK_FORMAT_R32G32B32_SFLOAT}, // R32G32B32_FLOAT - {VK_FORMAT_A8B8G8R8_SRGB_PACK32, Attachable}, // A8B8G8R8_SRGB + {VK_FORMAT_A8B8G8R8_SRGB_PACK32, Attachable | Storage}, // A8B8G8R8_SRGB {VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // R8G8_UNORM {VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // R8G8_SNORM {VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT @@ -180,7 +180,7 @@ struct FormatTuple { {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8_UNORM {VK_FORMAT_ASTC_8x5_UNORM_BLOCK}, // ASTC_2D_8X5_UNORM {VK_FORMAT_ASTC_5x4_UNORM_BLOCK}, // ASTC_2D_5X4_UNORM - {VK_FORMAT_B8G8R8A8_SRGB, Attachable}, // B8G8R8A8_SRGB + {VK_FORMAT_B8G8R8A8_SRGB, Attachable | Storage}, // B8G8R8A8_SRGB {VK_FORMAT_BC1_RGBA_SRGB_BLOCK}, // BC1_RGBA_SRGB {VK_FORMAT_BC2_SRGB_BLOCK}, // BC2_SRGB {VK_FORMAT_BC3_SRGB_BLOCK}, // BC3_SRGB diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d2731632d0..5cc4a80306 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1273,6 +1273,9 @@ void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& reg if (!state_tracker.TouchBlendConstants()) { return; } + if (!device.UsesAdvancedCoreDynamicState()) { + return; + } const std::array blend_constants{ regs.blend_color.r, regs.blend_color.g, @@ -1291,6 +1294,9 @@ void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs) if (!device.IsDepthBoundsSupported()) { return; } + if (!device.UsesAdvancedCoreDynamicState()) { + return; + } const bool unrestricted = device.IsExtDepthRangeUnrestrictedSupported(); const float min_depth = unrestricted ? regs.depth_bounds[0] : std::clamp(regs.depth_bounds[0], 0.0f, 1.0f); @@ -1318,6 +1324,11 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) return; } + if (!device.UsesAdvancedCoreDynamicState()) { + state_tracker.ClearStencilReset(); + return; + } + if (update_references) { if (two_sided) { const bool front_dirty = diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index acf713b52a..4d33d07fc8 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -91,8 +91,6 @@ constexpr std::array VK_FORMAT_A4B4G4R4_UNORM_PACK16{ }; constexpr std::array B10G11R11_UFLOAT_PACK32{ - VK_FORMAT_A8B8G8R8_UNORM_PACK32, - VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_UNDEFINED, @@ -806,7 +804,7 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags if (IsFormatSupported(wanted_format, wanted_usage, format_type)) { return wanted_format; } - // The wanted format is not supported by hardware, search for alternatives + const VkFormat* alternatives = GetFormatAlternatives(wanted_format); if (alternatives == nullptr) { LOG_ERROR(Render_Vulkan, @@ -816,18 +814,45 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags return wanted_format; } - std::size_t i = 0; - for (VkFormat alternative = *alternatives; alternative; alternative = alternatives[++i]) { +#if defined(ANDROID) + const auto downgrade_r16_to_ldr = [&](VkFormat candidate) -> VkFormat { + if (wanted_format != VK_FORMAT_B10G11R11_UFLOAT_PACK32) { + return candidate; + } + if (candidate != VK_FORMAT_R16G16B16A16_SFLOAT && + candidate != VK_FORMAT_R16G16B16A16_UNORM) { + return candidate; + } + static constexpr std::array ldr_candidates{ + VK_FORMAT_A8B8G8R8_UNORM_PACK32, + VK_FORMAT_A8B8G8R8_SRGB_PACK32, + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB, + }; + for (const VkFormat format : ldr_candidates) { + if (IsFormatSupported(format, wanted_usage, format_type)) { + return format; + } + } + return candidate; + }; +#endif + + for (std::size_t i = 0; VkFormat alternative = alternatives[i]; ++i) { if (!IsFormatSupported(alternative, wanted_usage, format_type)) { continue; } +#if defined(ANDROID) + const VkFormat selected = downgrade_r16_to_ldr(alternative); +#else + const VkFormat selected = alternative; +#endif LOG_DEBUG(Render_Vulkan, "Emulating format={} with alternative format={} with usage={} and type={}", - wanted_format, alternative, wanted_usage, format_type); - return alternative; + wanted_format, selected, wanted_usage, format_type); + return selected; } - // No alternatives found, panic LOG_ERROR(Render_Vulkan, "Format={} with usage={} and type={} is not supported by the host hardware and " "doesn't support any of the alternatives",