summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_rasterizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp62
1 files changed, 28 insertions, 34 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 089daf96f..7ce8c2bcc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -135,27 +135,25 @@ void RasterizerOpenGL::CheckExtensions() {
}
}
-void RasterizerOpenGL::SetupVertexFormat() {
+GLuint RasterizerOpenGL::SetupVertexFormat() {
auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
- if (!gpu.dirty_flags.vertex_attrib_format)
- return;
+ if (!gpu.dirty_flags.vertex_attrib_format) {
+ return state.draw.vertex_array;
+ }
gpu.dirty_flags.vertex_attrib_format = false;
MICROPROFILE_SCOPE(OpenGL_VAO);
auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
- auto& VAO = iter->second;
+ auto& vao_entry = iter->second;
if (is_cache_miss) {
- VAO.Create();
- state.draw.vertex_array = VAO.handle;
- state.ApplyVertexBufferState();
+ vao_entry.Create();
+ const GLuint vao = vao_entry.handle;
- // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work
- // around.
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle());
+ glVertexArrayElementBuffer(vao, buffer_cache.GetHandle());
// Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
// Enables the first 16 vertex attributes always, as we don't know which ones are actually
@@ -163,7 +161,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
// for now to avoid OpenGL errors.
// TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
// assume every shader uses them all.
- for (unsigned index = 0; index < 16; ++index) {
+ for (u32 index = 0; index < 16; ++index) {
const auto& attrib = regs.vertex_attrib_format[index];
// Ignore invalid attributes.
@@ -178,28 +176,29 @@ void RasterizerOpenGL::SetupVertexFormat() {
ASSERT(buffer.IsEnabled());
- glEnableVertexAttribArray(index);
+ glEnableVertexArrayAttrib(vao, index);
if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
attrib.type ==
Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
- glVertexAttribIFormat(index, attrib.ComponentCount(),
- MaxwellToGL::VertexType(attrib), attrib.offset);
+ glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
+ MaxwellToGL::VertexType(attrib), attrib.offset);
} else {
- glVertexAttribFormat(index, attrib.ComponentCount(),
- MaxwellToGL::VertexType(attrib),
- attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
+ glVertexArrayAttribFormat(
+ vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
}
- glVertexAttribBinding(index, attrib.buffer);
+ glVertexArrayAttribBinding(vao, index, attrib.buffer);
}
}
- state.draw.vertex_array = VAO.handle;
- state.ApplyVertexBufferState();
// Rebinding the VAO invalidates the vertex buffer bindings.
gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
+
+ state.draw.vertex_array = vao_entry.handle;
+ return vao_entry.handle;
}
-void RasterizerOpenGL::SetupVertexBuffer() {
+void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
@@ -217,7 +216,7 @@ void RasterizerOpenGL::SetupVertexBuffer() {
if (!vertex_array.IsEnabled())
continue;
- Tegra::GPUVAddr start = vertex_array.StartAddress();
+ const Tegra::GPUVAddr start = vertex_array.StartAddress();
const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
ASSERT(end > start);
@@ -225,21 +224,18 @@ void RasterizerOpenGL::SetupVertexBuffer() {
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);
+ glVertexArrayVertexBuffer(vao, index, buffer_cache.GetHandle(), vertex_buffer_offset,
+ vertex_array.stride);
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
// Enable vertex buffer instancing with the specified divisor.
- glVertexBindingDivisor(index, vertex_array.divisor);
+ glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
} else {
// Disable the vertex buffer instancing.
- glVertexBindingDivisor(index, 0);
+ glVertexArrayBindingDivisor(vao, index, 0);
}
}
- // Implicit set by glBindVertexBuffer. Stupid glstate handling...
- state.draw.vertex_buffer = buffer_cache.GetHandle();
-
gpu.dirty_flags.vertex_array = 0;
}
@@ -689,9 +685,6 @@ void RasterizerOpenGL::DrawArrays() {
// Draw the vertex batch
const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
- state.draw.vertex_buffer = buffer_cache.GetHandle();
- state.ApplyVertexBufferState();
-
std::size_t buffer_size = CalculateVertexArraysSize();
// Add space for index buffer (keeping in mind non-core primitives)
@@ -721,8 +714,9 @@ void RasterizerOpenGL::DrawArrays() {
gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
}
- SetupVertexFormat();
- SetupVertexBuffer();
+ const GLuint vao = SetupVertexFormat();
+ SetupVertexBuffer(vao);
+
DrawParameters params = SetupDraw();
SetupShaders(params.primitive_mode);