summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-03-14 20:24:54 -0300
committerGravatar ReinUsesLisp2020-04-01 01:14:04 -0300
commitb6571ca9f0be7799856cce76363ab752f478fb4b (patch)
tree2f4de71c3540eb1d8d159b0233bebb3fa04d2e6e /src/video_core/texture_cache
parentgl_device: Detect if ASTC is reported and expose it (diff)
downloadyuzu-b6571ca9f0be7799856cce76363ab752f478fb4b.tar.gz
yuzu-b6571ca9f0be7799856cce76363ab752f478fb4b.tar.xz
yuzu-b6571ca9f0be7799856cce76363ab752f478fb4b.zip
video_core: Use native ASTC when available
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/surface_base.cpp39
-rw-r--r--src/video_core/texture_cache/surface_base.h15
-rw-r--r--src/video_core/texture_cache/surface_params.cpp28
-rw-r--r--src/video_core/texture_cache/surface_params.h36
-rw-r--r--src/video_core/texture_cache/texture_cache.h6
5 files changed, 59 insertions, 65 deletions
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp
index 002df414f..6fe815135 100644
--- a/src/video_core/texture_cache/surface_base.cpp
+++ b/src/video_core/texture_cache/surface_base.cpp
@@ -18,15 +18,20 @@ MICROPROFILE_DEFINE(GPU_Flush_Texture, "GPU", "Texture Flush", MP_RGB(128, 192,
18 18
19using Tegra::Texture::ConvertFromGuestToHost; 19using Tegra::Texture::ConvertFromGuestToHost;
20using VideoCore::MortonSwizzleMode; 20using VideoCore::MortonSwizzleMode;
21using VideoCore::Surface::SurfaceCompression; 21using VideoCore::Surface::IsPixelFormatASTC;
22using VideoCore::Surface::PixelFormat;
22 23
23StagingCache::StagingCache() = default; 24StagingCache::StagingCache() = default;
24 25
25StagingCache::~StagingCache() = default; 26StagingCache::~StagingCache() = default;
26 27
27SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) 28SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params,
28 : params{params}, host_memory_size{params.GetHostSizeInBytes()}, gpu_addr{gpu_addr}, 29 bool is_astc_supported)
29 mipmap_sizes(params.num_levels), mipmap_offsets(params.num_levels) { 30 : params{params}, gpu_addr{gpu_addr}, mipmap_sizes(params.num_levels),
31 mipmap_offsets(params.num_levels) {
32 is_converted = IsPixelFormatASTC(params.pixel_format) && !is_astc_supported;
33 host_memory_size = params.GetHostSizeInBytes(is_converted);
34
30 std::size_t offset = 0; 35 std::size_t offset = 0;
31 for (u32 level = 0; level < params.num_levels; ++level) { 36 for (u32 level = 0; level < params.num_levels; ++level) {
32 const std::size_t mipmap_size{params.GetGuestMipmapSize(level)}; 37 const std::size_t mipmap_size{params.GetGuestMipmapSize(level)};
@@ -164,7 +169,7 @@ void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const Surf
164 169
165 std::size_t guest_offset{mipmap_offsets[level]}; 170 std::size_t guest_offset{mipmap_offsets[level]};
166 if (params.is_layered) { 171 if (params.is_layered) {
167 std::size_t host_offset{0}; 172 std::size_t host_offset = 0;
168 const std::size_t guest_stride = layer_size; 173 const std::size_t guest_stride = layer_size;
169 const std::size_t host_stride = params.GetHostLayerSize(level); 174 const std::size_t host_stride = params.GetHostLayerSize(level);
170 for (u32 layer = 0; layer < params.depth; ++layer) { 175 for (u32 layer = 0; layer < params.depth; ++layer) {
@@ -206,7 +211,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
206 ASSERT_MSG(params.block_width == 0, "Block width is defined as {} on texture target {}", 211 ASSERT_MSG(params.block_width == 0, "Block width is defined as {} on texture target {}",
207 params.block_width, static_cast<u32>(params.target)); 212 params.block_width, static_cast<u32>(params.target));
208 for (u32 level = 0; level < params.num_levels; ++level) { 213 for (u32 level = 0; level < params.num_levels; ++level) {
209 const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)}; 214 const std::size_t host_offset{params.GetHostMipmapLevelOffset(level, false)};
210 SwizzleFunc(MortonSwizzleMode::MortonToLinear, host_ptr, params, 215 SwizzleFunc(MortonSwizzleMode::MortonToLinear, host_ptr, params,
211 staging_buffer.data() + host_offset, level); 216 staging_buffer.data() + host_offset, level);
212 } 217 }
@@ -219,7 +224,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
219 const u32 height{(params.height + block_height - 1) / block_height}; 224 const u32 height{(params.height + block_height - 1) / block_height};
220 const u32 copy_size{width * bpp}; 225 const u32 copy_size{width * bpp};
221 if (params.pitch == copy_size) { 226 if (params.pitch == copy_size) {
222 std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes()); 227 std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes(false));
223 } else { 228 } else {
224 const u8* start{host_ptr}; 229 const u8* start{host_ptr};
225 u8* write_to{staging_buffer.data()}; 230 u8* write_to{staging_buffer.data()};
@@ -231,19 +236,15 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
231 } 236 }
232 } 237 }
233 238
234 auto compression_type = params.GetCompressionType(); 239 if (!is_converted && params.pixel_format != PixelFormat::S8Z24) {
235 if (compression_type == SurfaceCompression::None ||
236 compression_type == SurfaceCompression::Compressed)
237 return; 240 return;
241 }
238 242
239 for (u32 level_up = params.num_levels; level_up > 0; --level_up) { 243 for (u32 level = params.num_levels; level--;) {
240 const u32 level = level_up - 1; 244 const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level, false)};
241 const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level)}; 245 const std::size_t out_host_offset{params.GetHostMipmapLevelOffset(level, is_converted)};
242 const std::size_t out_host_offset = compression_type == SurfaceCompression::Rearranged 246 u8* const in_buffer = staging_buffer.data() + in_host_offset;
243 ? in_host_offset 247 u8* const out_buffer = staging_buffer.data() + out_host_offset;
244 : params.GetConvertedMipmapOffset(level);
245 u8* in_buffer = staging_buffer.data() + in_host_offset;
246 u8* out_buffer = staging_buffer.data() + out_host_offset;
247 ConvertFromGuestToHost(in_buffer, out_buffer, params.pixel_format, 248 ConvertFromGuestToHost(in_buffer, out_buffer, params.pixel_format,
248 params.GetMipWidth(level), params.GetMipHeight(level), 249 params.GetMipWidth(level), params.GetMipHeight(level),
249 params.GetMipDepth(level), true, true); 250 params.GetMipDepth(level), true, true);
@@ -273,7 +274,7 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
273 if (params.is_tiled) { 274 if (params.is_tiled) {
274 ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width); 275 ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width);
275 for (u32 level = 0; level < params.num_levels; ++level) { 276 for (u32 level = 0; level < params.num_levels; ++level) {
276 const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)}; 277 const std::size_t host_offset{params.GetHostMipmapLevelOffset(level, false)};
277 SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params, 278 SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params,
278 staging_buffer.data() + host_offset, level); 279 staging_buffer.data() + host_offset, level);
279 } 280 }
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h
index 5f79bb0aa..d7882a031 100644
--- a/src/video_core/texture_cache/surface_base.h
+++ b/src/video_core/texture_cache/surface_base.h
@@ -131,6 +131,10 @@ public:
131 return !params.is_tiled; 131 return !params.is_tiled;
132 } 132 }
133 133
134 bool IsConverted() const {
135 return is_converted;
136 }
137
134 bool MatchFormat(VideoCore::Surface::PixelFormat pixel_format) const { 138 bool MatchFormat(VideoCore::Surface::PixelFormat pixel_format) const {
135 return params.pixel_format == pixel_format; 139 return params.pixel_format == pixel_format;
136 } 140 }
@@ -160,7 +164,8 @@ public:
160 } 164 }
161 165
162protected: 166protected:
163 explicit SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params); 167 explicit SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params,
168 bool is_astc_supported);
164 ~SurfaceBaseImpl() = default; 169 ~SurfaceBaseImpl() = default;
165 170
166 virtual void DecorateSurfaceName() = 0; 171 virtual void DecorateSurfaceName() = 0;
@@ -168,12 +173,13 @@ protected:
168 const SurfaceParams params; 173 const SurfaceParams params;
169 std::size_t layer_size; 174 std::size_t layer_size;
170 std::size_t guest_memory_size; 175 std::size_t guest_memory_size;
171 const std::size_t host_memory_size; 176 std::size_t host_memory_size;
172 GPUVAddr gpu_addr{}; 177 GPUVAddr gpu_addr{};
173 CacheAddr cache_addr{}; 178 CacheAddr cache_addr{};
174 CacheAddr cache_addr_end{}; 179 CacheAddr cache_addr_end{};
175 VAddr cpu_addr{}; 180 VAddr cpu_addr{};
176 bool is_continuous{}; 181 bool is_continuous{};
182 bool is_converted{};
177 183
178 std::vector<std::size_t> mipmap_sizes; 184 std::vector<std::size_t> mipmap_sizes;
179 std::vector<std::size_t> mipmap_offsets; 185 std::vector<std::size_t> mipmap_offsets;
@@ -288,8 +294,9 @@ public:
288 } 294 }
289 295
290protected: 296protected:
291 explicit SurfaceBase(const GPUVAddr gpu_addr, const SurfaceParams& params) 297 explicit SurfaceBase(const GPUVAddr gpu_addr, const SurfaceParams& params,
292 : SurfaceBaseImpl(gpu_addr, params) {} 298 bool is_astc_supported)
299 : SurfaceBaseImpl(gpu_addr, params, is_astc_supported) {}
293 300
294 ~SurfaceBase() = default; 301 ~SurfaceBase() = default;
295 302
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index 9931c5ef7..47b2aafbd 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -309,28 +309,26 @@ std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const {
309 return offset; 309 return offset;
310} 310}
311 311
312std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const { 312std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level, bool is_converted) const {
313 std::size_t offset = 0; 313 std::size_t offset = 0;
314 for (u32 i = 0; i < level; i++) { 314 if (is_converted) {
315 offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers(); 315 for (u32 i = 0; i < level; ++i) {
316 } 316 offset += GetConvertedMipmapSize(i) * GetNumLayers();
317 return offset; 317 }
318} 318 } else {
319 319 for (u32 i = 0; i < level; ++i) {
320std::size_t SurfaceParams::GetConvertedMipmapOffset(u32 level) const { 320 offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers();
321 std::size_t offset = 0; 321 }
322 for (u32 i = 0; i < level; i++) {
323 offset += GetConvertedMipmapSize(i);
324 } 322 }
325 return offset; 323 return offset;
326} 324}
327 325
328std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const { 326std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const {
329 constexpr std::size_t rgba8_bpp = 4ULL; 327 constexpr std::size_t rgba8_bpp = 4ULL;
330 const std::size_t width_t = GetMipWidth(level); 328 const std::size_t mip_width = GetMipWidth(level);
331 const std::size_t height_t = GetMipHeight(level); 329 const std::size_t mip_height = GetMipHeight(level);
332 const std::size_t depth_t = is_layered ? depth : GetMipDepth(level); 330 const std::size_t mip_depth = is_layered ? 1 : GetMipDepth(level);
333 return width_t * height_t * depth_t * rgba8_bpp; 331 return mip_width * mip_height * mip_depth * rgba8_bpp;
334} 332}
335 333
336std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const { 334std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const {
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h
index 995cc3818..24957df8d 100644
--- a/src/video_core/texture_cache/surface_params.h
+++ b/src/video_core/texture_cache/surface_params.h
@@ -20,8 +20,6 @@ namespace VideoCommon {
20 20
21class FormatLookupTable; 21class FormatLookupTable;
22 22
23using VideoCore::Surface::SurfaceCompression;
24
25class SurfaceParams { 23class SurfaceParams {
26public: 24public:
27 /// Creates SurfaceCachedParams from a texture configuration. 25 /// Creates SurfaceCachedParams from a texture configuration.
@@ -67,16 +65,14 @@ public:
67 return GetInnerMemorySize(false, false, false); 65 return GetInnerMemorySize(false, false, false);
68 } 66 }
69 67
70 std::size_t GetHostSizeInBytes() const { 68 std::size_t GetHostSizeInBytes(bool is_converted) const {
71 std::size_t host_size_in_bytes; 69 if (!is_converted) {
72 if (GetCompressionType() == SurfaceCompression::Converted) { 70 return GetInnerMemorySize(true, false, false);
73 // ASTC is uncompressed in software, in emulated as RGBA8 71 }
74 host_size_in_bytes = 0; 72 // ASTC is uncompressed in software, in emulated as RGBA8
75 for (u32 level = 0; level < num_levels; ++level) { 73 std::size_t host_size_in_bytes = 0;
76 host_size_in_bytes += GetConvertedMipmapSize(level); 74 for (u32 level = 0; level < num_levels; ++level) {
77 } 75 host_size_in_bytes += GetConvertedMipmapSize(level) * GetNumLayers();
78 } else {
79 host_size_in_bytes = GetInnerMemorySize(true, false, false);
80 } 76 }
81 return host_size_in_bytes; 77 return host_size_in_bytes;
82 } 78 }
@@ -107,9 +103,8 @@ public:
107 u32 GetMipBlockDepth(u32 level) const; 103 u32 GetMipBlockDepth(u32 level) const;
108 104
109 /// Returns the best possible row/pitch alignment for the surface. 105 /// Returns the best possible row/pitch alignment for the surface.
110 u32 GetRowAlignment(u32 level) const { 106 u32 GetRowAlignment(u32 level, bool is_converted) const {
111 const u32 bpp = 107 const u32 bpp = is_converted ? 4 : GetBytesPerPixel();
112 GetCompressionType() == SurfaceCompression::Converted ? 4 : GetBytesPerPixel();
113 return 1U << Common::CountTrailingZeroes32(GetMipWidth(level) * bpp); 108 return 1U << Common::CountTrailingZeroes32(GetMipWidth(level) * bpp);
114 } 109 }
115 110
@@ -117,11 +112,7 @@ public:
117 std::size_t GetGuestMipmapLevelOffset(u32 level) const; 112 std::size_t GetGuestMipmapLevelOffset(u32 level) const;
118 113
119 /// Returns the offset in bytes in host memory (linear) of a given mipmap level. 114 /// Returns the offset in bytes in host memory (linear) of a given mipmap level.
120 std::size_t GetHostMipmapLevelOffset(u32 level) const; 115 std::size_t GetHostMipmapLevelOffset(u32 level, bool is_converted) const;
121
122 /// Returns the offset in bytes in host memory (linear) of a given mipmap level
123 /// for a texture that is converted in host gpu.
124 std::size_t GetConvertedMipmapOffset(u32 level) const;
125 116
126 /// Returns the size in bytes in guest memory of a given mipmap level. 117 /// Returns the size in bytes in guest memory of a given mipmap level.
127 std::size_t GetGuestMipmapSize(u32 level) const { 118 std::size_t GetGuestMipmapSize(u32 level) const {
@@ -196,11 +187,6 @@ public:
196 pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; 187 pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat;
197 } 188 }
198 189
199 /// Returns how the compression should be handled for this texture.
200 SurfaceCompression GetCompressionType() const {
201 return VideoCore::Surface::GetFormatCompressionType(pixel_format);
202 }
203
204 /// Returns is the surface is a TextureBuffer type of surface. 190 /// Returns is the surface is a TextureBuffer type of surface.
205 bool IsBuffer() const { 191 bool IsBuffer() const {
206 return target == VideoCore::Surface::SurfaceTarget::TextureBuffer; 192 return target == VideoCore::Surface::SurfaceTarget::TextureBuffer;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 6cdbe63d0..c8f8d659d 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -289,8 +289,9 @@ public:
289 } 289 }
290 290
291protected: 291protected:
292 TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer) 292 explicit TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
293 : system{system}, rasterizer{rasterizer} { 293 bool is_astc_supported)
294 : system{system}, is_astc_supported{is_astc_supported}, rasterizer{rasterizer} {
294 for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { 295 for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
295 SetEmptyColorBuffer(i); 296 SetEmptyColorBuffer(i);
296 } 297 }
@@ -381,6 +382,7 @@ protected:
381 } 382 }
382 383
383 Core::System& system; 384 Core::System& system;
385 const bool is_astc_supported;
384 386
385private: 387private:
386 enum class RecycleStrategy : u32 { 388 enum class RecycleStrategy : u32 {