duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

gpu_backend.h (3207B)


      1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #pragma once
      5 
      6 #include "gpu_types.h"
      7 
      8 #include "common/heap_array.h"
      9 #include "common/threading.h"
     10 
     11 #include <atomic>
     12 #include <condition_variable>
     13 #include <memory>
     14 #include <mutex>
     15 
     16 #ifdef _MSC_VER
     17 #pragma warning(push)
     18 #pragma warning(disable : 4324) // warning C4324: 'GPUBackend': structure was padded due to alignment specifier
     19 #endif
     20 
     21 class GPUBackend
     22 {
     23 public:
     24   GPUBackend();
     25   virtual ~GPUBackend();
     26 
     27   ALWAYS_INLINE const Threading::Thread* GetThread() const { return m_use_gpu_thread ? &m_gpu_thread : nullptr; }
     28 
     29   virtual bool Initialize(bool force_thread);
     30   virtual void UpdateSettings();
     31   virtual void Reset();
     32   virtual void Shutdown();
     33 
     34   GPUBackendFillVRAMCommand* NewFillVRAMCommand();
     35   GPUBackendUpdateVRAMCommand* NewUpdateVRAMCommand(u32 num_words);
     36   GPUBackendCopyVRAMCommand* NewCopyVRAMCommand();
     37   GPUBackendSetDrawingAreaCommand* NewSetDrawingAreaCommand();
     38   GPUBackendUpdateCLUTCommand* NewUpdateCLUTCommand();
     39   GPUBackendDrawPolygonCommand* NewDrawPolygonCommand(u32 num_vertices);
     40   GPUBackendDrawRectangleCommand* NewDrawRectangleCommand();
     41   GPUBackendDrawLineCommand* NewDrawLineCommand(u32 num_vertices);
     42 
     43   void PushCommand(GPUBackendCommand* cmd);
     44   void Sync(bool allow_sleep);
     45 
     46   /// Processes all pending GPU commands.
     47   void RunGPULoop();
     48 
     49 protected:
     50   void* AllocateCommand(GPUBackendCommandType command, u32 size);
     51   u32 GetPendingCommandSize() const;
     52   void WakeGPUThread();
     53   void StartGPUThread();
     54   void StopGPUThread();
     55 
     56   virtual void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color, GPUBackendCommandParameters params) = 0;
     57   virtual void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data,
     58                           GPUBackendCommandParameters params) = 0;
     59   virtual void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height,
     60                         GPUBackendCommandParameters params) = 0;
     61   virtual void DrawPolygon(const GPUBackendDrawPolygonCommand* cmd) = 0;
     62   virtual void DrawRectangle(const GPUBackendDrawRectangleCommand* cmd) = 0;
     63   virtual void DrawLine(const GPUBackendDrawLineCommand* cmd) = 0;
     64   virtual void FlushRender() = 0;
     65   virtual void DrawingAreaChanged() = 0;
     66   virtual void UpdateCLUT(GPUTexturePaletteReg reg, bool clut_is_8bit) = 0;
     67 
     68   void HandleCommand(const GPUBackendCommand* cmd);
     69 
     70   GPUDrawingArea m_drawing_area = {};
     71 
     72   Threading::KernelSemaphore m_sync_semaphore;
     73   std::atomic_bool m_gpu_thread_sleeping{false};
     74   std::atomic_bool m_gpu_loop_done{false};
     75   Threading::Thread m_gpu_thread;
     76   bool m_use_gpu_thread = false;
     77 
     78   std::mutex m_sync_mutex;
     79   std::condition_variable m_sync_cpu_thread_cv;
     80   std::condition_variable m_wake_gpu_thread_cv;
     81   bool m_sync_done = false;
     82 
     83   enum : u32
     84   {
     85     COMMAND_QUEUE_SIZE = 4 * 1024 * 1024,
     86     THRESHOLD_TO_WAKE_GPU = 256
     87   };
     88 
     89   FixedHeapArray<u8, COMMAND_QUEUE_SIZE> m_command_fifo_data;
     90   alignas(HOST_CACHE_LINE_SIZE) std::atomic<u32> m_command_fifo_read_ptr{0};
     91   alignas(HOST_CACHE_LINE_SIZE) std::atomic<u32> m_command_fifo_write_ptr{0};
     92 };
     93 
     94 #ifdef _MSC_VER
     95 #pragma warning(pop)
     96 #endif