3068: Fix alignment issues in CCommandBuffer r=def- a=Learath2

Though I prefer this version I also made one keeping the old ugly pointer arithmetic cb61356105

Feel  free to take whichever. Supersedes #3061 

Co-authored-by: Learath2 <learath2@gmail.com>
This commit is contained in:
bors[bot] 2020-10-12 17:26:41 +00:00 committed by GitHub
commit d006b400ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 27 deletions

View file

@ -3979,23 +3979,18 @@ bool CCommandProcessorFragment_SDL::RunCommand(const CCommandBuffer::SCommand *p
void CCommandProcessor_SDL_OpenGL::RunBuffer(CCommandBuffer *pBuffer) void CCommandProcessor_SDL_OpenGL::RunBuffer(CCommandBuffer *pBuffer)
{ {
unsigned CmdIndex = 0; for(CCommandBuffer::SCommand *pCommand = pBuffer->Head(); pCommand; pCommand = pCommand->m_pNext)
while(1)
{ {
const CCommandBuffer::SCommand *pBaseCommand = pBuffer->GetCommand(&CmdIndex); if(m_pOpenGL->RunCommand(pCommand))
if(pBaseCommand == 0x0)
break;
if(m_pOpenGL->RunCommand(pBaseCommand))
continue; continue;
if(m_SDL.RunCommand(pBaseCommand)) if(m_SDL.RunCommand(pCommand))
continue; continue;
if(m_General.RunCommand(pBaseCommand)) if(m_General.RunCommand(pCommand))
continue; continue;
dbg_msg("graphics", "unknown command %d", pBaseCommand->m_Cmd); dbg_msg("graphics", "unknown command %d", pCommand->m_Cmd);
} }
} }

View file

@ -4,6 +4,7 @@
#include <engine/graphics.h> #include <engine/graphics.h>
#include <engine/shared/config.h> #include <engine/shared/config.h>
#include <cstddef>
#include <vector> #include <vector>
#define CMD_BUFFER_DATA_BUFFER_SIZE 1024 * 1024 * 2 #define CMD_BUFFER_DATA_BUFFER_SIZE 1024 * 1024 * 2
@ -38,12 +39,14 @@ class CCommandBuffer
m_Used = 0; m_Used = 0;
} }
void *Alloc(unsigned Requested) void *Alloc(unsigned Requested, unsigned Alignment = alignof(std::max_align_t))
{ {
if(Requested + m_Used > m_Size) size_t Offset = Alignment - (reinterpret_cast<uintptr_t>(m_pData + m_Used) % Alignment);
if(Requested + Offset + m_Used > m_Size)
return 0; return 0;
void *pPtr = &m_pData[m_Used];
m_Used += Requested; void *pPtr = &m_pData[m_Used + Offset];
m_Used += Requested + Offset;
return pPtr; return pPtr;
} }
@ -173,10 +176,12 @@ public:
{ {
public: public:
SCommand(unsigned Cmd) : SCommand(unsigned Cmd) :
m_Cmd(Cmd), m_Size(0) {} m_Cmd(Cmd), m_pNext(nullptr) {}
unsigned m_Cmd; unsigned m_Cmd;
unsigned m_Size; SCommand *m_pNext;
}; };
SCommand *m_pCmdBufferHead;
SCommand *m_pCmdBufferTail;
struct SState struct SState
{ {
@ -559,7 +564,7 @@ public:
// //
CCommandBuffer(unsigned CmdBufferSize, unsigned DataBufferSize) : CCommandBuffer(unsigned CmdBufferSize, unsigned DataBufferSize) :
m_CmdBuffer(CmdBufferSize), m_DataBuffer(DataBufferSize) m_CmdBuffer(CmdBufferSize), m_DataBuffer(DataBufferSize), m_pCmdBufferHead(nullptr), m_pCmdBufferTail(nullptr)
{ {
} }
@ -575,26 +580,29 @@ public:
(void)static_cast<const SCommand *>(&Command); (void)static_cast<const SCommand *>(&Command);
// allocate and copy the command into the buffer // allocate and copy the command into the buffer
SCommand *pCmd = (SCommand *)m_CmdBuffer.Alloc(sizeof(Command)); T *pCmd = (T *)m_CmdBuffer.Alloc(sizeof(*pCmd), alignof(T));
if(!pCmd) if(!pCmd)
return false; return false;
mem_copy(pCmd, &Command, sizeof(Command)); *pCmd = Command;
pCmd->m_Size = sizeof(Command); pCmd->m_pNext = nullptr;
if(m_pCmdBufferTail)
m_pCmdBufferTail->m_pNext = pCmd;
if(!m_pCmdBufferHead)
m_pCmdBufferHead = pCmd;
m_pCmdBufferTail = pCmd;
return true; return true;
} }
SCommand *GetCommand(unsigned *pIndex) SCommand *Head()
{ {
if(*pIndex >= m_CmdBuffer.DataUsed()) return m_pCmdBufferHead;
return NULL;
SCommand *pCommand = (SCommand *)&m_CmdBuffer.DataPtr()[*pIndex];
*pIndex += pCommand->m_Size;
return pCommand;
} }
void Reset() void Reset()
{ {
m_pCmdBufferHead = m_pCmdBufferTail = nullptr;
m_CmdBuffer.Reset(); m_CmdBuffer.Reset();
m_DataBuffer.Reset(); m_DataBuffer.Reset();
} }