3092: Use pointer directly for tile layer building r=heinrich5991 a=Jupeyy

Huge maps like back in time 2, will always "only" upload 2MB of data at once, and then wait for the graphics thread to finish building/copying the VRAM, this might increase performance a bit

Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
bors[bot] 2020-10-13 22:23:46 +00:00 committed by GitHub
commit 1fb4f90191
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 199 additions and 112 deletions

View file

@ -1651,6 +1651,7 @@ void CCommandProcessorFragment_OpenGL2::Cmd_RenderTex3D(const CCommandBuffer::SC
void CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand)
{
void *pUploadData = pCommand->m_pUploadData;
int Index = pCommand->m_BufferIndex;
//create necessary space
if((size_t)Index >= m_BufferObjectIndices.size())
@ -1667,7 +1668,7 @@ void CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(const CCommandBuf
{
glGenBuffers(1, &VertBufferID);
glBindBuffer(GL_COPY_WRITE_BUFFER, VertBufferID);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pCommand->m_pUploadData, GL_STATIC_DRAW);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
}
@ -1675,19 +1676,23 @@ void CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(const CCommandBuf
BufferObject.m_BufferObjectID = VertBufferID;
BufferObject.m_DataSize = pCommand->m_DataSize;
BufferObject.m_pData = malloc(pCommand->m_DataSize);
if(pCommand->m_pUploadData)
mem_copy(BufferObject.m_pData, pCommand->m_pUploadData, pCommand->m_DataSize);
if(pUploadData)
mem_copy(BufferObject.m_pData, pUploadData, pCommand->m_DataSize);
if(pCommand->m_DeletePointer)
free(pUploadData);
}
void CCommandProcessorFragment_OpenGL2::Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand)
{
void *pUploadData = pCommand->m_pUploadData;
int Index = pCommand->m_BufferIndex;
SBufferObject &BufferObject = m_BufferObjectIndices[Index];
if(m_HasShaders)
{
glBindBuffer(GL_COPY_WRITE_BUFFER, BufferObject.m_BufferObjectID);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pCommand->m_pUploadData, GL_STATIC_DRAW);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
}
@ -1695,24 +1700,31 @@ void CCommandProcessorFragment_OpenGL2::Cmd_RecreateBufferObject(const CCommandB
if(BufferObject.m_pData)
free(BufferObject.m_pData);
BufferObject.m_pData = malloc(pCommand->m_DataSize);
if(pCommand->m_pUploadData)
mem_copy(BufferObject.m_pData, pCommand->m_pUploadData, pCommand->m_DataSize);
if(pUploadData)
mem_copy(BufferObject.m_pData, pUploadData, pCommand->m_DataSize);
if(pCommand->m_DeletePointer)
free(pUploadData);
}
void CCommandProcessorFragment_OpenGL2::Cmd_UpdateBufferObject(const CCommandBuffer::SCommand_UpdateBufferObject *pCommand)
{
void *pUploadData = pCommand->m_pUploadData;
int Index = pCommand->m_BufferIndex;
SBufferObject &BufferObject = m_BufferObjectIndices[Index];
if(m_HasShaders)
{
glBindBuffer(GL_COPY_WRITE_BUFFER, BufferObject.m_BufferObjectID);
glBufferSubData(GL_COPY_WRITE_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pCommand->m_pUploadData);
glBufferSubData(GL_COPY_WRITE_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pUploadData);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
}
if(pCommand->m_pUploadData)
mem_copy(((uint8_t *)BufferObject.m_pData) + (ptrdiff_t)pCommand->m_pOffset, pCommand->m_pUploadData, pCommand->m_DataSize);
if(pUploadData)
mem_copy(((uint8_t *)BufferObject.m_pData) + (ptrdiff_t)pCommand->m_pOffset, pUploadData, pCommand->m_DataSize);
if(pCommand->m_DeletePointer)
free(pUploadData);
}
void CCommandProcessorFragment_OpenGL2::Cmd_CopyBufferObject(const CCommandBuffer::SCommand_CopyBufferObject *pCommand)
@ -3097,6 +3109,7 @@ void CCommandProcessorFragment_OpenGL3_3::AppendIndices(unsigned int NewIndicesC
void CCommandProcessorFragment_OpenGL3_3::Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand)
{
void *pUploadData = pCommand->m_pUploadData;
int Index = pCommand->m_BufferIndex;
//create necessary space
if((size_t)Index >= m_BufferObjectIndices.size())
@ -3111,25 +3124,36 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_CreateBufferObject(const CCommandB
glGenBuffers(1, &VertBufferID);
glBindBuffer(GL_COPY_WRITE_BUFFER, VertBufferID);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pCommand->m_pUploadData, GL_STATIC_DRAW);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW);
m_BufferObjectIndices[Index] = VertBufferID;
if(pCommand->m_DeletePointer)
free(pUploadData);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand)
{
void *pUploadData = pCommand->m_pUploadData;
int Index = pCommand->m_BufferIndex;
glBindBuffer(GL_COPY_WRITE_BUFFER, m_BufferObjectIndices[Index]);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pCommand->m_pUploadData, GL_STATIC_DRAW);
glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW);
if(pCommand->m_DeletePointer)
free(pUploadData);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_UpdateBufferObject(const CCommandBuffer::SCommand_UpdateBufferObject *pCommand)
{
void *pUploadData = pCommand->m_pUploadData;
int Index = pCommand->m_BufferIndex;
glBindBuffer(GL_COPY_WRITE_BUFFER, m_BufferObjectIndices[Index]);
glBufferSubData(GL_COPY_WRITE_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pCommand->m_pUploadData);
glBufferSubData(GL_COPY_WRITE_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pUploadData);
if(pCommand->m_DeletePointer)
free(pUploadData);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_CopyBufferObject(const CCommandBuffer::SCommand_CopyBufferObject *pCommand)

View file

@ -1666,7 +1666,7 @@ void *CGraphics_Threaded::AllocCommandBufferData(unsigned AllocSize)
return pData;
}
int CGraphics_Threaded::CreateBufferObject(size_t UploadDataSize, void *pUploadData)
int CGraphics_Threaded::CreateBufferObject(size_t UploadDataSize, void *pUploadData, bool IsMovedPointer)
{
int Index = -1;
if(m_FirstFreeBufferObjectIndex == -1)
@ -1684,107 +1684,211 @@ int CGraphics_Threaded::CreateBufferObject(size_t UploadDataSize, void *pUploadD
CCommandBuffer::SCommand_CreateBufferObject Cmd;
Cmd.m_BufferIndex = Index;
Cmd.m_DataSize = UploadDataSize;
Cmd.m_DeletePointer = IsMovedPointer;
if(UploadDataSize <= CMD_BUFFER_DATA_BUFFER_SIZE)
if(IsMovedPointer)
{
Cmd.m_pUploadData = AllocCommandBufferData(UploadDataSize);
if(Cmd.m_pUploadData == NULL)
return -1;
Cmd.m_pUploadData = pUploadData;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return -1;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer object command");
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return -1;
}
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
else
{
Cmd.m_pUploadData = NULL;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(UploadDataSize <= CMD_BUFFER_DATA_BUFFER_SIZE)
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = AllocCommandBufferData(UploadDataSize);
if(Cmd.m_pUploadData == NULL)
return -1;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer object command");
return -1;
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return -1;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer object command");
return -1;
}
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
// update the buffer instead
size_t UploadDataOffset = 0;
while(UploadDataSize > 0)
else
{
size_t UpdateSize = (UploadDataSize > CMD_BUFFER_DATA_BUFFER_SIZE ? CMD_BUFFER_DATA_BUFFER_SIZE : UploadDataSize);
Cmd.m_pUploadData = NULL;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer object command");
return -1;
}
}
UpdateBufferObject(Index, UpdateSize, (((char *)pUploadData) + UploadDataOffset), (void *)UploadDataOffset);
// update the buffer instead
size_t UploadDataOffset = 0;
while(UploadDataSize > 0)
{
size_t UpdateSize = (UploadDataSize > CMD_BUFFER_DATA_BUFFER_SIZE ? CMD_BUFFER_DATA_BUFFER_SIZE : UploadDataSize);
UploadDataOffset += UpdateSize;
UploadDataSize -= UpdateSize;
UpdateBufferObject(Index, UpdateSize, (((char *)pUploadData) + UploadDataOffset), (void *)UploadDataOffset);
UploadDataOffset += UpdateSize;
UploadDataSize -= UpdateSize;
}
}
}
return Index;
}
void CGraphics_Threaded::RecreateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData)
void CGraphics_Threaded::RecreateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, bool IsMovedPointer)
{
CCommandBuffer::SCommand_RecreateBufferObject Cmd;
Cmd.m_BufferIndex = BufferIndex;
Cmd.m_DataSize = UploadDataSize;
Cmd.m_DeletePointer = IsMovedPointer;
if(UploadDataSize <= CMD_BUFFER_DATA_BUFFER_SIZE)
if(IsMovedPointer)
{
Cmd.m_pUploadData = AllocCommandBufferData(UploadDataSize);
if(Cmd.m_pUploadData == NULL)
return;
Cmd.m_pUploadData = pUploadData;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for recreate buffer object command");
return;
}
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
else
{
Cmd.m_pUploadData = NULL;
if(UploadDataSize <= CMD_BUFFER_DATA_BUFFER_SIZE)
{
Cmd.m_pUploadData = AllocCommandBufferData(UploadDataSize);
if(Cmd.m_pUploadData == NULL)
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for recreate buffer object command");
return;
}
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
else
{
Cmd.m_pUploadData = NULL;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return;
}
}
// update the buffer instead
size_t UploadDataOffset = 0;
while(UploadDataSize > 0)
{
size_t UpdateSize = (UploadDataSize > CMD_BUFFER_DATA_BUFFER_SIZE ? CMD_BUFFER_DATA_BUFFER_SIZE : UploadDataSize);
UpdateBufferObject(BufferIndex, UpdateSize, (((char *)pUploadData) + UploadDataOffset), (void *)UploadDataOffset);
UploadDataOffset += UpdateSize;
UploadDataSize -= UpdateSize;
}
}
}
}
void CGraphics_Threaded::UpdateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, void *pOffset, bool IsMovedPointer)
{
CCommandBuffer::SCommand_UpdateBufferObject Cmd;
Cmd.m_BufferIndex = BufferIndex;
Cmd.m_DataSize = UploadDataSize;
Cmd.m_pOffset = pOffset;
Cmd.m_DeletePointer = IsMovedPointer;
if(IsMovedPointer)
{
Cmd.m_pUploadData = pUploadData;
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return;
}
}
}
else
{
Cmd.m_pUploadData = AllocCommandBufferData(UploadDataSize);
if(Cmd.m_pUploadData == NULL)
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
@ -1792,54 +1896,10 @@ void CGraphics_Threaded::RecreateBufferObject(int BufferIndex, size_t UploadData
}
}
// update the buffer instead
size_t UploadDataOffset = 0;
while(UploadDataSize > 0)
{
size_t UpdateSize = (UploadDataSize > CMD_BUFFER_DATA_BUFFER_SIZE ? CMD_BUFFER_DATA_BUFFER_SIZE : UploadDataSize);
UpdateBufferObject(BufferIndex, UpdateSize, (((char *)pUploadData) + UploadDataOffset), (void *)UploadDataOffset);
UploadDataOffset += UpdateSize;
UploadDataSize -= UpdateSize;
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
}
void CGraphics_Threaded::UpdateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, void *pOffset)
{
CCommandBuffer::SCommand_UpdateBufferObject Cmd;
Cmd.m_BufferIndex = BufferIndex;
Cmd.m_DataSize = UploadDataSize;
Cmd.m_pOffset = pOffset;
Cmd.m_pUploadData = AllocCommandBufferData(UploadDataSize);
if(Cmd.m_pUploadData == NULL)
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return;
}
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
void CGraphics_Threaded::CopyBufferObject(int WriteBufferIndex, int ReadBufferIndex, size_t WriteOffset, size_t ReadOffset, size_t CopyDataSize)
{
CCommandBuffer::SCommand_CopyBufferObject Cmd;

View file

@ -250,6 +250,7 @@ public:
int m_BufferIndex;
bool m_DeletePointer;
void *m_pUploadData;
size_t m_DataSize;
};
@ -261,6 +262,7 @@ public:
int m_BufferIndex;
bool m_DeletePointer;
void *m_pUploadData;
size_t m_DataSize;
};
@ -272,6 +274,7 @@ public:
int m_BufferIndex;
bool m_DeletePointer;
void *m_pOffset;
void *m_pUploadData;
size_t m_DataSize;
@ -1076,9 +1079,9 @@ public:
void RenderText(int BufferContainerIndex, int TextQuadNum, int TextureSize, int TextureTextIndex, int TextureTextOutlineIndex, float *pTextColor, float *pTextoutlineColor) override;
// opengl 3.3 functions
int CreateBufferObject(size_t UploadDataSize, void *pUploadData) override;
void RecreateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData) override;
void UpdateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, void *pOffset) override;
int CreateBufferObject(size_t UploadDataSize, void *pUploadData, bool IsMovedPointer = false) override;
void RecreateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, bool IsMovedPointer = false) override;
void UpdateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, void *pOffset, bool IsMovedPointer = false) override;
void CopyBufferObject(int WriteBufferIndex, int ReadBufferIndex, size_t WriteOffset, size_t ReadOffset, size_t CopyDataSize) override;
void DeleteBufferObject(int BufferIndex) override;

