diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e6eb829eb..e6d6917fa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -151,24 +151,17 @@ 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 += vertex_array.stride * (gpu.state.current_instance / vertex_array.divisor); - } - ASSERT(end > start); - u64 size = end - start + 1; - - GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size); + const u64 size = end - start + 1; + const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size); // Bind the vertex array to the buffer at the current offset. glBindVertexBuffer(index, buffer_cache.GetHandle(), vertex_buffer_offset, 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); @@ -178,7 +171,7 @@ void RasterizerOpenGL::SetupVertexArrays() { void RasterizerOpenGL::SetupShaders() { MICROPROFILE_SCOPE(OpenGL_Shader); - auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); + const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); // Next available bindpoints to use when uploading the const buffers and textures to the GLSL // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. @@ -186,7 +179,7 @@ void RasterizerOpenGL::SetupShaders() { u32 current_texture_bindpoint = 0; for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { - auto& shader_config = gpu.regs.shader_config[index]; + const auto& shader_config = gpu.regs.shader_config[index]; const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; // Skip stages that are not enabled @@ -198,7 +191,7 @@ void RasterizerOpenGL::SetupShaders() { GLShader::MaxwellUniformData ubo{}; ubo.SetFromRegs(gpu.state.shader_stages[stage]); - GLintptr offset = buffer_cache.UploadHostMemory( + const GLintptr offset = buffer_cache.UploadHostMemory( &ubo, sizeof(ubo), static_cast<size_t>(uniform_buffer_alignment)); // Bind the buffer @@ -432,11 +425,12 @@ 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}; - auto [dirty_color_surface, dirty_depth_surface] = + const auto [dirty_color_surface, dirty_depth_surface] = ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true); SyncDepthTestState(); @@ -450,7 +444,8 @@ void RasterizerOpenGL::DrawArrays() { // Draw the vertex batch const bool is_indexed = accelerate_draw == AccelDraw::Indexed; - const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; + const u64 index_buffer_size{static_cast<u64>(regs.index_array.count) * + static_cast<u64>(regs.index_array.FormatSizeInBytes())}; state.draw.vertex_buffer = buffer_cache.GetHandle(); state.Apply(); @@ -493,13 +488,29 @@ void RasterizerOpenGL::DrawArrays() { const GLint base_vertex{static_cast<GLint>(regs.vb_element_base)}; // Adjust the index buffer offset so it points to the first desired index. - index_buffer_offset += regs.index_array.first * 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); + index_buffer_offset += static_cast<GLintptr>(regs.index_array.first) * + static_cast<GLintptr>(regs.index_array.FormatSizeInBytes()); + + 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 @@ -516,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); @@ -532,7 +539,6 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { } void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { - MICROPROFILE_SCOPE(OpenGL_CacheManagement); InvalidateRegion(addr, size); } @@ -588,7 +594,7 @@ void RasterizerOpenGL::SamplerInfo::Create() { } void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { - GLuint s = sampler.handle; + const GLuint s = sampler.handle; if (mag_filter != config.mag_filter) { mag_filter = config.mag_filter; @@ -687,7 +693,7 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { const auto& entry = entries[bindpoint]; - u32 current_bindpoint = current_unit + bindpoint; + const u32 current_bindpoint = current_unit + bindpoint; // Bind the uniform to the sampler. |
