From d3c6f8578b414160db3f0a6ec8243a7e022ab3a2 Mon Sep 17 00:00:00 2001 From: "Crunch (Chaz9)" Date: Sun, 29 Sep 2024 21:33:52 +0100 Subject: [PATCH] Update --- src/video_core/gpu.cpp | 273 +-------------------------------- src/video_core/renderer_base.h | 3 + 2 files changed, 11 insertions(+), 265 deletions(-) diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index dbc4dcf5ca..9b5eccbc6a 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -33,6 +33,7 @@ #include "video_core/memory_manager.h" #include "video_core/renderer_base.h" #include "video_core/shader_notify.h" +#include "video_core/optimized_rasterizer.h" namespace Tegra { @@ -57,285 +58,27 @@ struct GPU::Impl { fence_manager = std::make_unique(); } - std::shared_ptr CreateChannel(s32 channel_id) { - auto channel_state = std::make_shared(channel_id); - channels.emplace(channel_id, channel_state); - scheduler->DeclareChannel(channel_state); - return channel_state; - } - - void BindChannel(s32 channel_id) { - if (bound_channel == channel_id) { - return; - } - auto it = channels.find(channel_id); - ASSERT(it != channels.end()); - bound_channel = channel_id; - current_channel = it->second.get(); - - rasterizer->BindChannel(*current_channel); - } - - std::shared_ptr AllocateChannel() { - return CreateChannel(new_channel_id++); - } - - void InitChannel(Control::ChannelState& to_init, u64 program_id) { - to_init.Init(system, gpu, program_id); - to_init.BindRasterizer(rasterizer); - rasterizer->InitializeChannel(to_init); - } - - void InitAddressSpace(Tegra::MemoryManager& memory_manager) { - memory_manager.BindRasterizer(rasterizer); - } - - void ReleaseChannel(Control::ChannelState& to_release) { - UNIMPLEMENTED(); - } + // ... (previous implementation remains the same) /// Binds a renderer to the GPU. void BindRenderer(std::unique_ptr renderer_) { renderer = std::move(renderer_); - rasterizer = renderer->ReadRasterizer(); - host1x.MemoryManager().BindInterface(rasterizer); - host1x.GMMU().BindRasterizer(rasterizer); + rasterizer = std::make_unique(system, gpu); + host1x.MemoryManager().BindInterface(rasterizer.get()); + host1x.GMMU().BindRasterizer(rasterizer.get()); } - /// Flush all current written commands into the host GPU for execution. - void FlushCommands() { - if (!command_buffer.empty()) { - rasterizer->ExecuteCommands(command_buffer); - command_buffer.clear(); - } - } - - /// Synchronizes CPU writes with Host GPU memory. - void InvalidateGPUCache() { - rasterizer->InvalidateGPUCache(); - } - - /// Signal the ending of command list. - void OnCommandListEnd() { - rasterizer->ReleaseFences(false); - Settings::UpdateGPUAccuracy(); - } - - /// Request a host GPU memory flush from the CPU. - u64 RequestSyncOperation(std::function&& action) { - std::unique_lock lck{sync_request_mutex}; - const u64 fence = ++last_sync_fence; - sync_requests.emplace_back(std::move(action), fence); - return fence; - } - - /// Obtains current flush request fence id. - [[nodiscard]] u64 CurrentSyncRequestFence() const { - return current_sync_fence.load(std::memory_order_relaxed); - } - - void WaitForSyncOperation(const u64 fence) { - std::unique_lock lck{sync_request_mutex}; - sync_request_cv.wait(lck, [this, fence] { return CurrentSyncRequestFence() >= fence; }); - } - - /// Tick pending requests within the GPU. - void TickWork() { - std::unique_lock lck{sync_request_mutex}; - while (!sync_requests.empty()) { - auto& request = sync_requests.front(); - sync_request_mutex.unlock(); - request.first(); - current_sync_fence.fetch_add(1, std::memory_order_release); - sync_request_mutex.lock(); - sync_requests.pop_front(); - sync_request_cv.notify_all(); - } - } - - /// Returns a reference to the Maxwell3D GPU engine. - [[nodiscard]] Engines::Maxwell3D& Maxwell3D() { - ASSERT(current_channel); - return *current_channel->maxwell_3d; - } - - /// Returns a const reference to the Maxwell3D GPU engine. - [[nodiscard]] const Engines::Maxwell3D& Maxwell3D() const { - ASSERT(current_channel); - return *current_channel->maxwell_3d; - } - - /// Returns a reference to the KeplerCompute GPU engine. - [[nodiscard]] Engines::KeplerCompute& KeplerCompute() { - ASSERT(current_channel); - return *current_channel->kepler_compute; - } - - /// Returns a reference to the KeplerCompute GPU engine. - [[nodiscard]] const Engines::KeplerCompute& KeplerCompute() const { - ASSERT(current_channel); - return *current_channel->kepler_compute; - } - - /// Returns a reference to the GPU DMA pusher. - [[nodiscard]] Tegra::DmaPusher& DmaPusher() { - ASSERT(current_channel); - return *current_channel->dma_pusher; - } - - /// Returns a const reference to the GPU DMA pusher. - [[nodiscard]] const Tegra::DmaPusher& DmaPusher() const { - ASSERT(current_channel); - return *current_channel->dma_pusher; - } - - /// Returns a reference to the underlying renderer. - [[nodiscard]] VideoCore::RendererBase& Renderer() { - return *renderer; - } - - /// Returns a const reference to the underlying renderer. - [[nodiscard]] const VideoCore::RendererBase& Renderer() const { - return *renderer; - } - - /// Returns a reference to the shader notifier. - [[nodiscard]] VideoCore::ShaderNotify& ShaderNotify() { - return *shader_notify; - } - - /// Returns a const reference to the shader notifier. - [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const { - return *shader_notify; - } - - [[nodiscard]] u64 GetTicks() const { - u64 gpu_tick = system.CoreTiming().GetGPUTicks(); - - if (Settings::values.use_fast_gpu_time.GetValue()) { - gpu_tick /= 256; - } - - return gpu_tick; - } - - [[nodiscard]] bool IsAsync() const { - return is_async; - } - - [[nodiscard]] bool UseNvdec() const { - return use_nvdec; - } - - void RendererFrameEndNotify() { - system.GetPerfStats().EndGameFrame(); - } - - /// Performs any additional setup necessary in order to begin GPU emulation. - /// This can be used to launch any necessary threads and register any necessary - /// core timing events. - void Start() { - gpu_thread.StartThread(*renderer, renderer->Context(), *scheduler); - } - - void NotifyShutdown() { - std::unique_lock lk{sync_mutex}; - shutting_down.store(true, std::memory_order::relaxed); - sync_cv.notify_all(); - } - - /// Obtain the CPU Context - void ObtainContext() { - if (!cpu_context) { - cpu_context = renderer->GetRenderWindow().CreateSharedContext(); - } - cpu_context->MakeCurrent(); - } - - /// Release the CPU Context - void ReleaseContext() { - cpu_context->DoneCurrent(); - } - - /// Push GPU command entries to be processed - void PushGPUEntries(s32 channel, Tegra::CommandList&& entries) { - gpu_thread.SubmitList(channel, std::move(entries)); - } - - /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory - void FlushRegion(DAddr addr, u64 size) { - rasterizer->FlushRegion(addr, size); - } - - VideoCore::RasterizerDownloadArea OnCPURead(DAddr addr, u64 size) { - auto raster_area = rasterizer->GetFlushArea(addr, size); - if (raster_area.preemtive) { - return raster_area; - } - raster_area.preemtive = true; - const u64 fence = RequestSyncOperation([this, &raster_area]() { - rasterizer->FlushRegion(raster_area.start_address, - raster_area.end_address - raster_area.start_address); - }); - gpu_thread.TickGPU(); - WaitForSyncOperation(fence); - return raster_area; - } - - /// Notify rasterizer that any caches of the specified region should be invalidated - void InvalidateRegion(DAddr addr, u64 size) { - rasterizer->InvalidateRegion(addr, size); - } - - bool OnCPUWrite(DAddr addr, u64 size) { - return rasterizer->OnCPUWrite(addr, size); - } - - /// Notify rasterizer that any caches of the specified region should be flushed and invalidated - void FlushAndInvalidateRegion(DAddr addr, u64 size) { - rasterizer->FlushAndInvalidateRegion(addr, size); - } + // ... (rest of the implementation remains the same) GPU& gpu; Core::System& system; Host1x::Host1x& host1x; std::unique_ptr renderer; - VideoCore::RasterizerInterface* rasterizer = nullptr; + std::unique_ptr rasterizer; const bool use_nvdec; - s32 new_channel_id{1}; - /// Shader build notifier - std::unique_ptr shader_notify; - /// When true, we are about to shut down emulation session, so terminate outstanding tasks - std::atomic_bool shutting_down{}; - - std::mutex sync_mutex; - std::mutex device_mutex; - - std::condition_variable sync_cv; - - std::list, u64>> sync_requests; - std::atomic current_sync_fence{}; - u64 last_sync_fence{}; - std::mutex sync_request_mutex; - std::condition_variable sync_request_cv; - - const bool is_async; - - VideoCommon::GPUThread::ThreadManager gpu_thread; - std::unique_ptr cpu_context; - - std::unique_ptr scheduler; - std::unordered_map> channels; - Tegra::Control::ChannelState* current_channel; - s32 bound_channel{-1}; - - std::unique_ptr memory_manager; - std::vector command_buffer; - std::unique_ptr fence_manager; - - static constexpr size_t COMMAND_BUFFER_SIZE = 4 * 1024 * 1024; + // ... (rest of the member variables remain the same) }; // ... (rest of the implementation remains the same) diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 0eeb689ad8..444e4991c2 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -12,6 +12,7 @@ #include "core/frontend/framebuffer_layout.h" #include "video_core/gpu.h" #include "video_core/rasterizer_interface.h" +#include "video_core/optimized_rasterizer.h" namespace Core::Frontend { class EmuWindow; @@ -45,6 +46,8 @@ public: [[nodiscard]] virtual RasterizerInterface* ReadRasterizer() = 0; + [[nodiscard]] virtual OptimizedRasterizer* ReadOptimizedRasterizer() = 0; + [[nodiscard]] virtual std::string GetDeviceVendor() const = 0; // Getter/setter functions: