Merge pull request #920 from Jupeyy/master

VBO deletion after VAO deletion & viewport adjustment for dpi scaled displays at fullscreen
This commit is contained in:
Dennis Felsing 2017-10-24 07:58:37 +02:00 committed by GitHub
commit 2d889a0584
5 changed files with 110 additions and 26 deletions

View file

@ -1126,6 +1126,7 @@ endforeach()
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME ${PROJECT_NAME})
install(TARGETS ${TARGET_CLIENT} ${TARGET_SERVER} DESTINATION bin)
install(DIRECTORY data DESTINATION share/DDNet)
install(DIRECTORY shader DESTINATION share/DDNet)
set(CPACK_TARGETS
${TARGET_CLIENT}
@ -1137,6 +1138,7 @@ set(CPACK_TARGETS
map_extract
)
set(CPACK_DIRS data)
set(CPACK_DIRS shader)
set(CPACK_FILES
license.txt
storage.cfg

View file

@ -763,6 +763,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
glGenBuffers(1, &m_QuadDrawIndexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
m_LastIndexBufferBound = m_QuadDrawIndexBufferID;
unsigned int Indices[CCommandBuffer::MAX_VERTICES/4 * 6];
int Primq = 0;
@ -1011,7 +1012,11 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Render(const CCommandBuffer::SComm
glDrawArrays(GL_LINES, 0, pCommand->m_PrimCount*2);
break;
case CCommandBuffer::PRIMTYPE_QUADS:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
if (m_LastIndexBufferBound != m_QuadDrawIndexBufferID)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
m_LastIndexBufferBound = m_QuadDrawIndexBufferID;
}
glDrawElements(GL_TRIANGLES, pCommand->m_PrimCount*6, GL_UNSIGNED_INT, 0);
break;
default:
@ -1110,12 +1115,15 @@ void CCommandProcessorFragment_OpenGL3_3::DestroyTexture(int Slot)
void CCommandProcessorFragment_OpenGL3_3::DestroyVisualObjects(int Index)
{
SVisualObject& VisualObject = m_VisualObjects[Index];
if(VisualObject.m_VertArrayID != 0) glDeleteVertexArrays(1, &VisualObject.m_VertArrayID);
if(VisualObject.m_VertBufferID != 0) glDeleteBuffers(1, &VisualObject.m_VertBufferID);//this line should never be called
if (VisualObject.m_VertArrayID != 0) glDeleteVertexArrays(1, &VisualObject.m_VertArrayID);
// this is required, due to a driver bug for AMD under windows
if(VisualObject.m_VertBufferID != 0) glDeleteBuffers(1, &VisualObject.m_VertBufferID);
VisualObject.m_NumElements = 0;
VisualObject.m_IsTextured = false;
VisualObject.m_VertBufferID = VisualObject.m_VertArrayID = 0;
VisualObject.m_LastIndexBufferBound = 0;
}
void CCommandProcessorFragment_OpenGL3_3::AppendIndices(unsigned int NewIndicesCount)
@ -1135,7 +1143,6 @@ void CCommandProcessorFragment_OpenGL3_3::AppendIndices(unsigned int NewIndicesC
Primq+=4;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_COPY_READ_BUFFER, m_QuadDrawIndexBufferID);
GLuint NewIndexBufferID;
glGenBuffers(1, &NewIndexBufferID);
@ -1149,7 +1156,6 @@ void CCommandProcessorFragment_OpenGL3_3::AppendIndices(unsigned int NewIndicesC
glDeleteBuffers(1, &m_QuadDrawIndexBufferID);
m_QuadDrawIndexBufferID = NewIndexBufferID;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
m_CurrentIndicesInBuffer = NewIndicesCount;
delete[] Indices;
@ -1191,7 +1197,11 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTile(const CCommandBuf
pProgram->SetUniform(pProgram->m_LocJumpIndex, (int)pCommand->m_JumpIndex);
glBindVertexArray(VisualObject.m_VertArrayID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
if (VisualObject.m_LastIndexBufferBound != m_QuadDrawIndexBufferID)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
VisualObject.m_LastIndexBufferBound = m_QuadDrawIndexBufferID;
}
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, pCommand->m_pIndicesOffset, pCommand->m_DrawNum);
}
@ -1219,7 +1229,11 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTileLine(const CComman
pProgram->SetUniformVec2(pProgram->m_LocDir, 1, (float*)&pCommand->m_Dir);
glBindVertexArray(VisualObject.m_VertArrayID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
if (VisualObject.m_LastIndexBufferBound != m_QuadDrawIndexBufferID)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
VisualObject.m_LastIndexBufferBound = m_QuadDrawIndexBufferID;
}
glDrawElementsInstanced(GL_TRIANGLES, pCommand->m_IndexDrawNum, GL_UNSIGNED_INT, pCommand->m_pIndicesOffset, pCommand->m_DrawNum);
}
@ -1252,9 +1266,11 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderVertexArray(const CCommandBu
pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float*)&pCommand->m_Color);
glBindVertexArray(VisualObject.m_VertArrayID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
//for some reasons this function seems not to be in the coreprofile for quite some gpus
//glMultiDrawElements(GL_TRIANGLES, pCommand->m_pDrawCount, GL_UNSIGNED_INT, pCommand->m_pIndicesOffsets, pCommand->m_IndicesDrawNum);
if (VisualObject.m_LastIndexBufferBound != m_QuadDrawIndexBufferID)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
VisualObject.m_LastIndexBufferBound = m_QuadDrawIndexBufferID;
}
for (int i = 0; i < pCommand->m_IndicesDrawNum; ++i)
{
glDrawElements(GL_TRIANGLES, pCommand->m_pDrawCount[i], GL_UNSIGNED_INT, pCommand->m_pIndicesOffsets[i]);
@ -1348,9 +1364,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_CreateVertArray(const CCommandBuff
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//TODO: destroy the VBO here? it shouldn't be needed anymore
glDeleteBuffers(1, &VisualObject.m_VertBufferID);
VisualObject.m_VertBufferID = 0;
// due to a driver bug for AMD hardware (https://stackoverflow.com/questions/41520764/should-i-delete-vertex-buffer-object-after-binding-it-to-vertex-array-objects)
// we don't delete the VBO bound to the VAO
}
// ------------ CCommandProcessorFragment_SDL
@ -1371,6 +1386,11 @@ void CCommandProcessorFragment_SDL::Cmd_Init(const SCommand_Init *pCommand)
glDepthMask(0);
}
void CCommandProcessorFragment_SDL::Cmd_Update_Viewport(const SCommand_Update_Viewport* pCommand)
{
glViewport(pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height);
}
void CCommandProcessorFragment_SDL::Cmd_Shutdown(const SCommand_Shutdown *pCommand)
{
SDL_GL_MakeCurrent(NULL, NULL);
@ -1445,6 +1465,7 @@ bool CCommandProcessorFragment_SDL::RunCommand(const CCommandBuffer::SCommand *p
case CCommandBuffer::CMD_VIDEOMODES: Cmd_VideoModes(static_cast<const CCommandBuffer::SCommand_VideoModes *>(pBaseCommand)); break;
case CMD_INIT: Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand)); break;
case CMD_SHUTDOWN: Cmd_Shutdown(static_cast<const SCommand_Shutdown *>(pBaseCommand)); break;
case CMD_UPDATE_VIEWPORT: Cmd_Update_Viewport(static_cast<const SCommand_Update_Viewport *>(pBaseCommand)); break;
default: return false;
}
@ -1484,7 +1505,7 @@ void CCommandProcessor_SDL_OpenGL::RunBuffer(CCommandBuffer *pBuffer)
// ------------ CGraphicsBackend_SDL_OpenGL
int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight)
int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight, int* pCurrentWidth, int* pCurrentHeight)
{
if(!SDL_WasInit(SDL_INIT_VIDEO))
{
@ -1634,7 +1655,29 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
*pWidth = *pDesktopWidth;
*pHeight = *pDesktopHeight;
#else
SdlFlags |= SDL_WINDOW_FULLSCREEN;
//when we are at fullscreen, we really shouldn't allow window sizes, that aren't supported by the driver
bool SupportedResolution = false;
SDL_DisplayMode mode;
int maxModes = SDL_GetNumDisplayModes(g_Config.m_GfxScreen);
for (int i = 0; i < maxModes; i++)
{
if (SDL_GetDisplayMode(g_Config.m_GfxScreen, i, &mode) < 0)
{
dbg_msg("gfx", "unable to get display mode: %s", SDL_GetError());
continue;
}
if (*pWidth == mode.w && *pHeight == mode.h)
{
SupportedResolution = true;
break;
}
}
if(SupportedResolution)
SdlFlags |= SDL_WINDOW_FULLSCREEN;
else
SdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
#endif
}
@ -1721,8 +1764,39 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
WaitForIdle();
}
*pCurrentWidth = *pWidth;
*pCurrentHeight = *pHeight;
SDL_ShowWindow(m_pWindow);
SetWindowScreen(g_Config.m_GfxScreen);
if (SetWindowScreen(g_Config.m_GfxScreen))
{
// query the current displaymode, when running in fullscreen
// this is required if DPI scaling is active
if (SdlFlags&SDL_WINDOW_FULLSCREEN)
{
SDL_DisplayMode CurrentDisplayMode;
SDL_GetCurrentDisplayMode(g_Config.m_GfxScreen, &CurrentDisplayMode);
*pCurrentWidth = CurrentDisplayMode.w;
*pCurrentHeight = CurrentDisplayMode.h;
// since the window is centered, calculate how much the viewport has to be fixed
//int XOverflow = (*pWidth > *pCurrentWidth ? (*pWidth - *pCurrentWidth) : 0);
//int YOverflow = (*pHeight > *pCurrentHeight ? (*pHeight - *pCurrentHeight) : 0);
//TODO: current problem is, that the opengl driver knows about the scaled display,
//so the viewport cannot be adjusted for resolutions, that are higher than allowed by the display driver
CCommandProcessorFragment_SDL::SCommand_Update_Viewport CmdSDL;
CmdSDL.m_X = 0;
CmdSDL.m_Y = 0;
CmdSDL.m_Width = CurrentDisplayMode.w;
CmdSDL.m_Height = CurrentDisplayMode.h;
CmdBuffer.AddCommand(CmdSDL);
RunBuffer(&CmdBuffer);
WaitForIdle();
}
}
// return
return 0;

