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:
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user