RasterizerCache: Do not flush surfaces that have not been modified.

This should bring the performance closer to what it was before flushing was implemented.
This commit is contained in:
Subv
2018-09-19 19:30:43 -05:00
parent acfc8d7fc9
commit 23e1dd3c4d
3 changed files with 31 additions and 0 deletions

View File

@@ -322,6 +322,13 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
// Used when just a single color attachment is enabled, e.g. for clearing a color buffer
Surface color_surface =
res_cache.GetColorBufferSurface(*single_color_target, preserve_contents);
if (color_surface) {
// Assume that a surface will be written to if it is used as a framebuffer, even if
// the shader doesn't actually write to it.
color_surface->MarkAsDirty();
}
glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target), GL_TEXTURE_2D,
@@ -332,6 +339,11 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
std::array<GLenum, Maxwell::NumRenderTargets> buffers;
for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
Surface color_surface = res_cache.GetColorBufferSurface(index, preserve_contents);
if (color_surface) {
// Assume that a surface will be written to if it is used as a framebuffer, even
// if the shader doesn't actually write to it.
color_surface->MarkAsDirty();
}
buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
@@ -351,6 +363,12 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
}
if (depth_surface) {
if (depth_surface) {
// Assume that a surface will be written to if it is used as a framebuffer, even if
// the shader doesn't actually write to it.
depth_surface->MarkAsDirty();
}
if (regs.stencil_enable) {
// Attach both depth and stencil
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,

View File

@@ -638,12 +638,18 @@ void CachedSurface::LoadGLBuffer() {
}
ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer, params.pixel_format, params.width, params.height);
dirty = false;
}
MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64));
void CachedSurface::FlushGLBuffer() {
MICROPROFILE_SCOPE(OpenGL_SurfaceFlush);
// There is no need to flush the surface if it hasn't been modified by us.
if (!dirty)
return;
const auto& rect{params.GetRect()};
// Load data from memory to the surface
@@ -700,6 +706,8 @@ void CachedSurface::FlushGLBuffer() {
Memory::WriteBlock(params.addr + buffer_offset, &gl_buffer[buffer_offset],
gl_buffer.size() - buffer_offset);
}
dirty = false;
}
MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));

View File

@@ -745,6 +745,10 @@ public:
FlushGLBuffer();
}
void MarkAsDirty() {
dirty = true;
}
const OGLTexture& Texture() const {
return texture;
}
@@ -776,6 +780,7 @@ private:
std::vector<u8> gl_buffer;
SurfaceParams params;
GLenum gl_target;
bool dirty = false;
};
class RasterizerCacheOpenGL final : public RasterizerCache<Surface> {