Add support for cl-gl sharing

Change-Id: I08d7608722746baa3be61846e05eecb5419cc136
This commit is contained in:
Katarzyna Cencelewska
2018-08-27 16:30:40 +02:00
parent f5a2b38fa4
commit 962b6ce883
76 changed files with 22080 additions and 16 deletions

View File

@@ -0,0 +1,30 @@
# Copyright (c) 2017 - 2018, Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
set(RUNTIME_SRCS_OS_INTERFACE_WINDOWS_GL
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/gl_arb_sync_event_os.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing_win.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_options.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing_os.h
)
if(WIN32)
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_OS_INTERFACE_WINDOWS_GL})
endif()

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/sharings/gl/gl_arb_sync_event.h"
#include "runtime/command_stream/command_stream_receiver.h"
#include "runtime/context/context.h"
#include "runtime/os_interface/os_interface.h"
#include "runtime/os_interface/windows/os_context_win.h"
#include "runtime/os_interface/windows/os_interface.h"
#include "runtime/os_interface/windows/wddm/wddm.h"
#include "runtime/os_interface/windows/gdi_interface.h"
#include "runtime/sharings/gl/gl_sharing.h"
#include <GL/gl.h>
#include "CLGLShr.h"
namespace OCLRT {
void destroySync(Gdi &gdi, D3DKMT_HANDLE sync) {
if (!sync) {
return;
}
D3DKMT_DESTROYSYNCHRONIZATIONOBJECT destroySyncInfo = {0};
destroySyncInfo.hSyncObject = sync;
NTSTATUS status = gdi.destroySynchronizationObject(&destroySyncInfo);
DEBUG_BREAK_IF(0 != status);
}
void destroyEvent(OSInterface &osInterface, HANDLE event) {
if (!event) {
return;
}
auto ret = osInterface.get()->closeHandle(event);
DEBUG_BREAK_IF(TRUE != ret);
}
void cleanupArbSyncObject(OSInterface &osInterface, CL_GL_SYNC_INFO *glSyncInfo) {
if (nullptr == glSyncInfo) {
return;
}
auto gdi = osInterface.get()->getWddm()->getGdi();
UNRECOVERABLE_IF(nullptr == gdi);
destroySync(*gdi, glSyncInfo->serverSynchronizationObject);
destroySync(*gdi, glSyncInfo->clientSynchronizationObject);
destroySync(*gdi, glSyncInfo->submissionSynchronizationObject);
destroyEvent(osInterface, glSyncInfo->event);
destroyEvent(osInterface, glSyncInfo->submissionEvent);
destroyArbSyncEventName(glSyncInfo->eventName);
destroyArbSyncEventName(glSyncInfo->submissionEventName);
}
bool setupArbSyncObject(GLSharingFunctions &sharing, OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
glSyncInfo.hContextToBlock = static_cast<D3DKMT_HANDLE>(sharing.getGLContextHandle());
auto glDevice = static_cast<D3DKMT_HANDLE>(sharing.getGLDeviceHandle());
auto wddm = osInterface.get()->getWddm();
D3DKMT_CREATESYNCHRONIZATIONOBJECT serverSyncInitInfo = {0};
serverSyncInitInfo.hDevice = glDevice;
serverSyncInitInfo.Info.Type = D3DDDI_SEMAPHORE;
serverSyncInitInfo.Info.Semaphore.MaxCount = 32;
serverSyncInitInfo.Info.Semaphore.InitialCount = 0;
NTSTATUS serverSyncInitStatus = wddm->getGdi()->createSynchronizationObject(&serverSyncInitInfo);
glSyncInfo.serverSynchronizationObject = serverSyncInitInfo.hSyncObject;
glSyncInfo.eventName = createArbSyncEventName();
glSyncInfo.event = osInterface.get()->createEvent(NULL, TRUE, FALSE, glSyncInfo.eventName);
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 clientSyncInitInfo = {0};
clientSyncInitInfo.hDevice = glDevice;
clientSyncInitInfo.Info.Type = D3DDDI_CPU_NOTIFICATION;
clientSyncInitInfo.Info.CPUNotification.Event = glSyncInfo.event;
NTSTATUS clientSyncInitStatus = wddm->getGdi()->createSynchronizationObject2(&clientSyncInitInfo);
glSyncInfo.clientSynchronizationObject = clientSyncInitInfo.hSyncObject;
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 submissionSyncEventInfo = {0};
glSyncInfo.submissionEventName = createArbSyncEventName();
glSyncInfo.submissionEvent = osInterface.get()->createEvent(NULL, TRUE, FALSE, glSyncInfo.submissionEventName);
submissionSyncEventInfo.hDevice = glDevice;
submissionSyncEventInfo.Info.Type = D3DDDI_CPU_NOTIFICATION;
submissionSyncEventInfo.Info.CPUNotification.Event = glSyncInfo.submissionEvent;
auto submissionSyncInitStatus = wddm->getGdi()->createSynchronizationObject2(&submissionSyncEventInfo);
glSyncInfo.submissionSynchronizationObject = submissionSyncEventInfo.hSyncObject;
glSyncInfo.waitCalled = false;
bool setupFailed = false;
setupFailed |= (glSyncInfo.event == nullptr);
setupFailed |= (glSyncInfo.submissionEvent == nullptr);
setupFailed |= (0 != serverSyncInitStatus);
setupFailed |= (0 != clientSyncInitStatus);
setupFailed |= (0 != submissionSyncInitStatus);
if (setupFailed) {
DEBUG_BREAK_IF(true);
cleanupArbSyncObject(osInterface, &glSyncInfo);
return false;
}
return true;
}
void signalArbSyncObject(OsContext &osContext, CL_GL_SYNC_INFO &glSyncInfo) {
auto osContextWin = osContext.get();
UNRECOVERABLE_IF(!osContextWin);
auto wddm = osContextWin->getWddm();
D3DKMT_SIGNALSYNCHRONIZATIONOBJECT signalServerClientSyncInfo = {0};
signalServerClientSyncInfo.hContext = osContextWin->getContext();
signalServerClientSyncInfo.Flags.SignalAtSubmission = 0; // Wait for GPU to complete processing command buffer
signalServerClientSyncInfo.ObjectHandleArray[0] = glSyncInfo.serverSynchronizationObject;
signalServerClientSyncInfo.ObjectHandleArray[1] = glSyncInfo.clientSynchronizationObject;
signalServerClientSyncInfo.ObjectCount = 2;
NTSTATUS status = wddm->getGdi()->signalSynchronizationObject(&signalServerClientSyncInfo);
if (0 != status) {
DEBUG_BREAK_IF(true);
return;
}
D3DKMT_SIGNALSYNCHRONIZATIONOBJECT signalSubmissionSyncInfo = {0};
signalSubmissionSyncInfo.hContext = osContext.get()->getContext();
signalSubmissionSyncInfo.Flags.SignalAtSubmission = 1; // Don't wait for GPU to complete processing command buffer
signalSubmissionSyncInfo.ObjectHandleArray[0] = glSyncInfo.submissionSynchronizationObject;
signalSubmissionSyncInfo.ObjectCount = 1;
status = wddm->getGdi()->signalSynchronizationObject(&signalSubmissionSyncInfo);
DEBUG_BREAK_IF(0 != status);
}
void serverWaitForArbSyncObject(OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
auto wddm = osInterface.get()->getWddm();
D3DKMT_WAITFORSYNCHRONIZATIONOBJECT waitForSyncInfo = {0};
waitForSyncInfo.hContext = glSyncInfo.hContextToBlock;
waitForSyncInfo.ObjectCount = 1;
waitForSyncInfo.ObjectHandleArray[0] = glSyncInfo.serverSynchronizationObject;
NTSTATUS status = wddm->getGdi()->waitForSynchronizationObject(&waitForSyncInfo);
if (status != 0) {
DEBUG_BREAK_IF(true);
return;
}
glSyncInfo.waitCalled = true;
}
} // namespace OCLRT

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cstdint>
namespace Os {
const char *openglDllName = "opengl32.dll";
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#define OSAPI WINAPI
typedef uint32_t GLType;
typedef HDC GLDisplay;
typedef HGLRC GLContext;
// Windows OpenGL functions

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <cstdint>
#include <memory>
#include "runtime/os_interface/windows/windows_wrapper.h"
#include "runtime/sharings/gl/gl_arb_sync_event.h"
#include "runtime/sharings/gl/gl_sharing.h"
namespace Os {
extern const char *openglDllName;
}
namespace OCLRT {
GLboolean GLSharingFunctions::makeCurrent(GLContext contextHandle, GLDisplay displayHandle) {
if (displayHandle == 0) {
displayHandle = GLHDCHandle;
}
return this->wglMakeCurrent(displayHandle, contextHandle);
}
GLSharingFunctions::~GLSharingFunctions() {
if (pfnWglDeleteContext) {
pfnWglDeleteContext(GLHGLRCHandleBkpCtx);
}
}
GLboolean GLSharingFunctions::initGLFunctions() {
GLGetCurrentContext = reinterpret_cast<PFNOGLGetCurrentContext>(loadGlFunction("wglGetCurrentContext", GLHDCType));
GLGetCurrentDisplay = reinterpret_cast<PFNOGLGetCurrentDisplay>(loadGlFunction("wglGetCurrentDC", GLHDCType));
glGetString = reinterpret_cast<PFNglGetString>(loadGlFunction("glGetString", GLHDCType));
glGetIntegerv = reinterpret_cast<PFNglGetIntegerv>(loadGlFunction("glGetIntegerv", GLHDCType));
pfnWglCreateContext = reinterpret_cast<PFNwglCreateContext>(loadGlFunction("wglCreateContext", GLHDCType));
pfnWglDeleteContext = reinterpret_cast<PFNwglDeleteContext>(loadGlFunction("wglDeleteContext", GLHDCType));
pfnWglShareLists = reinterpret_cast<PFNwglShareLists>(loadGlFunction("wglShareLists", GLHDCType));
auto wglGetProcAddressFuncPtr = reinterpret_cast<PROC(WINAPI *)(LPCSTR)>(loadGlFunction("wglGetProcAddress", GLHDCType));
GLSetSharedOCLContextState = reinterpret_cast<PFNOGLSetSharedOCLContextStateINTEL>(wglGetProcAddressFuncPtr("wglSetSharedOCLContextStateINTEL"));
GLAcquireSharedBuffer = reinterpret_cast<PFNOGLAcquireSharedBufferINTEL>(wglGetProcAddressFuncPtr("wglAcquireSharedBufferINTEL"));
GLReleaseSharedBuffer = reinterpret_cast<PFNOGLReleaseSharedBufferINTEL>(wglGetProcAddressFuncPtr("wglReleaseSharedBufferINTEL"));
GLAcquireSharedRenderBuffer = reinterpret_cast<PFNOGLAcquireSharedRenderBufferINTEL>(wglGetProcAddressFuncPtr("wglAcquireSharedRenderBufferINTEL"));
GLReleaseSharedRenderBuffer = reinterpret_cast<PFNOGLReleaseSharedRenderBufferINTEL>(wglGetProcAddressFuncPtr("wglReleaseSharedRenderBufferINTEL"));
GLAcquireSharedTexture = reinterpret_cast<PFNOGLAcquireSharedTextureINTEL>(wglGetProcAddressFuncPtr("wglAcquireSharedTextureINTEL"));
GLReleaseSharedTexture = reinterpret_cast<PFNOGLReleaseSharedTextureINTEL>(wglGetProcAddressFuncPtr("wglReleaseSharedTextureINTEL"));
GLRetainSync = reinterpret_cast<PFNOGLRetainSyncINTEL>(wglGetProcAddressFuncPtr("wglRetainSyncINTEL"));
GLReleaseSync = reinterpret_cast<PFNOGLReleaseSyncINTEL>(wglGetProcAddressFuncPtr("wglReleaseSyncINTEL"));
GLGetSynciv = reinterpret_cast<PFNOGLGetSyncivINTEL>(wglGetProcAddressFuncPtr("wglGetSyncivINTEL"));
glGetStringi = reinterpret_cast<PFNglGetStringi>(wglGetProcAddressFuncPtr("glGetStringi"));
this->wglMakeCurrent = reinterpret_cast<PFNwglMakeCurrent>(loadGlFunction("wglMakeCurrent", GLHDCType));
this->pfnGlArbSyncObjectCleanup = cleanupArbSyncObject;
this->pfnGlArbSyncObjectSetup = setupArbSyncObject;
this->pfnGlArbSyncObjectSignal = signalArbSyncObject;
this->pfnGlArbSyncObjectWaitServer = serverWaitForArbSyncObject;
return 1;
}
bool GLSharingFunctions::isGlSharingEnabled() {
static bool oglLibAvailable = std::unique_ptr<OsLibrary>(OsLibrary::load(Os::openglDllName)).get() != nullptr;
return oglLibAvailable;
}
bool GLSharingFunctions::isOpenGlExtensionSupported(const char *pExtensionString) {
bool LoadedNull = (glGetStringi == nullptr) || (glGetIntegerv == nullptr);
if (LoadedNull) {
return false;
}
cl_int NumberOfExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
for (cl_int i = 0; i < NumberOfExtensions; i++) {
const char *pString = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
if (strcmp(pString, pExtensionString) == 0) {
return true;
}
}
return false;
}
bool GLSharingFunctions::isOpenGlSharingSupported() {
const char *Vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
if ((Vendor == NULL) || (strcmp(Vendor, "Intel") != 0)) {
return false;
}
const char *Version = reinterpret_cast<const char *>(glGetString(GL_VERSION));
if (Version == NULL) {
return false;
}
bool IsOpenGLES = false;
if (strstr(Version, "OpenGL ES") != NULL) {
IsOpenGLES = true;
}
if (IsOpenGLES == true) {
if (strstr(Version, "OpenGL ES 1.") != NULL) {
if (isOpenGlExtensionSupported("GL_OES_framebuffer_object") == false) {
return false;
}
}
} else {
if (Version[0] < '3') {
if (isOpenGlExtensionSupported("GL_EXT_framebuffer_object") == false) {
return false;
}
}
}
return true;
}
void *GLSharingFunctions::loadGlFunction(const char *functionName, uint32_t hdc) {
HMODULE module = LoadLibraryA(Os::openglDllName);
return reinterpret_cast<PFNglGetString>(GetProcAddress(module, functionName));
}
void GLSharingFunctions::createBackupContext() {
if (pfnWglCreateContext) {
GLHGLRCHandleBkpCtx = pfnWglCreateContext(GLHDCHandle);
pfnWglShareLists(GLHGLRCHandle, GLHGLRCHandleBkpCtx);
}
}
} // namespace OCLRT