diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 30 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 3 |
4 files changed, 29 insertions, 19 deletions
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 710e0e485..78cb761be 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -346,7 +346,7 @@ static void SetAxiConfigQoSMode(Service::Interface* self) { | |||
| 346 | 346 | ||
| 347 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 347 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 348 | 348 | ||
| 349 | LOG_WARNING(Service_GSP, "(STUBBED) called mode=0x%08X", mode); | 349 | LOG_DEBUG(Service_GSP, "(STUBBED) called mode=0x%08X", mode); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | /** | 352 | /** |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 1b734aaa5..3f2255e06 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -715,7 +715,11 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe | |||
| 715 | 715 | ||
| 716 | CachedSurface src_params; | 716 | CachedSurface src_params; |
| 717 | src_params.addr = config.GetPhysicalInputAddress(); | 717 | src_params.addr = config.GetPhysicalInputAddress(); |
| 718 | src_params.width = config.output_width; | 718 | // It's important to use the correct source input width to properly skip over parts of the input |
| 719 | // image which will be cropped from the output but still affect the stride of the input image. | ||
| 720 | src_params.width = config.input_width; | ||
| 721 | // Using the output's height is fine because we don't read or skip over the remaining part of | ||
| 722 | // the image, and it allows for smaller texture cache lookup rectangles. | ||
| 719 | src_params.height = config.output_height; | 723 | src_params.height = config.output_height; |
| 720 | src_params.is_tiled = !config.input_linear; | 724 | src_params.is_tiled = !config.input_linear; |
| 721 | src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.input_format); | 725 | src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.input_format); |
| @@ -736,6 +740,11 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe | |||
| 736 | return false; | 740 | return false; |
| 737 | } | 741 | } |
| 738 | 742 | ||
| 743 | // Adjust the source rectangle to take into account parts of the input lines being cropped | ||
| 744 | if (config.input_width > config.output_width) { | ||
| 745 | src_rect.right -= (config.input_width - config.output_width) * src_surface->res_scale_width; | ||
| 746 | } | ||
| 747 | |||
| 739 | // Require destination surface to have same resolution scale as source to preserve scaling | 748 | // Require destination surface to have same resolution scale as source to preserve scaling |
| 740 | dst_params.res_scale_width = src_surface->res_scale_width; | 749 | dst_params.res_scale_width = src_surface->res_scale_width; |
| 741 | dst_params.res_scale_height = src_surface->res_scale_height; | 750 | dst_params.res_scale_height = src_surface->res_scale_height; |
| @@ -938,7 +947,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con | |||
| 938 | src_params.addr = framebuffer_addr; | 947 | src_params.addr = framebuffer_addr; |
| 939 | src_params.width = config.width; | 948 | src_params.width = config.width; |
| 940 | src_params.height = config.height; | 949 | src_params.height = config.height; |
| 941 | src_params.stride = pixel_stride; | 950 | src_params.pixel_stride = pixel_stride; |
| 942 | src_params.is_tiled = false; | 951 | src_params.is_tiled = false; |
| 943 | src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.color_format); | 952 | src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.color_format); |
| 944 | 953 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 5cbad9b43..61f6e767f 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, | |||
| 158 | buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; | 158 | buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | if (OpenGLState::CheckFBStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | 161 | bool can_blit = OpenGLState::CheckFBStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE && |
| 162 | return false; | 162 | OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; |
| 163 | } | ||
| 164 | 163 | ||
| 165 | if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | 164 | if (can_blit) { |
| 166 | return false; | 165 | glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, |
| 166 | dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, | ||
| 167 | buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); | ||
| 167 | } | 168 | } |
| 168 | 169 | ||
| 169 | glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, dst_rect.left, | ||
| 170 | dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, | ||
| 171 | buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); | ||
| 172 | |||
| 173 | // Restore previous framebuffer bindings | 170 | // Restore previous framebuffer bindings |
| 174 | cur_state.draw.read_framebuffer = old_fbs[0]; | 171 | cur_state.draw.read_framebuffer = old_fbs[0]; |
| 175 | cur_state.draw.draw_framebuffer = old_fbs[1]; | 172 | cur_state.draw.draw_framebuffer = old_fbs[1]; |
| 176 | cur_state.Apply(); | 173 | cur_state.Apply(); |
| 177 | 174 | ||
| 178 | return true; | 175 | return can_blit; |
| 179 | } | 176 | } |
| 180 | 177 | ||
| 181 | bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, | 178 | bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, |
| @@ -291,6 +288,9 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo | |||
| 291 | 288 | ||
| 292 | MICROPROFILE_SCOPE(OpenGL_SurfaceUpload); | 289 | MICROPROFILE_SCOPE(OpenGL_SurfaceUpload); |
| 293 | 290 | ||
| 291 | // Stride only applies to linear images. | ||
| 292 | ASSERT(params.pixel_stride == 0 || !params.is_tiled); | ||
| 293 | |||
| 294 | std::shared_ptr<CachedSurface> new_surface = std::make_shared<CachedSurface>(); | 294 | std::shared_ptr<CachedSurface> new_surface = std::make_shared<CachedSurface>(); |
| 295 | 295 | ||
| 296 | new_surface->addr = params.addr; | 296 | new_surface->addr = params.addr; |
| @@ -299,7 +299,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo | |||
| 299 | new_surface->texture.Create(); | 299 | new_surface->texture.Create(); |
| 300 | new_surface->width = params.width; | 300 | new_surface->width = params.width; |
| 301 | new_surface->height = params.height; | 301 | new_surface->height = params.height; |
| 302 | new_surface->stride = params.stride; | 302 | new_surface->pixel_stride = params.pixel_stride; |
| 303 | new_surface->res_scale_width = params.res_scale_width; | 303 | new_surface->res_scale_width = params.res_scale_width; |
| 304 | new_surface->res_scale_height = params.res_scale_height; | 304 | new_surface->res_scale_height = params.res_scale_height; |
| 305 | 305 | ||
| @@ -325,14 +325,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo | |||
| 325 | cur_state.Apply(); | 325 | cur_state.Apply(); |
| 326 | glActiveTexture(GL_TEXTURE0); | 326 | glActiveTexture(GL_TEXTURE0); |
| 327 | 327 | ||
| 328 | glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->stride); | ||
| 329 | if (!new_surface->is_tiled) { | 328 | if (!new_surface->is_tiled) { |
| 330 | // TODO: Ensure this will always be a color format, not a depth or other format | 329 | // TODO: Ensure this will always be a color format, not a depth or other format |
| 331 | ASSERT((size_t)new_surface->pixel_format < fb_format_tuples.size()); | 330 | ASSERT((size_t)new_surface->pixel_format < fb_format_tuples.size()); |
| 332 | const FormatTuple& tuple = fb_format_tuples[(unsigned int)params.pixel_format]; | 331 | const FormatTuple& tuple = fb_format_tuples[(unsigned int)params.pixel_format]; |
| 333 | 332 | ||
| 333 | glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->pixel_stride); | ||
| 334 | glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, | 334 | glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, |
| 335 | tuple.format, tuple.type, texture_src_data); | 335 | tuple.format, tuple.type, texture_src_data); |
| 336 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | ||
| 336 | } else { | 337 | } else { |
| 337 | SurfaceType type = CachedSurface::GetFormatType(new_surface->pixel_format); | 338 | SurfaceType type = CachedSurface::GetFormatType(new_surface->pixel_format); |
| 338 | if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { | 339 | if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { |
| @@ -391,7 +392,6 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo | |||
| 391 | 0, tuple.format, tuple.type, temp_fb_depth_buffer.data()); | 392 | 0, tuple.format, tuple.type, temp_fb_depth_buffer.data()); |
| 392 | } | 393 | } |
| 393 | } | 394 | } |
| 394 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | ||
| 395 | 395 | ||
| 396 | // If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface | 396 | // If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface |
| 397 | if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) { | 397 | if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) { |
| @@ -701,13 +701,14 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { | |||
| 701 | cur_state.Apply(); | 701 | cur_state.Apply(); |
| 702 | glActiveTexture(GL_TEXTURE0); | 702 | glActiveTexture(GL_TEXTURE0); |
| 703 | 703 | ||
| 704 | glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->stride); | ||
| 705 | if (!surface->is_tiled) { | 704 | if (!surface->is_tiled) { |
| 706 | // TODO: Ensure this will always be a color format, not a depth or other format | 705 | // TODO: Ensure this will always be a color format, not a depth or other format |
| 707 | ASSERT((size_t)surface->pixel_format < fb_format_tuples.size()); | 706 | ASSERT((size_t)surface->pixel_format < fb_format_tuples.size()); |
| 708 | const FormatTuple& tuple = fb_format_tuples[(unsigned int)surface->pixel_format]; | 707 | const FormatTuple& tuple = fb_format_tuples[(unsigned int)surface->pixel_format]; |
| 709 | 708 | ||
| 709 | glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->pixel_stride); | ||
| 710 | glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, dst_buffer); | 710 | glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, dst_buffer); |
| 711 | glPixelStorei(GL_PACK_ROW_LENGTH, 0); | ||
| 711 | } else { | 712 | } else { |
| 712 | SurfaceType type = CachedSurface::GetFormatType(surface->pixel_format); | 713 | SurfaceType type = CachedSurface::GetFormatType(surface->pixel_format); |
| 713 | if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { | 714 | if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { |
| @@ -750,7 +751,6 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { | |||
| 750 | false); | 751 | false); |
| 751 | } | 752 | } |
| 752 | } | 753 | } |
| 753 | glPixelStorei(GL_PACK_ROW_LENGTH, 0); | ||
| 754 | 754 | ||
| 755 | surface->dirty = false; | 755 | surface->dirty = false; |
| 756 | 756 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 849530d86..32abfbaf5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -171,7 +171,8 @@ struct CachedSurface { | |||
| 171 | OGLTexture texture; | 171 | OGLTexture texture; |
| 172 | u32 width; | 172 | u32 width; |
| 173 | u32 height; | 173 | u32 height; |
| 174 | u32 stride = 0; | 174 | /// Stride between lines, in pixels. Only valid for images in linear format. |
| 175 | u32 pixel_stride = 0; | ||
| 175 | float res_scale_width = 1.f; | 176 | float res_scale_width = 1.f; |
| 176 | float res_scale_height = 1.f; | 177 | float res_scale_height = 1.f; |
| 177 | 178 | ||