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: 7175a76b6d]
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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<hsa_agent_t> gpu_agents_;
|
||||
std::vector<hsa_agent_t> 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_;
|
||||
|
||||
@@ -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<uint32_t> 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
|
||||
|
||||
@@ -20,8 +20,6 @@ typedef void* GLXContext;
|
||||
#include "device/rocm/rocregisters.hpp"
|
||||
#include "hsa_ext_amd.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
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<uint32_t> 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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user