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