texture_cache: Flush 3D textures in the order they are drawn

This commit is contained in:
ReinUsesLisp 2019-04-20 20:01:26 -03:00
parent 1b91e86f65
commit b7df49efba
5 changed files with 44 additions and 19 deletions

View file

@ -273,7 +273,7 @@ struct hash<VideoCommon::ViewKey> {
namespace VideoCommon {
template <typename TView, typename TExecutionContext>
template <typename TTextureCache, typename TView, typename TExecutionContext>
class SurfaceBase {
static_assert(std::is_trivially_copyable_v<TExecutionContext>);
@ -331,6 +331,9 @@ public:
void MarkAsModified(bool is_modified_) {
is_modified = is_modified_;
if (is_modified_) {
modification_tick = texture_cache.Tick();
}
}
const SurfaceParams& GetSurfaceParams() const {
@ -358,13 +361,18 @@ public:
is_registered = false;
}
u64 GetModificationTick() const {
return modification_tick;
}
bool IsRegistered() const {
return is_registered;
}
protected:
explicit SurfaceBase(const SurfaceParams& params)
: params{params}, view_offset_map{params.CreateViewOffsetMap()} {}
explicit SurfaceBase(TTextureCache& texture_cache, const SurfaceParams& params)
: params{params}, texture_cache{texture_cache}, view_offset_map{
params.CreateViewOffsetMap()} {}
~SurfaceBase() = default;
@ -389,12 +397,14 @@ private:
return view.get();
}
TTextureCache& texture_cache;
const std::map<u64, std::pair<u32, u32>> view_offset_map;
GPUVAddr gpu_addr{};
VAddr cpu_addr{};
u8* host_ptr{};
CacheAddr cache_addr{};
u64 modification_tick{};
bool is_modified{};
bool is_registered{};
std::unordered_map<ViewKey, std::unique_ptr<TView>> views;
@ -475,6 +485,10 @@ public:
return it != registered_surfaces.end() ? *it->second.begin() : nullptr;
}
u64 Tick() {
return ++ticks;
}
protected:
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
: system{system}, rasterizer{rasterizer} {}
@ -521,7 +535,7 @@ private:
const auto host_ptr{memory_manager.GetPointer(gpu_addr)};
const auto cache_addr{ToCacheAddr(host_ptr)};
const auto overlaps{GetSurfacesInRegion(cache_addr, params.GetGuestSizeInBytes())};
auto overlaps{GetSurfacesInRegion(cache_addr, params.GetGuestSizeInBytes())};
if (overlaps.empty()) {
return LoadSurfaceView(exctx, gpu_addr, *cpu_addr, host_ptr, params, preserve_contents);
}
@ -544,8 +558,8 @@ private:
for (const auto& surface : overlaps) {
if (!fast_view) {
// Flush even when we don't care about the contents, to preserve memory not written
// by the new surface.
// Flush even when we don't care about the contents, to preserve memory not
// written by the new surface.
exctx = surface->FlushBuffer(exctx);
}
Unregister(surface);
@ -614,6 +628,8 @@ private:
VideoCore::RasterizerInterface& rasterizer;
u64 ticks{};
IntervalMap registered_surfaces;
/// The surface reserve is a "backup" cache, this is where we put unique surfaces that have
@ -653,6 +669,10 @@ public:
return Base::TryFindFramebufferSurface(host_ptr);
}
u64 Tick() {
return Base::Tick();
}
protected:
explicit TextureCacheContextless(Core::System& system,
VideoCore::RasterizerInterface& rasterizer)
@ -678,8 +698,8 @@ private:
}
};
template <typename TView>
class SurfaceBaseContextless : public SurfaceBase<TView, DummyExecutionContext> {
template <typename TTextureCache, typename TView>
class SurfaceBaseContextless : public SurfaceBase<TTextureCache, TView, DummyExecutionContext> {
public:
DummyExecutionContext FlushBuffer(DummyExecutionContext) {
FlushBufferImpl();
@ -692,8 +712,8 @@ public:
}
protected:
explicit SurfaceBaseContextless(const SurfaceParams& params)
: SurfaceBase<TView, DummyExecutionContext>{params} {}
explicit SurfaceBaseContextless(TTextureCache& texture_cache, const SurfaceParams& params)
: SurfaceBase<TTextureCache, TView, DummyExecutionContext>{texture_cache, params} {}
virtual void FlushBufferImpl() = 0;