SWDEV-567119 - Windows GL Interop Support (#1892)

This commit is contained in:
Jin Jung
2025-12-08 08:03:59 -08:00
gecommit door GitHub
bovenliggende 4812d8e78b
commit deaf8ab38a
11 gewijzigde bestanden met toevoegingen van 299 en 104 verwijderingen
@@ -76,7 +76,6 @@ target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/device/rocm/rocblitcl.cpp
${ROCCLR_SRC_DIR}/device/rocm/roccounters.cpp
${ROCCLR_SRC_DIR}/device/rocm/rocdevice.cpp
${ROCCLR_SRC_DIR}/device/rocm/rocglinterop.cpp
${ROCCLR_SRC_DIR}/device/rocm/rockernel.cpp
${ROCCLR_SRC_DIR}/device/rocm/rocmemory.cpp
${ROCCLR_SRC_DIR}/device/rocm/rocprintf.cpp
@@ -86,4 +85,12 @@ target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/device/rocm/rocvirtual.cpp
${ROCCLR_SRC_DIR}/device/rocm/rocurilocator.cpp)
if(UNIX)
target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/device/rocm/rocglinterop.cpp)
else()
target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/device/rocm/rocglinterop_windows.cpp)
endif()
target_compile_definitions(rocclr PUBLIC WITH_HSA_DEVICE)
@@ -992,6 +992,15 @@ bool Device::populateOCLDeviceConstants() {
info_.uuid_[i] = unique_id[i + 4];
}
}
hsa_luid_t localUID = {0};
if (HSA_STATUS_SUCCESS ==
Hsa::agent_get_info(bkendDevice_, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_LUID),
&localUID)) {
info_.luidLowPart_ = localUID.low;
info_.luidHighPart_ = localUID.high;
}
if (HSA_STATUS_SUCCESS !=
Hsa::agent_get_info(bkendDevice_,
(amd::IS_HIP)
@@ -1743,53 +1752,33 @@ bool Device::amdFileWrite(amd::Os::FileDesc handle, void* devicePtr, uint64_t si
return true;
}
// ================================================================================================
bool Device::bindExternalDevice(uint flags, void* const gfxDevice[], void* gfxContext,
bool validateOnly) {
#if defined(_WIN32)
return false;
#else
if ((flags & amd::Context::GLDeviceKhr) == 0) return false;
MesaInterop::MESA_INTEROP_KIND kind = MesaInterop::MESA_INTEROP_NONE;
MesaInterop::DisplayHandle display;
MesaInterop::ContextHandle context;
if ((flags & amd::Context::EGLDeviceKhr) != 0) {
kind = MesaInterop::MESA_INTEROP_EGL;
display.eglDisplay = reinterpret_cast<EGLDisplay>(gfxDevice[amd::Context::GLDeviceKhrIdx]);
context.eglContext = reinterpret_cast<EGLContext>(gfxContext);
} else {
kind = MesaInterop::MESA_INTEROP_GLX;
display.glxDisplay = reinterpret_cast<Display*>(gfxDevice[amd::Context::GLDeviceKhrIdx]);
context.glxContext = reinterpret_cast<GLXContext>(gfxContext);
}
mesa_glinterop_device_info info;
info.version = MESA_GLINTEROP_DEVICE_INFO_VERSION;
if (!MesaInterop::Init(kind)) {
void* glDevice = gfxDevice[amd::Context::DeviceFlagIdx::GLDeviceKhrIdx];
if (!GlInterop::glAssociate(this, flags, gfxContext, glDevice)) {
LogError("Failed GlInterop::glAssociate()");
return false;
}
if (!MesaInterop::GetInfo(info, kind, display, context)) {
return false;
}
return info_.deviceTopology_.pcie.bus == info.pci_bus &&
info_.deviceTopology_.pcie.device == info.pci_device &&
info_.deviceTopology_.pcie.function == info.pci_function &&
info_.vendorId_ == info.vendor_id && pciDeviceId_ == info.device_id;
#endif
return true;
}
// ================================================================================================
bool Device::unbindExternalDevice(uint flags, void* const gfxDevice[], void* gfxContext,
bool validateOnly) {
#if defined(_WIN32)
return false;
#else
if ((flags & amd::Context::GLDeviceKhr) == 0) return false;
void* glDevice = gfxDevice[amd::Context::DeviceFlagIdx::GLDeviceKhrIdx];
if (glDevice != nullptr) {
if (!GlInterop::glDissociate(this, gfxContext, glDevice)) {
LogWarning("Failed GlInterop::glDissociate()");
return false;
}
}
return true;
#endif
}
amd::Memory* Device::findMapTarget(size_t size) const {
@@ -1,4 +1,4 @@
/* Copyright (c) 2016 - 2021 Advanced Micro Devices, Inc.
/* Copyright (c) 2016 - 2025 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,20 +18,20 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
#if defined(_WIN32)
#error "This file is not expected to be compiled on Windows."
#endif
#include "os/os.hpp"
#include "utils/debug.hpp"
#include "utils/flags.hpp"
#include "device/rocm/rocglinterop.hpp"
#if !defined(_WIN32)
#include <dlfcn.h>
#endif
namespace amd::roc {
namespace GlInterop {
namespace MesaInterop {
#if !defined(_WIN32)
static PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC* GlxInfo = nullptr;
static PFNMESAGLINTEROPGLXEXPORTOBJECTPROC* GlxExport = nullptr;
static PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC* EglInfo = nullptr;
@@ -39,9 +39,7 @@ static PFNMESAGLINTEROPEGLEXPORTOBJECTPROC* EglExport = nullptr;
static MESA_INTEROP_KIND loadedGLAPITypes(MESA_INTEROP_NONE);
using PFNGLXGETPROCADDRESSPROC = void* (*)(const GLubyte* procname);
using PFNEGLGETPROCADDRESSPROC = void* (*)(const char* procName);
#endif
static constexpr const char* errorStrings[] = {"MESA_GLINTEROP_SUCCESS",
"MESA_GLINTEROP_OUT_OF_RESOURCES",
@@ -55,63 +53,55 @@ static constexpr const char* errorStrings[] = {"MESA_GLINTEROP_SUCCESS",
"MESA_GLINTEROP_INVALID_MIP_LEVEL",
"MESA_GLINTEROP_UNSUPPORTED"};
bool Supported() {
#ifdef _WIN32
return false;
#else
return true;
#endif
}
#if !defined(_WIN32)
// ================================================================================================
// Fallback for older OS' and Mesa versions
static void LegacyInitGLX() {
if (!GlxInfo) {
GlxInfo = (PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC*)dlsym(RTLD_DEFAULT,
"MesaGLInteropGLXQueryDeviceInfo");
GlxInfo = reinterpret_cast<PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC*>(
dlsym(RTLD_DEFAULT, "MesaGLInteropGLXQueryDeviceInfo"));
}
if (!GlxExport) {
GlxExport =
(PFNMESAGLINTEROPGLXEXPORTOBJECTPROC*)dlsym(RTLD_DEFAULT, "MesaGLInteropGLXExportObject");
GlxExport = reinterpret_cast<PFNMESAGLINTEROPGLXEXPORTOBJECTPROC*>(
dlsym(RTLD_DEFAULT, "MesaGLInteropGLXExportObject"));
}
}
// ================================================================================================
static void LegacyInitEGL() {
if (!EglInfo) {
EglInfo = (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC*)dlsym(RTLD_DEFAULT,
"MesaGLInteropEGLQueryDeviceInfo");
EglInfo = reinterpret_cast<PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC*>(
dlsym(RTLD_DEFAULT, "MesaGLInteropEGLQueryDeviceInfo"));
}
if (!EglExport) {
EglExport =
(PFNMESAGLINTEROPEGLEXPORTOBJECTPROC*)dlsym(RTLD_DEFAULT, "MesaGLInteropEGLExportObject");
EglExport = reinterpret_cast<PFNMESAGLINTEROPEGLEXPORTOBJECTPROC*>(
dlsym(RTLD_DEFAULT, "MesaGLInteropEGLExportObject"));
}
}
#endif
// ================================================================================================
// 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 (loadedGLAPITypes == MESA_INTEROP_NONE) {
auto glx_procaddr_fn = (PFNGLXGETPROCADDRESSPROC)dlsym(RTLD_DEFAULT, "glXGetProcAddress");
auto egl_procaddr_fn = (PFNEGLGETPROCADDRESSPROC)dlsym(RTLD_DEFAULT, "eglGetProcAddress");
static std::once_flag gGlFuncInit;
std::call_once(gGlFuncInit, [&]() {
auto glx_procaddr_fn =
reinterpret_cast<PFNGLXGETPROCADDRESSPROC>(dlsym(RTLD_DEFAULT, "glXGetProcAddress"));
auto egl_procaddr_fn =
reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(dlsym(RTLD_DEFAULT, "eglGetProcAddress"));
if (glx_procaddr_fn) {
GlxInfo = (PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC*)glx_procaddr_fn(
(const GLubyte*)"glXGLInteropQueryDeviceInfoMESA");
GlxExport = (PFNMESAGLINTEROPGLXEXPORTOBJECTPROC*)glx_procaddr_fn(
(const GLubyte*)"glXGLInteropExportObjectMESA");
GlxInfo = reinterpret_cast<PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC*>(
glx_procaddr_fn(reinterpret_cast<const GLubyte*>("glXGLInteropQueryDeviceInfoMESA")));
GlxExport = reinterpret_cast<PFNMESAGLINTEROPGLXEXPORTOBJECTPROC*>(
glx_procaddr_fn(reinterpret_cast<const GLubyte*>("glXGLInteropExportObjectMESA")));
}
if (egl_procaddr_fn) {
EglInfo = (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC*)egl_procaddr_fn(
"eglGLInteropQueryDeviceInfoMESA");
EglExport =
(PFNMESAGLINTEROPEGLEXPORTOBJECTPROC*)egl_procaddr_fn("eglGLInteropExportObjectMESA");
EglInfo = reinterpret_cast<PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC*>(
egl_procaddr_fn("eglGLInteropQueryDeviceInfoMESA"));
EglExport = reinterpret_cast<PFNMESAGLINTEROPEGLEXPORTOBJECTPROC*>(
egl_procaddr_fn("eglGLInteropExportObjectMESA"));
}
if (!GlxInfo || !GlxExport) {
@@ -132,17 +122,14 @@ bool Init(MESA_INTEROP_KIND Kind) {
}
loadedGLAPITypes = MESA_INTEROP_KIND(ret);
}
});
return ((loadedGLAPITypes & Kind) == Kind);
#endif
}
// ================================================================================================
bool GetInfo(mesa_glinterop_device_info& info, MESA_INTEROP_KIND Kind, const DisplayHandle display,
const ContextHandle context) {
#ifdef _WIN32
return false;
#else
assert((loadedGLAPITypes & Kind) == Kind && "Requested interop API is not currently loaded.");
int ret;
switch (Kind) {
@@ -157,19 +144,16 @@ bool GetInfo(mesa_glinterop_device_info& info, MESA_INTEROP_KIND Kind, const Dis
return false;
}
if (ret == MESA_GLINTEROP_SUCCESS) return true;
if (ret < int(sizeof(errorStrings) / sizeof(errorStrings[0])))
if (ret < static_cast<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 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
assert((loadedGLAPITypes & Kind) == Kind && "Requested interop API is not currently loaded.");
int ret;
switch (Kind) {
@@ -184,12 +168,49 @@ bool Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out, MESA_I
return false;
}
if (ret == MESA_GLINTEROP_SUCCESS) return true;
if (ret < int(sizeof(errorStrings) / sizeof(errorStrings[0])))
if (ret < static_cast<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
}
} // namespace MesaInterop
// ================================================================================================
bool glAssociate(Device* device, uint flags, void* gfxContext, void* glDevice) {
if ((flags & amd::Context::GLDeviceKhr) == 0) return false;
MESA_INTEROP_KIND kind;
DisplayHandle display;
ContextHandle context;
if ((flags & amd::Context::EGLDeviceKhr) != 0) {
kind = MESA_INTEROP_EGL;
display.eglDisplay = reinterpret_cast<EGLDisplay>(glDevice);
context.eglContext = reinterpret_cast<EGLContext>(gfxContext);
} else {
kind = MESA_INTEROP_GLX;
display.glxDisplay = reinterpret_cast<Display*>(glDevice);
context.glxContext = reinterpret_cast<GLXContext>(gfxContext);
}
mesa_glinterop_device_info info = {.version = MESA_GLINTEROP_DEVICE_INFO_VERSION};
if (!Init(kind) || !GetInfo(info, kind, display, context))
return false;
const auto& pcie = device->info().deviceTopology_.pcie;
const auto& dev_info = device->info();
return pcie.bus == info.pci_bus &&
pcie.device == info.pci_device &&
pcie.function == info.pci_function &&
dev_info.vendorId_ == info.vendor_id &&
dev_info.pcieDeviceId_ == info.device_id;
}
// ================================================================================================
bool glDissociate(Device*, void*, void*) {
return true;
}
} // namespace GlInterop
} // namespace amd::roc
@@ -102,7 +102,9 @@ class image_metadata {
}
};
namespace MesaInterop {
namespace GlInterop {
#if !defined(_WIN32)
enum MESA_INTEROP_KIND { MESA_INTEROP_NONE = 0, MESA_INTEROP_GLX = 1, MESA_INTEROP_EGL = 2 };
union DisplayHandle {
@@ -121,9 +123,6 @@ union ContextHandle {
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);
@@ -133,6 +132,9 @@ bool GetInfo(mesa_glinterop_device_info& info, MESA_INTEROP_KIND Kind, const Dis
bool Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out, MESA_INTEROP_KIND Kind,
const DisplayHandle display, const ContextHandle context);
} // namespace MesaInterop
} // namespace amd::roc
#endif
bool glAssociate(Device* device, uint flags, void* GLplatformContext, void* GLdeviceContext);
bool glDissociate(Device* device, void* GLplatformContext, void* GLdeviceContext);
} // namespace GlInterop
} // namespace amd::roc
@@ -0,0 +1,160 @@
/* Copyright (c) 2025 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. */
#include "os/os.hpp"
#include "utils/debug.hpp"
#include "utils/flags.hpp"
#include "device/rocm/rocglinterop.hpp"
#include "GL/gl_interop.h"
namespace amd::roc {
namespace GlInterop {
typedef PROC(WINAPI* PFNWGLGETPROCADDRESS)(LPCSTR name);
typedef HGLRC(WINAPI* PFNWGLGETCURRENTCONTEXT)(void);
typedef HGLRC(WINAPI* PFNWGLCREATECONTEXT)(HDC hdc);
typedef BOOL(WINAPI* PFNWGLDELETECONTEXT)(HGLRC hglrc);
typedef BOOL(WINAPI* PFNWGLMAKECURRENT)(HDC hdc, HGLRC hglrc);
static PFNWGLGETPROCADDRESS pfnWglGetProcAddress = nullptr;
static PFNWGLGETCURRENTCONTEXT pfnWglGetCurrentContext = nullptr;
static PFNWGLCREATECONTEXT pfnWglCreateContext = nullptr;
static PFNWGLDELETECONTEXT pfnWglDeleteContext = nullptr;
static PFNWGLMAKECURRENT pfnWglMakeCurrent = nullptr;
static PFNWGLBEGINCLINTEROPAMD wglBeginCLInteropAMD = nullptr;
static PFNWGLENDCLINTEROPAMD wglEndCLInteropAMD = nullptr;
static PFNWGLRESOURCEATTACHAMD wglResourceAttachAMD = nullptr;
static PFNWGLRESOURCEDETACHAMD wglResourceAcquireAMD = nullptr;
static PFNWGLRESOURCEDETACHAMD wglResourceReleaseAMD = nullptr;
static PFNWGLRESOURCEDETACHAMD wglResourceDetachAMD = nullptr;
static PFNWGLGETCONTEXTGPUINFOAMD wglGetContextGPUInfoAMD = nullptr;
// ================================================================================================
bool initGLInteropPrivateExt(void* GLdeviceContext) {
static std::once_flag gGlFuncInit;
static bool gGlFuncLoaded = false;
std::call_once(gGlFuncInit, [GLdeviceContext]() {
if (!GLdeviceContext) {
LogError("GLdeviceContext is null");
return;
}
HMODULE h = static_cast<HMODULE>(amd::Os::loadLibrary("opengl32.dll"));
if (!h) {
LogError("Couldn't load opengl32.dll");
return;
}
pfnWglGetProcAddress =
reinterpret_cast<PFNWGLGETPROCADDRESS>(GetProcAddress(h, "wglGetProcAddress"));
pfnWglGetCurrentContext =
reinterpret_cast<PFNWGLGETCURRENTCONTEXT>(GetProcAddress(h, "wglGetCurrentContext"));
pfnWglCreateContext =
reinterpret_cast<PFNWGLCREATECONTEXT>(GetProcAddress(h, "wglCreateContext"));
pfnWglDeleteContext =
reinterpret_cast<PFNWGLDELETECONTEXT>(GetProcAddress(h, "wglDeleteContext"));
pfnWglMakeCurrent = reinterpret_cast<PFNWGLMAKECURRENT>(GetProcAddress(h, "wglMakeCurrent"));
if (!pfnWglGetProcAddress || !pfnWglGetCurrentContext || !pfnWglCreateContext ||
!pfnWglDeleteContext || !pfnWglMakeCurrent) {
LogError("Couldn't obtain WGL context API");
return;
}
// Create a temporary GL context if none is current; WGL extension
// functions require some current GL context when loaded.
HGLRC fakeRC = nullptr;
if (!pfnWglGetCurrentContext()) {
fakeRC = pfnWglCreateContext(static_cast<HDC>(GLdeviceContext));
if (fakeRC == nullptr) {
LogError("Couldn't create temporary WGL context");
return;
}
pfnWglMakeCurrent(static_cast<HDC>(GLdeviceContext), fakeRC);
}
wglBeginCLInteropAMD =
reinterpret_cast<PFNWGLBEGINCLINTEROPAMD>(pfnWglGetProcAddress("wglBeginCLInteroperabilityAMD"));
wglEndCLInteropAMD = reinterpret_cast<PFNWGLENDCLINTEROPAMD>(pfnWglGetProcAddress("wglEndCLInteroperabilityAMD"));
wglResourceAttachAMD = reinterpret_cast<PFNWGLRESOURCEATTACHAMD>(pfnWglGetProcAddress("wglResourceAttachAMD"));
wglResourceAcquireAMD = reinterpret_cast<PFNWGLRESOURCEDETACHAMD>(pfnWglGetProcAddress("wglResourceAcquireAMD"));
wglResourceReleaseAMD = reinterpret_cast<PFNWGLRESOURCEDETACHAMD>(pfnWglGetProcAddress("wglResourceReleaseAMD"));
wglResourceDetachAMD = reinterpret_cast<PFNWGLRESOURCEDETACHAMD>(pfnWglGetProcAddress("wglResourceDetachAMD"));
wglGetContextGPUInfoAMD =
reinterpret_cast<PFNWGLGETCONTEXTGPUINFOAMD>(pfnWglGetProcAddress("wglGetContextGPUInfoAMD"));
if (fakeRC) {
pfnWglMakeCurrent(nullptr, nullptr);
pfnWglDeleteContext(fakeRC);
}
gGlFuncLoaded = wglBeginCLInteropAMD && wglEndCLInteropAMD && wglResourceAttachAMD &&
wglResourceAcquireAMD && wglResourceReleaseAMD &&
wglResourceDetachAMD && wglGetContextGPUInfoAMD;
});
return gGlFuncLoaded;
}
// ================================================================================================
bool glCanInterop(Device* device, void* GLplatformContext, void* GLdeviceContext) {
bool canInteroperate = false;
LUID glAdapterLuid = {0, 0};
UINT glChainBitMask = 0;
HGLRC hRC = static_cast<HGLRC>(GLplatformContext);
// get GL context's LUID and chainBitMask from UGL
if (wglGetContextGPUInfoAMD(hRC, &glAdapterLuid, &glChainBitMask)) {
// match the adapter
canInteroperate = device->info().luidLowPart_ == glAdapterLuid.LowPart &&
device->info().luidHighPart_ == glAdapterLuid.HighPart &&
(((1 << device->index()) & glChainBitMask) != 0);
}
return canInteroperate;
}
// ================================================================================================
bool glAssociate(Device* device, uint flags, void* GLplatformContext, void* GLdeviceContext) {
static_cast<void>(flags); // unused
if (!initGLInteropPrivateExt(GLdeviceContext)) return false;
if (!glCanInterop(device, GLplatformContext, GLdeviceContext)) {
return false;
}
return wglBeginCLInteropAMD(static_cast<HGLRC>(GLplatformContext), 0) != FALSE;
}
// ================================================================================================
bool glDissociate(Device* device, void* GLplatformContext, void* GLdeviceContext) {
static_cast<void>(device); // unused
if (!initGLInteropPrivateExt(GLdeviceContext)) return false;
return wglEndCLInteropAMD(static_cast<HGLRC>(GLplatformContext), 0) != FALSE;
}
} // namespace GlInterop
} // namespace amd::roc
@@ -269,11 +269,11 @@ bool Memory::createInteropBuffer(GLenum targetType, int miplevel) {
const auto& glenv = owner()->getContext().glenv();
if (glenv->isEGL()) {
if (!MesaInterop::Export(in, out, MesaInterop::MESA_INTEROP_EGL, glenv->getEglDpy(),
if (!GlInterop::Export(in, out, GlInterop::MESA_INTEROP_EGL, glenv->getEglDpy(),
glenv->getEglOrigCtx()))
return false;
} else {
if (!MesaInterop::Export(in, out, MesaInterop::MESA_INTEROP_GLX, glenv->getDpy(),
if (!GlInterop::Export(in, out, GlInterop::MESA_INTEROP_GLX, glenv->getDpy(),
glenv->getOrigCtx()))
return false;
}
@@ -1606,4 +1606,3 @@ amd::Image* Image::FindView(cl_image_format format) const {
}
} // namespace amd::roc
@@ -1,4 +1,4 @@
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
/* Copyright (c) 2010 - 2025 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -127,10 +127,7 @@ bool Settings::create(bool fullProfile, const amd::Isa& isa, bool enableXNACK, b
enableExtension(ClAmdMediaOps);
enableExtension(ClAmdMediaOps2);
enableExtension(ClKhrImage2dFromBuffer);
if (MesaInterop::Supported()) {
enableExtension(ClKhrGlSharing);
}
enableExtension(ClKhrGlSharing);
// Enable platform extension
enableExtension(ClAmdDeviceAttributeQuery);
@@ -349,6 +349,9 @@ typedef struct _HsaNodeProperties
HSAuint32 KFDGpuID; // GPU Hash ID generated by KFD
HSAuint32 FamilyID; // GPU family id
HSAuint32 LuidLowPart; // Windows Locally Unique Identifier Low 4 bytes
HSAuint32 LuidHighPart; // Windows Locally Unique Identifier High 4 bytes
} HsaNodeProperties;
@@ -1713,6 +1713,10 @@ hsa_status_t GpuAgent::GetInfo(hsa_agent_info_t attribute, void* value) const {
case HSA_AMD_AGENT_INFO_PM4_EMULATION:
*((bool*)value) = properties_.Capability2.ui32.AqlEmulationPm4_;
break;
case HSA_AMD_AGENT_INFO_LUID:
static_cast<hsa_luid_t*>(value)->low = properties_.LuidLowPart;
static_cast<hsa_luid_t*>(value)->high = properties_.LuidHighPart;
break;
default:
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
break;
@@ -5691,6 +5691,14 @@ typedef void* hsa_handle_t;
typedef int hsa_handle_t;
#endif
/**
* @brief Platform-independent container for a Windows LUID.
*/
typedef struct hsa_luid_s {
uint32_t low; //!< Luid low 4 bytes, valid only on Windows
uint32_t high; //!< Luid high 4 bytes, valid only on Windows
} hsa_luid_t;
/**
* @deprecated
*
@@ -709,7 +709,12 @@ typedef enum hsa_amd_agent_info_s {
/**
* The agent uses PM4 emulation mode.
*/
HSA_AMD_AGENT_INFO_PM4_EMULATION = 0xA119
HSA_AMD_AGENT_INFO_PM4_EMULATION = 0xA119,
/**
* Queries for the LUID that identifies a hardware node. The LUID is only
* valid on Windows. The type of this attribute is LUID.
*/
HSA_AMD_AGENT_INFO_LUID = 0xA11A,
} hsa_amd_agent_info_t;
/**