summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp174
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h13
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h82
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h4
9 files changed, 186 insertions, 118 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e8d61bd41..8cfa0013f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -16,7 +16,7 @@
16#include "common/microprofile.h" 16#include "common/microprofile.h"
17#include "common/scope_exit.h" 17#include "common/scope_exit.h"
18#include "common/settings.h" 18#include "common/settings.h"
19 19#include "video_core/control/channel_state.h"
20#include "video_core/engines/kepler_compute.h" 20#include "video_core/engines/kepler_compute.h"
21#include "video_core/engines/maxwell_3d.h" 21#include "video_core/engines/maxwell_3d.h"
22#include "video_core/memory_manager.h" 22#include "video_core/memory_manager.h"
@@ -56,9 +56,8 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra
56 Core::Memory::Memory& cpu_memory_, const Device& device_, 56 Core::Memory::Memory& cpu_memory_, const Device& device_,
57 ScreenInfo& screen_info_, ProgramManager& program_manager_, 57 ScreenInfo& screen_info_, ProgramManager& program_manager_,
58 StateTracker& state_tracker_) 58 StateTracker& state_tracker_)
59 : RasterizerAccelerated(cpu_memory_), gpu(gpu_), maxwell3d(gpu.Maxwell3D()), 59 : RasterizerAccelerated(cpu_memory_), gpu(gpu_), device(device_), screen_info(screen_info_),
60 kepler_compute(gpu.KeplerCompute()), gpu_memory(gpu.MemoryManager()), device(device_), 60 program_manager(program_manager_), state_tracker(state_tracker_),
61 screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_),
62 texture_cache_runtime(device, program_manager, state_tracker), 61 texture_cache_runtime(device, program_manager, state_tracker),
63 texture_cache(texture_cache_runtime, *this), buffer_cache_runtime(device), 62 texture_cache(texture_cache_runtime, *this), buffer_cache_runtime(device),
64 buffer_cache(*this, cpu_memory_, buffer_cache_runtime), 63 buffer_cache(*this, cpu_memory_, buffer_cache_runtime),
@@ -70,7 +69,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra
70RasterizerOpenGL::~RasterizerOpenGL() = default; 69RasterizerOpenGL::~RasterizerOpenGL() = default;
71 70
72void RasterizerOpenGL::SyncVertexFormats() { 71void RasterizerOpenGL::SyncVertexFormats() {
73 auto& flags = maxwell3d.dirty.flags; 72 auto& flags = maxwell3d->dirty.flags;
74 if (!flags[Dirty::VertexFormats]) { 73 if (!flags[Dirty::VertexFormats]) {
75 return; 74 return;
76 } 75 }
@@ -88,7 +87,7 @@ void RasterizerOpenGL::SyncVertexFormats() {
88 } 87 }
89 flags[Dirty::VertexFormat0 + index] = false; 88 flags[Dirty::VertexFormat0 + index] = false;
90 89
91 const auto attrib = maxwell3d.regs.vertex_attrib_format[index]; 90 const auto attrib = maxwell3d->regs.vertex_attrib_format[index];
92 const auto gl_index = static_cast<GLuint>(index); 91 const auto gl_index = static_cast<GLuint>(index);
93 92
94 // Disable constant attributes. 93 // Disable constant attributes.
@@ -112,13 +111,13 @@ void RasterizerOpenGL::SyncVertexFormats() {
112} 111}
113 112
114void RasterizerOpenGL::SyncVertexInstances() { 113void RasterizerOpenGL::SyncVertexInstances() {
115 auto& flags = maxwell3d.dirty.flags; 114 auto& flags = maxwell3d->dirty.flags;
116 if (!flags[Dirty::VertexInstances]) { 115 if (!flags[Dirty::VertexInstances]) {
117 return; 116 return;
118 } 117 }
119 flags[Dirty::VertexInstances] = false; 118 flags[Dirty::VertexInstances] = false;
120 119
121 const auto& regs = maxwell3d.regs; 120 const auto& regs = maxwell3d->regs;
122 for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) { 121 for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {
123 if (!flags[Dirty::VertexInstance0 + index]) { 122 if (!flags[Dirty::VertexInstance0 + index]) {
124 continue; 123 continue;
@@ -139,11 +138,11 @@ void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_load
139 138
140void RasterizerOpenGL::Clear() { 139void RasterizerOpenGL::Clear() {
141 MICROPROFILE_SCOPE(OpenGL_Clears); 140 MICROPROFILE_SCOPE(OpenGL_Clears);
142 if (!maxwell3d.ShouldExecute()) { 141 if (!maxwell3d->ShouldExecute()) {
143 return; 142 return;
144 } 143 }
145 144
146 const auto& regs = maxwell3d.regs; 145 const auto& regs = maxwell3d->regs;
147 bool use_color{}; 146 bool use_color{};
148 bool use_depth{}; 147 bool use_depth{};
149 bool use_stencil{}; 148 bool use_stencil{};
@@ -221,17 +220,17 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
221 220
222 SyncState(); 221 SyncState();
223 222
224 const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology); 223 const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);
225 BeginTransformFeedback(pipeline, primitive_mode); 224 BeginTransformFeedback(pipeline, primitive_mode);
226 225
227 const GLuint base_instance = static_cast<GLuint>(maxwell3d.regs.vb_base_instance); 226 const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.vb_base_instance);
228 const GLsizei num_instances = 227 const GLsizei num_instances =
229 static_cast<GLsizei>(is_instanced ? maxwell3d.mme_draw.instance_count : 1); 228 static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1);
230 if (is_indexed) { 229 if (is_indexed) {
231 const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vb_element_base); 230 const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vb_element_base);
232 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.index_array.count); 231 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_array.count);
233 const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); 232 const GLvoid* const offset = buffer_cache_runtime.IndexOffset();
234 const GLenum format = MaxwellToGL::IndexFormat(maxwell3d.regs.index_array.format); 233 const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_array.format);
235 if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { 234 if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {
236 glDrawElements(primitive_mode, num_vertices, format, offset); 235 glDrawElements(primitive_mode, num_vertices, format, offset);
237 } else if (num_instances == 1 && base_instance == 0) { 236 } else if (num_instances == 1 && base_instance == 0) {
@@ -250,8 +249,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
250 base_instance); 249 base_instance);
251 } 250 }
252 } else { 251 } else {
253 const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vertex_buffer.first); 252 const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vertex_buffer.first);
254 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.vertex_buffer.count); 253 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.vertex_buffer.count);
255 if (num_instances == 1 && base_instance == 0) { 254 if (num_instances == 1 && base_instance == 0) {
256 glDrawArrays(primitive_mode, base_vertex, num_vertices); 255 glDrawArrays(primitive_mode, base_vertex, num_vertices);
257 } else if (base_instance == 0) { 256 } else if (base_instance == 0) {
@@ -273,7 +272,7 @@ void RasterizerOpenGL::DispatchCompute() {
273 return; 272 return;
274 } 273 }
275 pipeline->Configure(); 274 pipeline->Configure();
276 const auto& qmd{kepler_compute.launch_description}; 275 const auto& qmd{kepler_compute->launch_description};
277 glDispatchCompute(qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z); 276 glDispatchCompute(qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z);
278 ++num_queued_commands; 277 ++num_queued_commands;
279 has_written_global_memory |= pipeline->WritesGlobalMemory(); 278 has_written_global_memory |= pipeline->WritesGlobalMemory();
@@ -388,10 +387,10 @@ void RasterizerOpenGL::ModifyGPUMemory(GPUVAddr addr, u64 size) {
388 387
389void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { 388void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) {
390 if (!gpu.IsAsync()) { 389 if (!gpu.IsAsync()) {
391 gpu_memory.Write<u32>(addr, value); 390 gpu_memory->Write<u32>(addr, value);
392 return; 391 return;
393 } 392 }
394 auto paddr = gpu_memory.GetPointer(addr); 393 auto paddr = gpu_memory->GetPointer(addr);
395 fence_manager.SignalSemaphore(paddr, value); 394 fence_manager.SignalSemaphore(paddr, value);
396} 395}
397 396
@@ -483,12 +482,12 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA()
483 482
484void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, 483void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
485 std::span<u8> memory) { 484 std::span<u8> memory) {
486 auto cpu_addr = gpu_memory.GpuToCpuAddress(address); 485 auto cpu_addr = gpu_memory->GpuToCpuAddress(address);
487 if (!cpu_addr) [[unlikely]] { 486 if (!cpu_addr) [[unlikely]] {
488 gpu_memory.WriteBlock(address, memory.data(), copy_size); 487 gpu_memory->WriteBlock(address, memory.data(), copy_size);
489 return; 488 return;
490 } 489 }
491 gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size); 490 gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size);
492 { 491 {
493 std::unique_lock<std::mutex> lock{buffer_cache.mutex}; 492 std::unique_lock<std::mutex> lock{buffer_cache.mutex};
494 if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { 493 if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) {
@@ -551,8 +550,8 @@ void RasterizerOpenGL::SyncState() {
551} 550}
552 551
553void RasterizerOpenGL::SyncViewport() { 552void RasterizerOpenGL::SyncViewport() {
554 auto& flags = maxwell3d.dirty.flags; 553 auto& flags = maxwell3d->dirty.flags;
555 const auto& regs = maxwell3d.regs; 554 const auto& regs = maxwell3d->regs;
556 555
557 const bool rescale_viewports = flags[VideoCommon::Dirty::RescaleViewports]; 556 const bool rescale_viewports = flags[VideoCommon::Dirty::RescaleViewports];
558 const bool dirty_viewport = flags[Dirty::Viewports] || rescale_viewports; 557 const bool dirty_viewport = flags[Dirty::Viewports] || rescale_viewports;
@@ -657,23 +656,23 @@ void RasterizerOpenGL::SyncViewport() {
657} 656}
658 657
659void RasterizerOpenGL::SyncDepthClamp() { 658void RasterizerOpenGL::SyncDepthClamp() {
660 auto& flags = maxwell3d.dirty.flags; 659 auto& flags = maxwell3d->dirty.flags;
661 if (!flags[Dirty::DepthClampEnabled]) { 660 if (!flags[Dirty::DepthClampEnabled]) {
662 return; 661 return;
663 } 662 }
664 flags[Dirty::DepthClampEnabled] = false; 663 flags[Dirty::DepthClampEnabled] = false;
665 664
666 oglEnable(GL_DEPTH_CLAMP, maxwell3d.regs.view_volume_clip_control.depth_clamp_disabled == 0); 665 oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.view_volume_clip_control.depth_clamp_disabled == 0);
667} 666}
668 667
669void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { 668void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
670 auto& flags = maxwell3d.dirty.flags; 669 auto& flags = maxwell3d->dirty.flags;
671 if (!flags[Dirty::ClipDistances] && !flags[VideoCommon::Dirty::Shaders]) { 670 if (!flags[Dirty::ClipDistances] && !flags[VideoCommon::Dirty::Shaders]) {
672 return; 671 return;
673 } 672 }
674 flags[Dirty::ClipDistances] = false; 673 flags[Dirty::ClipDistances] = false;
675 674
676 clip_mask &= maxwell3d.regs.clip_distance_enabled; 675 clip_mask &= maxwell3d->regs.clip_distance_enabled;
677 if (clip_mask == last_clip_distance_mask) { 676 if (clip_mask == last_clip_distance_mask) {
678 return; 677 return;
679 } 678 }
@@ -689,8 +688,8 @@ void RasterizerOpenGL::SyncClipCoef() {
689} 688}
690 689
691void RasterizerOpenGL::SyncCullMode() { 690void RasterizerOpenGL::SyncCullMode() {
692 auto& flags = maxwell3d.dirty.flags; 691 auto& flags = maxwell3d->dirty.flags;
693 const auto& regs = maxwell3d.regs; 692 const auto& regs = maxwell3d->regs;
694 693
695 if (flags[Dirty::CullTest]) { 694 if (flags[Dirty::CullTest]) {
696 flags[Dirty::CullTest] = false; 695 flags[Dirty::CullTest] = false;
@@ -705,23 +704,23 @@ void RasterizerOpenGL::SyncCullMode() {
705} 704}
706 705
707void RasterizerOpenGL::SyncPrimitiveRestart() { 706void RasterizerOpenGL::SyncPrimitiveRestart() {
708 auto& flags = maxwell3d.dirty.flags; 707 auto& flags = maxwell3d->dirty.flags;
709 if (!flags[Dirty::PrimitiveRestart]) { 708 if (!flags[Dirty::PrimitiveRestart]) {
710 return; 709 return;
711 } 710 }
712 flags[Dirty::PrimitiveRestart] = false; 711 flags[Dirty::PrimitiveRestart] = false;
713 712
714 if (maxwell3d.regs.primitive_restart.enabled) { 713 if (maxwell3d->regs.primitive_restart.enabled) {
715 glEnable(GL_PRIMITIVE_RESTART); 714 glEnable(GL_PRIMITIVE_RESTART);
716 glPrimitiveRestartIndex(maxwell3d.regs.primitive_restart.index); 715 glPrimitiveRestartIndex(maxwell3d->regs.primitive_restart.index);
717 } else { 716 } else {
718 glDisable(GL_PRIMITIVE_RESTART); 717 glDisable(GL_PRIMITIVE_RESTART);
719 } 718 }
720} 719}
721 720
722void RasterizerOpenGL::SyncDepthTestState() { 721void RasterizerOpenGL::SyncDepthTestState() {
723 auto& flags = maxwell3d.dirty.flags; 722 auto& flags = maxwell3d->dirty.flags;
724 const auto& regs = maxwell3d.regs; 723 const auto& regs = maxwell3d->regs;
725 724
726 if (flags[Dirty::DepthMask]) { 725 if (flags[Dirty::DepthMask]) {
727 flags[Dirty::DepthMask] = false; 726 flags[Dirty::DepthMask] = false;
@@ -740,13 +739,13 @@ void RasterizerOpenGL::SyncDepthTestState() {
740} 739}
741 740
742void RasterizerOpenGL::SyncStencilTestState() { 741void RasterizerOpenGL::SyncStencilTestState() {
743 auto& flags = maxwell3d.dirty.flags; 742 auto& flags = maxwell3d->dirty.flags;
744 if (!flags[Dirty::StencilTest]) { 743 if (!flags[Dirty::StencilTest]) {
745 return; 744 return;
746 } 745 }
747 flags[Dirty::StencilTest] = false; 746 flags[Dirty::StencilTest] = false;
748 747
749 const auto& regs = maxwell3d.regs; 748 const auto& regs = maxwell3d->regs;
750 oglEnable(GL_STENCIL_TEST, regs.stencil_enable); 749 oglEnable(GL_STENCIL_TEST, regs.stencil_enable);
751 750
752 glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), 751 glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func),
@@ -771,23 +770,23 @@ void RasterizerOpenGL::SyncStencilTestState() {
771} 770}
772 771
773void RasterizerOpenGL::SyncRasterizeEnable() { 772void RasterizerOpenGL::SyncRasterizeEnable() {
774 auto& flags = maxwell3d.dirty.flags; 773 auto& flags = maxwell3d->dirty.flags;
775 if (!flags[Dirty::RasterizeEnable]) { 774 if (!flags[Dirty::RasterizeEnable]) {
776 return; 775 return;
777 } 776 }
778 flags[Dirty::RasterizeEnable] = false; 777 flags[Dirty::RasterizeEnable] = false;
779 778
780 oglEnable(GL_RASTERIZER_DISCARD, maxwell3d.regs.rasterize_enable == 0); 779 oglEnable(GL_RASTERIZER_DISCARD, maxwell3d->regs.rasterize_enable == 0);
781} 780}
782 781
783void RasterizerOpenGL::SyncPolygonModes() { 782void RasterizerOpenGL::SyncPolygonModes() {
784 auto& flags = maxwell3d.dirty.flags; 783 auto& flags = maxwell3d->dirty.flags;
785 if (!flags[Dirty::PolygonModes]) { 784 if (!flags[Dirty::PolygonModes]) {
786 return; 785 return;
787 } 786 }
788 flags[Dirty::PolygonModes] = false; 787 flags[Dirty::PolygonModes] = false;
789 788
790 const auto& regs = maxwell3d.regs; 789 const auto& regs = maxwell3d->regs;
791 if (regs.fill_rectangle) { 790 if (regs.fill_rectangle) {
792 if (!GLAD_GL_NV_fill_rectangle) { 791 if (!GLAD_GL_NV_fill_rectangle) {
793 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); 792 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
@@ -820,7 +819,7 @@ void RasterizerOpenGL::SyncPolygonModes() {
820} 819}
821 820
822void RasterizerOpenGL::SyncColorMask() { 821void RasterizerOpenGL::SyncColorMask() {
823 auto& flags = maxwell3d.dirty.flags; 822 auto& flags = maxwell3d->dirty.flags;
824 if (!flags[Dirty::ColorMasks]) { 823 if (!flags[Dirty::ColorMasks]) {
825 return; 824 return;
826 } 825 }
@@ -829,7 +828,7 @@ void RasterizerOpenGL::SyncColorMask() {
829 const bool force = flags[Dirty::ColorMaskCommon]; 828 const bool force = flags[Dirty::ColorMaskCommon];
830 flags[Dirty::ColorMaskCommon] = false; 829 flags[Dirty::ColorMaskCommon] = false;
831 830
832 const auto& regs = maxwell3d.regs; 831 const auto& regs = maxwell3d->regs;
833 if (regs.color_mask_common) { 832 if (regs.color_mask_common) {
834 if (!force && !flags[Dirty::ColorMask0]) { 833 if (!force && !flags[Dirty::ColorMask0]) {
835 return; 834 return;
@@ -854,30 +853,30 @@ void RasterizerOpenGL::SyncColorMask() {
854} 853}
855 854
856void RasterizerOpenGL::SyncMultiSampleState() { 855void RasterizerOpenGL::SyncMultiSampleState() {
857 auto& flags = maxwell3d.dirty.flags; 856 auto& flags = maxwell3d->dirty.flags;
858 if (!flags[Dirty::MultisampleControl]) { 857 if (!flags[Dirty::MultisampleControl]) {
859 return; 858 return;
860 } 859 }
861 flags[Dirty::MultisampleControl] = false; 860 flags[Dirty::MultisampleControl] = false;
862 861
863 const auto& regs = maxwell3d.regs; 862 const auto& regs = maxwell3d->regs;
864 oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); 863 oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage);
865 oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); 864 oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one);
866} 865}
867 866
868void RasterizerOpenGL::SyncFragmentColorClampState() { 867void RasterizerOpenGL::SyncFragmentColorClampState() {
869 auto& flags = maxwell3d.dirty.flags; 868 auto& flags = maxwell3d->dirty.flags;
870 if (!flags[Dirty::FragmentClampColor]) { 869 if (!flags[Dirty::FragmentClampColor]) {
871 return; 870 return;
872 } 871 }
873 flags[Dirty::FragmentClampColor] = false; 872 flags[Dirty::FragmentClampColor] = false;
874 873
875 glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d.regs.frag_color_clamp ? GL_TRUE : GL_FALSE); 874 glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d->regs.frag_color_clamp ? GL_TRUE : GL_FALSE);
876} 875}
877 876
878void RasterizerOpenGL::SyncBlendState() { 877void RasterizerOpenGL::SyncBlendState() {
879 auto& flags = maxwell3d.dirty.flags; 878 auto& flags = maxwell3d->dirty.flags;
880 const auto& regs = maxwell3d.regs; 879 const auto& regs = maxwell3d->regs;
881 880
882 if (flags[Dirty::BlendColor]) { 881 if (flags[Dirty::BlendColor]) {
883 flags[Dirty::BlendColor] = false; 882 flags[Dirty::BlendColor] = false;
@@ -934,13 +933,13 @@ void RasterizerOpenGL::SyncBlendState() {
934} 933}
935 934
936void RasterizerOpenGL::SyncLogicOpState() { 935void RasterizerOpenGL::SyncLogicOpState() {
937 auto& flags = maxwell3d.dirty.flags; 936 auto& flags = maxwell3d->dirty.flags;
938 if (!flags[Dirty::LogicOp]) { 937 if (!flags[Dirty::LogicOp]) {
939 return; 938 return;
940 } 939 }
941 flags[Dirty::LogicOp] = false; 940 flags[Dirty::LogicOp] = false;
942 941
943 const auto& regs = maxwell3d.regs; 942 const auto& regs = maxwell3d->regs;
944 if (regs.logic_op.enable) { 943 if (regs.logic_op.enable) {
945 glEnable(GL_COLOR_LOGIC_OP); 944 glEnable(GL_COLOR_LOGIC_OP);
946 glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); 945 glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation));
@@ -950,7 +949,7 @@ void RasterizerOpenGL::SyncLogicOpState() {
950} 949}
951 950
952void RasterizerOpenGL::SyncScissorTest() { 951void RasterizerOpenGL::SyncScissorTest() {
953 auto& flags = maxwell3d.dirty.flags; 952 auto& flags = maxwell3d->dirty.flags;
954 if (!flags[Dirty::Scissors] && !flags[VideoCommon::Dirty::RescaleScissors]) { 953 if (!flags[Dirty::Scissors] && !flags[VideoCommon::Dirty::RescaleScissors]) {
955 return; 954 return;
956 } 955 }
@@ -959,7 +958,7 @@ void RasterizerOpenGL::SyncScissorTest() {
959 const bool force = flags[VideoCommon::Dirty::RescaleScissors]; 958 const bool force = flags[VideoCommon::Dirty::RescaleScissors];
960 flags[VideoCommon::Dirty::RescaleScissors] = false; 959 flags[VideoCommon::Dirty::RescaleScissors] = false;
961 960
962 const auto& regs = maxwell3d.regs; 961 const auto& regs = maxwell3d->regs;
963 962
964 const auto& resolution = Settings::values.resolution_info; 963 const auto& resolution = Settings::values.resolution_info;
965 const bool is_rescaling{texture_cache.IsRescaling()}; 964 const bool is_rescaling{texture_cache.IsRescaling()};
@@ -995,39 +994,39 @@ void RasterizerOpenGL::SyncScissorTest() {
995} 994}
996 995
997void RasterizerOpenGL::SyncPointState() { 996void RasterizerOpenGL::SyncPointState() {
998 auto& flags = maxwell3d.dirty.flags; 997 auto& flags = maxwell3d->dirty.flags;
999 if (!flags[Dirty::PointSize]) { 998 if (!flags[Dirty::PointSize]) {
1000 return; 999 return;
1001 } 1000 }
1002 flags[Dirty::PointSize] = false; 1001 flags[Dirty::PointSize] = false;
1003 1002
1004 oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable); 1003 oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable);
1005 oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d.regs.vp_point_size.enable); 1004 oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.vp_point_size.enable);
1006 const bool is_rescaling{texture_cache.IsRescaling()}; 1005 const bool is_rescaling{texture_cache.IsRescaling()};
1007 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; 1006 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
1008 glPointSize(std::max(1.0f, maxwell3d.regs.point_size * scale)); 1007 glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale));
1009} 1008}
1010 1009
1011void RasterizerOpenGL::SyncLineState() { 1010void RasterizerOpenGL::SyncLineState() {
1012 auto& flags = maxwell3d.dirty.flags; 1011 auto& flags = maxwell3d->dirty.flags;
1013 if (!flags[Dirty::LineWidth]) { 1012 if (!flags[Dirty::LineWidth]) {
1014 return; 1013 return;
1015 } 1014 }
1016 flags[Dirty::LineWidth] = false; 1015 flags[Dirty::LineWidth] = false;
1017 1016
1018 const auto& regs = maxwell3d.regs; 1017 const auto& regs = maxwell3d->regs;
1019 oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable); 1018 oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable);
1020 glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased); 1019 glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased);
1021} 1020}
1022 1021
1023void RasterizerOpenGL::SyncPolygonOffset() { 1022void RasterizerOpenGL::SyncPolygonOffset() {
1024 auto& flags = maxwell3d.dirty.flags; 1023 auto& flags = maxwell3d->dirty.flags;
1025 if (!flags[Dirty::PolygonOffset]) { 1024 if (!flags[Dirty::PolygonOffset]) {
1026 return; 1025 return;
1027 } 1026 }
1028 flags[Dirty::PolygonOffset] = false; 1027 flags[Dirty::PolygonOffset] = false;
1029 1028
1030 const auto& regs = maxwell3d.regs; 1029 const auto& regs = maxwell3d->regs;
1031 oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable); 1030 oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable);
1032 oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); 1031 oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable);
1033 oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); 1032 oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable);
@@ -1041,13 +1040,13 @@ void RasterizerOpenGL::SyncPolygonOffset() {
1041} 1040}
1042 1041
1043void RasterizerOpenGL::SyncAlphaTest() { 1042void RasterizerOpenGL::SyncAlphaTest() {
1044 auto& flags = maxwell3d.dirty.flags; 1043 auto& flags = maxwell3d->dirty.flags;
1045 if (!flags[Dirty::AlphaTest]) { 1044 if (!flags[Dirty::AlphaTest]) {
1046 return; 1045 return;
1047 } 1046 }
1048 flags[Dirty::AlphaTest] = false; 1047 flags[Dirty::AlphaTest] = false;
1049 1048
1050 const auto& regs = maxwell3d.regs; 1049 const auto& regs = maxwell3d->regs;
1051 if (regs.alpha_test_enabled) { 1050 if (regs.alpha_test_enabled) {
1052 glEnable(GL_ALPHA_TEST); 1051 glEnable(GL_ALPHA_TEST);
1053 glAlphaFunc(MaxwellToGL::ComparisonOp(regs.alpha_test_func), regs.alpha_test_ref); 1052 glAlphaFunc(MaxwellToGL::ComparisonOp(regs.alpha_test_func), regs.alpha_test_ref);
@@ -1057,17 +1056,17 @@ void RasterizerOpenGL::SyncAlphaTest() {
1057} 1056}
1058 1057
1059void RasterizerOpenGL::SyncFramebufferSRGB() { 1058void RasterizerOpenGL::SyncFramebufferSRGB() {
1060 auto& flags = maxwell3d.dirty.flags; 1059 auto& flags = maxwell3d->dirty.flags;
1061 if (!flags[Dirty::FramebufferSRGB]) { 1060 if (!flags[Dirty::FramebufferSRGB]) {
1062 return; 1061 return;
1063 } 1062 }
1064 flags[Dirty::FramebufferSRGB] = false; 1063 flags[Dirty::FramebufferSRGB] = false;
1065 1064
1066 oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d.regs.framebuffer_srgb); 1065 oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d->regs.framebuffer_srgb);
1067} 1066}
1068 1067
1069void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) { 1068void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) {
1070 const auto& regs = maxwell3d.regs; 1069 const auto& regs = maxwell3d->regs;
1071 if (regs.tfb_enabled == 0) { 1070 if (regs.tfb_enabled == 0) {
1072 return; 1071 return;
1073 } 1072 }
@@ -1086,11 +1085,48 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum
1086} 1085}
1087 1086
1088void RasterizerOpenGL::EndTransformFeedback() { 1087void RasterizerOpenGL::EndTransformFeedback() {
1089 if (maxwell3d.regs.tfb_enabled != 0) { 1088 if (maxwell3d->regs.tfb_enabled != 0) {
1090 glEndTransformFeedback(); 1089 glEndTransformFeedback();
1091 } 1090 }
1092} 1091}
1093 1092
1093void RasterizerOpenGL::InitializeChannel(Tegra::Control::ChannelState& channel) {
1094 CreateChannel(channel);
1095 {
1096 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
1097 texture_cache.CreateChannel(channel);
1098 buffer_cache.CreateChannel(channel);
1099 }
1100 shader_cache.CreateChannel(channel);
1101 query_cache.CreateChannel(channel);
1102 state_tracker.SetupTables(channel);
1103}
1104
1105void RasterizerOpenGL::BindChannel(Tegra::Control::ChannelState& channel) {
1106 const s32 channel_id = channel.bind_id;
1107 BindToChannel(channel_id);
1108 {
1109 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
1110 texture_cache.BindToChannel(channel_id);
1111 buffer_cache.BindToChannel(channel_id);
1112 }
1113 shader_cache.BindToChannel(channel_id);
1114 query_cache.BindToChannel(channel_id);
1115 state_tracker.ChangeChannel(channel);
1116 state_tracker.InvalidateState();
1117}
1118
1119void RasterizerOpenGL::ReleaseChannel(s32 channel_id) {
1120 EraseChannel(channel_id);
1121 {
1122 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
1123 texture_cache.EraseChannel(channel_id);
1124 buffer_cache.EraseChannel(channel_id);
1125 }
1126 shader_cache.EraseChannel(channel_id);
1127 query_cache.EraseChannel(channel_id);
1128}
1129
1094AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {} 1130AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}
1095 1131
1096bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) { 1132bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 31a16fcba..39b20cfb2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -12,6 +12,7 @@
12#include <glad/glad.h> 12#include <glad/glad.h>
13 13
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "video_core/control/channel_state_cache.h"
15#include "video_core/engines/maxwell_dma.h" 16#include "video_core/engines/maxwell_dma.h"
16#include "video_core/rasterizer_accelerated.h" 17#include "video_core/rasterizer_accelerated.h"
17#include "video_core/rasterizer_interface.h" 18#include "video_core/rasterizer_interface.h"
@@ -58,7 +59,8 @@ private:
58 BufferCache& buffer_cache; 59 BufferCache& buffer_cache;
59}; 60};
60 61
61class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { 62class RasterizerOpenGL : public VideoCore::RasterizerAccelerated,
63 protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
62public: 64public:
63 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 65 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
64 Core::Memory::Memory& cpu_memory_, const Device& device_, 66 Core::Memory::Memory& cpu_memory_, const Device& device_,
@@ -107,6 +109,12 @@ public:
107 return num_queued_commands > 0; 109 return num_queued_commands > 0;
108 } 110 }
109 111
112 void InitializeChannel(Tegra::Control::ChannelState& channel) override;
113
114 void BindChannel(Tegra::Control::ChannelState& channel) override;
115
116 void ReleaseChannel(s32 channel_id) override;
117
110private: 118private:
111 static constexpr size_t MAX_TEXTURES = 192; 119 static constexpr size_t MAX_TEXTURES = 192;
112 static constexpr size_t MAX_IMAGES = 48; 120 static constexpr size_t MAX_IMAGES = 48;
@@ -191,9 +199,6 @@ private:
191 void EndTransformFeedback(); 199 void EndTransformFeedback();
192 200
193 Tegra::GPU& gpu; 201 Tegra::GPU& gpu;
194 Tegra::Engines::Maxwell3D& maxwell3d;
195 Tegra::Engines::KeplerCompute& kepler_compute;
196 Tegra::MemoryManager& gpu_memory;
197 202
198 const Device& device; 203 const Device& device;
199 ScreenInfo& screen_info; 204 ScreenInfo& screen_info;
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index 912725ef7..3657f867d 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -7,8 +7,8 @@
7 7
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "video_core/control/channel_state.h"
10#include "video_core/engines/maxwell_3d.h" 11#include "video_core/engines/maxwell_3d.h"
11#include "video_core/gpu.h"
12#include "video_core/renderer_opengl/gl_state_tracker.h" 12#include "video_core/renderer_opengl/gl_state_tracker.h"
13 13
14#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name) 14#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
@@ -202,9 +202,8 @@ void SetupDirtyMisc(Tables& tables) {
202 202
203} // Anonymous namespace 203} // Anonymous namespace
204 204
205StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} { 205void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
206 auto& dirty = gpu.Maxwell3D().dirty; 206 auto& tables{channel_state.maxwell_3d->dirty.tables};
207 auto& tables = dirty.tables;
208 SetupDirtyFlags(tables); 207 SetupDirtyFlags(tables);
209 SetupDirtyColorMasks(tables); 208 SetupDirtyColorMasks(tables);
210 SetupDirtyViewports(tables); 209 SetupDirtyViewports(tables);
@@ -230,4 +229,14 @@ StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags}
230 SetupDirtyMisc(tables); 229 SetupDirtyMisc(tables);
231} 230}
232 231
232void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) {
233 flags = &channel_state.maxwell_3d->dirty.flags;
234}
235
236void StateTracker::InvalidateState() {
237 flags->set();
238}
239
240StateTracker::StateTracker() : flags{} {}
241
233} // namespace OpenGL 242} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index 04e024f08..97d32768b 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -12,8 +12,10 @@
12#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
13 13
14namespace Tegra { 14namespace Tegra {
15class GPU; 15namespace Control {
16struct ChannelState;
16} 17}
18} // namespace Tegra
17 19
18namespace OpenGL { 20namespace OpenGL {
19 21
@@ -83,7 +85,7 @@ static_assert(Last <= std::numeric_limits<u8>::max());
83 85
84class StateTracker { 86class StateTracker {
85public: 87public:
86 explicit StateTracker(Tegra::GPU& gpu); 88 explicit StateTracker();
87 89
88 void BindIndexBuffer(GLuint new_index_buffer) { 90 void BindIndexBuffer(GLuint new_index_buffer) {
89 if (index_buffer == new_index_buffer) { 91 if (index_buffer == new_index_buffer) {
@@ -121,94 +123,106 @@ public:
121 } 123 }
122 124
123 void NotifyScreenDrawVertexArray() { 125 void NotifyScreenDrawVertexArray() {
124 flags[OpenGL::Dirty::VertexFormats] = true; 126 (*flags)[OpenGL::Dirty::VertexFormats] = true;
125 flags[OpenGL::Dirty::VertexFormat0 + 0] = true; 127 (*flags)[OpenGL::Dirty::VertexFormat0 + 0] = true;
126 flags[OpenGL::Dirty::VertexFormat0 + 1] = true; 128 (*flags)[OpenGL::Dirty::VertexFormat0 + 1] = true;
127 129
128 flags[VideoCommon::Dirty::VertexBuffers] = true; 130 (*flags)[VideoCommon::Dirty::VertexBuffers] = true;
129 flags[VideoCommon::Dirty::VertexBuffer0] = true; 131 (*flags)[VideoCommon::Dirty::VertexBuffer0] = true;
130 132
131 flags[OpenGL::Dirty::VertexInstances] = true; 133 (*flags)[OpenGL::Dirty::VertexInstances] = true;
132 flags[OpenGL::Dirty::VertexInstance0 + 0] = true; 134 (*flags)[OpenGL::Dirty::VertexInstance0 + 0] = true;
133 flags[OpenGL::Dirty::VertexInstance0 + 1] = true; 135 (*flags)[OpenGL::Dirty::VertexInstance0 + 1] = true;
134 } 136 }
135 137
136 void NotifyPolygonModes() { 138 void NotifyPolygonModes() {
137 flags[OpenGL::Dirty::PolygonModes] = true; 139 (*flags)[OpenGL::Dirty::PolygonModes] = true;
138 flags[OpenGL::Dirty::PolygonModeFront] = true; 140 (*flags)[OpenGL::Dirty::PolygonModeFront] = true;
139 flags[OpenGL::Dirty::PolygonModeBack] = true; 141 (*flags)[OpenGL::Dirty::PolygonModeBack] = true;
140 } 142 }
141 143
142 void NotifyViewport0() { 144 void NotifyViewport0() {
143 flags[OpenGL::Dirty::Viewports] = true; 145 (*flags)[OpenGL::Dirty::Viewports] = true;
144 flags[OpenGL::Dirty::Viewport0] = true; 146 (*flags)[OpenGL::Dirty::Viewport0] = true;
145 } 147 }
146 148
147 void NotifyScissor0() { 149 void NotifyScissor0() {
148 flags[OpenGL::Dirty::Scissors] = true; 150 (*flags)[OpenGL::Dirty::Scissors] = true;
149 flags[OpenGL::Dirty::Scissor0] = true; 151 (*flags)[OpenGL::Dirty::Scissor0] = true;
150 } 152 }
151 153
152 void NotifyColorMask(size_t index) { 154 void NotifyColorMask(size_t index) {
153 flags[OpenGL::Dirty::ColorMasks] = true; 155 (*flags)[OpenGL::Dirty::ColorMasks] = true;
154 flags[OpenGL::Dirty::ColorMask0 + index] = true; 156 (*flags)[OpenGL::Dirty::ColorMask0 + index] = true;
155 } 157 }
156 158
157 void NotifyBlend0() { 159 void NotifyBlend0() {
158 flags[OpenGL::Dirty::BlendStates] = true; 160 (*flags)[OpenGL::Dirty::BlendStates] = true;
159 flags[OpenGL::Dirty::BlendState0] = true; 161 (*flags)[OpenGL::Dirty::BlendState0] = true;
160 } 162 }
161 163
162 void NotifyFramebuffer() { 164 void NotifyFramebuffer() {
163 flags[VideoCommon::Dirty::RenderTargets] = true; 165 (*flags)[VideoCommon::Dirty::RenderTargets] = true;
164 } 166 }
165 167
166 void NotifyFrontFace() { 168 void NotifyFrontFace() {
167 flags[OpenGL::Dirty::FrontFace] = true; 169 (*flags)[OpenGL::Dirty::FrontFace] = true;
168 } 170 }
169 171
170 void NotifyCullTest() { 172 void NotifyCullTest() {
171 flags[OpenGL::Dirty::CullTest] = true; 173 (*flags)[OpenGL::Dirty::CullTest] = true;
172 } 174 }
173 175
174 void NotifyDepthMask() { 176 void NotifyDepthMask() {
175 flags[OpenGL::Dirty::DepthMask] = true; 177 (*flags)[OpenGL::Dirty::DepthMask] = true;
176 } 178 }
177 179
178 void NotifyDepthTest() { 180 void NotifyDepthTest() {
179 flags[OpenGL::Dirty::DepthTest] = true; 181 (*flags)[OpenGL::Dirty::DepthTest] = true;
180 } 182 }
181 183
182 void NotifyStencilTest() { 184 void NotifyStencilTest() {
183 flags[OpenGL::Dirty::StencilTest] = true; 185 (*flags)[OpenGL::Dirty::StencilTest] = true;
184 } 186 }
185 187
186 void NotifyPolygonOffset() { 188 void NotifyPolygonOffset() {
187 flags[OpenGL::Dirty::PolygonOffset] = true; 189 (*flags)[OpenGL::Dirty::PolygonOffset] = true;
188 } 190 }
189 191
190 void NotifyRasterizeEnable() { 192 void NotifyRasterizeEnable() {
191 flags[OpenGL::Dirty::RasterizeEnable] = true; 193 (*flags)[OpenGL::Dirty::RasterizeEnable] = true;
192 } 194 }
193 195
194 void NotifyFramebufferSRGB() { 196 void NotifyFramebufferSRGB() {
195 flags[OpenGL::Dirty::FramebufferSRGB] = true; 197 (*flags)[OpenGL::Dirty::FramebufferSRGB] = true;
196 } 198 }
197 199
198 void NotifyLogicOp() { 200 void NotifyLogicOp() {
199 flags[OpenGL::Dirty::LogicOp] = true; 201 (*flags)[OpenGL::Dirty::LogicOp] = true;
200 } 202 }
201 203
202 void NotifyClipControl() { 204 void NotifyClipControl() {
203 flags[OpenGL::Dirty::ClipControl] = true; 205 (*flags)[OpenGL::Dirty::ClipControl] = true;
204 } 206 }
205 207
206 void NotifyAlphaTest() { 208 void NotifyAlphaTest() {
207 flags[OpenGL::Dirty::AlphaTest] = true; 209 (*flags)[OpenGL::Dirty::AlphaTest] = true;
208 } 210 }
209 211
212 void NotifyRange(u8 start, u8 end) {
213 for (auto flag = start; flag <= end; flag++) {
214 (*flags)[flag] = true;
215 }
216 }
217
218 void SetupTables(Tegra::Control::ChannelState& channel_state);
219
220 void ChangeChannel(Tegra::Control::ChannelState& channel_state);
221
222 void InvalidateState();
223
210private: 224private:
211 Tegra::Engines::Maxwell3D::DirtyState::Flags& flags; 225 Tegra::Engines::Maxwell3D::DirtyState::Flags* flags;
212 226
213 GLuint framebuffer = 0; 227 GLuint framebuffer = 0;
214 GLuint index_buffer = 0; 228 GLuint index_buffer = 0;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 34f3f7a67..8bd5eba7e 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -131,7 +131,7 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
131 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, 131 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
132 std::unique_ptr<Core::Frontend::GraphicsContext> context_) 132 std::unique_ptr<Core::Frontend::GraphicsContext> context_)
133 : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_}, 133 : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_},
134 emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{gpu}, 134 emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{},
135 program_manager{device}, 135 program_manager{device},
136 rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) { 136 rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) {
137 if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) { 137 if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) {
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 68c2bc34c..d12669c9d 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -106,7 +106,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
106 surface(CreateSurface(instance, render_window)), 106 surface(CreateSurface(instance, render_window)),
107 device(CreateDevice(instance, dld, *surface)), 107 device(CreateDevice(instance, dld, *surface)),
108 memory_allocator(device, false), 108 memory_allocator(device, false),
109 state_tracker(gpu), 109 state_tracker(),
110 scheduler(device, state_tracker), 110 scheduler(device, state_tracker),
111 swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, 111 swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
112 render_window.GetFramebufferLayout().height, false), 112 render_window.GetFramebufferLayout().height, false),
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 5d9ff0589..bf750452f 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -995,7 +995,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
995 pipeline_cache.BindToChannel(channel_id); 995 pipeline_cache.BindToChannel(channel_id);
996 query_cache.BindToChannel(channel_id); 996 query_cache.BindToChannel(channel_id);
997 state_tracker.ChangeChannel(channel); 997 state_tracker.ChangeChannel(channel);
998 scheduler.InvalidateState(); 998 state_tracker.InvalidateState();
999} 999}
1000 1000
1001void RasterizerVulkan::ReleaseChannel(s32 channel_id) { 1001void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index a87bf8dd3..5a11d3267 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -10,7 +10,6 @@
10#include "video_core/control/channel_state.h" 10#include "video_core/control/channel_state.h"
11#include "video_core/dirty_flags.h" 11#include "video_core/dirty_flags.h"
12#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
13#include "video_core/gpu.h"
14#include "video_core/renderer_vulkan/vk_state_tracker.h" 13#include "video_core/renderer_vulkan/vk_state_tracker.h"
15 14
16#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name) 15#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
@@ -203,7 +202,10 @@ void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) {
203 flags = &channel_state.maxwell_3d->dirty.flags; 202 flags = &channel_state.maxwell_3d->dirty.flags;
204} 203}
205 204
206StateTracker::StateTracker(Tegra::GPU& gpu) 205void StateTracker::InvalidateState() {
207 : flags{}, invalidation_flags{MakeInvalidationFlags()} {} 206 flags->set();
207}
208
209StateTracker::StateTracker() : flags{}, invalidation_flags{MakeInvalidationFlags()} {}
208 210
209} // namespace Vulkan 211} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h
index 9f8a887f9..c107d9c24 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.h
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.h
@@ -59,7 +59,7 @@ class StateTracker {
59 using Maxwell = Tegra::Engines::Maxwell3D::Regs; 59 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
60 60
61public: 61public:
62 explicit StateTracker(Tegra::GPU& gpu); 62 explicit StateTracker();
63 63
64 void InvalidateCommandBufferState() { 64 void InvalidateCommandBufferState() {
65 (*flags) |= invalidation_flags; 65 (*flags) |= invalidation_flags;
@@ -149,6 +149,8 @@ public:
149 149
150 void ChangeChannel(Tegra::Control::ChannelState& channel_state); 150 void ChangeChannel(Tegra::Control::ChannelState& channel_state);
151 151
152 void InvalidateState();
153
152private: 154private:
153 static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u); 155 static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u);
154 156