Skip to content

Commit f18532c

Browse files
Refactor of glcl sharing
new pattern to load gl and wgl functions from dll Change-Id: I71d7510a210462c09d50e03ce8a444770c017b8d
1 parent d1a80db commit f18532c

File tree

13 files changed

+188
-50
lines changed

13 files changed

+188
-50
lines changed

runtime/helpers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ set(RUNTIME_SRCS_HELPERS_WINDOWS
8787
${CMAKE_CURRENT_SOURCE_DIR}/gmm_callbacks.inl
8888
${CMAKE_CURRENT_SOURCE_DIR}/windows/kmd_notify_properties_windows.cpp
8989
${CMAKE_CURRENT_SOURCE_DIR}/wddm_helper.h
90+
${CMAKE_CURRENT_SOURCE_DIR}/windows/gl_helper.h
9091
)
9192
set(RUNTIME_SRCS_HELPERS_LINUX
9293
${CMAKE_CURRENT_SOURCE_DIR}/linux/kmd_notify_properties_linux.cpp

runtime/helpers/windows/gl_helper.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "runtime/os_interface/os_library.h"
9+
#include "GL/gl.h"
10+
11+
namespace Os {
12+
extern const char *openglDllName;
13+
}
14+
15+
namespace OCLRT {
16+
class glFunctionHelper {
17+
public:
18+
glFunctionHelper::glFunctionHelper(OsLibrary *glLibrary, const std::string &functionName) {
19+
glFunctionPtr = (*glLibrary)[functionName];
20+
}
21+
22+
ConvertibleProcAddr operator[](const char *name) {
23+
return ConvertibleProcAddr{glFunctionPtr(name)};
24+
}
25+
26+
protected:
27+
// clang-format off
28+
PROC(__stdcall *glFunctionPtr)(LPCSTR Arg1) = nullptr;
29+
// clang-format on
30+
};
31+
}; // namespace OCLRT

runtime/os_interface/os_library.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,23 @@
77

88
#pragma once
99
#include <string>
10+
#include <type_traits>
1011

1112
namespace OCLRT {
1213

14+
struct ConvertibleProcAddr {
15+
template <typename T>
16+
operator T *() const {
17+
static_assert(std::is_function<T>::value, "Cannot convert to non-function and non-void* type");
18+
return reinterpret_cast<T *>(ptr);
19+
}
20+
21+
operator void *() const {
22+
return ptr;
23+
}
24+
void *ptr = nullptr;
25+
};
26+
1327
class OsLibrary {
1428
protected:
1529
OsLibrary() = default;
@@ -19,6 +33,9 @@ class OsLibrary {
1933

2034
static OsLibrary *load(const std::string &name);
2135

36+
ConvertibleProcAddr operator[](const std::string &name) {
37+
return ConvertibleProcAddr{getProcAddress(name)};
38+
}
2239
virtual void *getProcAddress(const std::string &procName) = 0;
2340
virtual bool isLoaded() = 0;
2441
};

runtime/os_interface/windows/gl/gl_sharing_win.cpp

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,31 @@ GLSharingFunctions::~GLSharingFunctions() {
3232
}
3333

3434
GLboolean GLSharingFunctions::initGLFunctions() {
35-
GLGetCurrentContext = reinterpret_cast<PFNOGLGetCurrentContext>(loadGlFunction("wglGetCurrentContext", GLHDCType));
36-
GLGetCurrentDisplay = reinterpret_cast<PFNOGLGetCurrentDisplay>(loadGlFunction("wglGetCurrentDC", GLHDCType));
37-
glGetString = reinterpret_cast<PFNglGetString>(loadGlFunction("glGetString", GLHDCType));
38-
glGetIntegerv = reinterpret_cast<PFNglGetIntegerv>(loadGlFunction("glGetIntegerv", GLHDCType));
39-
40-
pfnWglCreateContext = reinterpret_cast<PFNwglCreateContext>(loadGlFunction("wglCreateContext", GLHDCType));
41-
pfnWglDeleteContext = reinterpret_cast<PFNwglDeleteContext>(loadGlFunction("wglDeleteContext", GLHDCType));
42-
43-
pfnWglShareLists = reinterpret_cast<PFNwglShareLists>(loadGlFunction("wglShareLists", GLHDCType));
44-
45-
auto wglGetProcAddressFuncPtr = reinterpret_cast<PROC(WINAPI *)(LPCSTR)>(loadGlFunction("wglGetProcAddress", GLHDCType));
46-
GLSetSharedOCLContextState = reinterpret_cast<PFNOGLSetSharedOCLContextStateINTEL>(wglGetProcAddressFuncPtr("wglSetSharedOCLContextStateINTEL"));
47-
GLAcquireSharedBuffer = reinterpret_cast<PFNOGLAcquireSharedBufferINTEL>(wglGetProcAddressFuncPtr("wglAcquireSharedBufferINTEL"));
48-
GLReleaseSharedBuffer = reinterpret_cast<PFNOGLReleaseSharedBufferINTEL>(wglGetProcAddressFuncPtr("wglReleaseSharedBufferINTEL"));
49-
GLAcquireSharedRenderBuffer = reinterpret_cast<PFNOGLAcquireSharedRenderBufferINTEL>(wglGetProcAddressFuncPtr("wglAcquireSharedRenderBufferINTEL"));
50-
GLReleaseSharedRenderBuffer = reinterpret_cast<PFNOGLReleaseSharedRenderBufferINTEL>(wglGetProcAddressFuncPtr("wglReleaseSharedRenderBufferINTEL"));
51-
GLAcquireSharedTexture = reinterpret_cast<PFNOGLAcquireSharedTextureINTEL>(wglGetProcAddressFuncPtr("wglAcquireSharedTextureINTEL"));
52-
GLReleaseSharedTexture = reinterpret_cast<PFNOGLReleaseSharedTextureINTEL>(wglGetProcAddressFuncPtr("wglReleaseSharedTextureINTEL"));
53-
GLRetainSync = reinterpret_cast<PFNOGLRetainSyncINTEL>(wglGetProcAddressFuncPtr("wglRetainSyncINTEL"));
54-
GLReleaseSync = reinterpret_cast<PFNOGLReleaseSyncINTEL>(wglGetProcAddressFuncPtr("wglReleaseSyncINTEL"));
55-
GLGetSynciv = reinterpret_cast<PFNOGLGetSyncivINTEL>(wglGetProcAddressFuncPtr("wglGetSyncivINTEL"));
56-
glGetStringi = reinterpret_cast<PFNglGetStringi>(wglGetProcAddressFuncPtr("glGetStringi"));
57-
this->wglMakeCurrent = reinterpret_cast<PFNwglMakeCurrent>(loadGlFunction("wglMakeCurrent", GLHDCType));
58-
35+
glLibrary.reset(OsLibrary::load(Os::openglDllName));
36+
37+
if (glLibrary->isLoaded()) {
38+
glFunctionHelper wglLibrary(glLibrary.get(), "wglGetProcAddress");
39+
GLGetCurrentContext = (*glLibrary)["wglGetCurrentContext"];
40+
GLGetCurrentDisplay = (*glLibrary)["wglGetCurrentDC"];
41+
glGetString = (*glLibrary)["glGetString"];
42+
glGetIntegerv = (*glLibrary)["glGetIntegerv"];
43+
pfnWglCreateContext = (*glLibrary)["wglCreateContext"];
44+
pfnWglDeleteContext = (*glLibrary)["wglDeleteContext"];
45+
pfnWglShareLists = (*glLibrary)["wglShareLists"];
46+
47+
GLSetSharedOCLContextState = wglLibrary["wglSetSharedOCLContextStateINTEL"];
48+
GLAcquireSharedBuffer = wglLibrary["wglAcquireSharedBufferINTEL"];
49+
GLReleaseSharedBuffer = wglLibrary["wglReleaseSharedBufferINTEL"];
50+
GLAcquireSharedRenderBuffer = wglLibrary["wglAcquireSharedRenderBufferINTEL"];
51+
GLReleaseSharedRenderBuffer = wglLibrary["wglReleaseSharedRenderBufferINTEL"];
52+
GLAcquireSharedTexture = wglLibrary["wglAcquireSharedTextureINTEL"];
53+
GLReleaseSharedTexture = wglLibrary["wglReleaseSharedTextureINTEL"];
54+
GLRetainSync = wglLibrary["wglRetainSyncINTEL"];
55+
GLReleaseSync = wglLibrary["wglReleaseSyncINTEL"];
56+
GLGetSynciv = wglLibrary["wglGetSyncivINTEL"];
57+
glGetStringi = wglLibrary["glGetStringi"];
58+
wglMakeCurrent = wglLibrary["wglMakeCurrent"];
59+
}
5960
this->pfnGlArbSyncObjectCleanup = cleanupArbSyncObject;
6061
this->pfnGlArbSyncObjectSetup = setupArbSyncObject;
6162
this->pfnGlArbSyncObjectSignal = signalArbSyncObject;
@@ -120,12 +121,6 @@ bool GLSharingFunctions::isOpenGlSharingSupported() {
120121
return true;
121122
}
122123

123-
void *GLSharingFunctions::loadGlFunction(const char *functionName, uint32_t hdc) {
124-
125-
HMODULE module = LoadLibraryA(Os::openglDllName);
126-
return reinterpret_cast<PFNglGetString>(GetProcAddress(module, functionName));
127-
}
128-
129124
void GLSharingFunctions::createBackupContext() {
130125
if (pfnWglCreateContext) {
131126
GLHGLRCHandleBkpCtx = pfnWglCreateContext(GLHDCHandle);

runtime/sharings/gl/gl_sharing.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include "GL/gl.h"
1313
#include "GL/glext.h"
1414
#include "runtime/sharings/sharing.h"
15-
#include "gl/gl_sharing_os.h"
15+
#include "runtime/os_interface/windows/gl/gl_sharing_os.h"
16+
#include "runtime/helpers/windows/gl_helper.h"
1617

1718
#include <functional>
1819
#include <mutex>
@@ -208,6 +209,8 @@ class GLSharingFunctions : public SharingFunctions {
208209
}
209210

210211
protected:
212+
std::unique_ptr<OsLibrary> glLibrary;
213+
211214
GLType GLHDCType = 0;
212215
GLContext GLHGLRCHandle = 0;
213216
GLContext GLHGLRCHandleBkpCtx = 0;
@@ -240,9 +243,6 @@ class GLSharingFunctions : public SharingFunctions {
240243
PFNglArbSyncObjectSignal pfnGlArbSyncObjectSignal = nullptr;
241244
PFNglArbSyncObjectWaitServer pfnGlArbSyncObjectWaitServer = nullptr;
242245

243-
// loading OGL libraries for OGL_OCL sharing
244-
void *loadGlFunction(const char *functionName, uint32_t hdc);
245-
246246
// support for GL_ARB_cl_event
247247
std::mutex glArbEventMutex;
248248
std::unordered_map<Event *, GlArbSyncEvent *> glArbEventMapping;

unit_tests/helpers/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ set(IGDRCL_SRCS_tests_helpers
5353

5454
set(IGDRCL_SRCS_tests_helpers_windows
5555
${CMAKE_CURRENT_SOURCE_DIR}/windows/kmd_notify_windows_tests.cpp
56+
${CMAKE_CURRENT_SOURCE_DIR}/windows/gl_helper_tests.cpp
57+
${CMAKE_CURRENT_SOURCE_DIR}/windows/mock_function.h
5658
)
5759

5860
set(IGDRCL_SRCS_tests_helpers_linux
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include <memory>
9+
#include "runtime/os_interface/os_library.h"
10+
#include "runtime/os_interface/windows/windows_wrapper.h"
11+
#include "runtime/helpers/windows/gl_helper.h"
12+
#include "unit_tests/helpers/windows/mock_function.h"
13+
#include "test.h"
14+
#include "gtest/gtest.h"
15+
16+
typedef const char *(__cdecl *funcType)();
17+
18+
namespace OCLRT {
19+
class glFunctionHelperMock : public glFunctionHelper {
20+
public:
21+
glFunctionHelperMock(OsLibrary *glLibrary, const std::string &functionName) : glFunctionHelper(glLibrary, functionName) {}
22+
using glFunctionHelper::glFunctionPtr;
23+
};
24+
25+
TEST(glFunctionHelper, whenCreateGlFunctionHelperThenSetGlFunctionPtrToLoadAnotherFunctions) {
26+
std::unique_ptr<OsLibrary> glLibrary(OsLibrary::load("mock_opengl32.dll"));
27+
EXPECT_TRUE(glLibrary->isLoaded());
28+
glFunctionHelperMock loader(glLibrary.get(), "mockLoader");
29+
funcType function1 = ConvertibleProcAddr{loader.glFunctionPtr("realFunction")};
30+
funcType function2 = loader["realFunction"];
31+
EXPECT_STREQ(function1(), function2());
32+
}
33+
34+
TEST(glFunctionHelper, givenNonExistingFunctionNameWhenCreateGlFunctionHelperThenNullptr) {
35+
std::unique_ptr<OsLibrary> glLibrary(OsLibrary::load("mock_opengl32.dll"));
36+
EXPECT_TRUE(glLibrary->isLoaded());
37+
glFunctionHelper loader(glLibrary.get(), "mockLoader");
38+
funcType function = loader["nonExistingFunction"];
39+
EXPECT_EQ(nullptr, function);
40+
}
41+
42+
TEST(glFunctionHelper, givenRealFunctionNameWhenCreateGlFunctionHelperThenGetPointerToAppropriateFunction) {
43+
std::unique_ptr<OsLibrary> glLibrary(OsLibrary::load("mock_opengl32.dll"));
44+
EXPECT_TRUE(glLibrary->isLoaded());
45+
glFunctionHelper loader(glLibrary.get(), "mockLoader");
46+
funcType function = loader["realFunction"];
47+
EXPECT_STREQ(realFunction(), function());
48+
}
49+
}; // namespace OCLRT
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
const char *realFunction() { return "value"; }

unit_tests/mocks/gl/mock_gl_sharing.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,9 @@ class MockGLSharingFunctions : public GLSharingFunctions {
292292
((ContextInfo *)pContextInfo)->DeviceHandle = 2;
293293
return GLSetSharedOCLContextStateReturnedValue;
294294
}
295+
using GLSharingFunctions::glGetIntegerv;
296+
using GLSharingFunctions::glGetString;
295297

296-
void *loadGlFunction(const char *FunctionName, DWORD HDC) { return GLSharingFunctions::loadGlFunction(FunctionName, HDC); };
297-
298-
void setGetStringFcn(PFNglGetString fcn) { glGetString = fcn; }
299-
300-
void setglGetIntegervToNull() { glGetIntegerv = nullptr; }
301298
MockGLSharingFunctions() {
302299
glGetString = (PFNglGetString)glGetStringTest;
303300
glGetStringi = (PFNglGetStringi)glGetStringiTest;

unit_tests/mocks/gl/mock_opengl32.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
*
66
*/
77

8-
#include <cstdint>
8+
#include <string.h>
9+
#include "unit_tests/helpers/windows/mock_function.h"
910

1011
extern "C" {
11-
1212
void *__stdcall wglGetProcAddress(const char *name) { return nullptr; }
13+
void *__stdcall mockLoader(const char *name) {
14+
if (strcmp(name, "realFunction") == 0) {
15+
return *realFunction;
16+
}
17+
return nullptr;
18+
}
1319
}

unit_tests/mocks/gl/mock_opengl32.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@
2020

2121
LIBRARY "gdi32_mock"
2222
EXPORTS
23-
wglGetProcAddress
23+
wglGetProcAddress
24+
mockLoader

unit_tests/os_interface/os_library_tests.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,40 @@ TEST_F(OSLibraryTest, testFailNew) {
9191
};
9292
injectFailures(method);
9393
}
94+
95+
TEST(OsLibrary, whenCallingIndexOperatorThenObjectConvertibleToFunctionOrVoidPointerIsReturned) {
96+
struct MockOsLibrary : OsLibrary {
97+
void *getProcAddress(const std::string &procName) override {
98+
lastRequestedProcName = procName;
99+
return ptrToReturn;
100+
}
101+
bool isLoaded() override { return true; }
102+
103+
void *ptrToReturn = nullptr;
104+
std::string lastRequestedProcName;
105+
};
106+
107+
MockOsLibrary lib;
108+
109+
int varA;
110+
int varB;
111+
int varC;
112+
113+
using FunctionTypeA = void (*)(int *, float);
114+
using FunctionTypeB = int (*)();
115+
116+
lib.ptrToReturn = &varA;
117+
FunctionTypeA functionA = lib["funcA"];
118+
EXPECT_STREQ("funcA", lib.lastRequestedProcName.c_str());
119+
EXPECT_EQ(&varA, reinterpret_cast<void *>(functionA));
120+
121+
lib.ptrToReturn = &varB;
122+
FunctionTypeB functionB = lib["funcB"];
123+
EXPECT_STREQ("funcB", lib.lastRequestedProcName.c_str());
124+
EXPECT_EQ(&varB, reinterpret_cast<void *>(functionB));
125+
126+
lib.ptrToReturn = &varC;
127+
void *rawPtr = lib["funcC"];
128+
EXPECT_STREQ("funcC", lib.lastRequestedProcName.c_str());
129+
EXPECT_EQ(&varC, rawPtr);
130+
}

unit_tests/sharings/gl/gl_sharing_tests.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -650,12 +650,6 @@ TEST(glSharingBasicTest, GivenSharingFunctionsWhenItIsConstructedThenOglContextF
650650
EXPECT_EQ(1, GLSetSharedOCLContextStateCalled);
651651
}
652652

653-
TEST(glSharingBasicTest, givenInvalidFunctionNameWhenLoadGLFunctionThenReturnNullptr) {
654-
MockGLSharingFunctions glSharingFunctions;
655-
auto fPointer = glSharingFunctions.loadGlFunction("BadFunctionName", 0);
656-
EXPECT_EQ(nullptr, fPointer);
657-
}
658-
659653
TEST(glSharingBasicTest, givenInvalidExtensionNameWhenCheckGLExtensionSupportedThenReturnFalse) {
660654
GLSharingFunctions glSharingFunctions;
661655
bool RetVal = glSharingFunctions.isOpenGlExtensionSupported("InvalidExtensionName");
@@ -664,7 +658,7 @@ TEST(glSharingBasicTest, givenInvalidExtensionNameWhenCheckGLExtensionSupportedT
664658

665659
TEST(glSharingBasicTest, givenglGetIntegervIsNullWhenCheckGLExtensionSupportedThenReturnFalse) {
666660
MockGLSharingFunctions glSharingFunctions;
667-
glSharingFunctions.setglGetIntegervToNull();
661+
glSharingFunctions.glGetIntegerv = nullptr;
668662
bool RetVal = glSharingFunctions.isOpenGlExtensionSupported("InvalidExtensionName");
669663
EXPECT_FALSE(RetVal);
670664
}
@@ -687,7 +681,7 @@ TEST(glSharingBasicTest, givenVendorisNullWhenCheckGLSharingSupportedThenReturnF
687681
};
688682

689683
MockGLSharingFunctions glSharingFunctions;
690-
glSharingFunctions.setGetStringFcn(invalidGetStringFcn);
684+
glSharingFunctions.glGetString = invalidGetStringFcn;
691685

692686
bool RetVal = glSharingFunctions.isOpenGlSharingSupported();
693687
EXPECT_FALSE(RetVal);

0 commit comments

Comments
 (0)