View file

@ -124,7 +124,7 @@ class CGLSLQuadProgram;
class CGLSLTileProgram;
class CGLSLBorderTileProgram;
class CGLSLBorderTileLineProgram;
// takes care of opengl 3.2 related rendering
// takes care of opengl 3.3 related rendering
class CCommandProcessorFragment_OpenGL3_3
{
bool m_UseMultipleTextureUnits;
@ -141,7 +141,6 @@ class CCommandProcessorFragment_OpenGL3_3
volatile int *m_pTextureMemoryUsage;
CGLSLPrimitiveProgram* m_pPrimitiveProgram;
//CGLSLQuadProgram* m_QuadProgram;
CGLSLTileProgram* m_pTileProgram;
CGLSLTileProgram* m_pTileProgramTextured;
CGLSLBorderTileProgram* m_pBorderTileProgram;
@ -151,6 +150,7 @@ class CCommandProcessorFragment_OpenGL3_3
GLuint m_PrimitiveDrawVertexID;
GLuint m_PrimitiveDrawBufferID;
GLuint m_LastIndexBufferBound;
GLuint m_QuadDrawIndexBufferID;
unsigned int m_CurrentIndicesInBuffer;
@ -172,9 +172,10 @@ class CCommandProcessorFragment_OpenGL3_3
void AppendIndices(unsigned int NewIndicesCount);
struct SVisualObject{
SVisualObject() : m_VertArrayID(0), m_VertBufferID(0), m_NumElements(0), m_IsTextured(false) {}
SVisualObject() : m_VertArrayID(0), m_VertBufferID(0), m_LastIndexBufferBound(0), m_NumElements(0), m_IsTextured(false) {}
GLuint m_VertArrayID;
GLuint m_VertBufferID;
GLuint m_LastIndexBufferBound;
int m_NumElements; //vertices and texture coordinates
bool m_IsTextured;
};
@ -239,6 +240,7 @@ public:
enum
{
CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM_SDL,
CMD_UPDATE_VIEWPORT,
CMD_SHUTDOWN,
};
@ -249,6 +251,15 @@ public:
SDL_GLContext m_GLContext;
};
struct SCommand_Update_Viewport : public CCommandBuffer::SCommand
{
SCommand_Update_Viewport() : SCommand(CMD_UPDATE_VIEWPORT) {}
int m_X;
int m_Y;
int m_Width;
int m_Height;
};
struct SCommand_Shutdown : public CCommandBuffer::SCommand
{
SCommand_Shutdown() : SCommand(CMD_SHUTDOWN) {}
@ -256,6 +267,7 @@ public:
private:
void Cmd_Init(const SCommand_Init *pCommand);
void Cmd_Update_Viewport(const SCommand_Update_Viewport* pCommand);
void Cmd_Shutdown(const SCommand_Shutdown *pCommand);
void Cmd_Swap(const CCommandBuffer::SCommand_Swap *pCommand);
void Cmd_VSync(const CCommandBuffer::SCommand_VSync *pCommand);
@ -292,7 +304,7 @@ class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded
bool m_UseOpenGL3_3;
public:
virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight);
virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight, int* pCurrentWidth, int* pCurrentHeight);
virtual int Shutdown();
virtual int MemoryUsage() const;

