فهرست منبع

gl_rasterizer: Use baseInstance instead of moving the buffer points.

This hopefully helps our cache not to redundant upload the vertex buffer.

# Conflicts:
#	src/video_core/renderer_opengl/gl_rasterizer.cpp
bunnei 7 سال پیش
والد
کامیت
8b08cb925b
3فایلهای تغییر یافته به همراه29 افزوده شده و 21 حذف شده
  1. 25 21
      src/video_core/renderer_opengl/gl_rasterizer.cpp
  2. 2 0
      src/yuzu/main.cpp
  3. 2 0
      src/yuzu_cmd/emu_window/emu_window_sdl2.cpp

+ 25 - 21
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -151,11 +151,6 @@ void RasterizerOpenGL::SetupVertexArrays() {
         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 += static_cast<Tegra::GPUVAddr>(vertex_array.stride) *
-                     (gpu.state.current_instance / vertex_array.divisor);
-        }
-
         ASSERT(end > start);
         const u64 size = end - start + 1;
         const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size);
@@ -165,10 +160,8 @@ void RasterizerOpenGL::SetupVertexArrays() {
                            vertex_array.stride);
 
         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);
+            // Enable vertex buffer instancing with the specified divisor.
+            glVertexBindingDivisor(index, vertex_array.divisor);
         } else {
             // Disable the vertex buffer instancing.
             glVertexBindingDivisor(index, 0);
@@ -432,7 +425,8 @@ void RasterizerOpenGL::DrawArrays() {
         return;
 
     MICROPROFILE_SCOPE(OpenGL_Drawing);
-    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
+    const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
+    const auto& regs = gpu.regs;
 
     ScopeAcquireGLContext acquire_context{emu_window};
 
@@ -497,11 +491,26 @@ void RasterizerOpenGL::DrawArrays() {
         index_buffer_offset += static_cast<GLintptr>(regs.index_array.first) *
                                static_cast<GLintptr>(regs.index_array.FormatSizeInBytes());
 
-        glDrawElementsBaseVertex(primitive_mode, regs.index_array.count,
-                                 MaxwellToGL::IndexFormat(regs.index_array.format),
-                                 reinterpret_cast<const void*>(index_buffer_offset), base_vertex);
+        if (gpu.state.current_instance > 0) {
+            glDrawElementsInstancedBaseVertexBaseInstance(
+                primitive_mode, regs.index_array.count,
+                MaxwellToGL::IndexFormat(regs.index_array.format),
+                reinterpret_cast<const void*>(index_buffer_offset), 1, base_vertex,
+                gpu.state.current_instance);
+        } else {
+            glDrawElementsBaseVertex(primitive_mode, regs.index_array.count,
+                                     MaxwellToGL::IndexFormat(regs.index_array.format),
+                                     reinterpret_cast<const void*>(index_buffer_offset),
+                                     base_vertex);
+        }
     } else {
-        glDrawArrays(primitive_mode, regs.vertex_buffer.first, regs.vertex_buffer.count);
+        if (gpu.state.current_instance > 0) {
+            glDrawArraysInstancedBaseInstance(primitive_mode, regs.vertex_buffer.first,
+                                              regs.vertex_buffer.count, 1,
+                                              gpu.state.current_instance);
+        } else {
+            glDrawArrays(primitive_mode, regs.vertex_buffer.first, regs.vertex_buffer.count);
+        }
     }
 
     // Disable scissor test
@@ -518,13 +527,9 @@ void RasterizerOpenGL::DrawArrays() {
 
 void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {}
 
-void RasterizerOpenGL::FlushAll() {
-    MICROPROFILE_SCOPE(OpenGL_CacheManagement);
-}
+void RasterizerOpenGL::FlushAll() {}
 
-void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {
-    MICROPROFILE_SCOPE(OpenGL_CacheManagement);
-}
+void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {}
 
 void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
     MICROPROFILE_SCOPE(OpenGL_CacheManagement);
@@ -534,7 +539,6 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
 }
 
 void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
-    MICROPROFILE_SCOPE(OpenGL_CacheManagement);
     InvalidateRegion(addr, size);
 }
 

+ 2 - 0
src/yuzu/main.cpp

@@ -444,6 +444,8 @@ QStringList GMainWindow::GetUnsupportedGLExtensions() {
         unsupported_ext.append("ARB_vertex_type_10f_11f_11f_rev");
     if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge)
         unsupported_ext.append("ARB_texture_mirror_clamp_to_edge");
+    if (!GLAD_GL_ARB_base_instance)
+        unsupported_ext.append("ARB_base_instance");
 
     // Extensions required to support some texture formats.
     if (!GLAD_GL_EXT_texture_compression_s3tc)

+ 2 - 0
src/yuzu_cmd/emu_window/emu_window_sdl2.cpp

@@ -91,6 +91,8 @@ bool EmuWindow_SDL2::SupportsRequiredGLExtensions() {
         unsupported_ext.push_back("ARB_vertex_type_10f_11f_11f_rev");
     if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge)
         unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge");
+    if (!GLAD_GL_ARB_base_instance)
+        unsupported_ext.push_back("ARB_base_instance");
 
     // Extensions required to support some texture formats.
     if (!GLAD_GL_EXT_texture_compression_s3tc)