From 69ad6279e45db408ba3add0b540660ae34ba8e3f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 23:08:40 -0300 Subject: gl_state_tracker: Implement dirty flags for vertex formats --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 +++++++++++++++------- .../renderer_opengl/gl_state_tracker.cpp | 10 ++++++++ src/video_core/renderer_opengl/gl_state_tracker.h | 12 ++++++++++ src/video_core/renderer_opengl/renderer_opengl.cpp | 3 +++ 4 files changed, 44 insertions(+), 9 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b4cec274d..211b11489 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -120,7 +120,11 @@ void RasterizerOpenGL::CheckExtensions() { void RasterizerOpenGL::SetupVertexFormat() { auto& gpu = system.GPU().Maxwell3D(); - const auto& regs = gpu.regs; + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::VertexFormats]) { + return; + } + flags[Dirty::VertexFormats] = false; MICROPROFILE_SCOPE(OpenGL_VAO); @@ -130,25 +134,31 @@ void RasterizerOpenGL::SetupVertexFormat() { // avoid OpenGL errors. // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't // assume every shader uses them all. - for (u32 index = 0; index < 16; ++index) { - const auto& attrib = regs.vertex_attrib_format[index]; + for (std::size_t index = 0; index < 16; ++index) { + if (!flags[Dirty::VertexFormat0 + index]) { + continue; + } + flags[Dirty::VertexFormat0 + index] = false; + + const auto attrib = gpu.regs.vertex_attrib_format[index]; + const auto gl_index = static_cast(index); // Ignore invalid attributes. if (!attrib.IsValid()) { - glDisableVertexAttribArray(index); + glDisableVertexAttribArray(gl_index); continue; } - glEnableVertexAttribArray(index); + glEnableVertexAttribArray(gl_index); if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt || attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) { - glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - attrib.offset); + glVertexAttribIFormat(gl_index, attrib.ComponentCount(), + MaxwellToGL::VertexType(attrib), attrib.offset); } else { - glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + glVertexAttribFormat(gl_index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); } - glVertexAttribBinding(index, attrib.buffer); + glVertexAttribBinding(gl_index, attrib.buffer); } } diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 3c6231d58..572a43856 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -71,6 +71,15 @@ void SetupDirtyColorMasks(Tables& tables) { FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks); } +void SetupDirtyVertexFormat(Tables& tables) { + for (std::size_t i = 0; i < Regs::NumVertexAttributes; ++i) { + const std::size_t offset = OFF(vertex_attrib_format) + i * NUM(vertex_attrib_format[0]); + FillBlock(tables[0], offset, NUM(vertex_attrib_format[0]), VertexFormat0 + i); + } + + FillBlock(tables[1], OFF(vertex_attrib_format), Regs::NumVertexAttributes, VertexFormats); +} + void SetupDirtyViewports(Tables& tables) { for (std::size_t i = 0; i < Regs::NumViewports; ++i) { const std::size_t transf_offset = OFF(viewport_transform) + i * NUM(viewport_transform[0]); @@ -117,6 +126,7 @@ void StateTracker::Initialize() { SetupDirtyColorMasks(tables); SetupDirtyViewports(tables); SetupDirtyScissors(tables); + SetupDirtyVertexFormat(tables); } } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 0ad7c349a..7add22d88 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -20,6 +20,8 @@ enum : u8 { First = VideoCommon::Dirty::LastCommonEntry, VertexFormats, + VertexFormat0, + VertexFormat31 = VertexFormat0 + 31, VertexBuffers, VertexBuffer0, @@ -66,6 +68,16 @@ public: void Initialize(); + void NotifyScreenDrawVertexArray() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::VertexFormats] = true; + flags[OpenGL::Dirty::VertexFormat0 + 0] = true; + flags[OpenGL::Dirty::VertexFormat0 + 1] = true; + + flags[OpenGL::Dirty::VertexBuffers] = true; + flags[OpenGL::Dirty::VertexBuffer0] = true; + } + void NotifyViewport0() { auto& flags = system.GPU().Maxwell3D().dirty.flags; flags[OpenGL::Dirty::Viewports] = true; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 3ff7c8fb1..caa193c50 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -576,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); // TODO: Signal state tracker about these changes + state_tracker.NotifyScreenDrawVertexArray(); state_tracker.NotifyViewport0(); state_tracker.NotifyScissor0(); state_tracker.NotifyColorMask0(); @@ -608,6 +609,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { static_cast(layout.height)); glDepthRangeIndexed(0, 0.0, 0.0); + glEnableVertexAttribArray(PositionLocation); + glEnableVertexAttribArray(TexCoordLocation); glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, offsetof(ScreenRectVertex, position)); glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE, -- cgit v1.2.3