Files
compute-runtime/unit_tests/sharings/gl/gl_arb_sync_event_tests.cpp
Katarzyna Cencelewska 962b6ce883 Add support for cl-gl sharing
Change-Id: I08d7608722746baa3be61846e05eecb5419cc136
2018-09-18 11:18:46 +02:00

384 lines
15 KiB
C++

/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/context/context.h"
#include "runtime/event/event.h"
#include "runtime/execution_environment/execution_environment.h"
#include "runtime/os_interface/os_interface.h"
#include "runtime/sharings/sharing.h"
#include "runtime/sharings/gl/gl_arb_sync_event.h"
#include "unit_tests/mocks/gl/mock_gl_arb_sync_event.h"
#include "unit_tests/mocks/gl/mock_gl_sharing.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_command_queue.h"
#include "unit_tests/mocks/mock_csr.h"
#include "unit_tests/mocks/mock_device.h"
#include "unit_tests/mocks/mock_event.h"
#include "test.h"
using namespace OCLRT;
TEST(GlArbSyncEvent, whenCreateArbSyncEventNameIsCalledMultipleTimesThenEachCallReturnsUniqueName) {
char *name1 = OCLRT::createArbSyncEventName();
EXPECT_NE(nullptr, name1);
EXPECT_STRNE("", name1);
char *name2 = OCLRT::createArbSyncEventName();
EXPECT_NE(nullptr, name2);
EXPECT_STRNE("", name2);
char *name3 = OCLRT::createArbSyncEventName();
EXPECT_NE(nullptr, name3);
EXPECT_STRNE("", name3);
EXPECT_STRNE(name1, name2);
EXPECT_STRNE(name1, name3);
EXPECT_STRNE(name2, name3);
OCLRT::destroyArbSyncEventName(name1);
OCLRT::destroyArbSyncEventName(name2);
OCLRT::destroyArbSyncEventName(name3);
}
template <bool SignalWaited>
inline void glArbSyncObjectWaitServerMock(OCLRT::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 = new ExecutionEnvironment;
auto mockCsr = new MockCommandStreamReceiver();
executionEnvironment->commandStreamReceivers.push_back(std::unique_ptr<MockCommandStreamReceiver>(mockCsr));
executionEnvironment->memoryManager = std::make_unique<OsAgnosticMemoryManager>(false, false);
device.reset(MockDevice::create<MockDevice>(nullptr, executionEnvironment, 0u));
ctx.reset(new MockContext);
cmdQ.reset(new MockCommandQueue(ctx.get(), device.get(), nullptr));
sharing = new GlSharingFunctionsMock();
ctx->setSharingFunctions(sharing);
sharing->pfnGlArbSyncObjectCleanup = glArbSyncObjectCleanupMockDoNothing;
sharing->pfnGlArbSyncObjectSetup = mockGlArbSyncObjectSetup<false>;
sharing->pfnGlArbSyncObjectSignal = glArbSyncObjectSignalMockDoNothing;
sharing->pfnGlArbSyncObjectWaitServer = glArbSyncObjectWaitServerMock<false>;
osInterface = new OSInterface;
mockCsr->setOSInterface(osInterface);
executionEnvironment->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, Event::eventNotReady, Event::eventNotReady);
triggerEvent->addChild(*baseEvent);
}
return baseEvent;
}
void failSyncObjectCreation() {
sharing->pfnGlArbSyncObjectSetup = mockGlArbSyncObjectSetup<true>;
}
void setWaitCalledFlagOnServerWait() {
sharing->pfnGlArbSyncObjectWaitServer = glArbSyncObjectWaitServerMock<true>;
}
std::unique_ptr<MockDevice> 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()->getDevice().getCommandStreamReceiver().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, Event::eventNotReady, Event::eventNotReady);
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, whenGlArbSyncEventIsCreatedTheBaseEventIsProperlySet) {
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<OCLRT::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();
}