View file

@ -254,9 +254,10 @@ public:
virtual void RenderText(int BufferContainerIndex, int TextQuadNum, int TextureSize, int TextureTextIndex, int TextureTextOutlineIndex, float *pTextColor, float *pTextoutlineColor) = 0;
// opengl 3.3 functions
virtual int CreateBufferObject(size_t UploadDataSize, void *pUploadData) = 0;
virtual void RecreateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData) = 0;
virtual void UpdateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, void *pOffset) = 0;
// if a pointer is passed as moved pointer, it requires to be allocated with malloc()
virtual int CreateBufferObject(size_t UploadDataSize, void *pUploadData, bool IsMovedPointer = false) = 0;
virtual void RecreateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, bool IsMovedPointer = false) = 0;
virtual void UpdateBufferObject(int BufferIndex, size_t UploadDataSize, void *pUploadData, void *pOffset, bool IsMovedPointer = false) = 0;
virtual void CopyBufferObject(int WriteBufferIndex, int ReadBufferIndex, size_t WriteOffset, size_t ReadOffset, size_t CopyDataSize) = 0;
virtual void DeleteBufferObject(int BufferIndex) = 0;

View file

@ -836,7 +836,7 @@ void CMapLayers::OnMapLoad()
size_t UploadDataSize = tmpTileTexCoords.size() * sizeof(SGraphicTileTexureCoords) + tmpTiles.size() * sizeof(SGraphicTile);
if(UploadDataSize > 0)
{
char *pUploadData = new char[UploadDataSize];
char *pUploadData = (char *)malloc(sizeof(char) * UploadDataSize);
mem_copy_special(pUploadData, pTmpTiles, sizeof(vec2), tmpTiles.size() * 4, (DoTextureCoords ? sizeof(vec3) : 0));
if(DoTextureCoords)
@ -845,8 +845,7 @@ void CMapLayers::OnMapLoad()
}
// first create the buffer object
int BufferObjectIndex = Graphics()->CreateBufferObject(UploadDataSize, pUploadData);
delete[] pUploadData;
int BufferObjectIndex = Graphics()->CreateBufferObject(UploadDataSize, pUploadData, true);
// then create the buffer container
SBufferContainerInfo ContainerInfo;