Merge pull request #4542 from ReinUsesLisp/gpu-init-base
video_core: Initialize renderer with a GPU
This commit is contained in:
		| @@ -10,7 +10,13 @@ | |||||||
|  |  | ||||||
| namespace Tegra::Engines { | namespace Tegra::Engines { | ||||||
|  |  | ||||||
| Fermi2D::Fermi2D(VideoCore::RasterizerInterface& rasterizer) : rasterizer{rasterizer} {} | Fermi2D::Fermi2D() = default; | ||||||
|  |  | ||||||
|  | Fermi2D::~Fermi2D() = default; | ||||||
|  |  | ||||||
|  | void Fermi2D::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||||||
|  |     rasterizer = &rasterizer_; | ||||||
|  | } | ||||||
|  |  | ||||||
| void Fermi2D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | void Fermi2D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | ||||||
|     ASSERT_MSG(method < Regs::NUM_REGS, |     ASSERT_MSG(method < Regs::NUM_REGS, | ||||||
| @@ -87,7 +93,7 @@ void Fermi2D::HandleSurfaceCopy() { | |||||||
|     copy_config.src_rect = src_rect; |     copy_config.src_rect = src_rect; | ||||||
|     copy_config.dst_rect = dst_rect; |     copy_config.dst_rect = dst_rect; | ||||||
|  |  | ||||||
|     if (!rasterizer.AccelerateSurfaceCopy(regs.src, regs.dst, copy_config)) { |     if (!rasterizer->AccelerateSurfaceCopy(regs.src, regs.dst, copy_config)) { | ||||||
|         UNIMPLEMENTED(); |         UNIMPLEMENTED(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -34,8 +34,11 @@ namespace Tegra::Engines { | |||||||
|  |  | ||||||
| class Fermi2D final : public EngineInterface { | class Fermi2D final : public EngineInterface { | ||||||
| public: | public: | ||||||
|     explicit Fermi2D(VideoCore::RasterizerInterface& rasterizer); |     explicit Fermi2D(); | ||||||
|     ~Fermi2D() = default; |     ~Fermi2D(); | ||||||
|  |  | ||||||
|  |     /// Binds a rasterizer to this engine. | ||||||
|  |     void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||||||
|  |  | ||||||
|     /// Write the value to the register identified by method. |     /// Write the value to the register identified by method. | ||||||
|     void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; |     void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; | ||||||
| @@ -149,7 +152,7 @@ public: | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     VideoCore::RasterizerInterface& rasterizer; |     VideoCore::RasterizerInterface* rasterizer; | ||||||
|  |  | ||||||
|     /// Performs the copy from the source surface to the destination surface as configured in the |     /// Performs the copy from the source surface to the destination surface as configured in the | ||||||
|     /// registers. |     /// registers. | ||||||
|   | |||||||
| @@ -16,14 +16,15 @@ | |||||||
|  |  | ||||||
| namespace Tegra::Engines { | namespace Tegra::Engines { | ||||||
|  |  | ||||||
| KeplerCompute::KeplerCompute(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | KeplerCompute::KeplerCompute(Core::System& system_, MemoryManager& memory_manager_) | ||||||
|                              MemoryManager& memory_manager) |     : system{system_}, memory_manager{memory_manager_}, upload_state{memory_manager, regs.upload} {} | ||||||
|     : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, upload_state{ |  | ||||||
|                                                                                   memory_manager, |  | ||||||
|                                                                                   regs.upload} {} |  | ||||||
|  |  | ||||||
| KeplerCompute::~KeplerCompute() = default; | KeplerCompute::~KeplerCompute() = default; | ||||||
|  |  | ||||||
|  | void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||||||
|  |     rasterizer = &rasterizer_; | ||||||
|  | } | ||||||
|  |  | ||||||
| void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | ||||||
|     ASSERT_MSG(method < Regs::NUM_REGS, |     ASSERT_MSG(method < Regs::NUM_REGS, | ||||||
|                "Invalid KeplerCompute register, increase the size of the Regs structure"); |                "Invalid KeplerCompute register, increase the size of the Regs structure"); | ||||||
| @@ -104,11 +105,11 @@ SamplerDescriptor KeplerCompute::AccessSampler(u32 handle) const { | |||||||
| } | } | ||||||
|  |  | ||||||
| VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() { | VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() { | ||||||
|     return rasterizer.AccessGuestDriverProfile(); |     return rasterizer->AccessGuestDriverProfile(); | ||||||
| } | } | ||||||
|  |  | ||||||
| const VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() const { | const VideoCore::GuestDriverProfile& KeplerCompute::AccessGuestDriverProfile() const { | ||||||
|     return rasterizer.AccessGuestDriverProfile(); |     return rasterizer->AccessGuestDriverProfile(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void KeplerCompute::ProcessLaunch() { | void KeplerCompute::ProcessLaunch() { | ||||||
| @@ -119,7 +120,7 @@ void KeplerCompute::ProcessLaunch() { | |||||||
|     const GPUVAddr code_addr = regs.code_loc.Address() + launch_description.program_start; |     const GPUVAddr code_addr = regs.code_loc.Address() + launch_description.program_start; | ||||||
|     LOG_TRACE(HW_GPU, "Compute invocation launched at address 0x{:016x}", code_addr); |     LOG_TRACE(HW_GPU, "Compute invocation launched at address 0x{:016x}", code_addr); | ||||||
|  |  | ||||||
|     rasterizer.DispatchCompute(code_addr); |     rasterizer->DispatchCompute(code_addr); | ||||||
| } | } | ||||||
|  |  | ||||||
| Texture::TICEntry KeplerCompute::GetTICEntry(u32 tic_index) const { | Texture::TICEntry KeplerCompute::GetTICEntry(u32 tic_index) const { | ||||||
|   | |||||||
| @@ -42,10 +42,12 @@ namespace Tegra::Engines { | |||||||
|  |  | ||||||
| class KeplerCompute final : public ConstBufferEngineInterface, public EngineInterface { | class KeplerCompute final : public ConstBufferEngineInterface, public EngineInterface { | ||||||
| public: | public: | ||||||
|     explicit KeplerCompute(Core::System& system, VideoCore::RasterizerInterface& rasterizer, |     explicit KeplerCompute(Core::System& system, MemoryManager& memory_manager); | ||||||
|                            MemoryManager& memory_manager); |  | ||||||
|     ~KeplerCompute(); |     ~KeplerCompute(); | ||||||
|  |  | ||||||
|  |     /// Binds a rasterizer to this engine. | ||||||
|  |     void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||||||
|  |  | ||||||
|     static constexpr std::size_t NumConstBuffers = 8; |     static constexpr std::size_t NumConstBuffers = 8; | ||||||
|  |  | ||||||
|     struct Regs { |     struct Regs { | ||||||
| @@ -230,11 +232,6 @@ public: | |||||||
|     const VideoCore::GuestDriverProfile& AccessGuestDriverProfile() const override; |     const VideoCore::GuestDriverProfile& AccessGuestDriverProfile() const override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     Core::System& system; |  | ||||||
|     VideoCore::RasterizerInterface& rasterizer; |  | ||||||
|     MemoryManager& memory_manager; |  | ||||||
|     Upload::State upload_state; |  | ||||||
|  |  | ||||||
|     void ProcessLaunch(); |     void ProcessLaunch(); | ||||||
|  |  | ||||||
|     /// Retrieves information about a specific TIC entry from the TIC buffer. |     /// Retrieves information about a specific TIC entry from the TIC buffer. | ||||||
| @@ -242,6 +239,11 @@ private: | |||||||
|  |  | ||||||
|     /// Retrieves information about a specific TSC entry from the TSC buffer. |     /// Retrieves information about a specific TSC entry from the TSC buffer. | ||||||
|     Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; |     Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; | ||||||
|  |  | ||||||
|  |     Core::System& system; | ||||||
|  |     MemoryManager& memory_manager; | ||||||
|  |     VideoCore::RasterizerInterface* rasterizer = nullptr; | ||||||
|  |     Upload::State upload_state; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define ASSERT_REG_POSITION(field_name, position)                                                  \ | #define ASSERT_REG_POSITION(field_name, position)                                                  \ | ||||||
|   | |||||||
| @@ -22,14 +22,19 @@ using VideoCore::QueryType; | |||||||
| /// First register id that is actually a Macro call. | /// First register id that is actually a Macro call. | ||||||
| constexpr u32 MacroRegistersStart = 0xE00; | constexpr u32 MacroRegistersStart = 0xE00; | ||||||
|  |  | ||||||
| Maxwell3D::Maxwell3D(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | Maxwell3D::Maxwell3D(Core::System& system_, MemoryManager& memory_manager_) | ||||||
|                      MemoryManager& memory_manager) |     : system{system_}, memory_manager{memory_manager_}, macro_engine{GetMacroEngine(*this)}, | ||||||
|     : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, |       upload_state{memory_manager, regs.upload} { | ||||||
|       macro_engine{GetMacroEngine(*this)}, upload_state{memory_manager, regs.upload} { |  | ||||||
|     dirty.flags.flip(); |     dirty.flags.flip(); | ||||||
|     InitializeRegisterDefaults(); |     InitializeRegisterDefaults(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Maxwell3D::~Maxwell3D() = default; | ||||||
|  |  | ||||||
|  | void Maxwell3D::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||||||
|  |     rasterizer = &rasterizer_; | ||||||
|  | } | ||||||
|  |  | ||||||
| void Maxwell3D::InitializeRegisterDefaults() { | void Maxwell3D::InitializeRegisterDefaults() { | ||||||
|     // Initializes registers to their default values - what games expect them to be at boot. This is |     // Initializes registers to their default values - what games expect them to be at boot. This is | ||||||
|     // for certain registers that may not be explicitly set by games. |     // 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) { | |||||||
|  |  | ||||||
|     switch (method) { |     switch (method) { | ||||||
|     case MAXWELL3D_REG_INDEX(wait_for_idle): { |     case MAXWELL3D_REG_INDEX(wait_for_idle): { | ||||||
|         rasterizer.WaitForIdle(); |         rasterizer->WaitForIdle(); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     case MAXWELL3D_REG_INDEX(shadow_ram_control): { |     case MAXWELL3D_REG_INDEX(shadow_ram_control): { | ||||||
| @@ -402,7 +407,7 @@ void Maxwell3D::FlushMMEInlineDraw() { | |||||||
|  |  | ||||||
|     const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed; |     const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed; | ||||||
|     if (ShouldExecute()) { |     if (ShouldExecute()) { | ||||||
|         rasterizer.Draw(is_indexed, true); |         rasterizer->Draw(is_indexed, true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if |     // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if | ||||||
| @@ -465,7 +470,7 @@ void Maxwell3D::ProcessQueryGet() { | |||||||
|     switch (regs.query.query_get.operation) { |     switch (regs.query.query_get.operation) { | ||||||
|     case Regs::QueryOperation::Release: |     case Regs::QueryOperation::Release: | ||||||
|         if (regs.query.query_get.fence == 1) { |         if (regs.query.query_get.fence == 1) { | ||||||
|             rasterizer.SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence); |             rasterizer->SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence); | ||||||
|         } else { |         } else { | ||||||
|             StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); |             StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); | ||||||
|         } |         } | ||||||
| @@ -533,7 +538,7 @@ void Maxwell3D::ProcessQueryCondition() { | |||||||
| void Maxwell3D::ProcessCounterReset() { | void Maxwell3D::ProcessCounterReset() { | ||||||
|     switch (regs.counter_reset) { |     switch (regs.counter_reset) { | ||||||
|     case Regs::CounterReset::SampleCnt: |     case Regs::CounterReset::SampleCnt: | ||||||
|         rasterizer.ResetCounter(QueryType::SamplesPassed); |         rasterizer->ResetCounter(QueryType::SamplesPassed); | ||||||
|         break; |         break; | ||||||
|     default: |     default: | ||||||
|         LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", |         LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", | ||||||
| @@ -547,7 +552,7 @@ void Maxwell3D::ProcessSyncPoint() { | |||||||
|     const u32 increment = regs.sync_info.increment.Value(); |     const u32 increment = regs.sync_info.increment.Value(); | ||||||
|     [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); |     [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); | ||||||
|     if (increment) { |     if (increment) { | ||||||
|         rasterizer.SignalSyncPoint(sync_point); |         rasterizer->SignalSyncPoint(sync_point); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -570,7 +575,7 @@ void Maxwell3D::DrawArrays() { | |||||||
|  |  | ||||||
|     const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; |     const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; | ||||||
|     if (ShouldExecute()) { |     if (ShouldExecute()) { | ||||||
|         rasterizer.Draw(is_indexed, false); |         rasterizer->Draw(is_indexed, false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if |     // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if | ||||||
| @@ -590,7 +595,7 @@ std::optional<u64> Maxwell3D::GetQueryResult() { | |||||||
|         return 0; |         return 0; | ||||||
|     case Regs::QuerySelect::SamplesPassed: |     case Regs::QuerySelect::SamplesPassed: | ||||||
|         // Deferred. |         // Deferred. | ||||||
|         rasterizer.Query(regs.query.QueryAddress(), VideoCore::QueryType::SamplesPassed, |         rasterizer->Query(regs.query.QueryAddress(), VideoCore::QueryType::SamplesPassed, | ||||||
|                           system.GPU().GetTicks()); |                           system.GPU().GetTicks()); | ||||||
|         return {}; |         return {}; | ||||||
|     default: |     default: | ||||||
| @@ -718,7 +723,7 @@ void Maxwell3D::ProcessClearBuffers() { | |||||||
|            regs.clear_buffers.R == regs.clear_buffers.B && |            regs.clear_buffers.R == regs.clear_buffers.B && | ||||||
|            regs.clear_buffers.R == regs.clear_buffers.A); |            regs.clear_buffers.R == regs.clear_buffers.A); | ||||||
|  |  | ||||||
|     rasterizer.Clear(); |     rasterizer->Clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
| u32 Maxwell3D::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const { | u32 Maxwell3D::AccessConstBuffer32(ShaderType stage, u64 const_buffer, u64 offset) const { | ||||||
| @@ -752,11 +757,11 @@ SamplerDescriptor Maxwell3D::AccessSampler(u32 handle) const { | |||||||
| } | } | ||||||
|  |  | ||||||
| VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() { | VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() { | ||||||
|     return rasterizer.AccessGuestDriverProfile(); |     return rasterizer->AccessGuestDriverProfile(); | ||||||
| } | } | ||||||
|  |  | ||||||
| const VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() const { | const VideoCore::GuestDriverProfile& Maxwell3D::AccessGuestDriverProfile() const { | ||||||
|     return rasterizer.AccessGuestDriverProfile(); |     return rasterizer->AccessGuestDriverProfile(); | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace Tegra::Engines | } // namespace Tegra::Engines | ||||||
|   | |||||||
| @@ -51,9 +51,11 @@ namespace Tegra::Engines { | |||||||
|  |  | ||||||
| class Maxwell3D final : public ConstBufferEngineInterface, public EngineInterface { | class Maxwell3D final : public ConstBufferEngineInterface, public EngineInterface { | ||||||
| public: | public: | ||||||
|     explicit Maxwell3D(Core::System& system, VideoCore::RasterizerInterface& rasterizer, |     explicit Maxwell3D(Core::System& system, MemoryManager& memory_manager); | ||||||
|                        MemoryManager& memory_manager); |     ~Maxwell3D(); | ||||||
|     ~Maxwell3D() = default; |  | ||||||
|  |     /// Binds a rasterizer to this engine. | ||||||
|  |     void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||||||
|  |  | ||||||
|     /// Register structure of the Maxwell3D engine. |     /// Register structure of the Maxwell3D engine. | ||||||
|     /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. |     /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | ||||||
| @@ -1418,12 +1420,12 @@ public: | |||||||
|         return execute_on; |         return execute_on; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     VideoCore::RasterizerInterface& GetRasterizer() { |     VideoCore::RasterizerInterface& Rasterizer() { | ||||||
|         return rasterizer; |         return *rasterizer; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const VideoCore::RasterizerInterface& GetRasterizer() const { |     const VideoCore::RasterizerInterface& Rasterizer() const { | ||||||
|         return rasterizer; |         return *rasterizer; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Notify a memory write has happened. |     /// Notify a memory write has happened. | ||||||
| @@ -1460,11 +1462,10 @@ private: | |||||||
|     void InitializeRegisterDefaults(); |     void InitializeRegisterDefaults(); | ||||||
|  |  | ||||||
|     Core::System& system; |     Core::System& system; | ||||||
|  |  | ||||||
|     VideoCore::RasterizerInterface& rasterizer; |  | ||||||
|  |  | ||||||
|     MemoryManager& memory_manager; |     MemoryManager& memory_manager; | ||||||
|  |  | ||||||
|  |     VideoCore::RasterizerInterface* rasterizer = nullptr; | ||||||
|  |  | ||||||
|     /// Start offsets of each macro in macro_memory |     /// Start offsets of each macro in macro_memory | ||||||
|     std::array<u32, 0x80> macro_positions = {}; |     std::array<u32, 0x80> macro_positions = {}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,21 +27,28 @@ namespace Tegra { | |||||||
|  |  | ||||||
| MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); | MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); | ||||||
|  |  | ||||||
| GPU::GPU(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer_, bool is_async) | GPU::GPU(Core::System& system_, bool is_async_) | ||||||
|     : system{system}, renderer{std::move(renderer_)}, is_async{is_async} { |     : system{system_}, dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, | ||||||
|     auto& rasterizer{renderer->Rasterizer()}; |       memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, | ||||||
|     memory_manager = std::make_unique<Tegra::MemoryManager>(system, rasterizer); |       maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, | ||||||
|     dma_pusher = std::make_unique<Tegra::DmaPusher>(system, *this); |       fermi_2d{std::make_unique<Engines::Fermi2D>()}, | ||||||
|     maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); |       kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, | ||||||
|     fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer); |       maxwell_dma{std::make_unique<Engines::MaxwellDMA>(system, *memory_manager)}, | ||||||
|     kepler_compute = std::make_unique<Engines::KeplerCompute>(system, rasterizer, *memory_manager); |       kepler_memory{std::make_unique<Engines::KeplerMemory>(system, *memory_manager)}, | ||||||
|     maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, *memory_manager); |       shader_notify{std::make_unique<VideoCore::ShaderNotify>()}, is_async{is_async_} {} | ||||||
|     kepler_memory = std::make_unique<Engines::KeplerMemory>(system, *memory_manager); |  | ||||||
|     shader_notify = std::make_unique<VideoCore::ShaderNotify>(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| GPU::~GPU() = default; | GPU::~GPU() = default; | ||||||
|  |  | ||||||
|  | void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) { | ||||||
|  |     renderer = std::move(renderer_); | ||||||
|  |  | ||||||
|  |     VideoCore::RasterizerInterface& rasterizer = renderer->Rasterizer(); | ||||||
|  |     memory_manager->BindRasterizer(rasterizer); | ||||||
|  |     maxwell_3d->BindRasterizer(rasterizer); | ||||||
|  |     fermi_2d->BindRasterizer(rasterizer); | ||||||
|  |     kepler_compute->BindRasterizer(rasterizer); | ||||||
|  | } | ||||||
|  |  | ||||||
| Engines::Maxwell3D& GPU::Maxwell3D() { | Engines::Maxwell3D& GPU::Maxwell3D() { | ||||||
|     return *maxwell_3d; |     return *maxwell_3d; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -142,11 +142,6 @@ class MemoryManager; | |||||||
|  |  | ||||||
| class GPU { | class GPU { | ||||||
| public: | public: | ||||||
|     explicit GPU(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, |  | ||||||
|                  bool is_async); |  | ||||||
|  |  | ||||||
|     virtual ~GPU(); |  | ||||||
|  |  | ||||||
|     struct MethodCall { |     struct MethodCall { | ||||||
|         u32 method{}; |         u32 method{}; | ||||||
|         u32 argument{}; |         u32 argument{}; | ||||||
| @@ -162,6 +157,12 @@ public: | |||||||
|               method_count(method_count) {} |               method_count(method_count) {} | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     explicit GPU(Core::System& system, bool is_async); | ||||||
|  |     virtual ~GPU(); | ||||||
|  |  | ||||||
|  |     /// Binds a renderer to the GPU. | ||||||
|  |     void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer); | ||||||
|  |  | ||||||
|     /// Calls a GPU method. |     /// Calls a GPU method. | ||||||
|     void CallMethod(const MethodCall& method_call); |     void CallMethod(const MethodCall& method_call); | ||||||
|  |  | ||||||
| @@ -345,8 +346,8 @@ private: | |||||||
|     bool ExecuteMethodOnEngine(u32 method); |     bool ExecuteMethodOnEngine(u32 method); | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     std::unique_ptr<Tegra::DmaPusher> dma_pusher; |  | ||||||
|     Core::System& system; |     Core::System& system; | ||||||
|  |     std::unique_ptr<Tegra::DmaPusher> dma_pusher; | ||||||
|     std::unique_ptr<VideoCore::RendererBase> renderer; |     std::unique_ptr<VideoCore::RendererBase> renderer; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|   | |||||||
| @@ -10,16 +10,14 @@ | |||||||
|  |  | ||||||
| namespace VideoCommon { | namespace VideoCommon { | ||||||
|  |  | ||||||
| GPUAsynch::GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer_, | GPUAsynch::GPUAsynch(Core::System& system) : GPU{system, true}, gpu_thread{system} {} | ||||||
|                      std::unique_ptr<Core::Frontend::GraphicsContext>&& context) |  | ||||||
|     : GPU(system, std::move(renderer_), true), gpu_thread{system}, |  | ||||||
|       cpu_context(renderer->GetRenderWindow().CreateSharedContext()), |  | ||||||
|       gpu_context(std::move(context)) {} |  | ||||||
|  |  | ||||||
| GPUAsynch::~GPUAsynch() = default; | GPUAsynch::~GPUAsynch() = default; | ||||||
|  |  | ||||||
| void GPUAsynch::Start() { | void GPUAsynch::Start() { | ||||||
|     gpu_thread.StartThread(*renderer, *gpu_context, *dma_pusher); |     gpu_thread.StartThread(*renderer, renderer->Context(), *dma_pusher); | ||||||
|  |     cpu_context = renderer->GetRenderWindow().CreateSharedContext(); | ||||||
|  |     cpu_context->MakeCurrent(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GPUAsynch::ObtainContext() { | void GPUAsynch::ObtainContext() { | ||||||
|   | |||||||
| @@ -20,8 +20,7 @@ namespace VideoCommon { | |||||||
| /// Implementation of GPU interface that runs the GPU asynchronously | /// Implementation of GPU interface that runs the GPU asynchronously | ||||||
| class GPUAsynch final : public Tegra::GPU { | class GPUAsynch final : public Tegra::GPU { | ||||||
| public: | public: | ||||||
|     explicit GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, |     explicit GPUAsynch(Core::System& system); | ||||||
|                        std::unique_ptr<Core::Frontend::GraphicsContext>&& context); |  | ||||||
|     ~GPUAsynch() override; |     ~GPUAsynch() override; | ||||||
|  |  | ||||||
|     void Start() override; |     void Start() override; | ||||||
| @@ -42,7 +41,6 @@ protected: | |||||||
| private: | private: | ||||||
|     GPUThread::ThreadManager gpu_thread; |     GPUThread::ThreadManager gpu_thread; | ||||||
|     std::unique_ptr<Core::Frontend::GraphicsContext> cpu_context; |     std::unique_ptr<Core::Frontend::GraphicsContext> cpu_context; | ||||||
|     std::unique_ptr<Core::Frontend::GraphicsContext> gpu_context; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace VideoCommon | } // namespace VideoCommon | ||||||
|   | |||||||
| @@ -7,20 +7,18 @@ | |||||||
|  |  | ||||||
| namespace VideoCommon { | namespace VideoCommon { | ||||||
|  |  | ||||||
| GPUSynch::GPUSynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, | GPUSynch::GPUSynch(Core::System& system) : GPU{system, false} {} | ||||||
|                    std::unique_ptr<Core::Frontend::GraphicsContext>&& context) |  | ||||||
|     : GPU(system, std::move(renderer), false), context{std::move(context)} {} |  | ||||||
|  |  | ||||||
| GPUSynch::~GPUSynch() = default; | GPUSynch::~GPUSynch() = default; | ||||||
|  |  | ||||||
| void GPUSynch::Start() {} | void GPUSynch::Start() {} | ||||||
|  |  | ||||||
| void GPUSynch::ObtainContext() { | void GPUSynch::ObtainContext() { | ||||||
|     context->MakeCurrent(); |     renderer->Context().MakeCurrent(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GPUSynch::ReleaseContext() { | void GPUSynch::ReleaseContext() { | ||||||
|     context->DoneCurrent(); |     renderer->Context().DoneCurrent(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { | void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { | ||||||
|   | |||||||
| @@ -19,8 +19,7 @@ namespace VideoCommon { | |||||||
| /// Implementation of GPU interface that runs the GPU synchronously | /// Implementation of GPU interface that runs the GPU synchronously | ||||||
| class GPUSynch final : public Tegra::GPU { | class GPUSynch final : public Tegra::GPU { | ||||||
| public: | public: | ||||||
|     explicit GPUSynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer, |     explicit GPUSynch(Core::System& system); | ||||||
|                       std::unique_ptr<Core::Frontend::GraphicsContext>&& context); |  | ||||||
|     ~GPUSynch() override; |     ~GPUSynch() override; | ||||||
|  |  | ||||||
|     void Start() override; |     void Start() override; | ||||||
| @@ -36,9 +35,6 @@ public: | |||||||
| protected: | protected: | ||||||
|     void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, |     void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, | ||||||
|                              [[maybe_unused]] u32 value) const override {} |                              [[maybe_unused]] u32 value) const override {} | ||||||
|  |  | ||||||
| private: |  | ||||||
|     std::unique_ptr<Core::Frontend::GraphicsContext> context; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace VideoCommon | } // namespace VideoCommon | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||||||
|     maxwell3d.regs.index_array.first = parameters[4]; |     maxwell3d.regs.index_array.first = parameters[4]; | ||||||
|  |  | ||||||
|     if (maxwell3d.ShouldExecute()) { |     if (maxwell3d.ShouldExecute()) { | ||||||
|         maxwell3d.GetRasterizer().Draw(true, true); |         maxwell3d.Rasterizer().Draw(true, true); | ||||||
|     } |     } | ||||||
|     maxwell3d.regs.index_array.count = 0; |     maxwell3d.regs.index_array.count = 0; | ||||||
|     maxwell3d.mme_draw.instance_count = 0; |     maxwell3d.mme_draw.instance_count = 0; | ||||||
| @@ -42,7 +42,7 @@ void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||||||
|     maxwell3d.mme_draw.instance_count = count; |     maxwell3d.mme_draw.instance_count = count; | ||||||
|  |  | ||||||
|     if (maxwell3d.ShouldExecute()) { |     if (maxwell3d.ShouldExecute()) { | ||||||
|         maxwell3d.GetRasterizer().Draw(false, true); |         maxwell3d.Rasterizer().Draw(false, true); | ||||||
|     } |     } | ||||||
|     maxwell3d.regs.vertex_buffer.count = 0; |     maxwell3d.regs.vertex_buffer.count = 0; | ||||||
|     maxwell3d.mme_draw.instance_count = 0; |     maxwell3d.mme_draw.instance_count = 0; | ||||||
| @@ -65,7 +65,7 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||||||
|     maxwell3d.regs.draw.topology.Assign( |     maxwell3d.regs.draw.topology.Assign( | ||||||
|         static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); |         static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); | ||||||
|     if (maxwell3d.ShouldExecute()) { |     if (maxwell3d.ShouldExecute()) { | ||||||
|         maxwell3d.GetRasterizer().Draw(true, true); |         maxwell3d.Rasterizer().Draw(true, true); | ||||||
|     } |     } | ||||||
|     maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? |     maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? | ||||||
|     maxwell3d.regs.index_array.count = 0; |     maxwell3d.regs.index_array.count = 0; | ||||||
|   | |||||||
| @@ -14,11 +14,15 @@ | |||||||
|  |  | ||||||
| namespace Tegra { | namespace Tegra { | ||||||
|  |  | ||||||
| MemoryManager::MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | MemoryManager::MemoryManager(Core::System& system_) | ||||||
|     : system{system}, rasterizer{rasterizer}, page_table(page_table_size) {} |     : system{system_}, page_table(page_table_size) {} | ||||||
|  |  | ||||||
| MemoryManager::~MemoryManager() = default; | MemoryManager::~MemoryManager() = default; | ||||||
|  |  | ||||||
|  | void MemoryManager::BindRasterizer(VideoCore::RasterizerInterface& rasterizer_) { | ||||||
|  |     rasterizer = &rasterizer_; | ||||||
|  | } | ||||||
|  |  | ||||||
| GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size) { | GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size) { | ||||||
|     u64 remaining_size{size}; |     u64 remaining_size{size}; | ||||||
|     for (u64 offset{}; offset < size; offset += page_size) { |     for (u64 offset{}; offset < size; offset += page_size) { | ||||||
| @@ -217,7 +221,7 @@ void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::siz | |||||||
|  |  | ||||||
|             // Flush must happen on the rasterizer interface, such that memory is always synchronous |             // Flush must happen on the rasterizer interface, such that memory is always synchronous | ||||||
|             // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. |             // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. | ||||||
|             rasterizer.FlushRegion(src_addr, copy_amount); |             rasterizer->FlushRegion(src_addr, copy_amount); | ||||||
|             system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); |             system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -266,7 +270,7 @@ void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, s | |||||||
|  |  | ||||||
|             // Invalidate must happen on the rasterizer interface, such that memory is always |             // Invalidate must happen on the rasterizer interface, such that memory is always | ||||||
|             // synchronous when it is written (even when in asynchronous GPU mode). |             // synchronous when it is written (even when in asynchronous GPU mode). | ||||||
|             rasterizer.InvalidateRegion(dest_addr, copy_amount); |             rasterizer->InvalidateRegion(dest_addr, copy_amount); | ||||||
|             system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); |             system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -68,9 +68,12 @@ static_assert(sizeof(PageEntry) == 4, "PageEntry is too large"); | |||||||
|  |  | ||||||
| class MemoryManager final { | class MemoryManager final { | ||||||
| public: | public: | ||||||
|     explicit MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer); |     explicit MemoryManager(Core::System& system); | ||||||
|     ~MemoryManager(); |     ~MemoryManager(); | ||||||
|  |  | ||||||
|  |     /// Binds a renderer to the memory manager. | ||||||
|  |     void BindRasterizer(VideoCore::RasterizerInterface& rasterizer); | ||||||
|  |  | ||||||
|     std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr) const; |     std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr) const; | ||||||
|  |  | ||||||
|     template <typename T> |     template <typename T> | ||||||
| @@ -141,7 +144,7 @@ private: | |||||||
|  |  | ||||||
|     Core::System& system; |     Core::System& system; | ||||||
|  |  | ||||||
|     VideoCore::RasterizerInterface& rasterizer; |     VideoCore::RasterizerInterface* rasterizer = nullptr; | ||||||
|  |  | ||||||
|     std::vector<PageEntry> page_table; |     std::vector<PageEntry> page_table; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -9,7 +9,9 @@ | |||||||
|  |  | ||||||
| namespace VideoCore { | namespace VideoCore { | ||||||
|  |  | ||||||
| RendererBase::RendererBase(Core::Frontend::EmuWindow& window) : render_window{window} { | RendererBase::RendererBase(Core::Frontend::EmuWindow& window_, | ||||||
|  |                            std::unique_ptr<Core::Frontend::GraphicsContext> context_) | ||||||
|  |     : render_window{window_}, context{std::move(context_)} { | ||||||
|     RefreshBaseSettings(); |     RefreshBaseSettings(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,8 @@ | |||||||
|  |  | ||||||
| namespace Core::Frontend { | namespace Core::Frontend { | ||||||
| class EmuWindow; | class EmuWindow; | ||||||
| } | class GraphicsContext; | ||||||
|  | } // namespace Core::Frontend | ||||||
|  |  | ||||||
| namespace VideoCore { | namespace VideoCore { | ||||||
|  |  | ||||||
| @@ -25,14 +26,15 @@ struct RendererSettings { | |||||||
|  |  | ||||||
|     // Screenshot |     // Screenshot | ||||||
|     std::atomic<bool> screenshot_requested{false}; |     std::atomic<bool> screenshot_requested{false}; | ||||||
|     void* screenshot_bits; |     void* screenshot_bits{}; | ||||||
|     std::function<void()> screenshot_complete_callback; |     std::function<void()> screenshot_complete_callback; | ||||||
|     Layout::FramebufferLayout screenshot_framebuffer_layout; |     Layout::FramebufferLayout screenshot_framebuffer_layout; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class RendererBase : NonCopyable { | class RendererBase : NonCopyable { | ||||||
| public: | public: | ||||||
|     explicit RendererBase(Core::Frontend::EmuWindow& window); |     explicit RendererBase(Core::Frontend::EmuWindow& window, | ||||||
|  |                           std::unique_ptr<Core::Frontend::GraphicsContext> context); | ||||||
|     virtual ~RendererBase(); |     virtual ~RendererBase(); | ||||||
|  |  | ||||||
|     /// Initialize the renderer |     /// Initialize the renderer | ||||||
| @@ -68,6 +70,14 @@ public: | |||||||
|         return *rasterizer; |         return *rasterizer; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     Core::Frontend::GraphicsContext& Context() { | ||||||
|  |         return *context; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const Core::Frontend::GraphicsContext& Context() const { | ||||||
|  |         return *context; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Core::Frontend::EmuWindow& GetRenderWindow() { |     Core::Frontend::EmuWindow& GetRenderWindow() { | ||||||
|         return render_window; |         return render_window; | ||||||
|     } |     } | ||||||
| @@ -94,6 +104,7 @@ public: | |||||||
| protected: | protected: | ||||||
|     Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. |     Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. | ||||||
|     std::unique_ptr<RasterizerInterface> rasterizer; |     std::unique_ptr<RasterizerInterface> rasterizer; | ||||||
|  |     std::unique_ptr<Core::Frontend::GraphicsContext> context; | ||||||
|     f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer |     f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer | ||||||
|     int m_current_frame = 0;  ///< Current frame, should be set by the renderer |     int m_current_frame = 0;  ///< Current frame, should be set by the renderer | ||||||
|  |  | ||||||
|   | |||||||
| @@ -313,10 +313,11 @@ public: | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, | RendererOpenGL::RendererOpenGL(Core::System& system_, Core::Frontend::EmuWindow& emu_window_, | ||||||
|                                Core::Frontend::GraphicsContext& context) |                                Tegra::GPU& gpu_, | ||||||
|     : RendererBase{emu_window}, emu_window{emu_window}, system{system}, context{context}, |                                std::unique_ptr<Core::Frontend::GraphicsContext> context_) | ||||||
|       program_manager{device}, has_debug_tool{HasDebugTool()} {} |     : RendererBase{emu_window_, std::move(context_)}, system{system_}, | ||||||
|  |       emu_window{emu_window_}, gpu{gpu_}, program_manager{device}, has_debug_tool{HasDebugTool()} {} | ||||||
|  |  | ||||||
| RendererOpenGL::~RendererOpenGL() = default; | RendererOpenGL::~RendererOpenGL() = default; | ||||||
|  |  | ||||||
| @@ -384,7 +385,7 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||||||
|     if (has_debug_tool) { |     if (has_debug_tool) { | ||||||
|         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | ||||||
|         Present(0); |         Present(0); | ||||||
|         context.SwapBuffers(); |         context->SwapBuffers(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -56,8 +56,9 @@ class FrameMailbox; | |||||||
|  |  | ||||||
| class RendererOpenGL final : public VideoCore::RendererBase { | class RendererOpenGL final : public VideoCore::RendererBase { | ||||||
| public: | public: | ||||||
|     explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, |     explicit RendererOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | ||||||
|                             Core::Frontend::GraphicsContext& context); |                             Tegra::GPU& gpu, | ||||||
|  |                             std::unique_ptr<Core::Frontend::GraphicsContext> context); | ||||||
|     ~RendererOpenGL() override; |     ~RendererOpenGL() override; | ||||||
|  |  | ||||||
|     bool Init() override; |     bool Init() override; | ||||||
| @@ -93,9 +94,9 @@ private: | |||||||
|  |  | ||||||
|     bool Present(int timeout_ms); |     bool Present(int timeout_ms); | ||||||
|  |  | ||||||
|     Core::Frontend::EmuWindow& emu_window; |  | ||||||
|     Core::System& system; |     Core::System& system; | ||||||
|     Core::Frontend::GraphicsContext& context; |     Core::Frontend::EmuWindow& emu_window; | ||||||
|  |     Tegra::GPU& gpu; | ||||||
|     const Device device; |     const Device device; | ||||||
|  |  | ||||||
|     StateTracker state_tracker{system}; |     StateTracker state_tracker{system}; | ||||||
| @@ -120,7 +121,7 @@ private: | |||||||
|     std::vector<u8> gl_framebuffer_data; |     std::vector<u8> gl_framebuffer_data; | ||||||
|  |  | ||||||
|     /// Used for transforming the framebuffer orientation |     /// Used for transforming the framebuffer orientation | ||||||
|     Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags; |     Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags{}; | ||||||
|     Common::Rectangle<int> framebuffer_crop_rect; |     Common::Rectangle<int> framebuffer_crop_rect; | ||||||
|  |  | ||||||
|     /// Frame presentation mailbox |     /// Frame presentation mailbox | ||||||
|   | |||||||
| @@ -237,8 +237,10 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext | |||||||
|  |  | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& window, Core::System& system) | RendererVulkan::RendererVulkan(Core::System& system_, Core::Frontend::EmuWindow& emu_window, | ||||||
|     : RendererBase(window), system{system} {} |                                Tegra::GPU& gpu_, | ||||||
|  |                                std::unique_ptr<Core::Frontend::GraphicsContext> context) | ||||||
|  |     : RendererBase{emu_window, std::move(context)}, system{system_}, gpu{gpu_} {} | ||||||
|  |  | ||||||
| RendererVulkan::~RendererVulkan() { | RendererVulkan::~RendererVulkan() { | ||||||
|     ShutDown(); |     ShutDown(); | ||||||
|   | |||||||
| @@ -38,7 +38,9 @@ struct VKScreenInfo { | |||||||
|  |  | ||||||
| class RendererVulkan final : public VideoCore::RendererBase { | class RendererVulkan final : public VideoCore::RendererBase { | ||||||
| public: | public: | ||||||
|     explicit RendererVulkan(Core::Frontend::EmuWindow& window, Core::System& system); |     explicit RendererVulkan(Core::System& system, Core::Frontend::EmuWindow& emu_window, | ||||||
|  |                             Tegra::GPU& gpu, | ||||||
|  |                             std::unique_ptr<Core::Frontend::GraphicsContext> context); | ||||||
|     ~RendererVulkan() override; |     ~RendererVulkan() override; | ||||||
|  |  | ||||||
|     bool Init() override; |     bool Init() override; | ||||||
| @@ -58,6 +60,7 @@ private: | |||||||
|     void Report() const; |     void Report() const; | ||||||
|  |  | ||||||
|     Core::System& system; |     Core::System& system; | ||||||
|  |     Tegra::GPU& gpu; | ||||||
|  |  | ||||||
|     Common::DynamicLibrary library; |     Common::DynamicLibrary library; | ||||||
|     vk::InstanceDispatch dld; |     vk::InstanceDispatch dld; | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| // Refer to the license.txt file included. | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
| #include <memory> | #include <memory> | ||||||
|  |  | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
| @@ -16,37 +17,46 @@ | |||||||
| #include "video_core/video_core.h" | #include "video_core/video_core.h" | ||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
| std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window, |  | ||||||
|                                                         Core::System& system, | std::unique_ptr<VideoCore::RendererBase> CreateRenderer( | ||||||
|                                                         Core::Frontend::GraphicsContext& context) { |     Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, | ||||||
|  |     std::unique_ptr<Core::Frontend::GraphicsContext> context) { | ||||||
|     switch (Settings::values.renderer_backend.GetValue()) { |     switch (Settings::values.renderer_backend.GetValue()) { | ||||||
|     case Settings::RendererBackend::OpenGL: |     case Settings::RendererBackend::OpenGL: | ||||||
|         return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system, context); |         return std::make_unique<OpenGL::RendererOpenGL>(system, emu_window, gpu, | ||||||
|  |                                                         std::move(context)); | ||||||
| #ifdef HAS_VULKAN | #ifdef HAS_VULKAN | ||||||
|     case Settings::RendererBackend::Vulkan: |     case Settings::RendererBackend::Vulkan: | ||||||
|         return std::make_unique<Vulkan::RendererVulkan>(emu_window, system); |         return std::make_unique<Vulkan::RendererVulkan>(system, emu_window, gpu, | ||||||
|  |                                                         std::move(context)); | ||||||
| #endif | #endif | ||||||
|     default: |     default: | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| namespace VideoCore { | namespace VideoCore { | ||||||
|  |  | ||||||
| std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Core::System& system) { | std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Core::System& system) { | ||||||
|  |     std::unique_ptr<Tegra::GPU> gpu; | ||||||
|  |     if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { | ||||||
|  |         gpu = std::make_unique<VideoCommon::GPUAsynch>(system); | ||||||
|  |     } else { | ||||||
|  |         gpu = std::make_unique<VideoCommon::GPUSynch>(system); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     auto context = emu_window.CreateSharedContext(); |     auto context = emu_window.CreateSharedContext(); | ||||||
|     const auto scope = context->Acquire(); |     const auto scope = context->Acquire(); | ||||||
|     auto renderer = CreateRenderer(emu_window, system, *context); |  | ||||||
|  |     auto renderer = CreateRenderer(system, emu_window, *gpu, std::move(context)); | ||||||
|     if (!renderer->Init()) { |     if (!renderer->Init()) { | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { |     gpu->BindRenderer(std::move(renderer)); | ||||||
|         return std::make_unique<VideoCommon::GPUAsynch>(system, std::move(renderer), |     return gpu; | ||||||
|                                                         std::move(context)); |  | ||||||
|     } |  | ||||||
|     return std::make_unique<VideoCommon::GPUSynch>(system, std::move(renderer), std::move(context)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| u16 GetResolutionScaleFactor(const RendererBase& renderer) { | u16 GetResolutionScaleFactor(const RendererBase& renderer) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user