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.cpp66
1 files changed, 54 insertions, 12 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 630a58e49..82b7a0649 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -176,15 +176,25 @@ void RasterizerOpenGL::SetupVertexFormat() {
}
state.draw.vertex_array = VAO.handle;
state.ApplyVertexBufferState();
+
+ // Rebinding the VAO invalidates the vertex buffer bindings.
+ gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
}
void RasterizerOpenGL::SetupVertexBuffer() {
- MICROPROFILE_SCOPE(OpenGL_VB);
- const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
+ auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
+ if (!gpu.dirty_flags.vertex_array)
+ return;
+
+ MICROPROFILE_SCOPE(OpenGL_VB);
+
// Upload all guest vertex arrays sequentially to our buffer
for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
+ if (~gpu.dirty_flags.vertex_array & (1u << index))
+ continue;
+
const auto& vertex_array = regs.vertex_array[index];
if (!vertex_array.IsEnabled())
continue;
@@ -211,6 +221,8 @@ void RasterizerOpenGL::SetupVertexBuffer() {
// Implicit set by glBindVertexBuffer. Stupid glstate handling...
state.draw.vertex_buffer = buffer_cache.GetHandle();
+
+ gpu.dirty_flags.vertex_array = 0;
}
DrawParameters RasterizerOpenGL::SetupDraw() {
@@ -600,7 +612,7 @@ void RasterizerOpenGL::DrawArrays() {
return;
MICROPROFILE_SCOPE(OpenGL_Drawing);
- const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
+ auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
ScopeAcquireGLContext acquire_context{emu_window};
@@ -620,7 +632,7 @@ void RasterizerOpenGL::DrawArrays() {
SyncTransformFeedback();
SyncPointState();
CheckAlphaTests();
-
+ SyncPolygonOffset();
// TODO(bunnei): Sync framebuffer_scale uniform here
// TODO(bunnei): Sync scissorbox uniform(s) here
@@ -653,7 +665,11 @@ void RasterizerOpenGL::DrawArrays() {
// Add space for at least 18 constant buffers
buffer_size += Maxwell::MaxConstBuffers * (MaxConstbufferSize + uniform_buffer_alignment);
- buffer_cache.Map(buffer_size);
+ bool invalidate = buffer_cache.Map(buffer_size);
+ if (invalidate) {
+ // As all cached buffers are invalidated, we need to recheck their state.
+ gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
+ }
SetupVertexFormat();
SetupVertexBuffer();
@@ -969,13 +985,25 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumViewports; i++) {
- const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
+ const bool geometry_shaders_enabled =
+ regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
+ const std::size_t viewport_count =
+ geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
+ for (std::size_t i = 0; i < viewport_count; i++) {
auto& viewport = current_state.viewports[i];
- viewport.x = viewport_rect.left;
- viewport.y = viewport_rect.bottom;
- viewport.width = viewport_rect.GetWidth();
- viewport.height = viewport_rect.GetHeight();
+ const auto& src = regs.viewports[i];
+ if (regs.viewport_transform_enabled) {
+ const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
+ viewport.x = viewport_rect.left;
+ viewport.y = viewport_rect.bottom;
+ viewport.width = viewport_rect.GetWidth();
+ viewport.height = viewport_rect.GetHeight();
+ } else {
+ viewport.x = src.x;
+ viewport.y = src.y;
+ viewport.width = src.width;
+ viewport.height = src.height;
+ }
viewport.depth_range_far = regs.viewports[i].depth_range_far;
viewport.depth_range_near = regs.viewports[i].depth_range_near;
}
@@ -1149,7 +1177,11 @@ void RasterizerOpenGL::SyncLogicOpState() {
void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state) {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumViewports; i++) {
+ const bool geometry_shaders_enabled =
+ regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
+ const std::size_t viewport_count =
+ geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
+ for (std::size_t i = 0; i < viewport_count; i++) {
const auto& src = regs.scissor_test[i];
auto& dst = current_state.viewports[i].scissor;
dst.enabled = (src.enable != 0);
@@ -1179,6 +1211,16 @@ void RasterizerOpenGL::SyncPointState() {
state.point.size = regs.point_size;
}
+void RasterizerOpenGL::SyncPolygonOffset() {
+ const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
+ state.polygon_offset.fill_enable = regs.polygon_offset_fill_enable != 0;
+ state.polygon_offset.line_enable = regs.polygon_offset_line_enable != 0;
+ state.polygon_offset.point_enable = regs.polygon_offset_point_enable != 0;
+ state.polygon_offset.units = regs.polygon_offset_units;
+ state.polygon_offset.factor = regs.polygon_offset_factor;
+ state.polygon_offset.clamp = regs.polygon_offset_clamp;
+}
+
void RasterizerOpenGL::CheckAlphaTests() {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;