feature: add experimental support for cl-gl sharing on Linux

based on 'clgl-fork' branch from https://github.com/kallaballa/compute-runtime

EGL headers taken from https://github.com/KhronosGroup/EGL-Registry
revision: 57b4876de0f33677ece92dd9de0ef105ce69139d

Related-To: NEO-3599

Fixes https://github.com/intel/compute-runtime/issues/166

Co-authored-by: Jacek Danecki <jacek.danecki@intel.com>
Co-authored-by: Amir Hassan <amir@viel-zu.org>

Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2023-01-20 13:38:21 +01:00
committed by Compute-Runtime-Automation
parent 095f5a773a
commit 4919c7c9fb
52 changed files with 5387 additions and 113 deletions

View File

@@ -33,8 +33,10 @@ endmacro()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source/command_queue/definitions${BRANCH_DIR_SUFFIX})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source/mem_obj/definitions${BRANCH_DIR_SUFFIX})
if(MSVC)
if(WIN32)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source/sharings/gl/windows/include)
else()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source/sharings/gl/linux/include)
endif()
set(NEO_DYNAMIC_LIB_NAME "igdrcl_dll") # single NEO dll

View File

@@ -8,8 +8,9 @@
#ifndef OPENCL_SHARED_RESOURCE
#define OPENCL_SHARED_RESOURCE
#include "shared/source/gmm_helper/gmm_lib.h"
#include "GL/gl.h"
#include "GmmLib.h"
#include "third_party/opencl_headers/CL/cl_gl.h"
// Used for creating CL resources from GL resources
@@ -64,36 +65,32 @@ typedef struct _tagCLGLBufferInfo {
#ifdef _WIN32
// Used for creating GL sync objects from CL events
typedef struct _tagCLGLSyncInfo {
_tagCLGLSyncInfo()
: eventName(NULL),
event((HANDLE)0),
submissionEventName(NULL),
submissionEvent((HANDLE)0),
clientSynchronizationObject((D3DKMT_HANDLE)0),
serverSynchronizationObject((D3DKMT_HANDLE)0),
submissionSynchronizationObject((D3DKMT_HANDLE)0),
hContextToBlock((D3DKMT_HANDLE)0),
waitCalled(false) {
}
char *eventName;
HANDLE event;
char *submissionEventName;
HANDLE submissionEvent;
D3DKMT_HANDLE clientSynchronizationObject;
D3DKMT_HANDLE serverSynchronizationObject;
D3DKMT_HANDLE submissionSynchronizationObject;
D3DKMT_HANDLE hContextToBlock;
bool waitCalled;
char *eventName{};
HANDLE event{};
char *submissionEventName{};
HANDLE submissionEvent{};
D3DKMT_HANDLE clientSynchronizationObject{};
D3DKMT_HANDLE serverSynchronizationObject{};
D3DKMT_HANDLE submissionSynchronizationObject{};
D3DKMT_HANDLE hContextToBlock{};
bool waitCalled{};
} CL_GL_SYNC_INFO, *PCL_GL_SYNC_INFO;
#else
typedef struct _tagCLGLSyncInfo {
char *eventName{};
HANDLE event{};
char *submissionEventName{};
HANDLE submissionEvent{};
bool waitCalled{};
} CL_GL_SYNC_INFO, *PCL_GL_SYNC_INFO;
#endif
// Used for creating CL events from GL sync objects
typedef struct _tagGLCLSyncInfo {
__GLsync *syncName;
GLvoid *pSync;
} GL_CL_SYNC_INFO, *PGL_CL_SYNC_INFO;
#endif
typedef int(__stdcall *pfn_clRetainEvent)(struct _cl_event *event);
typedef int(__stdcall *pfn_clReleaseEvent)(struct _cl_event *event);

View File

@@ -30,6 +30,7 @@ set(RUNTIME_SRCS_HELPERS_BASE
${CMAKE_CURRENT_SOURCE_DIR}/enqueue_properties.h
${CMAKE_CURRENT_SOURCE_DIR}/error_mappers.h
${CMAKE_CURRENT_SOURCE_DIR}/get_info_status_mapper.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/gmm_types_converter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gmm_types_converter.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware_commands_helper.h
@@ -61,14 +62,7 @@ if(SUPPORT_PVC_AND_LATER)
list(APPEND RUNTIME_SRCS_HELPERS_BASE ${CMAKE_CURRENT_SOURCE_DIR}/cl_gfx_core_helper_pvc_and_later.inl)
endif()
set(RUNTIME_SRCS_HELPERS_WINDOWS
${CMAKE_CURRENT_SOURCE_DIR}/windows/gl_helper.h
)
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_HELPERS_BASE})
if(WIN32)
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_HELPERS_WINDOWS})
endif()
set_property(GLOBAL PROPERTY RUNTIME_SRCS_HELPERS_BASE ${RUNTIME_SRCS_HELPERS_BASE})

View File

