|
@@ -14,6 +14,7 @@
|
|
|
|
|
|
// CHANGELOG
|
|
|
// (minor and older changes stripped away, please see git history for details)
|
|
|
+// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127).
|
|
|
// 2022-05-13: OpenGL: Fix state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states.
|
|
|
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
|
|
|
// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
|
|
@@ -193,6 +194,7 @@ struct ImGui_ImplOpenGL3_Data
|
|
|
GLsizeiptr VertexBufferSize;
|
|
|
GLsizeiptr IndexBufferSize;
|
|
|
bool HasClipOrigin;
|
|
|
+ bool UseBufferSubData;
|
|
|
|
|
|
ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
|
|
};
|
|
@@ -261,6 +263,14 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|
|
sscanf(gl_version, "%d.%d", &major, &minor);
|
|
|
}
|
|
|
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
|
|
+
|
|
|
+ // Query vendor to enable glBufferSubData kludge
|
|
|
+#ifdef _WIN32
|
|
|
+ if (const char* vendor = (const char*)glGetString(GL_VENDOR))
|
|
|
+ if (strncmp(vendor, "Intel", 5) == 0)
|
|
|
+ bd->UseBufferSubData = true;
|
|
|
+#endif
|
|
|
+ //printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
|
|
#else
|
|
|
bd->GlVersion = 200; // GLES 2
|
|
|
#endif
|
|
@@ -474,20 +484,31 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
|
|
|
|
|
// Upload vertex/index buffers
|
|
|
- GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
|
|
- GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
|
|
- if (bd->VertexBufferSize < vtx_buffer_size)
|
|
|
+ // - On Intel windows drivers we got reports that regular glBufferData() led to accumulating leaks when using multi-viewports, so we started using orphaning + glBufferSubData(). (See https://github.com/ocornut/imgui/issues/4468)
|
|
|
+ // - On NVIDIA drivers we got reports that using orphaning + glBufferSubData() led to glitches when using multi-viewports.
|
|
|
+ // - OpenGL drivers are in a very sorry state in 2022, for now we are switching code path based on vendors.
|
|
|
+ const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
|
|
+ const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
|
|
+ if (bd->UseBufferSubData)
|
|
|
{
|
|
|
- bd->VertexBufferSize = vtx_buffer_size;
|
|
|
- glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, NULL, GL_STREAM_DRAW);
|
|
|
+ if (bd->VertexBufferSize < vtx_buffer_size)
|
|
|
+ {
|
|
|
+ bd->VertexBufferSize = vtx_buffer_size;
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, NULL, GL_STREAM_DRAW);
|
|
|
+ }
|
|
|
+ if (bd->IndexBufferSize < idx_buffer_size)
|
|
|
+ {
|
|
|
+ bd->IndexBufferSize = idx_buffer_size;
|
|
|
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, NULL, GL_STREAM_DRAW);
|
|
|
+ }
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data);
|
|
|
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data);
|
|
|
}
|
|
|
- if (bd->IndexBufferSize < idx_buffer_size)
|
|
|
+ else
|
|
|
{
|
|
|
- bd->IndexBufferSize = idx_buffer_size;
|
|
|
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, NULL, GL_STREAM_DRAW);
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
|
|
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
|
|
|
}
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data);
|
|
|
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data);
|
|
|
|
|
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
|
{
|