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.cpp72
1 files changed, 43 insertions, 29 deletions
diff --git a/src/video_core/texture_cache.cpp b/src/video_core/texture_cache.cpp
index 2994312f4..b47ce6b98 100644
--- a/src/video_core/texture_cache.cpp
+++ b/src/video_core/texture_cache.cpp
@@ -32,12 +32,13 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system,
32 const Tegra::Texture::FullTextureInfo& config) { 32 const Tegra::Texture::FullTextureInfo& config) {
33 SurfaceParams params; 33 SurfaceParams params;
34 params.is_tiled = config.tic.IsTiled(); 34 params.is_tiled = config.tic.IsTiled();
35 params.srgb_conversion = config.tic.IsSrgbConversionEnabled();
35 params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, 36 params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0,
36 params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, 37 params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0,
37 params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0, 38 params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0,
38 params.tile_width_spacing = params.is_tiled ? (1 << config.tic.tile_width_spacing.Value()) : 1; 39 params.tile_width_spacing = params.is_tiled ? (1 << config.tic.tile_width_spacing.Value()) : 1;
39 params.pixel_format = 40 params.pixel_format = PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value(),
40 PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value(), false); 41 params.srgb_conversion);
41 params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); 42 params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value());
42 params.type = GetFormatType(params.pixel_format); 43 params.type = GetFormatType(params.pixel_format);
43 params.target = SurfaceTargetFromTextureType(config.tic.texture_type); 44 params.target = SurfaceTargetFromTextureType(config.tic.texture_type);
@@ -62,6 +63,7 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer(
62 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) { 63 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) {
63 SurfaceParams params; 64 SurfaceParams params;
64 params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; 65 params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
66 params.srgb_conversion = false;
65 params.block_width = 1 << std::min(block_width, 5U); 67 params.block_width = 1 << std::min(block_width, 5U);
66 params.block_height = 1 << std::min(block_height, 5U); 68 params.block_height = 1 << std::min(block_height, 5U);
67 params.block_depth = 1 << std::min(block_depth, 5U); 69 params.block_depth = 1 << std::min(block_depth, 5U);
@@ -85,6 +87,8 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz
85 SurfaceParams params; 87 SurfaceParams params;
86 params.is_tiled = 88 params.is_tiled =
87 config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; 89 config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
90 params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB ||
91 config.format == Tegra::RenderTargetFormat::RGBA8_SRGB;
88 params.block_width = 1 << config.memory_layout.block_width; 92 params.block_width = 1 << config.memory_layout.block_width;
89 params.block_height = 1 << config.memory_layout.block_height; 93 params.block_height = 1 << config.memory_layout.block_height;
90 params.block_depth = 1 << config.memory_layout.block_depth; 94 params.block_depth = 1 << config.memory_layout.block_depth;
@@ -113,6 +117,8 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface(
113 const Tegra::Engines::Fermi2D::Regs::Surface& config) { 117 const Tegra::Engines::Fermi2D::Regs::Surface& config) {
114 SurfaceParams params{}; 118 SurfaceParams params{};
115 params.is_tiled = !config.linear; 119 params.is_tiled = !config.linear;
120 params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB ||
121 config.format == Tegra::RenderTargetFormat::RGBA8_SRGB;
116 params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0, 122 params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0,
117 params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, 123 params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0,
118 params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0, 124 params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0,
@@ -162,6 +168,7 @@ u32 SurfaceParams::GetMipBlockHeight(u32 level) const {
162 if (level == 0) { 168 if (level == 0) {
163 return this->block_height; 169 return this->block_height;
164 } 170 }
171
165 const u32 height{GetMipHeight(level)}; 172 const u32 height{GetMipHeight(level)};
166 const u32 default_block_height{GetDefaultBlockHeight()}; 173 const u32 default_block_height{GetDefaultBlockHeight()};
167 const u32 blocks_in_y{(height + default_block_height - 1) / default_block_height}; 174 const u32 blocks_in_y{(height + default_block_height - 1) / default_block_height};
@@ -173,10 +180,12 @@ u32 SurfaceParams::GetMipBlockHeight(u32 level) const {
173} 180}
174 181
175u32 SurfaceParams::GetMipBlockDepth(u32 level) const { 182u32 SurfaceParams::GetMipBlockDepth(u32 level) const {
176 if (level == 0) 183 if (level == 0) {
177 return block_depth; 184 return this->block_depth;
178 if (target != SurfaceTarget::Texture3D) 185 }
186 if (IsLayered()) {
179 return 1; 187 return 1;
188 }
180 189
181 const u32 depth{GetMipDepth(level)}; 190 const u32 depth{GetMipDepth(level)};
182 u32 block_depth = 32; 191 u32 block_depth = 32;
@@ -192,7 +201,7 @@ u32 SurfaceParams::GetMipBlockDepth(u32 level) const {
192std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const { 201std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const {
193 std::size_t offset = 0; 202 std::size_t offset = 0;
194 for (u32 i = 0; i < level; i++) { 203 for (u32 i = 0; i < level; i++) {
195 offset += GetInnerMipmapMemorySize(i, false, IsLayered(), false); 204 offset += GetInnerMipmapMemorySize(i, false, false);
196 } 205 }
197 return offset; 206 return offset;
198} 207}
@@ -200,21 +209,33 @@ std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const {
200std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const { 209std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const {
201 std::size_t offset = 0; 210 std::size_t offset = 0;
202 for (u32 i = 0; i < level; i++) { 211 for (u32 i = 0; i < level; i++) {
203 offset += GetInnerMipmapMemorySize(i, true, false, false); 212 offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers();
204 } 213 }
205 return offset; 214 return offset;
206} 215}
207 216
208std::size_t SurfaceParams::GetHostMipmapSize(u32 level) const { 217std::size_t SurfaceParams::GetHostMipmapSize(u32 level) const {
209 return GetInnerMipmapMemorySize(level, true, true, false) * GetNumLayers(); 218 return GetInnerMipmapMemorySize(level, true, false) * GetNumLayers();
210} 219}
211 220
212std::size_t SurfaceParams::GetGuestLayerSize() const { 221std::size_t SurfaceParams::GetGuestLayerSize() const {
213 return GetInnerMemorySize(false, true, false); 222 return GetLayerSize(false, false);
223}
224
225std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const {
226 std::size_t size = 0;
227 for (u32 level = 0; level < num_levels; ++level) {
228 size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed);
229 }
230 if (is_tiled && IsLayered()) {
231 return Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
232 }
233 return size;
214} 234}
215 235
216std::size_t SurfaceParams::GetHostLayerSize(u32 level) const { 236std::size_t SurfaceParams::GetHostLayerSize(u32 level) const {
217 return GetInnerMipmapMemorySize(level, true, IsLayered(), false); 237 ASSERT(target != SurfaceTarget::Texture3D);
238 return GetInnerMipmapMemorySize(level, true, false);
218} 239}
219 240
220u32 SurfaceParams::GetDefaultBlockWidth() const { 241u32 SurfaceParams::GetDefaultBlockWidth() const {
@@ -273,15 +294,6 @@ bool SurfaceParams::IsPixelFormatZeta() const {
273} 294}
274 295
275void SurfaceParams::CalculateCachedValues() { 296void SurfaceParams::CalculateCachedValues() {
276 guest_size_in_bytes = GetInnerMemorySize(false, false, false);
277
278 // ASTC is uncompressed in software, in emulated as RGBA8
279 if (IsPixelFormatASTC(pixel_format)) {
280 host_size_in_bytes = static_cast<std::size_t>(width * height * depth) * 4ULL;
281 } else {
282 host_size_in_bytes = GetInnerMemorySize(true, false, false);
283 }
284
285 switch (target) { 297 switch (target) {
286 case SurfaceTarget::Texture1D: 298 case SurfaceTarget::Texture1D:
287 case SurfaceTarget::Texture2D: 299 case SurfaceTarget::Texture2D:
@@ -297,28 +309,30 @@ void SurfaceParams::CalculateCachedValues() {
297 default: 309 default:
298 UNREACHABLE(); 310 UNREACHABLE();
299 } 311 }
312
313 guest_size_in_bytes = GetInnerMemorySize(false, false, false);
314
315 // ASTC is uncompressed in software, in emulated as RGBA8
316 if (IsPixelFormatASTC(pixel_format)) {
317 host_size_in_bytes = static_cast<std::size_t>(width * height * depth * 4U);
318 } else {
319 host_size_in_bytes = GetInnerMemorySize(true, false, false);
320 }
300} 321}
301 322
302std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size, bool layer_only, 323std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size,
303 bool uncompressed) const { 324 bool uncompressed) const {
304 const bool tiled{as_host_size ? false : is_tiled}; 325 const bool tiled{as_host_size ? false : is_tiled};
305 const u32 width{GetMipmapSize(uncompressed, GetMipWidth(level), GetDefaultBlockWidth())}; 326 const u32 width{GetMipmapSize(uncompressed, GetMipWidth(level), GetDefaultBlockWidth())};
306 const u32 height{GetMipmapSize(uncompressed, GetMipHeight(level), GetDefaultBlockHeight())}; 327 const u32 height{GetMipmapSize(uncompressed, GetMipHeight(level), GetDefaultBlockHeight())};
307 const u32 depth{layer_only ? 1U : GetMipDepth(level)}; 328 const u32 depth{target == SurfaceTarget::Texture3D ? GetMipDepth(level) : 1U};
308 return Tegra::Texture::CalculateSize(tiled, GetBytesPerPixel(), width, height, depth, 329 return Tegra::Texture::CalculateSize(tiled, GetBytesPerPixel(), width, height, depth,
309 GetMipBlockHeight(level), GetMipBlockDepth(level)); 330 GetMipBlockHeight(level), GetMipBlockDepth(level));
310} 331}
311 332
312std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only, 333std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only,
313 bool uncompressed) const { 334 bool uncompressed) const {
314 std::size_t size = 0; 335 return GetLayerSize(as_host_size, uncompressed) * (layer_only ? 1U : num_layers);
315 for (u32 level = 0; level < num_levels; ++level) {
316 size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed);
317 }
318 if (is_tiled && !as_host_size) {
319 size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
320 }
321 return size;
322} 336}
323 337
324std::map<u64, std::pair<u32, u32>> SurfaceParams::CreateViewOffsetMap() const { 338std::map<u64, std::pair<u32, u32>> SurfaceParams::CreateViewOffsetMap() const {