summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/texture_cache.cpp')
-rw-r--r--src/video_core/texture_cache.cpp110
1 files changed, 109 insertions, 1 deletions
diff --git a/src/video_core/texture_cache.cpp b/src/video_core/texture_cache.cpp
index b78a7d951..146e8ed9b 100644
--- a/src/video_core/texture_cache.cpp
+++ b/src/video_core/texture_cache.cpp
@@ -7,14 +7,16 @@
7#include "common/cityhash.h" 7#include "common/cityhash.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "video_core/morton.h"
10#include "video_core/surface.h" 11#include "video_core/surface.h"
11#include "video_core/texture_cache.h" 12#include "video_core/texture_cache.h"
13#include "video_core/textures/convert.h"
12#include "video_core/textures/decoders.h" 14#include "video_core/textures/decoders.h"
13#include "video_core/textures/texture.h" 15#include "video_core/textures/texture.h"
14 16
15namespace VideoCommon { 17namespace VideoCommon {
16 18
17using VideoCore::Surface::SurfaceTarget; 19using VideoCore::MortonSwizzleMode;
18 20
19using VideoCore::Surface::ComponentTypeFromDepthFormat; 21using VideoCore::Surface::ComponentTypeFromDepthFormat;
20using VideoCore::Surface::ComponentTypeFromRenderTarget; 22using VideoCore::Surface::ComponentTypeFromRenderTarget;
@@ -22,12 +24,118 @@ using VideoCore::Surface::ComponentTypeFromTexture;
22using VideoCore::Surface::PixelFormatFromDepthFormat; 24using VideoCore::Surface::PixelFormatFromDepthFormat;
23using VideoCore::Surface::PixelFormatFromRenderTargetFormat; 25using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
24using VideoCore::Surface::PixelFormatFromTextureFormat; 26using VideoCore::Surface::PixelFormatFromTextureFormat;
27using VideoCore::Surface::SurfaceTarget;
25using VideoCore::Surface::SurfaceTargetFromTextureType; 28using VideoCore::Surface::SurfaceTargetFromTextureType;
26 29
30using Tegra::Texture::ConvertFromGuestToHost;
31
32namespace {
33
27constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { 34constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) {
28 return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile); 35 return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile);
29} 36}
30 37
38void SwizzleFunc(MortonSwizzleMode mode, u8* memory, const SurfaceParams& params, u8* buffer,
39 u32 level) {
40 const u32 width{params.GetMipWidth(level)};
41 const u32 height{params.GetMipHeight(level)};
42 const u32 block_height{params.GetMipBlockHeight(level)};
43 const u32 block_depth{params.GetMipBlockDepth(level)};
44
45 std::size_t guest_offset{params.GetGuestMipmapLevelOffset(level)};
46 if (params.IsLayered()) {
47 std::size_t host_offset{0};
48 const std::size_t guest_stride = params.GetGuestLayerSize();
49 const std::size_t host_stride = params.GetHostLayerSize(level);
50 for (u32 layer = 0; layer < params.GetNumLayers(); layer++) {
51 MortonSwizzle(mode, params.GetPixelFormat(), width, block_height, height, block_depth,
52 1, params.GetTileWidthSpacing(), buffer + host_offset,
53 memory + guest_offset);
54 guest_offset += guest_stride;
55 host_offset += host_stride;
56 }
57 } else {
58 MortonSwizzle(mode, params.GetPixelFormat(), width, block_height, height, block_depth,
59 params.GetMipDepth(level), params.GetTileWidthSpacing(), buffer,
60 memory + guest_offset);
61 }
62}
63
64} // Anonymous namespace
65
66SurfaceBaseImpl::SurfaceBaseImpl(const SurfaceParams& params) : params{params} {
67 staging_buffer.resize(params.GetHostSizeInBytes());
68}
69
70SurfaceBaseImpl::~SurfaceBaseImpl() = default;
71
72void SurfaceBaseImpl::LoadBuffer() {
73 if (params.IsTiled()) {
74 ASSERT_MSG(params.GetBlockWidth() == 1, "Block width is defined as {} on texture target {}",
75 params.GetBlockWidth(), static_cast<u32>(params.GetTarget()));
76 for (u32 level = 0; level < params.GetNumLevels(); ++level) {
77 u8* const buffer{GetStagingBufferLevelData(level)};
78 SwizzleFunc(MortonSwizzleMode::MortonToLinear, host_ptr, params, buffer, level);
79 }
80 } else {
81 ASSERT_MSG(params.GetNumLevels() == 1, "Linear mipmap loading is not implemented");
82 const u32 bpp{GetFormatBpp(params.GetPixelFormat()) / CHAR_BIT};
83 const u32 block_width{params.GetDefaultBlockWidth()};
84 const u32 block_height{params.GetDefaultBlockHeight()};
85 const u32 width{(params.GetWidth() + block_width - 1) / block_width};
86 const u32 height{(params.GetHeight() + block_height - 1) / block_height};
87 const u32 copy_size{width * bpp};
88 if (params.GetPitch() == copy_size) {
89 std::memcpy(staging_buffer.data(), host_ptr, params.GetHostSizeInBytes());
90 } else {
91 const u8* start{host_ptr};
92 u8* write_to{staging_buffer.data()};
93 for (u32 h = height; h > 0; --h) {
94 std::memcpy(write_to, start, copy_size);
95 start += params.GetPitch();
96 write_to += copy_size;
97 }
98 }
99 }
100
101 for (u32 level = 0; level < params.GetNumLevels(); ++level) {
102 ConvertFromGuestToHost(GetStagingBufferLevelData(level), params.GetPixelFormat(),
103 params.GetMipWidth(level), params.GetMipHeight(level),
104 params.GetMipDepth(level), true, true);
105 }
106}
107
108void SurfaceBaseImpl::FlushBuffer() {
109 if (params.IsTiled()) {
110 ASSERT_MSG(params.GetBlockWidth() == 1, "Block width is defined as {}",
111 params.GetBlockWidth());
112 for (u32 level = 0; level < params.GetNumLevels(); ++level) {
113 u8* const buffer = GetStagingBufferLevelData(level);
114 SwizzleFunc(MortonSwizzleMode::LinearToMorton, GetHostPtr(), params, buffer, level);
115 }
116 } else {
117 UNIMPLEMENTED();
118 /*
119 ASSERT(params.GetTarget() == SurfaceTarget::Texture2D);
120 ASSERT(params.GetNumLevels() == 1);
121
122 const u32 bpp{params.GetFormatBpp() / 8};
123 const u32 copy_size{params.GetWidth() * bpp};
124 if (params.GetPitch() == copy_size) {
125 std::memcpy(host_ptr, staging_buffer.data(), GetSizeInBytes());
126 } else {
127 u8* start{host_ptr};
128 const u8* read_to{staging_buffer.data()};
129 for (u32 h = params.GetHeight(); h > 0; --h) {
130 std::memcpy(start, read_to, copy_size);
131 start += params.GetPitch();
132 read_to += copy_size;
133 }
134 }
135 */
136 }
137}
138
31SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, 139SurfaceParams SurfaceParams::CreateForTexture(Core::System& system,
32 const Tegra::Texture::FullTextureInfo& config) { 140 const Tegra::Texture::FullTextureInfo& config) {
33 SurfaceParams params; 141 SurfaceParams params;