aboutsummaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp70
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.