summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-08-20 14:32:50 -0400
committerGravatar GitHub2018-08-20 14:32:50 -0400
commit028d90eb79b75292d352cc8d4b96a2df74cd6b6e (patch)
treeab7df9fd12b103b7c832e9691d2abbb72ca38e93
parentMerge pull request #1115 from Subv/texs_mask (diff)
parentGLRasterizer: Implemented instanced vertex arrays. (diff)
downloadyuzu-028d90eb79b75292d352cc8d4b96a2df74cd6b6e.tar.gz
yuzu-028d90eb79b75292d352cc8d4b96a2df74cd6b6e.tar.xz
yuzu-028d90eb79b75292d352cc8d4b96a2df74cd6b6e.zip
Merge pull request #1104 from Subv/instanced_arrays
GLRasterizer: Implemented instanced vertex arrays.
-rw-r--r--src/video_core/engines/maxwell_3d.h15
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp19
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:
679 679
680 INSERT_PADDING_WORDS(0x7); 680 INSERT_PADDING_WORDS(0x7);
681 681
682 INSERT_PADDING_WORDS(0x46); 682 INSERT_PADDING_WORDS(0x20);
683
684 struct {
685 u32 is_instanced[NumVertexArrays];
686
687 /// Returns whether the vertex array specified by index is supposed to be
688 /// accessed per instance or not.
689 bool IsInstancingEnabled(u32 index) const {
690 return is_instanced[index];
691 }
692 } instanced_arrays;
693
694 INSERT_PADDING_WORDS(0x6);
683 695
684 Cull cull; 696 Cull cull;
685 697
@@ -928,6 +940,7 @@ ASSERT_REG_POSITION(point_coord_replace, 0x581);
928ASSERT_REG_POSITION(code_address, 0x582); 940ASSERT_REG_POSITION(code_address, 0x582);
929ASSERT_REG_POSITION(draw, 0x585); 941ASSERT_REG_POSITION(draw, 0x585);
930ASSERT_REG_POSITION(index_array, 0x5F2); 942ASSERT_REG_POSITION(index_array, 0x5F2);
943ASSERT_REG_POSITION(instanced_arrays, 0x620);
931ASSERT_REG_POSITION(cull, 0x646); 944ASSERT_REG_POSITION(cull, 0x646);
932ASSERT_REG_POSITION(clear_buffers, 0x674); 945ASSERT_REG_POSITION(clear_buffers, 0x674);
933ASSERT_REG_POSITION(query, 0x6C0); 946ASSERT_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() {}
98std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, 98std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
99 GLintptr buffer_offset) { 99 GLintptr buffer_offset) {
100 MICROPROFILE_SCOPE(OpenGL_VAO); 100 MICROPROFILE_SCOPE(OpenGL_VAO);
101 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 101 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
102 const auto& regs = gpu.regs;
102 103
103 state.draw.vertex_array = hw_vao.handle; 104 state.draw.vertex_array = hw_vao.handle;
104 state.draw.vertex_buffer = stream_buffer.GetHandle(); 105 state.draw.vertex_buffer = stream_buffer.GetHandle();
@@ -110,9 +111,13 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
110 if (!vertex_array.IsEnabled()) 111 if (!vertex_array.IsEnabled())
111 continue; 112 continue;
112 113
113 const Tegra::GPUVAddr start = vertex_array.StartAddress(); 114 Tegra::GPUVAddr start = vertex_array.StartAddress();
114 const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 115 const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
115 116
117 if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
118 start += vertex_array.stride * (gpu.state.current_instance / vertex_array.divisor);
119 }
120
116 ASSERT(end > start); 121 ASSERT(end > start);
117 u64 size = end - start + 1; 122 u64 size = end - start + 1;
118 123
@@ -124,7 +129,15 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
124 glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, 129 glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset,
125 vertex_array.stride); 130 vertex_array.stride);
126 131
127 ASSERT_MSG(vertex_array.divisor == 0, "Instanced vertex arrays are not supported"); 132 if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
133 // Tell OpenGL that this is an instanced vertex buffer to prevent accessing different
134 // indexes on each vertex. We do the instance indexing manually by incrementing the
135 // start address of the vertex buffer.
136 glVertexBindingDivisor(index, 1);
137 } else {
138 // Disable the vertex buffer instancing.
139 glVertexBindingDivisor(index, 0);
140 }
128 } 141 }
129 142
130 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. 143 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.