summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp150
1 files changed, 5 insertions, 145 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..2fbc753af 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()};
@@ -1163,7 +1031,10 @@ void RasterizerCacheOpenGL::AccurateCopySurface(const Surface& src_surface,
1163 const Surface& dst_surface) { 1031 const Surface& dst_surface) {
1164 const auto& src_params{src_surface->GetSurfaceParams()}; 1032 const auto& src_params{src_surface->GetSurfaceParams()};
1165 const auto& dst_params{dst_surface->GetSurfaceParams()}; 1033 const auto& dst_params{dst_surface->GetSurfaceParams()};
1166 FlushRegion(src_params.addr, dst_params.MemorySize()); 1034
1035 // Flush enough memory for both the source and destination surface
1036 FlushRegion(src_params.addr, std::max(src_params.MemorySize(), dst_params.MemorySize()));
1037
1167 LoadSurface(dst_surface); 1038 LoadSurface(dst_surface);
1168} 1039}
1169 1040
@@ -1189,20 +1060,9 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
1189 return new_surface; 1060 return new_surface;
1190 } 1061 }
1191 1062
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) { 1063 switch (new_params.target) {
1200 case SurfaceTarget::Texture2D: 1064 case SurfaceTarget::Texture2D:
1201 if (is_blit) { 1065 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; 1066 break;
1207 case SurfaceTarget::Texture3D: 1067 case SurfaceTarget::Texture3D:
1208 AccurateCopySurface(old_surface, new_surface); 1068 AccurateCopySurface(old_surface, new_surface);