summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp54
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_state.h4
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h5
6 files changed, 40 insertions, 39 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 8dd7bd514..c4fe86b49 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -140,7 +140,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
140 if (is_cache_miss) { 140 if (is_cache_miss) {
141 VAO.Create(); 141 VAO.Create();
142 state.draw.vertex_array = VAO.handle; 142 state.draw.vertex_array = VAO.handle;
143 state.Apply(); 143 state.ApplyVertexBufferState();
144 144
145 // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work 145 // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work
146 // around. 146 // around.
@@ -182,7 +182,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
182 } 182 }
183 } 183 }
184 state.draw.vertex_array = VAO.handle; 184 state.draw.vertex_array = VAO.handle;
185 state.Apply(); 185 state.ApplyVertexBufferState();
186} 186}
187 187
188void RasterizerOpenGL::SetupVertexBuffer() { 188void RasterizerOpenGL::SetupVertexBuffer() {
@@ -342,8 +342,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
342 index++; 342 index++;
343 } 343 }
344 } 344 }
345
346 state.Apply();
347} 345}
348 346
349std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { 347std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
@@ -412,8 +410,8 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
412 cached_pages.add({pages_interval, delta}); 410 cached_pages.add({pages_interval, delta});
413} 411}
414 412
415void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, 413void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool using_color_fb,
416 bool preserve_contents, 414 bool using_depth_fb, bool preserve_contents,
417 std::optional<std::size_t> single_color_target) { 415 std::optional<std::size_t> single_color_target) {
418 MICROPROFILE_SCOPE(OpenGL_Framebuffer); 416 MICROPROFILE_SCOPE(OpenGL_Framebuffer);
419 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 417 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
@@ -429,9 +427,9 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
429 ASSERT_MSG(regs.rt_separate_frag_data == 0, "Unimplemented"); 427 ASSERT_MSG(regs.rt_separate_frag_data == 0, "Unimplemented");
430 428
431 // Bind the framebuffer surfaces 429 // Bind the framebuffer surfaces
432 state.draw.draw_framebuffer = framebuffer.handle; 430 current_state.draw.draw_framebuffer = framebuffer.handle;
433 state.Apply(); 431 current_state.ApplyFramebufferState();
434 state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0; 432 current_state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
435 433
436 if (using_color_fb) { 434 if (using_color_fb) {
437 if (single_color_target) { 435 if (single_color_target) {
@@ -509,10 +507,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
509 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 507 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
510 0); 508 0);
511 } 509 }
512 510 SyncViewport(current_state);
513 SyncViewport();
514
515 state.Apply();
516} 511}
517 512
518void RasterizerOpenGL::Clear() { 513void RasterizerOpenGL::Clear() {
@@ -525,22 +520,23 @@ void RasterizerOpenGL::Clear() {
525 bool use_stencil{}; 520 bool use_stencil{};
526 521
527 OpenGLState clear_state; 522 OpenGLState clear_state;
528 clear_state.draw.draw_framebuffer = framebuffer.handle;
529 clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
530 clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
531 clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
532 clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
533
534 if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || 523 if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
535 regs.clear_buffers.A) { 524 regs.clear_buffers.A) {
536 use_color = true; 525 use_color = true;
537 } 526 }
527 if (use_color) {
528 clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
529 clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
530 clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
531 clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
532 }
538 if (regs.clear_buffers.Z) { 533 if (regs.clear_buffers.Z) {
539 ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); 534 ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
540 use_depth = true; 535 use_depth = true;
541 536
542 // Always enable the depth write when clearing the depth buffer. The depth write mask is 537 // Always enable the depth write when clearing the depth buffer. The depth write mask is
543 // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to true. 538 // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to
539 // true.
544 clear_state.depth.test_enabled = true; 540 clear_state.depth.test_enabled = true;
545 clear_state.depth.test_func = GL_ALWAYS; 541 clear_state.depth.test_func = GL_ALWAYS;
546 } 542 }
@@ -557,11 +553,8 @@ void RasterizerOpenGL::Clear() {
557 553
558 ScopeAcquireGLContext acquire_context{emu_window}; 554 ScopeAcquireGLContext acquire_context{emu_window};
559 555
560 ConfigureFramebuffers(use_color, use_depth || use_stencil, false, 556 ConfigureFramebuffers(clear_state, use_color, use_depth || use_stencil, false,
561 regs.clear_buffers.RT.Value()); 557 regs.clear_buffers.RT.Value());
562 // Copy the sRGB setting to the clear state to avoid problem with
563 // specific driver implementations
564 clear_state.framebuffer_srgb.enabled = state.framebuffer_srgb.enabled;
565 clear_state.Apply(); 558 clear_state.Apply();
566 559
567 if (use_color) { 560 if (use_color) {
@@ -587,7 +580,7 @@ void RasterizerOpenGL::DrawArrays() {
587 580
588 ScopeAcquireGLContext acquire_context{emu_window}; 581 ScopeAcquireGLContext acquire_context{emu_window};
589 582
590 ConfigureFramebuffers(); 583 ConfigureFramebuffers(state);
591 SyncColorMask(); 584 SyncColorMask();
592 SyncDepthTestState(); 585 SyncDepthTestState();
593 SyncStencilTestState(); 586 SyncStencilTestState();
@@ -608,7 +601,7 @@ void RasterizerOpenGL::DrawArrays() {
608 const bool is_indexed = accelerate_draw == AccelDraw::Indexed; 601 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
609 602
610 state.draw.vertex_buffer = buffer_cache.GetHandle(); 603 state.draw.vertex_buffer = buffer_cache.GetHandle();
611 state.Apply(); 604 state.ApplyVertexBufferState();
612 605
613 std::size_t buffer_size = CalculateVertexArraysSize(); 606 std::size_t buffer_size = CalculateVertexArraysSize();
614 607
@@ -923,11 +916,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
923 return current_unit + static_cast<u32>(entries.size()); 916 return current_unit + static_cast<u32>(entries.size());
924} 917}
925 918
926void RasterizerOpenGL::SyncViewport() { 919void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
927 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 920 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
928 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { 921 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
929 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()}; 922 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
930 auto& viewport = state.viewports[i]; 923 auto& viewport = current_state.viewports[i];
931 viewport.x = viewport_rect.left; 924 viewport.x = viewport_rect.left;
932 viewport.y = viewport_rect.bottom; 925 viewport.y = viewport_rect.bottom;
933 viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth()); 926 viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth());
@@ -1131,9 +1124,8 @@ void RasterizerOpenGL::CheckAlphaTests() {
1131 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 1124 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
1132 1125
1133 if (regs.alpha_test_enabled != 0 && regs.rt_control.count > 1) { 1126 if (regs.alpha_test_enabled != 0 && regs.rt_control.count > 1) {
1134 LOG_CRITICAL( 1127 LOG_CRITICAL(Render_OpenGL, "Alpha Testing is enabled with Multiple Render Targets, "
1135 Render_OpenGL, 1128 "this behavior is undefined.");
1136 "Alpha Testing is enabled with Multiple Render Targets, this behavior is undefined.");
1137 UNREACHABLE(); 1129 UNREACHABLE();
1138 } 1130 }
1139} 1131}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index aa793caf2..8ef0f6c12 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -109,8 +109,8 @@ private:
109 * @param preserve_contents If true, tries to preserve data from a previously used framebuffer. 109 * @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
110 * @param single_color_target Specifies if a single color buffer target should be used. 110 * @param single_color_target Specifies if a single color buffer target should be used.
111 */ 111 */
112 void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true, 112 void ConfigureFramebuffers(OpenGLState& current_state, bool use_color_fb = true,
113 bool preserve_contents = true, 113 bool using_depth_fb = true, bool preserve_contents = true,
114 std::optional<std::size_t> single_color_target = {}); 114 std::optional<std::size_t> single_color_target = {});
115 115
116 /* 116 /*
@@ -134,7 +134,7 @@ private:
134 GLenum primitive_mode, u32 current_unit); 134 GLenum primitive_mode, u32 current_unit);
135 135
136 /// Syncs the viewport and depth range to match the guest state 136 /// Syncs the viewport and depth range to match the guest state
137 void SyncViewport(); 137 void SyncViewport(OpenGLState& current_state);
138 138
139 /// Syncs the clip enabled status to match the guest state 139 /// Syncs the clip enabled status to match the guest state
140 void SyncClipEnabled(); 140 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 c8864cce8..894f4f294 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -580,7 +580,7 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
580 state.draw.draw_framebuffer = draw_fb_handle; 580 state.draw.draw_framebuffer = draw_fb_handle;
581 // Set sRGB enabled if the destination surfaces need it 581 // Set sRGB enabled if the destination surfaces need it
582 state.framebuffer_srgb.enabled = dst_params.srgb_conversion; 582 state.framebuffer_srgb.enabled = dst_params.srgb_conversion;
583 state.Apply(); 583 state.ApplyFramebufferState();
584 584
585 u32 buffers{}; 585 u32 buffers{};
586 586
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 9517285e5..2635f2b0c 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -427,7 +427,7 @@ void OpenGLState::ApplySamplers() const {
427 } 427 }
428} 428}
429 429
430void OpenGLState::Apply() const { 430void OpenGLState::ApplyFramebufferState() const {
431 // Framebuffer 431 // Framebuffer
432 if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { 432 if (draw.read_framebuffer != cur_state.draw.read_framebuffer) {
433 glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); 433 glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
@@ -435,7 +435,9 @@ void OpenGLState::Apply() const {
435 if (draw.draw_framebuffer != cur_state.draw.draw_framebuffer) { 435 if (draw.draw_framebuffer != cur_state.draw.draw_framebuffer) {
436 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer); 436 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer);
437 } 437 }
438}
438 439
440void OpenGLState::ApplyVertexBufferState() const {
439 // Vertex array 441 // Vertex array
440 if (draw.vertex_array != cur_state.draw.vertex_array) { 442 if (draw.vertex_array != cur_state.draw.vertex_array) {
441 glBindVertexArray(draw.vertex_array); 443 glBindVertexArray(draw.vertex_array);
@@ -445,7 +447,11 @@ void OpenGLState::Apply() const {
445 if (draw.vertex_buffer != cur_state.draw.vertex_buffer) { 447 if (draw.vertex_buffer != cur_state.draw.vertex_buffer) {
446 glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer); 448 glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
447 } 449 }
450}
448 451
452void OpenGLState::Apply() const {
453 ApplyFramebufferState();
454 ApplyVertexBufferState();
449 // Uniform buffer 455 // Uniform buffer
450 if (draw.uniform_buffer != cur_state.draw.uniform_buffer) { 456 if (draw.uniform_buffer != cur_state.draw.uniform_buffer) {
451 glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer); 457 glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer);
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index b8cf1f637..eacca0b9c 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -181,6 +181,10 @@ public:
181 } 181 }
182 /// Apply this state as the current OpenGL state 182 /// Apply this state as the current OpenGL state
183 void Apply() const; 183 void Apply() const;
184 /// Apply only the state afecting the framebuffer
185 void ApplyFramebufferState() const;
186 /// Apply only the state afecting the vertex buffer
187 void ApplyVertexBufferState() const;
184 /// Set the initial OpenGL state 188 /// Set the initial OpenGL state
185 static void ApplyDefaultState(); 189 static void ApplyDefaultState();
186 /// Resets any references to the given resource 190 /// Resets any references to the given resource
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 32dc158e4..3ce2cc6d2 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -159,8 +159,7 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode,
159 } 159 }
160 } 160 }
161 } 161 }
162 LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}", 162 LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}", static_cast<u32>(filter_mode));
163 static_cast<u32>(filter_mode));
164 return GL_LINEAR; 163 return GL_LINEAR;
165} 164}
166 165
@@ -206,7 +205,7 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
206 return GL_ALWAYS; 205 return GL_ALWAYS;
207 } 206 }
208 LOG_ERROR(Render_OpenGL, "Unimplemented texture depth compare function ={}", 207 LOG_ERROR(Render_OpenGL, "Unimplemented texture depth compare function ={}",
209 static_cast<u32>(func)); 208 static_cast<u32>(func));
210 return GL_GREATER; 209 return GL_GREATER;
211} 210}
212 211