@@ -6,29 +6,23 @@
*/
#pragma once
#include "shared/source/os_interface/os_library.h"
#include "GL/gl.h"
namespace Os {
extern const char *openglDllName;
}
#include "gl_types.h"
namespace NEO {
class GlFunctionHelper {
public:
GlFunctionHelper::GlFunctionHelper(OsLibrary *glLibrary, const std::string &functionName) {
GlFunctionHelper(OsLibrary *glLibrary, const std::string &functionName) {
glFunctionPtr = (*glLibrary)[functionName];
}
ConvertibleProcAddr operator[](const char *name) {
return ConvertibleProcAddr{glFunctionPtr(name)};
return ConvertibleProcAddr{reinterpret_cast<void *>(glFunctionPtr(name))};
}
protected:
// clang-format off
PROC(__stdcall *glFunctionPtr)(LPCSTR arg1) = nullptr;
// clang-format on
GLFunctionType glFunctionPtr = nullptr;
};
}; // namespace NEO

View File

@@ -17,6 +17,10 @@ target_include_directories(${SHARINGS_ENABLE_LIB_NAME} PRIVATE
${THIRD_PARTY_DIR}
)
if(UNIX AND NOT DISABLE_WDDM_LINUX)
target_include_directories(${SHARINGS_ENABLE_LIB_NAME} PUBLIC ${WDK_INCLUDE_PATHS})
endif()
set(RUNTIME_SRCS_SHARINGS
${CMAKE_CURRENT_SOURCE_DIR}/sharing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sharing.h

View File

@@ -4,23 +4,23 @@
# SPDX-License-Identifier: MIT
#
set(RUNTIME_SRCS_SHARINGS_GL
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_api_intel.h
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_api.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_arb_sync_event.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_buffer.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_cl_image_format.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_context_guard.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_sync_event.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_texture.h
)
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SHARINGS_GL})
add_subdirectories()
if(WIN32)
set(RUNTIME_SRCS_SHARINGS_GL
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_api_intel.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_arb_sync_event.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_buffer.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_cl_image_format.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_context_guard.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_sync_event.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_texture.h
)
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SHARINGS_GL})
add_subdirectories()
set(ADDITIONAL_EXPORTS
"clEnqueueMarkerWithSyncObjectINTEL"
"clGetCLObjectInfoINTEL"

View File

@@ -8,7 +8,6 @@
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/helpers/get_info.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/source/os_interface/windows/wddm/wddm.h"
#include "shared/source/utilities/api_intercept.h"
#include "opencl/source/api/api.h"
@@ -26,7 +25,6 @@
#include "opencl/source/sharings/gl/gl_buffer.h"
#include "opencl/source/sharings/gl/gl_sync_event.h"
#include "opencl/source/sharings/gl/gl_texture.h"
#include "opencl/source/sharings/gl/windows/gl_sharing_windows.h"
#include "opencl/source/tracing/tracing_notify.h"
#include "opencl/source/utilities/cl_logger.h"
@@ -317,8 +315,8 @@ cl_int CL_API_CALL clGetGLContextInfoKHR(const cl_context_properties *properties
fileLoggerInstance().getInput(paramValueSizeRet, 0));
GetInfoHelper info(paramValue, paramValueSize, paramValueSizeRet);
uint32_t GLHGLRCHandle = 0;
uint32_t GLHDCHandle = 0;
uint32_t glHglrcHandle = 0;
uint32_t glHdcHandle = 0;
uint32_t propertyType = 0;
uint32_t propertyValue = 0;
Platform *platform = nullptr;
@@ -332,22 +330,23 @@ cl_int CL_API_CALL clGetGLContextInfoKHR(const cl_context_properties *properties
platform = castToObject<Platform>(reinterpret_cast<cl_platform_id>(properties[1]));
} break;
case CL_GL_CONTEXT_KHR:
GLHGLRCHandle = propertyValue;
glHglrcHandle = propertyValue;
break;
case CL_WGL_HDC_KHR:
GLHDCHandle = propertyValue;
glHdcHandle = propertyValue;
break;
}
properties += 2;
}
}
if ((GLHDCHandle == 0) || (GLHGLRCHandle == 0)) {
auto glSharing = GLSharingFunctions::create();
if ((glHglrcHandle == 0) || glSharing->isGlHdcHandleMissing(glHdcHandle)) {
retVal = CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
return retVal;
}
auto glSharing = std::make_unique<GLSharingFunctionsWindows>();
glSharing->initGLFunctions();
if (glSharing->isOpenGlSharingSupported() == false) {
retVal = CL_INVALID_CONTEXT;
@@ -362,7 +361,7 @@ cl_int CL_API_CALL clGetGLContextInfoKHR(const cl_context_properties *properties
ClDevice *deviceToReturn = nullptr;
for (auto i = 0u; i < platform->getNumDevices(); i++) {
auto device = platform->getClDevice(i);
if (device->getRootDeviceEnvironment().osInterface->getDriverModel()->as<Wddm>()->verifyAdapterLuid(glSharing->getAdapterLuid(reinterpret_cast<GLContext>(static_cast<uintptr_t>(GLHGLRCHandle))))) {
if (glSharing->isHandleCompatible(*device->getRootDeviceEnvironment().osInterface->getDriverModel(), glHglrcHandle)) {
deviceToReturn = device;
break;
}

View File

@@ -28,6 +28,7 @@ class GlArbSyncEvent;
class GLSharingFunctions;
class OSInterface;
class OsContext;
class DriverModel;
typedef unsigned int OS_HANDLE;
@@ -51,6 +52,9 @@ class GLSharingFunctions : public SharingFunctions {
cl_GLenum *formats,
uint32_t *numImageFormats);
static std::unique_ptr<GLSharingFunctions> create();
virtual bool isHandleCompatible(const DriverModel &driverModel, uint32_t handle) const { return true; }
virtual bool isGlHdcHandleMissing(uint32_t handle) const { return false; }
virtual GLboolean initGLFunctions() = 0;
virtual bool isOpenGlSharingSupported() = 0;
};

View File

@@ -37,6 +37,7 @@ class GlTexture : GlSharing {
static uint32_t getClObjectType(cl_GLenum glType, bool returnClGlObjectType);
void releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) override;
void resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData) override;
cl_GLenum target;
cl_GLint miplevel;

View File

@@ -0,0 +1,32 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
set(RUNTIME_SRCS_SHARINGS_GL_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_api_helper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/include/gl_types.h
${CMAKE_CURRENT_SOURCE_DIR}/lin_enable_gl.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_arb_sync_event_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_buffer_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_context_guard_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_library_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing_linux.h
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sync_event_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_texture_linux.cpp
)
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SHARINGS_GL_LINUX})
set(RUNTIME_SRCS_SHARINGS_GL_ENABLE_LINUX
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/lin_enable_gl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/lin_enable_gl.h
)
target_sources(${SHARINGS_ENABLE_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SHARINGS_GL_ENABLE_LINUX})
endif()

View File

@@ -0,0 +1,15 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
namespace NEO {
std::unique_ptr<GLSharingFunctions> GLSharingFunctions::create() {
return std::make_unique<GLSharingFunctionsLinux>();
}
} // namespace NEO

View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/command_stream_receiver.h"
#include "shared/source/device/device.h"
#include "shared/source/os_interface/os_interface.h"
#include "opencl/extensions/public/cl_gl_private_intel.h"
#include "opencl/source/command_queue/command_queue.h"
#include "opencl/source/context/context.h"
#include "opencl/source/helpers/base_object.h"
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include <GL/gl.h>
namespace NEO {
void cleanupArbSyncObject(OSInterface &osInterface, CL_GL_SYNC_INFO *glSyncInfo) {}
bool setupArbSyncObject(GLSharingFunctions &sharing, OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
return false;
}
void signalArbSyncObject(OsContext &osContext, CL_GL_SYNC_INFO &glSyncInfo) {}
void serverWaitForArbSyncObject(OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {}
GlArbSyncEvent::GlArbSyncEvent(Context &context)
: Event(&context, nullptr, CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR, CompletionStamp::notReady, CompletionStamp::notReady),
glSyncInfo(std::make_unique<CL_GL_SYNC_INFO>()) {
}
bool GlArbSyncEvent::setBaseEvent(Event &ev) {
UNRECOVERABLE_IF(this->baseEvent != nullptr);
UNRECOVERABLE_IF(ev.getContext() == nullptr);
UNRECOVERABLE_IF(ev.getCommandQueue() == nullptr);
auto cmdQueue = ev.getCommandQueue();
auto osInterface = cmdQueue->getGpgpuCommandStreamReceiver().getOSInterface();
UNRECOVERABLE_IF(osInterface == nullptr);
if (false == ctx->getSharing<GLSharingFunctionsLinux>()->glArbSyncObjectSetup(*osInterface, *glSyncInfo)) {
return false;
}
this->baseEvent = &ev;
this->cmdQueue = cmdQueue;
this->cmdQueue->incRefInternal();
this->baseEvent->incRefInternal();
this->osInterface = osInterface;
ev.addChild(*this);
return true;
}
GlArbSyncEvent::~GlArbSyncEvent() {
if (baseEvent != nullptr) {
ctx->getSharing<GLSharingFunctionsLinux>()->glArbSyncObjectCleanup(*osInterface, glSyncInfo.get());
baseEvent->decRefInternal();
}
}
GlArbSyncEvent *GlArbSyncEvent::create(Event &baseEvent) {
if (baseEvent.getContext() == nullptr) {
return nullptr;
}
auto arbSyncEvent = new GlArbSyncEvent(*baseEvent.getContext());
if (false == arbSyncEvent->setBaseEvent(baseEvent)) {
delete arbSyncEvent;
arbSyncEvent = nullptr;
}
return arbSyncEvent;
}
void GlArbSyncEvent::unblockEventBy(Event &event, TaskCountType taskLevel, int32_t transitionStatus) {
DEBUG_BREAK_IF(&event != this->baseEvent);
if ((transitionStatus > CL_SUBMITTED) || (transitionStatus < 0)) {
return;
}
ctx->getSharing<GLSharingFunctionsLinux>()->glArbSyncObjectSignal(event.getCommandQueue()->getGpgpuCommandStreamReceiver().getOsContext(), *glSyncInfo);
ctx->getSharing<GLSharingFunctionsLinux>()->glArbSyncObjectWaitServer(*osInterface, *glSyncInfo);
}
} // namespace NEO
extern "C" CL_API_ENTRY cl_int CL_API_CALL
clEnqueueMarkerWithSyncObjectINTEL(cl_command_queue commandQueue,
cl_event *event,
cl_context *context) {
return CL_INVALID_OPERATION;
}
extern "C" CL_API_ENTRY cl_int CL_API_CALL
clGetCLObjectInfoINTEL(cl_mem memObj,
void *pResourceInfo) {
return CL_INVALID_OPERATION;
}
extern "C" CL_API_ENTRY cl_int CL_API_CALL
clGetCLEventInfoINTEL(cl_event event, PCL_GL_SYNC_INFO *pSyncInfoHandleRet, cl_context *pClContextRet) {
if ((nullptr == pSyncInfoHandleRet) || (nullptr == pClContextRet)) {
return CL_INVALID_ARG_VALUE;
}
auto neoEvent = NEO::castToObject<NEO::Event>(event);
if (nullptr == neoEvent) {
return CL_INVALID_EVENT;
}
if (neoEvent->getCommandType() != CL_COMMAND_RELEASE_GL_OBJECTS) {
*pSyncInfoHandleRet = nullptr;
*pClContextRet = static_cast<cl_context>(neoEvent->getContext());
return CL_SUCCESS;
}
auto sharing = neoEvent->getContext()->getSharing<NEO::GLSharingFunctionsLinux>();
if (sharing == nullptr) {
return CL_INVALID_OPERATION;
}
NEO::GlArbSyncEvent *arbSyncEvent = sharing->getOrCreateGlArbSyncEvent(*neoEvent);
if (nullptr == arbSyncEvent) {
return CL_OUT_OF_RESOURCES;
}
neoEvent->updateExecutionStatus();
CL_GL_SYNC_INFO *syncInfo = arbSyncEvent->getSyncInfo();
*pSyncInfoHandleRet = syncInfo;
*pClContextRet = static_cast<cl_context>(neoEvent->getContext());
return CL_SUCCESS;
}
extern "C" CL_API_ENTRY cl_int CL_API_CALL
clReleaseGlSharedEventINTEL(cl_event event) {
auto neoEvent = NEO::castToObject<NEO::Event>(event);
if (nullptr == neoEvent) {
return CL_INVALID_EVENT;
}
auto arbSyncEvent = neoEvent->getContext()->getSharing<NEO::GLSharingFunctionsLinux>()->getGlArbSyncEvent(*neoEvent);
neoEvent->getContext()->getSharing<NEO::GLSharingFunctionsLinux>()->removeGlArbSyncEventMapping(*neoEvent);
if (nullptr != arbSyncEvent) {
arbSyncEvent->release();
}
neoEvent->release();
return CL_SUCCESS;
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/gmm_helper/gmm.h"
#include "shared/source/helpers/get_info.h"
#include "shared/source/memory_manager/allocation_properties.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "opencl/extensions/public/cl_gl_private_intel.h"
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/source/context/context.h"
#include "opencl/source/mem_obj/buffer.h"
#include "opencl/source/sharings/gl/gl_buffer.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "config.h"
using namespace NEO;
Buffer *GlBuffer::createSharedGlBuffer(Context *context, cl_mem_flags flags, unsigned int bufferId, cl_int *errcodeRet) {
ErrorCodeHelper errorCode(errcodeRet, CL_SUCCESS);
CL_GL_BUFFER_INFO bufferInfo = {0};
bufferInfo.bufferName = bufferId;
GLSharingFunctionsLinux *sharingFunctions = context->getSharing<GLSharingFunctionsLinux>();
if (sharingFunctions->acquireSharedBufferINTEL(&bufferInfo) == GL_FALSE) {
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
auto graphicsAllocation = GlBuffer::createGraphicsAllocation(context, bufferId, bufferInfo);
if (!graphicsAllocation) {
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
auto glHandler = new GlBuffer(sharingFunctions, bufferId);
auto rootDeviceIndex = graphicsAllocation->getRootDeviceIndex();
auto multiGraphicsAllocation = MultiGraphicsAllocation(rootDeviceIndex);
multiGraphicsAllocation.addAllocation(graphicsAllocation);
return Buffer::createSharedBuffer(context, flags, glHandler, std::move(multiGraphicsAllocation));
}
void GlBuffer::synchronizeObject(UpdateData &updateData) {
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
CL_GL_BUFFER_INFO bufferInfo = {};
bufferInfo.bufferName = this->clGlObjectId;
sharingFunctions->acquireSharedBufferINTEL(&bufferInfo);
auto graphicsAllocation = updateData.memObject->getGraphicsAllocation(updateData.rootDeviceIndex);
updateData.sharedHandle = bufferInfo.globalShareHandle;
updateData.synchronizationStatus = SynchronizeStatus::ACQUIRE_SUCCESFUL;
graphicsAllocation->setAllocationOffset(bufferInfo.bufferOffset);
const auto currentSharedHandle = graphicsAllocation->peekSharedHandle();
if (currentSharedHandle != updateData.sharedHandle) {
updateData.updateData = new CL_GL_BUFFER_INFO(bufferInfo);
}
}
void GlBuffer::resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData) {
const auto memObject = updateData->memObject;
if (currentSharedHandle != updateData->sharedHandle) {
const auto bufferInfo = std::unique_ptr<CL_GL_BUFFER_INFO>(static_cast<CL_GL_BUFFER_INFO *>(updateData->updateData));
auto oldGraphicsAllocation = memObject->getGraphicsAllocation(updateData->rootDeviceIndex);
popGraphicsAllocationFromReuse(oldGraphicsAllocation);
Context *context = memObject->getContext();
auto newGraphicsAllocation = createGraphicsAllocation(context, clGlObjectId, *bufferInfo);
if (newGraphicsAllocation == nullptr) {
updateData->synchronizationStatus = SynchronizeStatus::SYNCHRONIZE_ERROR;
memObject->removeGraphicsAllocation(updateData->rootDeviceIndex);
} else {
updateData->synchronizationStatus = SynchronizeStatus::ACQUIRE_SUCCESFUL;
memObject->resetGraphicsAllocation(newGraphicsAllocation);
}
if (updateData->synchronizationStatus == SynchronizeStatus::ACQUIRE_SUCCESFUL) {
memObject->getGraphicsAllocation(updateData->rootDeviceIndex)->setAllocationOffset(bufferInfo->bufferOffset);
}
}
}
void GlBuffer::popGraphicsAllocationFromReuse(GraphicsAllocation *graphicsAllocation) {
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
std::unique_lock<std::mutex> lock(sharingFunctions->mutex);
auto &graphicsAllocations = sharingFunctions->graphicsAllocationsForGlBufferReuse;
auto foundIter = std::find_if(graphicsAllocations.begin(), graphicsAllocations.end(),
[&graphicsAllocation](const std::pair<unsigned int, GraphicsAllocation *> &entry) {
return entry.second == graphicsAllocation;
});
if (foundIter != graphicsAllocations.end()) {
std::iter_swap(foundIter, graphicsAllocations.end() - 1);
graphicsAllocations.pop_back();
}
graphicsAllocation->decReuseCount();
}
void GlBuffer::releaseReusedGraphicsAllocation() {
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
std::unique_lock<std::mutex> lock(sharingFunctions->mutex);
auto &allocationsVector = sharingFunctions->graphicsAllocationsForGlBufferReuse;
auto itEnd = allocationsVector.end();
for (auto it = allocationsVector.begin(); it != itEnd; it++) {
if (it->first == clGlObjectId) {
it->second->decReuseCount();
if (it->second->peekReuseCount() == 0) {
std::iter_swap(it, itEnd - 1);
allocationsVector.pop_back();
}
break;
}
}
}
GraphicsAllocation *GlBuffer::createGraphicsAllocation(Context *context, unsigned int bufferId, _tagCLGLBufferInfo &bufferInfo) {
GLSharingFunctionsLinux *sharingFunctions = context->getSharing<GLSharingFunctionsLinux>();
auto &allocationsVector = sharingFunctions->graphicsAllocationsForGlBufferReuse;
GraphicsAllocation *graphicsAllocation = nullptr;
bool reusedAllocation = false;
std::unique_lock<std::mutex> lock(sharingFunctions->mutex);
auto endIter = allocationsVector.end();
auto foundIter =
std::find_if(allocationsVector.begin(), endIter,
[&bufferId](const std::pair<unsigned int, GraphicsAllocation *> &entry) { return entry.first == bufferId; });
if (foundIter != endIter) {
graphicsAllocation = foundIter->second;
reusedAllocation = true;
}
if (!graphicsAllocation) {
AllocationProperties properties = {context->getDevice(0)->getRootDeviceIndex(),
false, // allocateMemory
0u, // size
AllocationType::SHARED_BUFFER,
false, // isMultiStorageAllocation
context->getDeviceBitfieldForAllocation(context->getDevice(0)->getRootDeviceIndex())};
// couldn't find allocation for reuse - create new
graphicsAllocation =
context->getMemoryManager()->createGraphicsAllocationFromSharedHandle(bufferInfo.globalShareHandle, properties, true, false, false);
}
if (!graphicsAllocation) {
return nullptr;
}
graphicsAllocation->incReuseCount(); // decremented in releaseReusedGraphicsAllocation() called from MemObj destructor
if (!reusedAllocation) {
sharingFunctions->graphicsAllocationsForGlBufferReuse.push_back(std::make_pair(bufferId, graphicsAllocation));
if (bufferInfo.pGmmResInfo) {
DEBUG_BREAK_IF(graphicsAllocation->getDefaultGmm() != nullptr);
auto helper = context->getDevice(0)->getRootDeviceEnvironment().getGmmHelper();
graphicsAllocation->setDefaultGmm(new Gmm(helper, bufferInfo.pGmmResInfo));
}
}
return graphicsAllocation;
}
void GlBuffer::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
CL_GL_BUFFER_INFO bufferInfo = {};
bufferInfo.bufferName = this->clGlObjectId;
sharingFunctions->releaseSharedBufferINTEL(&bufferInfo);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/sharings/gl/gl_context_guard.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
namespace NEO {
GLContextGuard::GLContextGuard(GLSharingFunctions &sharingFcns) : sharingFunctions(&sharingFcns) {
auto &sharing = *static_cast<GLSharingFunctionsLinux *>(sharingFunctions);
currentContextHandle = sharing.getCurrentContext();
currentDisplayHandle = sharing.getCurrentDisplay();
auto ctxToMakeCurrent = sharing.getContextHandle();
if (currentContextHandle == 0) {
ctxToMakeCurrent = sharing.getBackupContextHandle();
}
if (currentContextHandle != sharing.getContextHandle() && currentContextHandle != sharing.getBackupContextHandle()) {
if (sharing.makeCurrent(ctxToMakeCurrent) == GL_FALSE) {
while (sharing.makeCurrent(sharing.getBackupContextHandle()) == GL_FALSE) {
;
}
}
}
}
GLContextGuard::~GLContextGuard() {
auto &sharing = *static_cast<GLSharingFunctionsLinux *>(sharingFunctions);
if (currentContextHandle != sharing.getContextHandle()) {
sharing.makeCurrent(currentContextHandle, currentDisplayHandle);
}
}
} // namespace NEO

View File

@@ -0,0 +1,13 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include <cstdint>
namespace Os {
const char *eglDllName = "libEGL.so.1";
const char *openglDllName = "libGL.so.1";
} // namespace Os

View File

@@ -0,0 +1,156 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "opencl/source/context/context.inl"
#include "opencl/source/helpers/gl_helper.h"
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
namespace Os {
extern const char *eglDllName;
extern const char *openglDllName;
} // namespace Os
namespace NEO {
GLSharingFunctionsLinux::GLSharingFunctionsLinux(GLType glhdcType, GLContext glhglrcHandle, GLContext glhglrcHandleBkpCtx, GLDisplay glhdcHandle)
: glHDCType(glhdcType), glHGLRCHandle(glhglrcHandle), glHGLRCHandleBkpCtx(glhglrcHandleBkpCtx), glHDCHandle(glhdcHandle) {
GLSharingFunctionsLinux::initGLFunctions();
updateOpenGLContext();
}
GLSharingFunctionsLinux::~GLSharingFunctionsLinux() = default;
bool GLSharingFunctionsLinux::isGlSharingEnabled() {
static bool oglLibAvailable = std::unique_ptr<OsLibrary>(OsLibrary::load(Os::eglDllName)).get() != nullptr;
return oglLibAvailable;
}
void GLSharingFunctionsLinux::createBackupContext() {
if (pfnEglCreateContext) {
glHGLRCHandleBkpCtx = pfnEglCreateContext(glHDCHandle);
pfnEglShareLists(glHGLRCHandle, glHGLRCHandleBkpCtx);
}
}
GLboolean GLSharingFunctionsLinux::setSharedOCLContextState() {
ContextInfo contextInfo{};
GLboolean retVal = glSetSharedOCLContextState(glHDCHandle, glHGLRCHandle, CL_TRUE, &contextInfo);
if (retVal == GL_FALSE) {
return GL_FALSE;
}
glContextHandle = contextInfo.ContextHandle;
glDeviceHandle = contextInfo.DeviceHandle;
return retVal;
}
bool GLSharingFunctionsLinux::isOpenGlExtensionSupported(const unsigned char *pExtensionString) {
if (glGetStringi == nullptr || glGetIntegerv == nullptr) {
return false;
}
cl_int numberOfExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numberOfExtensions);
for (cl_int i = 0; i < numberOfExtensions; i++) {
std::basic_string<unsigned char> pString = glGetStringi(GL_EXTENSIONS, i);
if (pString == pExtensionString) {
return true;
}
}
return false;
}
bool GLSharingFunctionsLinux::isOpenGlSharingSupported() {
std::basic_string<unsigned char> vendor = glGetString(GL_VENDOR);
const unsigned char intelVendor[] = "Intel";
if ((vendor.empty()) || (vendor != intelVendor)) {
return false;
}
std::basic_string<unsigned char> version = glGetString(GL_VERSION);
if (version.empty()) {
return false;
}
bool isOpenGLES = false;
const unsigned char versionES[] = "OpenGL ES";
if (version.find(versionES) != std::string::npos) {
isOpenGLES = true;
}
if (isOpenGLES == true) {
const unsigned char versionES1[] = "OpenGL ES 1.";
if (version.find(versionES1) != std::string::npos) {
const unsigned char supportGLOES[] = "GL_OES_framebuffer_object";
if (isOpenGlExtensionSupported(supportGLOES) == false) {
return false;
}
}
} else {
if (version[0] < '3') {
const unsigned char supportGLEXT[] = "GL_EXT_framebuffer_object";
if (isOpenGlExtensionSupported(supportGLEXT) == false) {
return false;
}
}
}
return true;
}
GlArbSyncEvent *GLSharingFunctionsLinux::getGlArbSyncEvent(Event &baseEvent) {
std::lock_guard<std::mutex> lock{glArbEventMutex};
auto it = glArbEventMapping.find(&baseEvent);
if (it != glArbEventMapping.end()) {
return it->second;
}
return nullptr;
}
void GLSharingFunctionsLinux::removeGlArbSyncEventMapping(Event &baseEvent) {
std::lock_guard<std::mutex> lock{glArbEventMutex};
auto it = glArbEventMapping.find(&baseEvent);
if (it == glArbEventMapping.end()) {
DEBUG_BREAK_IF(it == glArbEventMapping.end());
return;
}
glArbEventMapping.erase(it);
}
GLboolean GLSharingFunctionsLinux::initGLFunctions() {
eglLibrary.reset(OsLibrary::load(Os::eglDllName));
glLibrary.reset(OsLibrary::load(Os::openglDllName));
if (eglLibrary->isLoaded()) {
GlFunctionHelper eglGetProc(eglLibrary.get(), "eglGetProcAddress");
glGetCurrentContext = eglGetProc["eglGetCurrentContext"];
glGetCurrentDisplay = eglGetProc["eglGetCurrentDisplay"];
pfnEglCreateContext = eglGetProc["eglCreateContext"];
pfnEglDeleteContext = eglGetProc["eglDestroyContext"];
eglMakeCurrent = eglGetProc["eglMakeCurrent"];
eglCreateImage = eglGetProc["eglCreateImage"];
eglDestroyImage = eglGetProc["eglDestroyImage"];
glAcquireSharedTexture = eglGetProc["eglExportDMABUFImageMESA"];
}
if (glLibrary->isLoaded()) {
glGetString = (*glLibrary)["glGetString"];
glGetStringi = (*glLibrary)["glGetStringi"];
glGetIntegerv = (*glLibrary)["glGetIntegerv"];
glGetTexLevelParameteriv = (*glLibrary)["glGetTexLevelParameteriv"];
}
this->pfnGlArbSyncObjectCleanup = cleanupArbSyncObject;
this->pfnGlArbSyncObjectSetup = setupArbSyncObject;
this->pfnGlArbSyncObjectSignal = signalArbSyncObject;
this->pfnGlArbSyncObjectWaitServer = serverWaitForArbSyncObject;
return 1;
}
template GLSharingFunctionsLinux *Context::getSharing<GLSharingFunctionsLinux>();
} // namespace NEO

View File

@@ -0,0 +1,221 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "opencl/extensions/public/cl_gl_private_intel.h"
#include "opencl/source/sharings/gl/gl_sharing.h"
#include "opencl/source/sharings/gl/linux/include/gl_types.h"
#include <GL/gl.h>
#include <EGL/eglext.h>
namespace NEO {
// OpenGL API names
typedef GLboolean (*PFNOGLSetSharedOCLContextStateINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLboolean state, GLvoid *pContextInfo);
typedef GLboolean (*PFNOGLAcquireSharedBufferINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pBufferInfo);
typedef GLboolean (*PFNOGLAcquireSharedRenderBufferINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pResourceInfo);
typedef GLboolean (*PFNOGLReleaseSharedBufferINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pBufferInfo);
typedef GLboolean (*PFNOGLReleaseSharedRenderBufferINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pResourceInfo);
typedef GLboolean (*PFNOGLReleaseSharedTextureINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pResourceInfo);
typedef GLContext (*PFNOGLGetCurrentContext)();
typedef GLDisplay (*PFNOGLGetCurrentDisplay)();
typedef GLboolean (*PFNOGLMakeCurrent)(GLDisplay hdcHandle, void *draw, void *read, GLContext contextHandle);
typedef GLboolean (*PFNOGLRetainSyncINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pSyncInfo);
typedef GLboolean (*PFNOGLReleaseSyncINTEL)(GLDisplay hdcHandle, GLContext contextHandle, GLContext backupContextHandle, GLvoid *pSync);
typedef void (*PFNOGLGetSyncivINTEL)(GLvoid *pSync, GLenum pname, GLint *value);
typedef const GLubyte *(*PFNglGetString)(GLenum name);
typedef const GLubyte *(*PFNglGetStringi)(GLenum name, GLuint index);
typedef void (*PFNglGetIntegerv)(GLenum pname, GLint *params);
typedef void (*PFNglBindTexture)(GLenum target, GLuint texture);
typedef void (*PFNglGetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params);
// egl
typedef unsigned char (*PFNeglMakeCurrent)(void *, void *);
typedef GLContext (*PFNeglCreateContext)(GLDisplay hdcHandle);
typedef int (*PFNeglShareLists)(GLContext contextHandle, GLContext backupContextHandle);
typedef EGLBoolean (*PFNeglDeleteContext)(EGLDisplay dpy, EGLContext ctx);
typedef bool (*PFNglArbSyncObjectSetup)(GLSharingFunctions &sharing, OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo);
typedef void (*PFNglArbSyncObjectCleanup)(OSInterface &osInterface, CL_GL_SYNC_INFO *glSyncInfo);
typedef void (*PFNglArbSyncObjectSignal)(OsContext &osContext, CL_GL_SYNC_INFO &glSyncInfo);
typedef void (*PFNglArbSyncObjectWaitServer)(OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo);
typedef EGLImage (*PFNeglCreateImage)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attribList);
typedef EGLBoolean (*PFNeglDestroyImage)(EGLDisplay dpy, EGLImage image);
class GLSharingFunctionsLinux : public GLSharingFunctions {
public:
GLSharingFunctionsLinux() = default;
GLSharingFunctionsLinux(GLType glhdcType, GLContext glhglrcHandle, GLContext glhglrcHandleBkpCtx, GLDisplay glhdcHandle);
~GLSharingFunctionsLinux() override;
OS_HANDLE getGLDeviceHandle() const { return glDeviceHandle; }
OS_HANDLE getGLContextHandle() const { return glContextHandle; }
GLboolean initGLFunctions() override;
bool isOpenGlSharingSupported() override;
static bool isGlSharingEnabled();
// Arb sync event
template <typename EventType = GlArbSyncEvent>
auto getOrCreateGlArbSyncEvent(Event &baseEvent) -> decltype(EventType::create(baseEvent));
GlArbSyncEvent *getGlArbSyncEvent(Event &baseEvent);
void removeGlArbSyncEventMapping(Event &baseEvent);
// Gl functions
GLboolean acquireSharedBufferINTEL(GLvoid *pBufferInfo) {
return glAcquireSharedBuffer(glHDCHandle, glHGLRCHandle, glHGLRCHandleBkpCtx, pBufferInfo);
}
GLboolean releaseSharedBufferINTEL(GLvoid *pBufferInfo) {
return glReleaseSharedBuffer(glHDCHandle, glHGLRCHandle, glHGLRCHandleBkpCtx, pBufferInfo);
}
GLboolean acquireSharedRenderBuffer(GLvoid *pResourceInfo) {
return glAcquireSharedRenderBuffer(glHDCHandle, glHGLRCHandle, glHGLRCHandleBkpCtx, pResourceInfo);
}
GLboolean releaseSharedRenderBuffer(GLvoid *pResourceInfo) {
return glReleaseSharedRenderBuffer(glHDCHandle, glHGLRCHandle, glHGLRCHandleBkpCtx, pResourceInfo);
}
EGLBoolean acquireSharedTexture(CL_GL_RESOURCE_INFO *pResourceInfo) {
int fds;
int stride, offset;
int miplevel = 0;
EGLAttrib attribList[] = {EGL_GL_TEXTURE_LEVEL, miplevel, EGL_NONE};
EGLImage image = eglCreateImage(glHDCHandle, glHGLRCHandle, EGL_GL_TEXTURE_2D, reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(pResourceInfo->name)), &attribList[0]);
if (image == EGL_NO_IMAGE) {
return EGL_FALSE;
}
EGLBoolean ret = glAcquireSharedTexture(glHDCHandle, image, &fds, &stride, &offset);
if (ret == EGL_TRUE && fds > 0) {
pResourceInfo->globalShareHandle = fds;
} else {
eglDestroyImage(glHDCHandle, image);
ret = EGL_FALSE;
}
return ret;
}
GLboolean releaseSharedTexture(GLvoid *pResourceInfo) {
return 1;
}
GLboolean retainSync(GLvoid *pSyncInfo) {
return glRetainSync(glHDCHandle, glHGLRCHandle, glHGLRCHandleBkpCtx, pSyncInfo);
}
GLboolean releaseSync(GLvoid *pSync) {
return glReleaseSync(glHDCHandle, glHGLRCHandle, glHGLRCHandleBkpCtx, pSync);
}
void getSynciv(GLvoid *pSync, GLenum pname, GLint *value) {
return glGetSynciv(pSync, pname, value);
}
GLContext getCurrentContext() {
return glGetCurrentContext();
}
GLDisplay getCurrentDisplay() {
return glGetCurrentDisplay();
}
GLboolean makeCurrent(GLContext contextHandle, GLDisplay displayHandle = 0) {
if (displayHandle == 0) {
displayHandle = glHDCHandle;
}
return this->eglMakeCurrent(displayHandle, contextHandle);
}
GLContext getBackupContextHandle() {
return glHGLRCHandleBkpCtx;
}
GLContext getContextHandle() {
return glHGLRCHandle;
}
bool glArbSyncObjectSetup(OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
return pfnGlArbSyncObjectSetup(*this, osInterface, glSyncInfo);
}
void glArbSyncObjectCleanup(OSInterface &osInterface, CL_GL_SYNC_INFO *glSyncInfo) {
pfnGlArbSyncObjectCleanup(osInterface, glSyncInfo);
}
void glArbSyncObjectSignal(OsContext &osContext, CL_GL_SYNC_INFO &glSyncInfo) {
pfnGlArbSyncObjectSignal(osContext, glSyncInfo);
}
void glArbSyncObjectWaitServer(OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
pfnGlArbSyncObjectWaitServer(osInterface, glSyncInfo);
}
// Buffer reuse
std::mutex mutex;
std::vector<std::pair<unsigned int, GraphicsAllocation *>> graphicsAllocationsForGlBufferReuse;
PFNglGetTexLevelParameteriv glGetTexLevelParameteriv = nullptr;
protected:
void updateOpenGLContext() {
if (glSetSharedOCLContextState) {
setSharedOCLContextState();
}
}
GLboolean setSharedOCLContextState();
void createBackupContext();
bool isOpenGlExtensionSupported(const unsigned char *pExtentionString);
// Handles
GLType glHDCType = 0;
GLContext glHGLRCHandle = 0;
GLContext glHGLRCHandleBkpCtx = 0;
GLDisplay glHDCHandle = 0;
OS_HANDLE glDeviceHandle = 0;
OS_HANDLE glContextHandle = 0;
// GL functions
std::unique_ptr<OsLibrary> glLibrary;
std::unique_ptr<OsLibrary> eglLibrary;
PFNOGLSetSharedOCLContextStateINTEL glSetSharedOCLContextState = nullptr;
PFNOGLAcquireSharedBufferINTEL glAcquireSharedBuffer = nullptr;
PFNOGLReleaseSharedBufferINTEL glReleaseSharedBuffer = nullptr;
PFNOGLAcquireSharedRenderBufferINTEL glAcquireSharedRenderBuffer = nullptr;
PFNOGLReleaseSharedRenderBufferINTEL glReleaseSharedRenderBuffer = nullptr;
PFNEGLEXPORTDMABUFIMAGEMESAPROC glAcquireSharedTexture = nullptr;
PFNOGLReleaseSharedTextureINTEL glReleaseSharedTexture = nullptr;
PFNOGLGetCurrentContext glGetCurrentContext = nullptr;
PFNOGLGetCurrentDisplay glGetCurrentDisplay = nullptr;
PFNglGetString glGetString = nullptr;
PFNglGetStringi glGetStringi = nullptr;
PFNglGetIntegerv glGetIntegerv = nullptr;
PFNeglCreateContext pfnEglCreateContext = nullptr;
PFNeglMakeCurrent eglMakeCurrent = nullptr;
PFNeglShareLists pfnEglShareLists = nullptr;
PFNeglDeleteContext pfnEglDeleteContext = nullptr;
PFNOGLRetainSyncINTEL glRetainSync = nullptr;
PFNOGLReleaseSyncINTEL glReleaseSync = nullptr;
PFNOGLGetSyncivINTEL glGetSynciv = nullptr;
PFNglArbSyncObjectSetup pfnGlArbSyncObjectSetup = nullptr;
PFNglArbSyncObjectCleanup pfnGlArbSyncObjectCleanup = nullptr;
PFNglArbSyncObjectSignal pfnGlArbSyncObjectSignal = nullptr;
PFNglArbSyncObjectWaitServer pfnGlArbSyncObjectWaitServer = nullptr;
PFNeglCreateImage eglCreateImage = nullptr;
PFNeglDestroyImage eglDestroyImage = nullptr;
// support for GL_ARB_cl_event
std::mutex glArbEventMutex;
std::unordered_map<Event *, GlArbSyncEvent *> glArbEventMapping;
};
template <typename EventType>
inline auto GLSharingFunctionsLinux::getOrCreateGlArbSyncEvent(Event &baseEvent) -> decltype(EventType::create(baseEvent)) {
std::lock_guard<std::mutex> lock{glArbEventMutex};
auto it = glArbEventMapping.find(&baseEvent);
if (it != glArbEventMapping.end()) {
return it->second;
}
auto arbEvent = EventType::create(baseEvent);
if (nullptr == arbEvent) {
return arbEvent;
}
glArbEventMapping[&baseEvent] = arbEvent;
return arbEvent;
}
} // namespace NEO

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/command_stream/command_stream_receiver.h"
#include "shared/source/device/device.h"
#include "shared/source/helpers/get_info.h"
#include "shared/source/helpers/timestamp_packet.h"
#include "opencl/extensions/public/cl_gl_private_intel.h"
#include "opencl/source/context/context.h"
#include "opencl/source/event/async_events_handler.h"
#include "opencl/source/event/event_builder.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/sharings/gl/gl_context_guard.h"
#include "opencl/source/sharings/gl/gl_sync_event.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
namespace NEO {
GlSyncEvent::GlSyncEvent(Context &context, const GL_CL_SYNC_INFO &sync)
: Event(&context, nullptr, CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR, CompletionStamp::notReady, CompletionStamp::notReady),
glSync(std::make_unique<GL_CL_SYNC_INFO>(sync)) {
transitionExecutionStatus(CL_SUBMITTED);
}
GlSyncEvent::~GlSyncEvent() {
ctx->getSharing<GLSharingFunctionsLinux>()->releaseSync(glSync->pSync);
}
GlSyncEvent *GlSyncEvent::create(Context &context, cl_GLsync sync, cl_int *errCode) {
GLContextGuard guard(*context.getSharing<GLSharingFunctionsLinux>());
ErrorCodeHelper err(errCode, CL_SUCCESS);
GL_CL_SYNC_INFO syncInfo = {sync, nullptr};
context.getSharing<GLSharingFunctionsLinux>()->retainSync(&syncInfo);
DEBUG_BREAK_IF(!syncInfo.pSync);
EventBuilder eventBuilder;
eventBuilder.create<GlSyncEvent>(context, syncInfo);
return static_cast<GlSyncEvent *>(eventBuilder.finalizeAndRelease());
}
void GlSyncEvent::updateExecutionStatus() {
GLContextGuard guard(*ctx->getSharing<GLSharingFunctionsLinux>());
int retVal = 0;
ctx->getSharing<GLSharingFunctionsLinux>()->getSynciv(glSync->pSync, GL_SYNC_STATUS, &retVal);
if (retVal == GL_SIGNALED) {
setStatus(CL_COMPLETE);
}
}
TaskCountType GlSyncEvent::getTaskLevel() {
if (peekExecutionStatus() == CL_COMPLETE) {
return 0;
}
return CompletionStamp::notReady;
}
} // namespace NEO

View File

@@ -0,0 +1,294 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/gmm_helper/gmm.h"
#include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/gmm_helper/resource_info.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/get_info.h"
#include "shared/source/helpers/gfx_core_helper.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/memory_manager/allocation_properties.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "shared/source/os_interface/product_helper.h"
#include "opencl/extensions/public/cl_gl_private_intel.h"
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/source/context/context.h"
#include "opencl/source/helpers/gmm_types_converter.h"
#include "opencl/source/mem_obj/image.h"
#include "opencl/source/sharings/gl/gl_texture.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "CL/cl_gl.h"
#include "config.h"
#include <GL/gl.h>
namespace NEO {
Image *GlTexture::createSharedGlTexture(Context *context, cl_mem_flags flags, cl_GLenum target, cl_GLint miplevel, cl_GLuint texture,
cl_int *errcodeRet) {
ErrorCodeHelper errorCode(errcodeRet, CL_INVALID_GL_OBJECT);
auto memoryManager = context->getMemoryManager();
cl_image_desc imgDesc = {};
ImageInfo imgInfo = {};
cl_image_format imgFormat = {};
McsSurfaceInfo mcsSurfaceInfo = {};
CL_GL_RESOURCE_INFO texInfo = {};
texInfo.name = texture;
texInfo.target = getBaseTargetType(target);
if (texInfo.target != GL_TEXTURE_2D) {
printf("target %x not supported\n", target);
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
uint32_t qPitch = 0;
uint32_t cubeFaceIndex = __GMM_NO_CUBE_MAP;
int imageWidth = 0, imageHeight = 0, internalFormat = 0;
GLSharingFunctionsLinux *sharingFunctions = context->getSharing<GLSharingFunctionsLinux>();
sharingFunctions->glGetTexLevelParameteriv(target, miplevel, GL_TEXTURE_WIDTH, &imageWidth);
sharingFunctions->glGetTexLevelParameteriv(target, miplevel, GL_TEXTURE_HEIGHT, &imageHeight);
sharingFunctions->glGetTexLevelParameteriv(target, miplevel, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat);
imgDesc.image_width = imageWidth;
imgDesc.image_height = imageHeight;
switch (internalFormat) {
case GL_RGBA:
case GL_RGBA8:
case GL_RGBA16F:
case GL_RGB:
texInfo.glInternalFormat = internalFormat;
break;
default:
printf("internal format %x not supported\n", internalFormat);
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
imgInfo.imgDesc.imageWidth = imgDesc.image_width;
imgInfo.imgDesc.imageType = ImageType::Image2D;
imgInfo.imgDesc.imageHeight = imgDesc.image_height;
if (target == GL_RENDERBUFFER_EXT) {
sharingFunctions->acquireSharedRenderBuffer(&texInfo);
} else {
if (sharingFunctions->acquireSharedTexture(&texInfo) != EGL_TRUE) {
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
}
errorCode.set(CL_SUCCESS);
if (setClImageFormat(texInfo.glInternalFormat, imgFormat) == false) {
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
auto surfaceFormatInfoAddress = Image::getSurfaceFormatFromTable(flags, &imgFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
if (!surfaceFormatInfoAddress) {
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
auto surfaceFormatInfo = *surfaceFormatInfoAddress;
imgInfo.surfaceFormat = &surfaceFormatInfo.surfaceFormat;
AllocationProperties allocProperties(context->getDevice(0)->getRootDeviceIndex(),
false, // allocateMemory
imgInfo,
AllocationType::SHARED_IMAGE,
context->getDeviceBitfieldForAllocation(context->getDevice(0)->getRootDeviceIndex()));
auto alloc = memoryManager->createGraphicsAllocationFromSharedHandle(texInfo.globalShareHandle, allocProperties, false, false, false);
if (alloc == nullptr) {
errorCode.set(CL_INVALID_GL_OBJECT);
return nullptr;
}
memoryManager->closeSharedHandle(alloc);
auto gmm = alloc->getDefaultGmm();
imgDesc.image_type = getClMemObjectType(target);
if (target == GL_TEXTURE_BUFFER) {
imgDesc.image_width = texInfo.textureBufferWidth;
imgDesc.image_row_pitch = texInfo.textureBufferSize;
} else {
imgDesc.image_width = gmm->gmmResourceInfo->getBaseWidth();
imgDesc.image_row_pitch = gmm->gmmResourceInfo->getRenderPitch();
if (imgDesc.image_row_pitch == 0) {
size_t alignedWidth = alignUp(imgDesc.image_width, gmm->gmmResourceInfo->getHAlign());
size_t bpp = gmm->gmmResourceInfo->getBitsPerPixel() >> 3;
imgDesc.image_row_pitch = alignedWidth * bpp;
}
}
uint32_t numSamples = static_cast<uint32_t>(gmm->gmmResourceInfo->getNumSamples());
imgDesc.num_samples = getValidParam(numSamples, 0u, 1u);
imgDesc.image_height = gmm->gmmResourceInfo->getBaseHeight();
imgDesc.image_array_size = gmm->gmmResourceInfo->getArraySize();
if (target == GL_TEXTURE_3D) {
imgDesc.image_depth = gmm->gmmResourceInfo->getBaseDepth();
}
if (imgDesc.image_array_size > 1 || imgDesc.image_depth > 1) {
GMM_REQ_OFFSET_INFO gmmReqInfo = {};
gmmReqInfo.ArrayIndex = imgDesc.image_array_size > 1 ? 1 : 0;
gmmReqInfo.Slice = imgDesc.image_depth > 1 ? 1 : 0;
gmmReqInfo.ReqLock = 1;
gmm->gmmResourceInfo->getOffset(gmmReqInfo);
imgDesc.image_slice_pitch = gmmReqInfo.Lock.Offset;
} else {
imgDesc.image_slice_pitch = alloc->getUnderlyingBufferSize();
}
cubeFaceIndex = GmmTypesConverter::getCubeFaceIndex(target);
qPitch = gmm->queryQPitch(gmm->gmmResourceInfo->getResourceType());
GraphicsAllocation *mcsAlloc = nullptr;
imgDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imgInfo.imgDesc = Image::convertDescriptor(imgDesc);
imgInfo.surfaceFormat = &surfaceFormatInfo.surfaceFormat;
imgInfo.qPitch = qPitch;
auto glTexture = new GlTexture(sharingFunctions, getClGlObjectType(target), texture, texInfo, target, std::max(miplevel, 0));
if (texInfo.isAuxEnabled && alloc->getDefaultGmm()->unifiedAuxTranslationCapable()) {
const auto &hwInfo = context->getDevice(0)->getHardwareInfo();
const auto &productHelper = context->getDevice(0)->getRootDeviceEnvironment().getHelper<ProductHelper>();
alloc->getDefaultGmm()->isCompressionEnabled = productHelper.isPageTableManagerSupported(hwInfo) ? memoryManager->mapAuxGpuVA(alloc)
: true;
}
auto multiGraphicsAllocation = MultiGraphicsAllocation(context->getDevice(0)->getRootDeviceIndex());
multiGraphicsAllocation.addAllocation(alloc);
return Image::createSharedImage(context, glTexture, mcsSurfaceInfo, std::move(multiGraphicsAllocation), mcsAlloc, flags, 0, &surfaceFormatInfo, imgInfo, cubeFaceIndex,
std::max(miplevel, 0), imgInfo.imgDesc.numMipLevels);
}
void GlTexture::synchronizeObject(UpdateData &updateData) {
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
CL_GL_RESOURCE_INFO resourceInfo = {0};
resourceInfo.name = this->clGlObjectId;
if (target == GL_RENDERBUFFER_EXT) {
sharingFunctions->acquireSharedRenderBuffer(&resourceInfo);
} else {
if (sharingFunctions->acquireSharedTexture(&resourceInfo) == EGL_TRUE) {
// Set texture buffer offset acquired from OpenGL layer in graphics allocation
updateData.memObject->getGraphicsAllocation(updateData.rootDeviceIndex)->setAllocationOffset(resourceInfo.textureBufferOffset);
} else {
updateData.synchronizationStatus = SynchronizeStatus::SYNCHRONIZE_ERROR;
return;
}
}
updateData.sharedHandle = resourceInfo.globalShareHandle;
updateData.synchronizationStatus = SynchronizeStatus::ACQUIRE_SUCCESFUL;
}
cl_int GlTexture::getGlTextureInfo(cl_gl_texture_info paramName, size_t paramValueSize, void *paramValue, size_t *paramValueSizeRet) const {
GetInfoHelper info(paramValue, paramValueSize, paramValueSizeRet);
if (paramName == CL_GL_TEXTURE_TARGET) {
info.set<GLenum>(target);
} else if (paramName == CL_GL_MIPMAP_LEVEL) {
info.set<GLenum>(miplevel);
} else if (paramName == CL_GL_NUM_SAMPLES) {
info.set<GLsizei>(textureInfo.numberOfSamples > 1 ? textureInfo.numberOfSamples : 0);
} else {
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
cl_mem_object_type GlTexture::getClMemObjectType(cl_GLenum glType) {
return static_cast<cl_mem_object_type>(getClObjectType(glType, false));
}
cl_gl_object_type GlTexture::getClGlObjectType(cl_GLenum glType) {
return static_cast<cl_gl_object_type>(getClObjectType(glType, true));
}
uint32_t GlTexture::getClObjectType(cl_GLenum glType, bool returnClGlObjectType) {
// return cl_gl_object_type if returnClGlObjectType is ture, otherwise cl_mem_object_type
uint32_t retValue = 0;
switch (glType) {
case GL_TEXTURE_1D:
retValue = returnClGlObjectType ? CL_GL_OBJECT_TEXTURE1D : CL_MEM_OBJECT_IMAGE1D;
break;
case GL_TEXTURE_1D_ARRAY:
retValue = returnClGlObjectType ? CL_GL_OBJECT_TEXTURE1D_ARRAY : CL_MEM_OBJECT_IMAGE1D_ARRAY;
break;
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_2D_MULTISAMPLE:
retValue = returnClGlObjectType ? CL_GL_OBJECT_TEXTURE2D : CL_MEM_OBJECT_IMAGE2D;
break;
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
retValue = returnClGlObjectType ? CL_GL_OBJECT_TEXTURE2D_ARRAY : CL_MEM_OBJECT_IMAGE2D_ARRAY;
break;
case GL_TEXTURE_3D:
retValue = returnClGlObjectType ? CL_GL_OBJECT_TEXTURE3D : CL_MEM_OBJECT_IMAGE3D;
break;
case GL_TEXTURE_BUFFER:
retValue = returnClGlObjectType ? CL_GL_OBJECT_TEXTURE_BUFFER : CL_MEM_OBJECT_IMAGE1D_BUFFER;
break;
case GL_RENDERBUFFER_EXT:
retValue = returnClGlObjectType ? CL_GL_OBJECT_RENDERBUFFER : CL_MEM_OBJECT_IMAGE2D;
break;
default:
retValue = 0;
break;
}
return retValue;
}
cl_GLenum GlTexture::getBaseTargetType(cl_GLenum target) {
cl_GLenum returnTarget = 0;
switch (target) {
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
returnTarget = GL_TEXTURE_CUBE_MAP_ARB;
break;
default:
returnTarget = target;
break;
}
return returnTarget;
}
void GlTexture::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
auto sharingFunctions = static_cast<GLSharingFunctionsLinux *>(this->sharingFunctions);
if (target == GL_RENDERBUFFER_EXT) {
sharingFunctions->releaseSharedRenderBuffer(&textureInfo);
} else {
sharingFunctions->releaseSharedTexture(&textureInfo);
auto memoryManager = memObject->getMemoryManager();
memoryManager->closeSharedHandle(memObject->getGraphicsAllocation(rootDeviceIndex));
}
}
void GlTexture::resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData) {
const auto memObject = updateData->memObject;
auto graphicsAllocation = memObject->getGraphicsAllocation(updateData->rootDeviceIndex);
graphicsAllocation->setSharedHandle(updateData->sharedHandle);
}
} // namespace NEO

View File

@@ -0,0 +1,13 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include <EGL/egl.h>
using GLDisplay = EGLDisplay;
using GLContext = EGLContext;
using GLType = uint32_t;
using GLFunctionType = decltype(&eglGetProcAddress);

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/sharings/gl/linux/lin_enable_gl.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "opencl/source/context/context.h"
#include "opencl/source/context/context.inl"
#include "opencl/source/sharings/gl/cl_gl_api_intel.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "opencl/source/sharings/sharing_factory.h"
#include "opencl/source/sharings/sharing_factory.inl"
#include <memory>
namespace NEO {
struct GlCreateContextProperties {
GLType glHDCType = 0;
GLContext glHGLRCHandle = 0;
GLDisplay glHDCHandle = 0;
};
GlSharingContextBuilder::GlSharingContextBuilder() = default;
GlSharingContextBuilder::~GlSharingContextBuilder() = default;
bool GlSharingContextBuilder::processProperties(cl_context_properties &propertyType, cl_context_properties &propertyValue) {
if (!contextData)
contextData = std::make_unique<GlCreateContextProperties>();
switch (propertyType) {
case CL_GL_CONTEXT_KHR:
contextData->glHGLRCHandle = reinterpret_cast<GLContext>(propertyValue);
return true;
case CL_EGL_DISPLAY_KHR:
contextData->glHDCType = static_cast<GLType>(CL_EGL_DISPLAY_KHR);
contextData->glHDCHandle = reinterpret_cast<GLDisplay>(propertyValue);
return true;
}
return false;
}
bool GlSharingContextBuilder::finalizeProperties(Context &context, int32_t &errcodeRet) {
if (contextData == nullptr)
return true;
if (contextData->glHGLRCHandle) {
context.registerSharing(new GLSharingFunctionsLinux(contextData->glHDCType, contextData->glHGLRCHandle,
nullptr, contextData->glHDCHandle));
}
return true;
}
std::unique_ptr<SharingContextBuilder> GlSharingBuilderFactory::createContextBuilder() {
return std::make_unique<GlSharingContextBuilder>();
};
void GlSharingBuilderFactory::fillGlobalDispatchTable() {
icdGlobalDispatchTable.clCreateFromGLBuffer = clCreateFromGLBuffer;
icdGlobalDispatchTable.clCreateFromGLTexture = clCreateFromGLTexture;
icdGlobalDispatchTable.clCreateFromGLTexture2D = clCreateFromGLTexture2D;
icdGlobalDispatchTable.clCreateFromGLTexture3D = clCreateFromGLTexture3D;
icdGlobalDispatchTable.clCreateFromGLRenderbuffer = clCreateFromGLRenderbuffer;
icdGlobalDispatchTable.clGetGLObjectInfo = clGetGLObjectInfo;
icdGlobalDispatchTable.clGetGLTextureInfo = clGetGLTextureInfo;
icdGlobalDispatchTable.clEnqueueAcquireGLObjects = clEnqueueAcquireGLObjects;
icdGlobalDispatchTable.clEnqueueReleaseGLObjects = clEnqueueReleaseGLObjects;
icdGlobalDispatchTable.clCreateEventFromGLsyncKHR = clCreateEventFromGLsyncKHR;
icdGlobalDispatchTable.clGetGLContextInfoKHR = clGetGLContextInfoKHR;
}
std::string GlSharingBuilderFactory::getExtensions(DriverInfo *driverInfo) {
if (DebugManager.flags.AddClGlSharing.get()) {
return "cl_khr_gl_sharing "
"cl_khr_gl_depth_images "
"cl_khr_gl_event "
"cl_khr_gl_msaa_sharing ";
} else if (GLSharingFunctionsLinux::isGlSharingEnabled()) {
return "cl_khr_gl_sharing "
"cl_khr_gl_depth_images "
"cl_khr_gl_event "
"cl_khr_gl_msaa_sharing ";
}
return "";
}
void *GlSharingBuilderFactory::getExtensionFunctionAddress(const std::string &functionName) {
if (DebugManager.flags.EnableFormatQuery.get() &&
functionName == "clGetSupportedGLTextureFormatsINTEL") {
return ((void *)(clGetSupportedGLTextureFormatsINTEL));
}
return nullptr;
}
static SharingFactory::RegisterSharing<GlSharingBuilderFactory, GLSharingFunctionsLinux> glSharing;
} // namespace NEO

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "opencl/source/sharings/sharing_factory.h"
#include <memory>
namespace NEO {
class Context;
struct GlCreateContextProperties;
class GlSharingContextBuilder : public SharingContextBuilder {
public:
GlSharingContextBuilder();
~GlSharingContextBuilder() override;
bool processProperties(cl_context_properties &propertyType, cl_context_properties &propertyValue) override;
bool finalizeProperties(Context &context, int32_t &errcodeRet) override;
protected:
std::unique_ptr<GlCreateContextProperties> contextData;
};
class GlSharingBuilderFactory : public SharingBuilderFactory {
public:
std::unique_ptr<SharingContextBuilder> createContextBuilder() override;
std::string getExtensions(DriverInfo *driverInfo) override;
void fillGlobalDispatchTable() override;
void *getExtensionFunctionAddress(const std::string &functionName) override;
};
} // namespace NEO

View File

@@ -7,7 +7,7 @@
if(WIN32)
set(RUNTIME_SRCS_SHARINGS_GL_WINDOWS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_api.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_api_helper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_arb_sync_event_windows.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_buffer_windows.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_context_guard_windows.cpp

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/windows/wddm/wddm.h"
#include "opencl/source/sharings/gl/windows/gl_sharing_windows.h"
namespace NEO {
std::unique_ptr<GLSharingFunctions> GLSharingFunctions::create() {
return std::make_unique<GLSharingFunctionsWindows>();
}
bool GLSharingFunctionsWindows::isHandleCompatible(const DriverModel &driverModel, uint32_t handle) const {
return driverModel.as<const Wddm>()->verifyAdapterLuid(getAdapterLuid(reinterpret_cast<GLContext>(static_cast<uintptr_t>(handle))));
}
} // namespace NEO

View File

@@ -8,9 +8,13 @@
#include "opencl/source/sharings/gl/windows/gl_sharing_windows.h"
#include "opencl/source/context/context.inl"
#include "opencl/source/helpers/windows/gl_helper.h"
#include "opencl/source/helpers/gl_helper.h"
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
namespace Os {
extern const char *openglDllName;
}
namespace NEO {
GLSharingFunctionsWindows::GLSharingFunctionsWindows(GLType glhdcType, GLContext glhglrcHandle, GLContext glhglrcHandleBkpCtx, GLDisplay glhdcHandle)
: GLHDCType(glhdcType), GLHGLRCHandle(glhglrcHandle), GLHGLRCHandleBkpCtx(glhglrcHandleBkpCtx), GLHDCHandle(glhdcHandle) {

View File

@@ -57,6 +57,8 @@ class GLSharingFunctionsWindows : public GLSharingFunctions {
GLboolean initGLFunctions() override;
bool isOpenGlSharingSupported() override;
bool isHandleCompatible(const DriverModel &driverModel, uint32_t handle) const override;
bool isGlHdcHandleMissing(uint32_t handle) const override { return handle == 0u; }
static bool isGlSharingEnabled();
// Arb sync event

View File

@@ -267,4 +267,8 @@ void GlTexture::releaseResource(MemObj *memObject, uint32_t rootDeviceIndex) {
}
}
void GlTexture::resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData) {
GlSharing::resolveGraphicsAllocationChange(currentSharedHandle, updateData);
}
} // namespace NEO

View File

@@ -13,6 +13,7 @@
#define OSAPI WINAPI
typedef uint32_t GLType;
typedef HDC GLDisplay;
typedef HGLRC GLContext;
using GLType = uint32_t;
using GLDisplay = HDC;
using GLContext = HGLRC;
using GLFunctionType = PROC(__stdcall *)(LPCSTR arg1);

View File

@@ -7527,8 +7527,6 @@ class ClWaitForEventsTracer {
tracing_notify_state_t state = TRACING_NOTIFY_STATE_NOTHING_CALLED;
};
#ifdef _WIN32
class ClCreateFromGlBufferTracer {
public:
ClCreateFromGlBufferTracer() {}
@@ -8152,6 +8150,4 @@ class ClGetGlTextureInfoTracer {
tracing_notify_state_t state = TRACING_NOTIFY_STATE_NOTHING_CALLED;
};
#endif
} // namespace HostSideTracing

View File

@@ -4,20 +4,18 @@
# SPDX-License-Identifier: MIT
#
if(WIN32)
set(IGDRCL_SRCS_tests_api_gl
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_buffer_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_renderbuffer_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_texture2d_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_texture3d_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_texture_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_acquire_gl_objects_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_release_gl_objects_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_device_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_object_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_texture_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_intel_tracing_tests.cpp
)
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_api_gl})
endif()
set(IGDRCL_SRCS_tests_api_gl
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_buffer_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_renderbuffer_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_texture2d_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_texture3d_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_create_from_gl_texture_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_acquire_gl_objects_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_enqueue_release_gl_objects_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_device_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_object_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_get_gl_texture_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_gl_intel_tracing_tests.cpp
)
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_api_gl})

View File

@@ -44,17 +44,17 @@ struct IntelGlTracingTest : public api_tests {
}
protected:
static void callback(cl_function_id fid, cl_callback_data *callback_data, void *user_data) {
ASSERT_NE(nullptr, user_data);
IntelGlTracingTest *base = (IntelGlTracingTest *)user_data;
base->vcallback(fid, callback_data, nullptr);
static void callback(cl_function_id fid, cl_callback_data *callbackData, void *userData) {
ASSERT_NE(nullptr, userData);
IntelGlTracingTest *base = reinterpret_cast<IntelGlTracingTest *>(userData);
base->vcallback(fid, callbackData, nullptr);
}
virtual void vcallback(cl_function_id fid, cl_callback_data *callback_data, void *user_data) {
virtual void vcallback(cl_function_id fid, cl_callback_data *callbackData, void *userData) {
if (fid == functionId) {
if (callback_data->site == CL_CALLBACK_SITE_ENTER) {
if (callbackData->site == CL_CALLBACK_SITE_ENTER) {
++enterCount;
} else if (callback_data->site == CL_CALLBACK_SITE_EXIT) {
} else if (callbackData->site == CL_CALLBACK_SITE_EXIT) {
++exitCount;
}
}

View File

@@ -9,7 +9,7 @@
#include "shared/source/os_interface/windows/windows_wrapper.h"
#include "shared/test/common/test_macros/hw_test.h"
#include "opencl/source/helpers/windows/gl_helper.h"
#include "opencl/source/helpers/gl_helper.h"
#include "opencl/test/unit_test/helpers/windows/mock_function.h"
#include "gtest/gtest.h"

View File

@@ -0,0 +1,12 @@
#
# Copyright (C) 2022-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
target_sources(igdrcl_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/mock_opengl.cpp
)
endif()

View File

@@ -0,0 +1,279 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_sharing_linux.h"
#include "GL/gl.h"
#include <string.h>
extern "C" {
const char *glString = "Intel";
const char *glVersion = "4.0";
const char *arrayStringi[2]{"GL_OES_framebuffer_object", "GL_EXT_framebuffer_object"};
int glAcquireSharedBufferCalled = 0;
int glAcquireSharedRenderBufferCalled = 0;
int glAcquireSharedTextureCalled = 0;
int glDeleteContextCalled = 0;
int glGetCurrentContextCalled = 0;
int glGetCurrentDisplayCalled = 0;
int glGetSyncivCalled = 0;
int glMakeCurrentCalled = 0;
int glReleaseSharedBufferCalled = 0;
int glReleaseSharedRenderBufferCalled = 0;
int glReleaseSharedTextureCalled = 0;
int glReleaseSyncCalled = 0;
int glRetainSyncCalled = 0;
int eglCreateContextCalled = 0;
int eglDeleteContextCalled = 0;
int eglShareListsCalled = 0;
CL_GL_BUFFER_INFO bufferInfoInput = {0};
CL_GL_BUFFER_INFO bufferInfoOutput = {0};
CL_GL_RESOURCE_INFO textureInfoInput = {0};
CL_GL_RESOURCE_INFO textureInfoOutput = {0};
GLboolean glSetSharedOCLContextStateReturnedValue = 1u;
static const auto mockImage = reinterpret_cast<void *>(0xEEEE);
void glGetTexLevelParameteriv(GLenum target,
GLint level,
GLenum pname,
GLint *params) {
switch (pname) {
case GL_TEXTURE_WIDTH:
*params = 256;
break;
case GL_TEXTURE_HEIGHT:
*params = 256;
break;
case GL_TEXTURE_INTERNAL_FORMAT:
*params = GL_RGBA;
break;
}
};
const unsigned char *glGetString(unsigned int name) {
if (name == GL_VENDOR)
return reinterpret_cast<const unsigned char *>(glString);
if (name == GL_VERSION)
return reinterpret_cast<const unsigned char *>(glVersion);
return reinterpret_cast<const unsigned char *>("");
};
EGLBoolean eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets) {
glAcquireSharedTextureCalled++;
if (image == mockImage) {
*fds = 10;
textureInfoInput.name = 1;
return GL_TRUE;
} else {
return GL_FALSE;
}
};
void *eglGetCurrentContext() {
glGetCurrentContextCalled++;
return nullptr;
};
void *eglGetCurrentDisplay() {
glGetCurrentDisplayCalled++;
return nullptr;
};
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext shareContext, const EGLint *attribList) {
eglCreateContextCalled++;
return (GLContext)0x101;
};
EGLBoolean eglDestroyContext(EGLDisplay display, EGLContext context) {
eglDeleteContextCalled++;
glDeleteContextCalled++;
return (GLboolean)1;
};
void glGetIntegerv(GLenum pname, GLint *params) { return NEO::MockGLSharingFunctions::glGetIntegervTest(pname, params); };
unsigned char eglShareLists(void *arg1, void *arg2) {
eglShareListsCalled++;
return 1;
};
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext arg2) {
glMakeCurrentCalled++;
return EGL_TRUE;
};
EGLImage eglCreateImage(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attribList) {
return mockImage;
}
EGLBoolean eglDestroyImage(EGLDisplay dpy, EGLImage image) {
if (image == mockImage)
return EGL_TRUE;
else
return EGL_FALSE;
}
void resetParam(const char *name) {
if (strcmp(name, "GLAcquireSharedBufferCalled") == 0) {
glAcquireSharedBufferCalled = 0;
}
if (strcmp(name, "GLAcquireSharedRenderBufferCalled") == 0) {
glAcquireSharedRenderBufferCalled = 0;
}
if (strcmp(name, "GLAcquireSharedTextureCalled") == 0) {
glAcquireSharedTextureCalled = 0;
}
if (strcmp(name, "GLDeleteContextCalled") == 0) {
glDeleteContextCalled = 0;
}
if (strcmp(name, "GLGetCurrentContextCalled") == 0) {
glGetCurrentContextCalled = 0;
}
if (strcmp(name, "GLGetCurrentDisplayCalled") == 0) {
glGetCurrentDisplayCalled = 0;
}
if (strcmp(name, "GLGetSyncivCalled") == 0) {
glGetSyncivCalled = 0;
}
if (strcmp(name, "GLMakeCurrentCalled") == 0) {
glMakeCurrentCalled = 0;
}
if (strcmp(name, "GLReleaseSharedBufferCalled") == 0) {
glReleaseSharedBufferCalled = 0;
}
if (strcmp(name, "GLReleaseSharedRenderBufferCalled") == 0) {
glReleaseSharedRenderBufferCalled = 0;
}
if (strcmp(name, "GLReleaseSharedTextureCalled") == 0) {
glReleaseSharedTextureCalled = 0;
}
if (strcmp(name, "GLReleaseSyncCalled") == 0) {
glReleaseSyncCalled = 0;
}
if (strcmp(name, "GLRetainSyncCalled") == 0) {
glRetainSyncCalled = 0;
}
if (strcmp(name, "EGLCreateContextCalled") == 0) {
eglCreateContextCalled = 0;
}
if (strcmp(name, "EGLDeleteContextCalled") == 0) {
eglDeleteContextCalled = 0;
}
if (strcmp(name, "EGLShareListsCalled") == 0) {
eglShareListsCalled = 0;
}
if (strcmp(name, "") == 0) {
glAcquireSharedBufferCalled = 0;
glAcquireSharedRenderBufferCalled = 0;
glAcquireSharedTextureCalled = 0;
glDeleteContextCalled = 0;
glGetCurrentContextCalled = 0;
glGetCurrentDisplayCalled = 0;
glGetSyncivCalled = 0;
glMakeCurrentCalled = 0;
glReleaseSharedBufferCalled = 0;
glReleaseSharedRenderBufferCalled = 0;
glReleaseSharedTextureCalled = 0;
glReleaseSyncCalled = 0;
glRetainSyncCalled = 0;
eglCreateContextCalled = 0;
eglDeleteContextCalled = 0;
eglShareListsCalled = 0;
}
};
int getParam(const char *name) {
if (strcmp(name, "GLAcquireSharedBufferCalled") == 0) {
return glAcquireSharedBufferCalled;
}
if (strcmp(name, "GLAcquireSharedRenderBufferCalled") == 0) {
return glAcquireSharedRenderBufferCalled;
}
if (strcmp(name, "GLAcquireSharedTextureCalled") == 0) {
return glAcquireSharedTextureCalled;
}
if (strcmp(name, "GLDeleteContextCalled") == 0) {
return glDeleteContextCalled;
}
if (strcmp(name, "GLGetCurrentContextCalled") == 0) {
return glGetCurrentContextCalled;
}
if (strcmp(name, "GLGetCurrentDisplayCalled") == 0) {
return glGetCurrentDisplayCalled;
}
if (strcmp(name, "GLGetSyncivCalled") == 0) {
return glGetSyncivCalled;
}
if (strcmp(name, "GLMakeCurrentCalled") == 0) {
return glMakeCurrentCalled;
}
if (strcmp(name, "GLReleaseSharedBufferCalled") == 0) {
return glReleaseSharedBufferCalled;
}
if (strcmp(name, "GLReleaseSharedRenderBufferCalled") == 0) {
return glReleaseSharedRenderBufferCalled;
}
if (strcmp(name, "GLReleaseSharedTextureCalled") == 0) {
return glReleaseSharedTextureCalled;
}
if (strcmp(name, "GLReleaseSyncCalled") == 0) {
return glReleaseSyncCalled;
}
if (strcmp(name, "GLRetainSyncCalled") == 0) {
return glRetainSyncCalled;
}
if (strcmp(name, "EGLCreateContextCalled") == 0) {
return eglCreateContextCalled;
}
if (strcmp(name, "EGLDeleteContextCalled") == 0) {
return eglDeleteContextCalled;
}
if (strcmp(name, "EGLShareListsCalled") == 0) {
return eglShareListsCalled;
}
return 0;
};
CL_GL_BUFFER_INFO getBufferInfo() { return bufferInfoInput; };
CL_GL_RESOURCE_INFO getTextureInfo() { return textureInfoInput; };
void memParam() {
memset(&bufferInfoInput, 0, sizeof(CL_GL_BUFFER_INFO));
memset(&bufferInfoOutput, 0, sizeof(CL_GL_BUFFER_INFO));
memset(&textureInfoInput, 0, sizeof(CL_GL_RESOURCE_INFO));
memset(&textureInfoOutput, 0, sizeof(CL_GL_RESOURCE_INFO));
};
void loadBuffer(CL_GL_BUFFER_INFO buff) { bufferInfoOutput = buff; };
void loadTexture(CL_GL_RESOURCE_INFO texture) { textureInfoOutput = texture; };
void glSetString(const char *name, unsigned int var) {
if (var == GL_VENDOR) {
glString = name;
} else if (var == GL_VERSION) {
glVersion = name;
}
};
void glSetStringi(const char *name, unsigned int index) { arrayStringi[index] = name; };
void setGLSetSharedOCLContextStateReturnedValue(GLboolean value) { glSetSharedOCLContextStateReturnedValue = static_cast<GLboolean>(value); };
GLboolean getGLSetSharedOCLContextStateReturnedValue() { return glSetSharedOCLContextStateReturnedValue; };
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) {
std::string functionName(procname);
if (functionName == "eglGetCurrentContext") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglGetCurrentContext);
} else if (functionName == "eglGetCurrentDisplay") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglGetCurrentDisplay);
} else if (functionName == "eglCreateContext") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglCreateContext);
} else if (functionName == "eglDestroyContext") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglDestroyContext);
} else if (functionName == "eglMakeCurrent") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglMakeCurrent);
} else if (functionName == "eglCreateImage") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglCreateImage);
} else if (functionName == "eglDestroyImage") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglDestroyImage);
} else if (functionName == "eglExportDMABUFImageMESA") {
return reinterpret_cast<__eglMustCastToProperFunctionPointerType EGLAPIENTRY>(eglExportDMABUFImageMESA);
}
return nullptr;
}
}

