diff --git a/projects/clr/opencl/amdocl/cl_gl.cpp b/projects/clr/opencl/amdocl/cl_gl.cpp index 7ccfb0c00b..f64101480f 100644 --- a/projects/clr/opencl/amdocl/cl_gl.cpp +++ b/projects/clr/opencl/amdocl/cl_gl.cpp @@ -765,7 +765,13 @@ RUNTIME_ENTRY_RET(cl_event, clCreateEventFromGLsyncKHR, LogWarning("Memory allocation of clglEvent object failed"); return nullptr; } - clglEvent->context().glenv()->glFlush_(); + + // Add this scope to bound the scoped lock + { + amd::GLFunctions::Lock lock(clglEvent->context().glenv()); + clglEvent->context().glenv()->glFlush_(); + } // Release scoped lock + // initially set the status of fence as queued clglEvent->setStatus(CL_SUBMITTED); // store GLsync id of the fence in event in order to associate them together @@ -1108,23 +1114,22 @@ cl_mem clCreateFromGLBufferAMD(Context& amdContext, cl_mem_flags flags, GLuint b // Mapping will be done at acquire time (sync point) + // Now create BufferGL object + pBufferGL = new (amdContext) BufferGL(amdContext, flags, gliSize, 0, bufobj); + + if (!pBufferGL) { + *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; + LogWarning("cannot create object of class BufferGL"); + return (cl_mem)0; + } + + if (!pBufferGL->create()) { + *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; + pBufferGL->release(); + return (cl_mem)0; + } } // Release scoped lock - // Now create BufferGL object - pBufferGL = new (amdContext) BufferGL(amdContext, flags, gliSize, 0, bufobj); - - if (!pBufferGL) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - LogWarning("cannot create object of class BufferGL"); - return (cl_mem)0; - } - - if (!pBufferGL->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pBufferGL->release(); - return (cl_mem)0; - } - *not_null(errcode_ret) = CL_SUCCESS; // Create interop object @@ -1430,34 +1435,34 @@ cl_mem clCreateFromGLTextureAMD(Context& amdContext, cl_mem_flags clFlags, GLenu // PBO and mapping will be done at "acquire" time (sync point) + target = (glTarget == GL_TEXTURE_CUBE_MAP) ? target : 0; + + if (wholeMipmap) { + pImageGL = new (amdContext) + ImageGL(amdContext, clType, clFlags, clImageFormat, static_cast(gliTexWidth), + static_cast(gliTexHeight), static_cast(gliTexDepth), glTarget, + texture, miplevel, glInternalFormat, clGLType, numSamples, gliTexMaxLevel, target); + } else { + pImageGL = new (amdContext) + ImageGL(amdContext, clType, clFlags, clImageFormat, static_cast(gliTexWidth), + static_cast(gliTexHeight), static_cast(gliTexDepth), glTarget, + texture, miplevel, glInternalFormat, clGLType, numSamples, target); + } + + if (!pImageGL) { + *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; + LogWarning("Cannot create class ImageGL - out of memory?"); + return static_cast(0); + } + + if (!pImageGL->create()) { + *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; + pImageGL->release(); + return static_cast(0); + } + } // Release scoped lock - target = (glTarget == GL_TEXTURE_CUBE_MAP) ? target : 0; - - if (wholeMipmap) { - pImageGL = new (amdContext) - ImageGL(amdContext, clType, clFlags, clImageFormat, static_cast(gliTexWidth), - static_cast(gliTexHeight), static_cast(gliTexDepth), glTarget, - texture, miplevel, glInternalFormat, clGLType, numSamples, gliTexMaxLevel, target); - } else { - pImageGL = new (amdContext) - ImageGL(amdContext, clType, clFlags, clImageFormat, static_cast(gliTexWidth), - static_cast(gliTexHeight), static_cast(gliTexDepth), glTarget, - texture, miplevel, glInternalFormat, clGLType, numSamples, target); - } - - if (!pImageGL) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - LogWarning("Cannot create class ImageGL - out of memory?"); - return static_cast(0); - } - - if (!pImageGL->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImageGL->release(); - return static_cast(0); - } - *not_null(errcode_ret) = CL_SUCCESS; return as_cl(pImageGL); } @@ -1553,25 +1558,24 @@ cl_mem clCreateFromGLRenderbufferAMD(Context& amdContext, cl_mem_flags clFlags, // PBO and mapping will be done at "acquire" time (sync point) + pImageGL = + new (amdContext) ImageGL(amdContext, CL_MEM_OBJECT_IMAGE2D, clFlags, clImageFormat, + (size_t)gliRbWidth, (size_t)gliRbHeight, 1, glTarget, renderbuffer, + 0, glInternalFormat, CL_GL_OBJECT_RENDERBUFFER, 0); + + if (!pImageGL) { + *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; + LogWarning("Cannot create class ImageGL from renderbuffer - out of memory?"); + return (cl_mem)0; + } + + if (!pImageGL->create()) { + *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; + pImageGL->release(); + return (cl_mem)0; + } } // Release scoped lock - pImageGL = - new (amdContext) ImageGL(amdContext, CL_MEM_OBJECT_IMAGE2D, clFlags, clImageFormat, - (size_t)gliRbWidth, (size_t)gliRbHeight, 1, glTarget, renderbuffer, - 0, glInternalFormat, CL_GL_OBJECT_RENDERBUFFER, 0); - - if (!pImageGL) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - LogWarning("Cannot create class ImageGL from renderbuffer - out of memory?"); - return (cl_mem)0; - } - - if (!pImageGL->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImageGL->release(); - return (cl_mem)0; - } - *not_null(errcode_ret) = CL_SUCCESS; return as_cl(pImageGL); } @@ -1627,6 +1631,7 @@ cl_int clEnqueueAcquireExtObjectsAMD(cl_command_queue command_queue, cl_uint num // that any such pending OpenGL operations are complete for an OpenGL context bound // to the same thread as the OpenCL context. if (hostQueue.device().settings().checkExtension(ClKhrGlEvent)) { + GLFunctions::Lock lock(gl_functions); gl_functions->WaitCurrentGlContext(hostQueue.context().info()); } } diff --git a/projects/clr/rocclr/platform/interop_gl.cpp b/projects/clr/rocclr/platform/interop_gl.cpp index 20cf3a7d05..7bb285b30f 100644 --- a/projects/clr/rocclr/platform/interop_gl.cpp +++ b/projects/clr/rocclr/platform/interop_gl.cpp @@ -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(-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(-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(-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(-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), diff --git a/projects/clr/rocclr/platform/interop_gl.hpp b/projects/clr/rocclr/platform/interop_gl.hpp index f7ab95804b..0523b9211a 100644 --- a/projects/clr/rocclr/platform/interop_gl.hpp +++ b/projects/clr/rocclr/platform/interop_gl.hpp @@ -280,6 +280,19 @@ public: bool isValid_; //!< If TRUE, then it's a valid setup }; + //! Locks any access to the virtual GPUs + class Lock : public amd::StackObject { + public: + //! Default constructor + Lock(GLFunctions* env); + + //! Destructor + ~Lock(); + + private: + GLFunctions* env_; //!< GL environment + }; + private: HMODULE libHandle_; int missed_; // Indicates how many GL functions not init'ed, if any