summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/gsp_gpu.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp30
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h3
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
181bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, 178bool 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