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 "common/align.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "settings.h"
@ -44,71 +45,59 @@ void GPUBackend::Shutdown()
GPUBackendFillVRAMCommand* GPUBackend::NewFillVRAMCommand()
{
GPUBackendFillVRAMCommand* cmd =
static_cast<GPUBackendFillVRAMCommand*>(AllocateCommand(sizeof(GPUBackendFillVRAMCommand)));
cmd->type = GPUBackendCommandType::FillVRAM;
cmd->size = cmd->Size();
return cmd;
return static_cast<GPUBackendFillVRAMCommand*>(
AllocateCommand(GPUBackendCommandType::FillVRAM, sizeof(GPUBackendFillVRAMCommand)));
}
GPUBackendUpdateVRAMCommand* GPUBackend::NewUpdateVRAMCommand(u32 num_words)
{
const u32 size = sizeof(GPUBackendUpdateVRAMCommand) + (num_words * sizeof(u16));
GPUBackendUpdateVRAMCommand* cmd = static_cast<GPUBackendUpdateVRAMCommand*>(AllocateCommand(size));
cmd->type = GPUBackendCommandType::UpdateVRAM;
cmd->size = size;
GPUBackendUpdateVRAMCommand* cmd =
static_cast<GPUBackendUpdateVRAMCommand*>(AllocateCommand(GPUBackendCommandType::UpdateVRAM, size));
return cmd;
}
GPUBackendCopyVRAMCommand* GPUBackend::NewCopyVRAMCommand()
{
GPUBackendCopyVRAMCommand* cmd =
static_cast<GPUBackendCopyVRAMCommand*>(AllocateCommand(sizeof(GPUBackendCopyVRAMCommand)));
cmd->type = GPUBackendCommandType::CopyVRAM;
cmd->size = cmd->Size();
return cmd;
return static_cast<GPUBackendCopyVRAMCommand*>(
AllocateCommand(GPUBackendCommandType::CopyVRAM, sizeof(GPUBackendCopyVRAMCommand)));
}
GPUBackendSetDrawingAreaCommand* GPUBackend::NewSetDrawingAreaCommand()
{
GPUBackendSetDrawingAreaCommand* cmd =
static_cast<GPUBackendSetDrawingAreaCommand*>(AllocateCommand(sizeof(GPUBackendSetDrawingAreaCommand)));
cmd->type = GPUBackendCommandType::SetDrawingArea;
cmd->size = cmd->Size();
return cmd;
return static_cast<GPUBackendSetDrawingAreaCommand*>(
AllocateCommand(GPUBackendCommandType::SetDrawingArea, sizeof(GPUBackendSetDrawingAreaCommand)));
}
GPUBackendDrawPolygonCommand* GPUBackend::NewDrawPolygonCommand(u32 num_vertices)
{
const u32 size = sizeof(GPUBackendDrawPolygonCommand) + (num_vertices * sizeof(GPUBackendDrawPolygonCommand::Vertex));
GPUBackendDrawPolygonCommand* cmd = static_cast<GPUBackendDrawPolygonCommand*>(AllocateCommand(size));
cmd->type = GPUBackendCommandType::DrawPolygon;
cmd->size = size;
GPUBackendDrawPolygonCommand* cmd =
static_cast<GPUBackendDrawPolygonCommand*>(AllocateCommand(GPUBackendCommandType::DrawPolygon, size));
cmd->num_vertices = Truncate16(num_vertices);
return cmd;
}
GPUBackendDrawRectangleCommand* GPUBackend::NewDrawRectangleCommand()
{
GPUBackendDrawRectangleCommand* cmd =
static_cast<GPUBackendDrawRectangleCommand*>(AllocateCommand(sizeof(GPUBackendDrawRectangleCommand)));
cmd->type = GPUBackendCommandType::DrawRectangle;
cmd->size = cmd->Size();
return cmd;
return static_cast<GPUBackendDrawRectangleCommand*>(
AllocateCommand(GPUBackendCommandType::DrawRectangle, sizeof(GPUBackendDrawRectangleCommand)));
}
GPUBackendDrawLineCommand* GPUBackend::NewDrawLineCommand(u32 num_vertices)
{
const u32 size = sizeof(GPUBackendDrawLineCommand) + (num_vertices * sizeof(GPUBackendDrawLineCommand::Vertex));
GPUBackendDrawLineCommand* cmd = static_cast<GPUBackendDrawLineCommand*>(AllocateCommand(size));
cmd->type = GPUBackendCommandType::DrawLine;
cmd->size = size;
GPUBackendDrawLineCommand* cmd =
static_cast<GPUBackendDrawLineCommand*>(AllocateCommand(GPUBackendCommandType::DrawLine, size));
cmd->num_vertices = Truncate16(num_vertices);
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 (;;)
{
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)
return;
GPUBackendSyncCommand* cmd = static_cast<GPUBackendSyncCommand*>(AllocateCommand(sizeof(GPUBackendSyncCommand)));
cmd->type = GPUBackendCommandType::Sync;
cmd->size = sizeof(GPUBackendSyncCommand);
GPUBackendSyncCommand* cmd =
static_cast<GPUBackendSyncCommand*>(AllocateCommand(GPUBackendCommandType::Sync, sizeof(GPUBackendSyncCommand)));
PushCommand(cmd);
WakeGPUThread();

View File

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

View File

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