Files
TheRock/rocm-systems/projects/clr/rocclr/platform/interop_gl.hpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

358 lines
12 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#ifdef _WIN32
#include <windows.h>
#else //!_WIN32
#include <dlfcn.h>
#endif //!_WIN32
#include <GL/gl.h>
#include <GL/glext.h>
#include "CL/cl_gl.h"
#ifndef _WIN32
#include <GL/glx.h>
#endif //!_WIN32
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include "platform/context.hpp"
#include "platform/command.hpp"
namespace amd {
//! Class GLObject keeps all the info about the GL object
//! from which the CL object is created
class GLObject : public InteropObject {
protected:
cl_gl_object_type clGLType_; //!< CL GL object type
GLenum glTarget_;
GLuint gluiName_;
GLint gliMipLevel_;
GLenum glInternalFormat_;
GLint gliWidth_;
GLint gliHeight_;
GLint gliDepth_;
GLenum glCubemapFace_;
GLsizei glNumSamples_;
public:
//! GLObject constructor initializes member variables
GLObject(GLenum glTarget, GLuint gluiName, GLint gliMipLevel, GLenum glInternalFormat,
GLint gliWidth, GLint gliHeight, GLint gliDepth, cl_gl_object_type clGLType,
GLenum glCubemapFace,
GLsizei glNumSamples)
: // Initialization of member variables
clGLType_(clGLType),
glTarget_(glTarget),
gluiName_(gluiName),
gliMipLevel_(gliMipLevel),
glInternalFormat_(glInternalFormat),
gliWidth_(gliWidth),
gliHeight_(gliHeight),
gliDepth_(gliDepth),
glCubemapFace_(glCubemapFace),
glNumSamples_(glNumSamples) {}
virtual ~GLObject() {}
virtual GLObject* asGLObject() { return this; }
//! GLObject query functions to get GL info from member variables
GLenum getGLTarget() const { return glTarget_; }
GLuint getGLName() const { return gluiName_; }
GLint getGLMipLevel() const { return gliMipLevel_; }
GLenum getGLInternalFormat() const { return glInternalFormat_; }
GLint getGLSize() const { return gliWidth_; }
GLint getGLWidth() const { return gliWidth_; }
GLint getGLHeight() const { return gliHeight_; }
GLint getGLDepth() const { return gliDepth_; }
cl_gl_object_type getCLGLObjectType() const { return clGLType_; }
GLenum getCubemapFace() const { return glCubemapFace_; }
GLsizei getNumSamples() const { return glNumSamples_; }
};
//! Class BufferGL is drived from classes Buffer and GLObject
//! where the former keeps all data for CL object and
//! the latter keeps all data for GL object
class BufferGL : public Buffer, public GLObject {
protected:
//! Initializes the device memory array which is nested
// after'BufferGL' object in memory layout.
virtual void initDeviceMemory();
public:
//! BufferGL constructor just calls constructors of base classes
//! to pass down the parameters
BufferGL(Context& amdContext, cl_mem_flags clFlags, size_t uiSizeInBytes, GLenum glTarget,
GLuint gluiName)
: // Call base classes constructors
Buffer(amdContext, clFlags, uiSizeInBytes),
GLObject(glTarget, gluiName,
0, // Mipmap level default
GL_ARRAY_BUFFER, // Just init to some value
(GLint)uiSizeInBytes, 1, 1, CL_GL_OBJECT_BUFFER, 0, 0) {
setInteropObj(this);
}
virtual ~BufferGL() {}
virtual BufferGL* asBufferGL() { return this; }
};
//! Class ImageGL is derived from classes Image and GLObject
//! where the former keeps all data for CL object and
//! the latter keeps all data for GL object
class ImageGL : public Image, public GLObject {
public:
//! ImageGL constructor just calls constructors of base classes
//! to pass down the parameters
ImageGL(Context& amdContext, cl_mem_object_type clType, cl_mem_flags clFlags,
const Format& format, size_t width, size_t height, size_t depth, GLenum glTarget,
GLuint gluiName, GLint gliMipLevel, GLenum glInternalFormat, cl_gl_object_type clGLType,
GLsizei numSamples, GLenum glCubemapFace = 0)
: Image(amdContext, clType, clFlags, format, width, height, depth,
Format(format).getElementSize() * width,
Format(format).getElementSize() * width * height),
GLObject(glTarget, gluiName, gliMipLevel, glInternalFormat, static_cast<GLint>(width),
static_cast<GLint>(height), static_cast<GLint>(depth), clGLType, glCubemapFace,
numSamples) {
setInteropObj(this);
}
//! ImageGL constructor for mipmapped image,
//! just calls constructors of base classes to pass down the parameters
ImageGL(Context& amdContext, cl_mem_object_type clType, cl_mem_flags clFlags,
const Format& format, size_t width, size_t height, size_t depth, GLenum glTarget,
GLuint gluiName, GLint gliMipLevel, GLenum glInternalFormat, cl_gl_object_type clGLType,
GLsizei numSamples, cl_int num_mip_levels, GLenum glCubemapFace = 0)
: Image(amdContext, clType, clFlags, format, width, height, depth,
Format(format).getElementSize() * width,
Format(format).getElementSize() * width * depth, num_mip_levels),
GLObject(glTarget, gluiName, gliMipLevel, glInternalFormat, static_cast<GLint>(width),
static_cast<GLint>(height), static_cast<GLint>(depth), clGLType, glCubemapFace,
numSamples) {
setInteropObj(this);
}
virtual ~ImageGL() {}
protected:
//! Initializes the device memory array which is nested
// after'BufferGL' object in memory layout.
virtual void initDeviceMemory();
};
typedef EGLContext (*PFN_eglGetCurrentContext)();
#ifdef _WIN32
#define APICALL WINAPI
#define GETPROCADDRESS GetProcAddress
#define API_GETPROCADDR "wglGetProcAddress"
#define FCN_STR_TYPE LPCSTR
typedef PROC(WINAPI* PFN_xxxGetProcAddress)(LPCSTR fcnName);
typedef HGLRC(APICALL* PFN_wglCreateContext)(HDC hdc);
typedef HGLRC(APICALL* PFN_wglGetCurrentContext)(void);
typedef HDC(APICALL* PFN_wglGetCurrentDC)(void);
typedef BOOL(APICALL* PFN_wglDeleteContext)(HGLRC hglrc);
typedef BOOL(APICALL* PFN_wglMakeCurrent)(HDC hdc, HGLRC hglrc);
typedef BOOL(APICALL* PFN_wglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
#else //!_WIN32
#define APICALL // __stdcall //??? todo odintsov
#define API_GETPROCADDR "glXGetProcAddress"
#define GETPROCADDRESS dlsym
#define FCN_STR_TYPE const GLubyte*
#define WINAPI
#define PROC void*
typedef void* (*PFN_xxxGetProcAddress)(const GLubyte* procName);
// X11 typedef
typedef Display* (*PFNXOpenDisplay)(_Xconst char* display_name);
typedef int (*PFNXCloseDisplay)(Display* display);
typedef int (*PFNXFree)(void* data);
// glx typedefs
typedef GLXDrawable (*PFNglXGetCurrentDrawable)();
typedef Display* (*PFNglXGetCurrentDisplay)();
typedef GLXContext (*PFNglXGetCurrentContext)(void);
typedef XVisualInfo* (*PFNglXChooseVisual)(Display* dpy, int screen, int* attribList);
typedef GLXContext (*PFNglXCreateContext)(Display* dpy, XVisualInfo* vis, GLXContext shareList,
Bool direct);
typedef void (*PFNglXDestroyContext)(Display* dpy, GLXContext ctx);
typedef Bool (*PFNglXMakeCurrent)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
typedef void* HMODULE;
#endif //!_WIN32
#define GLPREFIX(rtype, fcn, dclargs) typedef rtype(APICALL* PFN_##fcn) dclargs;
// Declare prototypes for GL functions
#include "gl_functions.hpp"
class GLFunctions {
public:
//! Locks any access to the virtual GPUs
class SetIntEnv : public amd::StackObject {
public:
//! Default constructor
SetIntEnv(GLFunctions* env);
//! Destructor
~SetIntEnv();
//! Checks if the environment setup was successful
bool isValid() const { return isValid_; }
private:
GLFunctions* env_; //!< GL environment
bool isValid_; //!< If TRUE, then it's a valid setup
};
//! Locks any access to the virtual GPUs
class Lock : public amd::StackObject {
public:
//! Default constructor
Lock(GLFunctions* env);
//! Destructor
~Lock();
private:
GLFunctions* env_; //!< GL environment
};
private:
HMODULE libHandle_;
int missed_; // Indicates how many GL functions not init'ed, if any
amd::Monitor lock_;
EGLDisplay eglDisplay_;
EGLContext eglOriginalContext_;
EGLContext eglInternalContext_;
EGLContext eglTempContext_;
bool isEGL_;
PFN_eglGetCurrentContext eglGetCurrentContext_;
#ifdef _WIN32
HGLRC hOrigGLRC_;
HDC hDC_;
HGLRC hIntGLRC_; // handle for internal GLRC to access shared context
HDC tempDC_;
HGLRC tempGLRC_;
public:
PFN_wglCreateContext wglCreateContext_;
PFN_wglGetCurrentContext wglGetCurrentContext_;
PFN_wglGetCurrentDC wglGetCurrentDC_;
PFN_wglDeleteContext wglDeleteContext_;
PFN_wglMakeCurrent wglMakeCurrent_;
PFN_wglShareLists wglShareLists_;
#else
public:
Display* Dpy_;
GLXDrawable Drawable_;
GLXContext origCtx_;
Display* intDpy_;
Window intDrawable_;
GLXContext intCtx_;
Display* tempDpy_;
GLXDrawable tempDrawable_;
GLXContext tempCtx_;
// pointers to X11 functions
PFNXOpenDisplay XOpenDisplay_;
PFNXCloseDisplay XCloseDisplay_;
PFNXFree XFree_;
// pointers to GLX functions
PFNglXGetCurrentDrawable glXGetCurrentDrawable_;
PFNglXGetCurrentDisplay glXGetCurrentDisplay_;
PFNglXGetCurrentContext glXGetCurrentContext_;
PFNglXChooseVisual glXChooseVisual_;
PFNglXCreateContext glXCreateContext_;
PFNglXDestroyContext glXDestroyContext_;
PFNglXMakeCurrent glXMakeCurrent_;
#endif
public:
GLFunctions(HMODULE h, bool isEGL);
~GLFunctions();
bool update(intptr_t hglrc);
bool IsCurrentGlContext(const amd::Context::Info& info) const {
if (isEGL_) {
return ((info.hCtx_ != nullptr) && (eglGetCurrentContext_ != nullptr) &&
(info.hCtx_ == eglGetCurrentContext_()));
} else {
#ifdef _WIN32
return ((info.hCtx_ != nullptr) && (info.hCtx_ == wglGetCurrentContext_()));
#else
return ((info.hCtx_ != nullptr) && (info.hCtx_ == glXGetCurrentContext_()));
#endif // _WIN32
}
}
void WaitCurrentGlContext(const amd::Context::Info& info) const;
// Query CL-GL context association
bool isAssociated() const {
if (isEGL_ && eglDisplay_ && eglOriginalContext_) return true;
#ifdef _WIN32
if (hDC_ && hOrigGLRC_) return true;
#else //!_WIN32
if (Dpy_ && origCtx_) return true;
#endif //!_WIN32
return false;
}
bool isEGL() const { return isEGL_; }
// Accessor methods
#ifdef _WIN32
HGLRC getOrigGLRC() const { return hOrigGLRC_; }
HDC getDC() const { return hDC_; }
HGLRC getIntGLRC() const { return hIntGLRC_; }
#else //!_WIN32
Display* getDpy() const { return Dpy_; }
GLXDrawable getDrawable() const { return Drawable_; }
GLXContext getOrigCtx() const { return origCtx_; }
Display* getIntDpy() const { return intDpy_; }
GLXDrawable getIntDrawable() const { return intDrawable_; }
GLXContext getIntCtx() const { return intCtx_; }
EGLDisplay getEglDpy() const { return eglDisplay_; }
EGLContext getEglOrigCtx() const { return eglOriginalContext_; }
#endif //!_WIN32
// Initialize GL dynamic library and function pointers
bool init(intptr_t hdc, intptr_t hglrc);
// Return true if successful, false - if error occurred
bool setIntEnv();
bool restoreEnv();
amd::Monitor& getLock() { return lock_; }
PFN_xxxGetProcAddress GetProcAddress_;
#define GLPREFIX(rtype, fcn, dclargs) PFN_##fcn fcn##_;
// Declare pointers to GL functions
#include "gl_functions.hpp"
};
//! Functions for executing the GL related stuff
cl_mem clCreateFromGLBufferAMD(Context& amdContext, cl_mem_flags flags, GLuint bufobj,
cl_int* errcode_ret);
cl_mem clCreateFromGLTextureAMD(Context& amdContext, cl_mem_flags flags, GLenum target,
GLint miplevel, GLuint texture, int* errcode_ret);
cl_mem clCreateFromGLRenderbufferAMD(Context& amdContext, cl_mem_flags flags, GLuint renderbuffer,
int* errcode_ret);
bool getCLFormatFromGL(const Context& amdContext, GLint gliInternalFormat,
cl_image_format* pclImageFormat, int* piBytesPerPixel, cl_mem_flags flags);
} // namespace amd