diff options
| author | 2021-01-06 15:39:51 +0800 | |
|---|---|---|
| committer | 2021-01-06 15:39:51 +0800 | |
| commit | e8d40559d50b952335f4899392944a9dca418b62 (patch) | |
| tree | 94cbbc1e616e12ecc6b9c167f630649b829368fe /src/video_core/texture_cache | |
| parent | Merge pull request #5250 from lat9nq/appimage (diff) | |
| parent | gl_texture_cache: Avoid format views on Intel and AMD (diff) | |
| download | yuzu-e8d40559d50b952335f4899392944a9dca418b62.tar.gz yuzu-e8d40559d50b952335f4899392944a9dca418b62.tar.xz yuzu-e8d40559d50b952335f4899392944a9dca418b62.zip | |
Merge pull request #5288 from ReinUsesLisp/workaround-garbage
gl_texture_cache: Avoid format views on Intel and AMD
Diffstat (limited to 'src/video_core/texture_cache')
| -rw-r--r-- | src/video_core/texture_cache/image_base.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_view_base.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 15 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.h | 8 |
5 files changed, 26 insertions, 16 deletions
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp index 448a05fcc..959b3f115 100644 --- a/src/video_core/texture_cache/image_base.cpp +++ b/src/video_core/texture_cache/image_base.cpp | |||
| @@ -120,7 +120,9 @@ void AddImageAlias(ImageBase& lhs, ImageBase& rhs, ImageId lhs_id, ImageId rhs_i | |||
| 120 | if (lhs.info.type == ImageType::Linear) { | 120 | if (lhs.info.type == ImageType::Linear) { |
| 121 | base = SubresourceBase{.level = 0, .layer = 0}; | 121 | base = SubresourceBase{.level = 0, .layer = 0}; |
| 122 | } else { | 122 | } else { |
| 123 | base = FindSubresource(rhs.info, lhs, rhs.gpu_addr, OPTIONS); | 123 | // We are passing relaxed formats as an option, having broken views or not won't matter |
| 124 | static constexpr bool broken_views = false; | ||
| 125 | base = FindSubresource(rhs.info, lhs, rhs.gpu_addr, OPTIONS, broken_views); | ||
| 124 | } | 126 | } |
| 125 | if (!base) { | 127 | if (!base) { |
| 126 | LOG_ERROR(HW_GPU, "Image alias should have been flipped"); | 128 | LOG_ERROR(HW_GPU, "Image alias should have been flipped"); |
diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 076a4bcfd..18f72e508 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp | |||
| @@ -24,7 +24,7 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i | |||
| 24 | .height = std::max(image_info.size.height >> range.base.level, 1u), | 24 | .height = std::max(image_info.size.height >> range.base.level, 1u), |
| 25 | .depth = std::max(image_info.size.depth >> range.base.level, 1u), | 25 | .depth = std::max(image_info.size.depth >> range.base.level, 1u), |
| 26 | } { | 26 | } { |
| 27 | ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format), | 27 | ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false), |
| 28 | "Image view format {} is incompatible with image format {}", info.format, | 28 | "Image view format {} is incompatible with image format {}", info.format, |
| 29 | image_info.format); | 29 | image_info.format); |
| 30 | const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); | 30 | const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 968059842..ad86c50b4 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -883,6 +883,7 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, | |||
| 883 | if (!cpu_addr) { | 883 | if (!cpu_addr) { |
| 884 | return ImageId{}; | 884 | return ImageId{}; |
| 885 | } | 885 | } |
| 886 | const bool broken_views = runtime.HasBrokenTextureViewFormats(); | ||
| 886 | ImageId image_id; | 887 | ImageId image_id; |
| 887 | const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) { | 888 | const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) { |
| 888 | if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear) { | 889 | if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear) { |
| @@ -892,11 +893,11 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, | |||
| 892 | if (existing_image.gpu_addr == gpu_addr && existing.type == info.type && | 893 | if (existing_image.gpu_addr == gpu_addr && existing.type == info.type && |
| 893 | existing.pitch == info.pitch && | 894 | existing.pitch == info.pitch && |
| 894 | IsPitchLinearSameSize(existing, info, strict_size) && | 895 | IsPitchLinearSameSize(existing, info, strict_size) && |
| 895 | IsViewCompatible(existing.format, info.format)) { | 896 | IsViewCompatible(existing.format, info.format, broken_views)) { |
| 896 | image_id = existing_image_id; | 897 | image_id = existing_image_id; |
| 897 | return true; | 898 | return true; |
| 898 | } | 899 | } |
| 899 | } else if (IsSubresource(info, existing_image, gpu_addr, options)) { | 900 | } else if (IsSubresource(info, existing_image, gpu_addr, options, broken_views)) { |
| 900 | image_id = existing_image_id; | 901 | image_id = existing_image_id; |
| 901 | return true; | 902 | return true; |
| 902 | } | 903 | } |
| @@ -926,6 +927,7 @@ template <class P> | |||
| 926 | ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr) { | 927 | ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr) { |
| 927 | ImageInfo new_info = info; | 928 | ImageInfo new_info = info; |
| 928 | const size_t size_bytes = CalculateGuestSizeInBytes(new_info); | 929 | const size_t size_bytes = CalculateGuestSizeInBytes(new_info); |
| 930 | const bool broken_views = runtime.HasBrokenTextureViewFormats(); | ||
| 929 | std::vector<ImageId> overlap_ids; | 931 | std::vector<ImageId> overlap_ids; |
| 930 | std::vector<ImageId> left_aliased_ids; | 932 | std::vector<ImageId> left_aliased_ids; |
| 931 | std::vector<ImageId> right_aliased_ids; | 933 | std::vector<ImageId> right_aliased_ids; |
| @@ -940,7 +942,9 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 940 | } | 942 | } |
| 941 | return; | 943 | return; |
| 942 | } | 944 | } |
| 943 | const auto solution = ResolveOverlap(new_info, gpu_addr, cpu_addr, overlap, true); | 945 | static constexpr bool strict_size = true; |
| 946 | const std::optional<OverlapResult> solution = | ||
| 947 | ResolveOverlap(new_info, gpu_addr, cpu_addr, overlap, strict_size, broken_views); | ||
| 944 | if (solution) { | 948 | if (solution) { |
| 945 | gpu_addr = solution->gpu_addr; | 949 | gpu_addr = solution->gpu_addr; |
| 946 | cpu_addr = solution->cpu_addr; | 950 | cpu_addr = solution->cpu_addr; |
| @@ -950,9 +954,10 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 950 | } | 954 | } |
| 951 | static constexpr auto options = RelaxedOptions::Size | RelaxedOptions::Format; | 955 | static constexpr auto options = RelaxedOptions::Size | RelaxedOptions::Format; |
| 952 | const ImageBase new_image_base(new_info, gpu_addr, cpu_addr); | 956 | const ImageBase new_image_base(new_info, gpu_addr, cpu_addr); |
| 953 | if (IsSubresource(new_info, overlap, gpu_addr, options)) { | 957 | if (IsSubresource(new_info, overlap, gpu_addr, options, broken_views)) { |
| 954 | left_aliased_ids.push_back(overlap_id); | 958 | left_aliased_ids.push_back(overlap_id); |
| 955 | } else if (IsSubresource(overlap.info, new_image_base, overlap.gpu_addr, options)) { | 959 | } else if (IsSubresource(overlap.info, new_image_base, overlap.gpu_addr, options, |
| 960 | broken_views)) { | ||
| 956 | right_aliased_ids.push_back(overlap_id); | 961 | right_aliased_ids.push_back(overlap_id); |
| 957 | } | 962 | } |
| 958 | }); | 963 | }); |
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 9ed1fc007..279932778 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp | |||
| @@ -1069,13 +1069,13 @@ bool IsPitchLinearSameSize(const ImageInfo& lhs, const ImageInfo& rhs, bool stri | |||
| 1069 | 1069 | ||
| 1070 | std::optional<OverlapResult> ResolveOverlap(const ImageInfo& new_info, GPUVAddr gpu_addr, | 1070 | std::optional<OverlapResult> ResolveOverlap(const ImageInfo& new_info, GPUVAddr gpu_addr, |
| 1071 | VAddr cpu_addr, const ImageBase& overlap, | 1071 | VAddr cpu_addr, const ImageBase& overlap, |
| 1072 | bool strict_size) { | 1072 | bool strict_size, bool broken_views) { |
| 1073 | ASSERT(new_info.type != ImageType::Linear); | 1073 | ASSERT(new_info.type != ImageType::Linear); |
| 1074 | ASSERT(overlap.info.type != ImageType::Linear); | 1074 | ASSERT(overlap.info.type != ImageType::Linear); |
| 1075 | if (!IsLayerStrideCompatible(new_info, overlap.info)) { | 1075 | if (!IsLayerStrideCompatible(new_info, overlap.info)) { |
| 1076 | return std::nullopt; | 1076 | return std::nullopt; |
| 1077 | } | 1077 | } |
| 1078 | if (!IsViewCompatible(overlap.info.format, new_info.format)) { | 1078 | if (!IsViewCompatible(overlap.info.format, new_info.format, broken_views)) { |
| 1079 | return std::nullopt; | 1079 | return std::nullopt; |
| 1080 | } | 1080 | } |
| 1081 | if (gpu_addr == overlap.gpu_addr) { | 1081 | if (gpu_addr == overlap.gpu_addr) { |
| @@ -1118,14 +1118,15 @@ bool IsLayerStrideCompatible(const ImageInfo& lhs, const ImageInfo& rhs) { | |||
| 1118 | } | 1118 | } |
| 1119 | 1119 | ||
| 1120 | std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const ImageBase& image, | 1120 | std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const ImageBase& image, |
| 1121 | GPUVAddr candidate_addr, RelaxedOptions options) { | 1121 | GPUVAddr candidate_addr, RelaxedOptions options, |
| 1122 | bool broken_views) { | ||
| 1122 | const std::optional<SubresourceBase> base = image.TryFindBase(candidate_addr); | 1123 | const std::optional<SubresourceBase> base = image.TryFindBase(candidate_addr); |
| 1123 | if (!base) { | 1124 | if (!base) { |
| 1124 | return std::nullopt; | 1125 | return std::nullopt; |
| 1125 | } | 1126 | } |
| 1126 | const ImageInfo& existing = image.info; | 1127 | const ImageInfo& existing = image.info; |
| 1127 | if (False(options & RelaxedOptions::Format)) { | 1128 | if (False(options & RelaxedOptions::Format)) { |
| 1128 | if (!IsViewCompatible(existing.format, candidate.format)) { | 1129 | if (!IsViewCompatible(existing.format, candidate.format, broken_views)) { |
| 1129 | return std::nullopt; | 1130 | return std::nullopt; |
| 1130 | } | 1131 | } |
| 1131 | } | 1132 | } |
| @@ -1162,8 +1163,8 @@ std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const | |||
| 1162 | } | 1163 | } |
| 1163 | 1164 | ||
| 1164 | bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr candidate_addr, | 1165 | bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr candidate_addr, |
| 1165 | RelaxedOptions options) { | 1166 | RelaxedOptions options, bool broken_views) { |
| 1166 | return FindSubresource(candidate, image, candidate_addr, options).has_value(); | 1167 | return FindSubresource(candidate, image, candidate_addr, options, broken_views).has_value(); |
| 1167 | } | 1168 | } |
| 1168 | 1169 | ||
| 1169 | void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, | 1170 | void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, |
diff --git a/src/video_core/texture_cache/util.h b/src/video_core/texture_cache/util.h index dbbbd33cd..52a9207d6 100644 --- a/src/video_core/texture_cache/util.h +++ b/src/video_core/texture_cache/util.h | |||
| @@ -87,17 +87,19 @@ void SwizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, const Ima | |||
| 87 | [[nodiscard]] std::optional<OverlapResult> ResolveOverlap(const ImageInfo& new_info, | 87 | [[nodiscard]] std::optional<OverlapResult> ResolveOverlap(const ImageInfo& new_info, |
| 88 | GPUVAddr gpu_addr, VAddr cpu_addr, | 88 | GPUVAddr gpu_addr, VAddr cpu_addr, |
| 89 | const ImageBase& overlap, | 89 | const ImageBase& overlap, |
| 90 | bool strict_size); | 90 | bool strict_size, bool broken_views); |
| 91 | 91 | ||
| 92 | [[nodiscard]] bool IsLayerStrideCompatible(const ImageInfo& lhs, const ImageInfo& rhs); | 92 | [[nodiscard]] bool IsLayerStrideCompatible(const ImageInfo& lhs, const ImageInfo& rhs); |
| 93 | 93 | ||
| 94 | [[nodiscard]] std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, | 94 | [[nodiscard]] std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, |
| 95 | const ImageBase& image, | 95 | const ImageBase& image, |
| 96 | GPUVAddr candidate_addr, | 96 | GPUVAddr candidate_addr, |
| 97 | RelaxedOptions options); | 97 | RelaxedOptions options, |
| 98 | bool broken_views); | ||
| 98 | 99 | ||
| 99 | [[nodiscard]] bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, | 100 | [[nodiscard]] bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, |
| 100 | GPUVAddr candidate_addr, RelaxedOptions options); | 101 | GPUVAddr candidate_addr, RelaxedOptions options, |
| 102 | bool broken_views); | ||
| 101 | 103 | ||
| 102 | void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, | 104 | void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, |
| 103 | const ImageBase* src); | 105 | const ImageBase* src); |