diff options
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 18 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 24 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 29 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 12 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 53 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 2 |
7 files changed, 39 insertions, 101 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 3a641c182..2134d6e4f 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -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(); } }; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3ccedcf55..63295761a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -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; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 0450657a7..d1d0aec32 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -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(); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index dcea16fd3..7c08cc3c2 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -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(); diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 44eb35dd5..b4c957c0d 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -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(); diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 0d5ef9ef6..12e820979 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -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); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 978a4d0eb..42a2141d8 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -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. |