diff options
22 files changed, 172 insertions, 119 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index ff10ff40d..6e50661a3 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -10,7 +10,13 @@ | |||
| 10 | 10 | ||
| 11 | namespace Tegra::Engines { | 11 | namespace Tegra::Engines { |
| 12 | 12 | ||
| 13 | Fermi2D::Fermi2D(VideoCore::RasterizerInterface& rasterizer) : rasterizer{rasterizer} {} | 13 | Fermi2D::Fermi2D() = default; |
| 14 | |||
| 15 | Fermi2D::~Fermi2D() = default; | ||
| 16 | |||
| 17 | void Fermi2D::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||
| 18 | rasterizer = &rasterizer_; | ||
| 19 | } | ||
| 14 | 20 | ||
| 15 | void Fermi2D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 21 | void Fermi2D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { |
| 16 | ASSERT_MSG(method < Regs::NUM_REGS, | 22 | ASSERT_MSG(method < Regs::NUM_REGS, |
| @@ -87,7 +93,7 @@ void Fermi2D::HandleSurfaceCopy() { | |||
| 87 | copy_config.src_rect = src_rect; | 93 | copy_config.src_rect = src_rect; |
| 88 | copy_config.dst_rect = dst_rect; | 94 | copy_config.dst_rect = dst_rect; |
| 89 | 95 | ||
| 90 | if (!rasterizer.AccelerateSurfaceCopy(regs.src, regs.dst, copy_config)) { | 96 | if (!rasterizer->AccelerateSurfaceCopy(regs.src, regs.dst, copy_config)) { |
| 91 | UNIMPLEMENTED(); | 97 | UNIMPLEMENTED(); |
| 92 | } | 98 | } |
| 93 | } | 99 | } |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 8f37d053f..213abfaae 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -34,8 +34,11 @@ namespace Tegra::Engines { | |||
| 34 | 34 | ||
| 35 | class Fermi2D final : public EngineInterface { | 35 | class Fermi2D final : public EngineInterface { |
| 36 | public: | 36 | public: |
| 37 | explicit Fermi2D(VideoCore::RasterizerInterface& rasterizer); | 37 | explicit Fermi2D(); |
| 38 | ~Fermi2D() = default; | 38 | ~Fermi2D(); |
| 39 | |||
| 40 | /// Binds a rasterizer to this engine. | ||
| 41 | void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||
| 39 | 42 | ||
| 40 | /// Write the value to the register identified by method. | 43 | /// Write the value to the register identified by method. |
| 41 | void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; | 44 | void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; |
| @@ -149,7 +152,7 @@ public: | |||
| 149 | }; | 152 | }; |
| 150 | 153 | ||
| 151 | private: | 154 | private: |
| 152 | VideoCore::RasterizerInterface& rasterizer; | 155 | VideoCore::RasterizerInterface* rasterizer; |
| 153 | 156 | ||
| 154 | /// Performs the copy from the source surface to the destination surface as configured in the | 157 | /// Performs the copy from the source surface to the destination surface as configured in the |
| 155 | /// registers. | 158 | /// registers. |
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index a82b06a38..898370739 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp | |||
| @@ -16,14 +16,15 @@ | |||
| 16 | 16 | ||
| 17 | namespace Tegra::Engines { | 17 | namespace Tegra::Engines { |
| 18 | 18 | ||
| 19 | KeplerCompute::KeplerCompute(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 19 | KeplerCompute::KeplerCompute(Core::System& system_, MemoryManager& memory_manager_) |
| 20 | MemoryManager& memory_manager) | 20 | : system{system_}, memory_manager{memory_manager_}, upload_state{memory_manager, regs.upload} {} |
| 21 | : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, upload_state{ | ||
| 22 | memory_manager, | ||
| 23 | regs.upload} {} | ||
| 24 | 21 | ||
| 25 | KeplerCompute::~KeplerCompute() = default; | 22 | KeplerCompute::~KeplerCompute() = default; |
| 26 | 23 | ||
| 24 | void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||
| 25 | rasterizer = &rasterizer_; | ||
| 26 | } | ||
| 27 | |||
| 27 | void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 28 | void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { |
| 28 | ASSERT_MSG(method < Regs::NUM_REGS, | 29 | ASSERT_MSG(method < Regs::NUM_REGS, |
| 29 | "Invalid KeplerCompute register, increase the size of the Regs structure"); | 30 | "Invalid KeplerCompute register, increase the size of the Regs structure"); |
| @@ -104,11 +105,11 @@ SamplerDescriptor KeplerCompute::AccessSampler(u32 handle) const { | |||
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() { | 107 | VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() { |
| 107 | return rasterizer.AccessGuestDriverProfile(); | 108 | return rasterizer->AccessGuestDriverProfile(); |
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | const VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() const { | 111 | const VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() const { |
| 111 | return rasterizer.AccessGuestDriverProfile(); | 112 | return rasterizer->AccessGuestDriverProfile(); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | void KeplerCompute::ProcessLaunch() { | 115 | void KeplerCompute::ProcessLaunch() { |
| @@ -119,7 +120,7 @@ void KeplerCompute::ProcessLaunch() { | |||
| 119 | const GPUVAddr code_addr = regs.code_loc.Address() + launch_description.program_start; | 120 | const GPUVAddr code_addr = regs.code_loc.Address() + launch_description.program_start; |
| 120 | LOG_TRACE(HW_GPU, "Compute invocation launched at address 0x{:016x}", code_addr); | 121 | LOG_TRACE(HW_GPU, "Compute invocation launched at address 0x{:016x}", code_addr); |
| 121 | 122 | ||
| 122 | rasterizer.DispatchCompute(code_addr); | 123 | rasterizer->DispatchCompute(code_addr); |
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | Texture::TICEntry KeplerCompute::GetTICEntry(u32 tic_index) const { | 126 | Texture::TICEntry KeplerCompute::GetTICEntry(u32 tic_index) const { |
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index b7f668d88..7f2500aab 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h | |||
| @@ -42,10 +42,12 @@ namespace Tegra::Engines { | |||
| 42 | 42 | ||
| 43 | class KeplerCompute final : public ConstBufferEngineInterface, public EngineInterface { | 43 | class KeplerCompute final : public ConstBufferEngineInterface, public EngineInterface { |
| 44 | public: | 44 | public: |
| 45 | explicit KeplerCompute(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 45 | explicit KeplerCompute(Core::System& system, MemoryManager& memory_manager); |
| 46 | MemoryManager& memory_manager); | ||
| 47 | ~KeplerCompute(); | 46 | ~KeplerCompute(); |
| 48 | 47 | ||
| 48 | /// Binds a rasterizer to this engine. | ||
| 49 | void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||
| 50 | |||
| 49 | static constexpr std::size_t NumConstBuffers = 8; | 51 | static constexpr std::size_t NumConstBuffers = 8; |
| 50 | 52 | ||
| 51 | struct Regs { | 53 | struct Regs { |
| @@ -230,11 +232,6 @@ public: | |||
| 230 | const VideoCore::GuestDriverProfile& AccessGuestDriverProfile() const override; | 232 | const VideoCore::GuestDriverProfile& AccessGuestDriverProfile() const override; |
| 231 | 233 | ||
| 232 | private: | 234 | private: |
| 233 | Core::System& system; | ||
| 234 | VideoCore::RasterizerInterface& rasterizer; | ||
| 235 | MemoryManager& memory_manager; | ||
| 236 | Upload::State upload_state; | ||
| 237 | |||
| 238 | void ProcessLaunch(); | 235 | void ProcessLaunch(); |
| 239 | 236 | ||
| 240 | /// Retrieves information about a specific TIC entry from the TIC buffer. | 237 | /// Retrieves information about a specific TIC entry from the TIC buffer. |
| @@ -242,6 +239,11 @@ private: | |||
| 242 | 239 | ||
| 243 | /// Retrieves information about a specific TSC entry from the TSC buffer. | 240 | /// Retrieves information about a specific TSC entry from the TSC buffer. |
| 244 | Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; | 241 | Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; |
| 242 | |||
| 243 | Core::System& system; | ||
| 244 | MemoryManager& memory_manager; | ||
| 245 | VideoCore::RasterizerInterface* rasterizer = nullptr; | ||
| 246 | Upload::State upload_state; | ||
| 245 | }; | 247 | }; |
| 246 | 248 | ||
| 247 | #define ASSERT_REG_POSITION(field_name, position) \ | 249 | #define ASSERT_REG_POSITION(field_name, position) \ |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index c01436295..33854445f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -22,14 +22,19 @@ using VideoCore::QueryType; | |||
| 22 | /// First register id that is actually a Macro call. | 22 | /// First register id that is actually a Macro call. |
| 23 | constexpr u32 MacroRegistersStart = 0xE00; | 23 | constexpr u32 MacroRegistersStart = 0xE00; |
| 24 | 24 | ||
| 25 | Maxwell3D::Maxwell3D(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 25 | Maxwell3D::Maxwell3D(Core::System& system_, MemoryManager& memory_manager_) |
| 26 | MemoryManager& memory_manager) | 26 | : system{system_}, memory_manager{memory_manager_}, macro_engine{GetMacroEngine(*this)}, |
| 27 | : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, | 27 | upload_state{memory_manager, regs.upload} { |
| 28 | macro_engine{GetMacroEngine(*this)}, upload_state{memory_manager, regs.upload} { | ||
| 29 | dirty.flags.flip(); | 28 | dirty.flags.flip(); |
| 30 | InitializeRegisterDefaults(); | 29 | InitializeRegisterDefaults(); |
| 31 | } | 30 | } |
| 32 | 31 | ||
| 32 | Maxwell3D::~Maxwell3D() = default; | ||
| 33 | |||
| 34 | void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||
| 35 | rasterizer = &rasterizer_; | ||
| 36 | } | ||
| 37 | |||
| 33 | void Maxwell3D::InitializeRegisterDefaults() { | 38 | void Maxwell3D::InitializeRegisterDefaults() { |
| 34 | // Initializes registers to their default values - what games expect them to be at boot. This is | 39 | // Initializes registers to their default values - what games expect them to be at boot. This is |
| 35 | // for certain registers that may not be explicitly set by games. | 40 | // for certain registers that may not be explicitly set by games. |
| @@ -192,7 +197,7 @@ void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | |||
| 192 | 197 | ||
| 193 | switch (method) { | 198 | switch (method) { |
| 194 | case MAXWELL3D_REG_INDEX(wait_for_idle): { | 199 | case MAXWELL3D_REG_INDEX(wait_for_idle): { |
| 195 | rasterizer.WaitForIdle(); | 200 | rasterizer->WaitForIdle(); |
| 196 | break; | 201 | break; |
| 197 | } | 202 | } |
| 198 | case MAXWELL3D_REG_INDEX(shadow_ram_control): { | 203 | case MAXWELL3D_REG_INDEX(shadow_ram_control): { |
| @@ -402,7 +407,7 @@ void Maxwell3D::FlushMMEInlineDraw() { | |||
| 402 | 407 | ||
| 403 | const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed; | 408 | const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed; |
| 404 | if (ShouldExecute()) { | 409 | if (ShouldExecute()) { |
| 405 | rasterizer.Draw(is_indexed, true); | 410 | rasterizer->Draw(is_indexed, true); |
| 406 | } | 411 | } |
| 407 | 412 | ||
| 408 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if | 413 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if |
| @@ -465,7 +470,7 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 465 | switch (regs.query.query_get.operation) { | 470 | switch (regs.query.query_get.operation) { |
| 466 | case Regs::QueryOperation::Release: | 471 | case Regs::QueryOperation::Release: |
| 467 | if (regs.query.query_get.fence == 1) { | 472 | if (regs.query.query_get.fence == 1) { |
| 468 | rasterizer.SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence); | 473 | rasterizer->SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence); |
| 469 | } else { | 474 | } else { |
| 470 | StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); | 475 | StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); |
| 471 | } | 476 | } |
| @@ -533,7 +538,7 @@ void Maxwell3D::ProcessQueryCondition() { | |||
| 533 | void Maxwell3D::ProcessCounterReset() { | 538 | void Maxwell3D::ProcessCounterReset() { |
| 534 | switch (regs.counter_reset) { | 539 | switch (regs.counter_reset) { |
| 535 | case Regs::CounterReset::SampleCnt: | 540 | case Regs::CounterReset::SampleCnt: |
| 536 | rasterizer.ResetCounter(QueryType::SamplesPassed); | 541 | rasterizer->ResetCounter(QueryType::SamplesPassed); |
| 537 | break; | 542 | break; |
| 538 | default: | 543 | default: |
| 539 | LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", | 544 | LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", |
| @@ -547,7 +552,7 @@ void Maxwell3D::ProcessSyncPoint() { | |||
| 547 | const u32 increment = regs.sync_info.increment.Value(); | 552 | const u32 increment = regs.sync_info.increment.Value(); |
| 548 | [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); | 553 | [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); |
| 549 | if (increment) { | 554 | if (increment) { |
| 550 | rasterizer.SignalSyncPoint(sync_point); | 555 | rasterizer->SignalSyncPoint(sync_point); |
| 551 | } | 556 | } |
| 552 | } | 557 | } |
| 553 | 558 | ||
| @@ -570,7 +575,7 @@ void Maxwell3D::DrawArrays() { | |||
| 570 | 575 | ||
| 571 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; | 576 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; |
| 572 | if (ShouldExecute()) { | 577 | if (ShouldExecute()) { |
| 573 | rasterizer.Draw(is_indexed, false); | 578 | rasterizer->Draw(is_indexed, false); |
| 574 | } | 579 | } |
| 575 | 580 | ||
| 576 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if | 581 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if |
| @@ -590,8 +595,8 @@ std::optional<u64> Maxwell3D::GetQueryResult() { | |||
| 590 | return 0; | 595 | return 0; |
| 591 | case Regs::QuerySelect::SamplesPassed: | 596 | case Regs::QuerySelect::SamplesPassed: |
| 592 | // Deferred. | 597 | // Deferred. |
| 593 | rasterizer.Query(regs.query.QueryAddress(), VideoCore::QueryType::SamplesPassed, | 598 | rasterizer->Query(regs.query.QueryAddress(), VideoCore::QueryType::SamplesPassed, |
| 594 | system.GPU().GetTicks()); | 599 | system.GPU().GetTicks()); |
| 595 | return {}; | 600 | return {}; |
| 596 | default: | 601 | default: |
| 597 | LOG_DEBUG(HW_GPU, "Unimplemented query select type {}", | 602 | LOG_DEBUG(HW_GPU, "Unimplemented query select type {}", |
| @@ -718,7 +723,7 @@ void Maxwell3D::ProcessClearBuffers() { | |||
| 718 | regs.clear_buffers.R == regs.clear_buffers.B && | 723 | regs.clear_buffers.R == regs.clear_buffers.B && |
| 719 | regs.clear_buffers.R == regs.clear_buffers.A); | 724 | regs.clear_buffers.R == regs.clear_buffers.A); |
| 720 | 725 | ||
| 721 | rasterizer.Clear(); | 726 | rasterizer->Clear(); |
| 722 | } | 727 | } |
| 723 | 728 | ||
| 724 | u32 Maxwell3D::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const { | 729 | u32 Maxwell3D::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const { |
| @@ -752,11 +757,11 @@ SamplerDescriptor Maxwell3D::AccessSampler(u32 handle) const { | |||
| 752 | } | 757 | } |
| 753 | 758 | ||
| 754 | VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() { | 759 | VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() { |
| 755 | return rasterizer.AccessGuestDriverProfile(); | 760 | return rasterizer->AccessGuestDriverProfile(); |
| 756 | } | 761 | } |
| 757 | 762 | ||
| 758 | const VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() const { | 763 | const VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() const { |
| 759 | return rasterizer.AccessGuestDriverProfile(); | 764 | return rasterizer->AccessGuestDriverProfile(); |
| 760 | } | 765 | } |
| 761 | 766 | ||
| 762 | } // namespace Tegra::Engines | 767 | } // namespace Tegra::Engines |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index c97eeb792..bc289c55d 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -51,9 +51,11 @@ namespace Tegra::Engines { | |||
| 51 | 51 | ||
| 52 | class Maxwell3D final : public ConstBufferEngineInterface, public EngineInterface { | 52 | class Maxwell3D final : public ConstBufferEngineInterface, public EngineInterface { |
| 53 | public: | 53 | public: |
| 54 | explicit Maxwell3D(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 54 | explicit Maxwell3D(Core::System& system, MemoryManager& memory_manager); |
| 55 | MemoryManager& memory_manager); | 55 | ~Maxwell3D(); |
| 56 | ~Maxwell3D() = default; | 56 | |
| 57 | /// Binds a rasterizer to this engine. | ||
| 58 | void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||
| 57 | 59 | ||
| 58 | /// Register structure of the Maxwell3D engine. | 60 | /// Register structure of the Maxwell3D engine. |
| 59 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | 61 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. |
| @@ -1418,12 +1420,12 @@ public: | |||
| 1418 | return execute_on; | 1420 | return execute_on; |
| 1419 | } | 1421 | } |
| 1420 | 1422 | ||
| 1421 | VideoCore::RasterizerInterface& GetRasterizer() { | 1423 | VideoCore::RasterizerInterface& Rasterizer() { |
| 1422 | return rasterizer; | 1424 | return *rasterizer; |
| 1423 | } | 1425 | } |
| 1424 | 1426 | ||
| 1425 | const VideoCore::RasterizerInterface& GetRasterizer() const { | 1427 | const VideoCore::RasterizerInterface& Rasterizer() const { |
| 1426 | return rasterizer; | 1428 | return *rasterizer; |
| 1427 | } | 1429 | } |
| 1428 | 1430 | ||
| 1429 | /// Notify a memory write has happened. | 1431 | /// Notify a memory write has happened. |
| @@ -1460,11 +1462,10 @@ private: | |||
| 1460 | void InitializeRegisterDefaults(); | 1462 | void InitializeRegisterDefaults(); |
| 1461 | 1463 | ||
| 1462 | Core::System& system; | 1464 | Core::System& system; |
| 1463 | |||
| 1464 | VideoCore::RasterizerInterface& rasterizer; | ||
| 1465 | |||
| 1466 | MemoryManager& memory_manager; | 1465 | MemoryManager& memory_manager; |
| 1467 | 1466 | ||
| 1467 | VideoCore::RasterizerInterface* rasterizer = nullptr; | ||
| 1468 | |||
| 1468 | /// Start offsets of each macro in macro_memory | 1469 | /// Start offsets of each macro in macro_memory |
| 1469 | std::array<u32, 0x80> macro_positions = {}; | 1470 | std::array<u32, 0x80> macro_positions = {}; |
| 1470 | 1471 | ||
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 512578c8b..acb6e6d46 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -27,21 +27,28 @@ namespace Tegra { | |||
| 27 | 27 | ||
| 28 | MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); | 28 | MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); |
| 29 | 29 | ||
| 30 | GPU::GPU(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer_, bool is_async) | 30 | GPU::GPU(Core::System& system_, bool is_async_) |
| 31 | : system{system}, renderer{std::move(renderer_)}, is_async{is_async} { | 31 | : system{system_}, dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, |
| 32 | auto& rasterizer{renderer->Rasterizer()}; | 32 | memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, |
| 33 | memory_manager = std::make_unique<Tegra::MemoryManager>(system, rasterizer); | 33 | maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, |
| 34 | dma_pusher = std::make_unique<Tegra::DmaPusher>(system, *this); | 34 | fermi_2d{std::make_unique<Engines::Fermi2D>()}, |
| 35 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); | 35 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, |
| 36 | fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer); | 36 | maxwell_dma{std::make_unique<Engines::MaxwellDMA>(system, *memory_manager)}, |
| 37 | kepler_compute = std::make_unique<Engines::KeplerCompute>(system, rasterizer, *memory_manager); | 37 | kepler_memory{std::make_unique<Engines::KeplerMemory>(system, *memory_manager)}, |
| 38 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, *memory_manager); | 38 | shader_notify{std::make_unique<VideoCore::ShaderNotify>()}, is_async{is_async_} {} |
| 39 | kepler_memory = std::make_unique<Engines::KeplerMemory>(system, *memory_manager); | ||
| 40 | shader_notify = std::make_unique<VideoCore::ShaderNotify>(); | ||
| 41 | } | ||
| 42 | 39 | ||
| 43 | GPU::~GPU() = default; | 40 | GPU::~GPU() = default; |
| 44 | 41 | ||
| 42 | void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) { | ||
| 43 | renderer = std::move(renderer_); | ||
| 44 | |||
| 45 | VideoCore::RasterizerInterface& rasterizer = renderer->Rasterizer(); | ||
| 46 | memory_manager->BindRasterizer(rasterizer); | ||
| 47 | maxwell_3d->BindRasterizer(rasterizer); | ||
| 48 | fermi_2d->BindRasterizer(rasterizer); | ||
| 49 | kepler_compute->BindRasterizer(rasterizer); | ||
| 50 | } | ||
| 51 | |||
| 45 | Engines::Maxwell3D& GPU::Maxwell3D() { | 52 | Engines::Maxwell3D& GPU::Maxwell3D() { |
| 46 | return *maxwell_3d; | 53 | return *maxwell_3d; |
| 47 | } | 54 | } |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index ebfc7b0c7..c7d11deb2 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -142,11 +142,6 @@ class MemoryManager; | |||
| 142 | 142 | ||
| 143 | class GPU { | 143 | class GPU { |
| 144 | public: | 144 | public: |
| 145 | explicit GPU(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, | ||
| 146 | bool is_async); | ||
| 147 | |||
| 148 | virtual ~GPU(); | ||
| 149 | |||
| 150 | struct MethodCall { | 145 | struct MethodCall { |
| 151 | u32 method{}; | 146 | u32 method{}; |
| 152 | u32 argument{}; | 147 | u32 argument{}; |
| @@ -162,6 +157,12 @@ public: | |||
| 162 | method_count(method_count) {} | 157 | method_count(method_count) {} |
| 163 | }; | 158 | }; |
| 164 | 159 | ||
| 160 | explicit GPU(Core::System& system, bool is_async); | ||
| 161 | virtual ~GPU(); | ||
| 162 | |||
| 163 | /// Binds a renderer to the GPU. | ||
| 164 | void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer); | ||
| 165 | |||
| 165 | /// Calls a GPU method. | 166 | /// Calls a GPU method. |
| 166 | void CallMethod(const MethodCall& method_call); | 167 | void CallMethod(const MethodCall& method_call); |
| 167 | 168 | ||
| @@ -345,8 +346,8 @@ private: | |||
| 345 | bool ExecuteMethodOnEngine(u32 method); | 346 | bool ExecuteMethodOnEngine(u32 method); |
| 346 | 347 | ||
| 347 | protected: | 348 | protected: |
| 348 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; | ||
| 349 | Core::System& system; | 349 | Core::System& system; |
| 350 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; | ||
| 350 | std::unique_ptr<VideoCore::RendererBase> renderer; | 351 | std::unique_ptr<VideoCore::RendererBase> renderer; |
| 351 | 352 | ||
| 352 | private: | 353 | private: |
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp index 7b855f63e..70a3d5738 100644 --- a/src/video_core/gpu_asynch.cpp +++ b/src/video_core/gpu_asynch.cpp | |||
| @@ -10,16 +10,14 @@ | |||
| 10 | 10 | ||
| 11 | namespace VideoCommon { | 11 | namespace VideoCommon { |
| 12 | 12 | ||
| 13 | GPUAsynch::GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer_, | 13 | GPUAsynch::GPUAsynch(Core::System& system) : GPU{system, true}, gpu_thread{system} {} |
| 14 | std::unique_ptr<Core::Frontend::GraphicsContext>&& context) | ||
| 15 | : GPU(system, std::move(renderer_), true), gpu_thread{system}, | ||
| 16 | cpu_context(renderer->GetRenderWindow().CreateSharedContext()), | ||
| 17 | gpu_context(std::move(context)) {} | ||
| 18 | 14 | ||
| 19 | GPUAsynch::~GPUAsynch() = default; | 15 | GPUAsynch::~GPUAsynch() = default; |
| 20 | 16 | ||
| 21 | void GPUAsynch::Start() { | 17 | void GPUAsynch::Start() { |
| 22 | gpu_thread.StartThread(*renderer, *gpu_context, *dma_pusher); | 18 | gpu_thread.StartThread(*renderer, renderer->Context(), *dma_pusher); |
| 19 | cpu_context = renderer->GetRenderWindow().CreateSharedContext(); | ||
| 20 | cpu_context->MakeCurrent(); | ||
| 23 | } | 21 | } |
| 24 | 22 | ||
| 25 | void GPUAsynch::ObtainContext() { | 23 | void GPUAsynch::ObtainContext() { |
diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h index 15e9f1d38..f89c855a5 100644 --- a/src/video_core/gpu_asynch.h +++ b/src/video_core/gpu_asynch.h | |||
| @@ -20,8 +20,7 @@ namespace VideoCommon { | |||
| 20 | /// Implementation of GPU interface that runs the GPU asynchronously | 20 | /// Implementation of GPU interface that runs the GPU asynchronously |
| 21 | class GPUAsynch final : public Tegra::GPU { | 21 | class GPUAsynch final : public Tegra::GPU { |
| 22 | public: | 22 | public: |
| 23 | explicit GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, | 23 | explicit GPUAsynch(Core::System& system); |
| 24 | std::unique_ptr<Core::Frontend::GraphicsContext>&& context); | ||
| 25 | ~GPUAsynch() override; | 24 | ~GPUAsynch() override; |
| 26 | 25 | ||
| 27 | void Start() override; | 26 | void Start() override; |
| @@ -42,7 +41,6 @@ protected: | |||
| 42 | private: | 41 | private: |
| 43 | GPUThread::ThreadManager gpu_thread; | 42 | GPUThread::ThreadManager gpu_thread; |
| 44 | std::unique_ptr<Core::Frontend::GraphicsContext> cpu_context; | 43 | std::unique_ptr<Core::Frontend::GraphicsContext> cpu_context; |
| 45 | std::unique_ptr<Core::Frontend::GraphicsContext> gpu_context; | ||
| 46 | }; | 44 | }; |
| 47 | 45 | ||
| 48 | } // namespace VideoCommon | 46 | } // namespace VideoCommon |
diff --git a/src/video_core/gpu_synch.cpp b/src/video_core/gpu_synch.cpp index aaeb9811d..1ca47ddef 100644 --- a/src/video_core/gpu_synch.cpp +++ b/src/video_core/gpu_synch.cpp | |||
| @@ -7,20 +7,18 @@ | |||
| 7 | 7 | ||
| 8 | namespace VideoCommon { | 8 | namespace VideoCommon { |
| 9 | 9 | ||
| 10 | GPUSynch::GPUSynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, | 10 | GPUSynch::GPUSynch(Core::System& system) : GPU{system, false} {} |
| 11 | std::unique_ptr<Core::Frontend::GraphicsContext>&& context) | ||
| 12 | : GPU(system, std::move(renderer), false), context{std::move(context)} {} | ||
| 13 | 11 | ||
| 14 | GPUSynch::~GPUSynch() = default; | 12 | GPUSynch::~GPUSynch() = default; |
| 15 | 13 | ||
| 16 | void GPUSynch::Start() {} | 14 | void GPUSynch::Start() {} |
| 17 | 15 | ||
| 18 | void GPUSynch::ObtainContext() { | 16 | void GPUSynch::ObtainContext() { |
| 19 | context->MakeCurrent(); | 17 | renderer->Context().MakeCurrent(); |
| 20 | } | 18 | } |
| 21 | 19 | ||
| 22 | void GPUSynch::ReleaseContext() { | 20 | void GPUSynch::ReleaseContext() { |
| 23 | context->DoneCurrent(); | 21 | renderer->Context().DoneCurrent(); |
| 24 | } | 22 | } |
| 25 | 23 | ||
| 26 | void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { | 24 | void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { |
diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h index 762c20aa5..297258cb1 100644 --- a/src/video_core/gpu_synch.h +++ b/src/video_core/gpu_synch.h | |||
| @@ -19,8 +19,7 @@ namespace VideoCommon { | |||
| 19 | /// Implementation of GPU interface that runs the GPU synchronously | 19 | /// Implementation of GPU interface that runs the GPU synchronously |
| 20 | class GPUSynch final : public Tegra::GPU { | 20 | class GPUSynch final : public Tegra::GPU { |
| 21 | public: | 21 | public: |
| 22 | explicit GPUSynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, | 22 | explicit GPUSynch(Core::System& system); |
| 23 | std::unique_ptr<Core::Frontend::GraphicsContext>&& context); | ||
| 24 | ~GPUSynch() override; | 23 | ~GPUSynch() override; |
| 25 | 24 | ||
| 26 | void Start() override; | 25 | void Start() override; |
| @@ -36,9 +35,6 @@ public: | |||
| 36 | protected: | 35 | protected: |
| 37 | void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, | 36 | void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, |
| 38 | [[maybe_unused]] u32 value) const override {} | 37 | [[maybe_unused]] u32 value) const override {} |
| 39 | |||
| 40 | private: | ||
| 41 | std::unique_ptr<Core::Frontend::GraphicsContext> context; | ||
| 42 | }; | 38 | }; |
| 43 | 39 | ||
| 44 | } // namespace VideoCommon | 40 | } // namespace VideoCommon |
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 0c9ff59a4..df00b57df 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp | |||
| @@ -24,7 +24,7 @@ void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 24 | maxwell3d.regs.index_array.first = parameters[4]; | 24 | maxwell3d.regs.index_array.first = parameters[4]; |
| 25 | 25 | ||
| 26 | if (maxwell3d.ShouldExecute()) { | 26 | if (maxwell3d.ShouldExecute()) { |
| 27 | maxwell3d.GetRasterizer().Draw(true, true); | 27 | maxwell3d.Rasterizer().Draw(true, true); |
| 28 | } | 28 | } |
| 29 | maxwell3d.regs.index_array.count = 0; | 29 | maxwell3d.regs.index_array.count = 0; |
| 30 | maxwell3d.mme_draw.instance_count = 0; | 30 | maxwell3d.mme_draw.instance_count = 0; |
| @@ -42,7 +42,7 @@ void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 42 | maxwell3d.mme_draw.instance_count = count; | 42 | maxwell3d.mme_draw.instance_count = count; |
| 43 | 43 | ||
| 44 | if (maxwell3d.ShouldExecute()) { | 44 | if (maxwell3d.ShouldExecute()) { |
| 45 | maxwell3d.GetRasterizer().Draw(false, true); | 45 | maxwell3d.Rasterizer().Draw(false, true); |
| 46 | } | 46 | } |
| 47 | maxwell3d.regs.vertex_buffer.count = 0; | 47 | maxwell3d.regs.vertex_buffer.count = 0; |
| 48 | maxwell3d.mme_draw.instance_count = 0; | 48 | maxwell3d.mme_draw.instance_count = 0; |
| @@ -65,7 +65,7 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 65 | maxwell3d.regs.draw.topology.Assign( | 65 | maxwell3d.regs.draw.topology.Assign( |
| 66 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); | 66 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); |
| 67 | if (maxwell3d.ShouldExecute()) { | 67 | if (maxwell3d.ShouldExecute()) { |
| 68 | maxwell3d.GetRasterizer().Draw(true, true); | 68 | maxwell3d.Rasterizer().Draw(true, true); |
| 69 | } | 69 | } |
| 70 | maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? | 70 | maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? |
| 71 | maxwell3d.regs.index_array.count = 0; | 71 | maxwell3d.regs.index_array.count = 0; |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 844164645..c217f5bb2 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -14,11 +14,15 @@ | |||
| 14 | 14 | ||
| 15 | namespace Tegra { | 15 | namespace Tegra { |
| 16 | 16 | ||
| 17 | MemoryManager::MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | 17 | MemoryManager::MemoryManager(Core::System& system_) |
| 18 | : system{system}, rasterizer{rasterizer}, page_table(page_table_size) {} | 18 | : system{system_}, page_table(page_table_size) {} |
| 19 | 19 | ||
| 20 | MemoryManager::~MemoryManager() = default; | 20 | MemoryManager::~MemoryManager() = default; |
| 21 | 21 | ||
| 22 | void MemoryManager::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||
| 23 | rasterizer = &rasterizer_; | ||
| 24 | } | ||
| 25 | |||
| 22 | GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size) { | 26 | GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size) { |
| 23 | u64 remaining_size{size}; | 27 | u64 remaining_size{size}; |
| 24 | for (u64 offset{}; offset < size; offset += page_size) { | 28 | for (u64 offset{}; offset < size; offset += page_size) { |
| @@ -217,7 +221,7 @@ void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::siz | |||
| 217 | 221 | ||
| 218 | // Flush must happen on the rasterizer interface, such that memory is always synchronous | 222 | // Flush must happen on the rasterizer interface, such that memory is always synchronous |
| 219 | // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. | 223 | // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. |
| 220 | rasterizer.FlushRegion(src_addr, copy_amount); | 224 | rasterizer->FlushRegion(src_addr, copy_amount); |
| 221 | system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); | 225 | system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); |
| 222 | } | 226 | } |
| 223 | 227 | ||
| @@ -266,7 +270,7 @@ void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, s | |||
| 266 | 270 | ||
| 267 | // Invalidate must happen on the rasterizer interface, such that memory is always | 271 | // Invalidate must happen on the rasterizer interface, such that memory is always |
| 268 | // synchronous when it is written (even when in asynchronous GPU mode). | 272 | // synchronous when it is written (even when in asynchronous GPU mode). |
| 269 | rasterizer.InvalidateRegion(dest_addr, copy_amount); | 273 | rasterizer->InvalidateRegion(dest_addr, copy_amount); |
| 270 | system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); | 274 | system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); |
| 271 | } | 275 | } |
| 272 | 276 | ||
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 681bd9588..8953fcb53 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -68,9 +68,12 @@ static_assert(sizeof(PageEntry) == 4, "PageEntry is too large"); | |||
| 68 | 68 | ||
| 69 | class MemoryManager final { | 69 | class MemoryManager final { |
| 70 | public: | 70 | public: |
| 71 | explicit MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer); | 71 | explicit MemoryManager(Core::System& system); |
| 72 | ~MemoryManager(); | 72 | ~MemoryManager(); |
| 73 | 73 | ||
| 74 | /// Binds a renderer to the memory manager. | ||
| 75 | void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||
| 76 | |||
| 74 | std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr) const; | 77 | std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr) const; |
| 75 | 78 | ||
| 76 | template <typename T> | 79 | template <typename T> |
| @@ -141,7 +144,7 @@ private: | |||
| 141 | 144 | ||
| 142 | Core::System& system; | 145 | Core::System& system; |
| 143 | 146 | ||
| 144 | VideoCore::RasterizerInterface& rasterizer; | 147 | VideoCore::RasterizerInterface* rasterizer = nullptr; |
| 145 | 148 | ||
| 146 | std::vector<PageEntry> page_table; | 149 | std::vector<PageEntry> page_table; |
| 147 | }; | 150 | }; |
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index dfb06e87e..a93a1732c 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp | |||
| @@ -9,7 +9,9 @@ | |||
| 9 | 9 | ||
| 10 | namespace VideoCore { | 10 | namespace VideoCore { |
| 11 | 11 | ||
| 12 | RendererBase::RendererBase(Core::Frontend::EmuWindow& window) : render_window{window} { | 12 | RendererBase::RendererBase(Core::Frontend::EmuWindow& window_, |
| 13 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) | ||
| 14 | : render_window{window_}, context{std::move(context_)} { | ||
| 13 | RefreshBaseSettings(); | 15 | RefreshBaseSettings(); |
| 14 | } | 16 | } |
| 15 | 17 | ||
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 1d85219b6..649074acd 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -15,7 +15,8 @@ | |||
| 15 | 15 | ||
| 16 | namespace Core::Frontend { | 16 | namespace Core::Frontend { |
| 17 | class EmuWindow; | 17 | class EmuWindow; |
| 18 | } | 18 | class GraphicsContext; |
| 19 | } // namespace Core::Frontend | ||
| 19 | 20 | ||
| 20 | namespace VideoCore { | 21 | namespace VideoCore { |
| 21 | 22 | ||
| @@ -25,14 +26,15 @@ struct RendererSettings { | |||
| 25 | 26 | ||
| 26 | // Screenshot | 27 | // Screenshot |
| 27 | std::atomic<bool> screenshot_requested{false}; | 28 | std::atomic<bool> screenshot_requested{false}; |
| 28 | void* screenshot_bits; | 29 | void* screenshot_bits{}; |
| 29 | std::function<void()> screenshot_complete_callback; | 30 | std::function<void()> screenshot_complete_callback; |
| 30 | Layout::FramebufferLayout screenshot_framebuffer_layout; | 31 | Layout::FramebufferLayout screenshot_framebuffer_layout; |
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| 33 | class RendererBase : NonCopyable { | 34 | class RendererBase : NonCopyable { |
| 34 | public: | 35 | public: |
| 35 | explicit RendererBase(Core::Frontend::EmuWindow& window); | 36 | explicit RendererBase(Core::Frontend::EmuWindow& window, |
| 37 | std::unique_ptr<Core::Frontend::GraphicsContext> context); | ||
| 36 | virtual ~RendererBase(); | 38 | virtual ~RendererBase(); |
| 37 | 39 | ||
| 38 | /// Initialize the renderer | 40 | /// Initialize the renderer |
| @@ -68,6 +70,14 @@ public: | |||
| 68 | return *rasterizer; | 70 | return *rasterizer; |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 73 | Core::Frontend::GraphicsContext& Context() { | ||
| 74 | return *context; | ||
| 75 | } | ||
| 76 | |||
| 77 | const Core::Frontend::GraphicsContext& Context() const { | ||
| 78 | return *context; | ||
| 79 | } | ||
| 80 | |||
| 71 | Core::Frontend::EmuWindow& GetRenderWindow() { | 81 | Core::Frontend::EmuWindow& GetRenderWindow() { |
| 72 | return render_window; | 82 | return render_window; |
| 73 | } | 83 | } |
| @@ -94,6 +104,7 @@ public: | |||
| 94 | protected: | 104 | protected: |
| 95 | Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. | 105 | Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. |
| 96 | std::unique_ptr<RasterizerInterface> rasterizer; | 106 | std::unique_ptr<RasterizerInterface> rasterizer; |
| 107 | std::unique_ptr<Core::Frontend::GraphicsContext> context; | ||
| 97 | f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer | 108 | f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer |
| 98 | int m_current_frame = 0; ///< Current frame, should be set by the renderer | 109 | int m_current_frame = 0; ///< Current frame, should be set by the renderer |
| 99 | 110 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 14bbc3a1c..c39663db7 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -313,10 +313,11 @@ public: | |||
| 313 | } | 313 | } |
| 314 | }; | 314 | }; |
| 315 | 315 | ||
| 316 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, | 316 | RendererOpenGL::RendererOpenGL(Core::System& system_, Core::Frontend::EmuWindow& emu_window_, |
| 317 | Core::Frontend::GraphicsContext& context) | 317 | Tegra::GPU& gpu_, |
| 318 | : RendererBase{emu_window}, emu_window{emu_window}, system{system}, context{context}, | 318 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) |
| 319 | program_manager{device}, has_debug_tool{HasDebugTool()} {} | 319 | : RendererBase{emu_window_, std::move(context_)}, system{system_}, |
| 320 | emu_window{emu_window_}, gpu{gpu_}, program_manager{device}, has_debug_tool{HasDebugTool()} {} | ||
| 320 | 321 | ||
| 321 | RendererOpenGL::~RendererOpenGL() = default; | 322 | RendererOpenGL::~RendererOpenGL() = default; |
| 322 | 323 | ||
| @@ -384,7 +385,7 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 384 | if (has_debug_tool) { | 385 | if (has_debug_tool) { |
| 385 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | 386 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |
| 386 | Present(0); | 387 | Present(0); |
| 387 | context.SwapBuffers(); | 388 | context->SwapBuffers(); |
| 388 | } | 389 | } |
| 389 | } | 390 | } |
| 390 | 391 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 8b18d32e6..52ea76b7d 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -56,8 +56,9 @@ class FrameMailbox; | |||
| 56 | 56 | ||
| 57 | class RendererOpenGL final : public VideoCore::RendererBase { | 57 | class RendererOpenGL final : public VideoCore::RendererBase { |
| 58 | public: | 58 | public: |
| 59 | explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, | 59 | explicit RendererOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 60 | Core::Frontend::GraphicsContext& context); | 60 | Tegra::GPU& gpu, |
| 61 | std::unique_ptr<Core::Frontend::GraphicsContext> context); | ||
| 61 | ~RendererOpenGL() override; | 62 | ~RendererOpenGL() override; |
| 62 | 63 | ||
| 63 | bool Init() override; | 64 | bool Init() override; |
| @@ -93,9 +94,9 @@ private: | |||
| 93 | 94 | ||
| 94 | bool Present(int timeout_ms); | 95 | bool Present(int timeout_ms); |
| 95 | 96 | ||
| 96 | Core::Frontend::EmuWindow& emu_window; | ||
| 97 | Core::System& system; | 97 | Core::System& system; |
| 98 | Core::Frontend::GraphicsContext& context; | 98 | Core::Frontend::EmuWindow& emu_window; |
| 99 | Tegra::GPU& gpu; | ||
| 99 | const Device device; | 100 | const Device device; |
| 100 | 101 | ||
| 101 | StateTracker state_tracker{system}; | 102 | StateTracker state_tracker{system}; |
| @@ -120,7 +121,7 @@ private: | |||
| 120 | std::vector<u8> gl_framebuffer_data; | 121 | std::vector<u8> gl_framebuffer_data; |
| 121 | 122 | ||
| 122 | /// Used for transforming the framebuffer orientation | 123 | /// Used for transforming the framebuffer orientation |
| 123 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags; | 124 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags{}; |
| 124 | Common::Rectangle<int> framebuffer_crop_rect; | 125 | Common::Rectangle<int> framebuffer_crop_rect; |
| 125 | 126 | ||
| 126 | /// Frame presentation mailbox | 127 | /// Frame presentation mailbox |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 6e49699d0..ae46e0444 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -237,8 +237,10 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext | |||
| 237 | 237 | ||
| 238 | } // Anonymous namespace | 238 | } // Anonymous namespace |
| 239 | 239 | ||
| 240 | RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& window, Core::System& system) | 240 | RendererVulkan::RendererVulkan(Core::System& system_, Core::Frontend::EmuWindow& emu_window, |
| 241 | : RendererBase(window), system{system} {} | 241 | Tegra::GPU& gpu_, |
| 242 | std::unique_ptr<Core::Frontend::GraphicsContext> context) | ||
| 243 | : RendererBase{emu_window, std::move(context)}, system{system_}, gpu{gpu_} {} | ||
| 242 | 244 | ||
| 243 | RendererVulkan::~RendererVulkan() { | 245 | RendererVulkan::~RendererVulkan() { |
| 244 | ShutDown(); | 246 | ShutDown(); |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 522b5bff8..13debbbc0 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -38,7 +38,9 @@ struct VKScreenInfo { | |||
| 38 | 38 | ||
| 39 | class RendererVulkan final : public VideoCore::RendererBase { | 39 | class RendererVulkan final : public VideoCore::RendererBase { |
| 40 | public: | 40 | public: |
| 41 | explicit RendererVulkan(Core::Frontend::EmuWindow& window, Core::System& system); | 41 | explicit RendererVulkan(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 42 | Tegra::GPU& gpu, | ||
| 43 | std::unique_ptr<Core::Frontend::GraphicsContext> context); | ||
| 42 | ~RendererVulkan() override; | 44 | ~RendererVulkan() override; |
| 43 | 45 | ||
| 44 | bool Init() override; | 46 | bool Init() override; |
| @@ -58,6 +60,7 @@ private: | |||
| 58 | void Report() const; | 60 | void Report() const; |
| 59 | 61 | ||
| 60 | Core::System& system; | 62 | Core::System& system; |
| 63 | Tegra::GPU& gpu; | ||
| 61 | 64 | ||
| 62 | Common::DynamicLibrary library; | 65 | Common::DynamicLibrary library; |
| 63 | vk::InstanceDispatch dld; | 66 | vk::InstanceDispatch dld; |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 45f360bdd..4e3a092c7 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | |||
| 6 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 8 | #include "core/core.h" |
| 8 | #include "core/settings.h" | 9 | #include "core/settings.h" |
| @@ -16,37 +17,46 @@ | |||
| 16 | #include "video_core/video_core.h" | 17 | #include "video_core/video_core.h" |
| 17 | 18 | ||
| 18 | namespace { | 19 | namespace { |
| 19 | std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window, | 20 | |
| 20 | Core::System& system, | 21 | std::unique_ptr<VideoCore::RendererBase> CreateRenderer( |
| 21 | Core::Frontend::GraphicsContext& context) { | 22 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, |
| 23 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { | ||
| 22 | switch (Settings::values.renderer_backend.GetValue()) { | 24 | switch (Settings::values.renderer_backend.GetValue()) { |
| 23 | case Settings::RendererBackend::OpenGL: | 25 | case Settings::RendererBackend::OpenGL: |
| 24 | return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system, context); | 26 | return std::make_unique<OpenGL::RendererOpenGL>(system, emu_window, gpu, |
| 27 | std::move(context)); | ||
| 25 | #ifdef HAS_VULKAN | 28 | #ifdef HAS_VULKAN |
| 26 | case Settings::RendererBackend::Vulkan: | 29 | case Settings::RendererBackend::Vulkan: |
| 27 | return std::make_unique<Vulkan::RendererVulkan>(emu_window, system); | 30 | return std::make_unique<Vulkan::RendererVulkan>(system, emu_window, gpu, |
| 31 | std::move(context)); | ||
| 28 | #endif | 32 | #endif |
| 29 | default: | 33 | default: |
| 30 | return nullptr; | 34 | return nullptr; |
| 31 | } | 35 | } |
| 32 | } | 36 | } |
| 37 | |||
| 33 | } // Anonymous namespace | 38 | } // Anonymous namespace |
| 34 | 39 | ||
| 35 | namespace VideoCore { | 40 | namespace VideoCore { |
| 36 | 41 | ||
| 37 | std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Core::System& system) { | 42 | std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Core::System& system) { |
| 43 | std::unique_ptr<Tegra::GPU> gpu; | ||
| 44 | if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { | ||
| 45 | gpu = std::make_unique<VideoCommon::GPUAsynch>(system); | ||
| 46 | } else { | ||
| 47 | gpu = std::make_unique<VideoCommon::GPUSynch>(system); | ||
| 48 | } | ||
| 49 | |||
| 38 | auto context = emu_window.CreateSharedContext(); | 50 | auto context = emu_window.CreateSharedContext(); |
| 39 | const auto scope = context->Acquire(); | 51 | const auto scope = context->Acquire(); |
| 40 | auto renderer = CreateRenderer(emu_window, system, *context); | 52 | |
| 53 | auto renderer = CreateRenderer(system, emu_window, *gpu, std::move(context)); | ||
| 41 | if (!renderer->Init()) { | 54 | if (!renderer->Init()) { |
| 42 | return nullptr; | 55 | return nullptr; |
| 43 | } | 56 | } |
| 44 | 57 | ||
| 45 | if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { | 58 | gpu->BindRenderer(std::move(renderer)); |
| 46 | return std::make_unique<VideoCommon::GPUAsynch>(system, std::move(renderer), | 59 | return gpu; |
| 47 | std::move(context)); | ||
| 48 | } | ||
| 49 | return std::make_unique<VideoCommon::GPUSynch>(system, std::move(renderer), std::move(context)); | ||
| 50 | } | 60 | } |
| 51 | 61 | ||
| 52 | u16 GetResolutionScaleFactor(const RendererBase& renderer) { | 62 | u16 GetResolutionScaleFactor(const RendererBase& renderer) { |