Initial commit

Change-Id: I4bf1707bd3dfeadf2c17b0a7daff372b1925ebbd
This commit is contained in:
Brandon Fliflet
2017-12-21 00:45:38 +01:00
commit 7e9ad41290
1350 changed files with 233156 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
# Copyright (c) 2017, 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.
#We are setting all of the source / OpenCL / tests / mem_obj files here and
#sending the variable up to the parent scope
set(IGDRCL_SRCS_tests_mem_obj
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
"${CMAKE_CURRENT_SOURCE_DIR}/buffer_set_arg_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/buffer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/buffer_pin_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/create_image_format_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/destructor_callback_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/get_mem_object_info_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/get_mem_object_info_subbufer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_copy_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_redescribe_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_release_mapped_ptr_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_set_arg_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_snorm_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_validate_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image1d_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image2d_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image3d_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_array_size_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image2d_from_buffer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_tiled_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/mem_obj_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/mem_obj_destruction_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/nv12_image_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/packed_yuv_image_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pipe_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/sub_buffer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/zero_copy_tests.cpp" PARENT_SCOPE)

View File

@@ -0,0 +1,115 @@
/*
* Copyright (c) 2017, 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/mem_obj/buffer.h"
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/helpers/memory_management.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/fixtures/platform_fixture.h"
#include "runtime/helpers/options.h"
#include "gtest/gtest.h"
#include "test.h"
using namespace OCLRT;
class TestedMemoryManager : public OsAgnosticMemoryManager {
public:
GraphicsAllocation *allocateGraphicsMemory(size_t size, size_t alignment, bool forcePin) override {
EXPECT_NE(0u, expectedSize);
if (expectedSize == size) {
EXPECT_TRUE(forcePin);
allocCount++;
}
return OsAgnosticMemoryManager::allocateGraphicsMemory(size, alignment, forcePin);
};
GraphicsAllocation *allocateGraphicsMemory64kb(size_t size, size_t alignment, bool forcePin) override {
return nullptr;
};
GraphicsAllocation *allocateGraphicsMemory(size_t size, const void *ptr, bool forcePin) override {
EXPECT_NE(0u, HPExpectedSize);
if (HPExpectedSize == size) {
EXPECT_TRUE(forcePin);
HPAllocCount++;
}
return OsAgnosticMemoryManager::allocateGraphicsMemory(size, ptr, forcePin);
}
size_t expectedSize = 0;
uint32_t allocCount = 0;
size_t HPExpectedSize = 0;
uint32_t HPAllocCount = 0;
};
TEST(BufferTests, doPinIsSet) {
std::unique_ptr<TestedMemoryManager> mm(new TestedMemoryManager());
{
MockContext context;
auto size = MemoryConstants::pageSize * 32;
auto retVal = CL_INVALID_OPERATION;
mm->expectedSize = size;
mm->HPExpectedSize = 0u;
context.setMemoryManager(mm.get());
auto buffer = Buffer::create(
&context,
0,
size,
nullptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, mm->allocCount);
delete buffer;
}
}
TEST(BufferTests, doPinIsSetForHostPtr) {
std::unique_ptr<TestedMemoryManager> mm(new TestedMemoryManager());
{
MockContext context;
auto retVal = CL_INVALID_OPERATION;
auto size = MemoryConstants::pageSize * 32;
mm->expectedSize = 0u;
mm->HPExpectedSize = size;
context.setMemoryManager(mm.get());
// memory must be aligned to use zero-copy
void *bff = alignedMalloc(size, MemoryConstants::pageSize);
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
bff,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, mm->HPAllocCount);
delete buffer;
alignedFree(bff);
}
}
TEST(BufferTests, ForcePinFlagIsTrue) {
EXPECT_TRUE(DebugManager.flags.EnableForcePin.get());
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 2017, 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/helpers/ptr_math.h"
#include "runtime/kernel/kernel.h"
#include "runtime/memory_manager/surface.h"
#include "runtime/memory_manager/svm_memory_manager.h"
#include "unit_tests/fixtures/context_fixture.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/buffer_fixture.h"
#include "unit_tests/mocks/mock_kernel.h"
#include "unit_tests/mocks/mock_program.h"
#include "gtest/gtest.h"
using namespace OCLRT;
class BufferSetArgTest : public ContextFixture,
public DeviceFixture,
public testing::Test {
using ContextFixture::SetUp;
public:
BufferSetArgTest()
{
}
protected:
void SetUp() override {
DeviceFixture::SetUp();
cl_device_id device = pDevice;
ContextFixture::SetUp(1, &device);
pKernelInfo = KernelInfo::create();
ASSERT_NE(nullptr, pKernelInfo);
// define kernel info
// setup kernel arg offsets
KernelArgPatchInfo kernelArgPatchInfo;
pKernelInfo->kernelArgInfo.resize(3);
pKernelInfo->kernelArgInfo[2].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
pKernelInfo->kernelArgInfo[1].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector.push_back(kernelArgPatchInfo);
uint32_t sizeOfPointer = sizeof(void *);
pKernelInfo->kernelArgInfo[2].kernelArgPatchInfoVector[0].crossthreadOffset = 0x10;
pKernelInfo->kernelArgInfo[1].kernelArgPatchInfoVector[0].crossthreadOffset = 0x20;
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset = 0x30;
pKernelInfo->kernelArgInfo[2].kernelArgPatchInfoVector[0].size = sizeOfPointer;
pKernelInfo->kernelArgInfo[1].kernelArgPatchInfoVector[0].size = sizeOfPointer;
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size = sizeOfPointer;
pProgram = new MockProgram(pContext);
pKernel = new MockKernel(pProgram, *pKernelInfo, *pDevice);
ASSERT_NE(nullptr, pKernel);
ASSERT_EQ(CL_SUCCESS, pKernel->initialize());
pKernel->setCrossThreadData(pCrossThreadData, sizeof(pCrossThreadData));
pKernel->setKernelArgHandler(1, &Kernel::setArgBuffer);
pKernel->setKernelArgHandler(2, &Kernel::setArgBuffer);
pKernel->setKernelArgHandler(0, &Kernel::setArgBuffer);
BufferDefaults::context = new MockContext(pDevice);
buffer = BufferHelper<>::create(BufferDefaults::context);
}
void TearDown() override {
delete buffer;
delete BufferDefaults::context;
delete pKernelInfo;
delete pKernel;
delete pProgram;
ContextFixture::TearDown();
DeviceFixture::TearDown();
}
cl_int retVal = CL_SUCCESS;
MockProgram *pProgram;
MockKernel *pKernel = nullptr;
KernelInfo *pKernelInfo = nullptr;
char pCrossThreadData[64];
Buffer *buffer = nullptr;
};
TEST_F(BufferSetArgTest, setKernelArgBuffer) {
auto pKernelArg = (void **)(pKernel->getCrossThreadData() +
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset);
auto tokenSize = pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size;
buffer->setArgStateless(pKernelArg, tokenSize);
EXPECT_EQ((void *)((uintptr_t)buffer->getGraphicsAllocation()->getGpuAddress()), *pKernelArg);
}
TEST_F(BufferSetArgTest, setKernelArgBufferWithWrongSizeReturnsInvalidArgValueError) {
cl_mem arg = buffer;
cl_int err = pKernel->setArgBuffer(0, sizeof(cl_mem) + 1, arg);
EXPECT_EQ(CL_INVALID_ARG_VALUE, err);
}
TEST_F(BufferSetArgTest, setKernelArgBufferFor32BitAddressing) {
auto pKernelArg = (void **)(pKernel->getCrossThreadData() +
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset);
auto tokenSize = pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size;
uintptr_t gpuBase = (uintptr_t)buffer->getGraphicsAllocation()->getGpuAddress() >> 2;
buffer->getGraphicsAllocation()->gpuBaseAddress = gpuBase;
buffer->setArgStateless(pKernelArg, tokenSize, true);
EXPECT_EQ((uintptr_t)buffer->getGraphicsAllocation()->getGpuAddress() - gpuBase, (uintptr_t)*pKernelArg);
}
TEST_F(BufferSetArgTest, givenBufferWhenOffsetedSubbufferIsPassedToSetKernelArgThenCorrectGpuVAIsPatched) {
cl_buffer_region region;
region.origin = 0xc0;
region.size = 32;
cl_int error = 0;
auto subBuffer = buffer->createSubBuffer(buffer->getFlags(), &region, error);
ASSERT_NE(nullptr, subBuffer);
EXPECT_EQ(ptrOffset(buffer->getCpuAddress(), region.origin), subBuffer->getCpuAddress());
auto pKernelArg = (void **)(pKernel->getCrossThreadData() +
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset);
auto tokenSize = pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size;
subBuffer->setArgStateless(pKernelArg, tokenSize);
EXPECT_EQ((void *)((uintptr_t)subBuffer->getGraphicsAllocation()->getGpuAddress() + region.origin), *pKernelArg);
delete subBuffer;
}
TEST_F(BufferSetArgTest, givenCurbeTokenThatSizeIs4BytesWhenStatelessArgIsPatchedThenOnly4BytesArePatchedInCurbe) {
auto pKernelArg = (void **)(pKernel->getCrossThreadData() +
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset);
//fill 8 bytes with 0xffffffffffffffff;
uint64_t fillValue = -1;
uint64_t *pointer64bytes = (uint64_t *)pKernelArg;
*pointer64bytes = fillValue;
uint32_t sizeOf4Bytes = sizeof(uint32_t);
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].size = sizeOf4Bytes;
buffer->setArgStateless(pKernelArg, sizeOf4Bytes);
//make sure only 4 bytes are patched
uintptr_t bufferAddress = (uintptr_t)buffer->getGraphicsAllocation()->getGpuAddress();
uint32_t address32bits = (uint32_t)bufferAddress;
uint64_t curbeValue = *pointer64bytes;
uint32_t higherPart = curbeValue >> 32;
uint32_t lowerPart = (curbeValue & 0xffffffff);
EXPECT_EQ(0xffffffff, higherPart);
EXPECT_EQ(address32bits, lowerPart);
}
TEST_F(BufferSetArgTest, clSetKernelArgBuffer) {
cl_mem memObj = buffer;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto pKernelArg = (void **)(pKernel->getCrossThreadData() +
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset);
EXPECT_EQ((void *)buffer->getGraphicsAllocation()->getGpuAddressToPatch(), *pKernelArg);
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
}
TEST_F(BufferSetArgTest, clSetKernelArgSVMPointer) {
void *ptrSVM = pContext->getSVMAllocsManager()->createSVMAlloc(256);
EXPECT_NE(nullptr, ptrSVM);
GraphicsAllocation *pSvmAlloc = pContext->getSVMAllocsManager()->getSVMAlloc(ptrSVM);
EXPECT_NE(nullptr, pSvmAlloc);
retVal = pKernel->setArgSvmAlloc(
0,
ptrSVM,
pSvmAlloc);
ASSERT_EQ(CL_SUCCESS, retVal);
auto pKernelArg = (void **)(pKernel->getCrossThreadData() +
pKernelInfo->kernelArgInfo[0].kernelArgPatchInfoVector[0].crossthreadOffset);
EXPECT_EQ(ptrSVM, *pKernelArg);
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
pContext->getSVMAllocsManager()->freeSVMAlloc(ptrSVM);
}
TEST_F(BufferSetArgTest, getKernelArgShouldReturnBuffer) {
cl_mem memObj = buffer;
retVal = pKernel->setArg(
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(memObj, pKernel->getKernelArg(0));
}

View File

@@ -0,0 +1,807 @@
/*
* Copyright (c) 2017, 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/mem_obj/buffer.h"
#include "runtime/memory_manager/svm_memory_manager.h"
#include "runtime/gmm_helper/gmm_helper.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "unit_tests/helpers/memory_management.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/fixtures/platform_fixture.h"
#include "unit_tests/libult/ult_command_stream_receiver.h"
#include "runtime/helpers/options.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "test.h"
using namespace OCLRT;
static const unsigned int g_scTestBufferSizeInBytes = 16;
TEST(Buffer, FromCL_nullptr_returnsNullPtr) {
EXPECT_EQ(nullptr, castToObject<Buffer>(nullptr));
}
class BufferTest : public DeviceFixture,
public testing::TestWithParam<uint64_t /*cl_mem_flags*/> {
public:
BufferTest() {
}
protected:
void SetUp() override {
flags = GetParam();
DeviceFixture::SetUp();
contextMemoryManager = context.getMemoryManager();
context.setMemoryManager(pDevice->getMemoryManager());
}
void TearDown() override {
context.setMemoryManager(contextMemoryManager);
DeviceFixture::TearDown();
}
cl_int retVal = CL_SUCCESS;
MockContext context;
MemoryManager *contextMemoryManager;
cl_mem_flags flags = 0;
unsigned char pHostPtr[g_scTestBufferSizeInBytes];
};
typedef BufferTest NoHostPtr;
TEST_P(NoHostPtr, ValidFlags) {
auto buffer = Buffer::create(
&context,
flags,
g_scTestBufferSizeInBytes,
nullptr,
retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, buffer);
auto address = buffer->getCpuAddress();
EXPECT_NE(nullptr, address);
delete buffer;
}
TEST_P(NoHostPtr, GivenNoHostPtrWhenHwBufferCreationFailsThenReturnNullptr) {
BufferFuncs BufferFuncsBackup[IGFX_MAX_CORE];
for (uint32_t i = 0; i < IGFX_MAX_CORE; i++) {
BufferFuncsBackup[i] = bufferFactory[i];
bufferFactory[i].createBufferFunction =
[](Context *,
cl_mem_flags,
size_t,
void *,
void *,
GraphicsAllocation *,
bool,
bool,
bool)
-> OCLRT::Buffer * { return nullptr; };
}
auto buffer = Buffer::create(
&context,
flags,
g_scTestBufferSizeInBytes,
nullptr,
retVal);
EXPECT_EQ(nullptr, buffer);
for (uint32_t i = 0; i < IGFX_MAX_CORE; i++) {
bufferFactory[i] = BufferFuncsBackup[i];
}
}
TEST_P(NoHostPtr, completionStamp) {
auto buffer = Buffer::create(
&context,
flags,
g_scTestBufferSizeInBytes,
nullptr,
retVal);
FlushStamp expectedFlushstamp = 0;
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, buffer);
EXPECT_EQ(0u, buffer->getCompletionStamp().taskCount);
EXPECT_EQ(expectedFlushstamp, buffer->getCompletionStamp().flushStamp);
EXPECT_EQ(0u, buffer->getCompletionStamp().deviceOrdinal);
EXPECT_EQ(0u, buffer->getCompletionStamp().engineOrdinal);
CompletionStamp completionStamp;
completionStamp.taskCount = 42;
completionStamp.deviceOrdinal = 43;
completionStamp.engineOrdinal = 44;
completionStamp.flushStamp = 5;
buffer->setCompletionStamp(completionStamp, nullptr, nullptr);
EXPECT_EQ(completionStamp.taskCount, buffer->getCompletionStamp().taskCount);
EXPECT_EQ(completionStamp.flushStamp, buffer->getCompletionStamp().flushStamp);
EXPECT_EQ(completionStamp.deviceOrdinal, buffer->getCompletionStamp().deviceOrdinal);
EXPECT_EQ(completionStamp.engineOrdinal, buffer->getCompletionStamp().engineOrdinal);
delete buffer;
}
TEST_P(NoHostPtr, WithUseHostPtr_returnsError) {
auto buffer = Buffer::create(
&context,
flags | CL_MEM_USE_HOST_PTR,
g_scTestBufferSizeInBytes,
nullptr,
retVal);
EXPECT_EQ(CL_INVALID_HOST_PTR, retVal);
EXPECT_EQ(nullptr, buffer);
delete buffer;
}
TEST_P(NoHostPtr, WithCopyHostPtr_returnsError) {
auto buffer = Buffer::create(
&context,
flags | CL_MEM_COPY_HOST_PTR,
g_scTestBufferSizeInBytes,
nullptr,
retVal);
EXPECT_EQ(CL_INVALID_HOST_PTR, retVal);
EXPECT_EQ(nullptr, buffer);
delete buffer;
}
TEST_P(NoHostPtr, withBufferGraphicsAllocationReportsBufferType) {
auto buffer = Buffer::create(
&context,
flags,
g_scTestBufferSizeInBytes,
nullptr,
retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, buffer);
auto &allocation = *buffer->getGraphicsAllocation();
auto type = allocation.getAllocationType();
auto isTypeBuffer = !!(type & GraphicsAllocation::ALLOCATION_TYPE_BUFFER);
EXPECT_TRUE(isTypeBuffer);
auto isTypeWritable = !!(type & GraphicsAllocation::ALLOCATION_TYPE_WRITABLE);
auto isBufferWritable = !(flags & (CL_MEM_READ_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS));
EXPECT_EQ(isBufferWritable, isTypeWritable);
delete buffer;
}
// Parameterized test that tests buffer creation with all flags
// that should be valid with a nullptr host ptr
cl_mem_flags NoHostPtrFlags[] = {
CL_MEM_READ_WRITE,
CL_MEM_WRITE_ONLY,
CL_MEM_READ_ONLY,
CL_MEM_HOST_READ_ONLY,
CL_MEM_HOST_WRITE_ONLY,
CL_MEM_HOST_NO_ACCESS};
INSTANTIATE_TEST_CASE_P(
BufferTest_Create,
NoHostPtr,
testing::ValuesIn(NoHostPtrFlags));
struct ValidHostPtr
: public BufferTest,
public MemoryManagementFixture,
public PlatformFixture {
typedef BufferTest BaseClass;
using BufferTest::SetUp;
using MemoryManagementFixture::SetUp;
using PlatformFixture::SetUp;
ValidHostPtr() {
}
void SetUp() override {
MemoryManagementFixture::SetUp();
PlatformFixture::SetUp(numPlatformDevices, platformDevices);
BaseClass::SetUp();
auto pDevice = pPlatform->getDevice(0);
ASSERT_NE(nullptr, pDevice);
}
void TearDown() override {
delete buffer;
BaseClass::TearDown();
PlatformFixture::TearDown();
MemoryManagementFixture::TearDown();
}
Buffer *createBuffer() {
return Buffer::create(
&context,
flags,
g_scTestBufferSizeInBytes,
pHostPtr,
retVal);
}
cl_int retVal = CL_INVALID_VALUE;
Buffer *buffer = nullptr;
};
TEST_P(ValidHostPtr, isResident_defaultsToFalseAfterCreate) {
buffer = createBuffer();
ASSERT_NE(nullptr, buffer);
EXPECT_FALSE(buffer->getGraphicsAllocation()->isResident());
}
TEST_P(ValidHostPtr, isResident_returnsValueFromSetResident) {
buffer = createBuffer();
ASSERT_NE(nullptr, buffer);
buffer->getGraphicsAllocation()->residencyTaskCount = 1;
EXPECT_TRUE(buffer->getGraphicsAllocation()->isResident());
buffer->getGraphicsAllocation()->residencyTaskCount = ObjectNotResident;
EXPECT_FALSE(buffer->getGraphicsAllocation()->isResident());
}
TEST_P(ValidHostPtr, getAddress) {
buffer = createBuffer();
ASSERT_NE(nullptr, buffer);
auto address = buffer->getCpuAddress();
EXPECT_NE(nullptr, address);
if (flags & CL_MEM_USE_HOST_PTR && buffer->isMemObjZeroCopy()) {
// Buffer should use host ptr
EXPECT_EQ(pHostPtr, address);
} else {
// Buffer should have a different ptr
EXPECT_NE(pHostPtr, address);
}
if (flags & CL_MEM_COPY_HOST_PTR) {
// Buffer should contain a copy of host memory
EXPECT_EQ(0, memcmp(pHostPtr, address, sizeof(g_scTestBufferSizeInBytes)));
}
}
TEST_P(ValidHostPtr, getSize) {
buffer = createBuffer();
ASSERT_NE(nullptr, buffer);
EXPECT_EQ(g_scTestBufferSizeInBytes, buffer->getSize());
}
TEST_P(ValidHostPtr, givenValidHostPtrParentFlagsWhenSubBufferIsCreatedWithZeroFlagsThenItCreatesSuccesfuly) {
auto retVal = CL_SUCCESS;
auto clBuffer = clCreateBuffer(&context,
flags,
g_scTestBufferSizeInBytes,
pHostPtr,
&retVal);
ASSERT_NE(nullptr, clBuffer);
cl_buffer_region region = {0, g_scTestBufferSizeInBytes};
auto subBuffer = clCreateSubBuffer(clBuffer,
0,
CL_BUFFER_CREATE_TYPE_REGION,
&region,
&retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clReleaseMemObject(subBuffer);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clReleaseMemObject(clBuffer);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_P(ValidHostPtr, givenValidHostPtrParentFlagsWhenSubBufferIsCreatedWithParentFlagsThenItIsCreatedSuccesfuly) {
auto retVal = CL_SUCCESS;
auto clBuffer = clCreateBuffer(&context,
flags,
g_scTestBufferSizeInBytes,
pHostPtr,
&retVal);
ASSERT_NE(nullptr, clBuffer);
cl_buffer_region region = {0, g_scTestBufferSizeInBytes};
const cl_mem_flags allValidFlags =
CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY |
CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS;
cl_mem_flags unionFlags = flags & allValidFlags;
auto subBuffer = clCreateSubBuffer(clBuffer,
unionFlags,
CL_BUFFER_CREATE_TYPE_REGION,
&region,
&retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, subBuffer);
retVal = clReleaseMemObject(subBuffer);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clReleaseMemObject(clBuffer);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_P(ValidHostPtr, givenValidHostPtrParentFlagsWhenSubBufferIsCreatedWithInvalidParentFlagsThenCreationFails) {
auto retVal = CL_SUCCESS;
cl_mem_flags invalidFlags = 0;
if (flags & CL_MEM_READ_ONLY) {
invalidFlags |= CL_MEM_WRITE_ONLY;
}
if (flags & CL_MEM_WRITE_ONLY) {
invalidFlags |= CL_MEM_READ_ONLY;
}
if (flags & CL_MEM_HOST_NO_ACCESS) {
invalidFlags |= CL_MEM_HOST_READ_ONLY;
}
if (flags & CL_MEM_HOST_READ_ONLY) {
invalidFlags |= CL_MEM_HOST_WRITE_ONLY;
}
if (flags & CL_MEM_HOST_WRITE_ONLY) {
invalidFlags |= CL_MEM_HOST_READ_ONLY;
}
if (invalidFlags == 0) {
return;
}
auto clBuffer = clCreateBuffer(&context,
flags,
g_scTestBufferSizeInBytes,
pHostPtr,
&retVal);
ASSERT_NE(nullptr, clBuffer);
cl_buffer_region region = {0, g_scTestBufferSizeInBytes};
auto subBuffer = clCreateSubBuffer(clBuffer,
invalidFlags,
CL_BUFFER_CREATE_TYPE_REGION,
&region,
&retVal);
EXPECT_NE(CL_SUCCESS, retVal);
EXPECT_EQ(nullptr, subBuffer);
retVal = clReleaseMemObject(clBuffer);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_P(ValidHostPtr, failedAllocationInjection) {
InjectedFunction method = [this](size_t failureIndex) {
delete buffer;
buffer = nullptr;
// System under test
buffer = createBuffer();
if (nonfailingAllocation == failureIndex) {
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, buffer);
} else {
EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal) << "for allocation " << failureIndex;
EXPECT_EQ(nullptr, buffer);
}
};
injectFailures(method);
}
TEST_P(ValidHostPtr, SvmHostPtr) {
const DeviceInfo &devInfo = pPlatform->getDevice(0)->getDeviceInfo();
if (devInfo.svmCapabilities != 0) {
auto ptr = clSVMAlloc(&context, CL_MEM_READ_WRITE, 64, 64);
auto bufferSvm = Buffer::create(&context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, 64, ptr, retVal);
EXPECT_NE(nullptr, bufferSvm);
EXPECT_TRUE(bufferSvm->isMemObjWithHostPtrSVM());
EXPECT_EQ(context.getSVMAllocsManager()->getSVMAlloc(ptr), bufferSvm->getGraphicsAllocation());
EXPECT_EQ(CL_SUCCESS, retVal);
clSVMFree(&context, ptr);
delete bufferSvm;
}
}
// Parameterized test that tests buffer creation with all flags that should be
// valid with a valid host ptr
cl_mem_flags ValidHostPtrFlags[] = {
0 | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_USE_HOST_PTR,
0 | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR};
INSTANTIATE_TEST_CASE_P(
BufferTest_Create,
ValidHostPtr,
testing::ValuesIn(ValidHostPtrFlags));
class BufferCalculateHostPtrSize : public testing::TestWithParam<std::tuple<size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t>> {
public:
BufferCalculateHostPtrSize(){};
protected:
void SetUp() override {
std::tie(origin[0], origin[1], origin[2], region[0], region[1], region[2], rowPitch, slicePitch, hostPtrSize) = GetParam();
}
void TearDown() override {
}
size_t origin[3];
size_t region[3];
size_t rowPitch;
size_t slicePitch;
size_t hostPtrSize;
};
/* origin, region, rowPitch, slicePitch, hostPtrSize*/
static std::tuple<size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t> Inputs[] = {std::make_tuple(0, 0, 0, 1, 1, 1, 10, 1, 1),
std::make_tuple(0, 0, 0, 7, 1, 1, 10, 1, 7),
std::make_tuple(0, 0, 0, 7, 3, 1, 10, 1, 27),
std::make_tuple(0, 0, 0, 7, 1, 3, 10, 10, 27),
std::make_tuple(0, 0, 0, 7, 2, 3, 10, 20, 57),
std::make_tuple(0, 0, 0, 7, 1, 3, 10, 30, 67),
std::make_tuple(0, 0, 0, 7, 2, 3, 10, 30, 77),
std::make_tuple(9, 0, 0, 1, 1, 1, 10, 1, 10),
std::make_tuple(0, 2, 0, 7, 3, 1, 10, 1, 27 + 20),
std::make_tuple(0, 0, 1, 7, 1, 3, 10, 10, 27 + 10),
std::make_tuple(0, 2, 1, 7, 2, 3, 10, 20, 57 + 40),
std::make_tuple(1, 1, 1, 7, 1, 3, 10, 30, 67 + 41),
std::make_tuple(2, 0, 2, 7, 2, 3, 10, 30, 77 + 62)};
TEST_P(BufferCalculateHostPtrSize, CheckReturnedSize) {
size_t calculatedSize = Buffer::calculateHostPtrSize(origin, region, rowPitch, slicePitch);
EXPECT_EQ(hostPtrSize, calculatedSize);
}
INSTANTIATE_TEST_CASE_P(
BufferCalculateHostPtrSizes,
BufferCalculateHostPtrSize,
testing::ValuesIn(Inputs));
TEST(Buffers64on32Tests, given32BitBufferCreatedWithUseHostPtrFlagThatIsZeroCopyWhenAskedForStorageThenHostPtrIsReturned) {
DebugManagerStateRestore dbgRestorer;
{
DebugManager.flags.Force32bitAddressing.set(true);
MockContext context;
auto size = MemoryConstants::pageSize;
void *ptr = (void *)0x1000;
auto ptrOffset = MemoryConstants::cacheLineSize;
uintptr_t offsetedPtr = (uintptr_t)ptr + ptrOffset;
auto retVal = CL_SUCCESS;
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
(void *)offsetedPtr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(buffer->isMemObjZeroCopy());
EXPECT_EQ((void *)offsetedPtr, buffer->getCpuAddressForMapping());
EXPECT_EQ((void *)offsetedPtr, buffer->getCpuAddressForMemoryTransfer());
delete buffer;
DebugManager.flags.Force32bitAddressing.set(false);
}
}
TEST(Buffers64on32Tests, given32BitBufferCreatedWithAllocHostPtrFlagThatIsZeroCopyWhenAskedForStorageThenStorageIsEqualToMemoryStorage) {
DebugManagerStateRestore dbgRestorer;
{
DebugManager.flags.Force32bitAddressing.set(true);
MockContext context;
auto size = MemoryConstants::pageSize;
auto retVal = CL_SUCCESS;
auto buffer = Buffer::create(
&context,
CL_MEM_ALLOC_HOST_PTR,
size,
nullptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(buffer->isMemObjZeroCopy());
EXPECT_EQ(buffer->getCpuAddress(), buffer->getCpuAddressForMapping());
EXPECT_EQ(buffer->getCpuAddress(), buffer->getCpuAddressForMemoryTransfer());
delete buffer;
DebugManager.flags.Force32bitAddressing.set(false);
}
}
TEST(Buffers64on32Tests, given32BitBufferThatIsCreatedWithUseHostPtrButIsNotZeroCopyThenProperPointersAreReturned) {
DebugManagerStateRestore dbgRestorer;
{
DebugManager.flags.Force32bitAddressing.set(true);
MockContext context;
auto size = MemoryConstants::pageSize;
void *ptr = (void *)alignedMalloc(size * 2, MemoryConstants::pageSize);
auto ptrOffset = 1;
uintptr_t offsetedPtr = (uintptr_t)ptr + ptrOffset;
auto retVal = CL_SUCCESS;
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
(void *)offsetedPtr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_FALSE(buffer->isMemObjZeroCopy());
EXPECT_EQ((void *)offsetedPtr, buffer->getCpuAddressForMapping());
EXPECT_EQ(buffer->getCpuAddress(), buffer->getCpuAddressForMemoryTransfer());
delete buffer;
DebugManager.flags.Force32bitAddressing.set(false);
alignedFree(ptr);
}
}
class BufferTests : public ::testing::Test {
protected:
void SetUp() override {
}
void TearDown() override {
}
MockContext context;
};
typedef BufferTests BufferSetSurfaceTests;
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemoryPtrAndSizeIsAlignedToCachelineThenL3CacheShouldBeOn) {
auto size = MemoryConstants::pageSize;
auto ptr = (void *)alignedMalloc(size * 2, MemoryConstants::pageSize);
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
size,
ptr);
auto mocs = surfaceState.getMemoryObjectControlState();
EXPECT_EQ(Gmm::getMOCS(GMM_RESOURCE_USAGE_OCL_BUFFER), mocs);
alignedFree(ptr);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemoryPtrIsUnalignedToCachelineThenL3CacheShouldBeOff) {
auto size = MemoryConstants::pageSize;
auto ptr = alignedMalloc(size * 2, MemoryConstants::pageSize);
auto ptrOffset = 1;
auto offsetedPtr = (void *)((uintptr_t)ptr + ptrOffset);
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
size,
offsetedPtr);
auto mocs = surfaceState.getMemoryObjectControlState();
EXPECT_EQ(Gmm::getMOCS(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED), mocs);
alignedFree(ptr);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemorySizeIsUnalignedToCachelineThenL3CacheShouldBeOff) {
auto size = MemoryConstants::pageSize;
auto ptr = alignedMalloc(size * 2, MemoryConstants::pageSize);
auto sizeOffset = 1;
auto offsetedSize = size + sizeOffset;
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
offsetedSize,
ptr);
auto mocs = surfaceState.getMemoryObjectControlState();
EXPECT_EQ(Gmm::getMOCS(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED), mocs);
alignedFree(ptr);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemoryIsUnalignedToCachelineButReadOnlyThenL3CacheShouldBeStillOn) {
auto size = MemoryConstants::pageSize;
auto ptr = alignedMalloc(size * 2, MemoryConstants::pageSize);
auto sizeOffset = 1;
auto offsetedSize = size + sizeOffset;
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
offsetedSize,
ptr,
nullptr,
CL_MEM_READ_ONLY);
auto mocs = surfaceState.getMemoryObjectControlState();
EXPECT_EQ(Gmm::getMOCS(GMM_RESOURCE_USAGE_OCL_BUFFER), mocs);
alignedFree(ptr);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemorySizeIsUnalignedThenSurfaceSizeShouldBeAlignedToFour) {
auto size = MemoryConstants::pageSize;
auto ptr = alignedMalloc(size * 2, MemoryConstants::pageSize);
auto sizeOffset = 1;
auto offsetedSize = size + sizeOffset;
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
offsetedSize,
ptr);
auto width = surfaceState.getWidth();
EXPECT_EQ(alignUp(width, 4), width);
alignedFree(ptr);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemoryPtrIsNotNullThenBufferSurfaceShouldBeUsed) {
auto size = MemoryConstants::pageSize;
auto ptr = alignedMalloc(size * 2, MemoryConstants::pageSize);
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
size,
ptr);
auto surfType = surfaceState.getSurfaceType();
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_BUFFER, surfType);
alignedFree(ptr);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatMemoryPtrIsNullThenNullSurfaceShouldBeUsed) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
Buffer::setSurfaceState(
&context,
&surfaceState,
0,
nullptr);
auto surfType = surfaceState.getSurfaceType();
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_NULL, surfType);
}
HWTEST_F(BufferSetSurfaceTests, givenBufferSetSurfaceThatAddressIsForcedTo32bitWhenSetArgStatefulIsCalledThenSurfaceBaseAddressIsPopulatedWithGpuAddress) {
DebugManagerStateRestore dbgRestorer;
{
DebugManager.flags.Force32bitAddressing.set(true);
MockContext context;
auto size = MemoryConstants::pageSize;
auto ptr = (void *)alignedMalloc(size * 2, MemoryConstants::pageSize);
auto retVal = CL_SUCCESS;
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
ptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(is64bit ? buffer->getGraphicsAllocation()->is32BitAllocation : true);
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
buffer->setArgStateful(&surfaceState);
auto surfBaseAddress = surfaceState.getSurfaceBaseAddress();
auto bufferAddress = buffer->getGraphicsAllocation()->getGpuAddress();
EXPECT_EQ(bufferAddress, surfBaseAddress);
delete buffer;
alignedFree(ptr);
DebugManager.flags.Force32bitAddressing.set(false);
}
}
HWTEST_F(BufferSetSurfaceTests, givenBufferWithOffsetWhenSetArgStatefulIsCalledThenSurfaceBaseAddressIsProperlyOffseted) {
MockContext context;
auto size = MemoryConstants::pageSize;
auto ptr = (void *)alignedMalloc(size * 2, MemoryConstants::pageSize);
auto retVal = CL_SUCCESS;
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
ptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
cl_buffer_region region = {4, 8};
retVal = -1;
auto subBuffer = buffer->createSubBuffer(CL_MEM_READ_WRITE, &region, retVal);
ASSERT_NE(nullptr, subBuffer);
ASSERT_EQ(CL_SUCCESS, retVal);
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState = {};
subBuffer->setArgStateful(&surfaceState);
auto surfBaseAddress = surfaceState.getSurfaceBaseAddress();
auto bufferAddress = buffer->getGraphicsAllocation()->getGpuAddress();
EXPECT_EQ(bufferAddress + region.origin, surfBaseAddress);
subBuffer->release();
delete buffer;
alignedFree(ptr);
DebugManager.flags.Force32bitAddressing.set(false);
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2017, 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/helpers/surface_formats.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "gtest/gtest.h"
using namespace OCLRT;
static const unsigned int testImageDimensions = 32;
template <cl_mem_flags _flags>
class CreateImageFormatTest : public testing::TestWithParam<size_t> {
public:
CreateImageFormatTest() : flags(_flags) {
}
protected:
void SetUp() override {
indexImageFormat = GetParam();
const SurfaceFormatInfo *surfaceFormatTable = nullptr;
size_t numSurfaceFormats = 0;
if ((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) {
surfaceFormatTable = readOnlySurfaceFormats;
numSurfaceFormats = numReadOnlySurfaceFormats;
} else if ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) {
surfaceFormatTable = writeOnlySurfaceFormats;
numSurfaceFormats = numWriteOnlySurfaceFormats;
} else {
surfaceFormatTable = readWriteSurfaceFormats;
numSurfaceFormats = numReadWriteSurfaceFormats;
}
ASSERT_GT(numSurfaceFormats, indexImageFormat);
surfaceFormat = (SurfaceFormatInfo *)&surfaceFormatTable[indexImageFormat];
// clang-format off
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = testImageDimensions;
imageDesc.image_height = testImageDimensions;
imageDesc.image_depth = 1;
imageDesc.image_array_size = 1;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
}
void TearDown() override {
}
SurfaceFormatInfo *surfaceFormat;
size_t indexImageFormat;
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
MockContext context;
cl_mem_flags flags;
};
typedef CreateImageFormatTest<CL_MEM_READ_WRITE> ReadWriteFormatTest;
TEST_P(ReadWriteFormatTest, returnsSuccess) {
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, image);
delete image;
}
static const size_t zero = 0;
INSTANTIATE_TEST_CASE_P(
CreateImage,
ReadWriteFormatTest,
testing::Range(zero, numReadWriteSurfaceFormats));
typedef CreateImageFormatTest<CL_MEM_READ_ONLY> ReadOnlyFormatTest;
TEST_P(ReadOnlyFormatTest, returnsSuccess) {
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, image);
delete image;
}
INSTANTIATE_TEST_CASE_P(
CreateImage,
ReadOnlyFormatTest,
testing::Range(zero, numReadOnlySurfaceFormats));
typedef CreateImageFormatTest<CL_MEM_WRITE_ONLY> WriteOnlyFormatTest;
TEST_P(WriteOnlyFormatTest, returnsSuccess) {
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, image);
delete image;
}
INSTANTIATE_TEST_CASE_P(
CreateImage,
WriteOnlyFormatTest,
testing::Range(zero, numWriteOnlySurfaceFormats));

