summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-28 21:56:21 -0500
committerGravatar bunnei2018-11-28 21:56:21 -0500
commit3d3cc35ee76c4cfda01865ef1ed68d83969d6df1 (patch)
tree2cd0922a2b4f94a9a865b2297c7140244cc29428 /src
parentMerge pull request #1808 from Tinob/master (diff)
downloadyuzu-3d3cc35ee76c4cfda01865ef1ed68d83969d6df1.tar.gz
yuzu-3d3cc35ee76c4cfda01865ef1ed68d83969d6df1.tar.xz
yuzu-3d3cc35ee76c4cfda01865ef1ed68d83969d6df1.zip
gl_rasterizer_cache: Remove BlitSurface and replace with more accurate copy.
- BlitSurface with different texture targets is inherently broken. - When target is the same, we can just use FastCopySurface. - Fixes rendering issues with Breath of the Wild.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp145
1 files changed, 1 insertions, 144 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index dde2f468d..6b024d9d0 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -405,138 +405,6 @@ void SwizzleFunc(const MortonSwizzleMode& mode, const SurfaceParams& params,
405 } 405 }
406} 406}
407 407
408MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64));
409static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
410 GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0,
411 GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
412 MICROPROFILE_SCOPE(OpenGL_BlitSurface);
413
414 const auto& src_params{src_surface->GetSurfaceParams()};
415 const auto& dst_params{dst_surface->GetSurfaceParams()};
416
417 OpenGLState prev_state{OpenGLState::GetCurState()};
418 SCOPE_EXIT({ prev_state.Apply(); });
419
420 OpenGLState state;
421 state.draw.read_framebuffer = read_fb_handle;
422 state.draw.draw_framebuffer = draw_fb_handle;
423 // Set sRGB enabled if the destination surfaces need it
424 state.framebuffer_srgb.enabled = dst_params.srgb_conversion;
425 state.ApplyFramebufferState();
426
427 u32 buffers{};
428
429 if (src_params.type == SurfaceType::ColorTexture) {
430 switch (src_params.target) {
431 case SurfaceTarget::Texture2D:
432 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
433 GL_TEXTURE_2D, src_surface->Texture().handle, 0);
434 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
435 0, 0);
436 break;
437 case SurfaceTarget::TextureCubemap:
438 glFramebufferTexture2D(
439 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
440 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face),
441 src_surface->Texture().handle, 0);
442 glFramebufferTexture2D(
443 GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
444 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
445 break;
446 case SurfaceTarget::Texture2DArray:
447 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
448 src_surface->Texture().handle, 0, 0);
449 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
450 break;
451 case SurfaceTarget::Texture3D:
452 glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
453 SurfaceTargetToGL(src_params.target),
454 src_surface->Texture().handle, 0, 0);
455 glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
456 SurfaceTargetToGL(src_params.target), 0, 0, 0);
457 break;
458 default:
459 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
460 GL_TEXTURE_2D, src_surface->Texture().handle, 0);
461 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
462 0, 0);
463 break;
464 }
465
466 switch (dst_params.target) {
467 case SurfaceTarget::Texture2D:
468 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
469 GL_TEXTURE_2D, dst_surface->Texture().handle, 0);
470 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
471 0, 0);
472 break;
473 case SurfaceTarget::TextureCubemap:
474 glFramebufferTexture2D(
475 GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
476 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face),
477 dst_surface->Texture().handle, 0);
478 glFramebufferTexture2D(
479 GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
480 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
481 break;
482 case SurfaceTarget::Texture2DArray:
483 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
484 dst_surface->Texture().handle, 0, 0);
485 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
486 break;
487
488 case SurfaceTarget::Texture3D:
489 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
490 SurfaceTargetToGL(dst_params.target),
491 dst_surface->Texture().handle, 0, 0);
492 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
493 SurfaceTargetToGL(dst_params.target), 0, 0, 0);
494 break;
495 default:
496 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
497 GL_TEXTURE_2D, dst_surface->Texture().handle, 0);
498 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
499 0, 0);
500 break;
501 }
502
503 buffers = GL_COLOR_BUFFER_BIT;
504 } else if (src_params.type == SurfaceType::Depth) {
505 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
506 GL_TEXTURE_2D, 0, 0);
507 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
508 src_surface->Texture().handle, 0);
509 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
510
511 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
512 GL_TEXTURE_2D, 0, 0);
513 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
514 dst_surface->Texture().handle, 0);
515 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
516
517 buffers = GL_DEPTH_BUFFER_BIT;
518 } else if (src_params.type == SurfaceType::DepthStencil) {
519 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
520 GL_TEXTURE_2D, 0, 0);
521 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
522 src_surface->Texture().handle, 0);
523
524 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
525 GL_TEXTURE_2D, 0, 0);
526 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
527 dst_surface->Texture().handle, 0);
528
529 buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
530 }
531
532 const auto& rect{src_params.GetRect()};
533 glBlitFramebuffer(rect.left, rect.bottom, rect.right, rect.top, rect.left, rect.bottom,
534 rect.right, rect.top, buffers,
535 buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST);
536
537 return true;
538}
539
540static void FastCopySurface(const Surface& src_surface, const Surface& dst_surface) { 408static void FastCopySurface(const Surface& src_surface, const Surface& dst_surface) {
541 const auto& src_params{src_surface->GetSurfaceParams()}; 409 const auto& src_params{src_surface->GetSurfaceParams()};
542 const auto& dst_params{dst_surface->GetSurfaceParams()}; 410 const auto& dst_params{dst_surface->GetSurfaceParams()};
@@ -1189,20 +1057,9 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
1189 return new_surface; 1057 return new_surface;
1190 } 1058 }
1191 1059
1192 // If the format is the same, just do a framebuffer blit. This is significantly faster than
1193 // using PBOs. The is also likely less accurate, as textures will be converted rather than
1194 // reinterpreted. When use_accurate_gpu_emulation setting is enabled, perform a more accurate
1195 // surface copy, where pixels are reinterpreted as a new format (without conversion). This
1196 // code path uses OpenGL PBOs and is quite slow.
1197 const bool is_blit{old_params.pixel_format == new_params.pixel_format};
1198
1199 switch (new_params.target) { 1060 switch (new_params.target) {
1200 case SurfaceTarget::Texture2D: 1061 case SurfaceTarget::Texture2D:
1201 if (is_blit) { 1062 CopySurface(old_surface, new_surface, copy_pbo.handle);
1202 BlitSurface(old_surface, new_surface, read_framebuffer.handle, draw_framebuffer.handle);
1203 } else {
1204 CopySurface(old_surface, new_surface, copy_pbo.handle);
1205 }
1206 break; 1063 break;
1207 case SurfaceTarget::Texture3D: 1064 case SurfaceTarget::Texture3D:
1208 AccurateCopySurface(old_surface, new_surface); 1065 AccurateCopySurface(old_surface, new_surface);