summaryrefslogtreecommitdiffstats
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2020-04-06 15:21:11 +0200
committerGitHub <noreply@github.com>2020-04-06 15:21:11 +0200
commit588a20be3fca40746c965ea7831177f5c894ebee (patch)
tree42848be537f341aba483d13e44a637a01e3e4e09 /src/video_core/texture_cache
parentMerge pull request #3592 from ReinUsesLisp/ipa (diff)
parentgl_texture_cache: Fix software ASTC fallback (diff)
downloadyuzu-588a20be3fca40746c965ea7831177f5c894ebee.tar
yuzu-588a20be3fca40746c965ea7831177f5c894ebee.tar.gz
yuzu-588a20be3fca40746c965ea7831177f5c894ebee.tar.bz2
yuzu-588a20be3fca40746c965ea7831177f5c894ebee.tar.lz
yuzu-588a20be3fca40746c965ea7831177f5c894ebee.tar.xz
yuzu-588a20be3fca40746c965ea7831177f5c894ebee.tar.zst
yuzu-588a20be3fca40746c965ea7831177f5c894ebee.zip
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,
using Tegra::Texture::ConvertFromGuestToHost;
using VideoCore::MortonSwizzleMode;
-using VideoCore::Surface::SurfaceCompression;
+using VideoCore::Surface::IsPixelFormatASTC;
+using VideoCore::Surface::PixelFormat;
StagingCache::StagingCache() = default;
StagingCache::~StagingCache() = default;
-SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params)
- : params{params}, host_memory_size{params.GetHostSizeInBytes()}, gpu_addr{gpu_addr},
- mipmap_sizes(params.num_levels), mipmap_offsets(params.num_levels) {
+SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params,
+ bool is_astc_supported)
+ : params{params}, gpu_addr{gpu_addr}, mipmap_sizes(params.num_levels),
+ mipmap_offsets(params.num_levels) {
+ is_converted = IsPixelFormatASTC(params.pixel_format) && !is_astc_supported;
+ host_memory_size = params.GetHostSizeInBytes(is_converted);
+
std::size_t offset = 0;
for (u32 level = 0; level < params.num_levels; ++level) {
const std::size_t mipmap_size{params.GetGuestMipmapSize(level)};
@@ -164,7 +169,7 @@ void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const Surf
std::size_t guest_offset{mipmap_offsets[level]};
if (params.is_layered) {
- std::size_t host_offset{0};
+ std::size_t host_offset = 0;
const std::size_t guest_stride = layer_size;
const std::size_t host_stride = params.GetHostLayerSize(level);
for (u32 layer = 0; layer < params.depth; ++layer) {
@@ -206,7 +211,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
ASSERT_MSG(params.block_width == 0, "Block width is defined as {} on texture target {}",
params.block_width, static_cast<u32>(params.target));
for (u32 level = 0; level < params.num_levels; ++level) {
- const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)};
+ const std::size_t host_offset{params.GetHostMipmapLevelOffset(level, false)};
SwizzleFunc(MortonSwizzleMode::MortonToLinear, host_ptr, params,
staging_buffer.data() + host_offset, level);
}
@@ -219,7 +224,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
const u32 height{(params.height + block_height - 1) / block_height};
const u32 copy_size{width * bpp};
if (params.pitch == copy_size) {
- std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes());
+ std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes(false));
} else {
const u8* start{host_ptr};
u8* write_to{staging_buffer.data()};
@@ -231,19 +236,15 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
}
}
- auto compression_type = params.GetCompressionType();
- if (compression_type == SurfaceCompression::None ||
- compression_type == SurfaceCompression::Compressed)
+ if (!is_converted && params.pixel_format != PixelFormat::S8Z24) {
return;
+ }
- for (u32 level_up = params.num_levels; level_up > 0; --level_up) {
- const u32 level = level_up - 1;
- const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level)};
- const std::size_t out_host_offset = compression_type == SurfaceCompression::Rearranged
- ? in_host_offset
- : params.GetConvertedMipmapOffset(level);
- u8* in_buffer = staging_buffer.data() + in_host_offset;
- u8* out_buffer = staging_buffer.data() + out_host_offset;
+ for (u32 level = params.num_levels; level--;) {
+ const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level, false)};
+ const std::size_t out_host_offset{params.GetHostMipmapLevelOffset(level, is_converted)};
+ u8* const in_buffer = staging_buffer.data() + in_host_offset;
+ u8* const out_buffer = staging_buffer.data() + out_host_offset;
ConvertFromGuestToHost(in_buffer, out_buffer, params.pixel_format,
params.GetMipWidth(level), params.GetMipHeight(level),
params.GetMipDepth(level), true, true);
@@ -273,7 +274,7 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
if (params.is_tiled) {
ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width);
for (u32 level = 0; level < params.num_levels; ++level) {
- const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)};
+ const std::size_t host_offset{params.GetHostMipmapLevelOffset(level, false)};
SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params,
staging_buffer.data() + host_offset, level);
}
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:
return !params.is_tiled;
}
+ bool IsConverted() const {
+ return is_converted;
+ }
+
bool MatchFormat(VideoCore::Surface::PixelFormat pixel_format) const {
return params.pixel_format == pixel_format;
}
@@ -160,7 +164,8 @@ public:
}
protected:
- explicit SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params);
+ explicit SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params,
+ bool is_astc_supported);
~SurfaceBaseImpl() = default;
virtual void DecorateSurfaceName() = 0;
@@ -168,12 +173,13 @@ protected:
const SurfaceParams params;
std::size_t layer_size;
std::size_t guest_memory_size;
- const std::size_t host_memory_size;
+ std::size_t host_memory_size;
GPUVAddr gpu_addr{};
CacheAddr cache_addr{};
CacheAddr cache_addr_end{};
VAddr cpu_addr{};
bool is_continuous{};
+ bool is_converted{};
std::vector<std::size_t> mipmap_sizes;
std::vector<std::size_t> mipmap_offsets;
@@ -288,8 +294,9 @@ public:
}
protected:
- explicit SurfaceBase(const GPUVAddr gpu_addr, const SurfaceParams& params)
- : SurfaceBaseImpl(gpu_addr, params) {}
+ explicit SurfaceBase(const GPUVAddr gpu_addr, const SurfaceParams& params,
+ bool is_astc_supported)
+ : SurfaceBaseImpl(gpu_addr, params, is_astc_supported) {}
~SurfaceBase() = default;
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 {
return offset;
}
-std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const {
+std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level, bool is_converted) const {
std::size_t offset = 0;
- for (u32 i = 0; i < level; i++) {
- offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers();
- }
- return offset;
-}
-
-std::size_t SurfaceParams::GetConvertedMipmapOffset(u32 level) const {
- std::size_t offset = 0;
- for (u32 i = 0; i < level; i++) {
- offset += GetConvertedMipmapSize(i);
+ if (is_converted) {
+ for (u32 i = 0; i < level; ++i) {
+ offset += GetConvertedMipmapSize(i) * GetNumLayers();
+ }
+ } else {
+ for (u32 i = 0; i < level; ++i) {
+ offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers();
+ }
}
return offset;
}
std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const {
constexpr std::size_t rgba8_bpp = 4ULL;
- const std::size_t width_t = GetMipWidth(level);
- const std::size_t height_t = GetMipHeight(level);
- const std::size_t depth_t = is_layered ? depth : GetMipDepth(level);
- return width_t * height_t * depth_t * rgba8_bpp;
+ const std::size_t mip_width = GetMipWidth(level);
+ const std::size_t mip_height = GetMipHeight(level);
+ const std::size_t mip_depth = is_layered ? 1 : GetMipDepth(level);
+ return mip_width * mip_height * mip_depth * rgba8_bpp;
}
std::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 {
class FormatLookupTable;
-using VideoCore::Surface::SurfaceCompression;
-
class SurfaceParams {
public:
/// Creates SurfaceCachedParams from a texture configuration.
@@ -67,16 +65,14 @@ public:
return GetInnerMemorySize(false, false, false);
}
- std::size_t GetHostSizeInBytes() const {
- std::size_t host_size_in_bytes;
- if (GetCompressionType() == SurfaceCompression::Converted) {
- // ASTC is uncompressed in software, in emulated as RGBA8
- host_size_in_bytes = 0;
- for (u32 level = 0; level < num_levels; ++level) {
- host_size_in_bytes += GetConvertedMipmapSize(level);
- }
- } else {
- host_size_in_bytes = GetInnerMemorySize(true, false, false);
+ std::size_t GetHostSizeInBytes(bool is_converted) const {
+ if (!is_converted) {
+ return GetInnerMemorySize(true, false, false);
+ }
+ // ASTC is uncompressed in software, in emulated as RGBA8
+ std::size_t host_size_in_bytes = 0;
+ for (u32 level = 0; level < num_levels; ++level) {
+ host_size_in_bytes += GetConvertedMipmapSize(level) * GetNumLayers();
}
return host_size_in_bytes;
}
@@ -107,9 +103,8 @@ public:
u32 GetMipBlockDepth(u32 level) const;
/// Returns the best possible row/pitch alignment for the surface.
- u32 GetRowAlignment(u32 level) const {
- const u32 bpp =
- GetCompressionType() == SurfaceCompression::Converted ? 4 : GetBytesPerPixel();
+ u32 GetRowAlignment(u32 level, bool is_converted) const {
+ const u32 bpp = is_converted ? 4 : GetBytesPerPixel();
return 1U << Common::CountTrailingZeroes32(GetMipWidth(level) * bpp);
}
@@ -117,11 +112,7 @@ public:
std::size_t GetGuestMipmapLevelOffset(u32 level) const;
/// Returns the offset in bytes in host memory (linear) of a given mipmap level.
- std::size_t GetHostMipmapLevelOffset(u32 level) const;
-
- /// Returns the offset in bytes in host memory (linear) of a given mipmap level
- /// for a texture that is converted in host gpu.
- std::size_t GetConvertedMipmapOffset(u32 level) const;
+ std::size_t GetHostMipmapLevelOffset(u32 level, bool is_converted) const;
/// Returns the size in bytes in guest memory of a given mipmap level.
std::size_t GetGuestMipmapSize(u32 level) const {
@@ -196,11 +187,6 @@ public:
pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat;
}
- /// Returns how the compression should be handled for this texture.
- SurfaceCompression GetCompressionType() const {
- return VideoCore::Surface::GetFormatCompressionType(pixel_format);
- }
-
/// Returns is the surface is a TextureBuffer type of surface.
bool IsBuffer() const {
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:
}
protected:
- TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
- : system{system}, rasterizer{rasterizer} {
+ explicit TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
+ bool is_astc_supported)
+ : system{system}, is_astc_supported{is_astc_supported}, rasterizer{rasterizer} {
for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
SetEmptyColorBuffer(i);
}
@@ -381,6 +382,7 @@ protected:
}
Core::System& system;
+ const bool is_astc_supported;
private:
enum class RecycleStrategy : u32 {