From fd96c14e2302729603b56b9fa67d6bae2b20ea06 Mon Sep 17 00:00:00 2001 From: foreman Date: Mon, 12 Feb 2018 18:02:35 -0500 Subject: [PATCH] P4 to Git Change 1515374 by skeely@skeely_HSA_linux on 2018/02/12 17:53:32 SWDEV-94389 - Get gl display and context from cl context object. Also report Mesa interop errors in debug log. Affected files ... ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_gl_amd.hpp#20 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#82 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.hpp#25 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.cpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.cpp#33 edit [ROCm/clr commit: 7175a76b6db1d14e4350a16b82bec2078d5a101d] --- .../rocclr/runtime/device/rocm/rocdevice.cpp | 10 +- .../rocclr/runtime/device/rocm/rocdevice.hpp | 3 - .../runtime/device/rocm/rocglinterop.cpp | 112 +++++++++++------- .../runtime/device/rocm/rocglinterop.hpp | 87 +++++--------- .../rocclr/runtime/device/rocm/rocmemory.cpp | 11 +- 5 files changed, 109 insertions(+), 114 deletions(-) diff --git a/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp b/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp index 24bcb1cbc9..f611fecffb 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocdevice.cpp @@ -1205,14 +1205,11 @@ bool Device::bindExternalDevice(uint flags, void* const gfxDevice[], void* gfxCo mesa_glinterop_device_info info; info.size = sizeof(mesa_glinterop_device_info); - MesaInterop temp; - if (!temp.Bind(kind, display, context)) { - assert(false && "Failed mesa interop bind."); + if (!MesaInterop::Init(kind)) { return false; } - if (!temp.GetInfo(info)) { - assert(false && "Failed to get mesa interop device info."); + if (!MesaInterop::GetInfo(info, kind, display, context)) { return false; } @@ -1223,8 +1220,6 @@ bool Device::bindExternalDevice(uint flags, void* const gfxDevice[], void* gfxCo match &= info_.vendorId_ == info.vendor_id; match &= deviceInfo_.pciDeviceId_ == info.device_id; - if (!validateOnly) mesa_ = temp; - return match; #endif } @@ -1235,7 +1230,6 @@ bool Device::unbindExternalDevice(uint flags, void* const gfxDevice[], void* gfx return false; #else if ((flags & amd::Context::GLDeviceKhr) == 0) return false; - if (!validateOnly) mesa_.Unbind(); return true; #endif } diff --git a/projects/clr/rocclr/runtime/device/rocm/rocdevice.hpp b/projects/clr/rocclr/runtime/device/rocm/rocdevice.hpp index 7630b70b72..56e2c5723e 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocdevice.hpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocdevice.hpp @@ -367,8 +367,6 @@ class Device : public NullDevice { const hsa_profile_t agent_profile() const { return agent_profile_; } - const MesaInterop& mesa() const { return mesa_; } - //! Finds an appropriate map target amd::Memory* findMapTarget(size_t size) const; @@ -417,7 +415,6 @@ class Device : public NullDevice { static hsa_agent_t cpu_agent_; static std::vector gpu_agents_; std::vector p2p_agents_; //!< List of P2P agents available for this device - MesaInterop mesa_; hsa_agent_t _bkendDevice; hsa_profile_t agent_profile_; hsa_amd_memory_pool_t group_segment_; diff --git a/projects/clr/rocclr/runtime/device/rocm/rocglinterop.cpp b/projects/clr/rocclr/runtime/device/rocm/rocglinterop.cpp index 463ba31545..fd6a730fcc 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocglinterop.cpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocglinterop.cpp @@ -15,16 +15,29 @@ namespace roc { +namespace MesaInterop { + #if !defined(_WIN32) static PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC GlxInfo = nullptr; static PFNMESAGLINTEROPGLXEXPORTOBJECTPROC GlxExport = nullptr; static PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC EglInfo = nullptr; static PFNMESAGLINTEROPEGLEXPORTOBJECTPROC EglExport = nullptr; +static MESA_INTEROP_KIND loadedGLAPITypes(MESA_INTEROP_NONE); #endif -std::atomic MesaInterop::refCount(0); +static const char* errorStrings[] = {"MESA_GLINTEROP_SUCCESS", + "MESA_GLINTEROP_OUT_OF_RESOURCES", + "MESA_GLINTEROP_OUT_OF_HOST_MEMORY", + "MESA_GLINTEROP_INVALID_OPERATION", + "MESA_GLINTEROP_INVALID_VALUE", + "MESA_GLINTEROP_INVALID_DISPLAY", + "MESA_GLINTEROP_INVALID_CONTEXT", + "MESA_GLINTEROP_INVALID_TARGET", + "MESA_GLINTEROP_INVALID_OBJECT", + "MESA_GLINTEROP_INVALID_MIP_LEVEL", + "MESA_GLINTEROP_UNSUPPORTED"}; -bool MesaInterop::Supported() { +bool Supported() { #ifdef _WIN32 return false; #else @@ -32,79 +45,88 @@ bool MesaInterop::Supported() { #endif } -// Attempt to locate Mesa interop APIs. Return which of glx/egl are supported. -bool MesaInterop::Bind(MESA_INTEROP_KIND Kind, const DisplayHandle& Display, - const ContextHandle& Context) { +// Returns true if the required subsystem is supported on the GL device. +// Must be called at least once, may be called multiple times. +bool Init(MESA_INTEROP_KIND Kind) { #if defined(_WIN32) return false; #else - if (Kind == MESA_INTEROP_NONE) return false; + if (loadedGLAPITypes == MESA_INTEROP_NONE) { + void* glxinfo = dlsym(RTLD_DEFAULT, "MesaGLInteropGLXQueryDeviceInfo"); + void* eglinfo = dlsym(RTLD_DEFAULT, "MesaGLInteropEGLQueryDeviceInfo"); - if (kind != MESA_INTEROP_NONE) { - LogError("Error - MesaInterop Bind while already bound."); - return false; + GlxInfo = (PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC)glxinfo; + EglInfo = (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC)eglinfo; + + GlxExport = + (PFNMESAGLINTEROPGLXEXPORTOBJECTPROC)dlsym(RTLD_DEFAULT, "MesaGLInteropGLXExportObject"); + EglExport = + (PFNMESAGLINTEROPEGLEXPORTOBJECTPROC)dlsym(RTLD_DEFAULT, "MesaGLInteropEGLExportObject"); + + uint32_t ret = MESA_INTEROP_NONE; + if (GlxInfo && GlxExport) ret |= MESA_INTEROP_GLX; + if (EglInfo && EglExport) ret |= MESA_INTEROP_EGL; + loadedGLAPITypes = MESA_INTEROP_KIND(ret); } - void* glxinfo = dlsym(RTLD_DEFAULT, "MesaGLInteropGLXQueryDeviceInfo"); - void* eglinfo = dlsym(RTLD_DEFAULT, "MesaGLInteropEGLQueryDeviceInfo"); - - if (((glxinfo != GlxInfo) || (eglinfo != EglInfo)) && (refCount != 0)) - LogWarning("Warning - Mesa changed while holding interop contexts."); - - GlxInfo = (PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC)glxinfo; - EglInfo = (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC)eglinfo; - - GlxExport = - (PFNMESAGLINTEROPGLXEXPORTOBJECTPROC)dlsym(RTLD_DEFAULT, "MesaGLInteropGLXExportObject"); - EglExport = - (PFNMESAGLINTEROPEGLEXPORTOBJECTPROC)dlsym(RTLD_DEFAULT, "MesaGLInteropEGLExportObject"); - - uint32_t ret = MESA_INTEROP_NONE; - if (GlxInfo && GlxExport) ret |= MESA_INTEROP_GLX; - if (EglInfo && EglExport) ret |= MESA_INTEROP_EGL; - - kind = MESA_INTEROP_KIND(ret & Kind); - display = Display; - context = Context; - - if (kind != MESA_INTEROP_NONE) { - refCount++; - return true; - } - return false; - + return ((loadedGLAPITypes & Kind) == Kind); #endif } -bool MesaInterop::GetInfo(mesa_glinterop_device_info& info) const { +bool GetInfo(mesa_glinterop_device_info& info, MESA_INTEROP_KIND Kind, const DisplayHandle display, + const ContextHandle context) { #ifdef _WIN32 return false; #else - switch (kind) { + assert((loadedGLAPITypes & Kind) == Kind && "Requested interop API is not currently loaded."); + int ret; + switch (Kind) { case MESA_INTEROP_GLX: - return GlxInfo(display.glxDisplay, context.glxContext, &info) == MESA_GLINTEROP_SUCCESS; + ret = GlxInfo(display.glxDisplay, context.glxContext, &info); + break; case MESA_INTEROP_EGL: - return EglInfo(display.eglDisplay, context.eglContext, &info) == MESA_GLINTEROP_SUCCESS; + ret = EglInfo(display.eglDisplay, context.eglContext, &info); + break; default: + assert(false && "Invalid interop kind."); return false; } + if (ret == MESA_GLINTEROP_SUCCESS) return true; + if (ret < int(sizeof(errorStrings) / sizeof(errorStrings[0]))) + LogPrintfError("Mesa interop: GetInfo failed with \"%s\".\n", errorStrings[ret]); + else + LogError("Mesa interop: GetInfo failed with invalid error code.\n"); + return false; #endif } -bool MesaInterop::Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out) const { +bool Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out, MESA_INTEROP_KIND Kind, + const DisplayHandle display, const ContextHandle context) { #ifdef _WIN32 return false; #else - switch (kind) { + assert((loadedGLAPITypes & Kind) == Kind && "Requested interop API is not currently loaded."); + int ret; + switch (Kind) { case MESA_INTEROP_GLX: - return GlxExport(display.glxDisplay, context.glxContext, &in, &out) == MESA_GLINTEROP_SUCCESS; + ret = GlxExport(display.glxDisplay, context.glxContext, &in, &out); + break; case MESA_INTEROP_EGL: - return EglExport(display.eglDisplay, context.eglContext, &in, &out) == MESA_GLINTEROP_SUCCESS; + ret = EglExport(display.eglDisplay, context.eglContext, &in, &out); + break; default: + assert(false && "Invalid interop kind."); return false; } + if (ret == MESA_GLINTEROP_SUCCESS) return true; + if (ret < int(sizeof(errorStrings) / sizeof(errorStrings[0]))) + LogPrintfError("Mesa interop: Export failed with \"%s\".\n", errorStrings[ret]); + else + LogError("Mesa interop: Export failed with invalid error code.\n"); + return false; #endif } } +} #endif // WITHOUT_HSA_BACKEND diff --git a/projects/clr/rocclr/runtime/device/rocm/rocglinterop.hpp b/projects/clr/rocclr/runtime/device/rocm/rocglinterop.hpp index a899096d9c..9d82d0fb14 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocglinterop.hpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocglinterop.hpp @@ -20,8 +20,6 @@ typedef void* GLXContext; #include "device/rocm/rocregisters.hpp" #include "hsa_ext_amd.h" -#include - namespace roc { // Specific typed container for version 1 @@ -78,63 +76,38 @@ class image_metadata { } }; -class MesaInterop { - public: - enum MESA_INTEROP_KIND { MESA_INTEROP_NONE = 0, MESA_INTEROP_GLX = 1, MESA_INTEROP_EGL = 2 }; +namespace MesaInterop { +enum MESA_INTEROP_KIND { MESA_INTEROP_NONE = 0, MESA_INTEROP_GLX = 1, MESA_INTEROP_EGL = 2 }; - union DisplayHandle { - Display* glxDisplay; - EGLDisplay eglDisplay; - }; - - union ContextHandle { - GLXContext glxContext; - EGLContext eglContext; - }; - - // True if the configuration supports the indicated interop ability. - static bool Supported(); - - MesaInterop() { kind = MESA_INTEROP_NONE; } - MesaInterop(const MesaInterop& rhs) { *this = rhs; } - ~MesaInterop() { Unbind(); } - - const MesaInterop& operator=(const MesaInterop& rhs) { - display = rhs.display; - context = rhs.context; - kind = rhs.kind; - if (kind != MESA_INTEROP_NONE) refCount++; - return *this; - } - - /* - Loads Mesa interop APIs and sets this interface object to use the indicated - subsystem (GLX/EGL). Returns true if the required subsystem is found. - */ - bool Bind(MESA_INTEROP_KIND Kind, const DisplayHandle& Display, const ContextHandle& Context); - - /* - Releases use of Mesa interop APIs. - Used to check for bad load/unload sequences. - */ - void Unbind() { - if (kind == MESA_INTEROP_NONE) return; - assert(refCount > 0 && "Invalid refCount in MesaInterop."); - refCount--; - kind = MESA_INTEROP_NONE; - } - - bool GetInfo(mesa_glinterop_device_info& info) const; - - bool Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out) const; - - private: - static std::atomic refCount; - - DisplayHandle display; - ContextHandle context; - MESA_INTEROP_KIND kind; +union DisplayHandle { + Display* glxDisplay; + EGLDisplay eglDisplay; + DisplayHandle() {} + DisplayHandle(Display* display) : glxDisplay(display) {} + DisplayHandle(EGLDisplay display) : eglDisplay(display) {} }; + +union ContextHandle { + GLXContext glxContext; + EGLContext eglContext; + ContextHandle() {} + ContextHandle(GLXContext context) : glxContext(context) {} + ContextHandle(EGLContext context) : eglContext(context) {} +}; + +// True if the build supports Mesa interop. +bool Supported(); + +// Returns true if the required subsystem is supported on the GL device. +// Must be called at least once, may be called multiple times. +bool Init(MESA_INTEROP_KIND Kind); + +bool GetInfo(mesa_glinterop_device_info& info, MESA_INTEROP_KIND Kind, const DisplayHandle display, + const ContextHandle context); + +bool Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out, MESA_INTEROP_KIND Kind, + const DisplayHandle display, const ContextHandle context); +} } #endif /*WITHOUT_HSA_BACKEND*/ diff --git a/projects/clr/rocclr/runtime/device/rocm/rocmemory.cpp b/projects/clr/rocclr/runtime/device/rocm/rocmemory.cpp index cd6a901686..7b5593da86 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocmemory.cpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocmemory.cpp @@ -213,7 +213,16 @@ bool Memory::createInteropBuffer(GLenum targetType, int miplevel) { in.out_driver_data_size = MaxMetadataSizeBytes; in.out_driver_data = &amdImageDesc_->data[0]; - if (!dev().mesa().Export(in, out)) return false; + const auto& glenv = owner()->getContext().glenv(); + if (glenv->isEGL()) { + if (!MesaInterop::Export(in, out, MesaInterop::MESA_INTEROP_EGL, glenv->getEglDpy(), + glenv->getEglOrigCtx())) + return false; + } else { + if (!MesaInterop::Export(in, out, MesaInterop::MESA_INTEROP_GLX, glenv->getDpy(), + glenv->getOrigCtx())) + return false; + } size_t size; size_t metadata_size = 0;