diff options
Diffstat (limited to '')
| -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 @@ | |||
| 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 | |||
| 70 | RasterizerOpenGL::~RasterizerOpenGL() = default; | 69 | RasterizerOpenGL::~RasterizerOpenGL() = default; |
| 71 | 70 | ||
| 72 | void RasterizerOpenGL::SyncVertexFormats() { | 71 | void 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 | ||
| 114 | void RasterizerOpenGL::SyncVertexInstances() { | 113 | void 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 | ||
| 140 | void RasterizerOpenGL::Clear() { | 139 | void 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 | ||
| 389 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { | 388 | void 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 | ||
| 484 | void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, | 483 | void 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 | ||
| 553 | void RasterizerOpenGL::SyncViewport() { | 552 | void 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 | ||
| 659 | void RasterizerOpenGL::SyncDepthClamp() { | 658 | void 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 | ||
| 669 | void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { | 668 | void 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 | ||
| 691 | void RasterizerOpenGL::SyncCullMode() { | 690 | void 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 | ||
| 707 | void RasterizerOpenGL::SyncPrimitiveRestart() { | 706 | void 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 | ||
| 722 | void RasterizerOpenGL::SyncDepthTestState() { | 721 | void 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 | ||
| 742 | void RasterizerOpenGL::SyncStencilTestState() { | 741 | void 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 | ||
| 773 | void RasterizerOpenGL::SyncRasterizeEnable() { | 772 | void 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 | ||
| 783 | void RasterizerOpenGL::SyncPolygonModes() { | 782 | void 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 | ||
| 822 | void RasterizerOpenGL::SyncColorMask() { | 821 | void 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 | ||
| 856 | void RasterizerOpenGL::SyncMultiSampleState() { | 855 | void 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 | ||
| 868 | void RasterizerOpenGL::SyncFragmentColorClampState() { | 867 | void 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 | ||
| 878 | void RasterizerOpenGL::SyncBlendState() { | 877 | void 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 | ||
| 936 | void RasterizerOpenGL::SyncLogicOpState() { | 935 | void 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 | ||
| 952 | void RasterizerOpenGL::SyncScissorTest() { | 951 | void 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 | ||
| 997 | void RasterizerOpenGL::SyncPointState() { | 996 | void 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 | ||
| 1011 | void RasterizerOpenGL::SyncLineState() { | 1010 | void 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 | ||
| 1023 | void RasterizerOpenGL::SyncPolygonOffset() { | 1022 | void 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 | ||
| 1043 | void RasterizerOpenGL::SyncAlphaTest() { | 1042 | void 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 | ||
| 1059 | void RasterizerOpenGL::SyncFramebufferSRGB() { | 1058 | void 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 | ||
| 1069 | void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) { | 1068 | void 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 | ||
| 1088 | void RasterizerOpenGL::EndTransformFeedback() { | 1087 | void 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 | ||
| 1093 | void 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 | |||
| 1105 | void 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 | |||
| 1119 | void 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 | |||
| 1094 | AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {} | 1130 | AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {} |
| 1095 | 1131 | ||
| 1096 | bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) { | 1132 | 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 @@ | |||
| 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 | ||
| 61 | class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { | 62 | class RasterizerOpenGL : public VideoCore::RasterizerAccelerated, |
| 63 | protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> { | ||
| 62 | public: | 64 | public: |
| 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 | |||
| 110 | private: | 118 | private: |
| 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 | ||
| 205 | StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} { | 205 | void 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 | ||
| 232 | void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) { | ||
| 233 | flags = &channel_state.maxwell_3d->dirty.flags; | ||
| 234 | } | ||
| 235 | |||
| 236 | void StateTracker::InvalidateState() { | ||
| 237 | flags->set(); | ||
| 238 | } | ||
| 239 | |||
| 240 | StateTracker::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 | ||
| 14 | namespace Tegra { | 14 | namespace Tegra { |
| 15 | class GPU; | 15 | namespace Control { |
| 16 | struct ChannelState; | ||
| 16 | } | 17 | } |
| 18 | } // namespace Tegra | ||
| 17 | 19 | ||
| 18 | namespace OpenGL { | 20 | namespace OpenGL { |
| 19 | 21 | ||
| @@ -83,7 +85,7 @@ static_assert(Last <= std::numeric_limits<u8>::max()); | |||
| 83 | 85 | ||
| 84 | class StateTracker { | 86 | class StateTracker { |
| 85 | public: | 87 | public: |
| 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 | |||
| 210 | private: | 224 | private: |
| 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 | ||
| 1001 | void RasterizerVulkan::ReleaseChannel(s32 channel_id) { | 1001 | 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 @@ | |||
| 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 | ||
| 206 | StateTracker::StateTracker(Tegra::GPU& gpu) | 205 | void StateTracker::InvalidateState() { |
| 207 | : flags{}, invalidation_flags{MakeInvalidationFlags()} {} | 206 | flags->set(); |
| 207 | } | ||
| 208 | |||
| 209 | StateTracker::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 | ||
| 61 | public: | 61 | public: |
| 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 | |||
| 152 | private: | 154 | private: |
| 153 | static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u); | 155 | static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u); |
| 154 | 156 | ||