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
|
// Used when just a single color attachment is enabled, e.g. for clearing a color buffer
|
||||||
Surface color_surface =
|
Surface color_surface =
|
||||||
res_cache.GetColorBufferSurface(*single_color_target, preserve_contents);
|
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(
|
glFramebufferTexture2D(
|
||||||
GL_DRAW_FRAMEBUFFER,
|
GL_DRAW_FRAMEBUFFER,
|
||||||
GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target), GL_TEXTURE_2D,
|
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;
|
std::array<GLenum, Maxwell::NumRenderTargets> buffers;
|
||||||
for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
|
for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
|
||||||
Surface color_surface = res_cache.GetColorBufferSurface(index, preserve_contents);
|
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);
|
buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
|
||||||
glFramebufferTexture2D(
|
glFramebufferTexture2D(
|
||||||
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
|
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) {
|
||||||
|
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) {
|
if (regs.stencil_enable) {
|
||||||
// Attach both depth and stencil
|
// Attach both depth and stencil
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
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);
|
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));
|
MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64));
|
||||||
void CachedSurface::FlushGLBuffer() {
|
void CachedSurface::FlushGLBuffer() {
|
||||||
MICROPROFILE_SCOPE(OpenGL_SurfaceFlush);
|
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()};
|
const auto& rect{params.GetRect()};
|
||||||
|
|
||||||
// Load data from memory to the surface
|
// Load data from memory to the surface
|
||||||
@@ -700,6 +706,8 @@ void CachedSurface::FlushGLBuffer() {
|
|||||||
Memory::WriteBlock(params.addr + buffer_offset, &gl_buffer[buffer_offset],
|
Memory::WriteBlock(params.addr + buffer_offset, &gl_buffer[buffer_offset],
|
||||||
gl_buffer.size() - buffer_offset);
|
gl_buffer.size() - buffer_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));
|
MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));
|
||||||
|
|||||||
@@ -745,6 +745,10 @@ public:
|
|||||||
FlushGLBuffer();
|
FlushGLBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarkAsDirty() {
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
const OGLTexture& Texture() const {
|
const OGLTexture& Texture() const {
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
@@ -776,6 +780,7 @@ private:
|
|||||||
std::vector<u8> gl_buffer;
|
std::vector<u8> gl_buffer;
|
||||||
SurfaceParams params;
|
SurfaceParams params;
|
||||||
GLenum gl_target;
|
GLenum gl_target;
|
||||||
|
bool dirty = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RasterizerCacheOpenGL final : public RasterizerCache<Surface> {
|
class RasterizerCacheOpenGL final : public RasterizerCache<Surface> {
|
||||||
|
|||||||
Reference in New Issue
Block a user