From 200c4fc12ea043f2765c7c166d6be963b3957e36 Mon Sep 17 00:00:00 2001 From: Learath2 Date: Sun, 11 Oct 2020 17:08:04 +0200 Subject: [PATCH] Fix alignment issues in CCommandBuffer --- src/engine/client/backend_sdl.cpp | 15 ++++------ src/engine/client/graphics_threaded.h | 42 ++++++++++++++++----------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index f94ecc6b1..d6a7bab37 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -3979,23 +3979,18 @@ bool CCommandProcessorFragment_SDL::RunCommand(const CCommandBuffer::SCommand *p void CCommandProcessor_SDL_OpenGL::RunBuffer(CCommandBuffer *pBuffer) { - unsigned CmdIndex = 0; - while(1) + for(CCommandBuffer::SCommand *pCommand = pBuffer->Head(); pCommand; pCommand = pCommand->m_pNext) { - const CCommandBuffer::SCommand *pBaseCommand = pBuffer->GetCommand(&CmdIndex); - if(pBaseCommand == 0x0) - break; - - if(m_pOpenGL->RunCommand(pBaseCommand)) + if(m_pOpenGL->RunCommand(pCommand)) continue; - if(m_SDL.RunCommand(pBaseCommand)) + if(m_SDL.RunCommand(pCommand)) continue; - if(m_General.RunCommand(pBaseCommand)) + if(m_General.RunCommand(pCommand)) continue; - dbg_msg("graphics", "unknown command %d", pBaseCommand->m_Cmd); + dbg_msg("graphics", "unknown command %d", pCommand->m_Cmd); } } diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index b072eced8..b9315c27c 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -4,6 +4,7 @@ #include #include +#include #include #define CMD_BUFFER_DATA_BUFFER_SIZE 1024 * 1024 * 2 @@ -38,12 +39,14 @@ class CCommandBuffer 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(m_pData + m_Used) % Alignment); + if(Requested + Offset + m_Used > m_Size) return 0; - void *pPtr = &m_pData[m_Used]; - m_Used += Requested; + + void *pPtr = &m_pData[m_Used + Offset]; + m_Used += Requested + Offset; return pPtr; } @@ -173,10 +176,12 @@ public: { public: SCommand(unsigned Cmd) : - m_Cmd(Cmd), m_Size(0) {} + m_Cmd(Cmd), m_pNext(nullptr) {} unsigned m_Cmd; - unsigned m_Size; + SCommand *m_pNext; }; + SCommand *m_pCmdBufferHead; + SCommand *m_pCmdBufferTail; struct SState { @@ -559,7 +564,7 @@ public: // 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(&Command); // 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) return false; - mem_copy(pCmd, &Command, sizeof(Command)); - pCmd->m_Size = sizeof(Command); + *pCmd = Command; + pCmd->m_pNext = nullptr; + + if(m_pCmdBufferTail) + m_pCmdBufferTail->m_pNext = pCmd; + if(!m_pCmdBufferHead) + m_pCmdBufferHead = pCmd; + m_pCmdBufferTail = pCmd; + return true; } - SCommand *GetCommand(unsigned *pIndex) + SCommand *Head() { - if(*pIndex >= m_CmdBuffer.DataUsed()) - return NULL; - - SCommand *pCommand = (SCommand *)&m_CmdBuffer.DataPtr()[*pIndex]; - *pIndex += pCommand->m_Size; - return pCommand; + return m_pCmdBufferHead; } void Reset() { + m_pCmdBufferHead = m_pCmdBufferTail = nullptr; m_CmdBuffer.Reset(); m_DataBuffer.Reset(); }