Implement SignalFinish on GPU and force flush linear surfaces on finish.

This commit is contained in:
Fernando Sahmkow
2019-02-03 20:52:03 -04:00
committed by FernandoS27
parent 3118b2434a
commit d2c43a04a4
7 changed files with 51 additions and 12 deletions

View File

@@ -104,7 +104,7 @@ protected:
}
/// Register an object into the cache
void Register(const T& object) {
virtual void Register(const T& object) {
object->SetIsRegistered(true);
interval_cache.add({GetInterval(object), ObjectSet{object}});
map_cache.insert({object->GetAddr(), object});
@@ -112,7 +112,7 @@ protected:
}
/// Unregisters an object from the cache
void Unregister(const T& object) {
virtual void Unregister(const T& object) {
object->SetIsRegistered(false);
rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), -1);
// Only flush if use_accurate_gpu_emulation is enabled, as it incurs a performance hit
@@ -129,6 +129,15 @@ protected:
return ++modified_ticks;
}
/// Flushes the specified object, updating appropriate cache state as needed
void FlushObject(const T& object) {
if (!object->IsDirty()) {
return;
}
object->Flush();
object->MarkAsModified(false, *this);
}
private:
/// Returns a list of cached objects from the specified memory region, ordered by access time
std::vector<T> GetSortedObjectsFromRegion(VAddr addr, u64 size) {
@@ -154,15 +163,6 @@ private:
return objects;
}
/// Flushes the specified object, updating appropriate cache state as needed
void FlushObject(const T& object) {
if (!object->IsDirty()) {
return;
}
object->Flush();
object->MarkAsModified(false, *this);
}
using ObjectSet = std::set<T>;
using ObjectCache = std::unordered_map<VAddr, T>;
using IntervalCache = boost::icl::interval_map<VAddr, ObjectSet>;

View File

@@ -66,5 +66,7 @@ public:
/// Initialize disk cached resources for the game being emulated
virtual void LoadDiskResources(const std::atomic_bool& stop_loading = false,
const DiskResourceLoadCallback& callback = {}) {}
/// Notify rasterizer that dma push has finished.
virtual void SignalFinish() = 0;
};
} // namespace VideoCore

View File

@@ -1283,4 +1283,8 @@ void RasterizerOpenGL::CheckAlphaTests() {
}
}
void RasterizerOpenGL::SignalFinish() {
res_cache.SignalFinish();
}
} // namespace OpenGL

View File

@@ -69,6 +69,8 @@ public:
void LoadDiskResources(const std::atomic_bool& stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) override;
void SignalFinish() override;
/// Maximum supported size that a constbuffer can have in bytes.
static constexpr std::size_t MaxConstbufferSize = 0x10000;
static_assert(MaxConstbufferSize % sizeof(GLvec4) == 0,

View File

@@ -700,7 +700,8 @@ void CachedSurface::LoadGLBuffer() {
u32 bpp = params.GetFormatBpp() / 8;
u32 copy_size = params.width * bpp;
if (params.pitch == copy_size) {
std::memcpy(gl_buffer[0].data(), Memory::GetPointer(params.addr), params.size_in_bytes_gl);
std::memcpy(gl_buffer[0].data(), Memory::GetPointer(params.addr),
params.size_in_bytes_gl);
} else {
u8* start = Memory::GetPointer(params.addr);
u8* write_to = gl_buffer[0].data();
@@ -1132,4 +1133,10 @@ Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params
return {};
}
void RasterizerCacheOpenGL::SignalFinish() {
for (const auto& o : surfaces_to_flush) {
FlushObject(o);
}
}
} // namespace OpenGL

View File

@@ -8,6 +8,7 @@
#include <map>
#include <memory>
#include <string>
#include <unordered_set>
#include <vector>
#include "common/alignment.h"
@@ -424,6 +425,26 @@ public:
void FermiCopySurface(const Tegra::Engines::Fermi2D::Regs::Surface& src_config,
const Tegra::Engines::Fermi2D::Regs::Surface& dst_config);
void SignalFinish();
protected:
void Register(const Surface& object) {
RasterizerCache<Surface>::Register(object);
const auto& params = object->GetSurfaceParams();
if (!params.is_tiled) {
surfaces_to_flush.insert(object);
}
}
/// Unregisters an object from the cache
void Unregister(const Surface& object) {
const auto& params = object->GetSurfaceParams();
if (!params.is_tiled) {
surfaces_to_flush.erase(object);
}
RasterizerCache<Surface>::Unregister(object);
}
private:
void LoadSurface(const Surface& surface);
Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true);
@@ -449,6 +470,8 @@ private:
/// destroyed when used with different surface parameters.
std::unordered_map<SurfaceReserveKey, Surface> surface_reserve;
std::unordered_set<Surface> surfaces_to_flush;
OGLFramebuffer read_framebuffer;
OGLFramebuffer draw_framebuffer;

View File

@@ -142,6 +142,7 @@ void RendererOpenGL::SwapBuffers(
// Restore the rasterizer state
prev_state.Apply();
rasterizer->SignalFinish();
}
/**