SWDEV-460019 - [OGLP][Nv2x] DaVinci Resolve Studio: Crash observed when editing in color tab

When CL-GL interop is used, a GL context are used by two or more threads at the same time, which causes race condition.

Solution:
Add lock when accessing GL functions during CL-GL interop.

Change-Id: I3a34da3cbdf74c401111cc4e3a04ad84cc52709e


[ROCm/clr commit: 0c6a952a90]
This commit is contained in:
Gu, Wangfeng
2024-05-09 14:43:18 +08:00
committed by Victor Zhang
parent 10b3a313d2
commit 28009e625b
3 changed files with 91 additions and 67 deletions
+14 -8
View File
@@ -63,6 +63,7 @@ bool amd::ClGlEvent::waitForFence() {
HGLRC tempGLRC_ = context().glenv()->wglGetCurrentContext_();
// Set DC and GLRC
if (tempDC_ && tempGLRC_) {
amd::GLFunctions::Lock lock(context().glenv());
ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT,
static_cast<GLuint64>(-1));
if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false;
@@ -74,14 +75,12 @@ bool amd::ClGlEvent::waitForFence() {
return false;
// Make the newly created GL context current to this thread
context().glenv()->setIntEnv();
amd::GLFunctions::SetIntEnv ie(context().glenv());
// If fence has not yet executed, wait till it finishes
ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT,
static_cast<GLuint64>(-1));
if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false;
// Since we're done making GL calls, restore whatever context was previously current to this
// thread
context().glenv()->restoreEnv();
}
#else // Lnx
Display* tempDpy_ = context().glenv()->glXGetCurrentDisplay_();
@@ -89,6 +88,7 @@ bool amd::ClGlEvent::waitForFence() {
GLXContext tempCtx_ = context().glenv()->glXGetCurrentContext_();
// Set internal Display and GLXContext
if (tempDpy_ && tempCtx_) {
amd::GLFunctions::Lock lock(context().glenv());
ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT,
static_cast<GLuint64>(-1));
if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false;
@@ -98,14 +98,12 @@ bool amd::ClGlEvent::waitForFence() {
return false;
// Make the newly created GL context current to this thread
context().glenv()->setIntEnv();
amd::GLFunctions::SetIntEnv ie(context().glenv());
// If fence has not yet executed, wait till it finishes
ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT,
static_cast<GLuint64>(-1));
if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false;
// Since we're done making GL calls, restore whatever context was previously current to this
// thread
context().glenv()->restoreEnv();
}
#endif
// If we reach this point, fence should have completed
@@ -151,6 +149,14 @@ amd::GLFunctions::SetIntEnv::~SetIntEnv() {
env_->getLock().unlock();
}
amd::GLFunctions::Lock::Lock(GLFunctions* env) : env_(env) {
env_->getLock().lock();
}
amd::GLFunctions::Lock::~Lock() {
env_->getLock().unlock();
}
amd::GLFunctions::GLFunctions(HMODULE h, bool isEGL)
: libHandle_(h),
missed_(0),