diff --git a/projects/clr/rocclr/cmake/ROCclrHSA.cmake b/projects/clr/rocclr/cmake/ROCclrHSA.cmake index f7e2ada661..37aed48e63 100644 --- a/projects/clr/rocclr/cmake/ROCclrHSA.cmake +++ b/projects/clr/rocclr/cmake/ROCclrHSA.cmake @@ -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) diff --git a/projects/clr/rocclr/device/rocm/rocdevice.cpp b/projects/clr/rocclr/device/rocm/rocdevice.cpp index 75020e2af8..40c06b2ba1 100644 --- a/projects/clr/rocclr/device/rocm/rocdevice.cpp +++ b/projects/clr/rocclr/device/rocm/rocdevice.cpp @@ -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_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(gfxDevice[amd::Context::GLDeviceKhrIdx]); - context.eglContext = reinterpret_cast(gfxContext); - } else { - kind = MesaInterop::MESA_INTEROP_GLX; - display.glxDisplay = reinterpret_cast(gfxDevice[amd::Context::GLDeviceKhrIdx]); - context.glxContext = reinterpret_cast(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 { diff --git a/projects/clr/rocclr/device/rocm/rocglinterop.cpp b/projects/clr/rocclr/device/rocm/rocglinterop.cpp index 9f48d81ade..0932797297 100644 --- a/projects/clr/rocclr/device/rocm/rocglinterop.cpp +++ b/projects/clr/rocclr/device/rocm/rocglinterop.cpp @@ -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 -#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( + dlsym(RTLD_DEFAULT, "MesaGLInteropGLXQueryDeviceInfo")); } if (!GlxExport) { - GlxExport = - (PFNMESAGLINTEROPGLXEXPORTOBJECTPROC*)dlsym(RTLD_DEFAULT, "MesaGLInteropGLXExportObject"); + GlxExport = reinterpret_cast( + dlsym(RTLD_DEFAULT, "MesaGLInteropGLXExportObject")); } } +// ================================================================================================ static void LegacyInitEGL() { if (!EglInfo) { - EglInfo = (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC*)dlsym(RTLD_DEFAULT, - "MesaGLInteropEGLQueryDeviceInfo"); + EglInfo = reinterpret_cast( + dlsym(RTLD_DEFAULT, "MesaGLInteropEGLQueryDeviceInfo")); } if (!EglExport) { - EglExport = - (PFNMESAGLINTEROPEGLEXPORTOBJECTPROC*)dlsym(RTLD_DEFAULT, "MesaGLInteropEGLExportObject"); + EglExport = reinterpret_cast( + 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(dlsym(RTLD_DEFAULT, "glXGetProcAddress")); + auto egl_procaddr_fn = + reinterpret_cast(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( + glx_procaddr_fn(reinterpret_cast("glXGLInteropQueryDeviceInfoMESA"))); + GlxExport = reinterpret_cast( + glx_procaddr_fn(reinterpret_cast("glXGLInteropExportObjectMESA"))); } if (egl_procaddr_fn) { - EglInfo = (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC*)egl_procaddr_fn( - "eglGLInteropQueryDeviceInfoMESA"); - EglExport = - (PFNMESAGLINTEROPEGLEXPORTOBJECTPROC*)egl_procaddr_fn("eglGLInteropExportObjectMESA"); + EglInfo = reinterpret_cast( + egl_procaddr_fn("eglGLInteropQueryDeviceInfoMESA")); + EglExport = reinterpret_cast( + 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(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(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(glDevice); + context.eglContext = reinterpret_cast(gfxContext); + } else { + kind = MESA_INTEROP_GLX; + display.glxDisplay = reinterpret_cast(glDevice); + context.glxContext = reinterpret_cast(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 diff --git a/projects/clr/rocclr/device/rocm/rocglinterop.hpp b/projects/clr/rocclr/device/rocm/rocglinterop.hpp index c19dd1be8b..ee10fe139d 100644 --- a/projects/clr/rocclr/device/rocm/rocglinterop.hpp +++ b/projects/clr/rocclr/device/rocm/rocglinterop.hpp @@ -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 diff --git a/projects/clr/rocclr/device/rocm/rocglinterop_windows.cpp b/projects/clr/rocclr/device/rocm/rocglinterop_windows.cpp new file mode 100644 index 0000000000..1bb66f124c --- /dev/null +++ b/projects/clr/rocclr/device/rocm/rocglinterop_windows.cpp @@ -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(amd::Os::loadLibrary("opengl32.dll")); + + if (!h) { + LogError("Couldn't load opengl32.dll"); + return; + } + + pfnWglGetProcAddress = + reinterpret_cast(GetProcAddress(h, "wglGetProcAddress")); + pfnWglGetCurrentContext = + reinterpret_cast(GetProcAddress(h, "wglGetCurrentContext")); + pfnWglCreateContext = + reinterpret_cast(GetProcAddress(h, "wglCreateContext")); + pfnWglDeleteContext = + reinterpret_cast(GetProcAddress(h, "wglDeleteContext")); + pfnWglMakeCurrent = reinterpret_cast(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(GLdeviceContext)); + if (fakeRC == nullptr) { + LogError("Couldn't create temporary WGL context"); + return; + } + pfnWglMakeCurrent(static_cast(GLdeviceContext), fakeRC); + } + + wglBeginCLInteropAMD = + reinterpret_cast(pfnWglGetProcAddress("wglBeginCLInteroperabilityAMD")); + wglEndCLInteropAMD = reinterpret_cast(pfnWglGetProcAddress("wglEndCLInteroperabilityAMD")); + wglResourceAttachAMD = reinterpret_cast(pfnWglGetProcAddress("wglResourceAttachAMD")); + wglResourceAcquireAMD = reinterpret_cast(pfnWglGetProcAddress("wglResourceAcquireAMD")); + wglResourceReleaseAMD = reinterpret_cast(pfnWglGetProcAddress("wglResourceReleaseAMD")); + wglResourceDetachAMD = reinterpret_cast(pfnWglGetProcAddress("wglResourceDetachAMD")); + wglGetContextGPUInfoAMD = + reinterpret_cast(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(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(flags); // unused + + if (!initGLInteropPrivateExt(GLdeviceContext)) return false; + + if (!glCanInterop(device, GLplatformContext, GLdeviceContext)) { + return false; + } + + return wglBeginCLInteropAMD(static_cast(GLplatformContext), 0) != FALSE; +} + +// ================================================================================================ +bool glDissociate(Device* device, void* GLplatformContext, void* GLdeviceContext) { + static_cast(device); // unused + + if (!initGLInteropPrivateExt(GLdeviceContext)) return false; + + return wglEndCLInteropAMD(static_cast(GLplatformContext), 0) != FALSE; +} + +} // namespace GlInterop +} // namespace amd::roc diff --git a/projects/clr/rocclr/device/rocm/rocmemory.cpp b/projects/clr/rocclr/device/rocm/rocmemory.cpp index 2b4e59b28e..7e7c3f31d9 100644 --- a/projects/clr/rocclr/device/rocm/rocmemory.cpp +++ b/projects/clr/rocclr/device/rocm/rocmemory.cpp @@ -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 - diff --git a/projects/clr/rocclr/device/rocm/rocsettings.cpp b/projects/clr/rocclr/device/rocm/rocsettings.cpp index 48aa4328ca..3899f2cf8b 100644 --- a/projects/clr/rocclr/device/rocm/rocsettings.cpp +++ b/projects/clr/rocclr/device/rocm/rocsettings.cpp @@ -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); diff --git a/projects/rocr-runtime/libhsakmt/include/hsakmt/hsakmttypes.h b/projects/rocr-runtime/libhsakmt/include/hsakmt/hsakmttypes.h index d621158997..53ea25a714 100644 --- a/projects/rocr-runtime/libhsakmt/include/hsakmt/hsakmttypes.h +++ b/projects/rocr-runtime/libhsakmt/include/hsakmt/hsakmttypes.h @@ -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; diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp index 88e8065a44..2537bb8256 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp @@ -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(value)->low = properties_.LuidLowPart; + static_cast(value)->high = properties_.LuidHighPart; + break; default: return HSA_STATUS_ERROR_INVALID_ARGUMENT; break; diff --git a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa.h b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa.h index 9d98bef5a0..80e7e5e9d5 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa.h @@ -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 * diff --git a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h index b1c5e8e67b..8c0a64afa5 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa_ext_amd.h @@ -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; /**