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