summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_framebuffer_cache.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_framebuffer_cache.h1
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp88
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h38
4 files changed, 33 insertions, 121 deletions
diff --git a/src/video_core/renderer_opengl/gl_framebuffer_cache.cpp b/src/video_core/renderer_opengl/gl_framebuffer_cache.cpp
index 7c926bd48..a5d69d78d 100644
--- a/src/video_core/renderer_opengl/gl_framebuffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_framebuffer_cache.cpp
@@ -35,21 +35,16 @@ OGLFramebuffer FramebufferCacheOpenGL::CreateFramebuffer(const FramebufferCacheK
35 local_state.draw.draw_framebuffer = framebuffer.handle; 35 local_state.draw.draw_framebuffer = framebuffer.handle;
36 local_state.ApplyFramebufferState(); 36 local_state.ApplyFramebufferState();
37 37
38 if (key.is_single_buffer) { 38 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
39 if (key.color_attachments[0] != GL_NONE && key.colors[0]) { 39 if (key.colors[index]) {
40 key.colors[0]->Attach(key.color_attachments[0], GL_DRAW_FRAMEBUFFER); 40 key.colors[index]->Attach(GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
41 glDrawBuffer(key.color_attachments[0]); 41 GL_DRAW_FRAMEBUFFER);
42 } else {
43 glDrawBuffer(GL_NONE);
44 }
45 } else {
46 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
47 if (key.colors[index]) {
48 key.colors[index]->Attach(GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
49 GL_DRAW_FRAMEBUFFER);
50 }
51 } 42 }
43 }
44 if (key.colors_count) {
52 glDrawBuffers(key.colors_count, key.color_attachments.data()); 45 glDrawBuffers(key.colors_count, key.color_attachments.data());
46 } else {
47 glDrawBuffer(GL_NONE);
53 } 48 }
54 49
55 if (key.zeta) { 50 if (key.zeta) {
@@ -67,9 +62,9 @@ std::size_t FramebufferCacheKey::Hash() const {
67} 62}
68 63
69bool FramebufferCacheKey::operator==(const FramebufferCacheKey& rhs) const { 64bool FramebufferCacheKey::operator==(const FramebufferCacheKey& rhs) const {
70 return std::tie(is_single_buffer, stencil_enable, colors_count, color_attachments, colors, 65 return std::tie(stencil_enable, colors_count, color_attachments, colors, zeta) ==
71 zeta) == std::tie(rhs.is_single_buffer, rhs.stencil_enable, rhs.colors_count, 66 std::tie(rhs.stencil_enable, rhs.colors_count, rhs.color_attachments, rhs.colors,
72 rhs.color_attachments, rhs.colors, rhs.zeta); 67 rhs.zeta);
73} 68}
74 69
75} // namespace OpenGL 70} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_framebuffer_cache.h b/src/video_core/renderer_opengl/gl_framebuffer_cache.h
index a3a996353..424344c48 100644
--- a/src/video_core/renderer_opengl/gl_framebuffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_framebuffer_cache.h
@@ -19,7 +19,6 @@
19namespace OpenGL { 19namespace OpenGL {
20 20
21struct alignas(sizeof(u64)) FramebufferCacheKey { 21struct alignas(sizeof(u64)) FramebufferCacheKey {
22 bool is_single_buffer = false;
23 bool stencil_enable = false; 22 bool stencil_enable = false;
24 u16 colors_count = 0; 23 u16 colors_count = 0;
25 24
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4dd08bccb..a2c1473db 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -445,99 +445,51 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
445 shader_cache.LoadDiskCache(stop_loading, callback); 445 shader_cache.LoadDiskCache(stop_loading, callback);
446} 446}
447 447
448std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers( 448void RasterizerOpenGL::ConfigureFramebuffers() {
449 OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents,
450 std::optional<std::size_t> single_color_target) {
451 MICROPROFILE_SCOPE(OpenGL_Framebuffer); 449 MICROPROFILE_SCOPE(OpenGL_Framebuffer);
452 auto& gpu = system.GPU().Maxwell3D(); 450 auto& gpu = system.GPU().Maxwell3D();
453 const auto& regs = gpu.regs; 451 if (!gpu.dirty.render_settings) {
454 452 return;
455 const FramebufferConfigState fb_config_state{using_color_fb, using_depth_fb, preserve_contents,
456 single_color_target};
457 if (fb_config_state == current_framebuffer_config_state && !gpu.dirty.render_settings) {
458 // Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
459 // single color targets). This is done because the guest registers may not change but the
460 // host framebuffer may contain different attachments
461 return current_depth_stencil_usage;
462 } 453 }
463 gpu.dirty.render_settings = false; 454 gpu.dirty.render_settings = false;
464 current_framebuffer_config_state = fb_config_state;
465 455
466 texture_cache.GuardRenderTargets(true); 456 texture_cache.GuardRenderTargets(true);
467 457
468 View depth_surface{}; 458 View depth_surface = texture_cache.GetDepthBufferSurface(true);
469 if (using_depth_fb) {
470 depth_surface = texture_cache.GetDepthBufferSurface(preserve_contents);
471 } else {
472 texture_cache.SetEmptyDepthBuffer();
473 }
474 459
460 const auto& regs = gpu.regs;
461 state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
475 UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0); 462 UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0);
476 463
477 // Bind the framebuffer surfaces 464 // Bind the framebuffer surfaces
478 current_state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
479
480 FramebufferCacheKey fbkey; 465 FramebufferCacheKey fbkey;
466 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
467 View color_surface{texture_cache.GetColorBufferSurface(index, true)};
481 468
482 if (using_color_fb) { 469 if (color_surface) {
483 if (single_color_target) { 470 // Assume that a surface will be written to if it is used as a framebuffer, even
484 // Used when just a single color attachment is enabled, e.g. for clearing a color buffer 471 // if the shader doesn't actually write to it.
485 View color_surface{ 472 texture_cache.MarkColorBufferInUse(index);
486 texture_cache.GetColorBufferSurface(*single_color_target, preserve_contents)};
487
488 if (color_surface) {
489 // Assume that a surface will be written to if it is used as a framebuffer, even if
490 // the shader doesn't actually write to it.
491 texture_cache.MarkColorBufferInUse(*single_color_target);
492 }
493
494 fbkey.is_single_buffer = true;
495 fbkey.color_attachments[0] =
496 GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target);
497 fbkey.colors[0] = color_surface;
498 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
499 if (index != *single_color_target) {
500 texture_cache.SetEmptyColorBuffer(index);
501 }
502 }
503 } else {
504 // Multiple color attachments are enabled
505 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
506 View color_surface{texture_cache.GetColorBufferSurface(index, preserve_contents)};
507
508 if (color_surface) {
509 // Assume that a surface will be written to if it is used as a framebuffer, even
510 // if the shader doesn't actually write to it.
511 texture_cache.MarkColorBufferInUse(index);
512 }
513
514 fbkey.color_attachments[index] =
515 GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
516 fbkey.colors[index] = color_surface;
517 }
518 fbkey.is_single_buffer = false;
519 fbkey.colors_count = regs.rt_control.count;
520 } 473 }
521 } else { 474
522 // No color attachments are enabled - leave them as zero 475 fbkey.color_attachments[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
523 fbkey.is_single_buffer = true; 476 fbkey.colors[index] = std::move(color_surface);
524 } 477 }
478 fbkey.colors_count = regs.rt_control.count;
525 479
526 if (depth_surface) { 480 if (depth_surface) {
527 // Assume that a surface will be written to if it is used as a framebuffer, even if 481 // Assume that a surface will be written to if it is used as a framebuffer, even if
528 // the shader doesn't actually write to it. 482 // the shader doesn't actually write to it.
529 texture_cache.MarkDepthBufferInUse(); 483 texture_cache.MarkDepthBufferInUse();
530 484
531 fbkey.zeta = depth_surface;
532 fbkey.stencil_enable = depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil; 485 fbkey.stencil_enable = depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil;
486 fbkey.zeta = std::move(depth_surface);
533 } 487 }
534 488
535 texture_cache.GuardRenderTargets(false); 489 texture_cache.GuardRenderTargets(false);
536 490
537 current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey); 491 state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey);
538 SyncViewport(current_state); 492 SyncViewport(state);
539
540 return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
541} 493}
542 494
543void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, 495void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
@@ -757,7 +709,7 @@ void RasterizerOpenGL::DrawArrays() {
757 SetupShaders(params.primitive_mode); 709 SetupShaders(params.primitive_mode);
758 texture_cache.GuardSamplers(false); 710 texture_cache.GuardSamplers(false);
759 711
760 ConfigureFramebuffers(state); 712 ConfigureFramebuffers();
761 713
762 // Signal the buffer cache that we are not going to upload more things. 714 // Signal the buffer cache that we are not going to upload more things.
763 const bool invalidate = buffer_cache.Unmap(); 715 const bool invalidate = buffer_cache.Unmap();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index eada752e0..4f5c7f864 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -77,39 +77,8 @@ public:
77 const VideoCore::DiskResourceLoadCallback& callback) override; 77 const VideoCore::DiskResourceLoadCallback& callback) override;
78 78
79private: 79private:
80 struct FramebufferConfigState { 80 /// Configures the color and depth framebuffer states.
81 bool using_color_fb{}; 81 void ConfigureFramebuffers();
82 bool using_depth_fb{};
83 bool preserve_contents{};
84 std::optional<std::size_t> single_color_target;
85
86 bool operator==(const FramebufferConfigState& rhs) const {
87 return std::tie(using_color_fb, using_depth_fb, preserve_contents,
88 single_color_target) == std::tie(rhs.using_color_fb, rhs.using_depth_fb,
89 rhs.preserve_contents,
90 rhs.single_color_target);
91 }
92 bool operator!=(const FramebufferConfigState& rhs) const {
93 return !operator==(rhs);
94 }
95 };
96
97 /**
98 * Configures the color and depth framebuffer states.
99 *
100 * @param current_state The current OpenGL state.
101 * @param using_color_fb If true, configure color framebuffers.
102 * @param using_depth_fb If true, configure the depth/stencil framebuffer.
103 * @param preserve_contents If true, tries to preserve data from a previously used
104 * framebuffer.
105 * @param single_color_target Specifies if a single color buffer target should be used.
106 *
107 * @returns If depth (first) or stencil (second) are being stored in the bound zeta texture
108 * (requires using_depth_fb to be true)
109 */
110 std::pair<bool, bool> ConfigureFramebuffers(
111 OpenGLState& current_state, bool using_color_fb = true, bool using_depth_fb = true,
112 bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
113 82
114 void ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, 83 void ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
115 bool using_depth_fb, bool using_stencil_fb); 84 bool using_depth_fb, bool using_stencil_fb);
@@ -228,9 +197,6 @@ private:
228 OGLVertexArray> 197 OGLVertexArray>
229 vertex_array_cache; 198 vertex_array_cache;
230 199
231 FramebufferConfigState current_framebuffer_config_state;
232 std::pair<bool, bool> current_depth_stencil_usage{};
233
234 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 200 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
235 OGLBufferCache buffer_cache; 201 OGLBufferCache buffer_cache;
236 202