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.cpp100
1 files changed, 37 insertions, 63 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index acdae849c..9658d379c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -107,7 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
state.draw.shader_program = 0;
state.Apply();
- LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
CheckExtensions();
}
@@ -121,66 +120,41 @@ void RasterizerOpenGL::CheckExtensions() {
}
}
-GLuint RasterizerOpenGL::SetupVertexFormat() {
+void RasterizerOpenGL::SetupVertexFormat() {
auto& gpu = system.GPU().Maxwell3D();
const auto& regs = gpu.regs;
MICROPROFILE_SCOPE(OpenGL_VAO);
- auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
- auto& vao_entry = iter->second;
-
- if (is_cache_miss) {
- vao_entry.Create();
- const GLuint vao = vao_entry.handle;
-
- // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob
- // that fails to properly create the vertex array if it's not bound even after creating it
- // with glCreateVertexArrays
- state.draw.vertex_array = vao;
- state.ApplyVertexArrayState();
-
- // 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
- // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
- // 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 (u32 index = 0; index < 16; ++index) {
- const auto& attrib = regs.vertex_attrib_format[index];
-
- // Ignore invalid attributes.
- if (!attrib.IsValid())
- continue;
-
- const auto& buffer = regs.vertex_array[attrib.buffer];
- LOG_TRACE(Render_OpenGL,
- "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
- index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
- attrib.offset.Value(), attrib.IsNormalized());
-
- ASSERT(buffer.IsEnabled());
-
- glEnableVertexArrayAttrib(vao, index);
- if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
- attrib.type ==
- Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
- glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
- MaxwellToGL::VertexType(attrib), attrib.offset);
- } else {
- glVertexArrayAttribFormat(
- vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
- attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
- }
- glVertexArrayAttribBinding(vao, index, attrib.buffer);
+ // 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 used until
+ // shader time. Note, Tegra technically supports 32, but we're capping this to 16 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 (u32 index = 0; index < 16; ++index) {
+ const auto& attrib = regs.vertex_attrib_format[index];
+
+ // Ignore invalid attributes.
+ if (!attrib.IsValid()) {
+ glDisableVertexAttribArray(index);
+ continue;
}
- }
+ glEnableVertexAttribArray(index);
- state.draw.vertex_array = vao_entry.handle;
- return vao_entry.handle;
+ if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
+ attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
+ glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ attrib.offset);
+ } else {
+ glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
+ }
+ glVertexAttribBinding(index, attrib.buffer);
+ }
}
-void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
+void RasterizerOpenGL::SetupVertexBuffer() {
auto& gpu = system.GPU().Maxwell3D();
const auto& regs = gpu.regs;
@@ -189,8 +163,9 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
// Upload all guest vertex arrays sequentially to our buffer
for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
const auto& vertex_array = regs.vertex_array[index];
- if (!vertex_array.IsEnabled())
+ if (!vertex_array.IsEnabled()) {
continue;
+ }
const GPUVAddr start = vertex_array.StartAddress();
const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
@@ -205,15 +180,15 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
// Enable vertex buffer instancing with the specified divisor.
- glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
+ glVertexBindingDivisor(index, vertex_array.divisor);
} else {
// Disable the vertex buffer instancing.
- glVertexArrayBindingDivisor(vao, index, 0);
+ glVertexBindingDivisor(index, 0);
}
}
}
-void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
+void RasterizerOpenGL::SetupVertexInstances() {
auto& gpu = system.GPU().Maxwell3D();
const auto& regs = gpu.regs;
@@ -222,10 +197,10 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
if (regs.instanced_arrays.IsInstancingEnabled(index) &&
regs.vertex_array[index].divisor != 0) {
// Enable vertex buffer instancing with the specified divisor.
- glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor);
+ glVertexBindingDivisor(index, regs.vertex_array[index].divisor);
} else {
// Disable the vertex buffer instancing.
- glVertexArrayBindingDivisor(vao, index, 0);
+ glVertexBindingDivisor(index, 0);
}
}
}
@@ -559,13 +534,12 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
buffer_cache.Map(buffer_size);
// Prepare vertex array format.
- const GLuint vao = SetupVertexFormat();
- vertex_array_pushbuffer.Setup(vao);
+ SetupVertexFormat();
+ vertex_array_pushbuffer.Setup();
// Upload vertex and index data.
- SetupVertexBuffer(vao);
- SetupVertexInstances(vao);
-
+ SetupVertexBuffer();
+ SetupVertexInstances();
GLintptr index_buffer_offset;
if (is_indexed) {
index_buffer_offset = SetupIndexBuffer();