mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-04 04:34:07 +01:00 
			
		
		
		
	gl_state: Remove viewport and depth range tracking
This commit is contained in:
		
							parent
							
								
									7c16b3551b
								
							
						
					
					
						commit
						d3e433a380
					
				@ -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.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user