Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/module/common/OCLGLCommonLinux.cpp
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

231 lines
7.2 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include "OCLGLCommon.h"
struct OCLGLHandle_ {
static Display* display;
static XVisualInfo* vInfo;
static int referenceCount;
GLXContext context;
Window window;
Colormap cmap;
};
Display* OCLGLHandle_::display = NULL;
XVisualInfo* OCLGLHandle_::vInfo = NULL;
int OCLGLHandle_::referenceCount = 0;
OCLGLCommon::OCLGLCommon() {
hGL_ = new OCLGLHandle_;
hGL_->context = NULL;
hGL_->window = 0;
hGL_->cmap = 0;
}
OCLGLCommon::~OCLGLCommon() { destroyGLContext(hGL_); }
void OCLGLCommon::destroyGLContext(OCLGLHandle& hGL) {
deleteGLContext(hGL);
delete hGL;
hGL = NULL;
}
void OCLGLCommon::deleteGLContext(OCLGLHandle& hGL) {
if (hGL->display != NULL) {
glXMakeCurrent(hGL->display, None, NULL);
if (hGL->cmap) {
XFreeColormap(hGL->display, hGL->cmap);
hGL->cmap = 0;
}
if (hGL->window) {
XDestroyWindow(hGL->display, hGL->window);
hGL->window = 0;
}
if (hGL->context) {
glXDestroyContext(hGL->display, hGL->context);
hGL->context = NULL;
}
hGL->referenceCount--;
if (hGL->referenceCount == 0) {
XCloseDisplay(hGL->display);
hGL->display = NULL;
XFree(hGL->vInfo);
hGL->vInfo = NULL;
}
}
}
bool OCLGLCommon::createGLContext(OCLGLHandle& hGL) {
hGL = new OCLGLHandle_;
return initializeGLContext(hGL);
}
bool OCLGLCommon::initializeGLContext(OCLGLHandle& hGL) {
if (hGL->display == NULL) {
hGL->display = XOpenDisplay(NULL);
if (hGL->display == NULL) {
printf("XOpenDisplay() failed\n");
return false;
}
}
if (hGL->vInfo == NULL) {
int dblBuf[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE,
1, GLX_DEPTH_SIZE, 12, GLX_DOUBLEBUFFER, None};
hGL->vInfo = glXChooseVisual(hGL->display, DefaultScreen(hGL->display), dblBuf);
if (hGL->vInfo == NULL) {
printf("glXChooseVisual() failed\n");
return false;
}
}
hGL->referenceCount++;
hGL->context = glXCreateContext(hGL->display, hGL->vInfo, None, True);
if (hGL->context == NULL) {
printf("glXCreateContext() failed\n");
return false;
}
XSetWindowAttributes swa = {0};
hGL->cmap = XCreateColormap(hGL->display, RootWindow(hGL->display, hGL->vInfo->screen),
hGL->vInfo->visual, AllocNone);
swa.colormap = hGL->cmap;
hGL->window = XCreateWindow(hGL->display, RootWindow(hGL->display, hGL->vInfo->screen), 0, 0, 640,
480, 0, hGL->vInfo->depth, InputOutput, hGL->vInfo->visual,
CWBorderPixel | CWColormap | CWEventMask, &swa);
Bool glErr = glXMakeCurrent(hGL->display, hGL->window, hGL->context);
if (False == glErr) {
return false;
}
if (!checkAssociationDeviceWithGLContext(hGL)) {
deleteGLContext(hGL);
return false;
}
return true;
}
bool OCLGLCommon::checkAssociationDeviceWithGLContext(OCLGLHandle& hGL) {
bool ret = false;
size_t devicesSize = 0;
cl_context_properties properties[] = {CL_CONTEXT_PLATFORM,
(cl_context_properties)platform_,
CL_GL_CONTEXT_KHR,
(cl_context_properties)hGL->context,
CL_GLX_DISPLAY_KHR,
(cl_context_properties)hGL->display,
0};
error_ = _wrapper->clGetGLContextInfoKHR(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR, 0, NULL,
&devicesSize);
if (error_ != CL_SUCCESS) {
printf("clGetGLContextInfoKHR failed (%d)\n", error_);
return false;
}
cl_uint numDevices = (cl_uint)devicesSize / sizeof(cl_device_id);
cl_device_id* interopDevices = (cl_device_id*)malloc(devicesSize);
error_ = _wrapper->clGetGLContextInfoKHR(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR, devicesSize,
interopDevices, NULL);
if (error_ != CL_SUCCESS) {
printf("clGetGLContextInfoKHR failed (%d)\n", error_);
free(interopDevices);
return false;
}
// Check that current device can be associated with OpenGL context
for (unsigned int i = 0; i < numDevices; i++) {
if (interopDevices[i] == devices_[_deviceId]) {
ret = true;
break;
}
}
// If the current device id does not work for CL GL interop,
// fall back to other devices.
if (!ret) {
for (unsigned int i = 0; i < numDevices; i++) {
for (unsigned int j = 0; j < deviceCount_; j++) {
if (interopDevices[i] == devices_[j]) {
// Found an OpenCL device work with current GL context.
_deviceId = j;
ret = true;
break;
}
}
}
}
free(interopDevices);
return ret;
}
void OCLGLCommon::createCLContextFromGLContext(OCLGLHandle& hGL) {
cl_context_properties properties[] = {CL_CONTEXT_PLATFORM,
(cl_context_properties)platform_,
CL_GL_CONTEXT_KHR,
(cl_context_properties)hGL->context,
CL_GLX_DISPLAY_KHR,
(cl_context_properties)hGL->display,
0};
// Release current command queue
if (cmdQueues_[_deviceId]) {
error_ = _wrapper->clReleaseCommandQueue(cmdQueues_[_deviceId]);
CHECK_RESULT_NO_RETURN((error_ != CL_SUCCESS), "clReleaseCommandQueue() failed");
}
// Release current context
if (context_) {
error_ = _wrapper->clReleaseContext(context_);
CHECK_RESULT_NO_RETURN((error_ != CL_SUCCESS), "clReleaseContext() failed");
}
// Create new CL context from GL context
context_ = clCreateContext(properties, 1, &devices_[_deviceId], NULL, NULL, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateContext() failed (%d)", error_);
// Create command queue for new context
cmdQueues_[_deviceId] = _wrapper->clCreateCommandQueue(context_, devices_[_deviceId], 0, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateCommandQueue() failed (%d)", error_);
// GLEW versions 1.13.0 and earlier do not fetch all GL function pointers
// without glewExperimental set.
glewExperimental = GL_TRUE;
GLenum glErr = glewInit();
CHECK_RESULT((glErr != GLEW_OK), "glewInit() failed: %s", glewGetErrorString(glErr));
}
void OCLGLCommon::makeCurrent(OCLGLHandle hGL) {
if (hGL == NULL) {
if (hGL_ != NULL) {
glXMakeCurrent(hGL_->display, None, NULL);
}
} else {
bool ret = glXMakeCurrent(hGL->display, hGL->window, hGL->context);
assert(ret && "glXMakeCurrent failed!");
}
}
void OCLGLCommon::getCLContextPropertiesFromGLContext(const OCLGLHandle hGL,
cl_context_properties properties[7]) {
if (!properties) return;
properties[0] = CL_CONTEXT_PLATFORM;
properties[1] = (cl_context_properties)platform_;
properties[2] = CL_GL_CONTEXT_KHR;
properties[3] = (cl_context_properties)hGL->context;
properties[4] = CL_GLX_DISPLAY_KHR;
properties[5] = (cl_context_properties)hGL->display;
properties[6] = 0;
}