GPUThread: Add BeginASyncBufferCall()

This commit is contained in:
Stenzek 2025-01-13 16:08:20 +10:00
parent 462a4a3b50
commit 3476140ba2
No known key found for this signature in database
4 changed files with 29 additions and 15 deletions

View File

@ -103,6 +103,7 @@ char (&__countof_ArraySizeHelper(T (&array)[N]))[N];
// disable warnings that show up at warning level 4 // disable warnings that show up at warning level 4
// TODO: Move to build system instead // TODO: Move to build system instead
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4200) // warning C4200: nonstandard extension used: zero-sized array in struct/union
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union #pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union
#pragma warning(disable : 4100) // warning C4100: 'Platform' : unreferenced formal parameter #pragma warning(disable : 4100) // warning C4100: 'Platform' : unreferenced formal parameter
#pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list #pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list

View File

@ -61,6 +61,8 @@ static bool Reconfigure(std::string serial, std::optional<GPURenderer> renderer,
// NOTE: Use with care! The handler needs to manually run the destructor. // NOTE: Use with care! The handler needs to manually run the destructor.
template<class T, typename... Args> template<class T, typename... Args>
T* AllocateCommand(u32 size, GPUBackendCommandType type, Args... args);
template<class T, typename... Args>
T* AllocateCommand(GPUBackendCommandType type, Args... args); T* AllocateCommand(GPUBackendCommandType type, Args... args);
static u32 GetPendingCommandSize(); static u32 GetPendingCommandSize();
@ -248,21 +250,27 @@ GPUThreadCommand* GPUThread::AllocateCommand(GPUBackendCommandType command, u32
} }
template<class T, typename... Args> template<class T, typename... Args>
T* GPUThread::AllocateCommand(GPUBackendCommandType command, Args... args) T* GPUThread::AllocateCommand(u32 size, GPUBackendCommandType type, Args... args)
{ {
const u32 size = GPUThreadCommand::AlignCommandSize(sizeof(T)); const u32 alloc_size = GPUThreadCommand::AlignCommandSize(size);
GPUThreadCommand* cmd = AllocateCommand(command, size); GPUThreadCommand* cmd = AllocateCommand(type, alloc_size);
DebugAssert(cmd->size == size); DebugAssert(cmd->size == alloc_size);
new (cmd) T(std::forward<Args>(args)...); new (cmd) T(std::forward<Args>(args)...);
// constructor may overwrite the fields, need to reset them // constructor may overwrite the fields, need to reset them
cmd->type = command; cmd->type = type;
cmd->size = size; cmd->size = alloc_size;
return static_cast<T*>(cmd); return static_cast<T*>(cmd);
} }
template<class T, typename... Args>
T* GPUThread::AllocateCommand(GPUBackendCommandType type, Args... args)
{
return AllocateCommand<T>(sizeof(T), type, std::forward<Args>(args)...);
}
u32 GPUThread::GetPendingCommandSize() u32 GPUThread::GetPendingCommandSize()
{ {
const u32 read_ptr = s_state.command_fifo_read_ptr.load(std::memory_order_acquire); const u32 read_ptr = s_state.command_fifo_read_ptr.load(std::memory_order_acquire);
@ -995,6 +1003,16 @@ void GPUThread::RunOnBackend(AsyncBackendCallType func, bool sync, bool spin_or_
PushCommand(cmd); PushCommand(cmd);
} }
std::pair<GPUThreadCommand*, void*> GPUThread::BeginASyncBufferCall(AsyncBufferCallType func, u32 buffer_size)
{
// this is less than optimal, but it's only used for input osd updates currently, so whatever
GPUThreadAsyncCallCommand* const cmd = AllocateCommand<GPUThreadAsyncCallCommand>(
sizeof(GPUThreadAsyncCallCommand) + buffer_size, GPUBackendCommandType::AsyncCall);
void* const buffer = static_cast<void*>(cmd + 1);
cmd->func = [func, buffer]() { func(buffer); };
return std::make_pair(static_cast<GPUThreadCommand*>(cmd), buffer);
}
void GPUThread::UpdateSettings(bool gpu_settings_changed, bool device_settings_changed) void GPUThread::UpdateSettings(bool gpu_settings_changed, bool device_settings_changed)
{ {
if (device_settings_changed) if (device_settings_changed)

View File

@ -7,6 +7,7 @@
#include <functional> #include <functional>
#include <optional> #include <optional>
#include <utility>
class Error; class Error;
struct WindowInfo; struct WindowInfo;
@ -28,6 +29,7 @@ struct GPUBackendUpdateDisplayCommand;
namespace GPUThread { namespace GPUThread {
using AsyncCallType = std::function<void()>; using AsyncCallType = std::function<void()>;
using AsyncBackendCallType = std::function<void(GPUBackend*)>; using AsyncBackendCallType = std::function<void(GPUBackend*)>;
using AsyncBufferCallType = void(*)(void*);
enum class RunIdleReason : u8 enum class RunIdleReason : u8
{ {
@ -70,6 +72,7 @@ bool IsOnThread();
bool IsUsingThread(); bool IsUsingThread();
void RunOnThread(AsyncCallType func); void RunOnThread(AsyncCallType func);
void RunOnBackend(AsyncBackendCallType func, bool sync, bool spin_or_wake); void RunOnBackend(AsyncBackendCallType func, bool sync, bool spin_or_wake);
std::pair<GPUThreadCommand*, void*> BeginASyncBufferCall(AsyncBufferCallType func, u32 buffer_size);
void SetVSync(GPUVSyncMode mode, bool allow_present_throttle); void SetVSync(GPUVSyncMode mode, bool allow_present_throttle);
// Should only be called on the GPU thread. // Should only be called on the GPU thread.

View File

@ -23,11 +23,6 @@ namespace System {
struct MemorySaveState; struct MemorySaveState;
} }
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4200) // warning C4200: nonstandard extension used: zero-sized array in struct/union
#endif
enum class GPUBackendCommandType : u8 enum class GPUBackendCommandType : u8
{ {
Wraparound, Wraparound,
@ -87,6 +82,7 @@ struct GPUThreadReconfigureCommand : public GPUThreadCommand
struct GPUThreadAsyncCallCommand : public GPUThreadCommand struct GPUThreadAsyncCallCommand : public GPUThreadCommand
{ {
GPUThreadAsyncCallCommand() = default;
GPUThreadAsyncCallCommand(std::function<void()> func_) : func(std::move(func_)) {} GPUThreadAsyncCallCommand(std::function<void()> func_) : func(std::move(func_)) {}
std::function<void()> func; std::function<void()> func;
@ -329,7 +325,3 @@ struct GPUBackendDrawPreciseLineCommand : public GPUBackendDrawCommand
Vertex vertices[0]; Vertex vertices[0];
}; };
#ifdef _MSC_VER
#pragma warning(pop)
#endif