View File

@@ -0,0 +1,16 @@
#
# Copyright (C) 2022-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
list(APPEND IGDRCL_SRCS_tests_mocks_linux
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/mock_gl_arb_sync_event_linux.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_gl_sharing_linux.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_gl_sharing_linux.h
)
target_sources(igdrcl_mocks PRIVATE ${IGDRCL_SRCS_tests_mocks_linux})
endif()

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
template <bool FailCreation>
struct DummyArbEvent : NEO::GlArbSyncEvent {
DummyArbEvent(NEO::Context &ctx)
: GlArbSyncEvent(ctx) {
}
using GlArbSyncEvent::baseEvent;
using GlArbSyncEvent::glSyncInfo;
using GlArbSyncEvent::osInterface;
bool useBaseSetEvent = false;
bool setBaseEvent(Event &ev) override {
return GlArbSyncEvent::setBaseEvent(ev);
}
~DummyArbEvent() override {
GlArbSyncEvent::glSyncInfo.reset();
}
static GlArbSyncEvent *create(Event &baseEv) {
if (FailCreation) {
return nullptr;
}
auto syncEv = new DummyArbEvent<FailCreation>(*baseEv.getContext());
syncEv->baseEvent = &baseEv;
return syncEv;
}
};
inline void glArbSyncObjectCleanupMockDoNothing(NEO::OSInterface &osInterface, CL_GL_SYNC_INFO *glSyncInfo) {
}
inline void glArbSyncObjectSignalMockDoNothing(NEO::OsContext &osContext, CL_GL_SYNC_INFO &glSyncInfo) {
}
template <bool Fail>
inline bool mockGlArbSyncObjectSetup(NEO::GLSharingFunctions &sharing, NEO::OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
return (Fail == false);
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_sharing_linux.h"
#include "config.h"
namespace NEO {
void GlSharingFunctionsMock::initMembers() {
GLSharingFunctionsLinux::initGLFunctions();
GlDllHelper dllParam;
dllParam.setGLSetSharedOCLContextStateReturnedValue(1u);
dllParam.resetParam("");
dllParam.loadTexture({0});
dllParam.loadBuffer({0});
}
GlSharingFunctionsMock::GlSharingFunctionsMock() {
initMembers();
}
MockGlSharing::MockGlSharing(GLType glhdcType, GLContext glhglrcHandle, GLContext glhglrcHandleBkpCtx, GLDisplay glhdcHandle) {
sharingFunctions->setHandles(glhdcType, glhglrcHandle, glhglrcHandleBkpCtx, glhdcHandle);
}
} // namespace NEO

View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "opencl/extensions/public/cl_gl_private_intel.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "opencl/test/unit_test/sharings/gl/gl_dll_helper.h"
#include "config.h"
#include <cstring>
namespace NEO {
namespace glTextureTargets {
static const unsigned int supportedTargets[] = {
GL_TEXTURE_2D,
};
} // namespace glTextureTargets
class GlSharingFunctionsMock : public GLSharingFunctionsLinux {
void initMembers();
public:
~GlSharingFunctionsMock() override = default;
using GLSharingFunctionsLinux::eglMakeCurrent;
using GLSharingFunctionsLinux::glAcquireSharedBuffer;
using GLSharingFunctionsLinux::glAcquireSharedRenderBuffer;
using GLSharingFunctionsLinux::glAcquireSharedTexture;
using GLSharingFunctionsLinux::glGetCurrentContext;
using GLSharingFunctionsLinux::glGetCurrentDisplay;
using GLSharingFunctionsLinux::glGetIntegerv;
using GLSharingFunctionsLinux::glGetString;
using GLSharingFunctionsLinux::glGetStringi;
using GLSharingFunctionsLinux::glGetSynciv;
using GLSharingFunctionsLinux::glReleaseSharedBuffer;
using GLSharingFunctionsLinux::glReleaseSharedRenderBuffer;
using GLSharingFunctionsLinux::glReleaseSharedTexture;
using GLSharingFunctionsLinux::glReleaseSync;
using GLSharingFunctionsLinux::glRetainSync;
using GLSharingFunctionsLinux::glSetSharedOCLContextState;
using GLSharingFunctionsLinux::isOpenGlExtensionSupported;
using GLSharingFunctionsLinux::pfnEglCreateContext;
using GLSharingFunctionsLinux::pfnEglDeleteContext;
using GLSharingFunctionsLinux::pfnEglShareLists;
using GLSharingFunctionsLinux::setSharedOCLContextState;
using GLSharingFunctionsLinux::glArbEventMapping;
using GLSharingFunctionsLinux::glContextHandle;
using GLSharingFunctionsLinux::glDeviceHandle;
using GLSharingFunctionsLinux::getSupportedFormats;
using GLSharingFunctionsLinux::pfnGlArbSyncObjectCleanup;
using GLSharingFunctionsLinux::pfnGlArbSyncObjectSetup;
using GLSharingFunctionsLinux::pfnGlArbSyncObjectSignal;
using GLSharingFunctionsLinux::pfnGlArbSyncObjectWaitServer;
GlSharingFunctionsMock(GLType glHDCType, GLContext glHGLRCHandle, GLContext glHGLRCHandleBkpCtx, GLDisplay glHDCHandle)
: GLSharingFunctionsLinux(glHDCType, glHGLRCHandle, glHGLRCHandleBkpCtx, glHDCHandle) {
initMembers();
updateOpenGLContext();
createBackupContext();
}
GlSharingFunctionsMock();
void setHandles(GLType glHDCType, GLContext glHGLRCHandle, GLContext glHGLRCHandleBkpCtx, GLDisplay glHDCHandle) {
this->glHDCType = glHDCType;
this->glHGLRCHandle = glHGLRCHandle;
this->glHGLRCHandleBkpCtx = glHGLRCHandleBkpCtx;
this->glHDCHandle = glHDCHandle;
}
void setGLAcquireSharedBufferMock(PFNOGLAcquireSharedBufferINTEL mock) { glAcquireSharedBuffer = mock; }
void setGLAcquireSharedTextureMock(PFNEGLEXPORTDMABUFIMAGEMESAPROC mock) { glAcquireSharedTexture = mock; }
};
class MockGlSharing {
public:
MockGlSharing() {}
MockGlSharing(GLType glHDCType, GLContext glHGLRCHandle, GLContext glHGLRCHandleBkpCtx, GLDisplay glHDCHandle);
void uploadDataToBufferInfo() {
dllParam->loadBuffer(m_bufferInfoOutput);
}
void uploadDataToBufferInfo(unsigned int sharedHandle, int bufferOffset, GMM_RESOURCE_INFO *gmmResInfo) {
m_bufferInfoOutput.globalShareHandle = sharedHandle;
m_bufferInfoOutput.bufferOffset = bufferOffset;
m_bufferInfoOutput.pGmmResInfo = gmmResInfo;
dllParam->loadBuffer(m_bufferInfoOutput);
}
void uploadDataToTextureInfo() {
dllParam->loadTexture(m_textureInfoOutput);
}
void uploadDataToTextureInfo(unsigned int sharedHandle) {
m_textureInfoOutput.globalShareHandle = sharedHandle;
dllParam->loadTexture(m_textureInfoOutput);
}
void uploadTextureBufferOffsetToTextureInfo(int texBufOffset) {
m_textureInfoOutput.textureBufferOffset = texBufOffset;
dllParam->loadTexture(m_textureInfoOutput);
}
std::unique_ptr<GlSharingFunctionsMock> sharingFunctions = std::make_unique<GlSharingFunctionsMock>();
std::unique_ptr<GlDllHelper> dllParam = std::make_unique<GlDllHelper>();
CL_GL_RESOURCE_INFO m_clGlResourceInfo = {0};
GL_CL_RESOURCE_INFO m_glClResourceInfo = {0};
CL_GL_BUFFER_INFO m_bufferInfoOutput = {0};
CL_GL_RESOURCE_INFO m_textureInfoOutput = {0};
};
class MockGLSharingFunctions : public GLSharingFunctionsLinux {
public:
using GLSharingFunctionsLinux::isOpenGlExtensionSupported;
using GLSharingFunctionsLinux::setSharedOCLContextState;
static void glGetIntegervTest(GLenum pname, GLint *data) {
if (pname == GL_NUM_EXTENSIONS)
*data = 2;
};
using GLSharingFunctionsLinux::glGetIntegerv;
using GLSharingFunctionsLinux::glGetString;
std::unique_ptr<GlDllHelper> dllParam = std::make_unique<GlDllHelper>();
MockGLSharingFunctions() {
GLSharingFunctionsLinux::initGLFunctions();
}
};
} // namespace NEO

View File

@@ -184,8 +184,6 @@ class MockGLSharingFunctions : public GLSharingFunctionsWindows {
using GLSharingFunctionsWindows::isOpenGlExtensionSupported;
using GLSharingFunctionsWindows::setSharedOCLContextState;
static bool SharingEnabled;
static void OSAPI glGetIntegervTest(GLenum pname, GLint *data) {
if (pname == GL_NUM_EXTENSIONS)
*data = 2;
@@ -195,7 +193,6 @@ class MockGLSharingFunctions : public GLSharingFunctionsWindows {
std::unique_ptr<GlDllHelper> dllParam = std::make_unique<GlDllHelper>();
MockGLSharingFunctions() {
GLSharingFunctionsWindows::initGLFunctions();
MockGLSharingFunctions::SharingEnabled = 1;
}
};
} // namespace NEO

View File

@@ -18,7 +18,7 @@
namespace Os {
extern const char *openglDllName;
}
} // namespace Os
namespace NEO {
struct GLMockReturnedValues;
@@ -44,10 +44,6 @@ struct GlDllHelper {
UNRECOVERABLE_IF(glSetString == nullptr);
glSetStringi = (*glDllLoad)["glSetStringi"];
UNRECOVERABLE_IF(glSetStringi == nullptr);
setGLSetSharedOCLContextStateReturnedValue = (*glDllLoad)["setGLSetSharedOCLContextStateReturnedValue"];
UNRECOVERABLE_IF(setGLSetSharedOCLContextStateReturnedValue == nullptr);
getGLSetSharedOCLContextStateReturnedValue = (*glDllLoad)["getGLSetSharedOCLContextStateReturnedValue"];
UNRECOVERABLE_IF(getGLSetSharedOCLContextStateReturnedValue == nullptr);
resetParam = (*glDllLoad)["resetParam"];
UNRECOVERABLE_IF(resetParam == nullptr);
getParam = (*glDllLoad)["getParam"];
@@ -63,9 +59,9 @@ struct GlDllHelper {
loadTexture = (*glDllLoad)["loadTexture"];
UNRECOVERABLE_IF(loadTexture == nullptr);
getGlMockReturnedValues = (*glDllLoad)["getGlMockReturnedValues"];
UNRECOVERABLE_IF(getGlMockReturnedValues == nullptr);
setGlMockReturnedValues = (*glDllLoad)["setGlMockReturnedValues"];
UNRECOVERABLE_IF(setGlMockReturnedValues == nullptr);
setGLSetSharedOCLContextStateReturnedValue = (*glDllLoad)["setGLSetSharedOCLContextStateReturnedValue"];
getGLSetSharedOCLContextStateReturnedValue = (*glDllLoad)["getGLSetSharedOCLContextStateReturnedValue"];
}
}
~GlDllHelper() {

View File

@@ -0,0 +1,19 @@
#
# Copyright (C) 2022-2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(UNIX)
set(IGDRCL_SRCS_tests_sharings_gl_linux
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/gl_arb_sync_event_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_create_from_texture_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_library_name.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing_enable_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_sharing_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_texture_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gl_types_tests.cpp
)
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_sharings_gl_linux})
endif()

View File

@@ -0,0 +1,372 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/execution_environment/execution_environment.h"
#include "shared/source/memory_manager/os_agnostic_memory_manager.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/test/common/mocks/mock_csr.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/test_macros/test.h"
#include "opencl/source/context/context.h"
#include "opencl/source/event/user_event.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
#include "opencl/source/sharings/sharing.h"
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_arb_sync_event_linux.h"
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_sharing_linux.h"
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_event.h"
#include "opencl/test/unit_test/mocks/mock_platform.h"
using namespace NEO;
TEST(GlArbSyncEvent, whenCreateArbSyncEventNameIsCalledMultipleTimesThenEachCallReturnsUniqueName) {
char *name1 = NEO::createArbSyncEventName();
EXPECT_NE(nullptr, name1);
EXPECT_STRNE("", name1);
char *name2 = NEO::createArbSyncEventName();
EXPECT_NE(nullptr, name2);
EXPECT_STRNE("", name2);
char *name3 = NEO::createArbSyncEventName();
EXPECT_NE(nullptr, name3);
EXPECT_STRNE("", name3);
EXPECT_STRNE(name1, name2);
EXPECT_STRNE(name1, name3);
EXPECT_STRNE(name2, name3);
NEO::destroyArbSyncEventName(name1);
NEO::destroyArbSyncEventName(name2);
NEO::destroyArbSyncEventName(name3);
}
template <bool SignalWaited>
inline void glArbSyncObjectWaitServerMock(NEO::OSInterface &osInterface, CL_GL_SYNC_INFO &glSyncInfo) {
glSyncInfo.waitCalled = SignalWaited;
}
struct MockBaseEvent : Event {
using Event::Event;
bool wasUpdated = false;
void updateExecutionStatus() override {
Event::updateExecutionStatus();
wasUpdated = true;
}
};
struct GlArbSyncEventTest : public ::testing::Test {
GlArbSyncEventTest(void) {
}
void SetUp() override {
executionEnvironment = platform()->peekExecutionEnvironment();
executionEnvironment->memoryManager = std::make_unique<OsAgnosticMemoryManager>(*executionEnvironment);
device = std::make_unique<MockClDevice>(MockDevice::create<MockDevice>(executionEnvironment, 0u));
auto mockCsr = new MockCommandStreamReceiver(*executionEnvironment, 0, device->getDeviceBitfield());
device->resetCommandStreamReceiver(mockCsr);
ctx.reset(new MockContext);
cmdQ.reset(new MockCommandQueue(ctx.get(), device.get(), nullptr, false));
sharing = new GlSharingFunctionsMock();
ctx->setSharingFunctions(sharing);
sharing->pfnGlArbSyncObjectCleanup = glArbSyncObjectCleanupMockDoNothing;
sharing->pfnGlArbSyncObjectSetup = mockGlArbSyncObjectSetup<false>;
sharing->pfnGlArbSyncObjectSignal = glArbSyncObjectSignalMockDoNothing;
sharing->pfnGlArbSyncObjectWaitServer = glArbSyncObjectWaitServerMock<false>;
osInterface = new OSInterface;
executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(osInterface);
}
void TearDown() override {
if (baseEvent) {
triggerEvent->setStatus(-1);
baseEvent->release();
triggerEvent->release();
}
}
template <typename T>
T *createArbEventMock() {
T *ret = new T(*ctx);
ret->osInterface = osInterface;
ret->baseEvent = getBaseEvent();
baseEvent->incRefInternal();
baseEvent->addChild(*ret);
return ret;
}
MockBaseEvent *getBaseEvent() {
if (baseEvent == nullptr) {
triggerEvent = new UserEvent(ctx.get());
baseEvent = new MockBaseEvent(cmdQ.get(), CL_COMMAND_RELEASE_GL_OBJECTS, CompletionStamp::notReady, CompletionStamp::notReady);
triggerEvent->addChild(*baseEvent);
}
return baseEvent;
}
void failSyncObjectCreation() {
sharing->pfnGlArbSyncObjectSetup = mockGlArbSyncObjectSetup<true>;
}
void setWaitCalledFlagOnServerWait() {
sharing->pfnGlArbSyncObjectWaitServer = glArbSyncObjectWaitServerMock<true>;
}
std::unique_ptr<MockClDevice> device;
std::unique_ptr<MockContext> ctx;
std::unique_ptr<MockCommandQueue> cmdQ;
OSInterface *osInterface = nullptr;
Event *triggerEvent = nullptr;
MockBaseEvent *baseEvent = nullptr;
GlSharingFunctionsMock *sharing = nullptr;
ExecutionEnvironment *executionEnvironment = nullptr;
};
TEST_F(GlArbSyncEventTest, whenGlArbEventIsCreatedThenBaseEventObjectIsConstructedWithProperContextAndCommandType) {
auto *syncEv = createArbEventMock<DummyArbEvent<false>>();
EXPECT_EQ(static_cast<unsigned int>(CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR), syncEv->getCommandType());
EXPECT_EQ(ctx.get(), syncEv->getContext());
EXPECT_NE(nullptr, syncEv->glSyncInfo);
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenGetSyncInfoIsCalledThenEventsSyncInfoIsReturned) {
auto *syncEv = createArbEventMock<DummyArbEvent<false>>();
EXPECT_NE(nullptr, syncEv->glSyncInfo);
EXPECT_EQ(syncEv->glSyncInfo.get(), syncEv->getSyncInfo());
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenSetBaseEventIsCalledThenProperMembersOfParentEventAreCopiedToSyncEventAndReferenceCountersAreUpdated) {
ASSERT_NE(nullptr, getBaseEvent()->getCommandQueue());
EXPECT_EQ(2, getBaseEvent()->getRefInternalCount());
EXPECT_EQ(2, getBaseEvent()->getCommandQueue()->getRefInternalCount());
EXPECT_FALSE(getBaseEvent()->peekHasChildEvents());
auto *syncEv = new DummyArbEvent<false>(*ctx);
EXPECT_EQ(nullptr, syncEv->baseEvent);
EXPECT_EQ(nullptr, syncEv->osInterface);
EXPECT_EQ(nullptr, syncEv->getCommandQueue());
syncEv->useBaseSetEvent = true;
bool ret = syncEv->setBaseEvent(*getBaseEvent());
EXPECT_TRUE(ret);
EXPECT_TRUE(getBaseEvent()->peekHasChildEvents());
EXPECT_EQ(getBaseEvent(), syncEv->baseEvent);
EXPECT_EQ(getBaseEvent()->getCommandQueue(), syncEv->getCommandQueue());
EXPECT_EQ(syncEv->getCommandQueue()->getGpgpuCommandStreamReceiver().getOSInterface(), syncEv->osInterface);
EXPECT_EQ(3, getBaseEvent()->getRefInternalCount());
EXPECT_EQ(3, getBaseEvent()->getCommandQueue()->getRefInternalCount());
EXPECT_TRUE(getBaseEvent()->peekHasChildEvents());
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenSetBaseEventIsCalledButGlArbSyncObjectCreationFailsThenOperationIsAborted) {
ASSERT_NE(nullptr, getBaseEvent()->getCommandQueue());
EXPECT_EQ(2, getBaseEvent()->getRefInternalCount());
EXPECT_EQ(2, getBaseEvent()->getCommandQueue()->getRefInternalCount());
EXPECT_FALSE(getBaseEvent()->peekHasChildEvents());
auto *syncEv = new DummyArbEvent<false>(*ctx);
EXPECT_EQ(nullptr, syncEv->baseEvent);
EXPECT_EQ(nullptr, syncEv->osInterface);
EXPECT_EQ(nullptr, syncEv->getCommandQueue());
syncEv->useBaseSetEvent = true;
failSyncObjectCreation();
bool ret = syncEv->setBaseEvent(*getBaseEvent());
EXPECT_FALSE(ret);
EXPECT_EQ(2, getBaseEvent()->getRefInternalCount());
EXPECT_EQ(2, getBaseEvent()->getCommandQueue()->getRefInternalCount());
EXPECT_FALSE(getBaseEvent()->peekHasChildEvents());
EXPECT_EQ(nullptr, syncEv->baseEvent);
EXPECT_EQ(nullptr, syncEv->osInterface);
EXPECT_EQ(nullptr, syncEv->getCommandQueue());
syncEv->osInterface = this->osInterface;
syncEv->baseEvent = getBaseEvent();
getBaseEvent()->incRefInternal();
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenGlArbSyncEventGetsUnblockedByTerminatedBaseEventThenSyncObjectDoesntGetSignalled) {
auto *syncEv = createArbEventMock<DummyArbEvent<false>>();
triggerEvent->setStatus(-1);
EXPECT_FALSE(syncEv->getSyncInfo()->waitCalled);
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenGlArbSyncEventGetsUnblockedByQueuedBaseEventThenSyncObjectDoesntGetSignalled) {
auto *syncEv = createArbEventMock<DummyArbEvent<false>>();
syncEv->unblockEventBy(*this->baseEvent, 0, CL_QUEUED);
EXPECT_FALSE(syncEv->getSyncInfo()->waitCalled);
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenGlArbSyncEventGetsUnblockedBySubmittedOrCompletedEventThenSyncObjectGetsSignalled) {
setWaitCalledFlagOnServerWait();
auto *syncEv = createArbEventMock<DummyArbEvent<false>>();
triggerEvent->setStatus(CL_COMPLETE);
EXPECT_TRUE(syncEv->getSyncInfo()->waitCalled);
syncEv->release();
}
TEST_F(GlArbSyncEventTest, whenGlArbSyncEventIsCreatedFromBaseEventWithoutValidContextThenCreationFails) {
Event *baseEvent = new Event(nullptr, CL_COMMAND_RELEASE_GL_OBJECTS, CompletionStamp::notReady, CompletionStamp::notReady);
auto *arbEvent = GlArbSyncEvent::create(*baseEvent);
EXPECT_EQ(nullptr, arbEvent);
baseEvent->release();
}
TEST_F(GlArbSyncEventTest, whenGlArbSyncEventIsCreatedAndSetEventFailsThenCreationFails) {
failSyncObjectCreation();
auto *arbEvent = GlArbSyncEvent::create(*this->getBaseEvent());
EXPECT_EQ(nullptr, arbEvent);
}
TEST_F(GlArbSyncEventTest, whenGlArbSyncEventIsCreatedThenBaseEventIsProperlySet) {
auto *arbEvent = GlArbSyncEvent::create(*this->getBaseEvent());
EXPECT_NE(nullptr, arbEvent);
EXPECT_TRUE(this->baseEvent->peekHasChildEvents());
EXPECT_EQ(arbEvent, this->baseEvent->peekChildEvents()->ref);
arbEvent->release();
}
TEST_F(GlArbSyncEventTest, whenClEnqueueMarkerWithSyncObjectINTELIsCalledThenInvalidOperationErrorCodeIsReturned) {
cl_command_queue queue = static_cast<cl_command_queue>(this->cmdQ.get());
auto ret = clEnqueueMarkerWithSyncObjectINTEL(queue, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_OPERATION, ret);
}
TEST_F(GlArbSyncEventTest, whenClGetCLObjectInfoINTELIsCalledThenInvalidOperationErrorCodeIsReturned) {
cl_mem mem = {};
auto ret = clGetCLObjectInfoINTEL(mem, nullptr);
EXPECT_EQ(CL_INVALID_OPERATION, ret);
}
TEST_F(GlArbSyncEventTest, givenNullSynInfoParameterWhenClGetCLEventInfoINTELIsCalledThenInvalidArgValueErrorCodeIsReturned) {
cl_event ev = getBaseEvent();
cl_context ctxRet = {};
auto ret = clGetCLEventInfoINTEL(ev, nullptr, &ctxRet);
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
}
TEST_F(GlArbSyncEventTest, givenNullContextParameterWhenClGetCLEventInfoINTELIsCalledThenInvalidArgValueErrorCodeIsReturned) {
cl_event ev = getBaseEvent();
CL_GL_SYNC_INFO *synInfoRet = nullptr;
auto ret = clGetCLEventInfoINTEL(ev, &synInfoRet, nullptr);
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
}
TEST_F(GlArbSyncEventTest, givenUnknownEventWhenclGetCLEventInfoINTELIsCalledThenInvalidEventErrorCodeIsReturned) {
auto deadEvent = new MockEvent<Event>(nullptr, 0, 0, 0);
deadEvent->magic = Event::deadMagic;
cl_event unknownEvent = deadEvent;
CL_GL_SYNC_INFO *synInfoRet = nullptr;
cl_context ctxRet = {};
auto ret = clGetCLEventInfoINTEL(unknownEvent, &synInfoRet, &ctxRet);
EXPECT_EQ(CL_INVALID_EVENT, ret);
deadEvent->release();
}
TEST_F(GlArbSyncEventTest, givenEventWithCommandDifferentThanReleaseGlObjectsWhenClGetCLEventInfoINTELIsCalledThenValidContextIsReturned) {
getBaseEvent();
cl_event ev = triggerEvent;
CL_GL_SYNC_INFO *synInfoRet = reinterpret_cast<CL_GL_SYNC_INFO *>(static_cast<uintptr_t>(0xFF));
cl_context ctxRet = {};
auto ret = clGetCLEventInfoINTEL(ev, &synInfoRet, &ctxRet);
EXPECT_EQ(CL_SUCCESS, ret);
EXPECT_EQ(nullptr, synInfoRet);
EXPECT_EQ(ctxRet, ctx.get());
}
TEST_F(GlArbSyncEventTest, givenDisabledSharingWhenClGetCLEventInfoINTELIsCalledThenInvalidOperationErrorCodeIsReturned) {
getBaseEvent();
cl_event ev = baseEvent;
CL_GL_SYNC_INFO *synInfoRet = reinterpret_cast<CL_GL_SYNC_INFO *>(static_cast<uintptr_t>(0xFF));
cl_context ctxRet = {};
auto sharing = ctx->getSharing<NEO::GLSharingFunctions>();
ctx->sharingFunctions[sharing->getId()] = nullptr;
auto ret = clGetCLEventInfoINTEL(ev, &synInfoRet, &ctxRet);
ctx->setSharingFunctions(new GlSharingFunctionsMock());
EXPECT_EQ(CL_INVALID_OPERATION, ret);
}
TEST_F(GlArbSyncEventTest, givenCallToClGetCLEventInfoINTELWhenGetOrCreateGlArbSyncFailsThenOutOfMemoryErrorCodeIsReturned) {
getBaseEvent();
cl_event ev = this->baseEvent;
CL_GL_SYNC_INFO *synInfoRet = reinterpret_cast<CL_GL_SYNC_INFO *>(static_cast<uintptr_t>(0xFF));
cl_context ctxRet = {};
sharing->pfnGlArbSyncObjectSetup = mockGlArbSyncObjectSetup<true>;
auto ret = clGetCLEventInfoINTEL(ev, &synInfoRet, &ctxRet);
EXPECT_EQ(CL_OUT_OF_RESOURCES, ret);
}
TEST_F(GlArbSyncEventTest, givenCallToClGetCLEventInfoINTELWhenFunctionSucceedsThenEventsGetUpdatedAndValidContextAndSyncInfoAreReturned) {
auto *arbEvent = GlArbSyncEvent::create(*this->getBaseEvent());
this->sharing->glArbEventMapping[this->baseEvent] = arbEvent;
cl_event ev = this->baseEvent;
CL_GL_SYNC_INFO *synInfoRet = reinterpret_cast<CL_GL_SYNC_INFO *>(static_cast<uintptr_t>(0xFF));
cl_context ctxRet = {};
EXPECT_FALSE(this->baseEvent->wasUpdated);
auto ret = clGetCLEventInfoINTEL(ev, &synInfoRet, &ctxRet);
EXPECT_TRUE(this->baseEvent->wasUpdated);
EXPECT_EQ(CL_SUCCESS, ret);
EXPECT_EQ(ctx.get(), ctxRet);
EXPECT_EQ(arbEvent->getSyncInfo(), synInfoRet);
arbEvent->release();
}
TEST_F(GlArbSyncEventTest, givenUnknownEventWhenClReleaseGlSharedEventINTELIsCalledThenInvalidEventErrorCodeIsReturned) {
auto deadEvent = new MockEvent<Event>(nullptr, 0, 0, 0);
deadEvent->magic = Event::deadMagic;
cl_event unknownEvent = deadEvent;
auto ret = clReleaseGlSharedEventINTEL(unknownEvent);
EXPECT_EQ(CL_INVALID_EVENT, ret);
deadEvent->release();
}
TEST_F(GlArbSyncEventTest, givenEventWithoutArbSyncWhenClReleaseGlSharedEventINTELIsCalledThenThisEventsRefcountIsDecreased) {
this->getBaseEvent();
triggerEvent->retain();
EXPECT_EQ(2, triggerEvent->getRefInternalCount());
cl_event ev = triggerEvent;
auto ret = clReleaseGlSharedEventINTEL(ev);
EXPECT_EQ(CL_SUCCESS, ret);
EXPECT_EQ(1, triggerEvent->getRefInternalCount());
}
TEST_F(GlArbSyncEventTest, givenEventWithArbSyncWhenClReleaseGlSharedEventINTELIsCalledThenThisEventsAndArbSyncsRefcountsAreDecreased) {
auto *arbEvent = GlArbSyncEvent::create(*this->getBaseEvent());
baseEvent->retain();
arbEvent->retain();
this->sharing->glArbEventMapping[baseEvent] = arbEvent;
EXPECT_EQ(4, baseEvent->getRefInternalCount());
EXPECT_EQ(3, arbEvent->getRefInternalCount());
cl_event ev = baseEvent;
auto ret = clReleaseGlSharedEventINTEL(ev);
EXPECT_EQ(CL_SUCCESS, ret);
EXPECT_EQ(3, baseEvent->getRefInternalCount());
EXPECT_EQ(2, arbEvent->getRefInternalCount());
arbEvent->release();
}

View File

@@ -0,0 +1,276 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/get_info.h"
#include "shared/source/memory_manager/os_agnostic_memory_manager.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_gmm.h"
#include "shared/test/common/mocks/mock_gmm_resource_info.h"
#include "shared/test/common/test_macros/test.h"
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/source/helpers/gmm_types_converter.h"
#include "opencl/source/mem_obj/image.h"
#include "opencl/source/sharings/gl/gl_texture.h"
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_sharing_linux.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "gtest/gtest.h"
namespace NEO {
class CreateFromGlTexture : public ::testing::Test {
public:
class TempMM : public OsAgnosticMemoryManager {
public:
TempMM() : OsAgnosticMemoryManager(*(new MockExecutionEnvironment(defaultHwInfo.get()))) {
mockExecutionEnvironment.reset(&executionEnvironment);
executionEnvironment.rootDeviceEnvironments[0]->initGmm();
}
GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness, bool isHostIpcAllocation, bool reuseSharedAllocation) override {
auto alloc = OsAgnosticMemoryManager::createGraphicsAllocationFromSharedHandle(handle, properties, requireSpecificBitness, isHostIpcAllocation, reuseSharedAllocation);
if (handle == CreateFromGlTexture::mcsHandle) {
alloc->setDefaultGmm(forceMcsGmm);
} else {
if (alloc->getDefaultGmm()) {
delete alloc->getDefaultGmm();
}
alloc->setDefaultGmm(forceGmm);
}
return alloc;
}
size_t forceAllocationSize;
Gmm *forceGmm = nullptr;
Gmm *forceMcsGmm = nullptr;
std::unique_ptr<ExecutionEnvironment> mockExecutionEnvironment;
};
void SetUp() override {
imgDesc = {};
imgInfo = {};
clContext.setSharingFunctions(glSharing->sharingFunctions.release());
clContext.memoryManager = &tempMM;
}
void TearDown() override {
gmm.release();
mcsGmm.release();
}
void updateImgInfoAndForceGmm() {
imgInfo = MockGmm::initImgInfo(imgDesc, 0, nullptr);
gmm = MockGmm::queryImgParams(clContext.getDevice(0)->getGmmHelper(), imgInfo, false);
tempMM.forceAllocationSize = imgInfo.size;
tempMM.forceGmm = gmm.get();
if (glSharing->m_textureInfoOutput.globalShareHandleMCS != 0) {
ImageDescriptor mcsImgDesc = {};
mcsImgDesc.imageHeight = 128;
mcsImgDesc.imageRowPitch = 256;
mcsImgDesc.imageWidth = 128;
mcsImgDesc.imageType = ImageType::Image2D;
auto mcsImgInfo = MockGmm::initImgInfo(mcsImgDesc, 0, nullptr);
mcsGmm = MockGmm::queryImgParams(clContext.getDevice(0)->getGmmHelper(), mcsImgInfo, false);
tempMM.forceMcsGmm = mcsGmm.get();
}
}
ImageDescriptor imgDesc;
ImageInfo imgInfo = {};
std::unique_ptr<Gmm> gmm;
std::unique_ptr<Gmm> mcsGmm;
TempMM tempMM;
MockContext clContext;
std::unique_ptr<MockGlSharing> glSharing = std::make_unique<MockGlSharing>();
cl_int retVal;
static const unsigned int mcsHandle = 0xFF;
};
class CreateFromGlTextureTestsWithParams : public CreateFromGlTexture,
public ::testing::WithParamInterface<unsigned int /*cl_GLenum*/> {
};
class CreateFromGlTextureTests : public CreateFromGlTexture {
};
INSTANTIATE_TEST_CASE_P(
CreateFromGlTextureTestsWithParams,
CreateFromGlTextureTestsWithParams,
testing::ValuesIn(glTextureTargets::supportedTargets));
TEST_P(CreateFromGlTextureTestsWithParams, givenAllTextureSpecificParamsWhenCreateIsCalledThenFillImageDescription) {
unsigned int target = GetParam();
unsigned int baseTarget = GlTexture::getBaseTargetType(target);
imgDesc.imageType = Image::convertType(GlTexture::getClMemObjectType(target));
imgDesc.imageWidth = 5;
if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
imgDesc.imageArraySize = 5;
}
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE ||
target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D ||
target == GL_RENDERBUFFER_EXT || baseTarget == GL_TEXTURE_CUBE_MAP_ARB ||
target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
imgDesc.imageHeight = 5;
}
if (target == GL_TEXTURE_3D) {
imgDesc.imageDepth = 5;
}
if (target == GL_TEXTURE_BUFFER) {
// size and width for texture buffer are queried from textureInfo - not from gmm
glSharing->m_textureInfoOutput.textureBufferWidth = 64;
glSharing->m_textureInfoOutput.textureBufferSize = 1024;
glSharing->uploadDataToTextureInfo();
}
if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
imgDesc.numSamples = 16;
glSharing->m_textureInfoOutput.numberOfSamples = 16;
glSharing->m_textureInfoOutput.globalShareHandleMCS = CreateFromGlTexture::mcsHandle;
glSharing->uploadDataToTextureInfo();
}
updateImgInfoAndForceGmm();
auto glImage = GlTexture::createSharedGlTexture(&clContext, (cl_mem_flags)0, target, 0, 0, &retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
if (target == GL_RENDERBUFFER_EXT) {
EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedRenderBufferCalled"));
} else {
EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
}
EXPECT_EQ(GmmTypesConverter::getCubeFaceIndex(target), glImage->getCubeFaceIndex());
auto glTexture = reinterpret_cast<GlTexture *>(glImage->peekSharingHandler());
EXPECT_EQ(glTexture->getTarget(), target);
EXPECT_EQ(glImage->getImageDesc().image_type, Image::convertType(imgDesc.imageType));
if (target == GL_TEXTURE_BUFFER) {
EXPECT_EQ(glImage->getImageDesc().image_width,
static_cast<size_t>(glTexture->getTextureInfo()->textureBufferWidth));
EXPECT_EQ(glImage->getImageDesc().image_row_pitch,
static_cast<size_t>(glTexture->getTextureInfo()->textureBufferSize));
} else {
EXPECT_EQ(glImage->getImageDesc().image_width, gmm->gmmResourceInfo->getBaseWidth());
size_t slicePitch = glImage->getHostPtrSlicePitch();
size_t rowPitch = glImage->getHostPtrRowPitch();
EXPECT_EQ(glImage->getImageDesc().image_row_pitch, rowPitch);
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, slicePitch);
size_t gmmRowPitch = gmm->gmmResourceInfo->getRenderPitch();
if (gmmRowPitch == 0) {
size_t alignedWidth = alignUp(glImage->getImageDesc().image_width, gmm->gmmResourceInfo->getHAlign());
size_t bpp = gmm->gmmResourceInfo->getBitsPerPixel() >> 3;
EXPECT_EQ(glImage->getImageDesc().image_row_pitch, alignedWidth * bpp);
} else {
EXPECT_EQ(glImage->getImageDesc().image_row_pitch, gmmRowPitch);
}
size_t imageInfoRowPitch = 0;
retVal = clGetImageInfo(glImage, CL_IMAGE_ROW_PITCH, sizeof(size_t), &imageInfoRowPitch, NULL);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_EQ(rowPitch, imageInfoRowPitch);
size_t imageInfoSlicePitch = 0;
slicePitch *= !(glImage->getImageDesc().image_type == CL_MEM_OBJECT_IMAGE2D || glImage->getImageDesc().image_type == CL_MEM_OBJECT_IMAGE1D || glImage->getImageDesc().image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER);
retVal = clGetImageInfo(glImage, CL_IMAGE_SLICE_PITCH, sizeof(size_t), &imageInfoSlicePitch, NULL);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_EQ(slicePitch, imageInfoSlicePitch);
}
EXPECT_EQ(glImage->getImageDesc().image_height, gmm->gmmResourceInfo->getBaseHeight());
EXPECT_EQ(glImage->getImageDesc().image_array_size, gmm->gmmResourceInfo->getArraySize());
if (target == GL_TEXTURE_3D) {
EXPECT_EQ(glImage->getImageDesc().image_depth, gmm->gmmResourceInfo->getBaseDepth());
} else {
EXPECT_EQ(glImage->getImageDesc().image_depth, 0u);
}
if (imgDesc.imageArraySize > 1 || imgDesc.imageDepth > 1) {
GMM_REQ_OFFSET_INFO gmmReqInfo = {};
gmmReqInfo.ArrayIndex = imgDesc.imageArraySize > 1 ? 1 : 0;
gmmReqInfo.Slice = imgDesc.imageDepth > 1 ? 1 : 0;
gmmReqInfo.ReqLock = 1;
gmm->gmmResourceInfo->getOffset(gmmReqInfo);
size_t expectedSlicePitch = gmmReqInfo.Lock.Offset;
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, expectedSlicePitch);
} else {
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, imgInfo.size);
}
EXPECT_EQ(glImage->getQPitch(), gmm->queryQPitch(gmm->gmmResourceInfo->getResourceType()));
uint32_t numSamples = static_cast<uint32_t>(gmm->gmmResourceInfo->getNumSamples());
auto expectedNumSamples = getValidParam(numSamples, 0u, 1u);
EXPECT_EQ(expectedNumSamples, glImage->getImageDesc().num_samples);
if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
EXPECT_NE(nullptr, glImage->getMcsAllocation());
EXPECT_EQ(getValidParam(static_cast<uint32_t>(mcsGmm->gmmResourceInfo->getRenderPitch() / 128)),
glImage->getMcsSurfaceInfo().pitch);
EXPECT_EQ(static_cast<uint32_t>(mcsGmm->gmmResourceInfo->getQPitch()),
glImage->getMcsSurfaceInfo().qPitch);
EXPECT_EQ(GmmTypesConverter::getRenderMultisamplesCount(static_cast<uint32_t>(gmm->gmmResourceInfo->getNumSamples())),
glImage->getMcsSurfaceInfo().multisampleCount);
}
delete glImage;
}
TEST_P(CreateFromGlTextureTestsWithParams, givenArrayTextureTargetAndArraySizeEqualOneWhenCreateIsCalledThenSlicePitchAndSizeAreEqual) {
unsigned int target = GetParam();
// only array targets
if (target == GL_TEXTURE_1D_ARRAY ||
target == GL_TEXTURE_2D_ARRAY) {
imgDesc.imageType = Image::convertType(GlTexture::getClMemObjectType(target));
imgDesc.imageWidth = 5;
if (target == GL_TEXTURE_2D_ARRAY) {
imgDesc.imageHeight = 5;
}
imgDesc.imageArraySize = 1;
updateImgInfoAndForceGmm();
auto glImage = GlTexture::createSharedGlTexture(&clContext, (cl_mem_flags)0, target, 0, 0, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, imgInfo.size);
delete glImage;
}
}
TEST_P(CreateFromGlTextureTestsWithParams, givenZeroRowPitchFromGmmWhenCreatingTextureThenComputeIt) {
unsigned int target = GL_TEXTURE_2D;
imgDesc.imageType = Image::convertType(GlTexture::getClMemObjectType(target));
imgDesc.imageWidth = 5;
imgDesc.imageHeight = 5;
imgDesc.imageArraySize = 1;
updateImgInfoAndForceGmm();
auto mockResInfo = static_cast<MockGmmResourceInfo *>(gmm->gmmResourceInfo.get());
mockResInfo->overrideReturnedRenderPitch(0u);
auto alignedWidth = alignUp(imgDesc.imageWidth, gmm->gmmResourceInfo->getHAlign());
auto expectedRowPitch = alignedWidth * (gmm->gmmResourceInfo->getBitsPerPixel() >> 3);
auto glImage = std::unique_ptr<Image>(GlTexture::createSharedGlTexture(&clContext, (cl_mem_flags)0, target, 0, 0, &retVal));
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(imgInfo.size, glImage->getImageDesc().image_slice_pitch);
EXPECT_EQ(expectedRowPitch, glImage->getImageDesc().image_row_pitch);
}
} // namespace NEO

