From 2600633b895ad06efb316ed0e3205f8adcaa96da Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 4 Dec 2016 05:16:14 -0800 Subject: OpenGL: Ensure framebuffer binding is restored if completion check fails --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 5cbad9b43..9ee3bb2ac 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -158,24 +158,21 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; } - if (OpenGLState::CheckFBStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; - } + bool can_blit = OpenGLState::CheckFBStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE && + OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; - if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; + if (can_blit) { + glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, + dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, + buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); } - glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, dst_rect.left, - dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, - buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); - // Restore previous framebuffer bindings cur_state.draw.read_framebuffer = old_fbs[0]; cur_state.draw.draw_framebuffer = old_fbs[1]; cur_state.Apply(); - return true; + return can_blit; } bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, -- cgit v1.2.3 From 8a1f96011daa6e7b386d6f9f024a1ccf5eb95366 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 4 Dec 2016 05:16:56 -0800 Subject: OpenGL: Non-zero stride only makes sense for linear buffers --- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 9ee3bb2ac..61f6e767f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -288,6 +288,9 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo MICROPROFILE_SCOPE(OpenGL_SurfaceUpload); + // Stride only applies to linear images. + ASSERT(params.pixel_stride == 0 || !params.is_tiled); + std::shared_ptr new_surface = std::make_shared(); new_surface->addr = params.addr; @@ -296,7 +299,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo new_surface->texture.Create(); new_surface->width = params.width; new_surface->height = params.height; - new_surface->stride = params.stride; + new_surface->pixel_stride = params.pixel_stride; new_surface->res_scale_width = params.res_scale_width; new_surface->res_scale_height = params.res_scale_height; @@ -322,14 +325,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo cur_state.Apply(); glActiveTexture(GL_TEXTURE0); - glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->stride); if (!new_surface->is_tiled) { // TODO: Ensure this will always be a color format, not a depth or other format ASSERT((size_t)new_surface->pixel_format < fb_format_tuples.size()); const FormatTuple& tuple = fb_format_tuples[(unsigned int)params.pixel_format]; + glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->pixel_stride); glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, tuple.format, tuple.type, texture_src_data); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { SurfaceType type = CachedSurface::GetFormatType(new_surface->pixel_format); if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { @@ -388,7 +392,6 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo 0, tuple.format, tuple.type, temp_fb_depth_buffer.data()); } } - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) { @@ -698,13 +701,14 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { cur_state.Apply(); glActiveTexture(GL_TEXTURE0); - glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->stride); if (!surface->is_tiled) { // TODO: Ensure this will always be a color format, not a depth or other format ASSERT((size_t)surface->pixel_format < fb_format_tuples.size()); const FormatTuple& tuple = fb_format_tuples[(unsigned int)surface->pixel_format]; + glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->pixel_stride); glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, dst_buffer); + glPixelStorei(GL_PACK_ROW_LENGTH, 0); } else { SurfaceType type = CachedSurface::GetFormatType(surface->pixel_format); if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { @@ -747,7 +751,6 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { false); } } - glPixelStorei(GL_PACK_ROW_LENGTH, 0); surface->dirty = false; -- cgit v1.2.3