gl_state: Remove viewport and depth range tracking
This commit is contained in:
		| @@ -574,7 +574,7 @@ public: | ||||
|             f32 translate_z; | ||||
|             INSERT_UNION_PADDING_WORDS(2); | ||||
|  | ||||
|             Common::Rectangle<s32> GetRect() const { | ||||
|             Common::Rectangle<f32> GetRect() const { | ||||
|                 return { | ||||
|                     GetX(),               // left | ||||
|                     GetY() + GetHeight(), // top | ||||
| @@ -583,20 +583,20 @@ public: | ||||
|                 }; | ||||
|             }; | ||||
|  | ||||
|             s32 GetX() const { | ||||
|                 return static_cast<s32>(std::max(0.0f, translate_x - std::fabs(scale_x))); | ||||
|             f32 GetX() const { | ||||
|                 return std::max(0.0f, translate_x - std::fabs(scale_x)); | ||||
|             } | ||||
|  | ||||
|             s32 GetY() const { | ||||
|                 return static_cast<s32>(std::max(0.0f, translate_y - std::fabs(scale_y))); | ||||
|             f32 GetY() const { | ||||
|                 return std::max(0.0f, translate_y - std::fabs(scale_y)); | ||||
|             } | ||||
|  | ||||
|             s32 GetWidth() const { | ||||
|                 return static_cast<s32>(translate_x + std::fabs(scale_x)) - GetX(); | ||||
|             f32 GetWidth() const { | ||||
|                 return translate_x + std::fabs(scale_x) - GetX(); | ||||
|             } | ||||
|  | ||||
|             s32 GetHeight() const { | ||||
|                 return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY(); | ||||
|             f32 GetHeight() const { | ||||
|                 return translate_y + std::fabs(scale_y) - GetY(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|   | ||||
| @@ -360,7 +360,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() { | ||||
|     texture_cache.GuardRenderTargets(false); | ||||
|  | ||||
|     state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key); | ||||
|     SyncViewport(state); | ||||
| } | ||||
|  | ||||
| void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, | ||||
| @@ -405,7 +404,6 @@ void RasterizerOpenGL::Clear() { | ||||
|     SCOPE_EXIT({ prev_state.Apply(); }); | ||||
|  | ||||
|     OpenGLState clear_state{OpenGLState::GetCurState()}; | ||||
|     clear_state.SetDefaultViewports(); | ||||
|     if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || | ||||
|         regs.clear_buffers.A) { | ||||
|         use_color = true; | ||||
| @@ -464,7 +462,6 @@ void RasterizerOpenGL::Clear() { | ||||
|  | ||||
|     ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil); | ||||
|  | ||||
|     SyncViewport(clear_state); | ||||
|     SyncRasterizeEnable(clear_state); | ||||
|     if (regs.clear_flags.scissor) { | ||||
|         SyncScissorTest(); | ||||
| @@ -496,6 +493,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | ||||
|  | ||||
|     query_cache.UpdateCounters(); | ||||
|  | ||||
|     SyncViewport(); | ||||
|     SyncRasterizeEnable(state); | ||||
|     SyncColorMask(); | ||||
|     SyncFragmentColorClampState(); | ||||
| @@ -935,22 +933,14 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t | ||||
|     state.images[binding] = view->GetTexture(); | ||||
| } | ||||
|  | ||||
| void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { | ||||
| void RasterizerOpenGL::SyncViewport() { | ||||
|     const auto& regs = system.GPU().Maxwell3D().regs; | ||||
|     const bool geometry_shaders_enabled = | ||||
|         regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry)); | ||||
|     const std::size_t viewport_count = | ||||
|         geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1; | ||||
|     for (std::size_t i = 0; i < viewport_count; i++) { | ||||
|         auto& viewport = current_state.viewports[i]; | ||||
|     for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) { | ||||
|         const auto& src = regs.viewports[i]; | ||||
|         const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()}; | ||||
|         viewport.x = viewport_rect.left; | ||||
|         viewport.y = viewport_rect.bottom; | ||||
|         viewport.width = viewport_rect.GetWidth(); | ||||
|         viewport.height = viewport_rect.GetHeight(); | ||||
|         viewport.depth_range_far = src.depth_range_far; | ||||
|         viewport.depth_range_near = src.depth_range_near; | ||||
|         const Common::Rectangle<f32> rect{regs.viewport_transform[i].GetRect()}; | ||||
|         glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom, rect.GetWidth(), | ||||
|                            rect.GetHeight()); | ||||
|         glDepthRangef(src.depth_range_near, src.depth_range_far); | ||||
|     } | ||||
|  | ||||
|     bool flip_y = false; | ||||
|   | ||||
| @@ -130,7 +130,7 @@ private: | ||||
|                     const GLShader::ImageEntry& entry); | ||||
|  | ||||
|     /// Syncs the viewport and depth range to match the guest state | ||||
|     void SyncViewport(OpenGLState& current_state); | ||||
|     void SyncViewport(); | ||||
|  | ||||
|     /// Syncs the depth clamp state | ||||
|     void SyncDepthClamp(); | ||||
|   | ||||
| @@ -85,10 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { | ||||
|  | ||||
| OpenGLState::OpenGLState() = default; | ||||
|  | ||||
| void OpenGLState::SetDefaultViewports() { | ||||
|     viewports.fill(Viewport{}); | ||||
| } | ||||
|  | ||||
| void OpenGLState::ApplyFramebufferState() { | ||||
|     if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { | ||||
|         glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); | ||||
| @@ -150,30 +146,6 @@ void OpenGLState::ApplyStencilTest() { | ||||
|     ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); | ||||
| } | ||||
|  | ||||
| void OpenGLState::ApplyViewport() { | ||||
|     for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) { | ||||
|         const auto& updated = viewports[i]; | ||||
|         auto& current = cur_state.viewports[i]; | ||||
|  | ||||
|         if (current.x != updated.x || current.y != updated.y || current.width != updated.width || | ||||
|             current.height != updated.height) { | ||||
|             current.x = updated.x; | ||||
|             current.y = updated.y; | ||||
|             current.width = updated.width; | ||||
|             current.height = updated.height; | ||||
|             glViewportIndexedf(i, static_cast<GLfloat>(updated.x), static_cast<GLfloat>(updated.y), | ||||
|                                static_cast<GLfloat>(updated.width), | ||||
|                                static_cast<GLfloat>(updated.height)); | ||||
|         } | ||||
|         if (current.depth_range_near != updated.depth_range_near || | ||||
|             current.depth_range_far != updated.depth_range_far) { | ||||
|             current.depth_range_near = updated.depth_range_near; | ||||
|             current.depth_range_far = updated.depth_range_far; | ||||
|             glDepthRangeIndexed(i, updated.depth_range_near, updated.depth_range_far); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void OpenGLState::ApplyGlobalBlending() { | ||||
|     const Blend& updated = blend[0]; | ||||
|     Blend& current = cur_state.blend[0]; | ||||
| @@ -283,7 +255,6 @@ void OpenGLState::Apply() { | ||||
|     ApplyProgramPipeline(); | ||||
|     ApplyClipDistances(); | ||||
|     ApplyRasterizerDiscard(); | ||||
|     ApplyViewport(); | ||||
|     ApplyStencilTest(); | ||||
|     ApplyBlending(); | ||||
|     ApplyTextures(); | ||||
|   | ||||
| @@ -56,16 +56,6 @@ public: | ||||
|         GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING | ||||
|     } draw; | ||||
|  | ||||
|     struct Viewport { | ||||
|         GLint x = 0; | ||||
|         GLint y = 0; | ||||
|         GLint width = 0; | ||||
|         GLint height = 0; | ||||
|         GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE | ||||
|         GLfloat depth_range_far = 1.0f;  // GL_DEPTH_RANGE | ||||
|     }; | ||||
|     std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports; | ||||
|  | ||||
|     std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE | ||||
|  | ||||
|     struct { | ||||
| @@ -82,7 +72,6 @@ public: | ||||
|         return cur_state; | ||||
|     } | ||||
|  | ||||
|     void SetDefaultViewports(); | ||||
|     /// Apply this state as the current OpenGL state | ||||
|     void Apply(); | ||||
|  | ||||
| @@ -92,7 +81,6 @@ public: | ||||
|     void ApplyClipDistances(); | ||||
|     void ApplyRasterizerDiscard(); | ||||
|     void ApplyStencilTest(); | ||||
|     void ApplyViewport(); | ||||
|     void ApplyTargetBlending(std::size_t target, bool force); | ||||
|     void ApplyGlobalBlending(); | ||||
|     void ApplyBlending(); | ||||
|   | ||||
| @@ -205,8 +205,8 @@ constexpr GLint TexCoordLocation = 1; | ||||
| constexpr GLint ModelViewMatrixLocation = 0; | ||||
|  | ||||
| struct ScreenRectVertex { | ||||
|     constexpr ScreenRectVertex(GLfloat x, GLfloat y, GLfloat u, GLfloat v) | ||||
|         : position{{x, y}}, tex_coord{{u, v}} {} | ||||
|     constexpr ScreenRectVertex(u32 x, u32 y, GLfloat u, GLfloat v) | ||||
|         : position{{static_cast<GLfloat>(x), static_cast<GLfloat>(y)}}, tex_coord{{u, v}} {} | ||||
|  | ||||
|     std::array<GLfloat, 2> position; | ||||
|     std::array<GLfloat, 2> tex_coord; | ||||
| @@ -514,8 +514,18 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | ||||
|     glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height); | ||||
| } | ||||
|  | ||||
| void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, | ||||
|                                          float h) { | ||||
| void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | ||||
|     if (renderer_settings.set_background_color) { | ||||
|         // Update background color before drawing | ||||
|         glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, | ||||
|                      0.0f); | ||||
|     } | ||||
|  | ||||
|     // Set projection matrix | ||||
|     const std::array ortho_matrix = | ||||
|         MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | ||||
|     glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); | ||||
|  | ||||
|     const auto& texcoords = screen_info.display_texcoords; | ||||
|     auto left = texcoords.left; | ||||
|     auto right = texcoords.right; | ||||
| @@ -547,12 +557,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | ||||
|                   static_cast<f32>(screen_info.texture.height); | ||||
|     } | ||||
|  | ||||
|     const auto& screen = layout.screen; | ||||
|     const std::array vertices = { | ||||
|         ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v), | ||||
|         ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v), | ||||
|         ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v), | ||||
|         ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), | ||||
|         ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u, left * scale_v), | ||||
|         ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u, left * scale_v), | ||||
|         ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u, right * scale_v), | ||||
|         ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u, right * scale_v), | ||||
|     }; | ||||
|     glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); | ||||
|  | ||||
|     state.textures[0] = screen_info.display_texture; | ||||
|     state.Apply(); | ||||
| @@ -572,6 +584,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | ||||
|     glCullFace(GL_BACK); | ||||
|     glFrontFace(GL_CW); | ||||
|     glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | ||||
|     glViewport(0, 0, layout.width, layout.height); | ||||
|  | ||||
|     glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, | ||||
|                          offsetof(ScreenRectVertex, position)); | ||||
| @@ -581,7 +594,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | ||||
|     glVertexAttribBinding(TexCoordLocation, 0); | ||||
|     glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex)); | ||||
|  | ||||
|     glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); | ||||
|     glClear(GL_COLOR_BUFFER_BIT); | ||||
|     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||||
|  | ||||
|     // Restore default state | ||||
| @@ -589,28 +602,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | ||||
|     state.Apply(); | ||||
| } | ||||
|  | ||||
| void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | ||||
|     if (renderer_settings.set_background_color) { | ||||
|         // Update background color before drawing | ||||
|         glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, | ||||
|                      0.0f); | ||||
|     } | ||||
|  | ||||
|     const auto& screen = layout.screen; | ||||
|  | ||||
|     glViewport(0, 0, layout.width, layout.height); | ||||
|     glClear(GL_COLOR_BUFFER_BIT); | ||||
|  | ||||
|     // Set projection matrix | ||||
|     const std::array ortho_matrix = | ||||
|         MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | ||||
|     glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); | ||||
|  | ||||
|     DrawScreenTriangles(screen_info, static_cast<float>(screen.left), | ||||
|                         static_cast<float>(screen.top), static_cast<float>(screen.GetWidth()), | ||||
|                         static_cast<float>(screen.GetHeight())); | ||||
| } | ||||
|  | ||||
| void RendererOpenGL::TryPresent(int timeout_ms) { | ||||
|     const auto& layout = render_window.GetFramebufferLayout(); | ||||
|     auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms); | ||||
|   | ||||
| @@ -76,8 +76,6 @@ private: | ||||
|     /// Draws the emulated screens to the emulator window. | ||||
|     void DrawScreen(const Layout::FramebufferLayout& layout); | ||||
|  | ||||
|     void DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, float h); | ||||
|  | ||||
|     void RenderScreenshot(); | ||||
|  | ||||
|     /// Loads framebuffer from emulated memory into the active OpenGL texture. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp