Răsfoiți Sursa

OpenGL: Non-zero stride only makes sense for linear buffers

Yuri Kunde Schlesner 9 ani în urmă
părinte
comite
8a1f96011d

+ 1 - 1
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -947,7 +947,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
     src_params.addr = framebuffer_addr;
     src_params.width = config.width;
     src_params.height = config.height;
-    src_params.stride = pixel_stride;
+    src_params.pixel_stride = pixel_stride;
     src_params.is_tiled = false;
     src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.color_format);
 

+ 8 - 5
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<CachedSurface> new_surface = std::make_shared<CachedSurface>();
 
     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;
 

+ 2 - 1
src/video_core/renderer_opengl/gl_rasterizer_cache.h

@@ -171,7 +171,8 @@ struct CachedSurface {
     OGLTexture texture;
     u32 width;
     u32 height;
-    u32 stride = 0;
+    /// Stride between lines, in pixels. Only valid for images in linear format.
+    u32 pixel_stride = 0;
     float res_scale_width = 1.f;
     float res_scale_height = 1.f;