diff options
| author | 2018-08-20 14:32:50 -0400 | |
|---|---|---|
| committer | 2018-08-20 14:32:50 -0400 | |
| commit | 028d90eb79b75292d352cc8d4b96a2df74cd6b6e (patch) | |
| tree | ab7df9fd12b103b7c832e9691d2abbb72ca38e93 | |
| parent | Merge pull request #1115 from Subv/texs_mask (diff) | |
| parent | GLRasterizer: Implemented instanced vertex arrays. (diff) | |
| download | yuzu-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.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: | |||
| 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); | |||
| 928 | ASSERT_REG_POSITION(code_address, 0x582); | 940 | ASSERT_REG_POSITION(code_address, 0x582); |
| 929 | ASSERT_REG_POSITION(draw, 0x585); | 941 | ASSERT_REG_POSITION(draw, 0x585); |
| 930 | ASSERT_REG_POSITION(index_array, 0x5F2); | 942 | ASSERT_REG_POSITION(index_array, 0x5F2); |
| 943 | ASSERT_REG_POSITION(instanced_arrays, 0x620); | ||
| 931 | ASSERT_REG_POSITION(cull, 0x646); | 944 | ASSERT_REG_POSITION(cull, 0x646); |
| 932 | ASSERT_REG_POSITION(clear_buffers, 0x674); | 945 | ASSERT_REG_POSITION(clear_buffers, 0x674); |
| 933 | ASSERT_REG_POSITION(query, 0x6C0); | 946 | 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() {} | |||
| 98 | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | 98 | std::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. |