Merge pull request #1104 from Subv/instanced_arrays
GLRasterizer: Implemented instanced vertex arrays.
This commit is contained in:
		| @@ -679,7 +679,19 @@ public: | |||||||
|  |  | ||||||
|                 INSERT_PADDING_WORDS(0x7); |                 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; |                 Cull cull; | ||||||
|  |  | ||||||
| @@ -928,6 +940,7 @@ ASSERT_REG_POSITION(point_coord_replace, 0x581); | |||||||
| ASSERT_REG_POSITION(code_address, 0x582); | ASSERT_REG_POSITION(code_address, 0x582); | ||||||
| ASSERT_REG_POSITION(draw, 0x585); | ASSERT_REG_POSITION(draw, 0x585); | ||||||
| ASSERT_REG_POSITION(index_array, 0x5F2); | ASSERT_REG_POSITION(index_array, 0x5F2); | ||||||
|  | ASSERT_REG_POSITION(instanced_arrays, 0x620); | ||||||
| ASSERT_REG_POSITION(cull, 0x646); | ASSERT_REG_POSITION(cull, 0x646); | ||||||
| ASSERT_REG_POSITION(clear_buffers, 0x674); | ASSERT_REG_POSITION(clear_buffers, 0x674); | ||||||
| ASSERT_REG_POSITION(query, 0x6C0); | ASSERT_REG_POSITION(query, 0x6C0); | ||||||
|   | |||||||
| @@ -98,7 +98,8 @@ RasterizerOpenGL::~RasterizerOpenGL() {} | |||||||
| std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | ||||||
|                                                              GLintptr buffer_offset) { |                                                              GLintptr buffer_offset) { | ||||||
|     MICROPROFILE_SCOPE(OpenGL_VAO); |     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_array = hw_vao.handle; | ||||||
|     state.draw.vertex_buffer = stream_buffer.GetHandle(); |     state.draw.vertex_buffer = stream_buffer.GetHandle(); | ||||||
| @@ -110,9 +111,13 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | |||||||
|         if (!vertex_array.IsEnabled()) |         if (!vertex_array.IsEnabled()) | ||||||
|             continue; |             continue; | ||||||
|  |  | ||||||
|         const Tegra::GPUVAddr start = vertex_array.StartAddress(); |         Tegra::GPUVAddr start = vertex_array.StartAddress(); | ||||||
|         const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); |         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); |         ASSERT(end > start); | ||||||
|         u64 size = end - start + 1; |         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, |         glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, | ||||||
|                            vertex_array.stride); |                            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. |     // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user