mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-04 15:53:45 +08:00
Initial commit
Change-Id: I4bf1707bd3dfeadf2c17b0a7daff372b1925ebbd
This commit is contained in:
51
unit_tests/mem_obj/CMakeLists.txt
Normal file
51
unit_tests/mem_obj/CMakeLists.txt
Normal 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)
|
||||
115
unit_tests/mem_obj/buffer_pin_tests.cpp
Normal file
115
unit_tests/mem_obj/buffer_pin_tests.cpp
Normal 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());
|
||||
}
|
||||
247
unit_tests/mem_obj/buffer_set_arg_tests.cpp
Normal file
247
unit_tests/mem_obj/buffer_set_arg_tests.cpp
Normal 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(), ®ion, 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));
|
||||
}
|
||||
807
unit_tests/mem_obj/buffer_tests.cpp
Normal file
807
unit_tests/mem_obj/buffer_tests.cpp
Normal 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,
|
||||
®ion,
|
||||
&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,
|
||||
®ion,
|
||||
&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,
|
||||
®ion,
|
||||
&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, ®ion, 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);
|
||||
}
|
||||
149
unit_tests/mem_obj/create_image_format_tests.cpp
Normal file
149
unit_tests/mem_obj/create_image_format_tests.cpp
Normal 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));
|
||||
124
unit_tests/mem_obj/destructor_callback_tests.cpp
Normal file
124
unit_tests/mem_obj/destructor_callback_tests.cpp
Normal 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);
|
||||
}
|
||||
152
unit_tests/mem_obj/get_mem_object_info_subbufer_tests.cpp
Normal file
152
unit_tests/mem_obj/get_mem_object_info_subbufer_tests.cpp
Normal 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, ®ion, 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);
|
||||
}
|
||||
323
unit_tests/mem_obj/get_mem_object_info_tests.cpp
Normal file
323
unit_tests/mem_obj/get_mem_object_info_tests.cpp
Normal 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);
|
||||
}
|
||||
150
unit_tests/mem_obj/image1d_tests.cpp
Normal file
150
unit_tests/mem_obj/image1d_tests.cpp
Normal 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));
|
||||
308
unit_tests/mem_obj/image2d_from_buffer_tests.cpp
Normal file
308
unit_tests/mem_obj/image2d_from_buffer_tests.cpp
Normal 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;
|
||||
}
|
||||
133
unit_tests/mem_obj/image2d_tests.cpp
Normal file
133
unit_tests/mem_obj/image2d_tests.cpp
Normal 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));
|
||||
150
unit_tests/mem_obj/image3d_tests.cpp
Normal file
150
unit_tests/mem_obj/image3d_tests.cpp
Normal 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);
|
||||
}
|
||||
206
unit_tests/mem_obj/image_array_size_tests.cpp
Normal file
206
unit_tests/mem_obj/image_array_size_tests.cpp
Normal 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));
|
||||
114
unit_tests/mem_obj/image_copy_tests.cpp
Normal file
114
unit_tests/mem_obj/image_copy_tests.cpp
Normal 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)));
|
||||
335
unit_tests/mem_obj/image_redescribe_tests.cpp
Normal file
335
unit_tests/mem_obj/image_redescribe_tests.cpp
Normal 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)));
|
||||
134
unit_tests/mem_obj/image_release_mapped_ptr_tests.cpp
Normal file
134
unit_tests/mem_obj/image_release_mapped_ptr_tests.cpp
Normal 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);
|
||||
}
|
||||
840
unit_tests/mem_obj/image_set_arg_tests.cpp
Normal file
840
unit_tests/mem_obj/image_set_arg_tests.cpp
Normal 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);
|
||||
}
|
||||
105
unit_tests/mem_obj/image_snorm_tests.cpp
Normal file
105
unit_tests/mem_obj/image_snorm_tests.cpp
Normal 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));
|
||||
944
unit_tests/mem_obj/image_tests.cpp
Normal file
944
unit_tests/mem_obj/image_tests.cpp
Normal 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);
|
||||
}
|
||||
181
unit_tests/mem_obj/image_tiled_tests.cpp
Normal file
181
unit_tests/mem_obj/image_tiled_tests.cpp
Normal 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));
|
||||
738
unit_tests/mem_obj/image_validate_tests.cpp
Normal file
738
unit_tests/mem_obj/image_validate_tests.cpp
Normal 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);
|
||||
}
|
||||
274
unit_tests/mem_obj/mem_obj_destruction_tests.cpp
Normal file
274
unit_tests/mem_obj/mem_obj_destruction_tests.cpp
Normal 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());
|
||||
216
unit_tests/mem_obj/mem_obj_tests.cpp
Normal file
216
unit_tests/mem_obj/mem_obj_tests.cpp
Normal 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();
|
||||
}
|
||||
590
unit_tests/mem_obj/nv12_image_tests.cpp
Normal file
590
unit_tests/mem_obj/nv12_image_tests.cpp
Normal 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);
|
||||
}
|
||||
121
unit_tests/mem_obj/packed_yuv_image_tests.cpp
Normal file
121
unit_tests/mem_obj/packed_yuv_image_tests.cpp
Normal 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));
|
||||
114
unit_tests/mem_obj/pipe_tests.cpp
Normal file
114
unit_tests/mem_obj/pipe_tests.cpp
Normal 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;
|
||||
}
|
||||
118
unit_tests/mem_obj/sub_buffer_tests.cpp
Normal file
118
unit_tests/mem_obj/sub_buffer_tests.cpp
Normal 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, ®ion, 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, ®ion, 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, ®ion, retVal);
|
||||
ASSERT_NE(nullptr, subBuffer);
|
||||
EXPECT_EQ(subBuffer->getSharingHandler().get(), handler);
|
||||
|
||||
delete subBuffer;
|
||||
EXPECT_EQ(1, buffer->getRefInternalCount());
|
||||
}
|
||||
} // namespace ULT
|
||||
169
unit_tests/mem_obj/zero_copy_tests.cpp
Normal file
169
unit_tests/mem_obj/zero_copy_tests.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user