View File

@@ -0,0 +1,124 @@
/*
* Copyright (c) 2017, 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 "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/helpers/memory_management.h"
#include "test.h"
#include "unit_tests/fixtures/buffer_fixture.h"
#include "gtest/gtest.h"
using namespace OCLRT;
class DestructorCallbackFixture : public MemoryManagementFixture {
public:
DestructorCallbackFixture() {
}
void SetUp() override {
MemoryManagementFixture::SetUp();
BufferDefaults::context = new MockContext;
}
void TearDown() override {
delete BufferDefaults::context;
MemoryManagementFixture::TearDown();
}
protected:
cl_int retVal = CL_SUCCESS;
};
typedef Test<DestructorCallbackFixture> DestructorCallbackTest;
static std::vector<int> calls(32);
void CL_CALLBACK callBack1(cl_mem memObj, void *userData) {
calls.push_back(1);
}
void CL_CALLBACK callBack2(cl_mem memObj, void *userData) {
calls.push_back(2);
}
void CL_CALLBACK callBack3(cl_mem memObj, void *userData) {
calls.push_back(3);
}
TEST_F(DestructorCallbackTest, checkCallOrder) {
auto buffer = BufferHelper<BufferUseHostPtr<>>::create();
auto address = buffer->getCpuAddress();
EXPECT_NE(nullptr, address);
calls.clear();
retVal = buffer->setDestructorCallback(callBack1, nullptr);
ASSERT_EQ(CL_SUCCESS, retVal);
retVal = buffer->setDestructorCallback(callBack2, nullptr);
ASSERT_EQ(CL_SUCCESS, retVal);
retVal = buffer->setDestructorCallback(callBack3, nullptr);
ASSERT_EQ(CL_SUCCESS, retVal);
delete buffer;
ASSERT_EQ(3u, calls.size());
EXPECT_EQ(3, calls[0]);
EXPECT_EQ(2, calls[1]);
EXPECT_EQ(1, calls[2]);
calls.clear();
}
TEST_F(DestructorCallbackTest, doFailAllocations) {
std::shared_ptr<MockContext> context(new MockContext);
InjectedFunction method = [this, context](size_t failureIndex) {
char hostPtr[42];
auto buffer = Buffer::create(
context.get(),
CL_MEM_USE_HOST_PTR,
sizeof(hostPtr),
hostPtr,
retVal);
// if failures are injected into Buffer::create, we ignore them
// we are only interested in setDestructorCallback
if (retVal == CL_SUCCESS && buffer != nullptr) {
auto address = buffer->getCpuAddress();
EXPECT_NE(nullptr, address);
calls.clear();
retVal = buffer->setDestructorCallback(callBack1, nullptr);
if (nonfailingAllocation == failureIndex) {
EXPECT_EQ(CL_SUCCESS, retVal);
} else {
EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal) << "for allocation " << failureIndex;
}
delete buffer;
if (nonfailingAllocation == failureIndex) {
EXPECT_EQ(1u, calls.size());
} else {
EXPECT_EQ(0u, calls.size());
}
}
};
injectFailures(method);
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2017, 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/helpers/ptr_math.h"
#include "runtime/mem_obj/buffer.h"
#include "runtime/helpers/aligned_memory.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
using namespace OCLRT;
struct GetMemObjectSubBuferInfo : public ::testing::Test {
GetMemObjectSubBuferInfo()
{
}
void SetUp() override {
bufferStorage = alignedMalloc(4096, MemoryConstants::preferredAlignment);
region.origin = 4;
region.size = 12;
}
void TearDown() override {
delete subBuffer;
delete buffer;
alignedFree(bufferStorage);
}
void createBuffer(cl_mem_flags flags = CL_MEM_READ_WRITE) {
auto retVal = CL_INVALID_VALUE;
buffer = Buffer::create(&context, flags, bufferSize, nullptr, retVal);
ASSERT_NE(nullptr, buffer);
}
void createSubBuffer(cl_mem_flags flags = CL_MEM_READ_WRITE) {
cl_int retVal;
subBuffer = buffer->createSubBuffer(flags, &region, retVal);
ASSERT_NE(nullptr, subBuffer);
}
void createHostPtrBuffer(cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR) {
auto retVal = CL_INVALID_VALUE;
buffer = Buffer::create(&context, flags, bufferSize, bufferStorage, retVal);
ASSERT_NE(nullptr, buffer);
}
MockContext context;
Buffer *buffer = nullptr;
Buffer *subBuffer = nullptr;
void *bufferStorage;
static const size_t bufferSize = 256;
cl_buffer_region region;
cl_int retVal;
size_t sizeReturned = 0;
};
TEST_F(GetMemObjectSubBuferInfo, MEM_ASSOCIATED_MEMOBJECT) {
createBuffer();
createSubBuffer();
cl_mem object = nullptr;
retVal = subBuffer->getMemObjectInfo(CL_MEM_ASSOCIATED_MEMOBJECT, 0, nullptr, &sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(object), sizeReturned);
retVal = subBuffer->getMemObjectInfo(CL_MEM_ASSOCIATED_MEMOBJECT, sizeof(object),
&object, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
cl_mem clBuffer = (cl_mem)buffer;
EXPECT_EQ(clBuffer, object);
}
TEST_F(GetMemObjectSubBuferInfo, MEM_OFFSET) {
createBuffer();
createSubBuffer();
size_t offset = 0;
retVal = subBuffer->getMemObjectInfo(CL_MEM_OFFSET, 0, nullptr, &sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(offset), sizeReturned);
retVal = subBuffer->getMemObjectInfo(CL_MEM_OFFSET, sizeof(offset), &offset, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(region.origin, offset);
}
TEST_F(GetMemObjectSubBuferInfo, MEM_FLAGS) {
createBuffer();
createSubBuffer();
cl_mem_flags flags = 0;
retVal = subBuffer->getMemObjectInfo(CL_MEM_FLAGS, 0, nullptr, &sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(flags), sizeReturned);
retVal = subBuffer->getMemObjectInfo(CL_MEM_FLAGS, sizeof(flags), &flags, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_READ_WRITE), flags);
}
TEST_F(GetMemObjectSubBuferInfo, MEM_FLAGS_empty) {
createBuffer(CL_MEM_READ_ONLY);
createSubBuffer(0);
cl_mem_flags flags = 0;
retVal = subBuffer->getMemObjectInfo(CL_MEM_FLAGS, 0, nullptr, &sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(flags), sizeReturned);
retVal = subBuffer->getMemObjectInfo(
CL_MEM_FLAGS,
sizeof(flags),
&flags,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(static_cast<cl_mem_flags>(0), flags);
}
TEST_F(GetMemObjectSubBuferInfo, MEM_HOST_PTR) {
createHostPtrBuffer();
createSubBuffer();
void *hostPtr = 0;
retVal = subBuffer->getMemObjectInfo(CL_MEM_HOST_PTR, 0, nullptr, &sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(hostPtr), sizeReturned);
retVal = subBuffer->getMemObjectInfo(CL_MEM_HOST_PTR, sizeof(hostPtr), &hostPtr, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
auto expected = ptrOffset(this->bufferStorage, region.origin);
EXPECT_EQ(expected, hostPtr);
}

View File

@@ -0,0 +1,323 @@
/*
* Copyright (c) 2017, 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/helpers/ptr_math.h"
#include "runtime/helpers/aligned_memory.h"
#include "unit_tests/fixtures/buffer_fixture.h"
#include "unit_tests/fixtures/platform_fixture.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "runtime/helpers/options.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
#include <memory>
using namespace OCLRT;
class GetMemObjectInfo : public ::testing::Test, public PlatformFixture, public DeviceFixture {
using PlatformFixture::SetUp;
using DeviceFixture::SetUp;
public:
void SetUp() override {
PlatformFixture::SetUp(numPlatformDevices, platformDevices);
DeviceFixture::SetUp();
BufferDefaults::context = new MockContext;
}
void TearDown() override {
delete BufferDefaults::context;
PlatformFixture::TearDown();
DeviceFixture::TearDown();
}
};
TEST_F(GetMemObjectInfo, InvalidFlags_returnsError) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
auto retVal = buffer->getMemObjectInfo(
0,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST_F(GetMemObjectInfo, MEM_TYPE) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_TYPE,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(cl_mem_object_type), sizeReturned);
cl_mem_object_type object_type = 0;
retVal = buffer->getMemObjectInfo(
CL_MEM_TYPE,
sizeof(cl_mem_object_type),
&object_type,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(static_cast<cl_mem_object_type>(CL_MEM_OBJECT_BUFFER), object_type);
}
TEST_F(GetMemObjectInfo, MEM_FLAGS) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
cl_mem_flags mem_flags = 0;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_FLAGS,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(mem_flags), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_FLAGS,
sizeof(mem_flags),
&mem_flags,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_READ_WRITE), mem_flags);
}
TEST_F(GetMemObjectInfo, MEM_SIZE) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
size_t mem_size = 0;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_SIZE,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(mem_size), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_SIZE,
sizeof(mem_size),
&mem_size,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(buffer->getSize(), mem_size);
}
TEST_F(GetMemObjectInfo, MEM_HOST_PTR) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
void *host_ptr = nullptr;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_HOST_PTR,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(host_ptr), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_HOST_PTR,
sizeof(host_ptr),
&host_ptr,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(buffer->getHostPtr(), host_ptr);
}
TEST_F(GetMemObjectInfo, MEM_CONTEXT) {
MockContext context;
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create(&context));
size_t sizeReturned = 0;
cl_context contextReturned = nullptr;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_CONTEXT,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(contextReturned), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_CONTEXT,
sizeof(contextReturned),
&contextReturned,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(&context, contextReturned);
}
TEST_F(GetMemObjectInfo, MEM_USES_SVM_POINTER_FALSE) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create());
size_t sizeReturned = 0;
cl_bool usesSVMPointer = false;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_USES_SVM_POINTER,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(usesSVMPointer), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_USES_SVM_POINTER,
sizeof(usesSVMPointer),
&usesSVMPointer,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(static_cast<cl_bool>(CL_FALSE), usesSVMPointer);
}
TEST_F(GetMemObjectInfo, MEM_USES_SVM_POINTER_TRUE) {
const DeviceInfo &devInfo = pDevice->getDeviceInfo();
if (devInfo.svmCapabilities != 0) {
auto hostPtr = clSVMAlloc(BufferDefaults::context, CL_MEM_READ_WRITE, BufferUseHostPtr<>::sizeInBytes, 64);
ASSERT_NE(nullptr, hostPtr);
cl_int retVal;
auto buffer = Buffer::create(
BufferDefaults::context,
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
BufferUseHostPtr<>::sizeInBytes,
hostPtr,
retVal);
size_t sizeReturned = 0;
cl_bool usesSVMPointer = false;
retVal = buffer->getMemObjectInfo(
CL_MEM_USES_SVM_POINTER,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(usesSVMPointer), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_USES_SVM_POINTER,
sizeof(usesSVMPointer),
&usesSVMPointer,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(static_cast<cl_bool>(CL_TRUE), usesSVMPointer);
delete buffer;
clSVMFree(BufferDefaults::context, hostPtr);
}
}
TEST_F(GetMemObjectInfo, MEM_OFFSET) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
size_t offset = false;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_OFFSET,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(offset), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_OFFSET,
sizeof(offset),
&offset,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0u, offset);
}
TEST_F(GetMemObjectInfo, MEM_ASSOCIATED_MEMOBJECT) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
cl_mem object = nullptr;
auto retVal = buffer->getMemObjectInfo(
CL_MEM_ASSOCIATED_MEMOBJECT,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(object), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_ASSOCIATED_MEMOBJECT,
sizeof(object),
&object,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(nullptr, object);
}
TEST_F(GetMemObjectInfo, MEM_MAP_COUNT) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
cl_uint mapCount = static_cast<uint32_t>(-1);
auto retVal = buffer->getMemObjectInfo(
CL_MEM_MAP_COUNT,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(mapCount), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_MAP_COUNT,
sizeof(mapCount),
&mapCount,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(mapCount), sizeReturned);
}
TEST_F(GetMemObjectInfo, MEM_REFERENCE_COUNT) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
size_t sizeReturned = 0;
cl_uint refCount = static_cast<uint32_t>(-1);
auto retVal = buffer->getMemObjectInfo(
CL_MEM_REFERENCE_COUNT,
0,
nullptr,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(refCount), sizeReturned);
retVal = buffer->getMemObjectInfo(
CL_MEM_REFERENCE_COUNT,
sizeof(refCount),
&refCount,
&sizeReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(sizeof(refCount), sizeReturned);
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2017, 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 "hw_cmds.h"
#include "runtime/mem_obj/image.h"
#include "runtime/mem_obj/buffer.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "test.h"
using namespace OCLRT;
static const unsigned int testImageDimensions = 32;
class CreateImage1DTest : public DeviceFixture,
public testing::TestWithParam<uint32_t /*cl_mem_object_type*/> {
public:
CreateImage1DTest() {
}
protected:
void SetUp() override {
DeviceFixture::SetUp();
types = GetParam();
// clang-format off
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_type = types;
imageDesc.image_width = testImageDimensions;
imageDesc.image_height = 0;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 1;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
if (types == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
imageDesc.image_array_size = 10;
}
context = new MockContext(pDevice);
if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
imageDesc.mem_object = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, testImageDimensions, nullptr, nullptr);
}
}
void TearDown() override {
if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
clReleaseMemObject(imageDesc.mem_object);
}
delete context;
DeviceFixture::TearDown();
}
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
MockContext *context;
cl_mem_object_type types = 0;
};
typedef CreateImage1DTest CreateImage1DType;
HWTEST_P(CreateImage1DType, validTypes) {
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
auto imgDesc = image->getImageDesc();
EXPECT_NE(0u, imgDesc.image_width);
EXPECT_EQ(0u, imgDesc.image_height);
EXPECT_EQ(0u, imgDesc.image_depth);
EXPECT_NE(0u, imgDesc.image_row_pitch);
EXPECT_GE(imgDesc.image_slice_pitch, imgDesc.image_row_pitch);
size_t ImageInfoHeight = 0;
retVal = clGetImageInfo(image, CL_IMAGE_HEIGHT, sizeof(size_t), &ImageInfoHeight, NULL);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_EQ(0u, ImageInfoHeight);
if ((types == CL_MEM_OBJECT_IMAGE1D) || (types == CL_MEM_OBJECT_IMAGE1D_BUFFER)) {
EXPECT_EQ(0u, imgDesc.image_array_size);
} else if (types == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
EXPECT_NE(0u, imgDesc.image_array_size);
} else {
ASSERT_TRUE(false);
}
EXPECT_EQ(image->getCubeFaceIndex(), static_cast<uint32_t>(__GMM_NO_CUBE_MAP));
ASSERT_EQ(true, image->isMemObjZeroCopy());
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
Buffer *inputBuffer = castToObject<Buffer>(imageDesc.buffer);
EXPECT_NE(nullptr, inputBuffer->getCpuAddress());
EXPECT_EQ(inputBuffer->getCpuAddress(), image->getCpuAddress());
EXPECT_TRUE(image->getIsObjectRedescribed());
EXPECT_GE(2, inputBuffer->getRefInternalCount());
}
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
auto imageHw = static_cast<ImageHw<FamilyType> *>(image);
EXPECT_EQ(SURFACE_STATE::SURFACE_TYPE_SURFTYPE_1D, imageHw->surfaceType);
delete image;
}
static cl_mem_object_type Image1DTypes[] = {
CL_MEM_OBJECT_IMAGE1D,
CL_MEM_OBJECT_IMAGE1D_BUFFER,
CL_MEM_OBJECT_IMAGE1D_ARRAY};
INSTANTIATE_TEST_CASE_P(
CreateImage1DTest_Create,
CreateImage1DType,
testing::ValuesIn(Image1DTypes));

View File

@@ -0,0 +1,308 @@
/*
* Copyright (c) 2017, 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/mem_obj/image.h"
#include "runtime/mem_obj/buffer.h"
#include "runtime/helpers/aligned_memory.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_gmm.h"
#include "test.h"
using namespace OCLRT;
// Tests for cl_khr_image2d_from_buffer
class Image2dFromBufferTest : public DeviceFixture, public ::testing::Test {
public:
Image2dFromBufferTest() {}
protected:
void SetUp() override {
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_array_size = 0;
imageDesc.image_depth = 0;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_height = 128;
imageDesc.image_width = 256;
imageDesc.num_mip_levels = 0;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_samples = 0;
size = 128 * 256 * 4;
hostPtr = alignedMalloc(size, 16);
ASSERT_NE(nullptr, hostPtr);
imageDesc.mem_object = clCreateBuffer(&context, CL_MEM_USE_HOST_PTR, size, hostPtr, &retVal);
ASSERT_NE(nullptr, imageDesc.mem_object);
}
void TearDown() override {
clReleaseMemObject(imageDesc.mem_object);
alignedFree(hostPtr);
}
Image *createImage() {
cl_mem_flags flags = CL_MEM_READ_ONLY;
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
return Image::create(&context, flags, surfaceFormat, &imageDesc, NULL, retVal);
}
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
MockContext context;
void *hostPtr;
size_t size;
};
TEST_F(Image2dFromBufferTest, CreateImage2dFromBuffer) {
auto buffer = castToObject<Buffer>(imageDesc.mem_object);
ASSERT_NE(nullptr, buffer);
EXPECT_EQ(1, buffer->getRefInternalCount());
auto imageFromBuffer = createImage();
ASSERT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2, buffer->getRefInternalCount());
EXPECT_NE(nullptr, imageFromBuffer);
EXPECT_FALSE(imageFromBuffer->allowTiling());
EXPECT_EQ(imageFromBuffer->getCubeFaceIndex(), static_cast<uint32_t>(__GMM_NO_CUBE_MAP));
delete imageFromBuffer;
EXPECT_EQ(1, buffer->getRefInternalCount());
}
TEST_F(Image2dFromBufferTest, InvalidImageType) {
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
cl_mem_flags flags = CL_MEM_READ_ONLY;
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
}
TEST_F(Image2dFromBufferTest, CalculateRowPitch) {
auto imageFromBuffer = createImage();
ASSERT_NE(nullptr, imageFromBuffer);
EXPECT_NE(0u, imageFromBuffer->getImageDesc().image_row_pitch);
EXPECT_EQ(1024u, imageFromBuffer->getImageDesc().image_row_pitch);
delete imageFromBuffer;
}
TEST_F(Image2dFromBufferTest, InvalidRowPitch) {
char ptr[10];
imageDesc.image_row_pitch = 257;
cl_mem_flags flags = CL_MEM_READ_ONLY;
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, ptr);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_F(Image2dFromBufferTest, givenRowPitchThatIsGreaterThenComputedWhenImageIsCreatedThenPassedRowPitchIsUsedInsteadOfComputed) {
auto computedSize = imageDesc.image_width * 4;
auto passedSize = computedSize * 2;
imageDesc.image_row_pitch = passedSize;
auto imageFromBuffer = createImage();
EXPECT_EQ(passedSize, imageFromBuffer->getHostPtrRowPitch());
delete imageFromBuffer;
}
TEST_F(Image2dFromBufferTest, InvalidHostPtrAlignment) {
std::unique_ptr<void, decltype(free) *> myHostPtr(malloc(size + 1), free);
ASSERT_NE(nullptr, myHostPtr);
void *nonAlignedHostPtr = myHostPtr.get();
if ((reinterpret_cast<uint64_t>(myHostPtr.get()) % 4) == 0) {
nonAlignedHostPtr = reinterpret_cast<void *>((reinterpret_cast<uint64_t>(myHostPtr.get()) + 1));
}
cl_mem origBuffer = imageDesc.mem_object;
imageDesc.mem_object = clCreateBuffer(&context, CL_MEM_USE_HOST_PTR, size, nonAlignedHostPtr, &retVal);
ASSERT_NE(nullptr, imageDesc.mem_object);
cl_mem_flags flags = CL_MEM_READ_ONLY;
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
clReleaseMemObject(imageDesc.mem_object);
imageDesc.mem_object = origBuffer;
}
TEST_F(Image2dFromBufferTest, InvalidFlags) {
cl_mem_flags flags = CL_MEM_USE_HOST_PTR;
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, reinterpret_cast<void *>(0x12345));
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST_F(Image2dFromBufferTest, InvalidSize) {
imageDesc.image_height = 1024;
cl_mem_flags flags = CL_MEM_READ_ONLY;
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
}
TEST_F(Image2dFromBufferTest, ExtensionString) {
auto device = std::unique_ptr<Device>(DeviceHelper<>::create(platformDevices[0]));
const auto &caps = device->getDeviceInfo();
std::string extensions = caps.deviceExtensions;
size_t found = extensions.find("cl_khr_image2d_from_buffer");
EXPECT_NE(std::string::npos, found);
}
TEST_F(Image2dFromBufferTest, InterceptBuffersHostPtr) {
auto buffer = castToObject<Buffer>(imageDesc.mem_object);
ASSERT_NE(nullptr, buffer);
EXPECT_EQ(1, buffer->getRefInternalCount());
auto imageFromBuffer = createImage();
ASSERT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(buffer->getHostPtr(), imageFromBuffer->getHostPtr());
EXPECT_EQ(true, imageFromBuffer->isMemObjZeroCopy());
delete imageFromBuffer;
}
TEST_F(Image2dFromBufferTest, givenMemoryManagerNotSupportingVirtualPaddingWhenImageIsCreatedThenPaddingIsNotApplied) {
auto memoryManager = context.getMemoryManager();
memoryManager->setVirtualPaddingSupport(false);
auto buffer = castToObject<Buffer>(imageDesc.mem_object);
ASSERT_NE(nullptr, buffer);
EXPECT_EQ(1, buffer->getRefInternalCount());
std::unique_ptr<Image> imageFromBuffer(createImage());
ASSERT_EQ(CL_SUCCESS, retVal);
//graphics allocation for image and buffer is the same
auto bufferGraphicsAllocation = buffer->getGraphicsAllocation();
auto imageGraphicsAllocation = imageFromBuffer->getGraphicsAllocation();
EXPECT_EQ(bufferGraphicsAllocation, imageGraphicsAllocation);
}
TEST_F(Image2dFromBufferTest, givenMemoryManagerSupportingVirtualPaddingWhenImageIsCreatedThatFitsInTheBufferThenPaddingIsNotApplied) {
auto memoryManager = context.getMemoryManager();
memoryManager->setVirtualPaddingSupport(true);
auto buffer = castToObject<Buffer>(imageDesc.mem_object);
ASSERT_NE(nullptr, buffer);
EXPECT_EQ(1, buffer->getRefInternalCount());
std::unique_ptr<Image> imageFromBuffer(createImage());
ASSERT_EQ(CL_SUCCESS, retVal);
//graphics allocation for image and buffer is the same
auto bufferGraphicsAllocation = buffer->getGraphicsAllocation();
auto imageGraphicsAllocation = imageFromBuffer->getGraphicsAllocation();
EXPECT_EQ(this->size, bufferGraphicsAllocation->getUnderlyingBufferSize());
auto imgInfo = MockGmm::initImgInfo(imageDesc, 0, &imageFromBuffer->getSurfaceFormatInfo());
auto queryGmm = MockGmm::queryImgParams(imgInfo);
EXPECT_TRUE(queryGmm->gmmResourceInfo->getSizeAllocation() >= this->size);
EXPECT_EQ(bufferGraphicsAllocation, imageGraphicsAllocation);
}
TEST_F(Image2dFromBufferTest, givenMemoryManagerSupportingVirtualPaddingWhenImageIsCreatedThatDoesntFitInTheBufferThenPaddingIsApplied) {
imageFormat.image_channel_data_type = CL_FLOAT;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_width = 29;
imageDesc.image_height = 29;
imageDesc.image_row_pitch = 512;
//application calcualted buffer size
auto bufferSize = imageDesc.image_row_pitch * imageDesc.image_height;
auto buffer2 = clCreateBuffer(&context, CL_MEM_READ_WRITE, bufferSize, nullptr, nullptr);
auto storeMem = imageDesc.mem_object;
imageDesc.mem_object = buffer2;
auto memoryManager = context.getMemoryManager();
memoryManager->setVirtualPaddingSupport(true);
auto buffer = castToObject<Buffer>(imageDesc.mem_object);
std::unique_ptr<Image> imageFromBuffer(createImage());
ASSERT_EQ(CL_SUCCESS, retVal);
//graphics allocation for image and buffer is the same
auto bufferGraphicsAllocation = buffer->getGraphicsAllocation();
auto imageGraphicsAllocation = imageFromBuffer->getGraphicsAllocation();
EXPECT_EQ(bufferSize, bufferGraphicsAllocation->getUnderlyingBufferSize());
auto imgInfo = MockGmm::initImgInfo(imageDesc, 0, &imageFromBuffer->getSurfaceFormatInfo());
auto queryGmm = MockGmm::queryImgParams(imgInfo);
EXPECT_GT(queryGmm->gmmResourceInfo->getSizeAllocation(), bufferSize);
EXPECT_NE(bufferGraphicsAllocation, imageGraphicsAllocation);
EXPECT_EQ(queryGmm->gmmResourceInfo->getSizeAllocation(), imageFromBuffer->getGraphicsAllocation()->getUnderlyingBufferSize());
EXPECT_EQ(bufferSize, imageFromBuffer->getSize());
imageDesc.mem_object = storeMem;
clReleaseMemObject(buffer2);
}
TEST_F(Image2dFromBufferTest, givenMemoryManagerSupportingVirtualPaddingWhen1DImageFromBufferImageIsCreatedThenVirtualPaddingIsNotApplied) {
imageFormat.image_channel_data_type = CL_FLOAT;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_width = 1024;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
//application calcualted buffer size
auto bufferSize = imageDesc.image_width * 16;
auto buffer2 = clCreateBuffer(&context, CL_MEM_READ_WRITE, bufferSize, nullptr, nullptr);
auto storeMem = imageDesc.mem_object;
imageDesc.mem_object = buffer2;
auto memoryManager = context.getMemoryManager();
memoryManager->setVirtualPaddingSupport(true);
auto buffer = castToObject<Buffer>(imageDesc.mem_object);
std::unique_ptr<Image> imageFromBuffer(createImage());
ASSERT_EQ(CL_SUCCESS, retVal);
//graphics allocation match
auto bufferGraphicsAllocation = buffer->getGraphicsAllocation();
auto imageGraphicsAllocation = imageFromBuffer->getGraphicsAllocation();
EXPECT_EQ(bufferGraphicsAllocation, imageGraphicsAllocation);
imageDesc.mem_object = storeMem;
clReleaseMemObject(buffer2);
}
TEST_F(Image2dFromBufferTest, givenMemoryManagerSupporting1DImageFromBufferWhenNoBufferThenCreatesImage) {
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
auto storeMem = imageDesc.mem_object;
imageDesc.mem_object = nullptr;
std::unique_ptr<Image> imageFromBuffer(createImage());
EXPECT_EQ(CL_SUCCESS, retVal);
imageDesc.mem_object = storeMem;
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2017, 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 "hw_cmds.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "test.h"
using namespace OCLRT;
static const unsigned int testImageDimensions = 32;
class CreateImage2DTest : public DeviceFixture,
public testing::TestWithParam<uint32_t /*cl_mem_object_type*/> {
public:
CreateImage2DTest() {
}
protected:
void SetUp() override {
DeviceFixture::SetUp();
types = GetParam();
// clang-format off
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_type = types;
imageDesc.image_width = testImageDimensions;
imageDesc.image_height = testImageDimensions;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 1;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
if (types == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
imageDesc.image_array_size = 10;
}
context = new MockContext(pDevice);
}
void TearDown() override {
delete context;
DeviceFixture::TearDown();
}
Image *createImageWithFlags(cl_mem_flags flags) {
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
return Image::create(context, flags, surfaceFormat, &imageDesc, nullptr, retVal);
}
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
MockContext *context;
cl_mem_object_type types = 0;
};
typedef CreateImage2DTest CreateImage2DType;
HWTEST_P(CreateImage2DType, validTypes) {
auto image = createImageWithFlags(CL_MEM_READ_WRITE);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
auto imgDesc = image->getImageDesc();
EXPECT_NE(0u, imgDesc.image_width);
EXPECT_NE(0u, imgDesc.image_height);
EXPECT_EQ(0u, imgDesc.image_depth);
EXPECT_NE(0u, imgDesc.image_row_pitch);
EXPECT_GE(imgDesc.image_slice_pitch, imgDesc.image_row_pitch);
if (types == CL_MEM_OBJECT_IMAGE2D) {
EXPECT_EQ(0u, imgDesc.image_array_size);
} else if (types == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
EXPECT_NE(0u, imgDesc.image_array_size);
} else {
ASSERT_TRUE(false);
}
EXPECT_EQ(image->getCubeFaceIndex(), static_cast<uint32_t>(__GMM_NO_CUBE_MAP));
ASSERT_EQ(true, image->isMemObjZeroCopy());
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
auto imageHw = static_cast<ImageHw<FamilyType> *>(image);
EXPECT_EQ(SURFACE_STATE::SURFACE_TYPE_SURFTYPE_2D, imageHw->surfaceType);
SurfaceOffsets surfaceOffsets;
image->getSurfaceOffsets(surfaceOffsets);
EXPECT_EQ(0u, surfaceOffsets.offset);
EXPECT_EQ(0u, surfaceOffsets.xOffset);
EXPECT_EQ(0u, surfaceOffsets.yOffset);
EXPECT_EQ(0u, surfaceOffsets.yOffsetForUVplane);
delete image;
}
static cl_mem_object_type Image2DTypes[] = {
CL_MEM_OBJECT_IMAGE2D,
CL_MEM_OBJECT_IMAGE2D_ARRAY};
INSTANTIATE_TEST_CASE_P(
CreateImage2DTest_Create,
CreateImage2DType,
testing::ValuesIn(Image2DTypes));

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2017, 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 "hw_cmds.h"
#include "runtime/mem_obj/image.h"
#include "runtime/helpers/aligned_memory.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_gmm.h"
#include "test.h"
using namespace OCLRT;
static const unsigned int testImageDimensions = 31;
class CreateImage3DTest : public DeviceFixture,
public testing::TestWithParam<uint32_t /*cl_mem_object_type*/> {
public:
CreateImage3DTest() {}
protected:
void SetUp() override {
DeviceFixture::SetUp();
context = new MockContext(pDevice);
// clang-format off
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE3D;
imageDesc.image_width = testImageDimensions;
imageDesc.image_height = testImageDimensions;
imageDesc.image_depth = testImageDimensions;
imageDesc.image_array_size = 1;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
}
void TearDown() override {
delete context;
DeviceFixture::TearDown();
}
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
MockContext *context;
cl_mem_object_type types = 0;
};
HWTEST_F(CreateImage3DTest, validTypes) {
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(context, flags, surfaceFormat, &imageDesc, nullptr, retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
auto imgDesc = image->getImageDesc();
EXPECT_NE(0u, imgDesc.image_width);
EXPECT_NE(0u, imgDesc.image_height);
EXPECT_NE(0u, imgDesc.image_depth);
EXPECT_NE(0u, imgDesc.image_slice_pitch);
EXPECT_EQ(0u, imgDesc.image_array_size);
EXPECT_NE(0u, imgDesc.image_row_pitch);
EXPECT_EQ(image->getCubeFaceIndex(), static_cast<uint32_t>(__GMM_NO_CUBE_MAP));
ASSERT_EQ(true, image->isMemObjZeroCopy());
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
auto imageHw = static_cast<ImageHw<FamilyType> *>(image);
EXPECT_EQ(SURFACE_STATE::SURFACE_TYPE_SURFTYPE_3D, imageHw->surfaceType);
delete image;
}
HWTEST_F(CreateImage3DTest, calculate3dImageQpitchTiledAndLinear) {
bool defaultTiling = DebugManager.flags.ForceLinearImages.get();
imageDesc.image_height = 1;
auto surfaceFormat = Image::getSurfaceFormatFromTable(0, &imageFormat);
auto imgInfo = MockGmm::initImgInfo(imageDesc, 0, surfaceFormat);
MockGmm::queryImgParams(imgInfo);
auto image = Image::create(
context,
0,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ(image->getSize(), imgInfo.size);
EXPECT_EQ(image->getImageDesc().image_slice_pitch, imgInfo.slicePitch);
EXPECT_GE(image->getImageDesc().image_slice_pitch, image->getImageDesc().image_row_pitch);
EXPECT_EQ(image->getImageDesc().image_row_pitch, imgInfo.rowPitch);
EXPECT_EQ(image->getQPitch(), imgInfo.qPitch);
delete image;
DebugManager.flags.ForceLinearImages.set(!defaultTiling);
// query again
surfaceFormat = Image::getSurfaceFormatFromTable(0, &imageFormat);
MockGmm::queryImgParams(imgInfo);
image = Image::create(
context,
0,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ(image->getSize(), imgInfo.size);
EXPECT_EQ(image->getImageDesc().image_slice_pitch, imgInfo.slicePitch);
EXPECT_EQ(image->getImageDesc().image_row_pitch, imgInfo.rowPitch);
EXPECT_GE(image->getImageDesc().image_slice_pitch, image->getImageDesc().image_row_pitch);
EXPECT_EQ(image->getQPitch(), imgInfo.qPitch);
delete image;
DebugManager.flags.ForceLinearImages.set(defaultTiling);
}

View File

@@ -0,0 +1,206 @@
/*
* Copyright (c) 2017, 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 "hw_cmds.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "test.h"
using namespace OCLRT;
static const unsigned int testImageDimensions = 17;
class ImageArraySizeTest : public DeviceFixture,
public testing::TestWithParam<uint32_t /*cl_mem_object_type*/> {
public:
ImageArraySizeTest() {
}
protected:
void SetUp() override {
DeviceFixture::SetUp();
types = GetParam();
// clang-format off
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_RGBA;
imageDesc.image_type = types;
imageDesc.image_width = testImageDimensions;
imageDesc.image_height = testImageDimensions;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 10;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
context = new MockContext(pDevice);
if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
imageDesc.mem_object = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, testImageDimensions, nullptr, nullptr);
}
}
void TearDown() override {
if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
clReleaseMemObject(imageDesc.mem_object);
}
delete context;
DeviceFixture::TearDown();
}
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
MockContext *context;
cl_mem_object_type types = 0;
};
typedef ImageArraySizeTest CreateImageArraySize;
HWTEST_P(CreateImageArraySize, arrayTypes) {
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
ASSERT_EQ(true, image->isMemObjZeroCopy());
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
ASSERT_EQ(10u, image->getImageDesc().image_array_size);
delete image;
}
static cl_mem_object_type ArrayImageTypes[] = {
CL_MEM_OBJECT_IMAGE1D_ARRAY,
CL_MEM_OBJECT_IMAGE2D_ARRAY};
INSTANTIATE_TEST_CASE_P(
ImageArraySizeTest_Create,
CreateImageArraySize,
testing::ValuesIn(ArrayImageTypes));
typedef ImageArraySizeTest CreateImageNonArraySize;
HWTEST_P(CreateImageNonArraySize, NonArrayTypes) {
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
ASSERT_EQ(true, image->isMemObjZeroCopy());
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
ASSERT_EQ(0u, image->getImageDesc().image_array_size);
delete image;
}
static cl_mem_object_type NonArrayImageTypes[] = {
CL_MEM_OBJECT_IMAGE1D,
CL_MEM_OBJECT_IMAGE1D_BUFFER,
CL_MEM_OBJECT_IMAGE2D,
CL_MEM_OBJECT_IMAGE3D};
INSTANTIATE_TEST_CASE_P(
ImageArraySizeTest_Create,
CreateImageNonArraySize,
testing::ValuesIn(NonArrayImageTypes));
typedef ImageArraySizeTest CreateImageSize;
HWTEST_P(CreateImageSize, GivenImageTypeAndRegionWhenAskedForHostPtrSizeThenProperSizeIsBeingReturned) {
size_t region[3] = {100, 200, 300};
auto rowPitch = 1000;
auto slicePitch = 4000;
auto pixelSize = 4;
auto imageType = GetParam();
auto size = Image::calculateHostPtrSize(region, rowPitch, slicePitch, pixelSize, imageType);
if ((imageType == CL_MEM_OBJECT_IMAGE1D) || (imageType == CL_MEM_OBJECT_IMAGE1D_BUFFER)) {
EXPECT_EQ(region[0] * pixelSize, size);
} else if (imageType == CL_MEM_OBJECT_IMAGE2D) {
EXPECT_EQ((region[1] - 1) * rowPitch + region[0] * pixelSize, size);
} else if (imageType == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
EXPECT_EQ((region[1] - 1) * slicePitch + region[0] * pixelSize, size);
} else if ((imageType == CL_MEM_OBJECT_IMAGE3D) || (imageType == CL_MEM_OBJECT_IMAGE2D_ARRAY)) {
EXPECT_EQ((region[2] - 1) * slicePitch + (region[1] - 1) * rowPitch + region[0] * pixelSize, size);
} else {
EXPECT_EQ(0u, size);
}
}
typedef ImageArraySizeTest CheckImageType;
TEST_P(CheckImageType, GivenImageTypeWhenImageTypeIsCheckedThenProperValueIsReturned) {
auto imageType = GetParam();
switch (imageType) {
case CL_MEM_OBJECT_IMAGE2D:
EXPECT_TRUE(Image::isImage2d(imageType));
EXPECT_TRUE(Image::isImage2dOr2dArray(imageType));
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
EXPECT_FALSE(Image::isImage2d(imageType));
EXPECT_TRUE(Image::isImage2dOr2dArray(imageType));
break;
default:
EXPECT_FALSE(Image::isImage2d(imageType));
EXPECT_FALSE(Image::isImage2dOr2dArray(imageType));
break;
}
}
static cl_mem_object_type AllImageTypes[] = {
0, //negative scenario
CL_MEM_OBJECT_IMAGE1D,
CL_MEM_OBJECT_IMAGE1D_BUFFER,
CL_MEM_OBJECT_IMAGE2D,
CL_MEM_OBJECT_IMAGE1D_ARRAY,
CL_MEM_OBJECT_IMAGE3D,
CL_MEM_OBJECT_IMAGE2D_ARRAY};
INSTANTIATE_TEST_CASE_P(
ImageArraySizeTest_Create,
CreateImageSize,
testing::ValuesIn(AllImageTypes));

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2017, 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/mem_obj/image.h"
#include "gtest/gtest.h"
using namespace OCLRT;
const char valueOfEmptyPixel = 0;
const char valueOfCopiedPixel = 1;
const char garbageValue = 2;
const int imageCount = 2;
const int imageDimension = 25;
auto const elementSize = 4;
class CopyImageTest : public testing::WithParamInterface<std::tuple<size_t, size_t> /*srcPitch, destPitch*/>,
public testing::Test {
public:
void SetUp() override {
std::tie(srcRowPitch, destRowPitch) = GetParam();
// clang-format off
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = imageDimension;
imageDesc.image_height = imageDimension;
imageDesc.image_depth = 0;
imageDesc.image_array_size = imageCount;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
lineWidth = imageDesc.image_width * elementSize;
srcSlicePitch = srcRowPitch * imageDimension;
destSlicePitch = destRowPitch * imageDimension;
srcPtrSize = srcSlicePitch * imageCount;
destPtrSize = destSlicePitch * imageCount;
srcPtr.reset(new char[srcPtrSize]);
destPtr.reset(new char[destPtrSize * 2]);
}
cl_image_desc imageDesc;
size_t srcRowPitch;
size_t srcSlicePitch;
size_t destRowPitch;
size_t destSlicePitch;
size_t srcPtrSize;
size_t destPtrSize;
size_t lineWidth;
std::unique_ptr<char> srcPtr;
std::unique_ptr<char> destPtr;
};
TEST_P(CopyImageTest, givenSrcAndDestPitchesWhenTransferDataIsCalledThenSpecificValuesAreCopied) {
memset(destPtr.get(), valueOfEmptyPixel, 2 * destPtrSize);
memset(srcPtr.get(), garbageValue, srcPtrSize);
for (size_t i = 0; i < imageCount; ++i) {
for (size_t j = 0; j < imageDimension; ++j) {
memset(srcPtr.get() + i * srcSlicePitch + j * srcRowPitch, valueOfCopiedPixel, lineWidth);
}
}
Image::transferData(srcPtr.get(), srcRowPitch, srcSlicePitch, destPtr.get(), destRowPitch, destSlicePitch, &imageDesc, elementSize, imageCount);
size_t unconfirmedCopies = 0;
//expect no garbage copied
for (size_t i = 0; i < 2 * destPtrSize; ++i) {
if (destPtr.get()[i] == valueOfCopiedPixel) {
unconfirmedCopies++;
}
EXPECT_NE(garbageValue, destPtr.get()[i]);
}
//expect copied to right locations
for (size_t i = 0; i < imageCount; ++i) {
for (size_t j = 0; j < imageDimension; ++j) {
for (size_t k = 0; k < lineWidth; ++k) {
EXPECT_EQ(valueOfCopiedPixel, destPtr.get()[i * destSlicePitch + j * destRowPitch + k]);
unconfirmedCopies--;
}
}
}
//expect copied only to destPtr
for (size_t i = 0; i < destPtrSize; ++i) {
EXPECT_EQ(valueOfEmptyPixel, destPtr.get()[destPtrSize + i]);
}
EXPECT_EQ(0u, unconfirmedCopies);
}
size_t valuesOfPitchesInCopyTests[] = {100, 101, 102};
INSTANTIATE_TEST_CASE_P(
CopyImageTests,
CopyImageTest,
testing::Combine(
testing::ValuesIn(valuesOfPitchesInCopyTests),
testing::ValuesIn(valuesOfPitchesInCopyTests)));

View File

