GPU/Software: Ensure commands are always aligned to 4 bytes
This commit is contained in:
parent
e340963c99
commit
419736aaee
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue