GPU/Software: Ensure commands are always aligned to 4 bytes

This commit is contained in:
Connor McLaughlin 2020-12-08 23:35:25 +10:00
parent e340963c99
commit 419736aaee
3 changed files with 28 additions and 52 deletions

View file

@ -1,4 +1,5 @@
#include "gpu_backend.h" #include "gpu_backend.h"
#include "common/align.h"
#include "common/log.h" #include "common/log.h"
#include "common/state_wrapper.h" #include "common/state_wrapper.h"
#include "settings.h" #include "settings.h"
@ -44,71 +45,59 @@ void GPUBackend::Shutdown()
GPUBackendFillVRAMCommand* GPUBackend::NewFillVRAMCommand() GPUBackendFillVRAMCommand* GPUBackend::NewFillVRAMCommand()
{ {
GPUBackendFillVRAMCommand* cmd = return static_cast<GPUBackendFillVRAMCommand*>(
static_cast<GPUBackendFillVRAMCommand*>(AllocateCommand(sizeof(GPUBackendFillVRAMCommand))); AllocateCommand(GPUBackendCommandType::FillVRAM, sizeof(GPUBackendFillVRAMCommand)));
cmd->type = GPUBackendCommandType::FillVRAM;
cmd->size = cmd->Size();
return cmd;
} }
GPUBackendUpdateVRAMCommand* GPUBackend::NewUpdateVRAMCommand(u32 num_words) GPUBackendUpdateVRAMCommand* GPUBackend::NewUpdateVRAMCommand(u32 num_words)
{ {
const u32 size = sizeof(GPUBackendUpdateVRAMCommand) + (num_words * sizeof(u16)); const u32 size = sizeof(GPUBackendUpdateVRAMCommand) + (num_words * sizeof(u16));
GPUBackendUpdateVRAMCommand* cmd = static_cast<GPUBackendUpdateVRAMCommand*>(AllocateCommand(size)); GPUBackendUpdateVRAMCommand* cmd =
cmd->type = GPUBackendCommandType::UpdateVRAM; static_cast<GPUBackendUpdateVRAMCommand*>(AllocateCommand(GPUBackendCommandType::UpdateVRAM, size));
cmd->size = size;
return cmd; return cmd;
} }
GPUBackendCopyVRAMCommand* GPUBackend::NewCopyVRAMCommand() GPUBackendCopyVRAMCommand* GPUBackend::NewCopyVRAMCommand()
{ {
GPUBackendCopyVRAMCommand* cmd = return static_cast<GPUBackendCopyVRAMCommand*>(
static_cast<GPUBackendCopyVRAMCommand*>(AllocateCommand(sizeof(GPUBackendCopyVRAMCommand))); AllocateCommand(GPUBackendCommandType::CopyVRAM, sizeof(GPUBackendCopyVRAMCommand)));
cmd->type = GPUBackendCommandType::CopyVRAM;
cmd->size = cmd->Size();
return cmd;
} }
GPUBackendSetDrawingAreaCommand* GPUBackend::NewSetDrawingAreaCommand() GPUBackendSetDrawingAreaCommand* GPUBackend::NewSetDrawingAreaCommand()
{ {
GPUBackendSetDrawingAreaCommand* cmd = return static_cast<GPUBackendSetDrawingAreaCommand*>(
static_cast<GPUBackendSetDrawingAreaCommand*>(AllocateCommand(sizeof(GPUBackendSetDrawingAreaCommand))); AllocateCommand(GPUBackendCommandType::SetDrawingArea, sizeof(GPUBackendSetDrawingAreaCommand)));
cmd->type = GPUBackendCommandType::SetDrawingArea;
cmd->size = cmd->Size();
return cmd;
} }
GPUBackendDrawPolygonCommand* GPUBackend::NewDrawPolygonCommand(u32 num_vertices) GPUBackendDrawPolygonCommand* GPUBackend::NewDrawPolygonCommand(u32 num_vertices)
{ {
const u32 size = sizeof(GPUBackendDrawPolygonCommand) + (num_vertices * sizeof(GPUBackendDrawPolygonCommand::Vertex)); const u32 size = sizeof(GPUBackendDrawPolygonCommand) + (num_vertices * sizeof(GPUBackendDrawPolygonCommand::Vertex));
GPUBackendDrawPolygonCommand* cmd = static_cast<GPUBackendDrawPolygonCommand*>(AllocateCommand(size)); GPUBackendDrawPolygonCommand* cmd =
cmd->type = GPUBackendCommandType::DrawPolygon; static_cast<GPUBackendDrawPolygonCommand*>(AllocateCommand(GPUBackendCommandType::DrawPolygon, size));
cmd->size = size;
cmd->num_vertices = Truncate16(num_vertices); cmd->num_vertices = Truncate16(num_vertices);
return cmd; return cmd;
} }
GPUBackendDrawRectangleCommand* GPUBackend::NewDrawRectangleCommand() GPUBackendDrawRectangleCommand* GPUBackend::NewDrawRectangleCommand()
{ {
GPUBackendDrawRectangleCommand* cmd = return static_cast<GPUBackendDrawRectangleCommand*>(
static_cast<GPUBackendDrawRectangleCommand*>(AllocateCommand(sizeof(GPUBackendDrawRectangleCommand))); AllocateCommand(GPUBackendCommandType::DrawRectangle, sizeof(GPUBackendDrawRectangleCommand)));
cmd->type = GPUBackendCommandType::DrawRectangle;
cmd->size = cmd->Size();
return cmd;
} }
GPUBackendDrawLineCommand* GPUBackend::NewDrawLineCommand(u32 num_vertices) GPUBackendDrawLineCommand* GPUBackend::NewDrawLineCommand(u32 num_vertices)
{ {
const u32 size = sizeof(GPUBackendDrawLineCommand) + (num_vertices * sizeof(GPUBackendDrawLineCommand::Vertex)); const u32 size = sizeof(GPUBackendDrawLineCommand) + (num_vertices * sizeof(GPUBackendDrawLineCommand::Vertex));
GPUBackendDrawLineCommand* cmd = static_cast<GPUBackendDrawLineCommand*>(AllocateCommand(size)); GPUBackendDrawLineCommand* cmd =
cmd->type = GPUBackendCommandType::DrawLine; static_cast<GPUBackendDrawLineCommand*>(AllocateCommand(GPUBackendCommandType::DrawLine, size));
cmd->size = size;
cmd->num_vertices = Truncate16(num_vertices); cmd->num_vertices = Truncate16(num_vertices);
return cmd; return cmd;
} }
void* GPUBackend::AllocateCommand(u32 size) void* GPUBackend::AllocateCommand(GPUBackendCommandType command, u32 size)
{ {
// Ensure size is a multiple of 4 so we don't end up with an unaligned command.
size = Common::AlignUpPow2(size, 4);
for (;;) for (;;)
{ {
u32 read_ptr = m_command_fifo_read_ptr.load(); u32 read_ptr = m_command_fifo_read_ptr.load();
@ -138,7 +127,10 @@ void* GPUBackend::AllocateCommand(u32 size)
} }
} }
return &m_command_fifo_data[write_ptr]; GPUBackendCommand* cmd = reinterpret_cast<GPUBackendCommand*>(&m_command_fifo_data[write_ptr]);
cmd->type = command;
cmd->size = size;
return cmd;
} }
} }
@ -200,9 +192,8 @@ void GPUBackend::Sync()
if (!m_use_gpu_thread) if (!m_use_gpu_thread)
return; return;
GPUBackendSyncCommand* cmd = static_cast<GPUBackendSyncCommand*>(AllocateCommand(sizeof(GPUBackendSyncCommand))); GPUBackendSyncCommand* cmd =
cmd->type = GPUBackendCommandType::Sync; static_cast<GPUBackendSyncCommand*>(AllocateCommand(GPUBackendCommandType::Sync, sizeof(GPUBackendSyncCommand)));
cmd->size = sizeof(GPUBackendSyncCommand);
PushCommand(cmd); PushCommand(cmd);
WakeGPUThread(); WakeGPUThread();

