From 3e25decb3946c23f80c73a81a4836f8629bf72cc Mon Sep 17 00:00:00 2001 From: Jin Jung Date: Tue, 2 Dec 2025 08:19:07 -0800 Subject: [PATCH] SWDEV-565719 - Enable GL Interop Tests on Windows (#1808) * SWDEV-565719 - Enable GL Interop Tests on Windows * SWDEV-565719 - Define USE_EGL feature * Update projects/hip-tests/catch/unit/gl_interop/gl_interop_common.hh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * SWDEV-565719 - Add glewInit * SWDEV-565719 - Remove incorrect glutExit() * Refactor GL interop build configuration --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: JeniferC99 <150404595+JeniferC99@users.noreply.github.com> --- .../catch/unit/gl_interop/CMakeLists.txt | 78 +++++++++++++++++-- .../unit/gl_interop/gl_interop_common.hh | 59 ++++++++++---- 2 files changed, 114 insertions(+), 23 deletions(-) diff --git a/projects/hip-tests/catch/unit/gl_interop/CMakeLists.txt b/projects/hip-tests/catch/unit/gl_interop/CMakeLists.txt index a270a5a6ab..859294a8a2 100644 --- a/projects/hip-tests/catch/unit/gl_interop/CMakeLists.txt +++ b/projects/hip-tests/catch/unit/gl_interop/CMakeLists.txt @@ -9,22 +9,84 @@ set(TEST_SRC hipGraphicsUnregisterResource.cc ) -find_package(OpenGL COMPONENTS OpenGL EGL) +# Find OpenGL with optional EGL support +find_package(OpenGL COMPONENTS OpenGL OPTIONAL_COMPONENTS EGL) message(STATUS "OpenGL_FOUND: ${OpenGL_FOUND}") -if(NOT OpenGL_FOUND) - message(STATUS "OpenGL not found, OpenGL interop tests not enabled.") + +if(NOT OpenGL_FOUND OR NOT TARGET OpenGL::GL) + message(STATUS "OpenGL not found or OpenGL::GL target unavailable, " + "OpenGL interop tests not enabled.") return() endif() -find_package(GLUT) -message(STATUS "GLUT_FOUND: ${GLUT_FOUND}") -if(NOT GLUT_FOUND) - message(STATUS "GLUT not found, OpenGL interop tests not enabled.") +if (OpenGL_EGL_FOUND) + message(STATUS "OpenGL::EGL: Found") +endif() + +# Handle GLUT - env vars first, then find_package +set(USE_ENV_GLUT FALSE) +if (DEFINED ENV{GLUT_glut_LIBRARY} AND + DEFINED ENV{GLUT_INCLUDE_DIR}) + if (NOT "$ENV{GLUT_glut_LIBRARY}" STREQUAL "" AND + NOT "$ENV{GLUT_INCLUDE_DIR}" STREQUAL "") + if (EXISTS "$ENV{GLUT_glut_LIBRARY}" AND + EXISTS "$ENV{GLUT_INCLUDE_DIR}") + set(USE_ENV_GLUT TRUE) + else() + message(WARNING "GLUT env vars invalid, using find_package") + endif() + endif() +endif() + +if (USE_ENV_GLUT) + message(STATUS "Using GLUT from environment variables") + message(STATUS " GLUT_glut_LIBRARY: $ENV{GLUT_glut_LIBRARY}") + message(STATUS " GLUT_INCLUDE_DIR: $ENV{GLUT_INCLUDE_DIR}") + + set(GLUT_glut_LIBRARY "$ENV{GLUT_glut_LIBRARY}" + CACHE FILEPATH "Path to GLUT library") + set(GLUT_INCLUDE_DIR "$ENV{GLUT_INCLUDE_DIR}" + CACHE PATH "Path to GLUT include directory") + + add_library(GLUT::GLUT UNKNOWN IMPORTED) + set_target_properties(GLUT::GLUT PROPERTIES + IMPORTED_LOCATION "${GLUT_glut_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GLUT_INCLUDE_DIR}" + ) +else() + message(STATUS "Searching for GLUT via find_package...") + find_package(GLUT) + if (NOT GLUT_FOUND) + message(STATUS "GLUT not found, OpenGL interop tests not enabled.") + return() + endif() + message(STATUS "GLUT_FOUND: ${GLUT_FOUND}") +endif() + +# GLEW is required on Windows for OpenGL extension access +# On Linux, extensions are available via native headers +find_package(GLEW) +if(WIN32 AND NOT GLEW_FOUND) + message(STATUS "GLEW required on Windows but not found, " + "GL interop tests not enabled.") return() endif() +# Create test executable hip_add_exe_to_target(NAME GLInteropTest TEST_SRC ${TEST_SRC} TEST_TARGET_NAME build_tests COMPILE_OPTIONS -std=c++17) -target_link_libraries(GLInteropTest OpenGL::GL OpenGL::EGL GLUT::GLUT) \ No newline at end of file + +# Link dependencies +target_link_libraries(GLInteropTest OpenGL::GL GLUT::GLUT) + +if (OpenGL_EGL_FOUND) + target_link_libraries(GLInteropTest OpenGL::EGL) + target_compile_definitions(GLInteropTest PRIVATE USE_EGL) +endif() + +if (GLEW_FOUND) + target_link_libraries(GLInteropTest GLEW::GLEW) + target_compile_definitions(GLInteropTest PRIVATE USE_GLEW) +endif() diff --git a/projects/hip-tests/catch/unit/gl_interop/gl_interop_common.hh b/projects/hip-tests/catch/unit/gl_interop/gl_interop_common.hh index 54692d1bed..6320df97bb 100644 --- a/projects/hip-tests/catch/unit/gl_interop/gl_interop_common.hh +++ b/projects/hip-tests/catch/unit/gl_interop/gl_interop_common.hh @@ -22,14 +22,21 @@ THE SOFTWARE. #pragma once -#include - +#ifdef USE_GLEW +#include +#elif defined(__linux__) #define GL_GLEXT_PROTOTYPES -#include -#include +#else +#error "GLEW is required on non-Linux platforms. Define USE_GLEW and link" \ + " against the GLEW library, or build on Linux." +#endif +#include + +#ifdef USE_EGL #include #include +#endif #include @@ -77,6 +84,11 @@ class GLImageObject { GLuint tex_; }; +class IContextScopeGuard { +public: + virtual ~IContextScopeGuard() = default; +}; + static std::once_flag glut_init_flag; static void GlutError(const char *fmt, va_list ap) { @@ -93,14 +105,16 @@ static void GlutError(const char *fmt, va_list ap) exit(1); } -class GLUTContextScopeGuard { +class GLUTContextScopeGuard : public IContextScopeGuard { public: GLUTContextScopeGuard() { std::call_once(glut_init_flag, &GLUTContextScopeGuard::init); glut_window_ = glutCreateWindow(""); } - ~GLUTContextScopeGuard() { glutDestroyWindow(glut_window_); } + ~GLUTContextScopeGuard() override { + glutDestroyWindow(glut_window_); + } GLUTContextScopeGuard(const GLUTContextScopeGuard&) = delete; GLUTContextScopeGuard& operator=(const GLUTContextScopeGuard&) = delete; @@ -122,7 +136,8 @@ class GLUTContextScopeGuard { } }; -class EGLContextScopeGuard { +#ifdef USE_EGL +class EGLContextScopeGuard : public IContextScopeGuard { public: EGLContextScopeGuard() { @@ -156,7 +171,7 @@ class EGLContextScopeGuard { REQUIRE(eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_)); } - ~EGLContextScopeGuard() { + ~EGLContextScopeGuard() override { // 6. Terminate EGL when finished eglTerminate(egl_display_); } @@ -198,13 +213,11 @@ class EGLContextScopeGuard { EGLSurface egl_surface_; EGLContext egl_context_; }; +#endif class GLContextScopeGuard { public: - using GLUTContextScopeGuardPtr = std::unique_ptr; - using EGLContextScopeGuardPtr = std::unique_ptr; - using GLContextScopeGuardVariant = - std::variant; + using GLContextScopeGuardPtr = std::unique_ptr; static constexpr char kEnvarName[] = "GL_CONTEXT_TYPE"; @@ -220,13 +233,29 @@ class GLContextScopeGuard { if (val_str.empty() || val_str == "GLUT") { gl_context_ = std::make_unique(); +#ifdef USE_EGL } else if (val_str == "EGL") { gl_context_ = std::make_unique(); +#endif } else { INFO("Unsupported " << kEnvarName << " value '" << val_str << "'"); - INFO("Supported values are ['GLUT', 'EGL']"); + INFO("Supported values are ['GLUT'" +#ifdef USE_EGL + << ", 'EGL'" +#endif + << "]"); REQUIRE(false); } + +#ifdef USE_GLEW + GLenum err = glewInit(); + if (err != GLEW_OK) { + fprintf(stderr, "GLEW initialization failed: %s\n", + glewGetErrorString(err)); + HipTest::HIP_SKIP_TEST("GLEW Init Failed"); + exit(1); + } +#endif } GLContextScopeGuard(const GLContextScopeGuard&) = delete; @@ -236,5 +265,5 @@ class GLContextScopeGuard { GLContextScopeGuard& operator=(GLContextScopeGuard&&) = delete; private: - GLContextScopeGuardVariant gl_context_; -}; \ No newline at end of file + GLContextScopeGuardPtr gl_context_; +};