diff options
| author | 2019-05-08 18:27:29 -0400 | |
|---|---|---|
| committer | 2019-06-20 21:36:12 -0300 | |
| commit | b347543e8341ae323ea232d47df2c144fe21c739 (patch) | |
| tree | ca0e48c61dea6e78b073a885ec4e5f96755f7cc1 /src | |
| parent | texture_cache: Correct premature texceptions (diff) | |
| download | yuzu-b347543e8341ae323ea232d47df2c144fe21c739.tar.gz yuzu-b347543e8341ae323ea232d47df2c144fe21c739.tar.xz yuzu-b347543e8341ae323ea232d47df2c144fe21c739.zip | |
Reduce amount of size calculations.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/common_funcs.h | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/surface_base.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/texture_cache/surface_base.h | 28 | ||||
| -rw-r--r-- | src/video_core/texture_cache/surface_params.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/texture_cache/surface_params.h | 50 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 40 |
8 files changed, 97 insertions, 88 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 8b0d34da6..00a5698f3 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <algorithm> | ||
| 7 | #include <string> | 8 | #include <string> |
| 8 | 9 | ||
| 9 | #if !defined(ARCHITECTURE_x86_64) | 10 | #if !defined(ARCHITECTURE_x86_64) |
| @@ -60,4 +61,14 @@ constexpr u32 MakeMagic(char a, char b, char c, char d) { | |||
| 60 | return a | b << 8 | c << 16 | d << 24; | 61 | return a | b << 8 | c << 16 | d << 24; |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 64 | template <class ForwardIt, class T, class Compare = std::less<>> | ||
| 65 | ForwardIt BinaryFind(ForwardIt first, ForwardIt last, const T& value, Compare comp = {}) { | ||
| 66 | // Note: BOTH type T and the type after ForwardIt is dereferenced | ||
| 67 | // must be implicitly convertible to BOTH Type1 and Type2, used in Compare. | ||
| 68 | // This is stricter than lower_bound requirement (see above) | ||
| 69 | |||
| 70 | first = std::lower_bound(first, last, value, comp); | ||
| 71 | return first != last && !comp(value, *first) ? first : last; | ||
| 72 | } | ||
| 73 | |||
| 63 | } // namespace Common | 74 | } // namespace Common |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index a58e3a816..32cb08963 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -240,7 +240,6 @@ CachedSurface::~CachedSurface() { | |||
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { | 242 | void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { |
| 243 | LOG_CRITICAL(Render_OpenGL, "Flushing"); | ||
| 244 | MICROPROFILE_SCOPE(OpenGL_Texture_Download); | 243 | MICROPROFILE_SCOPE(OpenGL_Texture_Download); |
| 245 | 244 | ||
| 246 | // TODO(Rodrigo): Optimize alignment | 245 | // TODO(Rodrigo): Optimize alignment |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 1ad01137b..0a1b57014 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -133,7 +133,7 @@ protected: | |||
| 133 | const VideoCommon::CopyParams& copy_params) override; | 133 | const VideoCommon::CopyParams& copy_params) override; |
| 134 | 134 | ||
| 135 | void ImageBlit(Surface src_surface, Surface dst_surface, const Common::Rectangle<u32>& src_rect, | 135 | void ImageBlit(Surface src_surface, Surface dst_surface, const Common::Rectangle<u32>& src_rect, |
| 136 | const Common::Rectangle<u32>& dst_rect) override; | 136 | const Common::Rectangle<u32>& dst_rect) override; |
| 137 | 137 | ||
| 138 | private: | 138 | private: |
| 139 | OGLFramebuffer src_framebuffer; | 139 | OGLFramebuffer src_framebuffer; |
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index dc5013240..36ca72b4a 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp | |||
| @@ -19,19 +19,27 @@ using Tegra::Texture::ConvertFromGuestToHost; | |||
| 19 | using VideoCore::MortonSwizzleMode; | 19 | using VideoCore::MortonSwizzleMode; |
| 20 | 20 | ||
| 21 | SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) | 21 | SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) |
| 22 | : params{params}, gpu_addr{gpu_addr}, layer_size{params.GetGuestLayerSize()}, | 22 | : params{params}, mipmap_sizes(params.num_levels), |
| 23 | guest_memory_size{params.GetGuestSizeInBytes()}, host_memory_size{ | 23 | mipmap_offsets(params.num_levels), gpu_addr{gpu_addr}, host_memory_size{ |
| 24 | params.GetHostSizeInBytes()} { | 24 | params.GetHostSizeInBytes()} { |
| 25 | mipmap_offsets.reserve(params.num_levels); | ||
| 26 | mipmap_sizes.reserve(params.num_levels); | ||
| 27 | 25 | ||
| 28 | std::size_t offset = 0; | 26 | std::size_t offset = 0; |
| 29 | for (u32 level = 0; level < params.num_levels; ++level) { | 27 | for (u32 level = 0; level < params.num_levels; ++level) { |
| 30 | const std::size_t mipmap_size{params.GetGuestMipmapSize(level)}; | 28 | const std::size_t mipmap_size{params.GetGuestMipmapSize(level)}; |
| 31 | mipmap_sizes.push_back(mipmap_size); | 29 | mipmap_sizes[level] = mipmap_size; |
| 32 | mipmap_offsets.push_back(offset); | 30 | mipmap_offsets[level] = offset; |
| 33 | offset += mipmap_size; | 31 | offset += mipmap_size; |
| 34 | } | 32 | } |
| 33 | layer_size = offset; | ||
| 34 | if (params.is_layered) { | ||
| 35 | if (params.is_tiled) { | ||
| 36 | layer_size = | ||
| 37 | SurfaceParams::AlignLayered(layer_size, params.block_height, params.block_depth); | ||
| 38 | } | ||
| 39 | guest_memory_size = layer_size * params.depth; | ||
| 40 | } else { | ||
| 41 | guest_memory_size = layer_size; | ||
| 42 | } | ||
| 35 | } | 43 | } |
| 36 | 44 | ||
| 37 | void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const SurfaceParams& params, | 45 | void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const SurfaceParams& params, |
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index 179e80ddb..095deb602 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | 10 | ||
| 11 | #include "common/assert.h" | 11 | #include "common/assert.h" |
| 12 | #include "common/common_funcs.h" | ||
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | #include "video_core/gpu.h" | 14 | #include "video_core/gpu.h" |
| 14 | #include "video_core/morton.h" | 15 | #include "video_core/morton.h" |
| @@ -16,16 +17,6 @@ | |||
| 16 | #include "video_core/texture_cache/surface_params.h" | 17 | #include "video_core/texture_cache/surface_params.h" |
| 17 | #include "video_core/texture_cache/surface_view.h" | 18 | #include "video_core/texture_cache/surface_view.h" |
| 18 | 19 | ||
| 19 | template <class ForwardIt, class T, class Compare = std::less<>> | ||
| 20 | ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare comp = {}) { | ||
| 21 | // Note: BOTH type T and the type after ForwardIt is dereferenced | ||
| 22 | // must be implicitly convertible to BOTH Type1 and Type2, used in Compare. | ||
| 23 | // This is stricter than lower_bound requirement (see above) | ||
| 24 | |||
| 25 | first = std::lower_bound(first, last, value, comp); | ||
| 26 | return first != last && !comp(value, *first) ? first : last; | ||
| 27 | } | ||
| 28 | |||
| 29 | namespace Tegra { | 20 | namespace Tegra { |
| 30 | class MemoryManager; | 21 | class MemoryManager; |
| 31 | } | 22 | } |
| @@ -153,7 +144,7 @@ public: | |||
| 153 | const auto layer{static_cast<u32>(relative_address / layer_size)}; | 144 | const auto layer{static_cast<u32>(relative_address / layer_size)}; |
| 154 | const GPUVAddr mipmap_address = relative_address - layer_size * layer; | 145 | const GPUVAddr mipmap_address = relative_address - layer_size * layer; |
| 155 | const auto mipmap_it = | 146 | const auto mipmap_it = |
| 156 | binary_find(mipmap_offsets.begin(), mipmap_offsets.end(), mipmap_address); | 147 | Common::BinaryFind(mipmap_offsets.begin(), mipmap_offsets.end(), mipmap_address); |
| 157 | if (mipmap_it == mipmap_offsets.end()) { | 148 | if (mipmap_it == mipmap_offsets.end()) { |
| 158 | return {}; | 149 | return {}; |
| 159 | } | 150 | } |
| @@ -172,8 +163,8 @@ protected: | |||
| 172 | virtual void DecorateSurfaceName() = 0; | 163 | virtual void DecorateSurfaceName() = 0; |
| 173 | 164 | ||
| 174 | const SurfaceParams params; | 165 | const SurfaceParams params; |
| 175 | const std::size_t layer_size; | 166 | std::size_t layer_size; |
| 176 | const std::size_t guest_memory_size; | 167 | std::size_t guest_memory_size; |
| 177 | const std::size_t host_memory_size; | 168 | const std::size_t host_memory_size; |
| 178 | GPUVAddr gpu_addr{}; | 169 | GPUVAddr gpu_addr{}; |
| 179 | CacheAddr cache_addr{}; | 170 | CacheAddr cache_addr{}; |
| @@ -268,9 +259,11 @@ public: | |||
| 268 | return GetView(ViewParams(overview_params.target, 0, num_layers, 0, params.num_levels)); | 259 | return GetView(ViewParams(overview_params.target, 0, num_layers, 0, params.num_levels)); |
| 269 | } | 260 | } |
| 270 | 261 | ||
| 271 | std::optional<TView> EmplaceView(const SurfaceParams& view_params, const GPUVAddr view_addr) { | 262 | std::optional<TView> EmplaceView(const SurfaceParams& view_params, const GPUVAddr view_addr, |
| 272 | if (view_addr < gpu_addr || params.target == SurfaceTarget::Texture3D || | 263 | const std::size_t candidate_size) { |
| 273 | params.num_levels == 1 || view_params.target == SurfaceTarget::Texture3D) { | 264 | if (params.target == SurfaceTarget::Texture3D || |
| 265 | (params.num_levels == 1 && !params.is_layered) || | ||
| 266 | view_params.target == SurfaceTarget::Texture3D) { | ||
| 274 | return {}; | 267 | return {}; |
| 275 | } | 268 | } |
| 276 | const auto layer_mipmap{GetLayerMipmap(view_addr)}; | 269 | const auto layer_mipmap{GetLayerMipmap(view_addr)}; |
| @@ -279,8 +272,7 @@ public: | |||
| 279 | } | 272 | } |
| 280 | const u32 layer{layer_mipmap->first}; | 273 | const u32 layer{layer_mipmap->first}; |
| 281 | const u32 mipmap{layer_mipmap->second}; | 274 | const u32 mipmap{layer_mipmap->second}; |
| 282 | const std::size_t size{view_params.GetGuestSizeInBytes()}; | 275 | if (GetMipmapSize(mipmap) != candidate_size) { |
| 283 | if (GetMipmapSize(mipmap) != size) { | ||
| 284 | // TODO: The view may cover many mimaps, this case can still go on. | 276 | // TODO: The view may cover many mimaps, this case can still go on. |
| 285 | // This edge-case can be safely be ignored since it will just result in worse | 277 | // This edge-case can be safely be ignored since it will just result in worse |
| 286 | // performance. | 278 | // performance. |
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index d9052152c..b537b26e2 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp | |||
| @@ -4,13 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #include <map> | 5 | #include <map> |
| 6 | 6 | ||
| 7 | #include "common/cityhash.h" | ||
| 8 | #include "common/alignment.h" | 7 | #include "common/alignment.h" |
| 8 | #include "common/cityhash.h" | ||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "video_core/engines/shader_bytecode.h" | 10 | #include "video_core/engines/shader_bytecode.h" |
| 11 | #include "video_core/surface.h" | 11 | #include "video_core/surface.h" |
| 12 | #include "video_core/texture_cache/surface_params.h" | 12 | #include "video_core/texture_cache/surface_params.h" |
| 13 | #include "video_core/textures/decoders.h" | ||
| 14 | 13 | ||
| 15 | namespace VideoCommon { | 14 | namespace VideoCommon { |
| 16 | 15 | ||
| @@ -169,18 +168,6 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( | |||
| 169 | return params; | 168 | return params; |
| 170 | } | 169 | } |
| 171 | 170 | ||
| 172 | u32 SurfaceParams::GetMipWidth(u32 level) const { | ||
| 173 | return std::max(1U, width >> level); | ||
| 174 | } | ||
| 175 | |||
| 176 | u32 SurfaceParams::GetMipHeight(u32 level) const { | ||
| 177 | return std::max(1U, height >> level); | ||
| 178 | } | ||
| 179 | |||
| 180 | u32 SurfaceParams::GetMipDepth(u32 level) const { | ||
| 181 | return is_layered ? depth : std::max(1U, depth >> level); | ||
| 182 | } | ||
| 183 | |||
| 184 | bool SurfaceParams::IsLayered() const { | 171 | bool SurfaceParams::IsLayered() const { |
| 185 | switch (target) { | 172 | switch (target) { |
| 186 | case SurfaceTarget::Texture1DArray: | 173 | case SurfaceTarget::Texture1DArray: |
| @@ -275,22 +262,6 @@ std::size_t SurfaceParams::GetHostLayerSize(u32 level) const { | |||
| 275 | return GetInnerMipmapMemorySize(level, true, false); | 262 | return GetInnerMipmapMemorySize(level, true, false); |
| 276 | } | 263 | } |
| 277 | 264 | ||
| 278 | u32 SurfaceParams::GetDefaultBlockWidth() const { | ||
| 279 | return VideoCore::Surface::GetDefaultBlockWidth(pixel_format); | ||
| 280 | } | ||
| 281 | |||
| 282 | u32 SurfaceParams::GetDefaultBlockHeight() const { | ||
| 283 | return VideoCore::Surface::GetDefaultBlockHeight(pixel_format); | ||
| 284 | } | ||
| 285 | |||
| 286 | u32 SurfaceParams::GetBitsPerPixel() const { | ||
| 287 | return VideoCore::Surface::GetFormatBpp(pixel_format); | ||
| 288 | } | ||
| 289 | |||
| 290 | u32 SurfaceParams::GetBytesPerPixel() const { | ||
| 291 | return VideoCore::Surface::GetBytesPerPixel(pixel_format); | ||
| 292 | } | ||
| 293 | |||
| 294 | bool SurfaceParams::IsPixelFormatZeta() const { | 265 | bool SurfaceParams::IsPixelFormatZeta() const { |
| 295 | return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && | 266 | return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && |
| 296 | pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; | 267 | pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; |
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h index ec8efa210..e0ec1be0e 100644 --- a/src/video_core/texture_cache/surface_params.h +++ b/src/video_core/texture_cache/surface_params.h | |||
| @@ -10,8 +10,9 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "video_core/engines/fermi_2d.h" | 11 | #include "video_core/engines/fermi_2d.h" |
| 12 | #include "video_core/engines/maxwell_3d.h" | 12 | #include "video_core/engines/maxwell_3d.h" |
| 13 | #include "video_core/surface.h" | ||
| 14 | #include "video_core/shader/shader_ir.h" | 13 | #include "video_core/shader/shader_ir.h" |
| 14 | #include "video_core/surface.h" | ||
| 15 | #include "video_core/textures/decoders.h" | ||
| 15 | 16 | ||
| 16 | namespace VideoCommon { | 17 | namespace VideoCommon { |
| 17 | 18 | ||
| @@ -50,10 +51,17 @@ public: | |||
| 50 | std::size_t GetHostSizeInBytes() const { | 51 | std::size_t GetHostSizeInBytes() const { |
| 51 | std::size_t host_size_in_bytes; | 52 | std::size_t host_size_in_bytes; |
| 52 | if (IsPixelFormatASTC(pixel_format)) { | 53 | if (IsPixelFormatASTC(pixel_format)) { |
| 54 | constexpr std::size_t rgb8_bpp = 4ULL; | ||
| 53 | // ASTC is uncompressed in software, in emulated as RGBA8 | 55 | // ASTC is uncompressed in software, in emulated as RGBA8 |
| 54 | host_size_in_bytes = static_cast<std::size_t>(Common::AlignUp(width, GetDefaultBlockWidth())) * | 56 | host_size_in_bytes = 0; |
| 55 | static_cast<std::size_t>(Common::AlignUp(height, GetDefaultBlockHeight())) * | 57 | for (std::size_t level = 0; level < num_levels; level++) { |
| 56 | static_cast<std::size_t>(depth) * 4ULL; | 58 | const std::size_t width = |
| 59 | Common::AlignUp(GetMipWidth(level), GetDefaultBlockWidth()); | ||
| 60 | const std::size_t height = | ||
| 61 | Common::AlignUp(GetMipHeight(level), GetDefaultBlockHeight()); | ||
| 62 | const std::size_t depth = is_layered ? depth : GetMipDepth(level); | ||
| 63 | host_size_in_bytes += width * height * depth * rgb8_bpp; | ||
| 64 | } | ||
| 57 | } else { | 65 | } else { |
| 58 | host_size_in_bytes = GetInnerMemorySize(true, false, false); | 66 | host_size_in_bytes = GetInnerMemorySize(true, false, false); |
| 59 | } | 67 | } |
| @@ -65,13 +73,19 @@ public: | |||
| 65 | } | 73 | } |
| 66 | 74 | ||
| 67 | /// Returns the width of a given mipmap level. | 75 | /// Returns the width of a given mipmap level. |
| 68 | u32 GetMipWidth(u32 level) const; | 76 | u32 GetMipWidth(u32 level) const { |
| 77 | return std::max(1U, width >> level); | ||
| 78 | } | ||
| 69 | 79 | ||
| 70 | /// Returns the height of a given mipmap level. | 80 | /// Returns the height of a given mipmap level. |
| 71 | u32 GetMipHeight(u32 level) const; | 81 | u32 GetMipHeight(u32 level) const { |
| 82 | return std::max(1U, height >> level); | ||
| 83 | } | ||
| 72 | 84 | ||
| 73 | /// Returns the depth of a given mipmap level. | 85 | /// Returns the depth of a given mipmap level. |
| 74 | u32 GetMipDepth(u32 level) const; | 86 | u32 GetMipDepth(u32 level) const { |
| 87 | return is_layered ? depth : std::max(1U, depth >> level); | ||
| 88 | } | ||
| 75 | 89 | ||
| 76 | /// Returns the block height of a given mipmap level. | 90 | /// Returns the block height of a given mipmap level. |
| 77 | u32 GetMipBlockHeight(u32 level) const; | 91 | u32 GetMipBlockHeight(u32 level) const; |
| @@ -79,6 +93,12 @@ public: | |||
| 79 | /// Returns the block depth of a given mipmap level. | 93 | /// Returns the block depth of a given mipmap level. |
| 80 | u32 GetMipBlockDepth(u32 level) const; | 94 | u32 GetMipBlockDepth(u32 level) const; |
| 81 | 95 | ||
| 96 | // Helper used for out of class size calculations | ||
| 97 | static std::size_t AlignLayered(const std::size_t out_size, const u32 block_height, | ||
| 98 | const u32 block_depth) { | ||
| 99 | return Common::AlignUp(out_size, Tegra::Texture::GetGOBSize() * block_height * block_depth); | ||
| 100 | } | ||
| 101 | |||
| 82 | /// Returns the offset in bytes in guest memory of a given mipmap level. | 102 | /// Returns the offset in bytes in guest memory of a given mipmap level. |
| 83 | std::size_t GetGuestMipmapLevelOffset(u32 level) const; | 103 | std::size_t GetGuestMipmapLevelOffset(u32 level) const; |
| 84 | 104 | ||
| @@ -98,16 +118,24 @@ public: | |||
| 98 | std::size_t GetHostLayerSize(u32 level) const; | 118 | std::size_t GetHostLayerSize(u32 level) const; |
| 99 | 119 | ||
| 100 | /// Returns the default block width. | 120 | /// Returns the default block width. |
| 101 | u32 GetDefaultBlockWidth() const; | 121 | u32 GetDefaultBlockWidth() const { |
| 122 | return VideoCore::Surface::GetDefaultBlockWidth(pixel_format); | ||
| 123 | } | ||
| 102 | 124 | ||
| 103 | /// Returns the default block height. | 125 | /// Returns the default block height. |
| 104 | u32 GetDefaultBlockHeight() const; | 126 | u32 GetDefaultBlockHeight() const { |
| 127 | return VideoCore::Surface::GetDefaultBlockHeight(pixel_format); | ||
| 128 | } | ||
| 105 | 129 | ||
| 106 | /// Returns the bits per pixel. | 130 | /// Returns the bits per pixel. |
| 107 | u32 GetBitsPerPixel() const; | 131 | u32 GetBitsPerPixel() const { |
| 132 | return VideoCore::Surface::GetFormatBpp(pixel_format); | ||
| 133 | } | ||
| 108 | 134 | ||
| 109 | /// Returns the bytes per pixel. | 135 | /// Returns the bytes per pixel. |
| 110 | u32 GetBytesPerPixel() const; | 136 | u32 GetBytesPerPixel() const { |
| 137 | return VideoCore::Surface::GetBytesPerPixel(pixel_format); | ||
| 138 | } | ||
| 111 | 139 | ||
| 112 | /// Returns true if the pixel format is a depth and/or stencil format. | 140 | /// Returns true if the pixel format is a depth and/or stencil format. |
| 113 | bool IsPixelFormatZeta() const; | 141 | bool IsPixelFormatZeta() const; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 96d108147..fbfd1ff0b 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -120,10 +120,6 @@ public: | |||
| 120 | return {}; | 120 | return {}; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | if (regs.color_mask[index].raw == 0) { | ||
| 124 | return {}; | ||
| 125 | } | ||
| 126 | |||
| 127 | auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index), | 123 | auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index), |
| 128 | preserve_contents); | 124 | preserve_contents); |
| 129 | if (render_targets[index].target) | 125 | if (render_targets[index].target) |
| @@ -165,7 +161,9 @@ public: | |||
| 165 | const Tegra::Engines::Fermi2D::Regs::Surface& dst_config, | 161 | const Tegra::Engines::Fermi2D::Regs::Surface& dst_config, |
| 166 | const Common::Rectangle<u32>& src_rect, | 162 | const Common::Rectangle<u32>& src_rect, |
| 167 | const Common::Rectangle<u32>& dst_rect) { | 163 | const Common::Rectangle<u32>& dst_rect) { |
| 168 | ImageBlit(GetFermiSurface(src_config), GetFermiSurface(dst_config), src_rect, dst_rect); | 164 | TSurface dst_surface = GetFermiSurface(dst_config); |
| 165 | ImageBlit(GetFermiSurface(src_config), dst_surface, src_rect, dst_rect); | ||
| 166 | dst_surface->MarkAsModified(true, Tick()); | ||
| 169 | } | 167 | } |
| 170 | 168 | ||
| 171 | TSurface TryFindFramebufferSurface(const u8* host_ptr) { | 169 | TSurface TryFindFramebufferSurface(const u8* host_ptr) { |
| @@ -270,10 +268,6 @@ private: | |||
| 270 | 268 | ||
| 271 | RecycleStrategy PickStrategy(std::vector<TSurface>& overlaps, const SurfaceParams& params, | 269 | RecycleStrategy PickStrategy(std::vector<TSurface>& overlaps, const SurfaceParams& params, |
| 272 | const GPUVAddr gpu_addr, const bool untopological) { | 270 | const GPUVAddr gpu_addr, const bool untopological) { |
| 273 | // Untopological decision | ||
| 274 | if (untopological) { | ||
| 275 | return RecycleStrategy::Ignore; | ||
| 276 | } | ||
| 277 | // 3D Textures decision | 271 | // 3D Textures decision |
| 278 | if (params.block_depth > 1 || params.target == SurfaceTarget::Texture3D) { | 272 | if (params.block_depth > 1 || params.target == SurfaceTarget::Texture3D) { |
| 279 | return RecycleStrategy::Flush; | 273 | return RecycleStrategy::Flush; |
| @@ -284,12 +278,16 @@ private: | |||
| 284 | return RecycleStrategy::Flush; | 278 | return RecycleStrategy::Flush; |
| 285 | } | 279 | } |
| 286 | } | 280 | } |
| 281 | // Untopological decision | ||
| 282 | if (untopological) { | ||
| 283 | return RecycleStrategy::Ignore; | ||
| 284 | } | ||
| 287 | return RecycleStrategy::Ignore; | 285 | return RecycleStrategy::Ignore; |
| 288 | } | 286 | } |
| 289 | 287 | ||
| 290 | std::pair<TSurface, TView> RecycleSurface(std::vector<TSurface>& overlaps, | 288 | std::pair<TSurface, TView> RecycleSurface(std::vector<TSurface>& overlaps, |
| 291 | const SurfaceParams& params, const GPUVAddr gpu_addr, | 289 | const SurfaceParams& params, const GPUVAddr gpu_addr, |
| 292 | const u8* host_ptr, const bool preserve_contents, | 290 | const bool preserve_contents, |
| 293 | const bool untopological) { | 291 | const bool untopological) { |
| 294 | for (auto surface : overlaps) { | 292 | for (auto surface : overlaps) { |
| 295 | Unregister(surface); | 293 | Unregister(surface); |
| @@ -328,6 +326,7 @@ private: | |||
| 328 | } | 326 | } |
| 329 | Unregister(current_surface); | 327 | Unregister(current_surface); |
| 330 | Register(new_surface); | 328 | Register(new_surface); |
| 329 | new_surface->MarkAsModified(current_surface->IsModified(), Tick()); | ||
| 331 | return {new_surface, new_surface->GetMainView()}; | 330 | return {new_surface, new_surface->GetMainView()}; |
| 332 | } | 331 | } |
| 333 | 332 | ||
| @@ -351,6 +350,7 @@ private: | |||
| 351 | if (params.target == SurfaceTarget::Texture3D) { | 350 | if (params.target == SurfaceTarget::Texture3D) { |
| 352 | return {}; | 351 | return {}; |
| 353 | } | 352 | } |
| 353 | bool modified = false; | ||
| 354 | TSurface new_surface = GetUncachedSurface(gpu_addr, params); | 354 | TSurface new_surface = GetUncachedSurface(gpu_addr, params); |
| 355 | for (auto surface : overlaps) { | 355 | for (auto surface : overlaps) { |
| 356 | const SurfaceParams& src_params = surface->GetSurfaceParams(); | 356 | const SurfaceParams& src_params = surface->GetSurfaceParams(); |
| @@ -358,7 +358,7 @@ private: | |||
| 358 | // We send this cases to recycle as they are more complex to handle | 358 | // We send this cases to recycle as they are more complex to handle |
| 359 | return {}; | 359 | return {}; |
| 360 | } | 360 | } |
| 361 | const std::size_t candidate_size = src_params.GetGuestSizeInBytes(); | 361 | const std::size_t candidate_size = surface->GetSizeInBytes(); |
| 362 | auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())}; | 362 | auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())}; |
| 363 | if (!mipmap_layer) { | 363 | if (!mipmap_layer) { |
| 364 | return {}; | 364 | return {}; |
| @@ -368,6 +368,7 @@ private: | |||
| 368 | if (new_surface->GetMipmapSize(mipmap) != candidate_size) { | 368 | if (new_surface->GetMipmapSize(mipmap) != candidate_size) { |
| 369 | return {}; | 369 | return {}; |
| 370 | } | 370 | } |
| 371 | modified |= surface->IsModified(); | ||
| 371 | // Now we got all the data set up | 372 | // Now we got all the data set up |
| 372 | const u32 dst_width{params.GetMipWidth(mipmap)}; | 373 | const u32 dst_width{params.GetMipWidth(mipmap)}; |
| 373 | const u32 dst_height{params.GetMipHeight(mipmap)}; | 374 | const u32 dst_height{params.GetMipHeight(mipmap)}; |
| @@ -381,6 +382,7 @@ private: | |||
| 381 | force_reconfiguration |= surface->IsProtected(); | 382 | force_reconfiguration |= surface->IsProtected(); |
| 382 | Unregister(surface, true); | 383 | Unregister(surface, true); |
| 383 | } | 384 | } |
| 385 | new_surface->MarkAsModified(modified, Tick()); | ||
| 384 | Register(new_surface); | 386 | Register(new_surface); |
| 385 | return {{new_surface, new_surface->GetMainView()}}; | 387 | return {{new_surface, new_surface->GetMainView()}}; |
| 386 | } | 388 | } |
| @@ -399,8 +401,7 @@ private: | |||
| 399 | 401 | ||
| 400 | for (auto surface : overlaps) { | 402 | for (auto surface : overlaps) { |
| 401 | if (!surface->MatchesTopology(params)) { | 403 | if (!surface->MatchesTopology(params)) { |
| 402 | return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, | 404 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, true); |
| 403 | true); | ||
| 404 | } | 405 | } |
| 405 | } | 406 | } |
| 406 | 407 | ||
| @@ -418,27 +419,26 @@ private: | |||
| 418 | } | 419 | } |
| 419 | } | 420 | } |
| 420 | if (!current_surface->IsInside(gpu_addr, gpu_addr + candidate_size)) { | 421 | if (!current_surface->IsInside(gpu_addr, gpu_addr + candidate_size)) { |
| 421 | return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, | 422 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false); |
| 422 | false); | ||
| 423 | } | 423 | } |
| 424 | std::optional<TView> view = current_surface->EmplaceView(params, gpu_addr); | 424 | std::optional<TView> view = |
| 425 | current_surface->EmplaceView(params, gpu_addr, candidate_size); | ||
| 425 | if (view.has_value()) { | 426 | if (view.has_value()) { |
| 426 | const bool is_mirage = !current_surface->MatchFormat(params.pixel_format); | 427 | const bool is_mirage = !current_surface->MatchFormat(params.pixel_format); |
| 427 | if (is_mirage) { | 428 | if (is_mirage) { |
| 428 | LOG_CRITICAL(HW_GPU, "Mirage View Unsupported"); | 429 | LOG_CRITICAL(HW_GPU, "Mirage View Unsupported"); |
| 429 | return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, | 430 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false); |
| 430 | false); | ||
| 431 | } | 431 | } |
| 432 | return {current_surface, *view}; | 432 | return {current_surface, *view}; |
| 433 | } | 433 | } |
| 434 | return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, false); | 434 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false); |
| 435 | } else { | 435 | } else { |
| 436 | std::optional<std::pair<TSurface, TView>> view = | 436 | std::optional<std::pair<TSurface, TView>> view = |
| 437 | ReconstructSurface(overlaps, params, gpu_addr, host_ptr); | 437 | ReconstructSurface(overlaps, params, gpu_addr, host_ptr); |
| 438 | if (view.has_value()) { | 438 | if (view.has_value()) { |
| 439 | return *view; | 439 | return *view; |
| 440 | } | 440 | } |
| 441 | return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, false); | 441 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false); |
| 442 | } | 442 | } |
| 443 | } | 443 | } |
| 444 | 444 | ||