View file

@ -41,7 +41,7 @@ public:
void RunGPULoop(); void RunGPULoop();
protected: protected:
void* AllocateCommand(u32 size); void* AllocateCommand(GPUBackendCommandType command, u32 size);
u32 GetPendingCommandSize() const; u32 GetPendingCommandSize() const;
void WakeGPUThread(); void WakeGPUThread();
void StartGPUThread(); void StartGPUThread();

View file

@ -262,14 +262,13 @@ union GPUBackendCommandParameters
struct GPUBackendCommand struct GPUBackendCommand
{ {
u32 size;
GPUBackendCommandType type; GPUBackendCommandType type;
GPUBackendCommandParameters params; GPUBackendCommandParameters params;
u32 size;
}; };
struct GPUBackendSyncCommand : public GPUBackendCommand struct GPUBackendSyncCommand : public GPUBackendCommand
{ {
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendSyncCommand); }
}; };
struct GPUBackendFillVRAMCommand : public GPUBackendCommand struct GPUBackendFillVRAMCommand : public GPUBackendCommand
@ -279,8 +278,6 @@ struct GPUBackendFillVRAMCommand : public GPUBackendCommand
u16 width; u16 width;
u16 height; u16 height;
u32 color; u32 color;
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendFillVRAMCommand); }
}; };
struct GPUBackendUpdateVRAMCommand : public GPUBackendCommand struct GPUBackendUpdateVRAMCommand : public GPUBackendCommand
@ -290,8 +287,6 @@ struct GPUBackendUpdateVRAMCommand : public GPUBackendCommand
u16 width; u16 width;
u16 height; u16 height;
u16 data[0]; u16 data[0];
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendUpdateVRAMCommand) + (sizeof(u16) * width * height); }
}; };
struct GPUBackendCopyVRAMCommand : public GPUBackendCommand struct GPUBackendCopyVRAMCommand : public GPUBackendCommand
@ -302,21 +297,17 @@ struct GPUBackendCopyVRAMCommand : public GPUBackendCommand
u16 dst_y; u16 dst_y;
u16 width; u16 width;
u16 height; u16 height;
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendCopyVRAMCommand); }
}; };
struct GPUBackendSetDrawingAreaCommand : public GPUBackendCommand struct GPUBackendSetDrawingAreaCommand : public GPUBackendCommand
{ {
Common::Rectangle<u32> new_area; Common::Rectangle<u32> new_area;
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendSetDrawingAreaCommand); }
}; };
struct GPUBackendDrawCommand : public GPUBackendCommand struct GPUBackendDrawCommand : public GPUBackendCommand
{ {
GPURenderCommand rc;
GPUDrawModeReg draw_mode; GPUDrawModeReg draw_mode;
GPURenderCommand rc;
GPUTexturePaletteReg palette; GPUTexturePaletteReg palette;
GPUTextureWindow window; GPUTextureWindow window;
@ -349,8 +340,6 @@ struct GPUBackendDrawPolygonCommand : public GPUBackendDrawCommand
}; };
Vertex vertices[0]; Vertex vertices[0];
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendDrawPolygonCommand) + sizeof(Vertex) * num_vertices; }
}; };
struct GPUBackendDrawRectangleCommand : public GPUBackendDrawCommand struct GPUBackendDrawRectangleCommand : public GPUBackendDrawCommand
@ -359,8 +348,6 @@ struct GPUBackendDrawRectangleCommand : public GPUBackendDrawCommand
u16 width, height; u16 width, height;
u16 texcoord; u16 texcoord;
u32 color; u32 color;
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendDrawRectangleCommand); }
}; };
struct GPUBackendDrawLineCommand : public GPUBackendDrawCommand struct GPUBackendDrawLineCommand : public GPUBackendDrawCommand
@ -381,8 +368,6 @@ struct GPUBackendDrawLineCommand : public GPUBackendDrawCommand
}; };
Vertex vertices[0]; Vertex vertices[0];
ALWAYS_INLINE u32 Size() const { return sizeof(GPUBackendDrawLineCommand) + sizeof(Vertex) * num_vertices; }
}; };
#ifdef _MSC_VER #ifdef _MSC_VER