diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 024c72b38e..06cf79151b 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -173,7 +173,7 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_SINT, usage_attachable | usage_storage, R16G16_SINT) \ SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_SNORM, usage_attachable | usage_storage, R16G16_SNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32B32_SFLOAT, 0, R32G32B32_FLOAT) \ - SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_SRGB_PACK32, usage_attachable, A8B8G8R8_SRGB) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_SRGB_PACK32, usage_attachable | usage_storage, A8B8G8R8_SRGB) \ SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_UNORM, usage_attachable | usage_storage, R8G8_UNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_SNORM, usage_attachable | usage_storage, R8G8_SNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_SINT, usage_attachable | usage_storage, R8G8_SINT) \ @@ -185,7 +185,7 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 0, ASTC_2D_8X8_UNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 0, ASTC_2D_8X5_UNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 0, ASTC_2D_5X4_UNORM) \ - SURFACE_FORMAT_ELEM(VK_FORMAT_B8G8R8A8_SRGB, usage_attachable, B8G8R8A8_SRGB) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_B8G8R8A8_SRGB, usage_attachable | usage_storage, B8G8R8A8_SRGB) \ SURFACE_FORMAT_ELEM(VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 0, BC1_RGBA_SRGB) \ SURFACE_FORMAT_ELEM(VK_FORMAT_BC2_SRGB_BLOCK, 0, BC2_SRGB) \ SURFACE_FORMAT_ELEM(VK_FORMAT_BC3_SRGB_BLOCK, 0, BC3_SRGB) \ diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 168a701e7c..7dd16e1818 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1262,6 +1262,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, @@ -1280,6 +1283,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); @@ -1307,6 +1313,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 5c46831264..7d0fe00717 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -93,8 +93,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, @@ -831,7 +829,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, @@ -841,18 +839,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",