summaryrefslogtreecommitdiffstats
path: root/src/video_core/texture_cache/texture_cache.h
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2020-05-30 04:32:41 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2020-06-08 10:01:00 +0200
commitc95c254f3eda75476ad221a4828033f4140a3470 (patch)
treeb06f5db8c853d3b40d82439e4e739205146cf07a /src/video_core/texture_cache/texture_cache.h
parentMerge pull request #4034 from ReinUsesLisp/storage-texels (diff)
downloadyuzu-c95c254f3eda75476ad221a4828033f4140a3470.tar
yuzu-c95c254f3eda75476ad221a4828033f4140a3470.tar.gz
yuzu-c95c254f3eda75476ad221a4828033f4140a3470.tar.bz2
yuzu-c95c254f3eda75476ad221a4828033f4140a3470.tar.lz
yuzu-c95c254f3eda75476ad221a4828033f4140a3470.tar.xz
yuzu-c95c254f3eda75476ad221a4828033f4140a3470.tar.zst
yuzu-c95c254f3eda75476ad221a4828033f4140a3470.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/texture_cache/texture_cache.h119
1 files changed, 51 insertions, 68 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 6f63217a2..4ee0d76b9 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -508,12 +508,12 @@ private:
return RecycleStrategy::Flush;
}
// 3D Textures decision
- if (params.block_depth > 1 || params.target == SurfaceTarget::Texture3D) {
+ if (params.target == SurfaceTarget::Texture3D) {
return RecycleStrategy::Flush;
}
for (const auto& s : overlaps) {
const auto& s_params = s->GetSurfaceParams();
- if (s_params.block_depth > 1 || s_params.target == SurfaceTarget::Texture3D) {
+ if (s_params.target == SurfaceTarget::Texture3D) {
return RecycleStrategy::Flush;
}
}
@@ -726,76 +726,60 @@ private:
* @param params The parameters on the new surface.
* @param gpu_addr The starting address of the new surface.
* @param cpu_addr The starting address of the new surface on physical memory.
- * @param preserve_contents Indicates that the new surface should be loaded from memory or
- * left blank.
*/
std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(VectorSurface& overlaps,
const SurfaceParams& params,
- const GPUVAddr gpu_addr,
- const VAddr cpu_addr,
- bool preserve_contents) {
- if (params.target == SurfaceTarget::Texture3D) {
- bool failed = false;
- if (params.num_levels > 1) {
- // We can't handle mipmaps in 3D textures yet, better fallback to LLE approach
- return std::nullopt;
- }
- TSurface new_surface = GetUncachedSurface(gpu_addr, params);
- bool modified = false;
- for (auto& surface : overlaps) {
- const SurfaceParams& src_params = surface->GetSurfaceParams();
- if (src_params.target != SurfaceTarget::Texture2D) {
- failed = true;
- break;
- }
- if (src_params.height != params.height) {
- failed = true;
- break;
- }
- if (src_params.block_depth != params.block_depth ||
- src_params.block_height != params.block_height) {
- failed = true;
- break;
+ GPUVAddr gpu_addr, VAddr cpu_addr) {
+ if (params.num_levels > 1) {
+ // We can't handle mipmaps in 3D textures yet, better fallback to LLE approach
+ return std::nullopt;
+ }
+
+ if (overlaps.size() == 1) {
+ const auto& surface = overlaps[0];
+ const SurfaceParams& overlap_params = surface->GetSurfaceParams();
+ // Don't attempt to render to textures with more than one level for now
+ // The texture has to be to the right or the sample address if we want to render to it
+ if (overlap_params.num_levels == 1 && cpu_addr >= surface->GetCpuAddr()) {
+ const u32 offset = static_cast<u32>(cpu_addr - surface->GetCpuAddr());
+ const u32 slice = std::get<2>(params.GetBlockOffsetXYZ(offset));
+ if (slice < overlap_params.depth) {
+ auto view = surface->Emplace3DView(slice, params.depth, 0, 1);
+ return std::make_pair(std::move(surface), std::move(view));
}
- const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr);
- const auto offsets = params.GetBlockOffsetXYZ(offset);
- const auto z = std::get<2>(offsets);
- modified |= surface->IsModified();
- const CopyParams copy_params(0, 0, 0, 0, 0, z, 0, 0, params.width, params.height,
- 1);
- ImageCopy(surface, new_surface, copy_params);
}
- if (failed) {
+ }
+
+ if (params.depth == 1) {
+ return std::nullopt;
+ }
+
+ TSurface new_surface = GetUncachedSurface(gpu_addr, params);
+ bool modified = false;
+ for (auto& surface : overlaps) {
+ const SurfaceParams& src_params = surface->GetSurfaceParams();
+ if (src_params.height != params.height ||
+ src_params.block_depth != params.block_depth ||
+ src_params.block_height != params.block_height) {
return std::nullopt;
}
- for (const auto& surface : overlaps) {
- Unregister(surface);
- }
- new_surface->MarkAsModified(modified, Tick());
- Register(new_surface);
- auto view = new_surface->GetMainView();
- return {{std::move(new_surface), view}};
- } else {
- for (const auto& surface : overlaps) {
- if (!surface->MatchTarget(params.target)) {
- if (overlaps.size() == 1 && surface->GetCpuAddr() == cpu_addr) {
- if (Settings::IsGPULevelExtreme()) {
- return std::nullopt;
- }
- Unregister(surface);
- return InitializeSurface(gpu_addr, params, preserve_contents);
- }
- return std::nullopt;
- }
- if (surface->GetCpuAddr() != cpu_addr) {
- continue;
- }
- if (surface->MatchesStructure(params) == MatchStructureResult::FullMatch) {
- return {{surface, surface->GetMainView()}};
- }
- }
- return InitializeSurface(gpu_addr, params, preserve_contents);
+ modified |= surface->IsModified();
+
+ const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr);
+ const u32 slice = std::get<2>(params.GetBlockOffsetXYZ(offset));
+ const u32 width = params.width;
+ const u32 height = params.height;
+ const CopyParams copy_params(0, 0, 0, 0, 0, slice, 0, 0, width, height, 1);
+ ImageCopy(surface, new_surface, copy_params);
}
+ for (const auto& surface : overlaps) {
+ Unregister(surface);
+ }
+ new_surface->MarkAsModified(modified, Tick());
+ Register(new_surface);
+
+ auto view = new_surface->GetMainView();
+ return std::make_pair(std::move(new_surface), std::move(view));
}
/**
@@ -873,10 +857,9 @@ private:
}
}
- // Check if it's a 3D texture
- if (params.block_depth > 0) {
- auto surface =
- Manage3DSurfaces(overlaps, params, gpu_addr, cpu_addr, preserve_contents);
+ // Manage 3D textures
+ if (params.target == SurfaceTarget::Texture3D) {
+ auto surface = Manage3DSurfaces(overlaps, params, gpu_addr, cpu_addr);
if (surface) {
return *surface;
}