@@ -0,0 +1,335 @@
/*
* Copyright (c) 2017, 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/helpers/surface_formats.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/mem_obj/image.h"
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
#include "igfxfmid.h"
extern GFXCORE_FAMILY renderCoreFamily;
using namespace OCLRT;
typedef decltype(&Image::redescribe) RedescribeMethod;
class ImageRedescribeTest : public testing::TestWithParam<std::tuple<RedescribeMethod, size_t, uint32_t>> {
public:
ImageRedescribeTest()
{
}
protected:
void SetUp() override {
cl_image_format imageFormat;
cl_image_desc imageDesc;
std::tie(redescribeMethod, indexImageFormat, ImageType) = this->GetParam();
std::stringstream streamTestString;
streamTestString << "Format: " << indexImageFormat;
testString = streamTestString.str();
auto &surfaceFormatInfo = readWriteSurfaceFormats[indexImageFormat];
// clang-format off
imageFormat = surfaceFormatInfo.OCLImageFormat;
auto imageHeight = ImageType == CL_MEM_OBJECT_IMAGE1D_ARRAY ? 0 : 32;
auto imageArrays = ImageType == CL_MEM_OBJECT_IMAGE1D_ARRAY || ImageType == CL_MEM_OBJECT_IMAGE2D_ARRAY ? 7 : 1;
imageDesc.image_type = ImageType;
imageDesc.image_width = 32;
imageDesc.image_height = imageHeight;
imageDesc.image_depth = 1;
imageDesc.image_array_size = imageArrays;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
retVal = CL_INVALID_VALUE;
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_NE(nullptr, image);
}
void TearDown() override {
delete image;
}
cl_int retVal = CL_SUCCESS;
MockContext context;
Image *image = nullptr;
size_t indexImageFormat = 0;
std::string testString;
RedescribeMethod redescribeMethod;
uint32_t ImageType;
};
TEST_P(ImageRedescribeTest, returnsImagePointer) {
auto imageNew = image->redescribe();
ASSERT_NE(image, imageNew) << testString;
EXPECT_NE(nullptr, imageNew) << testString;
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageHasUseHostPtrFlags) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_USE_HOST_PTR), imageNew->getFlags() & CL_MEM_USE_HOST_PTR) << testString;
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageHasSameAddress) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
EXPECT_EQ(image->getCpuAddress(), imageNew->getCpuAddress()) << testString;
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageHasNoFloatsOrHalfFloats) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
EXPECT_NE(static_cast<cl_channel_type>(CL_FLOAT), imageNew->getSurfaceFormatInfo().OCLImageFormat.image_channel_data_type) << testString;
EXPECT_NE(static_cast<cl_channel_type>(CL_HALF_FLOAT), imageNew->getSurfaceFormatInfo().OCLImageFormat.image_channel_data_type) << testString;
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageFormatHasSameImageElementSizeInBytes) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
if (redescribeMethod == &Image::redescribe) {
EXPECT_EQ(image->getSurfaceFormatInfo().ImageElementSizeInBytes,
imageNew->getSurfaceFormatInfo().ImageElementSizeInBytes)
<< testString;
} else {
EXPECT_EQ(1u, imageNew->getSurfaceFormatInfo().ImageElementSizeInBytes) << testString;
}
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageFormatHasNumberOfChannelsDependingOnBytesPerPixel) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
if (redescribeMethod == &Image::redescribe) {
size_t bytesPerPixel = image->getSurfaceFormatInfo().NumChannels * image->getSurfaceFormatInfo().PerChannelSizeInBytes;
size_t channelsExpected = 0;
switch (bytesPerPixel) {
case 1:
case 2:
case 4:
channelsExpected = 1;
break;
case 8:
channelsExpected = 2;
break;
case 16:
channelsExpected = 4;
break;
}
EXPECT_EQ(channelsExpected,
imageNew->getSurfaceFormatInfo().NumChannels)
<< testString;
} else {
EXPECT_EQ(1u, imageNew->getSurfaceFormatInfo().NumChannels) << testString;
}
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageFormatChannels_PerChannelSize_ElementSize_Jive) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
EXPECT_EQ(imageNew->getSurfaceFormatInfo().NumChannels * imageNew->getSurfaceFormatInfo().PerChannelSizeInBytes,
imageNew->getSurfaceFormatInfo().ImageElementSizeInBytes)
<< testString;
delete imageNew;
}
TEST_P(ImageRedescribeTest, newImageDimensionsConsistent) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew) << testString;
auto bytesWide = image->getSurfaceFormatInfo().ImageElementSizeInBytes * image->getImageDesc().image_width;
auto bytesWideNew = imageNew->getSurfaceFormatInfo().ImageElementSizeInBytes * imageNew->getImageDesc().image_width;
EXPECT_EQ(bytesWide, bytesWideNew) << testString;
EXPECT_EQ(imageNew->getImageDesc().image_height, image->getImageDesc().image_height);
EXPECT_EQ(imageNew->getImageDesc().image_array_size, image->getImageDesc().image_array_size);
EXPECT_EQ(imageNew->getImageDesc().image_depth, image->getImageDesc().image_depth);
EXPECT_EQ(imageNew->getImageDesc().image_type, image->getImageDesc().image_type);
EXPECT_EQ(imageNew->getQPitch(), image->getQPitch());
delete imageNew;
}
TEST_P(ImageRedescribeTest, VerifyCubeFaceIndices) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew);
ASSERT_EQ(imageNew->getCubeFaceIndex(), __GMM_NO_CUBE_MAP);
delete imageNew;
for (uint32_t n = __GMM_CUBE_FACE_POS_X; n < __GMM_MAX_CUBE_FACE; n++) {
image->setCubeFaceIndex(n);
auto imageNew2 = image->redescribe();
ASSERT_NE(nullptr, imageNew2);
ASSERT_EQ(imageNew2->getCubeFaceIndex(), n);
delete imageNew2;
}
for (uint32_t n = __GMM_CUBE_FACE_POS_X; n < __GMM_MAX_CUBE_FACE; n++) {
image->setCubeFaceIndex(n);
auto imageNew2 = image->redescribeFillImage();
ASSERT_NE(nullptr, imageNew2);
ASSERT_EQ(imageNew2->getCubeFaceIndex(), n);
delete imageNew2;
}
}
TEST_P(ImageRedescribeTest, newImageDoesNotExceedMaxSizes) {
cl_image_format imageFormat;
cl_image_desc imageDesc;
auto device = std::unique_ptr<Device>(DeviceHelper<>::create(platformDevices[0]));
const auto &caps = device->getDeviceInfo();
auto memoryManager = (OsAgnosticMemoryManager *)context.getMemoryManager();
memoryManager->turnOnFakingBigAllocations();
auto &surfaceFormatInfo = readWriteSurfaceFormats[indexImageFormat];
imageFormat = surfaceFormatInfo.OCLImageFormat;
auto imageWidth = 1;
auto imageHeight = 1;
auto imageArrays = ImageType == CL_MEM_OBJECT_IMAGE1D_ARRAY || ImageType == CL_MEM_OBJECT_IMAGE2D_ARRAY ? 7 : 1;
size_t maxImageWidth = 0;
size_t maxImageHeight = 0;
switch (ImageType) {
case CL_MEM_OBJECT_IMAGE1D:
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
imageWidth = 16384;
maxImageWidth = static_cast<size_t>(caps.maxMemAllocSize);
maxImageHeight = 1;
break;
case CL_MEM_OBJECT_IMAGE2D:
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
imageHeight = 16384;
maxImageWidth = caps.image2DMaxWidth;
maxImageHeight = caps.image2DMaxHeight;
break;
case CL_MEM_OBJECT_IMAGE3D:
imageHeight = 16384;
maxImageWidth = caps.image3DMaxWidth;
maxImageHeight = caps.image3DMaxHeight;
break;
}
imageDesc.image_type = ImageType;
imageDesc.image_width = imageWidth;
imageDesc.image_height = imageHeight;
imageDesc.image_depth = 1;
imageDesc.image_array_size = imageArrays;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto bigImage = std::unique_ptr<Image>(Image::create(&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal));
auto imageNew = (bigImage.get()->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew);
if (redescribeMethod == &Image::redescribe) {
EXPECT_GE(maxImageWidth,
imageNew->getImageDesc().image_width);
EXPECT_GE(maxImageHeight,
imageNew->getImageDesc().image_height);
}
delete imageNew;
}
static RedescribeMethod redescribeMethods[] = {
&Image::redescribe};
static uint32_t ImageType[] = {
CL_MEM_OBJECT_IMAGE1D,
CL_MEM_OBJECT_IMAGE2D,
CL_MEM_OBJECT_IMAGE1D_ARRAY,
CL_MEM_OBJECT_IMAGE2D_ARRAY};
typedef decltype(numReadWriteSurfaceFormats) ReadWriteSurfaceFormatsCountType;
INSTANTIATE_TEST_CASE_P(
Redescribe,
ImageRedescribeTest,
testing::Combine(
::testing::ValuesIn(redescribeMethods),
::testing::Range(static_cast<ReadWriteSurfaceFormatsCountType>(0u), numReadWriteSurfaceFormats),
::testing::ValuesIn(ImageType)));
typedef ImageRedescribeTest ImageRedescribeTestWidth;
TEST_P(ImageRedescribeTestWidth, newImageFormatHasSameWidth) {
auto imageNew = (image->*redescribeMethod)();
ASSERT_NE(nullptr, imageNew);
EXPECT_EQ(image->getImageDesc().image_width,
imageNew->getImageDesc().image_width);
delete imageNew;
}
INSTANTIATE_TEST_CASE_P(
Redescribe,
ImageRedescribeTestWidth,
testing::Combine(
::testing::Values(&Image::redescribe),
::testing::Range(static_cast<ReadWriteSurfaceFormatsCountType>(0u), numReadWriteSurfaceFormats),
::testing::ValuesIn(ImageType)));

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2017, 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 "gtest/gtest.h"
#include "runtime/command_queue/command_queue.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/fixtures/image_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_event.h"
#include "unit_tests/fixtures/device_fixture.h"
using namespace OCLRT;
class MockCommandQueue : public CommandQueue {
public:
MockCommandQueue(Context *context) : CommandQueue(context, nullptr, 0){};
cl_int enqueueWriteImage(Image *dstImage, cl_bool blockingWrite,
const size_t *origin, const size_t *region,
size_t inputRowPitch, size_t inputSlicePitch,
const void *ptr, cl_uint numEventsInWaitList,
const cl_event *eventWaitList,
cl_event *event) override {
passedBlockingWrite = blockingWrite;
passedPtr = (void *)ptr;
enqueueWriteImageCalled++;
return CL_SUCCESS;
}
cl_int finish(bool dcFlush) override {
EXPECT_TRUE(dcFlush);
finishCalled++;
return CL_SUCCESS;
}
void *passedPtr = nullptr;
cl_bool passedBlockingWrite = CL_INVALID_VALUE;
unsigned int enqueueWriteImageCalled = 0;
unsigned int finishCalled = 0;
};
class ImageUnmapTest : public ::testing::Test {
public:
void SetUp() override {
image.reset(ImageHelper<ImageReadOnly<Image3dDefaults>>::create(&context));
}
MockContext context;
std::unique_ptr<Image> image;
};
TEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledThenEnqueueNonBlockingMapImage) {
std::unique_ptr<MockCommandQueue> commandQueue(new MockCommandQueue(&context));
void *ptr = alignedMalloc(MemoryConstants::cacheLineSize, MemoryConstants::cacheLineSize);
image->setAllocatedMappedPtr(ptr);
image->unmapObj(commandQueue.get(), ptr, 0, nullptr, nullptr);
EXPECT_EQ(ptr, commandQueue->passedPtr);
EXPECT_EQ((cl_bool)CL_FALSE, commandQueue->passedBlockingWrite);
EXPECT_EQ(1u, commandQueue->enqueueWriteImageCalled);
EXPECT_EQ(ptr, image->getMappedPtr());
EXPECT_EQ(ptr, image->getAllocatedMappedPtr());
image->releaseAllocatedMappedPtr();
EXPECT_EQ(nullptr, image->getMappedPtr());
}
TEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithMemUseHostPtrAndWithoutEventsThenFinishIsCalled) {
std::unique_ptr<MockCommandQueue> commandQueue(new MockCommandQueue(&context));
image.reset(ImageHelper<ImageUseHostPtr<Image3dDefaults>>::create(&context));
image->unmapObj(commandQueue.get(), nullptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, commandQueue->finishCalled);
}
TEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithoutMemUseHostPtrThenFinishIsCalled) {
std::unique_ptr<MockCommandQueue> commandQueue(new MockCommandQueue(&context));
image->unmapObj(commandQueue.get(), nullptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, commandQueue->finishCalled);
}
TEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithMemUseHostPtrAndWithNotReadyEventsThenFinishIsNotCalled) {
std::unique_ptr<MockCommandQueue> commandQueue(new MockCommandQueue(&context));
image.reset(ImageHelper<ImageUseHostPtr<Image3dDefaults>>::create(&context));
MockEvent<UserEvent> mockEvent(&context);
mockEvent.setStatus(Event::eventNotReady);
cl_event clEvent = &mockEvent;
image->unmapObj(commandQueue.get(), nullptr, 1, &clEvent, nullptr);
EXPECT_EQ(0u, commandQueue->finishCalled);
}
TEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithMemUseHostPtrAndWithoutNotReadyEventsThenFinishIsCalled) {
std::unique_ptr<MockCommandQueue> commandQueue(new MockCommandQueue(&context));
image.reset(ImageHelper<ImageUseHostPtr<Image3dDefaults>>::create(&context));
MockEvent<UserEvent> mockEvent(&context);
mockEvent.setStatus(0);
cl_event clEvent = &mockEvent;
image->unmapObj(commandQueue.get(), nullptr, 1, &clEvent, nullptr);
EXPECT_EQ(1u, commandQueue->finishCalled);
}
TEST_F(ImageUnmapTest, givenImageWhenEnqueueMapImageIsCalledTwiceThenAllocatedMemoryPtrIsNotOverridden) {
cl_int retVal;
size_t origin[] = {0, 0, 0};
size_t region[] = {0, 0, 0};
std::unique_ptr<MockDevice> device(DeviceHelper<>::create());
std::unique_ptr<CommandQueue> commandQueue(CommandQueue::create(&context, device.get(), nullptr, retVal));
cl_mem clImage = (cl_mem)(image.get());
commandQueue->enqueueMapImage(clImage, CL_FALSE, 0, origin, region, nullptr, nullptr, 0, nullptr, nullptr, retVal);
EXPECT_NE(nullptr, image->getAllocatedMappedPtr());
void *ptr = image->getAllocatedMappedPtr();
EXPECT_EQ(alignUp(ptr, MemoryConstants::pageSize), ptr);
commandQueue->enqueueMapImage(clImage, CL_FALSE, 0, origin, region, nullptr, nullptr, 0, nullptr, nullptr, retVal);
EXPECT_EQ(ptr, image->getAllocatedMappedPtr());
image->unmapObj(commandQueue.get(), ptr, 0, nullptr, nullptr);
image->releaseAllocatedMappedPtr();
EXPECT_EQ(nullptr, image->getMappedPtr());
image.reset(nullptr);
}

View File

@@ -0,0 +1,840 @@
/*
* Copyright (c) 2017, 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 "hw_cmds.h"
#include "runtime/gmm_helper/gmm_helper.h"
#include "runtime/helpers/surface_formats.h"
#include "runtime/helpers/ptr_math.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/memory_manager/graphics_allocation.h"
#include "runtime/kernel/kernel.h"
#include "runtime/mem_obj/image.h"
#include "runtime/memory_manager/surface.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/image_fixture.h"
#include "unit_tests/mocks/mock_kernel.h"
#include "unit_tests/mocks/mock_program.h"
#include "unit_tests/mocks/mock_gmm_resource_info.h"
#include "gmock/gmock.h"
#include "test.h"
using namespace OCLRT;
using namespace ::testing;
class ImageSetArgTest : public DeviceFixture,
public testing::Test {
public:
ImageSetArgTest()
{
memset(&kernelHeader, 0, sizeof(kernelHeader));
}
protected:
template <typename FamilyType>
void SetupChannels(int imgChannelOrder) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
expectedChannelRed = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
expectedChannelGreen = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN_GREEN;
expectedChannelBlue = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE_BLUE;
if (imgChannelOrder == CL_A) {
expectedChannelRed = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO;
expectedChannelGreen = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN_ZERO;
expectedChannelBlue = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE_ZERO;
} else if (imgChannelOrder == CL_RA ||
imgChannelOrder == CL_R ||
imgChannelOrder == CL_Rx) {
expectedChannelGreen = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN_ZERO;
expectedChannelBlue = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE_ZERO;
} else if (imgChannelOrder == CL_RG ||
imgChannelOrder == CL_RGx) {
expectedChannelBlue = RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE_ZERO;
}
}
void SetUp() override {
DeviceFixture::SetUp();
pKernelInfo = KernelInfo::create();
// define kernel info
kernelHeader.SurfaceStateHeapSize = sizeof(surfaceStateHeap);
pKernelInfo->heapInfo.pSsh = surfaceStateHeap;
pKernelInfo->heapInfo.pKernelHeader = &kernelHeader;
pKernelInfo->usesSsh = true;
// setup kernel arg offsets
pKernelInfo->kernelArgInfo.resize(2);
pKernelInfo->kernelArgInfo[1].offsetHeap = 0x00;
pKernelInfo->kernelArgInfo[0].offsetHeap = 0x40;
pKernelInfo->kernelArgInfo[1].isImage = true;
pKernelInfo->kernelArgInfo[0].isImage = true;
pKernel = new MockKernel(&program, *pKernelInfo, *pDevice);
ASSERT_NE(nullptr, pKernel);
ASSERT_EQ(CL_SUCCESS, pKernel->initialize());
pKernel->setKernelArgHandler(0, &Kernel::setArgImage);
pKernel->setKernelArgHandler(1, &Kernel::setArgImage);
context = new MockContext(pDevice);
srcImage = Image3dHelper<>::create(context);
ASSERT_NE(nullptr, srcImage);
expectedChannelRed = 0;
expectedChannelGreen = 0;
expectedChannelBlue = 0;
}
void TearDown() override {
delete pKernelInfo;
delete srcImage;
delete pKernel;
delete context;
DeviceFixture::TearDown();
}
cl_int retVal = CL_SUCCESS;
MockContext *context;
MockProgram program;
MockKernel *pKernel = nullptr;
SKernelBinaryHeaderCommon kernelHeader;
KernelInfo *pKernelInfo = nullptr;
char surfaceStateHeap[0x80];
Image *srcImage = nullptr;
int expectedChannelRed;
int expectedChannelGreen;
int expectedChannelBlue;
};
HWTEST_F(ImageSetArgTest, setKernelArgImage) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
srcImage->setImageArg(const_cast<RENDER_SURFACE_STATE *>(surfaceState), false);
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
EXPECT_EQ(srcImage->getCpuAddress(), surfaceAddress);
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(0u, surfaces.size());
}
HWTEST_F(ImageSetArgTest, setKernelArgImageUsingMediaBlockImage) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState;
srcImage->setImageArg(&surfaceState, true);
auto computedWidth = surfaceState.getWidth();
auto expectedWidth = (srcImage->getImageDesc().image_width * srcImage->getSurfaceFormatInfo().ImageElementSizeInBytes) / sizeof(uint32_t);
EXPECT_EQ(expectedWidth, computedWidth);
}
HWTEST_F(ImageSetArgTest, setKernelArgImageUsingNormalImage) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState;
srcImage->setImageArg(&surfaceState, true);
auto computedWidth = surfaceState.getWidth();
EXPECT_EQ(srcImage->getImageDesc().image_width, computedWidth);
}
HWTEST_F(ImageSetArgTest, givenCubeMapIndexWhenSetKernelArgImageIsCalledThenModifySurfaceState) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
uint32_t cubeFaceIndex = 2;
Image *src2dImage = Image2dHelper<>::create(context);
src2dImage->setCubeFaceIndex(cubeFaceIndex);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
src2dImage->setImageArg(const_cast<RENDER_SURFACE_STATE *>(surfaceState), false);
auto renderTargetViewExtent = surfaceState->getRenderTargetViewExtent();
auto minimumArrayElement = surfaceState->getMinimumArrayElement();
auto isImageArray = surfaceState->getSurfaceArray();
auto depth = surfaceState->getDepth();
EXPECT_EQ(renderTargetViewExtent, 1u);
EXPECT_EQ(minimumArrayElement, cubeFaceIndex);
EXPECT_EQ(depth, (__GMM_MAX_CUBE_FACE - cubeFaceIndex));
EXPECT_TRUE(isImageArray);
delete src2dImage;
}
HWTEST_F(ImageSetArgTest, givenNonCubeMapIndexWhenSetKernelArgImageIsCalledThenDontModifySurfaceState) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
EXPECT_EQ(srcImage->getCubeFaceIndex(), __GMM_NO_CUBE_MAP);
srcImage->setImageArg(const_cast<RENDER_SURFACE_STATE *>(surfaceState), false);
auto renderTargetViewExtent = surfaceState->getRenderTargetViewExtent();
auto minimumArrayElement = surfaceState->getMinimumArrayElement();
auto isImageArray = surfaceState->getSurfaceArray();
auto depth = surfaceState->getDepth();
auto hAlign = static_cast<uint32_t>(surfaceState->getSurfaceHorizontalAlignment());
auto vAlign = static_cast<uint32_t>(surfaceState->getSurfaceVerticalAlignment());
auto expectedHAlign = static_cast<uint32_t>(RENDER_SURFACE_STATE::SURFACE_HORIZONTAL_ALIGNMENT_HALIGN_4);
auto expectedVAlign = static_cast<uint32_t>(RENDER_SURFACE_STATE::SURFACE_VERTICAL_ALIGNMENT_VALIGN_4);
// 3D image
EXPECT_EQ(renderTargetViewExtent, srcImage->getImageDesc().image_depth);
EXPECT_EQ(minimumArrayElement, 0u);
EXPECT_EQ(depth, srcImage->getImageDesc().image_depth);
EXPECT_EQ(expectedHAlign, hAlign);
EXPECT_EQ(expectedVAlign, vAlign);
EXPECT_FALSE(isImageArray);
}
HWTEST_F(ImageSetArgTest, givenOffsetedBufferWhenSetKernelArgImageIscalledThenFullGPuPointerIsPatched) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
auto graphicsAllocation = srcImage->getGraphicsAllocation();
graphicsAllocation->gpuBaseAddress = 12345u;
srcImage->setImageArg(const_cast<RENDER_SURFACE_STATE *>(surfaceState), false);
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
EXPECT_EQ(srcImage->getCpuAddress(), surfaceAddress);
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(0u, surfaces.size());
}
HWTEST_F(ImageSetArgTest, clSetKernelArgImage) {
auto imageMocs = Gmm::getMOCS(GMM_RESOURCE_USAGE_OCL_IMAGE);
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
cl_mem memObj = srcImage;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
size_t rPitch = srcImage->getImageDesc().image_row_pitch;
SetupChannels<FamilyType>(srcImage->getImageFormat().image_channel_order);
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
EXPECT_EQ(srcImage->getCpuAddress(), surfaceAddress);
EXPECT_EQ(srcImage->getImageDesc().image_width, surfaceState->getWidth());
EXPECT_EQ(srcImage->getImageDesc().image_height, surfaceState->getHeight());
EXPECT_EQ(srcImage->getImageDesc().image_depth, surfaceState->getDepth());
EXPECT_EQ(srcImage->getImageDesc().image_depth, surfaceState->getRenderTargetViewExtent());
EXPECT_EQ(rPitch, surfaceState->getSurfacePitch());
EXPECT_EQ(0u, surfaceState->getSurfaceQpitch() % 4);
EXPECT_EQ(srcImage->getSurfaceFormatInfo().GenxSurfaceFormat, (GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceFormat());
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_3D, surfaceState->getSurfaceType());
EXPECT_EQ(expectedChannelRed, surfaceState->getShaderChannelSelectRed());
EXPECT_EQ(expectedChannelGreen, surfaceState->getShaderChannelSelectGreen());
EXPECT_EQ(expectedChannelBlue, surfaceState->getShaderChannelSelectBlue());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ALPHA, surfaceState->getShaderChannelSelectAlpha());
EXPECT_EQ(imageMocs, surfaceState->getMemoryObjectControlState());
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
}
HWTEST_F(ImageSetArgTest, givenImage2DWithMipmapsWhenSetKernelArgIsCalledThenMipLevelIsSet) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
cl_mem memObj = srcImage;
int mipLevel = 1;
srcImage->setMipLevel(mipLevel);
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
EXPECT_EQ((uint32_t)mipLevel, surfaceState->getSurfaceMinLod());
}
HWTEST_F(ImageSetArgTest, clSetKernelArgImage2Darray) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
Image *image2Darray = Image2dArrayHelper<>::create(context);
cl_mem memObj = image2Darray;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
size_t rPitch = srcImage->getImageDesc().image_row_pitch;
SetupChannels<FamilyType>(image2Darray->getImageFormat().image_channel_order);
EXPECT_EQ(image2Darray->getCpuAddress(), surfaceAddress);
EXPECT_EQ(image2Darray->getImageDesc().image_width, surfaceState->getWidth());
EXPECT_EQ(image2Darray->getImageDesc().image_height, surfaceState->getHeight());
EXPECT_EQ(image2Darray->getImageDesc().image_array_size, surfaceState->getDepth());
EXPECT_EQ(image2Darray->getImageDesc().image_array_size, surfaceState->getRenderTargetViewExtent());
EXPECT_EQ(rPitch, surfaceState->getSurfacePitch());
EXPECT_EQ(0u, surfaceState->getSurfaceQpitch() % 4);
EXPECT_EQ(image2Darray->getSurfaceFormatInfo().GenxSurfaceFormat, (GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceFormat());
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_2D, surfaceState->getSurfaceType());
EXPECT_TRUE((GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceArray());
EXPECT_EQ(expectedChannelRed, surfaceState->getShaderChannelSelectRed());
EXPECT_EQ(expectedChannelGreen, surfaceState->getShaderChannelSelectGreen());
EXPECT_EQ(expectedChannelBlue, surfaceState->getShaderChannelSelectBlue());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ALPHA, surfaceState->getShaderChannelSelectAlpha());
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
delete image2Darray;
}
HWTEST_F(ImageSetArgTest, clSetKernelArgImage1Darray) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
Image *image1Darray = Image1dArrayHelper<>::create(context);
cl_mem memObj = image1Darray;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
SetupChannels<FamilyType>(image1Darray->getImageFormat().image_channel_order);
EXPECT_EQ(image1Darray->getCpuAddress(), surfaceAddress);
EXPECT_EQ(image1Darray->getImageDesc().image_width, surfaceState->getWidth());
EXPECT_EQ(1u, surfaceState->getHeight());
EXPECT_EQ(image1Darray->getImageDesc().image_array_size, surfaceState->getDepth());
EXPECT_EQ(image1Darray->getImageDesc().image_array_size, surfaceState->getRenderTargetViewExtent());
EXPECT_EQ(image1Darray->getImageDesc().image_row_pitch, surfaceState->getSurfacePitch());
EXPECT_EQ(0u, surfaceState->getSurfaceQpitch() % 4);
EXPECT_EQ(image1Darray->getGraphicsAllocation()->gmm->queryQPitch(::renderCoreFamily, GMM_RESOURCE_TYPE::RESOURCE_1D), surfaceState->getSurfaceQpitch());
EXPECT_EQ(image1Darray->getSurfaceFormatInfo().GenxSurfaceFormat, (GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceFormat());
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_1D, surfaceState->getSurfaceType());
EXPECT_TRUE((GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceArray());
EXPECT_EQ(expectedChannelRed, surfaceState->getShaderChannelSelectRed());
EXPECT_EQ(expectedChannelGreen, surfaceState->getShaderChannelSelectGreen());
EXPECT_EQ(expectedChannelBlue, surfaceState->getShaderChannelSelectBlue());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ALPHA, surfaceState->getShaderChannelSelectAlpha());
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
delete image1Darray;
}
HWTEST_F(ImageSetArgTest, givenMcsAllocationWhenSetArgIsCalledThenProgramAuxFields) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
McsSurfaceInfo msi = {10, 20, 3};
auto mcsAlloc = context->getMemoryManager()->allocateGraphicsMemory(4096);
cl_image_desc imgDesc = Image2dDefaults::imageDesc;
imgDesc.num_samples = 8;
auto image = Image2dHelper<>::create(context, &imgDesc);
image->setMcsSurfaceInfo(msi);
image->setMcsAllocation(mcsAlloc);
cl_mem memObj = image;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
EXPECT_FALSE(Image::isDepthFormat(image->getImageFormat()));
EXPECT_TRUE(surfaceState->getMultisampledSurfaceStorageFormat() ==
RENDER_SURFACE_STATE::MULTISAMPLED_SURFACE_STORAGE_FORMAT::MULTISAMPLED_SURFACE_STORAGE_FORMAT_MSS);
EXPECT_TRUE(surfaceState->getAuxiliarySurfaceMode() == (typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE)1);
EXPECT_EQ(msi.pitch, surfaceState->getAuxiliarySurfacePitch());
EXPECT_EQ(msi.qPitch, surfaceState->getAuxiliarySurfaceQpitch());
EXPECT_EQ(msi.multisampleCount, static_cast<uint32_t>(surfaceState->getNumberOfMultisamples()));
EXPECT_EQ(mcsAlloc->getGpuAddress(), surfaceState->getAuxiliarySurfaceBaseAddress());
delete image;
}
HWTEST_F(ImageSetArgTest, givenDepthFormatWhenSetArgIsCalledThenProgramAuxFields) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
McsSurfaceInfo msi = {0, 0, 3};
cl_image_desc imgDesc = Image2dDefaults::imageDesc;
imgDesc.num_samples = 8;
cl_image_format imgFormat = {CL_DEPTH, CL_FLOAT};
auto image = Image2dHelper<>::create(context, &imgDesc, &imgFormat);
image->setMcsSurfaceInfo(msi);
cl_mem memObj = image;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
EXPECT_TRUE(Image::isDepthFormat(image->getImageFormat()));
EXPECT_TRUE(surfaceState->getMultisampledSurfaceStorageFormat() ==
RENDER_SURFACE_STATE::MULTISAMPLED_SURFACE_STORAGE_FORMAT::MULTISAMPLED_SURFACE_STORAGE_FORMAT_DEPTH_STENCIL);
EXPECT_TRUE(surfaceState->getAuxiliarySurfaceMode() == (typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE)0);
EXPECT_EQ(1u, surfaceState->getAuxiliarySurfacePitch());
EXPECT_EQ(0u, surfaceState->getAuxiliarySurfaceQpitch());
EXPECT_EQ(msi.multisampleCount, static_cast<uint32_t>(surfaceState->getNumberOfMultisamples()));
EXPECT_EQ(0u, surfaceState->getAuxiliarySurfaceBaseAddress());
delete image;
}
HWTEST_F(ImageSetArgTest, clSetKernelArgImage1Dbuffer) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
auto buffer = clCreateBuffer(context, 0, 4096 * 10, nullptr, nullptr);
ASSERT_NE(nullptr, buffer);
cl_image_desc imageDesc = {0};
imageDesc.buffer = buffer;
imageDesc.image_width = 6400;
// 2 * (1 << 21) + 5 * (1 << 7) + 0;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
cl_image_format imageFormat = {0};
imageFormat.image_channel_data_type = CL_FLOAT;
imageFormat.image_channel_order = CL_RGBA;
auto imageFromBuffer = clCreateImage(context, 0, &imageFormat, &imageDesc, nullptr, nullptr);
ASSERT_NE(nullptr, imageFromBuffer);
retVal = clSetKernelArg(
pKernel,
0,
sizeof(imageFromBuffer),
&imageFromBuffer);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
auto image = castToObject<Image>(imageFromBuffer);
EXPECT_EQ((void *)((uintptr_t)image->getGraphicsAllocation()->getGpuAddress()), surfaceAddress);
// Width is 7 bits
EXPECT_EQ(128u, surfaceState->getWidth());
// Height is 14 bits
EXPECT_EQ(50u, surfaceState->getHeight());
// Depth is 11 bits
EXPECT_EQ(1u, surfaceState->getDepth());
EXPECT_EQ(1u, surfaceState->getRenderTargetViewExtent());
EXPECT_EQ(0u, surfaceState->getSurfaceQpitch() % 4);
EXPECT_EQ(0u, surfaceState->getSurfaceQpitch());
EXPECT_EQ(image->getSurfaceFormatInfo().GenxSurfaceFormat, (GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceFormat());
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_BUFFER, surfaceState->getSurfaceType());
EXPECT_FALSE((GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceArray());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, surfaceState->getShaderChannelSelectRed());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN_GREEN, surfaceState->getShaderChannelSelectGreen());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE_BLUE, surfaceState->getShaderChannelSelectBlue());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ALPHA, surfaceState->getShaderChannelSelectAlpha());
clReleaseMemObject(imageFromBuffer);
clReleaseMemObject(buffer);
}
HWTEST_F(ImageSetArgTest, clSetKernelArgImageWithCLLuminanceFormat) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
Image *luminanceImage = Image3dHelper<LuminanceImage>::create(context);
cl_mem memObj = luminanceImage;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
//for CL_LUMINANCE format we override channels to RED to be spec complaint.
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, surfaceState->getShaderChannelSelectRed());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN_RED, surfaceState->getShaderChannelSelectGreen());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE_RED, surfaceState->getShaderChannelSelectBlue());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ALPHA, surfaceState->getShaderChannelSelectAlpha());
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
delete luminanceImage;
}
HWTEST_F(ImageSetArgTest, getKernelArgShouldReturnImage) {
cl_mem memObj = srcImage;
retVal = pKernel->setArg(
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(memObj, pKernel->getKernelArg(0));
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
}
HWTEST_F(ImageSetArgTest, givenRenderCompressedResourceWhenSettingImgArgThenSetCorrectAuxParams) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
typedef typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE AUXILIARY_SURFACE_MODE;
auto surfaceState = RENDER_SURFACE_STATE::sInit();
auto gmm = srcImage->getGraphicsAllocation()->gmm;
auto mockGmmResInfo = reinterpret_cast<NiceMock<MockGmmResourceInfo> *>(gmm->gmmResourceInfo.get());
gmm->isRenderCompressed = true;
uint32_t expectedRenderAuxPitchTiles = 30;
uint32_t expectedAuxQPitch = 60;
uint64_t expectedAuxSurfaceOffset = 0x10000;
EXPECT_CALL(*mockGmmResInfo, getRenderAuxPitchTiles()).Times(1).WillRepeatedly(Return(expectedRenderAuxPitchTiles));
EXPECT_CALL(*mockGmmResInfo, getAuxQPitch()).Times(1).WillRepeatedly(Return(expectedAuxQPitch));
EXPECT_CALL(*mockGmmResInfo, getUnifiedAuxSurfaceOffset(GMM_UNIFIED_AUX_TYPE::GMM_AUX_CCS)).Times(1).WillRepeatedly(Return(expectedAuxSurfaceOffset));
srcImage->setImageArg(&surfaceState, false);
EXPECT_TRUE(surfaceState.getAuxiliarySurfaceMode() == (typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE)5);
EXPECT_EQ(expectedRenderAuxPitchTiles, surfaceState.getAuxiliarySurfacePitch());
EXPECT_EQ(expectedAuxQPitch, surfaceState.getAuxiliarySurfaceQpitch());
EXPECT_EQ(surfaceState.getSurfaceBaseAddress() + expectedAuxSurfaceOffset, surfaceState.getAuxiliarySurfaceBaseAddress());
}
HWTEST_F(ImageSetArgTest, givenNonRenderCompressedResourceWhenSettingImgArgThenDontSetAuxParams) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
typedef typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE AUXILIARY_SURFACE_MODE;
auto surfaceState = RENDER_SURFACE_STATE::sInit();
auto gmm = srcImage->getGraphicsAllocation()->gmm;
auto mockGmmResInfo = reinterpret_cast<NiceMock<MockGmmResourceInfo> *>(gmm->gmmResourceInfo.get());
gmm->isRenderCompressed = false;
EXPECT_CALL(*mockGmmResInfo, getRenderAuxPitchTiles()).Times(0);
EXPECT_CALL(*mockGmmResInfo, getAuxQPitch()).Times(0);
EXPECT_CALL(*mockGmmResInfo, getUnifiedAuxSurfaceOffset(_)).Times(0);
srcImage->setImageArg(&surfaceState, false);
EXPECT_TRUE(surfaceState.getAuxiliarySurfaceMode() == AUXILIARY_SURFACE_MODE::AUXILIARY_SURFACE_MODE_AUX_NONE);
EXPECT_EQ(1u, surfaceState.getAuxiliarySurfacePitch());
EXPECT_EQ(0u, surfaceState.getAuxiliarySurfaceQpitch());
EXPECT_EQ(0u, surfaceState.getAuxiliarySurfaceBaseAddress());
}
/* cl_intel_media_block_io */
class ImageMediaBlockSetArgTest : public ImageSetArgTest {
protected:
void SetUp() override {
DeviceFixture::SetUp();
pKernelInfo = KernelInfo::create();
// define kernel info
kernelHeader.SurfaceStateHeapSize = sizeof(surfaceStateHeap);
pKernelInfo->heapInfo.pSsh = surfaceStateHeap;
pKernelInfo->heapInfo.pKernelHeader = &kernelHeader;
pKernelInfo->usesSsh = true;
// setup kernel arg offsets
pKernelInfo->kernelArgInfo.resize(2);
pKernelInfo->kernelArgInfo[1].offsetHeap = 0x00;
pKernelInfo->kernelArgInfo[0].offsetHeap = 0x40;
pKernelInfo->kernelArgInfo[1].isImage = true;
pKernelInfo->kernelArgInfo[0].isImage = true;
pKernelInfo->kernelArgInfo[1].isMediaBlockImage = true;
pKernelInfo->kernelArgInfo[0].isMediaBlockImage = true;
pKernel = new MockKernel(&program, *pKernelInfo, *pDevice);
ASSERT_NE(nullptr, pKernel);
ASSERT_EQ(CL_SUCCESS, pKernel->initialize());
pKernel->setKernelArgHandler(0, &Kernel::setArgImage);
pKernel->setKernelArgHandler(1, &Kernel::setArgImage);
context = new MockContext(pDevice);
srcImage = Image3dHelper<>::create(context);
ASSERT_NE(nullptr, srcImage);
}
};
HWTEST_F(ImageMediaBlockSetArgTest, clSetKernelArgImage) {
auto imageMocs = Gmm::getMOCS(GMM_RESOURCE_USAGE_OCL_IMAGE);
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
cl_mem memObj = srcImage;
retVal = clSetKernelArg(
pKernel,
0,
sizeof(memObj),
&memObj);
ASSERT_EQ(CL_SUCCESS, retVal);
auto surfaceState = reinterpret_cast<const RENDER_SURFACE_STATE *>(
ptrOffset(pKernel->getSurfaceStateHeap(),
pKernelInfo->kernelArgInfo[0].offsetHeap));
size_t rPitch = srcImage->getImageDesc().image_row_pitch;
void *surfaceAddress = reinterpret_cast<void *>(surfaceState->getSurfaceBaseAddress());
EXPECT_EQ(srcImage->getCpuAddress(), surfaceAddress);
uint32_t element_size = static_cast<uint32_t>(srcImage->getSurfaceFormatInfo().ImageElementSizeInBytes);
SetupChannels<FamilyType>(srcImage->getImageFormat().image_channel_order);
EXPECT_EQ(srcImage->getImageDesc().image_width * element_size / sizeof(uint32_t), surfaceState->getWidth());
EXPECT_EQ(srcImage->getImageDesc().image_height, surfaceState->getHeight());
EXPECT_EQ(srcImage->getImageDesc().image_depth, surfaceState->getDepth());
EXPECT_EQ(srcImage->getImageDesc().image_depth, surfaceState->getRenderTargetViewExtent());
EXPECT_EQ(rPitch, surfaceState->getSurfacePitch());
EXPECT_EQ(0u, surfaceState->getSurfaceQpitch() % 4);
EXPECT_EQ(srcImage->getSurfaceFormatInfo().GenxSurfaceFormat, (GFX3DSTATE_SURFACEFORMAT)surfaceState->getSurfaceFormat());
EXPECT_EQ(RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_3D, surfaceState->getSurfaceType());
EXPECT_EQ(expectedChannelRed, surfaceState->getShaderChannelSelectRed());
EXPECT_EQ(expectedChannelGreen, surfaceState->getShaderChannelSelectGreen());
EXPECT_EQ(expectedChannelBlue, surfaceState->getShaderChannelSelectBlue());
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ALPHA, surfaceState->getShaderChannelSelectAlpha());
EXPECT_EQ(imageMocs, surfaceState->getMemoryObjectControlState());
std::vector<Surface *> surfaces;
pKernel->getResidency(surfaces);
EXPECT_EQ(1u, surfaces.size());
for (auto &surface : surfaces) {
delete surface;
}
}
typedef ImageSetArgTest ImageShaderChanelValueTest;
HWTEST_F(ImageShaderChanelValueTest, ChannelA) {
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
int outputChannel = 0;
int inputChannel = 0;
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_A);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_A);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_A);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_A);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
}
HWTEST_F(ImageShaderChanelValueTest, ChannelRA) {
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
int outputChannel = 0;
int inputChannel = 0;
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_R);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_R);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_R);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_R);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_Rx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_Rx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_Rx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_Rx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
}
HWTEST_F(ImageShaderChanelValueTest, ChannelRGA) {
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
int outputChannel = 0;
int inputChannel = 0;
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RG);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RG);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RG);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RG);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ZERO, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGx);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN, outputChannel);
}
HWTEST_F(ImageShaderChanelValueTest, ChannelRGBA) {
typedef typename FamilyType::RENDER_SURFACE_STATE SURFACE_STATE;
int outputChannel = 0;
int inputChannel = 0;
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGBA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_ALPHA, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGBA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_RED, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGBA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_GREEN, outputChannel);
inputChannel = SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE;
outputChannel = ImageHw<FamilyType>::getShaderChannelValue(inputChannel, CL_RGBA);
EXPECT_EQ(SURFACE_STATE::SHADER_CHANNEL_SELECT_RED_BLUE, outputChannel);
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2017, 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/helpers/surface_formats.h"
#include "runtime/mem_obj/image.h"
#include "gtest/gtest.h"
using namespace OCLRT;
typedef decltype(numSnormSurfaceFormats) SnormSurfaceFormatsCountType;
class GetSurfaceFormatTest : public ::testing::TestWithParam<std::tuple<size_t /*format index*/, uint64_t /*flags*/>> {
public:
void SetUp() override {
size_t index;
std::tie(index, flags) = GetParam();
surfaceFormat = snormSurfaceFormats[index];
}
void compareFormats(const SurfaceFormatInfo *first, const SurfaceFormatInfo *second) {
EXPECT_EQ(first->GenxSurfaceFormat, second->GenxSurfaceFormat);
EXPECT_EQ(first->GMMSurfaceFormat, second->GMMSurfaceFormat);
EXPECT_EQ(first->GMMTileWalk, second->GMMTileWalk);
EXPECT_EQ(first->ImageElementSizeInBytes, second->ImageElementSizeInBytes);
EXPECT_EQ(first->NumChannels, second->NumChannels);
EXPECT_EQ(first->OCLImageFormat.image_channel_data_type, second->OCLImageFormat.image_channel_data_type);
EXPECT_EQ(first->OCLImageFormat.image_channel_order, second->OCLImageFormat.image_channel_order);
EXPECT_EQ(first->PerChannelSizeInBytes, second->PerChannelSizeInBytes);
}
SurfaceFormatInfo surfaceFormat;
cl_mem_flags flags;
};
TEST_P(GetSurfaceFormatTest, givenSnormFormatWhenGetSurfaceFormatFromTableIsCalledThenReturnsCorrectFormat) {
auto format = Image::getSurfaceFormatFromTable(flags, &surfaceFormat.OCLImageFormat);
EXPECT_NE(nullptr, format);
compareFormats(&surfaceFormat, format);
}
cl_mem_flags flagsForTests[] = {CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY, CL_MEM_READ_WRITE};
INSTANTIATE_TEST_CASE_P(
ImageSnormTests,
GetSurfaceFormatTest,
::testing::Combine(
::testing::Range(static_cast<SnormSurfaceFormatsCountType>(0u), numSnormSurfaceFormats),
::testing::ValuesIn(flagsForTests)));
class IsSnormFormatTest : public ::testing::TestWithParam<std::tuple<uint32_t /*image data type*/, bool /*expected value*/>> {
public:
void SetUp() override {
std::tie(format.image_channel_data_type, expectedValue) = GetParam();
}
cl_image_format format;
bool expectedValue;
};
TEST_P(IsSnormFormatTest, givenSnormFormatWhenGetSurfaceFormatFromTableIsCalledThenReturnsCorrectFormat) {
bool retVal = Image::isSnormFormat(format);
EXPECT_EQ(expectedValue, retVal);
}
std::tuple<uint32_t, bool> paramsForSnormTests[] = {
std::make_tuple<uint32_t, bool>(CL_SNORM_INT8, true),
std::make_tuple<uint32_t, bool>(CL_SNORM_INT16, true),
std::make_tuple<uint32_t, bool>(CL_UNORM_INT8, false),
std::make_tuple<uint32_t, bool>(CL_UNORM_INT16, false),
std::make_tuple<uint32_t, bool>(CL_UNORM_SHORT_565, false),
std::make_tuple<uint32_t, bool>(CL_UNORM_SHORT_555, false),
std::make_tuple<uint32_t, bool>(CL_UNORM_INT_101010, false),
std::make_tuple<uint32_t, bool>(CL_SIGNED_INT8, false),
std::make_tuple<uint32_t, bool>(CL_SIGNED_INT16, false),
std::make_tuple<uint32_t, bool>(CL_SIGNED_INT32, false),
std::make_tuple<uint32_t, bool>(CL_UNSIGNED_INT8, false),
std::make_tuple<uint32_t, bool>(CL_UNSIGNED_INT16, false),
std::make_tuple<uint32_t, bool>(CL_UNSIGNED_INT32, false),
std::make_tuple<uint32_t, bool>(CL_HALF_FLOAT, false),
std::make_tuple<uint32_t, bool>(CL_FLOAT, false),
std::make_tuple<uint32_t, bool>(CL_UNORM_INT24, false),
std::make_tuple<uint32_t, bool>(CL_UNORM_INT_101010_2, false)};
INSTANTIATE_TEST_CASE_P(
ImageSnormTests,
IsSnormFormatTest,
::testing::ValuesIn(paramsForSnormTests));

