diff options
Diffstat (limited to 'src/video_core')
4 files changed, 56 insertions, 22 deletions
| diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 211b11489..bb89985cc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -164,12 +164,22 @@ void RasterizerOpenGL::SetupVertexFormat() {  void RasterizerOpenGL::SetupVertexBuffer() {      auto& gpu = system.GPU().Maxwell3D(); -    const auto& regs = gpu.regs; +    auto& flags = gpu.dirty.flags; +    if (!flags[Dirty::VertexBuffers]) { +        return; +    } +    flags[Dirty::VertexBuffers] = false;      MICROPROFILE_SCOPE(OpenGL_VB);      // Upload all guest vertex arrays sequentially to our buffer -    for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { +    const auto& regs = gpu.regs; +    for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { +        if (!flags[Dirty::VertexBuffer0 + index]) { +            continue; +        } +        flags[Dirty::VertexBuffer0 + index] = false; +          const auto& vertex_array = regs.vertex_array[index];          if (!vertex_array.IsEnabled()) {              continue; @@ -183,33 +193,30 @@ void RasterizerOpenGL::SetupVertexBuffer() {          const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);          // Bind the vertex array to the buffer at the current offset. -        vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset, -                                                vertex_array.stride); - -        if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { -            // Enable vertex buffer instancing with the specified divisor. -            glVertexBindingDivisor(index, vertex_array.divisor); -        } else { -            // Disable the vertex buffer instancing. -            glVertexBindingDivisor(index, 0); -        } +        vertex_array_pushbuffer.SetVertexBuffer(static_cast<GLuint>(index), vertex_buffer, +                                                vertex_buffer_offset, vertex_array.stride);      }  }  void RasterizerOpenGL::SetupVertexInstances() {      auto& gpu = system.GPU().Maxwell3D(); -    const auto& regs = gpu.regs; +    auto& flags = gpu.dirty.flags; +    if (!flags[Dirty::VertexInstances]) { +        return; +    } +    flags[Dirty::VertexInstances] = false; -    // Upload all guest vertex arrays sequentially to our buffer -    for (u32 index = 0; index < 16; ++index) { -        if (regs.instanced_arrays.IsInstancingEnabled(index) && -            regs.vertex_array[index].divisor != 0) { -            // Enable vertex buffer instancing with the specified divisor. -            glVertexBindingDivisor(index, regs.vertex_array[index].divisor); -        } else { -            // Disable the vertex buffer instancing. -            glVertexBindingDivisor(index, 0); +    const auto& regs = gpu.regs; +    for (std::size_t index = 0; index < 16; ++index) { +        if (!flags[Dirty::VertexInstance0 + index]) { +            continue;          } +        flags[Dirty::VertexInstance0 + index] = false; + +        const auto gl_index = static_cast<GLuint>(index); +        const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index); +        const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0; +        glVertexBindingDivisor(gl_index, divisor);      }  } diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 319fd825b..7150b9247 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -71,6 +71,26 @@ void SetupDirtyColorMasks(Tables& tables) {      FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks);  } +void SetupDirtyVertexArrays(Tables& tables) { +    static constexpr std::size_t num_array = 3; +    static constexpr std::size_t instance_base_offset = 3; +    for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) { +        const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]); +        const std::size_t limit_offset = OFF(vertex_array_limit) + i * NUM(vertex_array_limit[0]); + +        FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers); +        FillBlock(tables, limit_offset, NUM(vertex_array_limit), VertexBuffer0 + i, VertexBuffers); + +        const std::size_t instance_array_offset = array_offset + instance_base_offset; +        tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i); +        tables[1][instance_array_offset] = VertexInstances; + +        const std::size_t instance_offset = OFF(instanced_arrays) + i; +        tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i); +        tables[1][instance_offset] = VertexInstances; +    } +} +  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]); @@ -115,6 +135,7 @@ void StateTracker::Initialize() {      SetupDirtyColorMasks(tables);      SetupDirtyViewports(tables);      SetupDirtyScissors(tables); +    SetupDirtyVertexArrays(tables);      SetupDirtyVertexFormat(tables);      auto& store = dirty.on_write_stores; diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index a368aefd7..85667cee1 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -78,6 +78,10 @@ public:          flags[OpenGL::Dirty::VertexBuffers] = true;          flags[OpenGL::Dirty::VertexBuffer0] = true; + +        flags[OpenGL::Dirty::VertexInstances] = true; +        flags[OpenGL::Dirty::VertexInstance0 + 0] = true; +        flags[OpenGL::Dirty::VertexInstance0 + 1] = true;      }      void NotifyViewport0() { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index caa193c50..cbe916488 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -611,6 +611,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {      glEnableVertexAttribArray(PositionLocation);      glEnableVertexAttribArray(TexCoordLocation); +    glVertexAttribDivisor(PositionLocation, 0); +    glVertexAttribDivisor(TexCoordLocation, 0);      glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,                           offsetof(ScreenRectVertex, position));      glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE, | 
