diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 150 |
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 | ||
| 408 | MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64)); | ||
| 409 | static 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 | |||
| 540 | static void FastCopySurface(const Surface& src_surface, const Surface& dst_surface) { | 408 | static 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); |