View File

@@ -0,0 +1,944 @@
/*
* Copyright (c) 2017, 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 "unit_tests/command_queue/command_queue_fixture.h"
#include "unit_tests/fixtures/image_fixture.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "runtime/compiler_interface/compiler_interface.h"
#include "runtime/mem_obj/image.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/built_ins/built_ins.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "unit_tests/helpers/kernel_binary_helper.h"
#include "unit_tests/helpers/memory_management.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_memory_manager.h"
#include "gtest/gtest.h"
using namespace OCLRT;
static const unsigned int testImageDimensions = 45;
auto channelType = CL_UNORM_INT8;
auto channelOrder = CL_RGBA;
auto const elementSize = 4; //sizeof CL_RGBA * CL_UNORM_INT8
class CreateImageTest : public DeviceFixture,
public testing::TestWithParam<uint64_t /*cl_mem_flags*/>,
public CommandQueueHwFixture {
typedef CommandQueueHwFixture CommandQueueFixture;
public:
CreateImageTest() {
}
Image *createImageWithFlags(cl_mem_flags flags) {
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
return Image::create(context, flags, surfaceFormat, &imageDesc, nullptr, retVal);
}
protected:
void SetUp() override {
DeviceFixture::SetUp();
memoryManager = new MockMemoryManager();
pDevice->injectMemoryManager(memoryManager);
CommandQueueFixture::SetUp(pDevice, 0);
flags = GetParam();
// clang-format off
imageFormat.image_channel_data_type = channelType;
imageFormat.image_channel_order = channelOrder;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = testImageDimensions;
imageDesc.image_height = testImageDimensions;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 1;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
}
void TearDown() override {
BuiltIns::shutDown();
CommandQueueFixture::TearDown();
DeviceFixture::TearDown();
}
MockMemoryManager *memoryManager;
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
cl_mem_flags flags = 0;
unsigned char pHostPtr[testImageDimensions * testImageDimensions * elementSize * 4];
};
typedef CreateImageTest CreateImageNoHostPtr;
TEST(TestSliceAndRowPitch, ForDifferentDescriptorsGetHostPtrSlicePitchAndRowPitchReturnsProperValues) {
DebugManagerStateRestore dbgRestorer;
DebugManager.flags.ForceLinearImages.set(true);
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal;
MockContext context;
const size_t width = 5;
const size_t height = 3;
const size_t depth = 2;
char *hostPtr = (char *)alignedMalloc(width * height * depth * elementSize * 2, 64);
imageFormat.image_channel_data_type = channelType;
imageFormat.image_channel_order = channelOrder;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// 1D image with 0 row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D;
imageDesc.image_width = width;
imageDesc.image_height = 0;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 0;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ(width * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ(0u, image->getHostPtrSlicePitch());
delete image;
// 1D image with non-zero row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D;
imageDesc.image_width = width;
imageDesc.image_height = 0;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 0;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = 0;
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ(0u, image->getHostPtrSlicePitch());
delete image;
// 2D image with non-zero row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 0;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = 0;
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ(0u, image->getHostPtrSlicePitch());
delete image;
// 1D ARRAY image with non-zero row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
imageDesc.image_width = width;
imageDesc.image_height = 0;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 2;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = 0;
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrSlicePitch());
delete image;
// 2D ARRAY image with non-zero row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 2;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = 0;
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ((width + 1) * elementSize * height, image->getHostPtrSlicePitch());
delete image;
// 2D ARRAY image with zero row_pitch and non-zero slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 2;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = (width + 1) * elementSize * height;
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ(width * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ((width + 1) * elementSize * height, image->getHostPtrSlicePitch());
delete image;
// 2D ARRAY image with non-zero row_pitch and non-zero slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 2;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = (width + 1) * elementSize * height;
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ((width + 1) * elementSize * height, image->getHostPtrSlicePitch());
delete image;
// 2D ARRAY image with non-zero row_pitch and non-zero slice_pitch > row_pitch * height
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 2;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = (width + 1) * elementSize * (height + 1);
image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ((width + 1) * elementSize * (height + 1), image->getHostPtrSlicePitch());
delete image;
alignedFree(hostPtr);
}
TEST(TestCreateImage, UseSharedContextToCreateImage) {
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal;
MockContext context;
context.isSharedContext = true;
const size_t width = 5;
const size_t height = 3;
const size_t depth = 2;
char *hostPtr = (char *)alignedMalloc(width * height * depth * elementSize * 2, 64);
imageFormat.image_channel_data_type = channelType;
imageFormat.image_channel_order = channelOrder;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// 2D image with non-zero row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 0;
imageDesc.image_row_pitch = (width + 1) * elementSize;
imageDesc.image_slice_pitch = 0;
cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_EQ((width + 1) * elementSize, image->getHostPtrRowPitch());
EXPECT_EQ(0u, image->getHostPtrSlicePitch());
delete image;
alignedFree(hostPtr);
}
TEST(TestCreateImageUseHostPtr, CheckMemoryAllocationForDifferenHostPtrAlignments) {
KernelBinaryHelper kbHelper(KernelBinaryHelper::BUILT_INS);
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal;
MockContext context;
const size_t width = 4;
const size_t height = 32;
imageFormat.image_channel_data_type = channelType;
imageFormat.image_channel_order = channelOrder;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// 2D image with 0 row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.image_width = width;
imageDesc.image_height = height;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 0;
imageDesc.image_row_pitch = alignUp(alignUp(width, 4) * 4, 0x80); //row pitch for tiled img
imageDesc.image_slice_pitch = 0;
void *pageAlignedPointer = alignedMalloc(imageDesc.image_row_pitch * height * 1 * 4 + 256, 4096);
void *hostPtr[] = {reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(pageAlignedPointer) + 16), // 16 - byte alignment
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(pageAlignedPointer) + 32), // 32 - byte alignment
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(pageAlignedPointer) + 64), // 64 - byte alignment
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(pageAlignedPointer) + 128)}; // 128 - byte alignment
bool result[] = {false,
false,
true,
true};
cl_mem_flags flags = CL_MEM_HOST_NO_ACCESS | CL_MEM_USE_HOST_PTR;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
for (int i = 0; i < 4; i++) {
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
hostPtr[i],
retVal);
ASSERT_NE(nullptr, image);
auto address = image->getCpuAddress();
if (result[i] && !image->allowTiling()) {
EXPECT_EQ(hostPtr[i], address);
} else {
EXPECT_NE(hostPtr[i], address);
}
delete image;
}
alignedFree(pageAlignedPointer);
}
TEST_P(CreateImageNoHostPtr, validFlags) {
auto image = createImageWithFlags(flags);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
ASSERT_EQ(true, image->isMemObjZeroCopy());
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
delete image;
}
TEST_P(CreateImageNoHostPtr, getImageDesc) {
auto image = createImageWithFlags(flags);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
const auto &imageDesc = image->getImageDesc();
// Sometimes the user doesn't pass image_row/slice_pitch during a create.
// Ensure the driver fills in the missing data.
EXPECT_NE(0u, imageDesc.image_row_pitch);
EXPECT_GE(imageDesc.image_slice_pitch, imageDesc.image_row_pitch);
delete image;
}
TEST_P(CreateImageNoHostPtr, completionStamp) {
auto image = createImageWithFlags(flags);
FlushStamp expectedFlushStamp = 0;
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
ASSERT_EQ(true, image->isMemObjZeroCopy());
EXPECT_EQ(0u, image->getCompletionStamp().taskCount);
EXPECT_EQ(expectedFlushStamp, image->getCompletionStamp().flushStamp);
EXPECT_EQ(0u, image->getCompletionStamp().deviceOrdinal);
EXPECT_EQ(0u, image->getCompletionStamp().engineOrdinal);
CompletionStamp completionStamp;
completionStamp.taskCount = 42;
completionStamp.deviceOrdinal = 43;
completionStamp.engineOrdinal = 44;
completionStamp.flushStamp = 5;
image->setCompletionStamp(completionStamp, nullptr, nullptr);
EXPECT_EQ(completionStamp.taskCount, image->getCompletionStamp().taskCount);
EXPECT_EQ(completionStamp.flushStamp, image->getCompletionStamp().flushStamp);
EXPECT_EQ(completionStamp.deviceOrdinal, image->getCompletionStamp().deviceOrdinal);
EXPECT_EQ(completionStamp.engineOrdinal, image->getCompletionStamp().engineOrdinal);
delete image;
}
TEST_P(CreateImageNoHostPtr, withUseHostPtrReturnsError) {
auto image = createImageWithFlags(flags | CL_MEM_USE_HOST_PTR);
EXPECT_EQ(CL_INVALID_HOST_PTR, retVal);
EXPECT_EQ(nullptr, image);
delete image;
}
TEST_P(CreateImageNoHostPtr, withCopyHostPtrReturnsError) {
auto image = createImageWithFlags(flags | CL_MEM_COPY_HOST_PTR);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
EXPECT_EQ(nullptr, image);
}
TEST_P(CreateImageNoHostPtr, withImageGraphicsAllocationReportsImageType) {
auto image = createImageWithFlags(flags);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, image);
auto &allocation = *image->getGraphicsAllocation();
auto type = allocation.getAllocationType();
auto isTypeImage = !!(type & GraphicsAllocation::ALLOCATION_TYPE_IMAGE);
EXPECT_TRUE(isTypeImage);
auto isTypeWritable = !!(type & GraphicsAllocation::ALLOCATION_TYPE_WRITABLE);
auto isImageWritable = !(flags & (CL_MEM_READ_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS));
EXPECT_EQ(isImageWritable, isTypeWritable);
delete image;
}
// Parameterized test that tests image creation with all flags that should be
// valid with a nullptr host ptr
static cl_mem_flags NoHostPtrFlags[] = {
CL_MEM_READ_WRITE,
CL_MEM_WRITE_ONLY,
CL_MEM_READ_ONLY,
CL_MEM_HOST_READ_ONLY,
CL_MEM_HOST_WRITE_ONLY,
CL_MEM_HOST_NO_ACCESS};
INSTANTIATE_TEST_CASE_P(
CreateImageTest_Create,
CreateImageNoHostPtr,
testing::ValuesIn(NoHostPtrFlags));
struct CreateImageHostPtr
: public CreateImageTest,
public MemoryManagementFixture {
typedef CreateImageTest BaseClass;
CreateImageHostPtr() {
}
void SetUp() override {
MemoryManagementFixture::SetUp();
BaseClass::SetUp();
}
void TearDown() override {
delete image;
CompilerInterface::shutdown();
BaseClass::TearDown();
MemoryManagementFixture::TearDown();
}
Image *createImage(cl_int &retVal) {
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
return Image::create(
context,
flags,
surfaceFormat,
&imageDesc,
pHostPtr,
retVal);
}
cl_int retVal = CL_INVALID_VALUE;
Image *image = nullptr;
};
TEST_P(CreateImageHostPtr, isResidentDefaultsToFalseAfterCreate) {
KernelBinaryHelper kbHelper(KernelBinaryHelper::BUILT_INS);
image = createImage(retVal);
ASSERT_NE(nullptr, image);
EXPECT_FALSE(image->getGraphicsAllocation()->isResident());
}
TEST_P(CreateImageHostPtr, isResidentReturnsValueFromSetResident) {
image = createImage(retVal);
ASSERT_NE(nullptr, image);
image->getGraphicsAllocation()->residencyTaskCount = 1;
EXPECT_TRUE(image->getGraphicsAllocation()->isResident());
image->getGraphicsAllocation()->residencyTaskCount = ObjectNotResident;
EXPECT_FALSE(image->getGraphicsAllocation()->isResident());
}
TEST_P(CreateImageHostPtr, getAddress) {
image = createImage(retVal);
ASSERT_NE(nullptr, image);
auto address = image->getCpuAddress();
EXPECT_NE(nullptr, address);
if (!(flags & CL_MEM_USE_HOST_PTR)) {
EXPECT_EQ(nullptr, image->getHostPtr());
}
if (flags & CL_MEM_USE_HOST_PTR) {
//if size fits within a page then zero copy can be applied, if not RT needs to do a copy of image
auto computedSize = imageDesc.image_width * elementSize * alignUp(imageDesc.image_height, 4) * imageDesc.image_array_size;
auto ptrSize = imageDesc.image_width * elementSize * imageDesc.image_height * imageDesc.image_array_size;
auto alignedRequiredSize = alignSizeWholePage(static_cast<void *>(pHostPtr), computedSize);
auto alignedPtrSize = alignSizeWholePage(static_cast<void *>(pHostPtr), ptrSize);
size_t HalignReq = imageDesc.image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY ? 64 : 1;
auto rowPitch = imageDesc.image_width * elementSize;
auto slicePitch = rowPitch * imageDesc.image_height;
auto requiredRowPitch = alignUp(imageDesc.image_width, HalignReq) * elementSize;
auto requiredSlicePitch = requiredRowPitch * alignUp(imageDesc.image_height, 4);
bool copyRequired = (alignedRequiredSize > alignedPtrSize) | (requiredRowPitch != rowPitch) | (slicePitch != requiredSlicePitch);
if (copyRequired) {
// Buffer should use host ptr
EXPECT_NE(pHostPtr, address);
EXPECT_EQ(pHostPtr, image->getHostPtr());
EXPECT_FALSE(image->isMemObjZeroCopy());
} else {
// Buffer should use host ptr
EXPECT_EQ(pHostPtr, address);
EXPECT_TRUE(image->isMemObjZeroCopy());
}
} else {
// Buffer should have a different ptr
EXPECT_NE(pHostPtr, address);
}
if (flags & CL_MEM_COPY_HOST_PTR && !image->allowTiling()) {
// Buffer should contain a copy of host memory
EXPECT_EQ(0, memcmp(pHostPtr, address, sizeof(testImageDimensions)));
}
}
TEST_P(CreateImageHostPtr, getSize) {
image = createImage(retVal);
ASSERT_NE(nullptr, image);
EXPECT_NE(0u, image->getSize());
}
TEST_P(CreateImageHostPtr, graphicsAllocationPresent) {
image = createImage(retVal);
ASSERT_NE(nullptr, image);
EXPECT_NE(nullptr, image->getGraphicsAllocation());
}
TEST_P(CreateImageHostPtr, getImageDesc) {
image = createImage(retVal);
ASSERT_NE(nullptr, image);
const auto &imageDesc = image->getImageDesc();
// clang-format off
EXPECT_EQ(this->imageDesc.image_type, imageDesc.image_type);
EXPECT_EQ(this->imageDesc.image_width, imageDesc.image_width);
EXPECT_EQ(this->imageDesc.image_height, imageDesc.image_height);
EXPECT_EQ(this->imageDesc.image_depth, imageDesc.image_depth);
EXPECT_EQ(0u, imageDesc.image_array_size);
EXPECT_NE(0u, imageDesc.image_row_pitch);
EXPECT_GE(imageDesc.image_slice_pitch, imageDesc.image_row_pitch);
EXPECT_EQ(this->imageDesc.num_mip_levels, imageDesc.num_mip_levels);
EXPECT_EQ(this->imageDesc.num_samples, imageDesc.num_samples);
EXPECT_EQ(this->imageDesc.buffer, imageDesc.buffer);
EXPECT_EQ(this->imageDesc.mem_object, imageDesc.mem_object);
// clang-format on
EXPECT_EQ(image->getHostPtrRowPitch(), static_cast<size_t>(imageDesc.image_width * elementSize));
// Only 3D, and array images can have slice pitch
int isArrayOr3DType = 0;
if (this->imageDesc.image_type == CL_MEM_OBJECT_IMAGE3D ||
this->imageDesc.image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY ||
this->imageDesc.image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
isArrayOr3DType = 1;
}
EXPECT_EQ(image->getHostPtrSlicePitch(), static_cast<size_t>(imageDesc.image_width * elementSize * imageDesc.image_height) * isArrayOr3DType);
EXPECT_EQ(image->getImageCount(), 1u);
}
TEST_P(CreateImageHostPtr, failedAllocationInjection) {
InjectedFunction method = [this](size_t failureIndex) {
// System under test
image = createImage(retVal);
if (nonfailingAllocation == failureIndex) {
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, image);
} else {
EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal) << "for allocation " << failureIndex;
EXPECT_EQ(nullptr, image);
}
delete image;
image = nullptr;
};
injectFailures(method, 4); // check only first 5 allocations - avoid checks on writeImg call allocations for tiled imgs
}
TEST_P(CreateImageHostPtr, checkWritingOutsideAllocatedMemoryWhileCreatingImage) {
memoryManager->redundancyRatio = 2;
memset(pHostPtr, 1, testImageDimensions * testImageDimensions * elementSize * 4);
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
imageDesc.image_height = 1;
imageDesc.image_row_pitch = elementSize * imageDesc.image_width + 1;
image = createImage(retVal);
char *memory = (char *)image->getGraphicsAllocation()->getUnderlyingBuffer();
auto memorySize = image->getGraphicsAllocation()->getUnderlyingBufferSize() / 2;
for (size_t i = 0; i < image->getHostPtrSlicePitch(); ++i) {
if (i < imageDesc.image_width * elementSize) {
EXPECT_EQ(1, memory[i]);
} else {
EXPECT_EQ(0, memory[i]);
}
}
for (size_t i = 0; i < memorySize; ++i) {
EXPECT_EQ(0, memory[memorySize + i]);
}
memoryManager->redundancyRatio = 1;
}
struct ModifyableImage {
enum { flags = 0 };
static cl_image_format imageFormat;
static cl_image_desc imageDesc;
static void *hostPtr;
static OCLRT::Context *context;
};
void *ModifyableImage::hostPtr = nullptr;
OCLRT::Context *ModifyableImage::context = nullptr;
cl_image_format ModifyableImage::imageFormat;
cl_image_desc ModifyableImage::imageDesc;
class ImageTransfer : public ::testing::Test {
public:
void SetUp() override {
context = new MockContext();
ASSERT_NE(context, nullptr);
ModifyableImage::context = context;
ModifyableImage::hostPtr = nullptr;
ModifyableImage::imageFormat = {CL_R, CL_FLOAT};
ModifyableImage::imageDesc = {CL_MEM_OBJECT_IMAGE1D, 512, 0, 0, 0, 0, 0, 0, 0, {nullptr}};
hostPtr = nullptr;
unalignedHostPtr = nullptr;
}
void TearDown() override {
if (context)
delete context;
if (hostPtr)
alignedFree(hostPtr);
}
void createHostPtrs(size_t imageSize) {
hostPtr = alignedMalloc(imageSize + 100, 4096);
unalignedHostPtr = (char *)hostPtr + 4;
memset(hostPtr, 0, imageSize + 100);
memset(unalignedHostPtr, 1, imageSize);
}
MockContext *context;
void *hostPtr;
void *unalignedHostPtr;
};
TEST_F(ImageTransfer, GivenNonZeroCopyImageWhenDataTransferedFromHostPtrToMemStorageThenNoOverflowOfHostPtr) {
size_t imageSize = 512 * 4;
createHostPtrs(imageSize);
ModifyableImage::imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D;
ModifyableImage::imageDesc.image_width = 512;
ModifyableImage::imageDesc.image_height = 0;
ModifyableImage::imageDesc.image_row_pitch = 0;
ModifyableImage::imageDesc.image_array_size = 0;
ModifyableImage::imageFormat.image_channel_order = CL_R;
ModifyableImage::imageFormat.image_channel_data_type = CL_FLOAT;
ModifyableImage::hostPtr = unalignedHostPtr;
Image *imageNonZeroCopy = ImageHelper<ImageUseHostPtr<ModifyableImage>>::create();
ASSERT_NE(nullptr, imageNonZeroCopy);
void *memoryStorage = imageNonZeroCopy->getCpuAddress();
size_t memoryStorageSize = imageNonZeroCopy->getSize();
ASSERT_NE(memoryStorage, unalignedHostPtr);
int result = memcmp(memoryStorage, unalignedHostPtr, imageSize);
EXPECT_EQ(0, result);
memset(memoryStorage, 0, memoryStorageSize);
memset((char *)unalignedHostPtr + imageSize, 2, 100 - 4);
imageNonZeroCopy->transferDataFromHostPtrToMemoryStorage();
void *foundData = memchr(memoryStorage, 2, memoryStorageSize);
EXPECT_EQ(0, foundData);
delete imageNonZeroCopy;
}
TEST_F(ImageTransfer, GivenNonZeroCopyNonZeroRowPitchImageWhenDataIsTransferedFromHostPtrToMemStorageThenDestinationIsNotOverflowed) {
ModifyableImage::imageDesc.image_width = 16;
ModifyableImage::imageDesc.image_row_pitch = 65;
ModifyableImage::imageFormat.image_channel_data_type = CL_UNORM_INT8;
size_t imageSize = ModifyableImage::imageDesc.image_row_pitch;
size_t imageWidth = ModifyableImage::imageDesc.image_width;
createHostPtrs(imageSize);
ModifyableImage::hostPtr = unalignedHostPtr;
Image *imageNonZeroCopy = ImageHelper<ImageUseHostPtr<ModifyableImage>>::create();
ASSERT_NE(nullptr, imageNonZeroCopy);
void *memoryStorage = imageNonZeroCopy->getCpuAddress();
size_t memoryStorageSize = imageNonZeroCopy->getSize();
ASSERT_NE(memoryStorage, unalignedHostPtr);
int result = memcmp(memoryStorage, unalignedHostPtr, imageWidth);
EXPECT_EQ(0, result);
memset(memoryStorage, 0, memoryStorageSize);
memset((char *)unalignedHostPtr + imageSize, 2, 100 - 4);
imageNonZeroCopy->transferDataFromHostPtrToMemoryStorage();
void *foundData = memchr(memoryStorage, 2, memoryStorageSize);
EXPECT_EQ(0, foundData);
delete imageNonZeroCopy;
}
TEST_F(ImageTransfer, GivenNonZeroCopyNonZeroRowPitchWithExtraBytes1DArrayImageWhenDataIsTransferedForthAndBackThenDataValidates) {
ModifyableImage::imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
ModifyableImage::imageDesc.image_width = 5;
ModifyableImage::imageDesc.image_row_pitch = 28; // == (4 * 5) row bytes + (4 * 2) extra bytes
ModifyableImage::imageDesc.image_array_size = 3;
ModifyableImage::imageFormat.image_channel_order = CL_RGBA;
ModifyableImage::imageFormat.image_channel_data_type = CL_UNORM_INT8;
const size_t imageWidth = ModifyableImage::imageDesc.image_width;
const size_t imageRowPitchInPixels = ModifyableImage::imageDesc.image_row_pitch / 4;
const size_t imageHeight = 1;
const size_t imageCount = ModifyableImage::imageDesc.image_array_size;
size_t imageSize = ModifyableImage::imageDesc.image_row_pitch * imageHeight * imageCount;
createHostPtrs(imageSize);
uint32_t *row = static_cast<uint32_t *>(unalignedHostPtr);
for (uint32_t arrayIndex = 0; arrayIndex < imageCount; ++arrayIndex) {
for (uint32_t pixelInRow = 0; pixelInRow < imageRowPitchInPixels; ++pixelInRow) {
if (pixelInRow < imageWidth) {
row[pixelInRow] = pixelInRow;
} else {
row[pixelInRow] = 66;
}
}
row = row + imageRowPitchInPixels;
}
ModifyableImage::hostPtr = unalignedHostPtr;
Image *imageNonZeroCopy = ImageHelper<ImageUseHostPtr<ModifyableImage>>::create();
ASSERT_NE(nullptr, imageNonZeroCopy);
void *memoryStorage = imageNonZeroCopy->getCpuAddress();
ASSERT_NE(memoryStorage, unalignedHostPtr);
size_t internalSlicePitch = imageNonZeroCopy->getImageDesc().image_slice_pitch;
// Check twice, once after image create, and second time after transfer from HostPtrToMemoryStorage
// when these paths are unified, only one check will be enough
for (size_t run = 0; run < 2; ++run) {
row = static_cast<uint32_t *>(unalignedHostPtr);
unsigned char *internalRow = static_cast<unsigned char *>(memoryStorage);
if (run == 1) {
imageNonZeroCopy->transferDataFromHostPtrToMemoryStorage();
}
for (size_t arrayIndex = 0; arrayIndex < imageCount; ++arrayIndex) {
for (size_t pixelInRow = 0; pixelInRow < imageRowPitchInPixels; ++pixelInRow) {
if (pixelInRow < imageWidth) {
if (memcmp(&row[pixelInRow], &internalRow[pixelInRow * 4], 4)) {
EXPECT_FALSE(1) << "Data in memory storage did not validate, row: " << pixelInRow << " array: " << arrayIndex << "\n";
}
} else {
// Change extra bytes pattern
row[pixelInRow] = 55;
}
}
row = row + imageRowPitchInPixels;
internalRow = internalRow + internalSlicePitch;
}
}
imageNonZeroCopy->transferDataToHostPtr();
row = static_cast<uint32_t *>(unalignedHostPtr);
for (size_t arrayIndex = 0; arrayIndex < imageCount; ++arrayIndex) {
for (size_t pixelInRow = 0; pixelInRow < imageRowPitchInPixels; ++pixelInRow) {
if (pixelInRow < imageWidth) {
if (row[pixelInRow] != pixelInRow) {
EXPECT_FALSE(1) << "Data under host_ptr did not validate, row: " << pixelInRow << " array: " << arrayIndex << "\n";
}
} else {
if (row[pixelInRow] != 55) {
EXPECT_FALSE(1) << "Data under host_ptr corrupted in extra bytes, row: " << pixelInRow << " array: " << arrayIndex << "\n";
}
}
}
row = row + imageRowPitchInPixels;
}
delete imageNonZeroCopy;
}
// Parameterized test that tests image creation with all flags that should be
// valid with a valid host ptr
static cl_mem_flags ValidHostPtrFlags[] = {
0 | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_USE_HOST_PTR,
0 | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR};
INSTANTIATE_TEST_CASE_P(
CreateImageTest_Create,
CreateImageHostPtr,
testing::ValuesIn(ValidHostPtrFlags));
TEST(ImageGetSurfaceFormatInfoTest, givenNullptrFormatWhenGetSurfaceFormatInfoIsCalledThenReturnsNullptr) {
auto surfaceFormat = Image::getSurfaceFormatFromTable(0, nullptr);
EXPECT_EQ(nullptr, surfaceFormat);
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2017, 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 "unit_tests/command_queue/command_queue_fixture.h"
#include "unit_tests/fixtures/image_fixture.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_gmm.h"
#include "unit_tests/mocks/mock_graphics_allocation.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
using namespace OCLRT;
static const auto dimension = 16;
static auto channelType = CL_UNORM_INT8;
static auto channelOrder = CL_RGBA;
class CreateTiledImageTest : public DeviceFixture,
public testing::TestWithParam<uint32_t>,
public CommandQueueHwFixture {
typedef CommandQueueHwFixture CommandQueueFixture;
public:
CreateTiledImageTest() {
}
protected:
void SetUp() override {
DeviceFixture::SetUp();
CommandQueueFixture::SetUp(pDevice, 0);
type = GetParam();
// clang-format off
imageFormat.image_channel_data_type = channelType;
imageFormat.image_channel_order = channelOrder;
imageDesc.image_type = type;
imageDesc.image_width = dimension;
imageDesc.image_height = dimension;
imageDesc.image_depth = 1;
imageDesc.image_array_size = 1;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// clang-format on
}
void TearDown() override {
CommandQueueFixture::TearDown();
DeviceFixture::TearDown();
}
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_int retVal = CL_SUCCESS;
cl_mem_object_type type = 0;
};
TEST_P(CreateTiledImageTest, isTiledImageIsSetForTiledImages) {
MockContext context;
cl_mem_flags flags = CL_MEM_READ_WRITE;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_TRUE(image->isTiledImage);
delete image;
}
TEST_P(CreateTiledImageTest, isTiledImageIsSetForSharedImages) {
MockContext context;
MockGraphicsAllocation *alloc = new MockGraphicsAllocation(0, 0x1000);
ImageInfo info = {0};
McsSurfaceInfo msi = {};
SurfaceFormatInfo surfaceFormat;
surfaceFormat.GMMSurfaceFormat = GMM_FORMAT_B8G8R8A8_UNORM;
info.surfaceFormat = &surfaceFormat;
info.imgDesc = &imageDesc;
info.plane = GMM_NO_PLANE;
auto gmm = MockGmm::queryImgParams(info);
alloc->gmm = gmm.release();
auto image = Image::createSharedImage(
&context,
nullptr,
msi,
alloc,
nullptr,
CL_MEM_READ_WRITE,
info,
0, 0);
ASSERT_NE(nullptr, image);
EXPECT_TRUE(image->isTiledImage);
delete image;
}
typedef CreateTiledImageTest CreateNonTiledImageTest;
TEST_P(CreateNonTiledImageTest, isTiledImageIsNotSetForNonTiledSharedImage) {
MockContext context;
MockGraphicsAllocation *alloc = new MockGraphicsAllocation(0, 0x1000);
ImageInfo info = {0};
McsSurfaceInfo msi = {};
SurfaceFormatInfo surfaceFormat;
imageDesc.image_height = 1;
surfaceFormat.GMMSurfaceFormat = GMM_FORMAT_B8G8R8A8_UNORM;
info.surfaceFormat = &surfaceFormat;
info.imgDesc = &imageDesc;
info.plane = GMM_NO_PLANE;
auto gmm = MockGmm::queryImgParams(info);
alloc->gmm = gmm.release();
auto image = Image::createSharedImage(
&context,
nullptr,
msi,
alloc,
nullptr,
CL_MEM_READ_WRITE,
info,
0, 0);
ASSERT_NE(nullptr, image);
EXPECT_FALSE(image->isTiledImage);
delete image;
}
// Parameterized test that tests image creation with tiled types
static uint32_t TiledImageTypes[] = {
CL_MEM_OBJECT_IMAGE2D,
CL_MEM_OBJECT_IMAGE2D_ARRAY,
CL_MEM_OBJECT_IMAGE3D};
static uint32_t NonTiledImageTypes[] = {
CL_MEM_OBJECT_IMAGE1D};
INSTANTIATE_TEST_CASE_P(CreateTiledImageTest, CreateTiledImageTest, testing::ValuesIn(TiledImageTypes));
INSTANTIATE_TEST_CASE_P(CreateNonTiledImageTest, CreateNonTiledImageTest, testing::ValuesIn(NonTiledImageTypes));

View File

@@ -0,0 +1,738 @@
/*
* Copyright (c) 2017, 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/helpers/surface_formats.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
using namespace OCLRT;
typedef decltype(&Image::redescribe) RedescribeMethod;
class ImageValidateTest : public testing::TestWithParam<cl_image_desc> {
public:
ImageValidateTest() {
imageFormat = &surfaceFormat.OCLImageFormat;
imageFormat->image_channel_data_type = CL_UNSIGNED_INT8;
imageFormat->image_channel_order = CL_RGBA;
}
protected:
void SetUp() override {
}
void TearDown() override {
}
cl_int retVal = CL_SUCCESS;
MockContext context;
SurfaceFormatInfo surfaceFormat;
cl_image_format *imageFormat;
cl_image_desc imageDesc;
};
typedef ImageValidateTest ValidDescriptor;
typedef ImageValidateTest InvalidDescriptor;
typedef ImageValidateTest InvalidSize;
TEST_P(ValidDescriptor, validSizePassedToValidateReturnsSuccess) {
imageDesc = GetParam();
retVal = Image::validate(&context, 0, &surfaceFormat, &imageDesc, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_P(InvalidDescriptor, zeroSizePassedToValidateReturnsError) {
imageDesc = GetParam();
retVal = Image::validate(&context, 0, &surfaceFormat, &imageDesc, nullptr);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_P(InvalidSize, invalidSizePassedToValidateReturnsError) {
imageDesc = GetParam();
retVal = Image::validate(&context, 0, &surfaceFormat, &imageDesc, nullptr);
EXPECT_EQ(CL_INVALID_IMAGE_SIZE, retVal);
}
TEST_P(ValidDescriptor, given3dImageFormatWhenGetSupportedFormatIsCalledThenDontReturnDepthFormats) {
imageDesc = GetParam();
uint32_t readOnlyformatCount;
uint32_t writeOnlyformatCount;
uint32_t readWriteOnlyformatCount;
context.getSupportedImageFormats(context.getDevice(0), CL_MEM_READ_ONLY, imageDesc.image_type, 0, nullptr, &readOnlyformatCount);
context.getSupportedImageFormats(context.getDevice(0), CL_MEM_WRITE_ONLY, imageDesc.image_type, 0, nullptr, &writeOnlyformatCount);
context.getSupportedImageFormats(context.getDevice(0), CL_MEM_READ_WRITE, imageDesc.image_type, 0, nullptr, &readWriteOnlyformatCount);
auto readOnlyImgFormats = new cl_image_format[readOnlyformatCount];
auto writeOnlyImgFormats = new cl_image_format[writeOnlyformatCount];
auto readWriteOnlyImgFormats = new cl_image_format[readWriteOnlyformatCount];
context.getSupportedImageFormats(context.getDevice(0), CL_MEM_READ_ONLY, imageDesc.image_type, readOnlyformatCount, readOnlyImgFormats, 0);
context.getSupportedImageFormats(context.getDevice(0), CL_MEM_WRITE_ONLY, imageDesc.image_type, writeOnlyformatCount, writeOnlyImgFormats, 0);
context.getSupportedImageFormats(context.getDevice(0), CL_MEM_READ_WRITE, imageDesc.image_type, readWriteOnlyformatCount, readWriteOnlyImgFormats, 0);
bool depthFound = false;
for (uint32_t i = 0; i < readOnlyformatCount; i++) {
if (readOnlyImgFormats[i].image_channel_order == CL_DEPTH || readOnlyImgFormats[i].image_channel_order == CL_DEPTH_STENCIL)
depthFound = true;
}
for (uint32_t i = 0; i < readOnlyformatCount; i++) {
if (readOnlyImgFormats[i].image_channel_order == CL_DEPTH || readOnlyImgFormats[i].image_channel_order == CL_DEPTH_STENCIL)
depthFound = true;
}
for (uint32_t i = 0; i < readOnlyformatCount; i++) {
if (readOnlyImgFormats[i].image_channel_order == CL_DEPTH || readOnlyImgFormats[i].image_channel_order == CL_DEPTH_STENCIL)
depthFound = true;
}
if (!Image::isImage2dOr2dArray(imageDesc.image_type)) {
EXPECT_FALSE(depthFound);
} else {
EXPECT_TRUE(depthFound);
}
delete[] readOnlyImgFormats;
delete[] writeOnlyImgFormats;
delete[] readWriteOnlyImgFormats;
}
TEST(ImageDepthFormatTest, returnSurfaceFormatForDepthFormats) {
cl_image_format imgFormat = {};
imgFormat.image_channel_order = CL_DEPTH;
imgFormat.image_channel_data_type = CL_FLOAT;
auto surfaceFormatInfo = Image::getSurfaceFormatFromTable(CL_MEM_READ_WRITE, &imgFormat);
ASSERT_NE(surfaceFormatInfo, nullptr);
EXPECT_TRUE(surfaceFormatInfo->GMMSurfaceFormat == GMM_FORMAT_R32_FLOAT_TYPE);
imgFormat.image_channel_data_type = CL_UNORM_INT16;
surfaceFormatInfo = Image::getSurfaceFormatFromTable(CL_MEM_READ_WRITE, &imgFormat);
ASSERT_NE(surfaceFormatInfo, nullptr);
EXPECT_TRUE(surfaceFormatInfo->GMMSurfaceFormat == GMM_FORMAT_R16_UNORM_TYPE);
}
TEST(ImageDepthFormatTest, returnSurfaceFormatForWriteOnlyDepthFormats) {
cl_image_format imgFormat = {};
imgFormat.image_channel_order = CL_DEPTH;
imgFormat.image_channel_data_type = CL_FLOAT;
auto surfaceFormatInfo = Image::getSurfaceFormatFromTable(CL_MEM_WRITE_ONLY, &imgFormat);
ASSERT_NE(surfaceFormatInfo, nullptr);
EXPECT_TRUE(surfaceFormatInfo->GMMSurfaceFormat == GMM_FORMAT_R32_FLOAT_TYPE);
imgFormat.image_channel_data_type = CL_UNORM_INT16;
surfaceFormatInfo = Image::getSurfaceFormatFromTable(CL_MEM_WRITE_ONLY, &imgFormat);
ASSERT_NE(surfaceFormatInfo, nullptr);
EXPECT_TRUE(surfaceFormatInfo->GMMSurfaceFormat == GMM_FORMAT_R16_UNORM_TYPE);
}
TEST(ImageDepthFormatTest, returnSurfaceFormatForDepthStencilFormats) {
cl_image_format imgFormat = {};
imgFormat.image_channel_order = CL_DEPTH_STENCIL;
imgFormat.image_channel_data_type = CL_UNORM_INT24;
auto surfaceFormatInfo = Image::getSurfaceFormatFromTable(CL_MEM_READ_ONLY, &imgFormat);
ASSERT_NE(surfaceFormatInfo, nullptr);
EXPECT_TRUE(surfaceFormatInfo->GMMSurfaceFormat == GMM_FORMAT_GENERIC_32BIT);
imgFormat.image_channel_order = CL_DEPTH_STENCIL;
imgFormat.image_channel_data_type = CL_FLOAT;
surfaceFormatInfo = Image::getSurfaceFormatFromTable(CL_MEM_READ_ONLY, &imgFormat);
ASSERT_NE(surfaceFormatInfo, nullptr);
EXPECT_TRUE(surfaceFormatInfo->GMMSurfaceFormat == GMM_FORMAT_R32G32_FLOAT_TYPE);
}
static cl_image_desc validImageDesc[] = {
{CL_MEM_OBJECT_IMAGE1D, /*image_type*/
16384, /*image_width*/
1, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE1D_ARRAY, /*image_type*/
16384, /*image_width*/
1, /*image_height*/
1, /*image_depth*/
2, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE2D, /*image_type*/
512, /*image_width*/
512, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE2D, /*image_type*/
16384, /*image_width*/
16384, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE2D_ARRAY, /*image_type*/
16384, /*image_width*/
16384, /*image_height*/
1, /*image_depth*/
1, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE2D_ARRAY, /*image_type*/
16384, /*image_width*/
16384, /*image_height*/
1, /*image_depth*/
2, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE3D, /*image_type*/
16384, /*image_width*/
16384, /*image_height*/
3, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE3D, /*image_type*/
2, /*image_width*/
2, /*image_height*/
2, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
};
static cl_image_desc invalidImageDesc[] = {
{CL_MEM_OBJECT_IMAGE2D, /*image_type*/
0, /*image_width*/
512, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE2D, /*image_type*/
512, /*image_width*/
0, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
};
static cl_image_desc invalidImageSize[] = {
{CL_MEM_OBJECT_IMAGE2D, /*image_type*/
16384 + 10, /*image_width*/
512, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
{CL_MEM_OBJECT_IMAGE2D, /*image_type*/
1, /*image_width*/
16384 + 10, /*image_height*/
1, /*image_depth*/
0, /*image_array_size*/
0, /*image_row_pitch*/
0, /*image_slice_pitch*/
0, /*num_mip_levels*/
0, /*num_samples*/
{0}}, /*mem_object */
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidDescriptor,
::testing::ValuesIn(validImageDesc));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidDescriptor,
::testing::ValuesIn(invalidImageDesc));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidSize,
::testing::ValuesIn(invalidImageSize));
class ValidImageFormatTest : public ::testing::TestWithParam<std::tuple<unsigned int, unsigned int>> {
public:
void validateFormat() {
cl_image_format imageFormat;
cl_int retVal;
std::tie(imageFormat.image_channel_order, imageFormat.image_channel_data_type) = GetParam();
retVal = Image::validateImageFormat(&imageFormat);
EXPECT_EQ(CL_SUCCESS, retVal);
}
};
class InvalidImageFormatTest : public ::testing::TestWithParam<std::tuple<unsigned int, unsigned int>> {
public:
void validateFormat() {
cl_image_format imageFormat;
cl_int retVal;
std::tie(imageFormat.image_channel_order, imageFormat.image_channel_data_type) = GetParam();
retVal = Image::validateImageFormat(&imageFormat);
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
}
};
typedef ValidImageFormatTest ValidSingleChannelFormat;
typedef InvalidImageFormatTest InvalidSingleChannelFormat;
cl_channel_order validSingleChannelOrder[] = {CL_R, CL_A, CL_Rx};
cl_channel_type validSingleChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT};
cl_channel_type invalidSingleChannelDataTypes[] = {CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidSingleChannelFormat, givenValidSingleChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidSingleChannelFormat, givenInvalidSingleChannelChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidSingleChannelFormat,
::testing::Combine(
::testing::ValuesIn(validSingleChannelOrder),
::testing::ValuesIn(validSingleChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidSingleChannelFormat,
::testing::Combine(
::testing::ValuesIn(validSingleChannelOrder),
::testing::ValuesIn(invalidSingleChannelDataTypes)));
typedef ValidImageFormatTest ValidIntensityFormat;
typedef InvalidImageFormatTest InvalidIntensityFormat;
cl_channel_order validIntensityChannelOrders[] = {CL_INTENSITY};
cl_channel_type validIntensityChannelDataTypes[] = {CL_UNORM_INT8, CL_UNORM_INT16, CL_SNORM_INT8, CL_SNORM_INT16, CL_HALF_FLOAT, CL_FLOAT};
cl_channel_type invalidIntensityChannelDataTypes[] = {CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidIntensityFormat, givenValidIntensityImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidIntensityFormat, givenInvalidIntensityChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidIntensityFormat,
::testing::Combine(
::testing::ValuesIn(validIntensityChannelOrders),
::testing::ValuesIn(validIntensityChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidIntensityFormat,
::testing::Combine(
::testing::ValuesIn(validIntensityChannelOrders),
::testing::ValuesIn(invalidIntensityChannelDataTypes)));
typedef ValidImageFormatTest ValidLuminanceFormat;
typedef InvalidImageFormatTest InvalidLuminanceFormat;
cl_channel_order validLuminanceChannelOrders[] = {CL_LUMINANCE};
cl_channel_type validLuminanceChannelDataTypes[] = {CL_UNORM_INT8, CL_UNORM_INT16, CL_SNORM_INT8, CL_SNORM_INT16, CL_HALF_FLOAT, CL_FLOAT};
cl_channel_type invalidLuminanceChannelDataTypes[] = {CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidLuminanceFormat, givenValidLuminanceImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidLuminanceFormat, givenInvalidLuminanceChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidLuminanceFormat,
::testing::Combine(
::testing::ValuesIn(validLuminanceChannelOrders),
::testing::ValuesIn(validLuminanceChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidLuminanceFormat,
::testing::Combine(
::testing::ValuesIn(validLuminanceChannelOrders),
::testing::ValuesIn(invalidLuminanceChannelDataTypes)));
typedef ValidImageFormatTest ValidDepthFormat;
typedef InvalidImageFormatTest InvalidDepthFormat;
cl_channel_order validDepthChannelOrders[] = {CL_DEPTH};
cl_channel_type validDepthChannelDataTypes[] = {CL_UNORM_INT16, CL_FLOAT};
cl_channel_type invalidDepthChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidDepthFormat, givenValidDepthImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidDepthFormat, givenInvalidDepthChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidDepthFormat,
::testing::Combine(
::testing::ValuesIn(validDepthChannelOrders),
::testing::ValuesIn(validDepthChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidDepthFormat,
::testing::Combine(
::testing::ValuesIn(validDepthChannelOrders),
::testing::ValuesIn(invalidDepthChannelDataTypes)));
typedef ValidImageFormatTest ValidDoubleChannelFormat;
typedef InvalidImageFormatTest InvalidDoubleChannelFormat;
cl_channel_order validDoubleChannelOrders[] = {CL_RG, CL_RGx, CL_RA};
cl_channel_type validDoubleChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT};
cl_channel_type invalidDoubleChannelDataTypes[] = {CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidDoubleChannelFormat, givenValidDoubleChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidDoubleChannelFormat, givenInvalidDoubleChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidDoubleChannelFormat,
::testing::Combine(
::testing::ValuesIn(validDoubleChannelOrders),
::testing::ValuesIn(validDoubleChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidDoubleChannelFormat,
::testing::Combine(
::testing::ValuesIn(validDoubleChannelOrders),
::testing::ValuesIn(invalidDoubleChannelDataTypes)));
typedef ValidImageFormatTest ValidTripleChannelFormat;
typedef InvalidImageFormatTest InvalidTripleChannelFormat;
cl_channel_order validTripleChannelOrders[] = {CL_RGB, CL_RGBx};
cl_channel_type validTripleChannelDataTypes[] = {CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010};
cl_channel_type invalidTripleChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidTripleChannelFormat, givenValidTripleChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidTripleChannelFormat, givenInvalidTripleChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidTripleChannelFormat,
::testing::Combine(
::testing::ValuesIn(validTripleChannelOrders),
::testing::ValuesIn(validTripleChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidTripleChannelFormat,
::testing::Combine(
::testing::ValuesIn(validTripleChannelOrders),
::testing::ValuesIn(invalidTripleChannelDataTypes)));
typedef ValidImageFormatTest ValidRGBAChannelFormat;
typedef InvalidImageFormatTest InvalidRGBAChannelFormat;
cl_channel_order validRGBAChannelOrders[] = {CL_RGBA};
cl_channel_type validRGBAChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT};
cl_channel_type invalidRGBAChannelDataTypes[] = {CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidRGBAChannelFormat, givenValidRGBAChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidRGBAChannelFormat, givenInvalidRGBAChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidRGBAChannelFormat,
::testing::Combine(
::testing::ValuesIn(validRGBAChannelOrders),
::testing::ValuesIn(validRGBAChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidRGBAChannelFormat,
::testing::Combine(
::testing::ValuesIn(validRGBAChannelOrders),
::testing::ValuesIn(invalidRGBAChannelDataTypes)));
typedef ValidImageFormatTest ValidSRGBChannelFormat;
typedef InvalidImageFormatTest InvalidSRGBChannelFormat;
cl_channel_order validSRGBChannelOrders[] = {CL_sRGB, CL_sRGBx, CL_sRGBA, CL_sBGRA};
cl_channel_type validSRGBChannelDataTypes[] = {CL_UNORM_INT8};
cl_channel_type invalidSRGBChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT16, CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidSRGBChannelFormat, givenValidSRGBChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidSRGBChannelFormat, givenInvalidSRGBChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidSRGBChannelFormat,
::testing::Combine(
::testing::ValuesIn(validSRGBChannelOrders),
::testing::ValuesIn(validSRGBChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidSRGBChannelFormat,
::testing::Combine(
::testing::ValuesIn(validSRGBChannelOrders),
::testing::ValuesIn(invalidSRGBChannelDataTypes)));
typedef ValidImageFormatTest ValidARGBChannelFormat;
typedef InvalidImageFormatTest InvalidARGBChannelFormat;
cl_channel_order validARGBChannelOrders[] = {CL_ARGB, CL_BGRA, CL_ABGR};
cl_channel_type validARGBChannelDataTypes[] = {CL_UNORM_INT8, CL_SNORM_INT8, CL_SIGNED_INT8, CL_UNSIGNED_INT8};
cl_channel_type invalidARGBChannelDataTypes[] = {CL_SNORM_INT16, CL_UNORM_INT16, CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidARGBChannelFormat, givenValidARGBChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidARGBChannelFormat, givenInvalidARGBChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidARGBChannelFormat,
::testing::Combine(
::testing::ValuesIn(validARGBChannelOrders),
::testing::ValuesIn(validARGBChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidARGBChannelFormat,
::testing::Combine(
::testing::ValuesIn(validARGBChannelOrders),
::testing::ValuesIn(invalidARGBChannelDataTypes)));
typedef ValidImageFormatTest ValidDepthStencilChannelFormat;
typedef InvalidImageFormatTest InvalidDepthStencilChannelFormat;
cl_channel_order validDepthStencilChannelOrders[] = {CL_DEPTH_STENCIL};
cl_channel_type validDepthStencilChannelDataTypes[] = {CL_UNORM_INT24, CL_FLOAT};
cl_channel_type invalidDepthStencilChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16, CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_UNORM_INT_101010_2};
TEST_P(ValidDepthStencilChannelFormat, givenValidDepthStencilChannelImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidDepthStencilChannelFormat, givenInvalidDepthStencilChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidDepthStencilChannelFormat,
::testing::Combine(
::testing::ValuesIn(validDepthStencilChannelOrders),
::testing::ValuesIn(validDepthStencilChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidDepthStencilChannelFormat,
::testing::Combine(
::testing::ValuesIn(validDepthStencilChannelOrders),
::testing::ValuesIn(invalidDepthStencilChannelDataTypes)));
typedef ValidImageFormatTest ValidYUVImageFormat;
typedef InvalidImageFormatTest InvalidYUVImageFormat;
cl_channel_order validYUVChannelOrders[] = {CL_NV12_INTEL, CL_YUYV_INTEL, CL_UYVY_INTEL, CL_YVYU_INTEL, CL_VYUY_INTEL};
cl_channel_type validYUVChannelDataTypes[] = {CL_UNORM_INT8};
cl_channel_type invalidYUVChannelDataTypes[] = {CL_SNORM_INT8, CL_SNORM_INT16, CL_UNORM_INT16, CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010, CL_SIGNED_INT8, CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT, CL_UNORM_INT24, CL_UNORM_INT_101010_2};
TEST_P(ValidYUVImageFormat, givenValidYUVImageFormatWhenValidateImageFormatIsCalledThenReturnsSuccess) {
validateFormat();
};
TEST_P(InvalidYUVImageFormat, givenInvalidYUVChannelDataTypeWhenValidateImageFormatIsCalledThenReturnsError) {
validateFormat();
};
INSTANTIATE_TEST_CASE_P(
ImageValidate,
ValidYUVImageFormat,
::testing::Combine(
::testing::ValuesIn(validYUVChannelOrders),
::testing::ValuesIn(validYUVChannelDataTypes)));
INSTANTIATE_TEST_CASE_P(
ImageValidate,
InvalidYUVImageFormat,
::testing::Combine(
::testing::ValuesIn(validYUVChannelOrders),
::testing::ValuesIn(invalidYUVChannelDataTypes)));
TEST(ImageFormat, givenNullptrImageFormatWhenValidateImageFormatIsCalledThenReturnsError) {
auto retVal = Image::validateImageFormat(nullptr);
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
}
TEST(validateAndCreateImage, givenErrorCodeWhenValidateAndCreateImageIsCalledThenReturnsError) {
cl_image_format imageFormat;
cl_int retVal = CL_INVALID_VALUE;
Image *image;
imageFormat.image_channel_order = 0;
imageFormat.image_channel_data_type = 0;
image = Image::validateAndCreateImage(nullptr, 0, &imageFormat, nullptr, nullptr, retVal);
EXPECT_EQ(nullptr, image);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(validateAndCreateImage, givenInvalidImageFormatWhenValidateAndCreateImageIsCalledThenReturnsInvalidDescriptorError) {
cl_image_format imageFormat;
cl_int retVal = CL_SUCCESS;
Image *image;
imageFormat.image_channel_order = 0;
imageFormat.image_channel_data_type = 0;
image = Image::validateAndCreateImage(nullptr, 0, &imageFormat, nullptr, nullptr, retVal);
EXPECT_EQ(nullptr, image);
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
}
TEST(validateAndCreateImage, givenNotSupportedImageFormatWhenValidateAndCreateImageIsCalledThenReturnsNotSupportedFormatError) {
MockContext context;
cl_image_format imageFormat = {CL_INTENSITY, CL_UNORM_INT8};
cl_int retVal = CL_SUCCESS;
Image *image;
image = Image::validateAndCreateImage(&context, CL_MEM_READ_WRITE, &imageFormat, nullptr, nullptr, retVal);
EXPECT_EQ(nullptr, image);
EXPECT_EQ(CL_IMAGE_FORMAT_NOT_SUPPORTED, retVal);
}
TEST(validateAndCreateImage, givenValidImageParamsWhenValidateAndCreateImageIsCalledThenReturnsSuccess) {
MockContext context;
cl_image_desc imageDesc;
cl_mem_flags flags = CL_MEM_READ_ONLY;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
imageDesc.mem_object = NULL;
// 1D image with 0 row_pitch and 0 slice_pitch
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D;
imageDesc.image_width = 10;
imageDesc.image_height = 0;
imageDesc.image_depth = 0;
imageDesc.image_array_size = 0;
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
cl_image_format imageFormat = {CL_INTENSITY, CL_UNORM_INT8};
cl_int retVal = CL_SUCCESS;
std::unique_ptr<Image> image = nullptr;
image.reset(Image::validateAndCreateImage(
&context,
flags,
&imageFormat,
&imageDesc,
nullptr,
retVal));
EXPECT_NE(nullptr, image);
EXPECT_EQ(CL_SUCCESS, retVal);
}

View File

@@ -0,0 +1,274 @@
/*
* Copyright (c) 2017, 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/mem_obj/mem_obj.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_device.h"
#include "unit_tests/mocks/mock_memory_manager.h"
#include "unit_tests/libult/ult_command_stream_receiver.h"
#include "test.h"
using namespace OCLRT;
template <typename Family>
class MyCsr : public UltCommandStreamReceiver<Family> {
public:
MyCsr(const HardwareInfo &hwInfo) : UltCommandStreamReceiver<Family>(hwInfo) {}
MOCK_METHOD1(waitForFlushStamp, bool(FlushStamp &flushStampToWait));
MOCK_METHOD3(waitForCompletionWithTimeout, bool(bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait));
};
void CL_CALLBACK emptyDestructorCallback(cl_mem memObj, void *userData) {
}
TEST(MemObjDebugFlags, givenDefaultDebugFlagsWhenMemObjDestructorIsCalledThenMemObjDestroysAllocationsSynchronously) {
EXPECT_TRUE(DebugManager.flags.EnableAsyncDestroyAllocations.get());
}
class MemObjDestructionTest : public ::testing::TestWithParam<bool> {
public:
void SetUp() override {
memoryManager = new MockMemoryManager;
device = static_cast<MockDevice *>(context.getDevice(0));
device->injectMemoryManager(memoryManager);
context.setMemoryManager(memoryManager);
allocation = memoryManager->allocateGraphicsMemory(size, MemoryConstants::pageSize);
memObj = new MemObj(&context, CL_MEM_OBJECT_BUFFER,
CL_MEM_READ_WRITE,
size,
nullptr, nullptr, allocation, true, false, false);
*context.getDevice(0)->getTagAddress() = 0;
}
void makeMemObjUsed() {
memObj->getGraphicsAllocation()->taskCount = 3;
}
void makeMemObjNotReady() {
makeMemObjUsed();
*context.getDevice(0)->getTagAddress() = memObj->getGraphicsAllocation()->taskCount - 1;
}
void makeMemObjReady() {
makeMemObjUsed();
*context.getDevice(0)->getTagAddress() = memObj->getGraphicsAllocation()->taskCount;
}
MockDevice *device;
MockMemoryManager *memoryManager;
MockContext context;
GraphicsAllocation *allocation;
MemObj *memObj;
size_t size = MemoryConstants::pageSize;
};
class MemObjAsyncDestructionTest : public MemObjDestructionTest {
public:
void SetUp() override {
DebugManager.flags.EnableAsyncDestroyAllocations.set(true);
MemObjDestructionTest::SetUp();
}
void TearDown() override {
MemObjDestructionTest::TearDown();
DebugManager.flags.EnableAsyncDestroyAllocations.set(defaultFlag);
}
bool defaultFlag = DebugManager.flags.EnableAsyncDestroyAllocations.get();
};
class MemObjSyncDestructionTest : public MemObjDestructionTest {
public:
void SetUp() override {
DebugManager.flags.EnableAsyncDestroyAllocations.set(false);
MemObjDestructionTest::SetUp();
}
void TearDown() override {
MemObjDestructionTest::TearDown();
DebugManager.flags.EnableAsyncDestroyAllocations.set(defaultFlag);
}
bool defaultFlag = DebugManager.flags.EnableAsyncDestroyAllocations.get();
};
TEST_P(MemObjAsyncDestructionTest, givenMemObjWithDestructableAllocationWhenAsyncDestructionsAreEnabledAndAllocationIsNotReadyAndMemObjectIsDestructedThenAllocationIsDeferred) {
bool isMemObjReady;
bool expectedDeferration;
isMemObjReady = GetParam();
expectedDeferration = !isMemObjReady;
if (isMemObjReady) {
makeMemObjReady();
} else {
makeMemObjNotReady();
}
EXPECT_TRUE(memoryManager->isAllocationListEmpty());
delete memObj;
EXPECT_EQ(!expectedDeferration, memoryManager->isAllocationListEmpty());
if (expectedDeferration) {
EXPECT_EQ(allocation, memoryManager->peekAllocationListHead());
}
}
HWTEST_P(MemObjAsyncDestructionTest, givenUsedMemObjWithAsyncDestructionsEnabledThatHasDestructorCallbacksWhenItIsDestroyedThenDestructorWaitsOnTaskCount) {
makeMemObjUsed();
bool hasCallbacks = GetParam();
if (hasCallbacks) {
memObj->setDestructorCallback(emptyDestructorCallback, nullptr);
}
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(device->getHardwareInfo());
device->resetCommandStreamReceiver(mockCsr);
bool desired = true;
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return desired; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
if (hasCallbacks) {
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, TimeoutControls::maxTimeout, allocation->taskCount)).Times(1);
} else {
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).Times(0);
}
delete memObj;
}
HWTEST_P(MemObjAsyncDestructionTest, givenUsedMemObjWithAsyncDestructionsEnabledThatHasAllocatedMappedPtrWhenItIsDestroyedThenDestructorWaitsOnTaskCount) {
makeMemObjUsed();
bool hasAllocatedMappedPtr = GetParam();
if (hasAllocatedMappedPtr) {
auto allocatedPtr = alignedMalloc(size, MemoryConstants::pageSize);
memObj->setAllocatedMappedPtr(allocatedPtr);
}
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(device->getHardwareInfo());
device->resetCommandStreamReceiver(mockCsr);
bool desired = true;
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return desired; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
if (hasAllocatedMappedPtr) {
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, TimeoutControls::maxTimeout, allocation->taskCount)).Times(1);
} else {
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).Times(0);
}
delete memObj;
}
HWTEST_P(MemObjAsyncDestructionTest, givenUsedMemObjWithAsyncDestructionsEnabledThatHasDestructableMappedPtrWhenItIsDestroyedThenDestructorWaitsOnTaskCount) {
auto storage = alignedMalloc(size, MemoryConstants::pageSize);
bool hasAllocatedMappedPtr = GetParam();
if (!hasAllocatedMappedPtr) {
delete memObj;
allocation = memoryManager->allocateGraphicsMemory(size, MemoryConstants::pageSize);
memObj = new MemObj(&context, CL_MEM_OBJECT_BUFFER,
CL_MEM_READ_WRITE,
size,
storage, nullptr, allocation, true, false, false);
}
memObj->setMappedPtr(storage);
makeMemObjUsed();
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(device->getHardwareInfo());
device->resetCommandStreamReceiver(mockCsr);
bool desired = true;
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return desired; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
if (hasAllocatedMappedPtr) {
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, TimeoutControls::maxTimeout, allocation->taskCount)).Times(1);
} else {
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).Times(0);
}
delete memObj;
if (!hasAllocatedMappedPtr) {
alignedFree(storage);
}
}
HWTEST_P(MemObjSyncDestructionTest, givenMemObjWithDestructableAllocationWhenAsyncDestructionsAreDisabledThenDestructorWaitsOnTaskCount) {
bool isMemObjReady;
isMemObjReady = GetParam();
if (isMemObjReady) {
makeMemObjReady();
} else {
makeMemObjNotReady();
}
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(device->getHardwareInfo());
device->resetCommandStreamReceiver(mockCsr);
bool desired = true;
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return desired; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
EXPECT_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, TimeoutControls::maxTimeout, allocation->taskCount)).Times(1);
delete memObj;
}
HWTEST_P(MemObjSyncDestructionTest, givenMemObjWithDestructableAllocationWhenAsyncDestructionsAreDisabledThenAllocationIsNotDeferred) {
bool isMemObjReady;
isMemObjReady = GetParam();
if (isMemObjReady) {
makeMemObjReady();
} else {
makeMemObjNotReady();
}
auto mockCsr = new ::testing::NiceMock<MyCsr<FamilyType>>(device->getHardwareInfo());
device->resetCommandStreamReceiver(mockCsr);
bool desired = true;
auto waitForCompletionWithTimeoutMock = [=](bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait) -> bool { return desired; };
ON_CALL(*mockCsr, waitForCompletionWithTimeout(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(waitForCompletionWithTimeoutMock));
delete memObj;
EXPECT_TRUE(memoryManager->isAllocationListEmpty());
}
INSTANTIATE_TEST_CASE_P(
MemObjTests,
MemObjAsyncDestructionTest,
testing::Bool());
INSTANTIATE_TEST_CASE_P(
MemObjTests,
MemObjSyncDestructionTest,
testing::Bool());

View File

@@ -0,0 +1,216 @@
/*
* Copyright (c) 2017, 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/mem_obj/mem_obj.h"
#include "runtime/device/device.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_deferred_deleter.h"
#include "unit_tests/mocks/mock_graphics_allocation.h"
#include "unit_tests/mocks/mock_memory_manager.h"
#include "gtest/gtest.h"
using namespace OCLRT;
TEST(MemObj, useCount) {
char buffer[64];
MockContext context;
MockGraphicsAllocation *mockAllocation = new MockGraphicsAllocation(buffer, sizeof(buffer));
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
sizeof(buffer), buffer, buffer, mockAllocation, true, false, false);
EXPECT_EQ(ObjectNotResident, memObj.getGraphicsAllocation()->residencyTaskCount);
memObj.getGraphicsAllocation()->residencyTaskCount = 1;
EXPECT_EQ(1, memObj.getGraphicsAllocation()->residencyTaskCount);
memObj.getGraphicsAllocation()->residencyTaskCount--;
EXPECT_EQ(0, memObj.getGraphicsAllocation()->residencyTaskCount);
}
TEST(MemObj, GivenMemObjWhenInititalizedFromHostPtrThenInitializeFields) {
const size_t size = 64;
char buffer[size];
MockContext context;
MockGraphicsAllocation *mockAllocation = new MockGraphicsAllocation(buffer, sizeof(buffer));
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
sizeof(buffer), buffer, buffer, mockAllocation, true, false, false);
EXPECT_EQ(&buffer, memObj.getCpuAddress());
EXPECT_EQ(&buffer, memObj.getHostPtr());
EXPECT_EQ(size, memObj.getSize());
EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_USE_HOST_PTR), memObj.getFlags());
EXPECT_EQ(nullptr, memObj.getMappedPtr());
EXPECT_EQ(0u, memObj.getMappedSize());
EXPECT_EQ(0u, memObj.getMappedOffset());
}
TEST(MemObj, GivenMemObjectWhenAskedForTransferDataThenNullPtrIsReturned) {
char buffer[64];
MockContext context;
MockGraphicsAllocation *mockAllocation = new MockGraphicsAllocation(buffer, sizeof(buffer));
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
sizeof(buffer), buffer, buffer, mockAllocation, true, false, false);
auto ptr = memObj.transferDataToHostPtr();
EXPECT_EQ(nullptr, ptr);
}
TEST(MemObj, givenMemObjWhenAllocatedMappedPtrIsSetThenGetMappedPtrReturnsAllocatedMappedPtr) {
void *mockPtr = (void *)0x01234;
MockContext context;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
1, nullptr, nullptr, nullptr, true, false, false);
EXPECT_EQ(nullptr, memObj.getAllocatedMappedPtr());
EXPECT_EQ(nullptr, memObj.getMappedPtr());
memObj.setAllocatedMappedPtr(mockPtr);
EXPECT_EQ(mockPtr, memObj.getAllocatedMappedPtr());
EXPECT_EQ(mockPtr, memObj.getMappedPtr());
memObj.setAllocatedMappedPtr(nullptr);
}
TEST(MemObj, givenMemObjWhenAllocatedMappedPtrAndMappedPtrAreSetThenGetMappedPtrReturnsAllocatedMappedPtr) {
void *mockPtr = (void *)0x01234;
void *mockAllocatedPtr = (void *)0x01235;
EXPECT_NE(mockPtr, mockAllocatedPtr);
MockContext context;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
1, nullptr, nullptr, nullptr, true, false, false);
memObj.setAllocatedMappedPtr(mockAllocatedPtr);
memObj.setMappedPtr(mockPtr);
EXPECT_EQ(mockAllocatedPtr, memObj.getAllocatedMappedPtr());
EXPECT_EQ(mockAllocatedPtr, memObj.getMappedPtr());
memObj.setAllocatedMappedPtr(nullptr);
memObj.setMappedPtr(nullptr);
}
TEST(MemObj, givenMemObjWhenReleaseAllocatedPtrIsCalledTwiceThenItDoesntCrash) {
void *allocatedPtr = alignedMalloc(MemoryConstants::cacheLineSize, MemoryConstants::cacheLineSize);
MockContext context;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
1, nullptr, nullptr, nullptr, true, false, false);
memObj.setAllocatedMappedPtr(allocatedPtr);
memObj.releaseAllocatedMappedPtr();
EXPECT_EQ(nullptr, memObj.getAllocatedMappedPtr());
memObj.releaseAllocatedMappedPtr();
EXPECT_EQ(nullptr, memObj.getAllocatedMappedPtr());
}
TEST(MemObj, givenNotReadyGraphicsAllocationWhenMemObjDestroysAllocationAsyncThenAllocationIsAddedToMemoryManagerAllocationList) {
MockMemoryManager memoryManager;
MockContext context;
context.setMemoryManager(&memoryManager);
memoryManager.setDevice(context.getDevice(0));
auto allocation = memoryManager.allocateGraphicsMemory(MemoryConstants::pageSize, MemoryConstants::pageSize);
allocation->taskCount = 2;
*memoryManager.device->getTagAddress() = 1;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_COPY_HOST_PTR,
MemoryConstants::pageSize, nullptr, nullptr, nullptr, true, false, false);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
memObj.destroyGraphicsAllocation(allocation, true);
EXPECT_FALSE(memoryManager.isAllocationListEmpty());
}
TEST(MemObj, givenReadyGraphicsAllocationWhenMemObjDestroysAllocationAsyncThenAllocationIsNotAddedToMemoryManagerAllocationList) {
MockMemoryManager memoryManager;
MockContext context;
context.setMemoryManager(&memoryManager);
memoryManager.setDevice(context.getDevice(0));
auto allocation = memoryManager.allocateGraphicsMemory(MemoryConstants::pageSize, MemoryConstants::pageSize);
allocation->taskCount = 1;
*memoryManager.device->getTagAddress() = 1;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_COPY_HOST_PTR,
MemoryConstants::pageSize, nullptr, nullptr, nullptr, true, false, false);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
memObj.destroyGraphicsAllocation(allocation, true);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
}
TEST(MemObj, givenNotUsedGraphicsAllocationWhenMemObjDestroysAllocationAsyncThenAllocationIsNotAddedToMemoryManagerAllocationList) {
MockMemoryManager memoryManager;
MockContext context;
context.setMemoryManager(&memoryManager);
memoryManager.setDevice(context.getDevice(0));
auto allocation = memoryManager.allocateGraphicsMemory(MemoryConstants::pageSize, MemoryConstants::pageSize);
allocation->taskCount = ObjectNotUsed;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_COPY_HOST_PTR,
MemoryConstants::pageSize, nullptr, nullptr, nullptr, true, false, false);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
memObj.destroyGraphicsAllocation(allocation, true);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
}
TEST(MemObj, givenMemoryManagerWithoutDeviceWhenMemObjDestroysAllocationAsyncThenAllocationIsNotAddedToMemoryManagerAllocationList) {
MockMemoryManager memoryManager;
MockContext context;
context.setMemoryManager(&memoryManager);
auto allocation = memoryManager.allocateGraphicsMemory(MemoryConstants::pageSize, MemoryConstants::pageSize);
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_COPY_HOST_PTR,
MemoryConstants::pageSize, nullptr, nullptr, nullptr, true, false, false);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
memObj.destroyGraphicsAllocation(allocation, true);
EXPECT_TRUE(memoryManager.isAllocationListEmpty());
}
TEST(MemObj, givenMemObjWhenItDoesntHaveGraphicsAllocationThenWaitForCsrCompletionDoesntCrash) {
MockMemoryManager memoryManager;
MockContext context;
context.setMemoryManager(&memoryManager);
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_COPY_HOST_PTR,
MemoryConstants::pageSize, nullptr, nullptr, nullptr, true, false, false);
EXPECT_EQ(nullptr, memoryManager.device);
EXPECT_EQ(nullptr, memObj.getGraphicsAllocation());
memObj.waitForCsrCompletion();
memoryManager.setDevice(context.getDevice(0));
EXPECT_NE(nullptr, memoryManager.device);
EXPECT_EQ(nullptr, memObj.getGraphicsAllocation());
memObj.waitForCsrCompletion();
}

View File

@@ -0,0 +1,590 @@
/*
* Copyright (c) 2017, 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/helpers/surface_formats.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/gmm_helper/gmm_helper.h"
#include "runtime/mem_obj/image.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "unit_tests/helpers/kernel_binary_helper.h"
#include "unit_tests/mocks/mock_buffer.h"
#include "unit_tests/mocks/mock_command_queue.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_gmm_resource_info.h"
#include "gtest/gtest.h"
#include "test.h"
using namespace OCLRT;
class Nv12ImageTest : public testing::Test {
public:
void computeExpectedOffsets(Image *image) {
SurfaceOffsets expectedSurfaceOffsets = {};
GMM_REQ_OFFSET_INFO reqOffsetInfo = {};
SurfaceOffsets requestedOffsets = {};
auto mockResInfo = reinterpret_cast<::testing::NiceMock<MockGmmResourceInfo> *>(image->getGraphicsAllocation()->gmm->gmmResourceInfo.get());
mockResInfo->getOffset(reqOffsetInfo);
if (image->getImageDesc().mem_object) {
expectedSurfaceOffsets.offset = reqOffsetInfo.Render.Offset;
expectedSurfaceOffsets.xOffset = reqOffsetInfo.Render.XOffset / (mockResInfo->getBitsPerPixel() / 8);
expectedSurfaceOffsets.yOffset = reqOffsetInfo.Render.YOffset;
}
expectedSurfaceOffsets.yOffsetForUVplane = reqOffsetInfo.Lock.Offset / reqOffsetInfo.Lock.Pitch;
image->getSurfaceOffsets(requestedOffsets);
EXPECT_TRUE(memcmp(&expectedSurfaceOffsets, &requestedOffsets, sizeof(SurfaceOffsets)) == 0);
}
protected:
void SetUp() override {
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_NV12_INTEL;
imageDesc.mem_object = NULL;
imageDesc.image_array_size = 0;
imageDesc.image_depth = 1;
imageDesc.image_height = 4 * 4; // Valid values multiple of 4
imageDesc.image_width = 4 * 4; // Valid values multiple of 4
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
flags = CL_MEM_HOST_NO_ACCESS;
}
void validateImageWithFlags(cl_mem_flags flags) {
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, nullptr);
}
Image *createImageWithFlags(cl_mem_flags flags) {
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
return Image::create(&context, flags, surfaceFormat, &imageDesc, nullptr, retVal);
}
cl_int retVal = CL_SUCCESS;
MockContext context;
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_mem_flags flags;
};
TEST_F(Nv12ImageTest, isNV12ImageReturnsTrue) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
EXPECT_TRUE(IsNV12Image(&image->getImageFormat()));
delete image;
}
TEST_F(Nv12ImageTest, validNV12ImageFormatAndDescriptor) {
validateImageWithFlags(flags);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_F(Nv12ImageTest, invalidNV12ImageFormat) {
imageFormat.image_channel_data_type = CL_SNORM_INT16;
validateImageWithFlags(flags);
EXPECT_EQ(CL_IMAGE_FORMAT_NOT_SUPPORTED, retVal);
}
TEST_F(Nv12ImageTest, invalidNV12ImageType) {
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D;
validateImageWithFlags(flags);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_F(Nv12ImageTest, DISABLED_invalidNV12ImageDepth) {
imageDesc.image_depth = 2;
validateImageWithFlags(flags);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_F(Nv12ImageTest, invalidNV12ImageHeigth) {
imageDesc.image_height = 17;
validateImageWithFlags(flags);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_F(Nv12ImageTest, invalidNV12ImageWidth) {
imageDesc.image_width = 17;
validateImageWithFlags(flags);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_F(Nv12ImageTest, invalidNV12ImageFlag) {
flags &= ~(CL_MEM_HOST_NO_ACCESS);
validateImageWithFlags(flags);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST_F(Nv12ImageTest, validateNV12YPlane) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
imageDesc.mem_object = image;
imageDesc.image_depth = 0; // Plane Y of NV12 image
validateImageWithFlags(CL_MEM_READ_WRITE);
EXPECT_EQ(CL_SUCCESS, retVal);
delete image;
}
TEST_F(Nv12ImageTest, validateNV12YUVPlane) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
imageDesc.mem_object = image;
imageDesc.image_depth = 1; // Plane UV of NV12 image
validateImageWithFlags(CL_MEM_READ_WRITE);
EXPECT_EQ(CL_SUCCESS, retVal);
delete image;
}
TEST_F(Nv12ImageTest, givenNV12ImageWhenInvalidDepthIsPassedThenValidateFails) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
imageDesc.mem_object = image;
imageDesc.image_depth = 3; // Invalid Plane of NV12 image
validateImageWithFlags(CL_MEM_READ_WRITE);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
delete image;
}
TEST_F(Nv12ImageTest, given2DImageWhenPassedToValidateImageTraitsThenValidateReturnsSuccess) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
imageDesc.mem_object = image;
imageDesc.image_depth = 0;
retVal = Image::validateImageTraits(&context, CL_MEM_READ_WRITE, &imageFormat, &imageDesc, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
delete image;
}
TEST_F(Nv12ImageTest, given1DImageWhenPassedAsParentImageThenValidateImageTraitsReturnsSuccess) {
imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D;
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
imageDesc.mem_object = image;
imageDesc.image_depth = 0;
retVal = Image::validateImageTraits(&context, CL_MEM_READ_WRITE, &imageFormat, &imageDesc, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
delete image;
}
TEST_F(Nv12ImageTest, givenBufferWhenPassedAsNV12ParentImageThenValidateImageTraitsReturnsInvalidDesriptor) {
MockBuffer Buffer;
imageDesc.mem_object = &Buffer;
imageDesc.image_depth = 0; // Plane of NV12 image
retVal = Image::validateImageTraits(&context, CL_MEM_READ_WRITE, &imageFormat, &imageDesc, nullptr);
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
TEST_F(Nv12ImageTest, createNV12Image) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
auto rowPitch = image->getHostPtrRowPitch();
EXPECT_NE(0u, rowPitch);
SurfaceOffsets surfaceOffsets;
image->getSurfaceOffsets(surfaceOffsets);
EXPECT_EQ(0u, surfaceOffsets.offset);
EXPECT_EQ(0u, surfaceOffsets.xOffset);
EXPECT_EQ(0u, surfaceOffsets.yOffset);
EXPECT_NE(0u, surfaceOffsets.yOffsetForUVplane);
delete image;
}
TEST_F(Nv12ImageTest, createNV12YPlaneImage) {
// Create Parent NV12 image
auto imageNV12 = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, imageNV12);
imageDesc.mem_object = imageNV12;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_R;
imageDesc.image_width = 0;
imageDesc.image_height = 0;
imageDesc.image_depth = 0;
// Create NV12 Y Plane image
auto imageYPlane = createImageWithFlags(CL_MEM_READ_WRITE);
ASSERT_NE(nullptr, imageYPlane);
EXPECT_EQ(imageNV12->getGraphicsAllocation(), imageYPlane->getGraphicsAllocation());
cl_image_desc parentDimensions, planeDimensions;
parentDimensions = imageNV12->getImageDesc();
planeDimensions = imageYPlane->getImageDesc();
EXPECT_EQ(parentDimensions.image_height, planeDimensions.image_height);
EXPECT_EQ(parentDimensions.image_width, planeDimensions.image_width);
EXPECT_EQ(0u, planeDimensions.image_depth);
EXPECT_NE(0u, planeDimensions.image_row_pitch);
EXPECT_EQ(parentDimensions.image_slice_pitch, planeDimensions.image_slice_pitch);
EXPECT_EQ(parentDimensions.image_type, planeDimensions.image_type);
EXPECT_EQ(parentDimensions.image_array_size, planeDimensions.image_array_size);
computeExpectedOffsets(imageYPlane);
computeExpectedOffsets(imageNV12);
delete imageYPlane;
delete imageNV12;
}
TEST_F(Nv12ImageTest, createNV12UVPlaneImage) {
// Create Parent NV12 image
auto imageNV12 = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, imageNV12);
imageDesc.mem_object = imageNV12;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_R;
imageDesc.image_width = 0;
imageDesc.image_height = 0;
imageDesc.image_depth = 1; // UV plane
// Create NV12 UV Plane image
auto imageUVPlane = createImageWithFlags(CL_MEM_READ_WRITE);
ASSERT_NE(nullptr, imageUVPlane);
EXPECT_EQ(imageNV12->getGraphicsAllocation(), imageUVPlane->getGraphicsAllocation());
cl_image_desc parentDimensions, planeDimensions;
parentDimensions = imageNV12->getImageDesc();
planeDimensions = imageUVPlane->getImageDesc();
EXPECT_EQ(parentDimensions.image_height / 2, planeDimensions.image_height);
EXPECT_EQ(parentDimensions.image_width / 2, planeDimensions.image_width);
EXPECT_EQ(0u, planeDimensions.image_depth);
EXPECT_EQ(parentDimensions.image_row_pitch, planeDimensions.image_row_pitch);
EXPECT_NE(0u, planeDimensions.image_row_pitch);
EXPECT_EQ(parentDimensions.image_slice_pitch, planeDimensions.image_slice_pitch);
EXPECT_EQ(parentDimensions.image_type, planeDimensions.image_type);
EXPECT_EQ(parentDimensions.image_array_size, planeDimensions.image_array_size);
computeExpectedOffsets(imageUVPlane);
computeExpectedOffsets(imageNV12);
delete imageUVPlane;
delete imageNV12;
}
TEST_F(Nv12ImageTest, createNV12UVPlaneImageWithOffsetOfUVPlane) {
// This size returns offset of UV plane, and 0 yOffset
imageDesc.image_height = 64; // Valid values multiple of 4
imageDesc.image_width = 64; // Valid values multiple of 4
// Create Parent NV12 image
auto imageNV12 = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, imageNV12);
imageDesc.mem_object = imageNV12;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_R;
imageDesc.image_width = 0;
imageDesc.image_height = 0;
imageDesc.image_depth = 1; // UV plane
// Create NV12 UV Plane image
auto imageUVPlane = createImageWithFlags(CL_MEM_READ_WRITE);
ASSERT_NE(nullptr, imageUVPlane);
EXPECT_EQ(imageNV12->getGraphicsAllocation(), imageUVPlane->getGraphicsAllocation());
cl_image_desc parentDimensions, planeDimensions;
parentDimensions = imageNV12->getImageDesc();
planeDimensions = imageUVPlane->getImageDesc();
EXPECT_EQ(parentDimensions.image_height / 2, planeDimensions.image_height);
EXPECT_EQ(parentDimensions.image_width / 2, planeDimensions.image_width);
EXPECT_EQ(0u, planeDimensions.image_depth);
EXPECT_EQ(parentDimensions.image_row_pitch, planeDimensions.image_row_pitch);
EXPECT_NE(0u, planeDimensions.image_row_pitch);
EXPECT_EQ(parentDimensions.image_slice_pitch, planeDimensions.image_slice_pitch);
EXPECT_EQ(parentDimensions.image_type, planeDimensions.image_type);
EXPECT_EQ(parentDimensions.image_array_size, planeDimensions.image_array_size);
computeExpectedOffsets(imageUVPlane);
computeExpectedOffsets(imageNV12);
delete imageUVPlane;
delete imageNV12;
}
HWTEST_F(Nv12ImageTest, checkIfPlanesAreWritten) {
KernelBinaryHelper kbHelper(KernelBinaryHelper::BUILT_INS);
auto device = std::unique_ptr<Device>(DeviceHelper<>::create());
char hostPtr[16 * 16 * 16];
MockContext contextWithMockCmdQ(device.get(), true);
MockCommandQueueHw<FamilyType> cmdQ(&contextWithMockCmdQ, device.get(), 0);
contextWithMockCmdQ.setSpecialQueue(&cmdQ);
// Create Parent NV12 image
cl_mem_flags flags = CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL | CL_MEM_USE_HOST_PTR;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto imageNV12 = Image::create(&contextWithMockCmdQ, flags, surfaceFormat, &imageDesc, hostPtr, retVal);
EXPECT_EQ(2u, cmdQ.EnqueueWriteImageCounter);
contextWithMockCmdQ.setSpecialQueue(nullptr);
ASSERT_NE(nullptr, imageNV12);
delete imageNV12;
}
HWTEST_F(Nv12ImageTest, setImageArg) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState;
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
SurfaceOffsets surfaceOffsets;
image->getSurfaceOffsets(surfaceOffsets);
image->setImageArg(&surfaceState, false);
EXPECT_EQ(surfaceOffsets.xOffset, surfaceState.getXOffset());
EXPECT_EQ(surfaceOffsets.yOffset, surfaceState.getYOffset());
EXPECT_EQ(surfaceOffsets.yOffsetForUVplane, surfaceState.getYOffsetForUOrUvPlane());
// NV 12 image has correct alpha channel == one
EXPECT_EQ(RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ALPHA_ONE, surfaceState.getShaderChannelSelectAlpha());
delete image;
}
HWTEST_F(Nv12ImageTest, setImageArgUVPlaneImageSetsOffsetedSurfaceBaseAddressAndSetsCorrectTileMode) {
typedef typename FamilyType::RENDER_SURFACE_STATE RENDER_SURFACE_STATE;
RENDER_SURFACE_STATE surfaceState;
// Create Parent NV12 image
auto imageNV12 = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, imageNV12);
imageDesc.mem_object = imageNV12;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_R;
imageDesc.image_width = 0;
imageDesc.image_height = 0;
imageDesc.image_depth = 1; // UV plane
// Create NV12 UV Plane image
auto imageUVPlane = createImageWithFlags(CL_MEM_READ_WRITE);
ASSERT_NE(nullptr, imageUVPlane);
EXPECT_EQ(imageNV12->getGraphicsAllocation(), imageUVPlane->getGraphicsAllocation());
SurfaceOffsets surfaceOffsets;
imageUVPlane->getSurfaceOffsets(surfaceOffsets);
imageUVPlane->setImageArg(&surfaceState, false);
EXPECT_EQ(imageUVPlane->getGraphicsAllocation()->getGpuAddress() + surfaceOffsets.offset, surfaceState.getSurfaceBaseAddress());
auto tileMode = RENDER_SURFACE_STATE::TILE_MODE_LINEAR;
if (imageNV12->allowTiling()) {
tileMode = RENDER_SURFACE_STATE::TILE_MODE_YMAJOR;
}
EXPECT_EQ(tileMode, surfaceState.getTileMode());
delete imageUVPlane;
delete imageNV12;
}
HWTEST_F(Nv12ImageTest, setMediaImageArg) {
using MEDIA_SURFACE_STATE = typename FamilyType::MEDIA_SURFACE_STATE;
MEDIA_SURFACE_STATE surfaceState;
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
SurfaceOffsets surfaceOffsets;
image->getSurfaceOffsets(surfaceOffsets);
image->setMediaImageArg(&surfaceState);
EXPECT_EQ(surfaceOffsets.xOffset, surfaceState.getXOffsetForUCb());
EXPECT_EQ(surfaceOffsets.yOffset, surfaceState.getXOffsetForUCb());
EXPECT_EQ(surfaceOffsets.yOffsetForUVplane, surfaceState.getYOffsetForUCb());
EXPECT_EQ(image->getGraphicsAllocation()->getGpuAddress() + surfaceOffsets.offset,
surfaceState.getSurfaceBaseAddress());
delete image;
}
TEST_F(Nv12ImageTest, redescribedNV12ImageAndUVPlaneImageHasCorrectOffsets) {
auto image = createImageWithFlags(CL_MEM_READ_ONLY | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL);
ASSERT_NE(nullptr, image);
auto imageRedescribed = image->redescribe();
ASSERT_NE(nullptr, imageRedescribed);
SurfaceOffsets imageOffsets, redescribedOffsets;
image->getSurfaceOffsets(imageOffsets);
imageRedescribed->getSurfaceOffsets(redescribedOffsets);
EXPECT_EQ(imageOffsets.xOffset, redescribedOffsets.xOffset);
EXPECT_EQ(imageOffsets.yOffset, redescribedOffsets.yOffset);
EXPECT_EQ(imageOffsets.yOffsetForUVplane, redescribedOffsets.yOffsetForUVplane);
delete imageRedescribed;
imageDesc.mem_object = image;
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = CL_R;
imageDesc.image_width = 0;
imageDesc.image_height = 0;
imageDesc.image_depth = 1; // UV plane
// Create NV12 UV Plane image
auto imageUVPlane = createImageWithFlags(CL_MEM_READ_WRITE);
ASSERT_NE(nullptr, imageUVPlane);
imageRedescribed = imageUVPlane->redescribe();
ASSERT_NE(nullptr, imageRedescribed);
imageUVPlane->getSurfaceOffsets(imageOffsets);
imageRedescribed->getSurfaceOffsets(redescribedOffsets);
EXPECT_EQ(imageOffsets.xOffset, redescribedOffsets.xOffset);
EXPECT_EQ(imageOffsets.yOffset, redescribedOffsets.yOffset);
EXPECT_EQ(imageOffsets.yOffsetForUVplane, redescribedOffsets.yOffsetForUVplane);
delete imageRedescribed;
delete imageUVPlane;
delete image;
}
TEST_F(Nv12ImageTest, invalidPlanarYUVImageHeight) {
auto pDevice = context.getDevice(0);
const size_t *maxHeight = nullptr;
size_t srcSize = 0;
size_t retSize = 0;
ASSERT_NE(nullptr, pDevice);
pDevice->getCap<CL_DEVICE_PLANAR_YUV_MAX_HEIGHT_INTEL>(reinterpret_cast<const void *&>(maxHeight), srcSize, retSize);
imageDesc.image_height = *maxHeight + 12;
retVal = Image::validatePlanarYUV(&context, flags, &imageDesc, nullptr);
EXPECT_EQ(CL_INVALID_IMAGE_SIZE, retVal);
}
TEST_F(Nv12ImageTest, invalidPlanarYUVImageWidth) {
auto pDevice = context.getDevice(0);
const size_t *maxWidth = nullptr;
size_t srcSize = 0;
size_t retSize = 0;
ASSERT_NE(nullptr, pDevice);
pDevice->getCap<CL_DEVICE_PLANAR_YUV_MAX_WIDTH_INTEL>(reinterpret_cast<const void *&>(maxWidth), srcSize, retSize);
imageDesc.image_width = *maxWidth + 12;
retVal = Image::validatePlanarYUV(&context, flags, &imageDesc, nullptr);
EXPECT_EQ(CL_INVALID_IMAGE_SIZE, retVal);
}
TEST_F(Nv12ImageTest, validPlanarYUVImageHeight) {
retVal = Image::validatePlanarYUV(&context, flags, &imageDesc, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_F(Nv12ImageTest, validPlanarYUVImageWidth) {
retVal = Image::validatePlanarYUV(&context, flags, &imageDesc, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2017, 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/helpers/surface_formats.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/mem_obj/image.h"
#include "runtime/helpers/validators.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_buffer.h"
#include "unit_tests/mocks/mock_command_queue.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
#include "test.h"
using namespace OCLRT;
typedef decltype(&Image::redescribe) RedescribeMethod;
class PackedYuvImageTest : public testing::Test,
public testing::WithParamInterface<unsigned int> {
public:
PackedYuvImageTest() {
}
protected:
void SetUp() override {
imageFormat.image_channel_data_type = CL_UNORM_INT8;
imageFormat.image_channel_order = GetParam();
imageDesc.mem_object = nullptr;
imageDesc.image_array_size = 0;
imageDesc.image_depth = 1;
imageDesc.image_height = 13;
imageDesc.image_width = 16; // Valid values multiple of 2
imageDesc.image_row_pitch = 0;
imageDesc.image_slice_pitch = 0;
imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
imageDesc.num_mip_levels = 0;
imageDesc.num_samples = 0;
}
void TearDown() override {
}
void validateFormat() {
retVal = Image::validateImageFormat(&imageFormat);
if (retVal != CL_SUCCESS)
return;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, nullptr);
}
cl_int retVal = CL_SUCCESS;
MockContext context;
cl_image_format imageFormat;
cl_image_desc imageDesc;
cl_mem_flags flags;
};
cl_channel_order packedYuvChannels[] = {CL_YUYV_INTEL, CL_UYVY_INTEL, CL_YVYU_INTEL, CL_VYUY_INTEL};
TEST_P(PackedYuvImageTest, isPackedYuvImageReturnsTrue) {
flags = CL_MEM_READ_ONLY;
auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat);
auto image = Image::create(
&context,
flags,
surfaceFormat,
&imageDesc,
nullptr,
retVal);
ASSERT_NE(nullptr, image);
EXPECT_TRUE(IsPackedYuvImage(&image->getImageFormat()));
delete image;
}
TEST_P(PackedYuvImageTest, validPackedYuvImageFormatAndDescriptor) {
flags = CL_MEM_READ_ONLY;
validateFormat();
EXPECT_EQ(CL_SUCCESS, retVal);
}
TEST_P(PackedYuvImageTest, invalidPackedYuvImageFormat) {
imageFormat.image_channel_data_type = CL_SNORM_INT16;
flags = CL_MEM_READ_ONLY;
validateFormat();
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
}
TEST_P(PackedYuvImageTest, invalidPackedYuvImageWidth) {
imageDesc.image_width = 17;
flags = CL_MEM_READ_ONLY;
validateFormat();
EXPECT_EQ(CL_INVALID_IMAGE_DESCRIPTOR, retVal);
}
INSTANTIATE_TEST_CASE_P(
PackedYuvImageTests,
PackedYuvImageTest,
testing::ValuesIn(packedYuvChannels));

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2017, 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/command_queue/command_queue.h"
#include "runtime/mem_obj/pipe.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "test.h"
using namespace OCLRT;
//Tests for pipes
class PipeTest : public DeviceFixture, public ::testing::Test, public MemoryManagementFixture {
public:
PipeTest() {}
protected:
void SetUp() override {
}
void TearDown() override {
}
cl_int retVal = CL_SUCCESS;
MockContext context;
size_t size;
};
TEST_F(PipeTest, CreatePipe) {
int errCode = CL_SUCCESS;
auto pipe = Pipe::create(&context, CL_MEM_READ_ONLY, 1, 20, nullptr, errCode);
EXPECT_NE(nullptr, pipe);
EXPECT_EQ(CL_SUCCESS, errCode);
delete pipe;
}
TEST_F(PipeTest, PipeCheckReservedHeaderSizeAddition) {
int errCode = CL_SUCCESS;
auto pipe = Pipe::create(&context, CL_MEM_READ_ONLY, 1, 20, nullptr, errCode);
ASSERT_NE(nullptr, pipe);
EXPECT_EQ(CL_SUCCESS, errCode);
EXPECT_EQ((1 * (20 + 1)) + Pipe::intelPipeHeaderReservedSpace, pipe->getSize());
delete pipe;
}
TEST_F(PipeTest, PipeCheckHeaderinitialization) {
int errCode = CL_SUCCESS;
auto pipe = Pipe::create(&context, CL_MEM_READ_ONLY, 1, 20, nullptr, errCode);
ASSERT_NE(nullptr, pipe);
EXPECT_EQ(CL_SUCCESS, errCode);
EXPECT_EQ(21u, *reinterpret_cast<unsigned int *>(pipe->getCpuAddress()));
delete pipe;
}
TEST_F(PipeTest, FailedAllocationInjection) {
InjectedFunction method = [this](size_t failureIndex) {
auto retVal = CL_INVALID_VALUE;
auto pipe = Pipe::create(&context, CL_MEM_READ_ONLY, 1, 20, nullptr, retVal);
if (nonfailingAllocation == failureIndex) {
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, pipe);
delete pipe;
} else {
EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal) << "for allocation " << failureIndex;
EXPECT_EQ(nullptr, pipe);
}
};
injectFailures(method);
}
TEST_F(PipeTest, givenPipeWhenUnmapIsCalledThenReturnError) {
int errCode = CL_SUCCESS;
auto pipe = Pipe::create(&context, CL_MEM_READ_ONLY, 1, 20, nullptr, errCode);
ASSERT_NE(nullptr, pipe);
EXPECT_EQ(CL_SUCCESS, errCode);
auto cmdQ = CommandQueue::create(&context, context.getDevice(0), 0, errCode);
EXPECT_EQ(CL_SUCCESS, errCode);
errCode = pipe->unmapObj(cmdQ, nullptr, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_MEM_OBJECT, errCode);
delete pipe;
delete cmdQ;
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2017, 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/helpers/ptr_math.h"
#include "runtime/mem_obj/buffer.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/helpers/memory_management.h"
#include "unit_tests/mocks/mock_buffer.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
using namespace OCLRT;
namespace ULT {
static const unsigned int sizeTestBufferInBytes = 32;
class SubBufferTest : public DeviceFixture,
public MemoryManagementFixture,
public ::testing::Test {
public:
SubBufferTest() {
}
protected:
void SetUp() override {
buffer = Buffer::create(&context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
sizeTestBufferInBytes, pHostPtr, retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_NE(nullptr, buffer);
}
void TearDown() override {
delete buffer;
DeviceFixture::TearDown();
}
cl_int retVal = CL_SUCCESS;
MockContext context;
unsigned char pHostPtr[sizeTestBufferInBytes];
Buffer *buffer = nullptr;
};
TEST_F(SubBufferTest, createSubBuffer) {
cl_buffer_region region = {2, 12};
EXPECT_EQ(1, buffer->getRefInternalCount());
auto subBuffer = buffer->createSubBuffer(CL_MEM_READ_ONLY, &region, retVal);
EXPECT_EQ(2, buffer->getRefInternalCount());
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, subBuffer);
delete subBuffer;
EXPECT_EQ(1, buffer->getRefInternalCount());
}
TEST_F(SubBufferTest, GivenUnalignedHostPtrBufferWhenSubBufferIsCreatedThenItIsNonZeroCopy) {
cl_buffer_region region = {2, 2};
cl_int retVal = 0;
void *pUnalignedHostPtr = alignUp(&pHostPtr, 4);
Buffer *buffer = Buffer::create(&context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
sizeTestBufferInBytes, pUnalignedHostPtr, retVal);
ASSERT_NE(nullptr, buffer);
ASSERT_EQ(CL_SUCCESS, retVal);
auto subBuffer = buffer->createSubBuffer(CL_MEM_READ_ONLY, &region, retVal);
EXPECT_NE(nullptr, subBuffer);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_FALSE(subBuffer->isMemObjZeroCopy());
subBuffer->release();
buffer->release();
}
TEST_F(SubBufferTest, GivenAlignmentThatIsHigherThen4BytesWhenCheckedForValidityThenTrueIsReturned) {
cl_buffer_region region = {2, 2};
EXPECT_FALSE(buffer->isValidSubBufferOffset(region.origin));
cl_buffer_region region2 = {4, 4};
EXPECT_TRUE(buffer->isValidSubBufferOffset(region2.origin));
cl_buffer_region region3 = {8, 4};
EXPECT_TRUE(buffer->isValidSubBufferOffset(region3.origin));
}
TEST_F(SubBufferTest, givenSharingHandlerFromParentBufferWhenCreateThenShareHandler) {
cl_buffer_region region = {2, 12};
auto handler = new SharingHandler();
buffer->setSharingHandler(handler);
auto subBuffer = buffer->createSubBuffer(CL_MEM_READ_ONLY, &region, retVal);
ASSERT_NE(nullptr, subBuffer);
EXPECT_EQ(subBuffer->getSharingHandler().get(), handler);
delete subBuffer;
EXPECT_EQ(1, buffer->getRefInternalCount());
}
} // namespace ULT

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) 2017, 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/mem_obj/buffer.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "unit_tests/helpers/memory_management.h"
#include "runtime/helpers/aligned_memory.h"
#include "unit_tests/mocks/mock_context.h"
#include "gtest/gtest.h"
using namespace OCLRT;
class ZeroCopyBufferTest : public DeviceFixture,
public testing::TestWithParam<std::tuple<uint64_t /*cl_mem_flags*/, size_t, size_t, int, bool, bool>> {
public:
ZeroCopyBufferTest() {
}
protected:
void SetUp() override {
size_t sizeToAlloc;
size_t alignment;
host_ptr = nullptr;
std::tie(flags, sizeToAlloc, alignment, size, ShouldBeZeroCopy, MisalignPointer) = GetParam();
if (sizeToAlloc > 0) {
host_ptr = (void *)alignedMalloc(sizeToAlloc, alignment);
}
DeviceFixture::SetUp();
}
void TearDown() override {
DeviceFixture::TearDown();
alignedFree(host_ptr);
}
cl_int retVal = CL_SUCCESS;
MockContext context;
cl_mem_flags flags = 0;
void *host_ptr;
bool ShouldBeZeroCopy;
cl_int size;
bool MisalignPointer;
};
static const int Multiplier = 1000;
static const int CacheLinedAlignedSize = MemoryConstants::cacheLineSize * Multiplier;
static const int CacheLinedMisAlignedSize = CacheLinedAlignedSize - 1;
static const int PageAlignSize = MemoryConstants::preferredAlignment * Multiplier;
// clang-format off
//flags, size to alloc, alignment, size, ZeroCopy, MisalignPointer
std::tuple<uint64_t , size_t, size_t, int, bool, bool> Inputs[] = {std::make_tuple((cl_mem_flags)CL_MEM_USE_HOST_PTR, CacheLinedMisAlignedSize, MemoryConstants::preferredAlignment, CacheLinedMisAlignedSize, false, true),
std::make_tuple((cl_mem_flags)CL_MEM_USE_HOST_PTR, CacheLinedAlignedSize, MemoryConstants::preferredAlignment, CacheLinedAlignedSize, false, true),
std::make_tuple((cl_mem_flags)CL_MEM_USE_HOST_PTR, CacheLinedAlignedSize, MemoryConstants::preferredAlignment, CacheLinedAlignedSize, true, false),
std::make_tuple((cl_mem_flags)CL_MEM_USE_HOST_PTR, CacheLinedMisAlignedSize, MemoryConstants::preferredAlignment, CacheLinedMisAlignedSize, false, false),
std::make_tuple((cl_mem_flags)CL_MEM_USE_HOST_PTR, PageAlignSize, MemoryConstants::preferredAlignment, PageAlignSize, true, false),
std::make_tuple((cl_mem_flags)CL_MEM_USE_HOST_PTR, CacheLinedMisAlignedSize, MemoryConstants::cacheLineSize, CacheLinedAlignedSize, true, false),
std::make_tuple((cl_mem_flags)CL_MEM_COPY_HOST_PTR, CacheLinedMisAlignedSize, MemoryConstants::preferredAlignment, CacheLinedMisAlignedSize, true, true),
std::make_tuple((cl_mem_flags)CL_MEM_COPY_HOST_PTR, CacheLinedMisAlignedSize, MemoryConstants::preferredAlignment, CacheLinedMisAlignedSize, true, false),
std::make_tuple((cl_mem_flags)NULL, 0, 0, CacheLinedMisAlignedSize, true, false),
std::make_tuple((cl_mem_flags)NULL, 0, 0, CacheLinedAlignedSize, true, true)};
//clang-format on
TEST_P(ZeroCopyBufferTest, CheckCacheAlignedPointerResultsInZeroCopy) {
char *PassedPtr = (char *)host_ptr;
//misalign the pointer
if (MisalignPointer && PassedPtr) {
PassedPtr += 1;
}
auto buffer = Buffer::create(
&context,
flags,
size,
PassedPtr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(ShouldBeZeroCopy, buffer->isMemObjZeroCopy()) << "Zero Copy not handled properly";
if (!ShouldBeZeroCopy && flags & CL_MEM_USE_HOST_PTR) {
EXPECT_NE(buffer->getCpuAddress(), host_ptr);
}
EXPECT_NE(nullptr, buffer->getCpuAddress());
//check if buffer always have properly aligned storage ( PAGE )
EXPECT_EQ(alignUp(buffer->getCpuAddress(), MemoryConstants::cacheLineSize), buffer->getCpuAddress());
delete buffer;
}
INSTANTIATE_TEST_CASE_P(
ZeroCopyBufferTests,
ZeroCopyBufferTest,
testing::ValuesIn(Inputs));
TEST(ZeroCopyBufferTestWithSharedContext, GivenContextThatIsSharedWhenAskedForBufferCreationThenAlwaysResultsInZeroCopy) {
MockContext context;
auto host_ptr = (void*)0x1001;
auto size = 64;
auto retVal = CL_SUCCESS;
context.isSharedContext = true;
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
host_ptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(buffer->isMemObjZeroCopy()) << "Zero Copy not handled properly";
if (buffer->getGraphicsAllocation()->is32BitAllocation == false)
{
EXPECT_EQ(host_ptr, (void*)buffer->getGraphicsAllocation()->getUnderlyingBuffer());
}
delete buffer;
}
TEST(ZeroCopyBufferWith32BitAddressing, GivenDeviceSupporting32BitAddressingWhenAskedForBufferCreationFromHostPtrThenNonZeroCopyBufferIsReturned)
{
DebugManagerStateRestore dbgRestorer;
{
DebugManager.flags.Force32bitAddressing.set(true);
MockContext context;
auto host_ptr = (void*)alignedMalloc(MemoryConstants::pageSize, MemoryConstants::pageSize);
auto size = MemoryConstants::pageSize;
auto retVal = CL_SUCCESS;
auto buffer = Buffer::create(
&context,
CL_MEM_USE_HOST_PTR,
size,
host_ptr,
retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(buffer->isMemObjZeroCopy());
if( is64bit)
EXPECT_TRUE(buffer->getGraphicsAllocation()->is32BitAllocation);
delete buffer;
alignedFree(host_ptr);
DebugManager.flags.Force32bitAddressing.set(false);
}
}