diff options
| author | bunnei <bunneidev@gmail.com> | 2018-08-20 14:32:50 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-20 14:32:50 -0400 | 
| commit | 028d90eb79b75292d352cc8d4b96a2df74cd6b6e (patch) | |
| tree | ab7df9fd12b103b7c832e9691d2abbb72ca38e93 | |
| parent | 296e57fa0e0cd681b8063560c9c9ca60cfb77889 (diff) | |
| parent | e0f66c1fbfa7874df9970c2d269bd61e05758309 (diff) | |
Merge pull request #1104 from Subv/instanced_arrays
GLRasterizer: Implemented instanced vertex arrays.
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 19 | 
2 files changed, 30 insertions, 4 deletions
| diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 771eb5abc..3c869d3a1 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -679,7 +679,19 @@ public:                  INSERT_PADDING_WORDS(0x7); -                INSERT_PADDING_WORDS(0x46); +                INSERT_PADDING_WORDS(0x20); + +                struct { +                    u32 is_instanced[NumVertexArrays]; + +                    /// Returns whether the vertex array specified by index is supposed to be +                    /// accessed per instance or not. +                    bool IsInstancingEnabled(u32 index) const { +                        return is_instanced[index]; +                    } +                } instanced_arrays; + +                INSERT_PADDING_WORDS(0x6);                  Cull cull; @@ -928,6 +940,7 @@ ASSERT_REG_POSITION(point_coord_replace, 0x581);  ASSERT_REG_POSITION(code_address, 0x582);  ASSERT_REG_POSITION(draw, 0x585);  ASSERT_REG_POSITION(index_array, 0x5F2); +ASSERT_REG_POSITION(instanced_arrays, 0x620);  ASSERT_REG_POSITION(cull, 0x646);  ASSERT_REG_POSITION(clear_buffers, 0x674);  ASSERT_REG_POSITION(query, 0x6C0); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 93eadde7a..fe1f55e85 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -98,7 +98,8 @@ RasterizerOpenGL::~RasterizerOpenGL() {}  std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,                                                               GLintptr buffer_offset) {      MICROPROFILE_SCOPE(OpenGL_VAO); -    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; +    const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); +    const auto& regs = gpu.regs;      state.draw.vertex_array = hw_vao.handle;      state.draw.vertex_buffer = stream_buffer.GetHandle(); @@ -110,9 +111,13 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,          if (!vertex_array.IsEnabled())              continue; -        const Tegra::GPUVAddr start = vertex_array.StartAddress(); +        Tegra::GPUVAddr start = vertex_array.StartAddress();          const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); +        if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { +            start += vertex_array.stride * (gpu.state.current_instance / vertex_array.divisor); +        } +          ASSERT(end > start);          u64 size = end - start + 1; @@ -124,7 +129,15 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,          glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset,                             vertex_array.stride); -        ASSERT_MSG(vertex_array.divisor == 0, "Instanced vertex arrays are not supported"); +        if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { +            // Tell OpenGL that this is an instanced vertex buffer to prevent accessing different +            // indexes on each vertex. We do the instance indexing manually by incrementing the +            // start address of the vertex buffer. +            glVertexBindingDivisor(index, 1); +        } else { +            // Disable the vertex buffer instancing. +            glVertexBindingDivisor(index, 0); +        }      }      // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. | 