View File

@@ -0,0 +1,11 @@
/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
namespace Os {
const char *eglDllName = "";
const char *openglDllName = "";
} // namespace Os

View File

@@ -0,0 +1,177 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/common/fixtures/memory_management_fixture.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "opencl/source/sharings/gl/linux/lin_enable_gl.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "gtest/gtest.h"
using namespace NEO;
class GlSharingEnablerTests : public ::testing::Test {
public:
void SetUp() override {
factory.reset(new GlSharingBuilderFactory());
ASSERT_NE(nullptr, factory.get());
}
std::unique_ptr<GlSharingBuilderFactory> factory;
};
TEST_F(GlSharingEnablerTests, givenGlFactoryWhenAskedThenExtensionsAreReturned) {
auto ext = factory->getExtensions(nullptr);
EXPECT_GT(ext.length(), 0u);
EXPECT_STRNE("", ext.c_str());
}
TEST_F(GlSharingEnablerTests, givenGlFactoryWhenAskedThenGlobalIcdIsConfigured) {
class IcdRestore {
public:
IcdRestore() { icdSnapshot = icdGlobalDispatchTable; }
~IcdRestore() { icdGlobalDispatchTable = icdSnapshot; }
decltype(icdGlobalDispatchTable) icdSnapshot;
};
// we play with global table, so first save state then restore it with use of RAII
IcdRestore icdRestore;
// clear ICD table
icdGlobalDispatchTable.clCreateFromGLBuffer = nullptr;
icdGlobalDispatchTable.clCreateFromGLTexture = nullptr;
icdGlobalDispatchTable.clCreateFromGLTexture2D = nullptr;
icdGlobalDispatchTable.clCreateFromGLTexture3D = nullptr;
icdGlobalDispatchTable.clCreateFromGLRenderbuffer = nullptr;
icdGlobalDispatchTable.clGetGLObjectInfo = nullptr;
icdGlobalDispatchTable.clGetGLTextureInfo = nullptr;
icdGlobalDispatchTable.clEnqueueAcquireGLObjects = nullptr;
icdGlobalDispatchTable.clEnqueueReleaseGLObjects = nullptr;
icdGlobalDispatchTable.clCreateEventFromGLsyncKHR = nullptr;
icdGlobalDispatchTable.clGetGLContextInfoKHR = nullptr;
factory->fillGlobalDispatchTable();
EXPECT_NE(nullptr, icdGlobalDispatchTable.clCreateFromGLBuffer);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clCreateFromGLTexture);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clCreateFromGLTexture2D);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clCreateFromGLTexture3D);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clCreateFromGLRenderbuffer);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clGetGLObjectInfo);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clGetGLTextureInfo);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clEnqueueAcquireGLObjects);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clEnqueueReleaseGLObjects);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clCreateEventFromGLsyncKHR);
EXPECT_NE(nullptr, icdGlobalDispatchTable.clGetGLContextInfoKHR);
}
TEST_F(GlSharingEnablerTests, givenGlFactoryWhenAskedThenBuilderIsCreated) {
auto builder = factory->createContextBuilder();
EXPECT_NE(nullptr, builder);
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenUnknownPropertyThenFalseIsReturned) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
cl_context_properties property = CL_CONTEXT_PLATFORM;
cl_context_properties value;
auto res = builder->processProperties(property, value);
EXPECT_FALSE(res);
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenInvalidPropertyThenFalseIsReturned) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
cl_context_properties property = CL_CGL_SHAREGROUP_KHR;
cl_context_properties value;
auto res = builder->processProperties(property, value);
EXPECT_FALSE(res);
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenValidPropertyThenTrueIsReturned) {
cl_context_properties props[] = {CL_GL_CONTEXT_KHR, CL_EGL_DISPLAY_KHR};
for (auto currProperty : props) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
cl_context_properties property = currProperty;
cl_context_properties value = 0x10000;
auto res = builder->processProperties(property, value);
EXPECT_TRUE(res);
// repeat to check if we don't allocate twice
auto prevAllocations = MemoryManagement::numAllocations.load();
res = builder->processProperties(property, value);
EXPECT_TRUE(res);
auto currAllocations = MemoryManagement::numAllocations.load();
EXPECT_EQ(prevAllocations, currAllocations);
}
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenNoPropertiesThenFinalizerReturnsTrue) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
MockContext context;
int32_t errcodeRet = CL_SUCCESS;
auto res = builder->finalizeProperties(context, errcodeRet);
EXPECT_TRUE(res);
EXPECT_EQ(CL_SUCCESS, errcodeRet);
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenInvalidPropertiesThenFinalizerReturnsTrue) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
cl_context_properties property = CL_CONTEXT_PLATFORM;
cl_context_properties value;
auto res = builder->processProperties(property, value);
EXPECT_FALSE(res);
MockContext context;
int32_t errcodeRet = CL_SUCCESS;
res = builder->finalizeProperties(context, errcodeRet);
EXPECT_TRUE(res);
EXPECT_EQ(CL_SUCCESS, errcodeRet);
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenNullHandleThenFinalizerReturnsTrueAndNoSharingRegistered) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
cl_context_properties property = CL_GL_CONTEXT_KHR;
cl_context_properties value = 0x0;
auto res = builder->processProperties(property, value);
EXPECT_TRUE(res);
MockContext context;
int32_t errcodeRet = CL_SUCCESS;
res = builder->finalizeProperties(context, errcodeRet);
EXPECT_TRUE(res);
EXPECT_EQ(CL_SUCCESS, errcodeRet);
auto sharing = context.getSharing<GLSharingFunctions>();
EXPECT_EQ(nullptr, sharing);
}
TEST_F(GlSharingEnablerTests, givenGlBuilderWhenHandleThenFinalizerReturnsTrueAndSharingIsRegistered) {
auto builder = factory->createContextBuilder();
ASSERT_NE(nullptr, builder);
cl_context_properties property = CL_GL_CONTEXT_KHR;
cl_context_properties value = 0x1000;
auto res = builder->processProperties(property, value);
EXPECT_TRUE(res);
MockContext context;
int32_t errcodeRet = CL_SUCCESS;
res = builder->finalizeProperties(context, errcodeRet);
EXPECT_TRUE(res);
EXPECT_EQ(CL_SUCCESS, errcodeRet);
auto sharing = context.getSharing<GLSharingFunctions>();
EXPECT_NE(nullptr, sharing);
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device/device.h"
#include "shared/source/gmm_helper/gmm.h"
#include "shared/source/helpers/array_count.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_gmm.h"
#include "shared/test/common/mocks/mock_gmm_resource_info.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
#include "shared/test/common/test_macros/test.h"
#include "opencl/source/command_queue/command_queue.h"
#include "opencl/source/event/user_event.h"
#include "opencl/source/mem_obj/buffer.h"
#include "opencl/source/mem_obj/image.h"
#include "opencl/source/sharings/gl/cl_gl_api_intel.h"
#include "opencl/source/sharings/gl/gl_arb_sync_event.h"
#include "opencl/source/sharings/gl/gl_buffer.h"
#include "opencl/source/sharings/gl/gl_context_guard.h"
#include "opencl/source/sharings/gl/gl_sync_event.h"
#include "opencl/source/sharings/gl/gl_texture.h"
#include "opencl/source/sharings/gl/linux/gl_sharing_linux.h"
#include "opencl/source/sharings/gl/linux/include/gl_types.h"
#include "opencl/source/sharings/sharing.h"
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_arb_sync_event_linux.h"
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_sharing_linux.h"
#include "opencl/test/unit_test/mocks/mock_async_event_handler.h"
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_event.h"
using namespace NEO;
class GlSharingTests : public ::testing::Test {
public:
void SetUp() override {
rootDeviceIndex = context.getDevice(0)->getRootDeviceIndex();
mockGlSharingFunctions = mockGlSharing->sharingFunctions.release();
context.setSharingFunctions(mockGlSharingFunctions);
mockGlSharing->m_bufferInfoOutput.globalShareHandle = bufferId;
mockGlSharing->m_bufferInfoOutput.bufferSize = 4096u;
mockGlSharing->uploadDataToBufferInfo();
}
uint32_t rootDeviceIndex;
MockContext context;
std::unique_ptr<MockGlSharing> mockGlSharing = std::make_unique<MockGlSharing>();
GlSharingFunctionsMock *mockGlSharingFunctions;
unsigned int bufferId = 1u;
};
TEST(APIclCreateEventFromGLsyncKHR, givenInvalidContexWhenCreateThenReturnError) {
cl_int retVal = CL_SUCCESS;
cl_GLsync sync = {0};
auto event = clCreateEventFromGLsyncKHR(nullptr, sync, &retVal);
EXPECT_EQ(CL_INVALID_CONTEXT, retVal);
EXPECT_EQ(nullptr, event);
}
using clGetSupportedGLTextureFormatsINTELTests = GlSharingTests;
TEST_F(clGetSupportedGLTextureFormatsINTELTests, givenContextWithoutGlSharingWhenGettingFormatsThenInvalidContextErrorIsReturned) {
MockContext context;
auto retVal = clGetSupportedGLTextureFormatsINTEL(&context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_CONTEXT, retVal);
}
TEST_F(clGetSupportedGLTextureFormatsINTELTests, givenValidInputsWhenGettingFormatsThenSuccesAndValidFormatsAreReturned) {
cl_uint numFormats = 0;
cl_GLenum glFormats[2] = {};
auto glFormatsCount = static_cast<cl_uint>(arrayCount(glFormats));
auto retVal = clGetSupportedGLTextureFormatsINTEL(&context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D,
glFormatsCount, glFormats, &numFormats);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(0u, numFormats);
for (uint32_t i = 0; i < glFormatsCount; i++) {
EXPECT_NE(GlSharing::glToCLFormats.end(), GlSharing::glToCLFormats.find(glFormats[i]));
}
}

View File

@@ -0,0 +1,370 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/product_helper.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_gmm.h"
#include "shared/test/common/mocks/mock_gmm_resource_info.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
#include "opencl/source/helpers/gmm_types_converter.h"
#include "opencl/source/mem_obj/image.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/sharings/gl/gl_texture.h"
#include "opencl/test/unit_test/mocks/gl/linux/mock_gl_sharing_linux.h"
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_platform.h"
#include "gtest/gtest.h"
using namespace NEO;
class GlSharingTextureTests : public ::testing::Test {
public:
class TempMM : public MockMemoryManager {
public:
using MockMemoryManager::MockMemoryManager;
GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness, bool isHostIpcAllocation, bool reuseSharedAllocation) override {
auto alloc = OsAgnosticMemoryManager::createGraphicsAllocationFromSharedHandle(handle, properties, requireSpecificBitness, isHostIpcAllocation, reuseSharedAllocation);
if (useForcedGmm) {
if (alloc->getDefaultGmm()) {
delete alloc->getDefaultGmm();
}
alloc->setDefaultGmm(forceGmm.get());
}
return alloc;
}
void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation) override {
if (useForcedGmm) {
forceGmm.release();
}
OsAgnosticMemoryManager::freeGraphicsMemoryImpl(gfxAllocation);
}
bool mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) override {
mapAuxGpuVACalled++;
return false;
}
uint32_t mapAuxGpuVACalled = 0u;
size_t forceAllocationSize;
std::unique_ptr<Gmm> forceGmm;
bool useForcedGmm = true;
};
void SetUp() override {
executionEnvironment = platform()->peekExecutionEnvironment();
imgDesc = {};
imgDesc.imageType = ImageType::Image2D;
imgDesc.imageWidth = 10;
imgDesc.imageHeight = 10;
auto imgInfo = MockGmm::initImgInfo(imgDesc, 0, nullptr);
tempMM = new TempMM(*executionEnvironment);
executionEnvironment->memoryManager.reset(tempMM);
device = std::make_unique<MockClDevice>(MockDevice::create<MockDevice>(executionEnvironment, 0));
clContext = std::make_unique<MockContext>(device.get());
mockGlSharingFunctions = glSharing->sharingFunctions.release();
clContext->setSharingFunctions(mockGlSharingFunctions);
tempMM->forceGmm = MockGmm::queryImgParams(device->getGmmHelper(), imgInfo, false);
tempMM->forceAllocationSize = textureSize;
textureSize = imgInfo.size;
textureId = 1;
}
void setUnifiedAuxSurf() {
tempMM->useForcedGmm = true;
auto mockGmmResInfo = static_cast<MockGmmResourceInfo *>(tempMM->forceGmm->gmmResourceInfo.get());
mockGmmResInfo->setUnifiedAuxTranslationCapable();
}
ExecutionEnvironment *executionEnvironment;
ImageDescriptor imgDesc;
TempMM *tempMM;
std::unique_ptr<MockClDevice> device;
std::unique_ptr<MockContext> clContext;
std::unique_ptr<MockGlSharing> glSharing = std::make_unique<MockGlSharing>();
GlSharingFunctionsMock *mockGlSharingFunctions;
size_t textureSize;
unsigned int textureId;
};
TEST_F(GlSharingTextureTests, givenMockGlWhen2dGlTextureIsCreatedThenMemObjectHasGlHandler) {
cl_int retVal = CL_INVALID_VALUE;
glSharing->uploadDataToTextureInfo(textureId);
auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_2D, 0, textureId, &retVal);
ASSERT_NE(nullptr, glTexture);
auto graphicsAllocation = glTexture->getGraphicsAllocation(device->getRootDeviceIndex());
EXPECT_NE(nullptr, graphicsAllocation);
EXPECT_EQ(textureSize, graphicsAllocation->getUnderlyingBufferSize());
EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(textureId, glSharing->dllParam->getTextureInfo().name); // input
auto handler = glTexture->peekSharingHandler();
ASSERT_NE(nullptr, handler);
auto glHandler = static_cast<GlSharing *>(handler);
EXPECT_EQ(glHandler->peekFunctionsHandler(), mockGlSharingFunctions);
delete glTexture;
}
class FailingMemoryManager : public MockMemoryManager {
public:
GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness, bool isHostIpcAllocation, bool reuseSharedAllocation) override {
return nullptr;
}
};
TEST_F(GlSharingTextureTests, givenMockGlWhenGlTextureIsCreatedFromWrongHandleThenErrorAndNoTextureIsReturned) {
auto tempMemoryManager = clContext->getMemoryManager();
tempMM->useForcedGmm = false;
auto memoryManager = std::unique_ptr<FailingMemoryManager>(new FailingMemoryManager());
clContext->memoryManager = memoryManager.get();
auto retVal = CL_SUCCESS;
auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_2D, 0, textureId, &retVal);
EXPECT_EQ(nullptr, glTexture);
EXPECT_EQ(CL_INVALID_GL_OBJECT, retVal);
clContext->memoryManager = tempMemoryManager;
}
EGLBoolean mockGLAcquireSharedTexture(EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets) {
CL_GL_RESOURCE_INFO textureInfo;
GlDllHelper dllParam;
textureInfo.globalShareHandle = dllParam.getTextureInfo().globalShareHandle;
textureInfo.globalShareHandleMCS = dllParam.getTextureInfo().globalShareHandleMCS;
if (textureInfo.target == GL_TEXTURE_BUFFER) {
// size and width for texture buffer are queried from textureInfo - not from gmm
textureInfo.textureBufferSize = dllParam.getTextureInfo().textureBufferSize;
textureInfo.textureBufferWidth = dllParam.getTextureInfo().textureBufferWidth;
}
textureInfo.pGmmResInfo = dllParam.getTextureInfo().pGmmResInfo;
textureInfo.glInternalFormat = 99999;
textureInfo.glHWFormat = dllParam.getTextureInfo().glHWFormat;
textureInfo.textureBufferOffset = dllParam.getTextureInfo().textureBufferOffset;
dllParam.loadTexture(textureInfo);
*fds = 0;
return GL_FALSE;
};
TEST_F(GlSharingTextureTests, givenMockGlWhenGlTextureIsCreatedFromIncorrectFormatThenErrorAndNoTextureIsReturned) {
mockGlSharingFunctions->setGLAcquireSharedTextureMock(mockGLAcquireSharedTexture);
tempMM->useForcedGmm = false;
auto retVal = CL_SUCCESS;
auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_2D, 0, textureId, &retVal);
EXPECT_EQ(nullptr, glTexture);
EXPECT_EQ(CL_INVALID_GL_OBJECT, retVal);
}
TEST_F(GlSharingTextureTests, givenGmmResourceAsInputWhenTextureIsCreatedThenItHasGmmSet) {
cl_int retVal = CL_INVALID_VALUE;
glSharing->m_textureInfoOutput.globalShareHandle = textureId;
glSharing->m_textureInfoOutput.pGmmResInfo = this->tempMM->forceGmm->gmmResourceInfo->peekGmmResourceInfo();
this->tempMM->useForcedGmm = false;
glSharing->m_textureInfoOutput.pGmmResInfo = this->tempMM->forceGmm->gmmResourceInfo->peekGmmResourceInfo();
glSharing->uploadDataToTextureInfo();
auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_2D, 0, textureId, &retVal);
ASSERT_NE(nullptr, glTexture);
auto graphicsAllocation = glTexture->getGraphicsAllocation(device->getRootDeviceIndex());
EXPECT_NE(nullptr, graphicsAllocation);
ASSERT_NE(nullptr, graphicsAllocation->getDefaultGmm());
ASSERT_NE(nullptr, graphicsAllocation->getDefaultGmm()->gmmResourceInfo->peekHandle());
delete glTexture;
}
TEST_F(GlSharingTextureTests, givenContextWithoutSharingAnd2dTextureWhenClCreateFromGlTextureIsCalledThenErrorIsReturned) {
tempMM->useForcedGmm = false;
clContext->resetSharingFunctions(CLGL_SHARING);
cl_int retVal = CL_INVALID_GL_OBJECT;
auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
ASSERT_EQ(nullptr, glImage);
}
TEST_F(GlSharingTextureTests, givenGlCl2dTextureWhenAskedForCLGLGetInfoThenIdAndTypeIsReturned) {
auto retVal = CL_SUCCESS;
auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, glImage);
cl_gl_object_type objectType = 0u;
cl_GLuint objectId = 0u;
retVal = clGetGLObjectInfo(glImage, &objectType, &objectId);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(objectType, (cl_gl_object_type)CL_GL_OBJECT_TEXTURE2D);
EXPECT_EQ(objectId, textureId);
retVal = clReleaseMemObject(glImage);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_F(GlSharingTextureTests, givenContextWithoutSharingAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture1dThenErrorIsReturned) {
tempMM->useForcedGmm = false;
clContext->resetSharingFunctions(CLGL_SHARING);
auto retVal = CL_SUCCESS;
auto glImage = clCreateFromGLTexture2D(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
ASSERT_EQ(nullptr, glImage);
}
TEST_F(GlSharingTextureTests, givenHwCommandQueueAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture2dThenImageObjectIsReturned) {
auto retVal = CL_SUCCESS;
auto glImage = clCreateFromGLTexture2D(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, glImage);
cl_gl_object_type objectType = 0u;
cl_GLuint objectId = 0u;
retVal = clGetGLObjectInfo(glImage, &objectType, &objectId);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(objectType, (cl_gl_object_type)CL_GL_OBJECT_TEXTURE2D);
EXPECT_EQ(objectId, textureId);
retVal = clReleaseMemObject(glImage);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_F(GlSharingTextureTests, givenHwCommandQueueAndGlTextureWhenAcquireIsCalledThenAcquireCountIsIncremented) {
glSharing->uploadDataToTextureInfo(textureId);
auto retVal = CL_SUCCESS;
auto commandQueue = clCreateCommandQueue(clContext.get(), clContext->getDevice(0), 0, &retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
retVal = clEnqueueReleaseGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(3, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
retVal = clReleaseCommandQueue(commandQueue);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clReleaseMemObject(glImage);
EXPECT_EQ(CL_SUCCESS, retVal);
}
class GetGlTextureInfoTests : public GlSharingTextureTests,
public ::testing::WithParamInterface<unsigned int /*cl_GLenum*/> {
};
INSTANTIATE_TEST_CASE_P(
GetGlTextureInfoTests,
GetGlTextureInfoTests,
testing::ValuesIn(glTextureTargets::supportedTargets));
TEST_P(GetGlTextureInfoTests, givenGlTextureWhenAskedForCLGetGLTextureInfoThenReturnValidInfo) {
auto retVal = CL_SUCCESS;
GLenum expectedTarget = GetParam();
GLint mipLevel = 1u;
auto glImage = clCreateFromGLTexture(clContext.get(), 0, expectedTarget, mipLevel, textureId, &retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, glImage);
auto pMemObj = castToObject<MemObj>(glImage);
auto glTextureObj = (GlTexture *)pMemObj->peekSharingHandler();
GLenum textureTarget = 0u;
size_t retSize = 0;
retVal = clGetGLTextureInfo(glImage, CL_GL_TEXTURE_TARGET, sizeof(GLenum), &textureTarget, &retSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(expectedTarget, textureTarget);
EXPECT_EQ(sizeof(GLenum), retSize);
retVal = clGetGLTextureInfo(glImage, CL_GL_MIPMAP_LEVEL, sizeof(GLenum), &mipLevel, &retSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(glTextureObj->getMiplevel(), mipLevel);
EXPECT_EQ(sizeof(GLint), retSize);
retVal = clGetGLTextureInfo(glImage, CL_INVALID_VALUE, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
auto image = castToObject<Image>(glImage);
EXPECT_EQ(mipLevel, image->peekBaseMipLevel());
retVal = clReleaseMemObject(glImage);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_P(GetGlTextureInfoTests, givenApiTargetTypeWhenAskedForBaseTypeThenConvertOnlyCubeMaps) {
tempMM->useForcedGmm = false;
auto apiTarget = GetParam();
unsigned int expectedBaseType;
switch (apiTarget) {
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
expectedBaseType = GL_TEXTURE_CUBE_MAP_ARB;
break;
default:
expectedBaseType = apiTarget;
break;
}
EXPECT_EQ(GlTexture::getBaseTargetType(apiTarget), expectedBaseType);
}
TEST_P(GetGlTextureInfoTests, givenApiTargetTypeWhenAskedForGmmCubeFaceIndexThenReturnValidOnlyForCubeType) {
tempMM->useForcedGmm = false;
auto apiTarget = GetParam();
auto gmmCubeFaceIndex = static_cast<unsigned int>(GmmTypesConverter::getCubeFaceIndex(apiTarget));
switch (apiTarget) {
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_NEG_X));
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_POS_X));
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_NEG_Y));
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_POS_Y));
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_NEG_Z));
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_POS_Z));
break;
default:
EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_NO_CUBE_MAP));
break;
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/sharings/gl/gl_texture.h"
#include "config.h"
#include "gtest/gtest.h"
namespace NEO {
namespace glTypes {
static const std::tuple<int, uint32_t /*cl_channel_type*/, uint32_t /*cl_channel_order*/> allImageFormats[] = {
// input, output, output
std::make_tuple(GL_RGBA8, CL_UNORM_INT8, CL_RGBA),
std::make_tuple(GL_RGBA8I, CL_SIGNED_INT8, CL_RGBA),
std::make_tuple(GL_RGBA16, CL_UNORM_INT16, CL_RGBA),
std::make_tuple(GL_RGBA16I, CL_SIGNED_INT16, CL_RGBA),
std::make_tuple(GL_RGBA32I, CL_SIGNED_INT32, CL_RGBA),
std::make_tuple(GL_RGBA8UI, CL_UNSIGNED_INT8, CL_RGBA),
std::make_tuple(GL_RGBA16UI, CL_UNSIGNED_INT16, CL_RGBA),
std::make_tuple(GL_RGBA32UI, CL_UNSIGNED_INT32, CL_RGBA),
std::make_tuple(GL_RGBA16F, CL_HALF_FLOAT, CL_RGBA),
std::make_tuple(GL_RGBA32F, CL_FLOAT, CL_RGBA),
std::make_tuple(GL_RGBA, CL_UNORM_INT8, CL_RGBA),
std::make_tuple(GL_RGBA8_SNORM, CL_SNORM_INT8, CL_RGBA),
std::make_tuple(GL_RGBA16_SNORM, CL_SNORM_INT16, CL_RGBA),
std::make_tuple(GL_BGRA, CL_UNORM_INT8, CL_BGRA),
std::make_tuple(GL_R8, CL_UNORM_INT8, CL_R),
std::make_tuple(GL_R8_SNORM, CL_SNORM_INT8, CL_R),
std::make_tuple(GL_R16, CL_UNORM_INT16, CL_R),
std::make_tuple(GL_R16_SNORM, CL_SNORM_INT16, CL_R),
std::make_tuple(GL_R16F, CL_HALF_FLOAT, CL_R),
std::make_tuple(GL_R32F, CL_FLOAT, CL_R),
std::make_tuple(GL_R8I, CL_SIGNED_INT8, CL_R),
std::make_tuple(GL_R16I, CL_SIGNED_INT16, CL_R),
std::make_tuple(GL_R32I, CL_SIGNED_INT32, CL_R),
std::make_tuple(GL_R8UI, CL_UNSIGNED_INT8, CL_R),
std::make_tuple(GL_R16UI, CL_UNSIGNED_INT16, CL_R),
std::make_tuple(GL_R32UI, CL_UNSIGNED_INT32, CL_R),
std::make_tuple(GL_DEPTH_COMPONENT32F, CL_FLOAT, CL_DEPTH),
std::make_tuple(GL_DEPTH_COMPONENT16, CL_UNORM_INT16, CL_DEPTH),
std::make_tuple(GL_DEPTH24_STENCIL8, CL_UNORM_INT24, CL_DEPTH_STENCIL),
std::make_tuple(GL_DEPTH32F_STENCIL8, CL_FLOAT, CL_DEPTH_STENCIL),
std::make_tuple(GL_SRGB8_ALPHA8, CL_UNORM_INT8, CL_sRGBA),
std::make_tuple(GL_RG8, CL_UNORM_INT8, CL_RG),
std::make_tuple(GL_RG8_SNORM, CL_SNORM_INT8, CL_RG),
std::make_tuple(GL_RG16, CL_UNORM_INT16, CL_RG),
std::make_tuple(GL_RG16_SNORM, CL_SNORM_INT16, CL_RG),
std::make_tuple(GL_RG16F, CL_HALF_FLOAT, CL_RG),
std::make_tuple(GL_RG32F, CL_FLOAT, CL_RG),
std::make_tuple(GL_RG8I, CL_SIGNED_INT8, CL_RG),
std::make_tuple(GL_RG16I, CL_SIGNED_INT16, CL_RG),
std::make_tuple(GL_RG32I, CL_SIGNED_INT32, CL_RG),
std::make_tuple(GL_RG8UI, CL_UNSIGNED_INT8, CL_RG),
std::make_tuple(GL_RG16UI, CL_UNSIGNED_INT16, CL_RG),
std::make_tuple(GL_RG32UI, CL_UNSIGNED_INT32, CL_RG),
std::make_tuple(GL_RGB10, CL_UNORM_INT16, CL_RGBA),
std::make_tuple(CL_INVALID_VALUE, 0, 0)};
static const std::tuple<unsigned int, uint32_t /*cl_gl_object_type*/, uint32_t /*cl_mem_object_type*/> allObjTypes[] = {
// input, output, output
std::make_tuple(GL_TEXTURE_1D, CL_GL_OBJECT_TEXTURE1D, CL_MEM_OBJECT_IMAGE1D),
std::make_tuple(GL_TEXTURE_1D_ARRAY, CL_GL_OBJECT_TEXTURE1D_ARRAY, CL_MEM_OBJECT_IMAGE1D_ARRAY),
std::make_tuple(GL_TEXTURE_2D, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_RECTANGLE, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_CUBE_MAP_POSITIVE_X, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_2D_MULTISAMPLE, CL_GL_OBJECT_TEXTURE2D, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(GL_TEXTURE_2D_ARRAY, CL_GL_OBJECT_TEXTURE2D_ARRAY, CL_MEM_OBJECT_IMAGE2D_ARRAY),
std::make_tuple(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, CL_GL_OBJECT_TEXTURE2D_ARRAY, CL_MEM_OBJECT_IMAGE2D_ARRAY),
std::make_tuple(GL_TEXTURE_3D, CL_GL_OBJECT_TEXTURE3D, CL_MEM_OBJECT_IMAGE3D),
std::make_tuple(GL_TEXTURE_BUFFER, CL_GL_OBJECT_TEXTURE_BUFFER, CL_MEM_OBJECT_IMAGE1D_BUFFER),
std::make_tuple(GL_RENDERBUFFER_EXT, CL_GL_OBJECT_RENDERBUFFER, CL_MEM_OBJECT_IMAGE2D),
std::make_tuple(CL_INVALID_VALUE, 0, 0)};
} // namespace glTypes
struct GlClImageFormatTests
: public ::testing::WithParamInterface<std::tuple<int, uint32_t /*cl_channel_type*/, uint32_t /*cl_channel_order*/>>,
public ::testing::Test {};
INSTANTIATE_TEST_CASE_P(GlClImageFormatTests, GlClImageFormatTests, testing::ValuesIn(glTypes::allImageFormats));
TEST_P(GlClImageFormatTests, WhenSettingClImageFormatThenValidFormatIsSet) {
cl_image_format imgFormat = {};
auto glFormat = std::get<0>(GetParam());
auto expectedClChannelType = static_cast<cl_channel_type>(std::get<1>(GetParam()));
auto expectedClChannelOrder = static_cast<cl_channel_order>(std::get<2>(GetParam()));
GlTexture::setClImageFormat(glFormat, imgFormat);
EXPECT_EQ(imgFormat.image_channel_data_type, expectedClChannelType);
EXPECT_EQ(imgFormat.image_channel_order, expectedClChannelOrder);
}
struct GlClObjTypesTests
: public ::testing::WithParamInterface<std::tuple<unsigned int, uint32_t /*cl_gl_object_type*/, uint32_t /*cl_mem_object_type*/>>,
public ::testing::Test {};
INSTANTIATE_TEST_CASE_P(GlClObjTypesTests, GlClObjTypesTests, testing::ValuesIn(glTypes::allObjTypes));
TEST_P(GlClObjTypesTests, WhenConvertingTypeThenTypeIsSetCorrectly) {
auto glType = static_cast<cl_GLenum>(std::get<0>(GetParam()));
auto expectedClGlObjType = static_cast<cl_gl_object_type>(std::get<1>(GetParam()));
auto expectedClMemObjType = static_cast<cl_mem_object_type>(std::get<2>(GetParam()));
auto clGlObjType = GlTexture::getClGlObjectType(glType);
auto clMemObjType = GlTexture::getClMemObjectType(glType);
EXPECT_EQ(expectedClGlObjType, clGlObjType);
EXPECT_EQ(clMemObjType, expectedClMemObjType);
}
} // namespace NEO

View File

@@ -41,8 +41,6 @@
using namespace NEO;
bool MockGLSharingFunctions::SharingEnabled = false;
class glSharingTests : public ::testing::Test {
public:
void SetUp() override {

342
third_party/opengl_headers/EGL/egl.h vendored Normal file
View File

@@ -0,0 +1,342 @@
#ifndef __egl_h_
#define __egl_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright 2013-2020 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
**
** This header is generated from the Khronos EGL XML API Registry.
** The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.khronos.org/registry/egl
**
** Khronos $Git commit SHA1: 8c62b915dd $ on $Git commit date: 2021-11-05 23:32:01 -0400 $
*/
#include <EGL/eglplatform.h>
#ifndef EGL_EGL_PROTOTYPES
#define EGL_EGL_PROTOTYPES 1
#endif
/* Generated on date 20211116 */
/* Generated C header for:
* API: egl
* Versions considered: .*
* Versions emitted: .*
* Default extensions included: None
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef EGL_VERSION_1_0
#define EGL_VERSION_1_0 1
typedef unsigned int EGLBoolean;
typedef void *EGLDisplay;
#include <KHR/khrplatform.h>
#include <EGL/eglplatform.h>
typedef void *EGLConfig;
typedef void *EGLSurface;
typedef void *EGLContext;
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300A
#define EGL_BAD_NATIVE_WINDOW 0x300B
#define EGL_BAD_PARAMETER 0x300C
#define EGL_BAD_SURFACE 0x300D
#define EGL_BLUE_SIZE 0x3022
#define EGL_BUFFER_SIZE 0x3020
#define EGL_CONFIG_CAVEAT 0x3027
#define EGL_CONFIG_ID 0x3028
#define EGL_CORE_NATIVE_ENGINE 0x305B
#define EGL_DEPTH_SIZE 0x3025
#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
#define EGL_DRAW 0x3059
#define EGL_EXTENSIONS 0x3055
#define EGL_FALSE 0
#define EGL_GREEN_SIZE 0x3023
#define EGL_HEIGHT 0x3056
#define EGL_LARGEST_PBUFFER 0x3058
#define EGL_LEVEL 0x3029
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
#define EGL_MAX_PBUFFER_PIXELS 0x302B
#define EGL_MAX_PBUFFER_WIDTH 0x302C
#define EGL_NATIVE_RENDERABLE 0x302D
#define EGL_NATIVE_VISUAL_ID 0x302E
#define EGL_NATIVE_VISUAL_TYPE 0x302F
#define EGL_NONE 0x3038
#define EGL_NON_CONFORMANT_CONFIG 0x3051
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
#define EGL_PBUFFER_BIT 0x0001
#define EGL_PIXMAP_BIT 0x0002
#define EGL_READ 0x305A
#define EGL_RED_SIZE 0x3024
#define EGL_SAMPLES 0x3031
#define EGL_SAMPLE_BUFFERS 0x3032
#define EGL_SLOW_CONFIG 0x3050
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SUCCESS 0x3000
#define EGL_SURFACE_TYPE 0x3033
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
#define EGL_TRANSPARENT_RED_VALUE 0x3037
#define EGL_TRANSPARENT_RGB 0x3052
#define EGL_TRANSPARENT_TYPE 0x3034
#define EGL_TRUE 1
#define EGL_VENDOR 0x3053
#define EGL_VERSION 0x3054
#define EGL_WIDTH 0x3057
#define EGL_WINDOW_BIT 0x0004
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void);
typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw);
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id);
typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void);
typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
EGLAPI EGLint EGLAPIENTRY eglGetError (void);
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
#endif
#endif /* EGL_VERSION_1_0 */
#ifndef EGL_VERSION_1_1
#define EGL_VERSION_1_1 1
#define EGL_BACK_BUFFER 0x3084
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
#define EGL_CONTEXT_LOST 0x300E
#define EGL_MIN_SWAP_INTERVAL 0x303B
#define EGL_MAX_SWAP_INTERVAL 0x303C
#define EGL_MIPMAP_TEXTURE 0x3082
#define EGL_MIPMAP_LEVEL 0x3083
#define EGL_NO_TEXTURE 0x305C
#define EGL_TEXTURE_2D 0x305F
#define EGL_TEXTURE_FORMAT 0x3080
#define EGL_TEXTURE_RGB 0x305D
#define EGL_TEXTURE_RGBA 0x305E
#define EGL_TEXTURE_TARGET 0x3081
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
#endif
#endif /* EGL_VERSION_1_1 */
#ifndef EGL_VERSION_1_2
#define EGL_VERSION_1_2 1
typedef unsigned int EGLenum;
typedef void *EGLClientBuffer;
#define EGL_ALPHA_FORMAT 0x3088
#define EGL_ALPHA_FORMAT_NONPRE 0x308B
#define EGL_ALPHA_FORMAT_PRE 0x308C
#define EGL_ALPHA_MASK_SIZE 0x303E
#define EGL_BUFFER_PRESERVED 0x3094
#define EGL_BUFFER_DESTROYED 0x3095
#define EGL_CLIENT_APIS 0x308D
#define EGL_COLORSPACE 0x3087
#define EGL_COLORSPACE_sRGB 0x3089
#define EGL_COLORSPACE_LINEAR 0x308A
#define EGL_COLOR_BUFFER_TYPE 0x303F
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
#define EGL_DISPLAY_SCALING 10000
#define EGL_HORIZONTAL_RESOLUTION 0x3090
#define EGL_LUMINANCE_BUFFER 0x308F
#define EGL_LUMINANCE_SIZE 0x303D
#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_OPENVG_BIT 0x0002
#define EGL_OPENGL_ES_API 0x30A0
#define EGL_OPENVG_API 0x30A1
#define EGL_OPENVG_IMAGE 0x3096
#define EGL_PIXEL_ASPECT_RATIO 0x3092
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_RENDER_BUFFER 0x3086
#define EGL_RGB_BUFFER 0x308E
#define EGL_SINGLE_BUFFER 0x3085
#define EGL_SWAP_BEHAVIOR 0x3093
#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
#define EGL_VERTICAL_RESOLUTION 0x3091
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api);
typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
#endif
#endif /* EGL_VERSION_1_2 */
#ifndef EGL_VERSION_1_3
#define EGL_VERSION_1_3 1
#define EGL_CONFORMANT 0x3042
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_MATCH_NATIVE_PIXMAP 0x3041
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_VG_ALPHA_FORMAT 0x3088
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
#define EGL_VG_COLORSPACE 0x3087
#define EGL_VG_COLORSPACE_sRGB 0x3089
#define EGL_VG_COLORSPACE_LINEAR 0x308A
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
#endif /* EGL_VERSION_1_3 */
#ifndef EGL_VERSION_1_4
#define EGL_VERSION_1_4 1
#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
#define EGL_MULTISAMPLE_RESOLVE 0x3099
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
#define EGL_OPENGL_API 0x30A2
#define EGL_OPENGL_BIT 0x0008
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
#endif
#endif /* EGL_VERSION_1_4 */
#ifndef EGL_VERSION_1_5
#define EGL_VERSION_1_5 1
typedef void *EGLSync;
typedef intptr_t EGLAttrib;
typedef khronos_utime_nanoseconds_t EGLTime;
typedef void *EGLImage;
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
#define EGL_NO_RESET_NOTIFICATION 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
#define EGL_OPENGL_ES3_BIT 0x00000040
#define EGL_CL_EVENT_HANDLE 0x309C
#define EGL_SYNC_CL_EVENT 0x30FE
#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
#define EGL_SYNC_TYPE 0x30F7
#define EGL_SYNC_STATUS 0x30F1
#define EGL_SYNC_CONDITION 0x30F8
#define EGL_SIGNALED 0x30F2
#define EGL_UNSIGNALED 0x30F3
#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
#define EGL_TIMEOUT_EXPIRED 0x30F5
#define EGL_CONDITION_SATISFIED 0x30F6
#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
#define EGL_SYNC_FENCE 0x30F9
#define EGL_GL_COLORSPACE 0x309D
#define EGL_GL_COLORSPACE_SRGB 0x3089
#define EGL_GL_COLORSPACE_LINEAR 0x308A
#define EGL_GL_RENDERBUFFER 0x30B9
#define EGL_GL_TEXTURE_2D 0x30B1
#define EGL_GL_TEXTURE_LEVEL 0x30BC
#define EGL_GL_TEXTURE_3D 0x30B2
#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
#define EGL_IMAGE_PRESERVED 0x30D2
#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image);
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
#endif
#endif /* EGL_VERSION_1_5 */
#ifdef __cplusplus
}
#endif
#endif

1479
third_party/opengl_headers/EGL/eglext.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,169 @@
#ifndef __eglplatform_h_
#define __eglplatform_h_
/*
** Copyright 2007-2020 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
*/
/* Platform-specific types and definitions for egl.h
*
* Adopters may modify khrplatform.h and this file to suit their platform.
* You are encouraged to submit all modifications to the Khronos group so that
* they can be included in future versions of this file. Please submit changes
* by filing an issue or pull request on the public Khronos EGL Registry, at
* https://www.github.com/KhronosGroup/EGL-Registry/
*/
#include <KHR/khrplatform.h>
/* Macros used in EGL function prototype declarations.
*
* EGL functions should be prototyped as:
*
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
*
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
*/
#ifndef EGLAPI
#define EGLAPI KHRONOS_APICALL
#endif
#ifndef EGLAPIENTRY
#define EGLAPIENTRY KHRONOS_APIENTRY
#endif
#define EGLAPIENTRYP EGLAPIENTRY*
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
* are aliases of window-system-dependent types, such as X Display * or
* Windows Device Context. They must be defined in platform-specific
* code below. The EGL-prefixed versions of Native*Type are the same
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
*
* Khronos STRONGLY RECOMMENDS that you use the default definitions
* provided below, since these changes affect both binary and source
* portability of applications using EGL running on different EGL
* implementations.
*/
#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES)
typedef void *EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
#elif defined(__EMSCRIPTEN__)
typedef int EGLNativeDisplayType;
typedef int EGLNativePixmapType;
typedef int EGLNativeWindowType;
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
typedef int EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(WL_EGL_PLATFORM)
typedef struct wl_display *EGLNativeDisplayType;
typedef struct wl_egl_pixmap *EGLNativePixmapType;
typedef struct wl_egl_window *EGLNativeWindowType;
#elif defined(__GBM__)
typedef struct gbm_device *EGLNativeDisplayType;
typedef struct gbm_bo *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(__ANDROID__) || defined(ANDROID)
struct ANativeWindow;
struct egl_native_pixmap_t;
typedef void* EGLNativeDisplayType;
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
typedef struct ANativeWindow* EGLNativeWindowType;
#elif defined(USE_OZONE)
typedef intptr_t EGLNativeDisplayType;
typedef intptr_t EGLNativePixmapType;
typedef intptr_t EGLNativeWindowType;
#elif defined(USE_X11)
/* X11 (tentative) */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
typedef Display *EGLNativeDisplayType;
typedef Pixmap EGLNativePixmapType;
typedef Window EGLNativeWindowType;
#elif defined(__unix__)
typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;
#elif defined(__APPLE__)
typedef int EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(__HAIKU__)
#include <kernel/image.h>
typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;
#elif defined(__Fuchsia__)
typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;
#else
#error "Platform not recognized"
#endif
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
typedef EGLNativeDisplayType NativeDisplayType;
typedef EGLNativePixmapType NativePixmapType;
typedef EGLNativeWindowType NativeWindowType;
/* Define EGLint. This must be a signed integral type large enough to contain
* all legal attribute names and values passed into and out of EGL, whether
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
* handle, or other. While in general a 32-bit integer will suffice, if
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
* integer type.
*/
typedef khronos_int32_t EGLint;
/* C++ / C typecast macros for special EGL handle values */
#if defined(__cplusplus)
#define EGL_CAST(type, value) (static_cast<type>(value))
#else
#define EGL_CAST(type, value) ((type) (value))
#endif
#endif /* __eglplatform_h */