diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 174 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state_tracker.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state_tracker.h | 82 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.h | 4 | 
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 @@  #include "common/microprofile.h"  #include "common/scope_exit.h"  #include "common/settings.h" - +#include "video_core/control/channel_state.h"  #include "video_core/engines/kepler_compute.h"  #include "video_core/engines/maxwell_3d.h"  #include "video_core/memory_manager.h" @@ -56,9 +56,8 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra                                     Core::Memory::Memory& cpu_memory_, const Device& device_,                                     ScreenInfo& screen_info_, ProgramManager& program_manager_,                                     StateTracker& state_tracker_) -    : RasterizerAccelerated(cpu_memory_), gpu(gpu_), maxwell3d(gpu.Maxwell3D()), -      kepler_compute(gpu.KeplerCompute()), gpu_memory(gpu.MemoryManager()), device(device_), -      screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_), +    : RasterizerAccelerated(cpu_memory_), gpu(gpu_), device(device_), screen_info(screen_info_), +      program_manager(program_manager_), state_tracker(state_tracker_),        texture_cache_runtime(device, program_manager, state_tracker),        texture_cache(texture_cache_runtime, *this), buffer_cache_runtime(device),        buffer_cache(*this, cpu_memory_, buffer_cache_runtime), @@ -70,7 +69,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra  RasterizerOpenGL::~RasterizerOpenGL() = default;  void RasterizerOpenGL::SyncVertexFormats() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::VertexFormats]) {          return;      } @@ -88,7 +87,7 @@ void RasterizerOpenGL::SyncVertexFormats() {          }          flags[Dirty::VertexFormat0 + index] = false; -        const auto attrib = maxwell3d.regs.vertex_attrib_format[index]; +        const auto attrib = maxwell3d->regs.vertex_attrib_format[index];          const auto gl_index = static_cast<GLuint>(index);          // Disable constant attributes. @@ -112,13 +111,13 @@ void RasterizerOpenGL::SyncVertexFormats() {  }  void RasterizerOpenGL::SyncVertexInstances() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::VertexInstances]) {          return;      }      flags[Dirty::VertexInstances] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {          if (!flags[Dirty::VertexInstance0 + index]) {              continue; @@ -139,11 +138,11 @@ void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_load  void RasterizerOpenGL::Clear() {      MICROPROFILE_SCOPE(OpenGL_Clears); -    if (!maxwell3d.ShouldExecute()) { +    if (!maxwell3d->ShouldExecute()) {          return;      } -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      bool use_color{};      bool use_depth{};      bool use_stencil{}; @@ -221,17 +220,17 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {      SyncState(); -    const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology); +    const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);      BeginTransformFeedback(pipeline, primitive_mode); -    const GLuint base_instance = static_cast<GLuint>(maxwell3d.regs.vb_base_instance); +    const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.vb_base_instance);      const GLsizei num_instances = -        static_cast<GLsizei>(is_instanced ? maxwell3d.mme_draw.instance_count : 1); +        static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1);      if (is_indexed) { -        const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vb_element_base); -        const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.index_array.count); +        const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vb_element_base); +        const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_array.count);          const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); -        const GLenum format = MaxwellToGL::IndexFormat(maxwell3d.regs.index_array.format); +        const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_array.format);          if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {              glDrawElements(primitive_mode, num_vertices, format, offset);          } else if (num_instances == 1 && base_instance == 0) { @@ -250,8 +249,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {                                                            base_instance);          }      } else { -        const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vertex_buffer.first); -        const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.vertex_buffer.count); +        const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vertex_buffer.first); +        const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.vertex_buffer.count);          if (num_instances == 1 && base_instance == 0) {              glDrawArrays(primitive_mode, base_vertex, num_vertices);          } else if (base_instance == 0) { @@ -273,7 +272,7 @@ void RasterizerOpenGL::DispatchCompute() {          return;      }      pipeline->Configure(); -    const auto& qmd{kepler_compute.launch_description}; +    const auto& qmd{kepler_compute->launch_description};      glDispatchCompute(qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z);      ++num_queued_commands;      has_written_global_memory |= pipeline->WritesGlobalMemory(); @@ -388,10 +387,10 @@ void RasterizerOpenGL::ModifyGPUMemory(GPUVAddr addr, u64 size) {  void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) {      if (!gpu.IsAsync()) { -        gpu_memory.Write<u32>(addr, value); +        gpu_memory->Write<u32>(addr, value);          return;      } -    auto paddr = gpu_memory.GetPointer(addr); +    auto paddr = gpu_memory->GetPointer(addr);      fence_manager.SignalSemaphore(paddr, value);  } @@ -483,12 +482,12 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA()  void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,                                                  std::span<u8> memory) { -    auto cpu_addr = gpu_memory.GpuToCpuAddress(address); +    auto cpu_addr = gpu_memory->GpuToCpuAddress(address);      if (!cpu_addr) [[unlikely]] { -        gpu_memory.WriteBlock(address, memory.data(), copy_size); +        gpu_memory->WriteBlock(address, memory.data(), copy_size);          return;      } -    gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size); +    gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size);      {          std::unique_lock<std::mutex> lock{buffer_cache.mutex};          if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) { @@ -551,8 +550,8 @@ void RasterizerOpenGL::SyncState() {  }  void RasterizerOpenGL::SyncViewport() { -    auto& flags = maxwell3d.dirty.flags; -    const auto& regs = maxwell3d.regs; +    auto& flags = maxwell3d->dirty.flags; +    const auto& regs = maxwell3d->regs;      const bool rescale_viewports = flags[VideoCommon::Dirty::RescaleViewports];      const bool dirty_viewport = flags[Dirty::Viewports] || rescale_viewports; @@ -657,23 +656,23 @@ void RasterizerOpenGL::SyncViewport() {  }  void RasterizerOpenGL::SyncDepthClamp() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::DepthClampEnabled]) {          return;      }      flags[Dirty::DepthClampEnabled] = false; -    oglEnable(GL_DEPTH_CLAMP, maxwell3d.regs.view_volume_clip_control.depth_clamp_disabled == 0); +    oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.view_volume_clip_control.depth_clamp_disabled == 0);  }  void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::ClipDistances] && !flags[VideoCommon::Dirty::Shaders]) {          return;      }      flags[Dirty::ClipDistances] = false; -    clip_mask &= maxwell3d.regs.clip_distance_enabled; +    clip_mask &= maxwell3d->regs.clip_distance_enabled;      if (clip_mask == last_clip_distance_mask) {          return;      } @@ -689,8 +688,8 @@ void RasterizerOpenGL::SyncClipCoef() {  }  void RasterizerOpenGL::SyncCullMode() { -    auto& flags = maxwell3d.dirty.flags; -    const auto& regs = maxwell3d.regs; +    auto& flags = maxwell3d->dirty.flags; +    const auto& regs = maxwell3d->regs;      if (flags[Dirty::CullTest]) {          flags[Dirty::CullTest] = false; @@ -705,23 +704,23 @@ void RasterizerOpenGL::SyncCullMode() {  }  void RasterizerOpenGL::SyncPrimitiveRestart() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::PrimitiveRestart]) {          return;      }      flags[Dirty::PrimitiveRestart] = false; -    if (maxwell3d.regs.primitive_restart.enabled) { +    if (maxwell3d->regs.primitive_restart.enabled) {          glEnable(GL_PRIMITIVE_RESTART); -        glPrimitiveRestartIndex(maxwell3d.regs.primitive_restart.index); +        glPrimitiveRestartIndex(maxwell3d->regs.primitive_restart.index);      } else {          glDisable(GL_PRIMITIVE_RESTART);      }  }  void RasterizerOpenGL::SyncDepthTestState() { -    auto& flags = maxwell3d.dirty.flags; -    const auto& regs = maxwell3d.regs; +    auto& flags = maxwell3d->dirty.flags; +    const auto& regs = maxwell3d->regs;      if (flags[Dirty::DepthMask]) {          flags[Dirty::DepthMask] = false; @@ -740,13 +739,13 @@ void RasterizerOpenGL::SyncDepthTestState() {  }  void RasterizerOpenGL::SyncStencilTestState() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::StencilTest]) {          return;      }      flags[Dirty::StencilTest] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      oglEnable(GL_STENCIL_TEST, regs.stencil_enable);      glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), @@ -771,23 +770,23 @@ void RasterizerOpenGL::SyncStencilTestState() {  }  void RasterizerOpenGL::SyncRasterizeEnable() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::RasterizeEnable]) {          return;      }      flags[Dirty::RasterizeEnable] = false; -    oglEnable(GL_RASTERIZER_DISCARD, maxwell3d.regs.rasterize_enable == 0); +    oglEnable(GL_RASTERIZER_DISCARD, maxwell3d->regs.rasterize_enable == 0);  }  void RasterizerOpenGL::SyncPolygonModes() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::PolygonModes]) {          return;      }      flags[Dirty::PolygonModes] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      if (regs.fill_rectangle) {          if (!GLAD_GL_NV_fill_rectangle) {              LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); @@ -820,7 +819,7 @@ void RasterizerOpenGL::SyncPolygonModes() {  }  void RasterizerOpenGL::SyncColorMask() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::ColorMasks]) {          return;      } @@ -829,7 +828,7 @@ void RasterizerOpenGL::SyncColorMask() {      const bool force = flags[Dirty::ColorMaskCommon];      flags[Dirty::ColorMaskCommon] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      if (regs.color_mask_common) {          if (!force && !flags[Dirty::ColorMask0]) {              return; @@ -854,30 +853,30 @@ void RasterizerOpenGL::SyncColorMask() {  }  void RasterizerOpenGL::SyncMultiSampleState() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::MultisampleControl]) {          return;      }      flags[Dirty::MultisampleControl] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage);      oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one);  }  void RasterizerOpenGL::SyncFragmentColorClampState() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::FragmentClampColor]) {          return;      }      flags[Dirty::FragmentClampColor] = false; -    glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d.regs.frag_color_clamp ? GL_TRUE : GL_FALSE); +    glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d->regs.frag_color_clamp ? GL_TRUE : GL_FALSE);  }  void RasterizerOpenGL::SyncBlendState() { -    auto& flags = maxwell3d.dirty.flags; -    const auto& regs = maxwell3d.regs; +    auto& flags = maxwell3d->dirty.flags; +    const auto& regs = maxwell3d->regs;      if (flags[Dirty::BlendColor]) {          flags[Dirty::BlendColor] = false; @@ -934,13 +933,13 @@ void RasterizerOpenGL::SyncBlendState() {  }  void RasterizerOpenGL::SyncLogicOpState() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::LogicOp]) {          return;      }      flags[Dirty::LogicOp] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      if (regs.logic_op.enable) {          glEnable(GL_COLOR_LOGIC_OP);          glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); @@ -950,7 +949,7 @@ void RasterizerOpenGL::SyncLogicOpState() {  }  void RasterizerOpenGL::SyncScissorTest() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::Scissors] && !flags[VideoCommon::Dirty::RescaleScissors]) {          return;      } @@ -959,7 +958,7 @@ void RasterizerOpenGL::SyncScissorTest() {      const bool force = flags[VideoCommon::Dirty::RescaleScissors];      flags[VideoCommon::Dirty::RescaleScissors] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      const auto& resolution = Settings::values.resolution_info;      const bool is_rescaling{texture_cache.IsRescaling()}; @@ -995,39 +994,39 @@ void RasterizerOpenGL::SyncScissorTest() {  }  void RasterizerOpenGL::SyncPointState() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::PointSize]) {          return;      }      flags[Dirty::PointSize] = false; -    oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable); -    oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d.regs.vp_point_size.enable); +    oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable); +    oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.vp_point_size.enable);      const bool is_rescaling{texture_cache.IsRescaling()};      const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; -    glPointSize(std::max(1.0f, maxwell3d.regs.point_size * scale)); +    glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale));  }  void RasterizerOpenGL::SyncLineState() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::LineWidth]) {          return;      }      flags[Dirty::LineWidth] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable);      glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased);  }  void RasterizerOpenGL::SyncPolygonOffset() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::PolygonOffset]) {          return;      }      flags[Dirty::PolygonOffset] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable);      oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable);      oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); @@ -1041,13 +1040,13 @@ void RasterizerOpenGL::SyncPolygonOffset() {  }  void RasterizerOpenGL::SyncAlphaTest() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::AlphaTest]) {          return;      }      flags[Dirty::AlphaTest] = false; -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      if (regs.alpha_test_enabled) {          glEnable(GL_ALPHA_TEST);          glAlphaFunc(MaxwellToGL::ComparisonOp(regs.alpha_test_func), regs.alpha_test_ref); @@ -1057,17 +1056,17 @@ void RasterizerOpenGL::SyncAlphaTest() {  }  void RasterizerOpenGL::SyncFramebufferSRGB() { -    auto& flags = maxwell3d.dirty.flags; +    auto& flags = maxwell3d->dirty.flags;      if (!flags[Dirty::FramebufferSRGB]) {          return;      }      flags[Dirty::FramebufferSRGB] = false; -    oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d.regs.framebuffer_srgb); +    oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d->regs.framebuffer_srgb);  }  void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) { -    const auto& regs = maxwell3d.regs; +    const auto& regs = maxwell3d->regs;      if (regs.tfb_enabled == 0) {          return;      } @@ -1086,11 +1085,48 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum  }  void RasterizerOpenGL::EndTransformFeedback() { -    if (maxwell3d.regs.tfb_enabled != 0) { +    if (maxwell3d->regs.tfb_enabled != 0) {          glEndTransformFeedback();      }  } +void RasterizerOpenGL::InitializeChannel(Tegra::Control::ChannelState& channel) { +    CreateChannel(channel); +    { +        std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; +        texture_cache.CreateChannel(channel); +        buffer_cache.CreateChannel(channel); +    } +    shader_cache.CreateChannel(channel); +    query_cache.CreateChannel(channel); +    state_tracker.SetupTables(channel); +} + +void RasterizerOpenGL::BindChannel(Tegra::Control::ChannelState& channel) { +    const s32 channel_id = channel.bind_id; +    BindToChannel(channel_id); +    { +        std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; +        texture_cache.BindToChannel(channel_id); +        buffer_cache.BindToChannel(channel_id); +    } +    shader_cache.BindToChannel(channel_id); +    query_cache.BindToChannel(channel_id); +    state_tracker.ChangeChannel(channel); +    state_tracker.InvalidateState(); +} + +void RasterizerOpenGL::ReleaseChannel(s32 channel_id) { +    EraseChannel(channel_id); +    { +        std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; +        texture_cache.EraseChannel(channel_id); +        buffer_cache.EraseChannel(channel_id); +    } +    shader_cache.EraseChannel(channel_id); +    query_cache.EraseChannel(channel_id); +} +  AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}  bool 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 @@  #include <glad/glad.h>  #include "common/common_types.h" +#include "video_core/control/channel_state_cache.h"  #include "video_core/engines/maxwell_dma.h"  #include "video_core/rasterizer_accelerated.h"  #include "video_core/rasterizer_interface.h" @@ -58,7 +59,8 @@ private:      BufferCache& buffer_cache;  }; -class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { +class RasterizerOpenGL : public VideoCore::RasterizerAccelerated, +                         protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {  public:      explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,                                Core::Memory::Memory& cpu_memory_, const Device& device_, @@ -107,6 +109,12 @@ public:          return num_queued_commands > 0;      } +    void InitializeChannel(Tegra::Control::ChannelState& channel) override; + +    void BindChannel(Tegra::Control::ChannelState& channel) override; + +    void ReleaseChannel(s32 channel_id) override; +  private:      static constexpr size_t MAX_TEXTURES = 192;      static constexpr size_t MAX_IMAGES = 48; @@ -191,9 +199,6 @@ private:      void EndTransformFeedback();      Tegra::GPU& gpu; -    Tegra::Engines::Maxwell3D& maxwell3d; -    Tegra::Engines::KeplerCompute& kepler_compute; -    Tegra::MemoryManager& gpu_memory;      const Device& device;      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 @@  #include "common/common_types.h"  #include "core/core.h" +#include "video_core/control/channel_state.h"  #include "video_core/engines/maxwell_3d.h" -#include "video_core/gpu.h"  #include "video_core/renderer_opengl/gl_state_tracker.h"  #define OFF(field_name) MAXWELL3D_REG_INDEX(field_name) @@ -202,9 +202,8 @@ void SetupDirtyMisc(Tables& tables) {  } // Anonymous namespace -StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} { -    auto& dirty = gpu.Maxwell3D().dirty; -    auto& tables = dirty.tables; +void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) { +    auto& tables{channel_state.maxwell_3d->dirty.tables};      SetupDirtyFlags(tables);      SetupDirtyColorMasks(tables);      SetupDirtyViewports(tables); @@ -230,4 +229,14 @@ StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags}      SetupDirtyMisc(tables);  } +void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) { +    flags = &channel_state.maxwell_3d->dirty.flags; +} + +void StateTracker::InvalidateState() { +    flags->set(); +} + +StateTracker::StateTracker() : flags{} {} +  } // 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 @@  #include "video_core/engines/maxwell_3d.h"  namespace Tegra { -class GPU; +namespace Control { +struct ChannelState;  } +} // namespace Tegra  namespace OpenGL { @@ -83,7 +85,7 @@ static_assert(Last <= std::numeric_limits<u8>::max());  class StateTracker {  public: -    explicit StateTracker(Tegra::GPU& gpu); +    explicit StateTracker();      void BindIndexBuffer(GLuint new_index_buffer) {          if (index_buffer == new_index_buffer) { @@ -121,94 +123,106 @@ public:      }      void NotifyScreenDrawVertexArray() { -        flags[OpenGL::Dirty::VertexFormats] = true; -        flags[OpenGL::Dirty::VertexFormat0 + 0] = true; -        flags[OpenGL::Dirty::VertexFormat0 + 1] = true; +        (*flags)[OpenGL::Dirty::VertexFormats] = true; +        (*flags)[OpenGL::Dirty::VertexFormat0 + 0] = true; +        (*flags)[OpenGL::Dirty::VertexFormat0 + 1] = true; -        flags[VideoCommon::Dirty::VertexBuffers] = true; -        flags[VideoCommon::Dirty::VertexBuffer0] = true; +        (*flags)[VideoCommon::Dirty::VertexBuffers] = true; +        (*flags)[VideoCommon::Dirty::VertexBuffer0] = true; -        flags[OpenGL::Dirty::VertexInstances] = true; -        flags[OpenGL::Dirty::VertexInstance0 + 0] = true; -        flags[OpenGL::Dirty::VertexInstance0 + 1] = true; +        (*flags)[OpenGL::Dirty::VertexInstances] = true; +        (*flags)[OpenGL::Dirty::VertexInstance0 + 0] = true; +        (*flags)[OpenGL::Dirty::VertexInstance0 + 1] = true;      }      void NotifyPolygonModes() { -        flags[OpenGL::Dirty::PolygonModes] = true; -        flags[OpenGL::Dirty::PolygonModeFront] = true; -        flags[OpenGL::Dirty::PolygonModeBack] = true; +        (*flags)[OpenGL::Dirty::PolygonModes] = true; +        (*flags)[OpenGL::Dirty::PolygonModeFront] = true; +        (*flags)[OpenGL::Dirty::PolygonModeBack] = true;      }      void NotifyViewport0() { -        flags[OpenGL::Dirty::Viewports] = true; -        flags[OpenGL::Dirty::Viewport0] = true; +        (*flags)[OpenGL::Dirty::Viewports] = true; +        (*flags)[OpenGL::Dirty::Viewport0] = true;      }      void NotifyScissor0() { -        flags[OpenGL::Dirty::Scissors] = true; -        flags[OpenGL::Dirty::Scissor0] = true; +        (*flags)[OpenGL::Dirty::Scissors] = true; +        (*flags)[OpenGL::Dirty::Scissor0] = true;      }      void NotifyColorMask(size_t index) { -        flags[OpenGL::Dirty::ColorMasks] = true; -        flags[OpenGL::Dirty::ColorMask0 + index] = true; +        (*flags)[OpenGL::Dirty::ColorMasks] = true; +        (*flags)[OpenGL::Dirty::ColorMask0 + index] = true;      }      void NotifyBlend0() { -        flags[OpenGL::Dirty::BlendStates] = true; -        flags[OpenGL::Dirty::BlendState0] = true; +        (*flags)[OpenGL::Dirty::BlendStates] = true; +        (*flags)[OpenGL::Dirty::BlendState0] = true;      }      void NotifyFramebuffer() { -        flags[VideoCommon::Dirty::RenderTargets] = true; +        (*flags)[VideoCommon::Dirty::RenderTargets] = true;      }      void NotifyFrontFace() { -        flags[OpenGL::Dirty::FrontFace] = true; +        (*flags)[OpenGL::Dirty::FrontFace] = true;      }      void NotifyCullTest() { -        flags[OpenGL::Dirty::CullTest] = true; +        (*flags)[OpenGL::Dirty::CullTest] = true;      }      void NotifyDepthMask() { -        flags[OpenGL::Dirty::DepthMask] = true; +        (*flags)[OpenGL::Dirty::DepthMask] = true;      }      void NotifyDepthTest() { -        flags[OpenGL::Dirty::DepthTest] = true; +        (*flags)[OpenGL::Dirty::DepthTest] = true;      }      void NotifyStencilTest() { -        flags[OpenGL::Dirty::StencilTest] = true; +        (*flags)[OpenGL::Dirty::StencilTest] = true;      }      void NotifyPolygonOffset() { -        flags[OpenGL::Dirty::PolygonOffset] = true; +        (*flags)[OpenGL::Dirty::PolygonOffset] = true;      }      void NotifyRasterizeEnable() { -        flags[OpenGL::Dirty::RasterizeEnable] = true; +        (*flags)[OpenGL::Dirty::RasterizeEnable] = true;      }      void NotifyFramebufferSRGB() { -        flags[OpenGL::Dirty::FramebufferSRGB] = true; +        (*flags)[OpenGL::Dirty::FramebufferSRGB] = true;      }      void NotifyLogicOp() { -        flags[OpenGL::Dirty::LogicOp] = true; +        (*flags)[OpenGL::Dirty::LogicOp] = true;      }      void NotifyClipControl() { -        flags[OpenGL::Dirty::ClipControl] = true; +        (*flags)[OpenGL::Dirty::ClipControl] = true;      }      void NotifyAlphaTest() { -        flags[OpenGL::Dirty::AlphaTest] = true; +        (*flags)[OpenGL::Dirty::AlphaTest] = true;      } +    void NotifyRange(u8 start, u8 end) { +        for (auto flag = start; flag <= end; flag++) { +            (*flags)[flag] = true; +        } +    } + +    void SetupTables(Tegra::Control::ChannelState& channel_state); + +    void ChangeChannel(Tegra::Control::ChannelState& channel_state); + +    void InvalidateState(); +  private: -    Tegra::Engines::Maxwell3D::DirtyState::Flags& flags; +    Tegra::Engines::Maxwell3D::DirtyState::Flags* flags;      GLuint framebuffer = 0;      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_,                                 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,                                 std::unique_ptr<Core::Frontend::GraphicsContext> context_)      : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_}, -      emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{gpu}, +      emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{},        program_manager{device},        rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) {      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_,        surface(CreateSurface(instance, render_window)),        device(CreateDevice(instance, dld, *surface)),        memory_allocator(device, false), -      state_tracker(gpu), +      state_tracker(),        scheduler(device, state_tracker),        swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,                  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) {      pipeline_cache.BindToChannel(channel_id);      query_cache.BindToChannel(channel_id);      state_tracker.ChangeChannel(channel); -    scheduler.InvalidateState(); +    state_tracker.InvalidateState();  }  void 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 @@  #include "video_core/control/channel_state.h"  #include "video_core/dirty_flags.h"  #include "video_core/engines/maxwell_3d.h" -#include "video_core/gpu.h"  #include "video_core/renderer_vulkan/vk_state_tracker.h"  #define OFF(field_name) MAXWELL3D_REG_INDEX(field_name) @@ -203,7 +202,10 @@ void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) {      flags = &channel_state.maxwell_3d->dirty.flags;  } -StateTracker::StateTracker(Tegra::GPU& gpu) -    : flags{}, invalidation_flags{MakeInvalidationFlags()} {} +void StateTracker::InvalidateState() { +    flags->set(); +} + +StateTracker::StateTracker() : flags{}, invalidation_flags{MakeInvalidationFlags()} {}  } // 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 {      using Maxwell = Tegra::Engines::Maxwell3D::Regs;  public: -    explicit StateTracker(Tegra::GPU& gpu); +    explicit StateTracker();      void InvalidateCommandBufferState() {          (*flags) |= invalidation_flags; @@ -149,6 +149,8 @@ public:      void ChangeChannel(Tegra::Control::ChannelState& channel_state); +    void InvalidateState(); +  private:      static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u);  | 
