summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-06-26 19:25:49 -0300
committerGravatar ReinUsesLisp2020-06-26 20:52:22 -0300
commitbb2cbdf7047ed765c236e2da0c04420082d7fd8f (patch)
tree7ee16bceea67ccf546f263344d6b72bf157b308d
parentvideo_core/compatible_formats: Table to test if two formats are legal to view... (diff)
downloadyuzu-bb2cbdf7047ed765c236e2da0c04420082d7fd8f.tar.gz
yuzu-bb2cbdf7047ed765c236e2da0c04420082d7fd8f.tar.xz
yuzu-bb2cbdf7047ed765c236e2da0c04420082d7fd8f.zip
texture_cache: Test format compatibility before copying
Avoid illegal copies. This intercepts the last step of a copy to avoid generating validation errors or corrupting the driver on some instances. We can create views and emit copies accordingly in future commits and remove this last-step validation.
-rw-r--r--src/video_core/compatible_formats.cpp2
-rw-r--r--src/video_core/texture_cache/texture_cache.h25
2 files changed, 21 insertions, 6 deletions
diff --git a/src/video_core/compatible_formats.cpp b/src/video_core/compatible_formats.cpp
index 01e5c26ae..6c426b035 100644
--- a/src/video_core/compatible_formats.cpp
+++ b/src/video_core/compatible_formats.cpp
@@ -130,7 +130,7 @@ template <typename Range>
130void EnableRange(FormatCompatibility::Table& compatibility, const Range& range) { 130void EnableRange(FormatCompatibility::Table& compatibility, const Range& range) {
131 for (auto it_a = range.begin(); it_a != range.end(); ++it_a) { 131 for (auto it_a = range.begin(); it_a != range.end(); ++it_a) {
132 for (auto it_b = it_a; it_b != range.end(); ++it_b) { 132 for (auto it_b = it_a; it_b != range.end(); ++it_b) {
133 Enable(*it_a, *it_b); 133 Enable(compatibility, *it_a, *it_b);
134 } 134 }
135 } 135 }
136} 136}
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 85075e868..6207d8dfe 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -24,6 +24,7 @@
24#include "core/core.h" 24#include "core/core.h"
25#include "core/memory.h" 25#include "core/memory.h"
26#include "core/settings.h" 26#include "core/settings.h"
27#include "video_core/compatible_formats.h"
27#include "video_core/dirty_flags.h" 28#include "video_core/dirty_flags.h"
28#include "video_core/engines/fermi_2d.h" 29#include "video_core/engines/fermi_2d.h"
29#include "video_core/engines/maxwell_3d.h" 30#include "video_core/engines/maxwell_3d.h"
@@ -47,8 +48,8 @@ class RasterizerInterface;
47 48
48namespace VideoCommon { 49namespace VideoCommon {
49 50
51using VideoCore::Surface::FormatCompatibility;
50using VideoCore::Surface::PixelFormat; 52using VideoCore::Surface::PixelFormat;
51
52using VideoCore::Surface::SurfaceTarget; 53using VideoCore::Surface::SurfaceTarget;
53using RenderTargetConfig = Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig; 54using RenderTargetConfig = Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig;
54 55
@@ -595,7 +596,7 @@ private:
595 } else { 596 } else {
596 new_surface = GetUncachedSurface(gpu_addr, params); 597 new_surface = GetUncachedSurface(gpu_addr, params);
597 } 598 }
598 const auto& final_params = new_surface->GetSurfaceParams(); 599 const SurfaceParams& final_params = new_surface->GetSurfaceParams();
599 if (cr_params.type != final_params.type) { 600 if (cr_params.type != final_params.type) {
600 if (Settings::IsGPULevelExtreme()) { 601 if (Settings::IsGPULevelExtreme()) {
601 BufferCopy(current_surface, new_surface); 602 BufferCopy(current_surface, new_surface);
@@ -603,7 +604,7 @@ private:
603 } else { 604 } else {
604 std::vector<CopyParams> bricks = current_surface->BreakDown(final_params); 605 std::vector<CopyParams> bricks = current_surface->BreakDown(final_params);
605 for (auto& brick : bricks) { 606 for (auto& brick : bricks) {
606 ImageCopy(current_surface, new_surface, brick); 607 TryCopyImage(current_surface, new_surface, brick);
607 } 608 }
608 } 609 }
609 Unregister(current_surface); 610 Unregister(current_surface);
@@ -694,7 +695,7 @@ private:
694 } 695 }
695 const CopyParams copy_params(0, 0, 0, 0, 0, base_layer, 0, mipmap, width, height, 696 const CopyParams copy_params(0, 0, 0, 0, 0, base_layer, 0, mipmap, width, height,
696 src_params.depth); 697 src_params.depth);
697 ImageCopy(surface, new_surface, copy_params); 698 TryCopyImage(surface, new_surface, copy_params);
698 } 699 }
699 } 700 }
700 if (passed_tests == 0) { 701 if (passed_tests == 0) {
@@ -791,7 +792,7 @@ private:
791 const u32 width = params.width; 792 const u32 width = params.width;
792 const u32 height = params.height; 793 const u32 height = params.height;
793 const CopyParams copy_params(0, 0, 0, 0, 0, slice, 0, 0, width, height, 1); 794 const CopyParams copy_params(0, 0, 0, 0, 0, slice, 0, 0, width, height, 1);
794 ImageCopy(surface, new_surface, copy_params); 795 TryCopyImage(surface, new_surface, copy_params);
795 } 796 }
796 for (const auto& surface : overlaps) { 797 for (const auto& surface : overlaps) {
797 Unregister(surface); 798 Unregister(surface);
@@ -1192,6 +1193,19 @@ private:
1192 return {}; 1193 return {};
1193 } 1194 }
1194 1195
1196 /// Try to do an image copy logging when formats are incompatible.
1197 void TryCopyImage(TSurface& src, TSurface& dst, const CopyParams& copy) {
1198 const SurfaceParams& src_params = src->GetSurfaceParams();
1199 const SurfaceParams& dst_params = dst->GetSurfaceParams();
1200 if (!format_compatibility.TestCopy(src_params.pixel_format, dst_params.pixel_format)) {
1201 LOG_ERROR(HW_GPU, "Illegal copy between formats={{{}, {}}}",
1202 static_cast<int>(dst_params.pixel_format),
1203 static_cast<int>(src_params.pixel_format));
1204 return;
1205 }
1206 ImageCopy(src, dst, copy);
1207 }
1208
1195 constexpr PixelFormat GetSiblingFormat(PixelFormat format) const { 1209 constexpr PixelFormat GetSiblingFormat(PixelFormat format) const {
1196 return siblings_table[static_cast<std::size_t>(format)]; 1210 return siblings_table[static_cast<std::size_t>(format)];
1197 } 1211 }
@@ -1241,6 +1255,7 @@ private:
1241 VideoCore::RasterizerInterface& rasterizer; 1255 VideoCore::RasterizerInterface& rasterizer;
1242 1256
1243 FormatLookupTable format_lookup_table; 1257 FormatLookupTable format_lookup_table;
1258 FormatCompatibility format_compatibility;
1244 1259
1245 u64 ticks{}; 1260 u64 ticks{};
1246 1261