View file

@ -1212,7 +1212,7 @@ int CGraphics_Threaded::IssueInit()
if(g_Config.m_GfxVsync) Flags |= IGraphicsBackend::INITFLAG_VSYNC;
if(g_Config.m_GfxResizable) Flags |= IGraphicsBackend::INITFLAG_RESIZABLE;
int r = m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight);
int r = m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight, &m_ScreenWidth, &m_ScreenHeight);
m_UseOpenGL3_3 = m_pBackend->IsOpenGL3_3();
return r;
}
@ -1286,10 +1286,6 @@ int CGraphics_Threaded::Init()
else
m_pVertices = m_aVerticesOld;
// fetch final resolution
m_ScreenWidth = g_Config.m_GfxScreenWidth;
m_ScreenHeight = g_Config.m_GfxScreenHeight;
// create command buffers
for(int i = 0; i < NUM_CMDBUFFERS; i++)
m_apCommandBuffers[i] = new CCommandBuffer(256*1024, 2*1024*1024);

View file

@ -429,7 +429,7 @@ public:
virtual ~IGraphicsBackend() {}
virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight) = 0;
virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight, int* pCurrentWidth, int* pCurrentHeight) = 0;
virtual int Shutdown() = 0;
virtual int MemoryUsage() const = 0;