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;