diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 54 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 5 |
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 | ||
| 188 | void RasterizerOpenGL::SetupVertexBuffer() { | 188 | void 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 | ||
| 349 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 347 | std::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 | ||
| 415 | void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, | 413 | void 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 | ||
| 518 | void RasterizerOpenGL::Clear() { | 513 | void 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 | ||
| 926 | void RasterizerOpenGL::SyncViewport() { | 919 | void 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 | ||
| 430 | void OpenGLState::Apply() const { | 430 | void 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 | ||
| 440 | void 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 | ||
| 452 | void 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 | ||