diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 114 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 68 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 11 |
5 files changed, 95 insertions, 132 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index f59d01738..d3be900a4 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -533,7 +533,11 @@ public: | |||
| 533 | u32 stencil_back_mask; | 533 | u32 stencil_back_mask; |
| 534 | u32 stencil_back_func_mask; | 534 | u32 stencil_back_func_mask; |
| 535 | 535 | ||
| 536 | INSERT_PADDING_WORDS(0x20); | 536 | INSERT_PADDING_WORDS(0x13); |
| 537 | |||
| 538 | u32 rt_separate_frag_data; | ||
| 539 | |||
| 540 | INSERT_PADDING_WORDS(0xC); | ||
| 537 | 541 | ||
| 538 | struct { | 542 | struct { |
| 539 | u32 address_high; | 543 | u32 address_high; |
| @@ -557,7 +561,22 @@ public: | |||
| 557 | struct { | 561 | struct { |
| 558 | union { | 562 | union { |
| 559 | BitField<0, 4, u32> count; | 563 | BitField<0, 4, u32> count; |
| 564 | BitField<4, 3, u32> map_0; | ||
| 565 | BitField<7, 3, u32> map_1; | ||
| 566 | BitField<10, 3, u32> map_2; | ||
| 567 | BitField<13, 3, u32> map_3; | ||
| 568 | BitField<16, 3, u32> map_4; | ||
| 569 | BitField<19, 3, u32> map_5; | ||
| 570 | BitField<22, 3, u32> map_6; | ||
| 571 | BitField<25, 3, u32> map_7; | ||
| 560 | }; | 572 | }; |
| 573 | |||
| 574 | u32 GetMap(size_t index) const { | ||
| 575 | const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3, | ||
| 576 | map_4, map_5, map_6, map_7}; | ||
| 577 | ASSERT(index < maps.size()); | ||
| 578 | return maps[index]; | ||
| 579 | } | ||
| 561 | } rt_control; | 580 | } rt_control; |
| 562 | 581 | ||
| 563 | INSERT_PADDING_WORDS(0x2); | 582 | INSERT_PADDING_WORDS(0x2); |
| @@ -968,6 +987,7 @@ ASSERT_REG_POSITION(clear_stencil, 0x368); | |||
| 968 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); | 987 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); |
| 969 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); | 988 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); |
| 970 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); | 989 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); |
| 990 | ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); | ||
| 971 | ASSERT_REG_POSITION(zeta, 0x3F8); | 991 | ASSERT_REG_POSITION(zeta, 0x3F8); |
| 972 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); | 992 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); |
| 973 | ASSERT_REG_POSITION(rt_control, 0x487); | 993 | ASSERT_REG_POSITION(rt_control, 0x487); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e6d6917fa..c7e2c877c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -294,17 +294,10 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | |||
| 294 | cached_pages.add({pages_interval, delta}); | 294 | cached_pages.add({pages_interval, delta}); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, | 297 | void RasterizerOpenGL::ConfigureFramebuffers(bool using_depth_fb, bool preserve_contents) { |
| 298 | bool using_depth_fb, | ||
| 299 | bool preserve_contents) { | ||
| 300 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); | 298 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); |
| 301 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 299 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 302 | 300 | ||
| 303 | if (regs.rt[0].format == Tegra::RenderTargetFormat::NONE) { | ||
| 304 | LOG_ERROR(HW_GPU, "RenderTargetFormat is not configured"); | ||
| 305 | using_color_fb = false; | ||
| 306 | } | ||
| 307 | |||
| 308 | const bool has_stencil = regs.stencil_enable; | 301 | const bool has_stencil = regs.stencil_enable; |
| 309 | const bool write_color_fb = | 302 | const bool write_color_fb = |
| 310 | state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || | 303 | state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || |
| @@ -314,41 +307,52 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c | |||
| 314 | (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) || | 307 | (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) || |
| 315 | (has_stencil && (state.stencil.front.write_mask || state.stencil.back.write_mask)); | 308 | (has_stencil && (state.stencil.front.write_mask || state.stencil.back.write_mask)); |
| 316 | 309 | ||
| 317 | Surface color_surface; | ||
| 318 | Surface depth_surface; | 310 | Surface depth_surface; |
| 319 | MathUtil::Rectangle<u32> surfaces_rect; | 311 | if (using_depth_fb) { |
| 320 | std::tie(color_surface, depth_surface, surfaces_rect) = | 312 | depth_surface = res_cache.GetDepthBufferSurface(preserve_contents); |
| 321 | res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, preserve_contents); | 313 | } |
| 322 | 314 | ||
| 323 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 315 | // TODO(bunnei): Figure out how the below register works. According to envytools, this should be |
| 324 | const MathUtil::Rectangle<u32> draw_rect{ | 316 | // used to enable multiple render targets. However, it is left unset on all games that I have |
| 325 | static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left, | 317 | // tested. |
| 326 | surfaces_rect.left, surfaces_rect.right)), // Left | 318 | ASSERT_MSG(regs.rt_separate_frag_data == 0, "Unimplemented"); |
| 327 | static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top, | ||
| 328 | surfaces_rect.bottom, surfaces_rect.top)), // Top | ||
| 329 | static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.right, | ||
| 330 | surfaces_rect.left, surfaces_rect.right)), // Right | ||
| 331 | static_cast<u32>( | ||
| 332 | std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.bottom, | ||
| 333 | surfaces_rect.bottom, surfaces_rect.top))}; // Bottom | ||
| 334 | 319 | ||
| 335 | // Bind the framebuffer surfaces | 320 | // Bind the framebuffer surfaces |
| 336 | BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); | 321 | state.draw.draw_framebuffer = framebuffer.handle; |
| 322 | state.Apply(); | ||
| 337 | 323 | ||
| 338 | SyncViewport(surfaces_rect); | 324 | std::array<GLenum, Maxwell::NumRenderTargets> buffers; |
| 325 | for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) { | ||
| 326 | Surface color_surface = res_cache.GetColorBufferSurface(index, preserve_contents); | ||
| 327 | buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index); | ||
| 328 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, | ||
| 329 | GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index), GL_TEXTURE_2D, | ||
| 330 | color_surface != nullptr ? color_surface->Texture().handle : 0, 0); | ||
| 331 | } | ||
| 339 | 332 | ||
| 340 | // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable | 333 | glDrawBuffers(regs.rt_control.count, buffers.data()); |
| 341 | // scissor test to prevent drawing outside of the framebuffer region | 334 | |
| 342 | state.scissor.enabled = true; | 335 | if (depth_surface) { |
| 343 | state.scissor.x = draw_rect.left; | 336 | if (has_stencil) { |
| 344 | state.scissor.y = draw_rect.bottom; | 337 | // Attach both depth and stencil |
| 345 | state.scissor.width = draw_rect.GetWidth(); | 338 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, |
| 346 | state.scissor.height = draw_rect.GetHeight(); | 339 | depth_surface->Texture().handle, 0); |
| 347 | state.Apply(); | 340 | } else { |
| 341 | // Attach depth | ||
| 342 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, | ||
| 343 | depth_surface->Texture().handle, 0); | ||
| 344 | // Clear stencil attachment | ||
| 345 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); | ||
| 346 | } | ||
| 347 | } else { | ||
| 348 | // Clear both depth and stencil attachment | ||
| 349 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, | ||
| 350 | 0); | ||
| 351 | } | ||
| 352 | |||
| 353 | SyncViewport(); | ||
| 348 | 354 | ||
| 349 | // Only return the surface to be marked as dirty if writing to it is enabled. | 355 | state.Apply(); |
| 350 | return std::make_pair(write_color_fb ? color_surface : nullptr, | ||
| 351 | write_depth_fb ? depth_surface : nullptr); | ||
| 352 | } | 356 | } |
| 353 | 357 | ||
| 354 | void RasterizerOpenGL::Clear() { | 358 | void RasterizerOpenGL::Clear() { |
| @@ -407,8 +411,7 @@ void RasterizerOpenGL::Clear() { | |||
| 407 | 411 | ||
| 408 | ScopeAcquireGLContext acquire_context{emu_window}; | 412 | ScopeAcquireGLContext acquire_context{emu_window}; |
| 409 | 413 | ||
| 410 | auto [dirty_color_surface, dirty_depth_surface] = | 414 | ConfigureFramebuffers(use_depth_fb, false); |
| 411 | ConfigureFramebuffers(use_color_fb, use_depth_fb, false); | ||
| 412 | 415 | ||
| 413 | clear_state.Apply(); | 416 | clear_state.Apply(); |
| 414 | 417 | ||
| @@ -430,8 +433,7 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 430 | 433 | ||
| 431 | ScopeAcquireGLContext acquire_context{emu_window}; | 434 | ScopeAcquireGLContext acquire_context{emu_window}; |
| 432 | 435 | ||
| 433 | const auto [dirty_color_surface, dirty_depth_surface] = | 436 | ConfigureFramebuffers(true, true); |
| 434 | ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true); | ||
| 435 | 437 | ||
| 436 | SyncDepthTestState(); | 438 | SyncDepthTestState(); |
| 437 | SyncStencilTestState(); | 439 | SyncStencilTestState(); |
| @@ -729,38 +731,12 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, | |||
| 729 | return current_unit + static_cast<u32>(entries.size()); | 731 | return current_unit + static_cast<u32>(entries.size()); |
| 730 | } | 732 | } |
| 731 | 733 | ||
| 732 | void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface, | 734 | void RasterizerOpenGL::SyncViewport() { |
| 733 | const Surface& depth_surface, bool has_stencil) { | ||
| 734 | state.draw.draw_framebuffer = framebuffer.handle; | ||
| 735 | state.Apply(); | ||
| 736 | |||
| 737 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | ||
| 738 | color_surface != nullptr ? color_surface->Texture().handle : 0, 0); | ||
| 739 | if (depth_surface != nullptr) { | ||
| 740 | if (has_stencil) { | ||
| 741 | // attach both depth and stencil | ||
| 742 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, | ||
| 743 | depth_surface->Texture().handle, 0); | ||
| 744 | } else { | ||
| 745 | // attach depth | ||
| 746 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, | ||
| 747 | depth_surface->Texture().handle, 0); | ||
| 748 | // clear stencil attachment | ||
| 749 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); | ||
| 750 | } | ||
| 751 | } else { | ||
| 752 | // clear both depth and stencil attachment | ||
| 753 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, | ||
| 754 | 0); | ||
| 755 | } | ||
| 756 | } | ||
| 757 | |||
| 758 | void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect) { | ||
| 759 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 735 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 760 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 736 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; |
| 761 | 737 | ||
| 762 | state.viewport.x = static_cast<GLint>(surfaces_rect.left) + viewport_rect.left; | 738 | state.viewport.x = viewport_rect.left; |
| 763 | state.viewport.y = static_cast<GLint>(surfaces_rect.bottom) + viewport_rect.bottom; | 739 | state.viewport.y = viewport_rect.bottom; |
| 764 | state.viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth()); | 740 | state.viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth()); |
| 765 | state.viewport.height = static_cast<GLsizei>(viewport_rect.GetHeight()); | 741 | state.viewport.height = static_cast<GLsizei>(viewport_rect.GetHeight()); |
| 766 | } | 742 | } |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index c6bb1516b..3d62cc196 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -97,14 +97,8 @@ private: | |||
| 97 | GLvec4 border_color; | 97 | GLvec4 border_color; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | /// Configures the color and depth framebuffer states and returns the dirty <Color, Depth> | 100 | /// Configures the color and depth framebuffer states |
| 101 | /// surfaces if writing was enabled. | 101 | void ConfigureFramebuffers(bool using_depth_fb, bool preserve_contents); |
| 102 | std::pair<Surface, Surface> ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, | ||
| 103 | bool preserve_contents); | ||
| 104 | |||
| 105 | /// Binds the framebuffer color and depth surface | ||
| 106 | void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface, | ||
| 107 | bool has_stencil); | ||
| 108 | 102 | ||
| 109 | /* | 103 | /* |
| 110 | * Configures the current constbuffers to use for the draw command. | 104 | * Configures the current constbuffers to use for the draw command. |
| @@ -127,7 +121,7 @@ private: | |||
| 127 | u32 current_unit); | 121 | u32 current_unit); |
| 128 | 122 | ||
| 129 | /// Syncs the viewport to match the guest state | 123 | /// Syncs the viewport to match the guest state |
| 130 | void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect); | 124 | void SyncViewport(); |
| 131 | 125 | ||
| 132 | /// Syncs the clip enabled status to match the guest state | 126 | /// Syncs the clip enabled status to match the guest state |
| 133 | void SyncClipEnabled(); | 127 | void SyncClipEnabled(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index fa730b9e6..20a8e1cda 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -61,8 +61,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 61 | return params; | 61 | return params; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer( | 64 | /*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(size_t index) { |
| 65 | const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config) { | 65 | const auto& config{Core::System::GetInstance().GPU().Maxwell3D().regs.rt[index]}; |
| 66 | SurfaceParams params{}; | 66 | SurfaceParams params{}; |
| 67 | params.addr = TryGetCpuAddr(config.Address()); | 67 | params.addr = TryGetCpuAddr(config.Address()); |
| 68 | params.is_tiled = true; | 68 | params.is_tiled = true; |
| @@ -708,62 +708,34 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||
| 708 | return GetSurface(SurfaceParams::CreateForTexture(config)); | 708 | return GetSurface(SurfaceParams::CreateForTexture(config)); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool using_color_fb, | 711 | Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) { |
| 712 | bool using_depth_fb, | 712 | const auto& regs{Core::System::GetInstance().GPU().Maxwell3D().regs}; |
| 713 | bool preserve_contents) { | 713 | if (!regs.zeta.Address() || !regs.zeta_enable) { |
| 714 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 714 | return {}; |
| 715 | } | ||
| 715 | 716 | ||
| 716 | // TODO(bunnei): This is hard corded to use just the first render buffer | 717 | SurfaceParams depth_params{SurfaceParams::CreateForDepthBuffer( |
| 717 | LOG_TRACE(Render_OpenGL, "hard-coded for render target 0!"); | 718 | regs.zeta_width, regs.zeta_height, regs.zeta.Address(), regs.zeta.format)}; |
| 718 | 719 | ||
| 719 | // get color and depth surfaces | 720 | return GetSurface(depth_params, preserve_contents); |
| 720 | SurfaceParams color_params{}; | 721 | } |
| 721 | SurfaceParams depth_params{}; | ||
| 722 | 722 | ||
| 723 | if (using_color_fb) { | 723 | Surface RasterizerCacheOpenGL::GetColorBufferSurface(size_t index, bool preserve_contents) { |
| 724 | color_params = SurfaceParams::CreateForFramebuffer(regs.rt[0]); | 724 | const auto& regs{Core::System::GetInstance().GPU().Maxwell3D().regs}; |
| 725 | } | ||
| 726 | 725 | ||
| 727 | if (using_depth_fb) { | 726 | ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); |
| 728 | depth_params = SurfaceParams::CreateForDepthBuffer(regs.zeta_width, regs.zeta_height, | ||
| 729 | regs.zeta.Address(), regs.zeta.format); | ||
| 730 | } | ||
| 731 | 727 | ||
| 732 | MathUtil::Rectangle<u32> color_rect{}; | 728 | if (index >= regs.rt_control.count) { |
| 733 | Surface color_surface; | 729 | return {}; |
| 734 | if (using_color_fb) { | ||
| 735 | color_surface = GetSurface(color_params, preserve_contents); | ||
| 736 | if (color_surface) { | ||
| 737 | color_rect = color_surface->GetSurfaceParams().GetRect(); | ||
| 738 | } | ||
| 739 | } | 730 | } |
| 740 | 731 | ||
| 741 | MathUtil::Rectangle<u32> depth_rect{}; | 732 | if (regs.rt[index].Address() == 0 || regs.rt[index].format == Tegra::RenderTargetFormat::NONE) { |
| 742 | Surface depth_surface; | 733 | return {}; |
| 743 | if (using_depth_fb) { | ||
| 744 | depth_surface = GetSurface(depth_params, preserve_contents); | ||
| 745 | if (depth_surface) { | ||
| 746 | depth_rect = depth_surface->GetSurfaceParams().GetRect(); | ||
| 747 | } | ||
| 748 | } | 734 | } |
| 749 | 735 | ||
| 750 | MathUtil::Rectangle<u32> fb_rect{}; | 736 | const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(index)}; |
| 751 | if (color_surface && depth_surface) { | ||
| 752 | fb_rect = color_rect; | ||
| 753 | // Color and Depth surfaces must have the same dimensions and offsets | ||
| 754 | if (color_rect.bottom != depth_rect.bottom || color_rect.top != depth_rect.top || | ||
| 755 | color_rect.left != depth_rect.left || color_rect.right != depth_rect.right) { | ||
| 756 | color_surface = GetSurface(color_params); | ||
| 757 | depth_surface = GetSurface(depth_params); | ||
| 758 | fb_rect = color_surface->GetSurfaceParams().GetRect(); | ||
| 759 | } | ||
| 760 | } else if (color_surface) { | ||
| 761 | fb_rect = color_rect; | ||
| 762 | } else if (depth_surface) { | ||
| 763 | fb_rect = depth_rect; | ||
| 764 | } | ||
| 765 | 737 | ||
| 766 | return std::make_tuple(color_surface, depth_surface, fb_rect); | 738 | return GetSurface(color_params, preserve_contents); |
| 767 | } | 739 | } |
| 768 | 740 | ||
| 769 | void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) { | 741 | void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 8312b2c7a..e215f260f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -669,8 +669,7 @@ struct SurfaceParams { | |||
| 669 | static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config); | 669 | static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config); |
| 670 | 670 | ||
| 671 | /// Creates SurfaceParams from a framebuffer configuration | 671 | /// Creates SurfaceParams from a framebuffer configuration |
| 672 | static SurfaceParams CreateForFramebuffer( | 672 | static SurfaceParams CreateForFramebuffer(size_t index); |
| 673 | const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config); | ||
| 674 | 673 | ||
| 675 | /// Creates SurfaceParams for a depth buffer configuration | 674 | /// Creates SurfaceParams for a depth buffer configuration |
| 676 | static SurfaceParams CreateForDepthBuffer(u32 zeta_width, u32 zeta_height, | 675 | static SurfaceParams CreateForDepthBuffer(u32 zeta_width, u32 zeta_height, |
| @@ -774,9 +773,11 @@ public: | |||
| 774 | /// Get a surface based on the texture configuration | 773 | /// Get a surface based on the texture configuration |
| 775 | Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); | 774 | Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); |
| 776 | 775 | ||
| 777 | /// Get the color and depth surfaces based on the framebuffer configuration | 776 | /// Get the depth surface based on the framebuffer configuration |
| 778 | SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, | 777 | Surface GetDepthBufferSurface(bool preserve_contents); |
| 779 | bool preserve_contents); | 778 | |
| 779 | /// Get the color surface based on the framebuffer configuration and the specified render target | ||
| 780 | Surface GetColorBufferSurface(size_t index, bool preserve_contents); | ||
| 780 | 781 | ||
| 781 | /// Flushes the surface to Switch memory | 782 | /// Flushes the surface to Switch memory |
| 782 | void FlushSurface(const Surface& surface); | 783 | void FlushSurface(const Surface& surface); |