SWDEV-570501 - Add Windows support for hipGraphicsGLRegisterBuffer (#2323)
Dieser Commit ist enthalten in:
@@ -74,10 +74,9 @@ bool Stream::Create() { return create(); }
|
||||
// ================================================================================================
|
||||
void Stream::Destroy(hip::Stream* stream, bool forceDestroy) {
|
||||
stream->device().removeFromActiveQueues(stream);
|
||||
stream->device_->RemoveStream(stream);
|
||||
stream->GetDevice()->RemoveStream(stream);
|
||||
stream->SetForceDestroy(forceDestroy);
|
||||
stream->release();
|
||||
stream = nullptr;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
|
||||
@@ -136,5 +136,7 @@ bool Export(mesa_glinterop_export_in& in, mesa_glinterop_export_out& out, MESA_I
|
||||
|
||||
bool glAssociate(Device* device, uint flags, void* GLplatformContext, void* GLdeviceContext);
|
||||
bool glDissociate(Device* device, void* GLplatformContext, void* GLdeviceContext);
|
||||
bool Export(amd::Memory* mem, GLenum targetType, int miplevel, hsa_handle_t* handle, int* offset);
|
||||
|
||||
} // namespace GlInterop
|
||||
} // namespace amd::roc
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "utils/flags.hpp"
|
||||
#include "device/rocm/rocglinterop.hpp"
|
||||
#include "GL/gl_interop.h"
|
||||
#include "platform/interop_gl.hpp"
|
||||
|
||||
namespace amd::roc {
|
||||
namespace GlInterop {
|
||||
@@ -156,5 +157,29 @@ bool glDissociate(Device* device, void* GLplatformContext, void* GLdeviceContext
|
||||
return wglEndCLInteropAMD(static_cast<HGLRC>(GLplatformContext), 0) != FALSE;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
bool Export(amd::Memory* mem, GLenum targetType, int miplevel, hsa_handle_t* handle, int* offset) {
|
||||
assert(mem->getInteropObj() != nullptr);
|
||||
assert(mem->getInteropObj()->asGLObject() != nullptr);
|
||||
|
||||
const auto* obj = mem->getInteropObj()->asGLObject();
|
||||
const auto GLContext = mem->getContext().info().hCtx_;
|
||||
const auto name = static_cast<uint>(obj->getGLName());
|
||||
|
||||
assert(targetType == GL_ARRAY_BUFFER && "Only GL_ARRAY_BUFFER is supported");
|
||||
constexpr GLenum type = GL_RESOURCE_ATTACH_VERTEXBUFFER_AMD;
|
||||
|
||||
const auto glRenderContext = reinterpret_cast<HGLRC>(GLContext);
|
||||
GLResource glResource = {.type = type, .name = name};
|
||||
GLResourceData glResourceData = {.version = GL_RESOURCE_DATA_VERSION};
|
||||
|
||||
if (!wglResourceAttachAMD(glRenderContext, static_cast<GLvoid*>(&glResource), &glResourceData))
|
||||
return false;
|
||||
*handle = reinterpret_cast<hsa_handle_t>(glResourceData.handle);
|
||||
*offset = static_cast<int>(glResourceData.offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace GlInterop
|
||||
} // namespace amd::roc
|
||||
|
||||
@@ -202,13 +202,13 @@ void Memory::cpuUnmap(device::VirtualDevice& vDev) {
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
hsa_status_t Memory::interopMapBuffer(amd::Os::FileDesc fdn) {
|
||||
hsa_status_t Memory::interopMapBuffer(hsa_handle_t fdn, hsa_interop_map_flag_t flags) {
|
||||
hsa_agent_t agent = dev().getBackendDevice();
|
||||
size_t size;
|
||||
size_t metadata_size = 0;
|
||||
void* metadata;
|
||||
auto fd = fdn;
|
||||
hsa_status_t status = Hsa::interop_map_buffer(1, &agent, fd, 0, &size, &interop_deviceMemory_,
|
||||
hsa_status_t status = Hsa::interop_map_buffer(1, &agent, fd, flags, &size, &interop_deviceMemory_,
|
||||
&metadata_size, (const void**)&metadata);
|
||||
ClPrint(amd::LOG_DEBUG, amd::LOG_MEM, "Map Interop memory %p, size 0x%zx", interop_deviceMemory_,
|
||||
size);
|
||||
@@ -231,7 +231,14 @@ hsa_status_t Memory::interopMapBuffer(amd::Os::FileDesc fdn) {
|
||||
// ================================================================================================
|
||||
bool Memory::createInteropBuffer(GLenum targetType, int miplevel) {
|
||||
#if IS_WINDOWS
|
||||
return false;
|
||||
hsa_handle_t handle;
|
||||
int offset;
|
||||
|
||||
if (!GlInterop::Export(owner(), targetType, miplevel, &handle, &offset)) return false;
|
||||
if (interopMapBuffer(handle, HSA_INTEROP_MAP_FLAG_KMT_HANDLE) != HSA_STATUS_SUCCESS) return false;
|
||||
|
||||
deviceMemory_ = static_cast<char*>(interop_deviceMemory_) + offset;
|
||||
return true;
|
||||
#else
|
||||
assert(owner()->isInterop() && "Object is not an interop object.");
|
||||
|
||||
@@ -895,9 +902,7 @@ bool Buffer::create(bool alloc_local) {
|
||||
auto ext_memory = interop->asExternalMemory();
|
||||
amd::GLObject* glObject = interop->asGLObject();
|
||||
if (ext_memory != nullptr) {
|
||||
hsa_status_t status = interopMapBuffer(ext_memory->Handle());
|
||||
if (status != HSA_STATUS_SUCCESS) return false;
|
||||
return true;
|
||||
return interopMapBuffer(ext_memory->Handle()) == HSA_STATUS_SUCCESS;
|
||||
} else if (glObject != nullptr) {
|
||||
return createInteropBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,10 @@ class Memory : public device::Memory {
|
||||
|
||||
// Free / deregister device memory.
|
||||
virtual void destroy() = 0;
|
||||
hsa_status_t interopMapBuffer(amd::Os::FileDesc fdn);
|
||||
|
||||
// Map interop buffer
|
||||
hsa_status_t interopMapBuffer(hsa_handle_t fdn,
|
||||
hsa_interop_map_flag_t flags = HSA_INTEROP_MAP_FLAG_NONE);
|
||||
|
||||
// Place interop object into HSA's flat address space
|
||||
bool createInteropBuffer(GLenum targetType, int miplevel);
|
||||
|
||||
@@ -386,11 +386,11 @@ class Hsa : public amd::AllStatic {
|
||||
return ROCR_DYN(hsa_amd_memory_unlock)(host_ptr);
|
||||
}
|
||||
static hsa_status_t interop_map_buffer(uint32_t num_agents, hsa_agent_t* agents,
|
||||
amd::Os::FileDesc interop_handle,
|
||||
uint32_t flags, size_t* size,
|
||||
void** ptr, size_t* metadata_size, const void** metadata) {
|
||||
return ROCR_DYN(hsa_amd_interop_map_buffer)(num_agents, agents, interop_handle, flags, size,
|
||||
ptr, metadata_size, metadata);
|
||||
hsa_handle_t interop_handle, uint32_t flags,
|
||||
size_t* size, void** ptr, size_t* metadata_size,
|
||||
const void** metadata) {
|
||||
return ROCR_DYN(hsa_amd_interop_map_buffer)(num_agents, agents, interop_handle, flags, size, ptr,
|
||||
metadata_size, metadata);
|
||||
}
|
||||
static hsa_status_t interop_unmap_buffer(void* ptr) {
|
||||
return ROCR_DYN(hsa_amd_interop_unmap_buffer)(ptr);
|
||||
|
||||
@@ -1516,6 +1516,7 @@ typedef union
|
||||
struct
|
||||
{
|
||||
unsigned int requiresVAddr : 1; // Requires virtual address
|
||||
unsigned int kmtHandle : 1; // Handle is a KMT handle
|
||||
} ui32;
|
||||
} HSA_REGISTER_MEM_FLAGS;
|
||||
|
||||
|
||||
@@ -1092,17 +1092,12 @@ hsa_status_t HSA_API
|
||||
}
|
||||
|
||||
// Mirrors Amd Extension Apis
|
||||
hsa_status_t HSA_API hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
hsa_agent_t* agents,
|
||||
hsa_handle_t interop_handle,
|
||||
uint32_t flags,
|
||||
size_t* size,
|
||||
void** ptr,
|
||||
size_t* metadata_size,
|
||||
const void** metadata) {
|
||||
return amdExtTable->hsa_amd_interop_map_buffer_fn(
|
||||
num_agents, agents, interop_handle,
|
||||
flags, size, ptr, metadata_size, metadata);
|
||||
hsa_status_t HSA_API hsa_amd_interop_map_buffer(uint32_t num_agents, hsa_agent_t* agents,
|
||||
hsa_handle_t interop_handle, uint32_t flags,
|
||||
size_t* size, void** ptr, size_t* metadata_size,
|
||||
const void** metadata) {
|
||||
return amdExtTable->hsa_amd_interop_map_buffer_fn(num_agents, agents, interop_handle, flags, size,
|
||||
ptr, metadata_size, metadata);
|
||||
}
|
||||
|
||||
// Mirrors Amd Extension Apis
|
||||
|
||||
@@ -347,11 +347,9 @@ class Runtime {
|
||||
hsa_signal_value_t value,
|
||||
hsa_amd_signal_handler handler, void* arg);
|
||||
|
||||
hsa_status_t InteropMap(uint32_t num_agents, Agent** agents,
|
||||
hsa_handle_t interop_handle,
|
||||
uint32_t flags, size_t* size,
|
||||
void** ptr, size_t* metadata_size,
|
||||
const void** metadata);
|
||||
hsa_status_t InteropMap(uint32_t num_agents, Agent** agents, hsa_handle_t handle,
|
||||
hsa_interop_map_flag_t flags, size_t* size, void** ptr,
|
||||
size_t* metadata_size, const void** metadata);
|
||||
|
||||
hsa_status_t InteropUnmap(void* ptr);
|
||||
|
||||
|
||||
@@ -992,19 +992,15 @@ hsa_status_t hsa_amd_agent_memory_pool_get_info(
|
||||
CATCH;
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
hsa_agent_t* agents,
|
||||
hsa_handle_t interop_handle,
|
||||
uint32_t flags, size_t* size,
|
||||
void** ptr, size_t* metadata_size,
|
||||
const void** metadata) {
|
||||
static const int tinyArraySize=8;
|
||||
hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents, hsa_agent_t* agents,
|
||||
hsa_handle_t interop_handle, uint32_t flags, size_t* size,
|
||||
void** ptr, size_t* metadata_size, const void** metadata) {
|
||||
static const int tinyArraySize = 8;
|
||||
TRY;
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(agents);
|
||||
IS_BAD_PTR(size);
|
||||
IS_BAD_PTR(ptr);
|
||||
if (flags != 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
if (num_agents == 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
core::Agent* short_agents[tinyArraySize];
|
||||
@@ -1025,8 +1021,8 @@ hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
}
|
||||
|
||||
auto ret = core::Runtime::runtime_singleton_->InteropMap(
|
||||
num_agents, core_agents, interop_handle, flags, size, ptr, metadata_size,
|
||||
metadata);
|
||||
num_agents, core_agents, interop_handle, static_cast<hsa_interop_map_flag_t>(flags), size,
|
||||
ptr, metadata_size, metadata);
|
||||
|
||||
return ret;
|
||||
CATCH;
|
||||
|
||||
@@ -868,24 +868,21 @@ hsa_status_t Runtime::SetAsyncSignalHandler(hsa_signal_t signal,
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t Runtime::InteropMap(uint32_t num_agents, Agent** agents,
|
||||
hsa_handle_t interop_handle,
|
||||
uint32_t flags,
|
||||
size_t* size, void** ptr,
|
||||
hsa_status_t Runtime::InteropMap(uint32_t num_agents, Agent** agents, hsa_handle_t handle,
|
||||
hsa_interop_map_flag_t flags, size_t* size, void** ptr,
|
||||
size_t* metadata_size, const void** metadata) {
|
||||
static const int tinyArraySize=8;
|
||||
constexpr int tinyArraySize = 8;
|
||||
HsaGraphicsResourceInfo info;
|
||||
|
||||
HSAuint32 short_nodes[tinyArraySize];
|
||||
HSAuint32* nodes = short_nodes;
|
||||
|
||||
static_assert(sizeof(HSAint64) >= sizeof(interop_handle),
|
||||
"HSAint64 too small for interop_handle");
|
||||
static_assert(sizeof(HSAint64) >= sizeof(handle), "HSAint64 too small for interop_handle");
|
||||
HSAint64 resource_handle =
|
||||
#ifdef _WIN32
|
||||
static_cast<HSAint64>(reinterpret_cast<uintptr_t>(interop_handle));
|
||||
static_cast<HSAint64>(reinterpret_cast<uintptr_t>(handle));
|
||||
#else
|
||||
static_cast<HSAint64>(interop_handle);
|
||||
static_cast<HSAint64>(handle);
|
||||
#endif
|
||||
|
||||
if (num_agents > tinyArraySize) {
|
||||
@@ -903,9 +900,12 @@ hsa_status_t Runtime::InteropMap(uint32_t num_agents, Agent** agents,
|
||||
agents[i]->GetInfo(static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_DRIVER_NODE_ID), &nodes[i]);
|
||||
}
|
||||
|
||||
if (HSAKMT_CALL(hsaKmtRegisterGraphicsHandleToNodes(resource_handle, &info, num_agents,
|
||||
nodes)) != HSAKMT_STATUS_SUCCESS)
|
||||
return HSA_STATUS_ERROR;
|
||||
const HSA_REGISTER_MEM_FLAGS reg_flags = {
|
||||
.ui32 = {.kmtHandle = ((flags & HSA_INTEROP_MAP_FLAG_KMT_HANDLE) != 0)}};
|
||||
|
||||
auto status =
|
||||
hsaKmtRegisterGraphicsHandleToNodesExt(resource_handle, &info, num_agents, nodes, reg_flags);
|
||||
if (status != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;
|
||||
|
||||
assert(num_agents > 0);
|
||||
auto& driver = agents[0]->driver();
|
||||
|
||||
@@ -5691,6 +5691,14 @@ typedef void* hsa_handle_t;
|
||||
typedef int hsa_handle_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Interop map flags.
|
||||
*/
|
||||
typedef uint32_t hsa_interop_map_flag_t;
|
||||
|
||||
#define HSA_INTEROP_MAP_FLAG_NONE 0u
|
||||
#define HSA_INTEROP_MAP_FLAG_KMT_HANDLE (1u << 0)
|
||||
|
||||
/**
|
||||
* @brief Platform-independent container for a Windows LUID.
|
||||
*/
|
||||
|
||||
@@ -2307,7 +2307,8 @@ hsa_status_t HSA_API
|
||||
*
|
||||
* @param[in] agents List of accessing agents.
|
||||
*
|
||||
* @param[in] interop_handle Handle of interop buffer (dmabuf handle in Linux)
|
||||
* @param[in] interop_handle interop buffer handle (FD on Linux and HANDLE on
|
||||
* Windows)
|
||||
*
|
||||
* @param [in] flags Reserved, must be 0
|
||||
*
|
||||
@@ -2328,14 +2329,10 @@ hsa_status_t HSA_API
|
||||
*
|
||||
* @retval HSA_STATUS_ERROR_INVALID_ARGUMENT all other errors
|
||||
*/
|
||||
hsa_status_t HSA_API hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
hsa_agent_t* agents,
|
||||
hsa_handle_t interop_handle,
|
||||
uint32_t flags,
|
||||
size_t* size,
|
||||
void** ptr,
|
||||
size_t* metadata_size,
|
||||
const void** metadata);
|
||||
hsa_status_t HSA_API hsa_amd_interop_map_buffer(uint32_t num_agents, hsa_agent_t* agents,
|
||||
hsa_handle_t interop_handle, uint32_t flags,
|
||||
size_t* size, void** ptr, size_t* metadata_size,
|
||||
const void** metadata);
|
||||
|
||||
/**
|
||||
* @brief Removes a previously mapped interop object from HSA's flat address space.
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren