1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/helpers/aligned_memory.h"
9 #include "shared/test/common/helpers/unit_test_helper.h"
10 #include "shared/test/common/test_macros/test.h"
11 
12 #include "opencl/source/helpers/cl_memory_properties_helpers.h"
13 #include "opencl/source/mem_obj/image.h"
14 #include "opencl/test/unit_test/fixtures/cl_device_fixture.h"
15 #include "opencl/test/unit_test/mocks/mock_context.h"
16 
17 using namespace NEO;
18 
19 static const unsigned int testImageDimensions = 17;
20 
21 class ImageArraySizeTest : public ClDeviceFixture,
22                            public testing::TestWithParam<uint32_t /*cl_mem_object_type*/> {
23   public:
ImageArraySizeTest()24     ImageArraySizeTest() {
25     }
26 
27   protected:
SetUp()28     void SetUp() override {
29         ClDeviceFixture::SetUp();
30         types = GetParam();
31 
32         // clang-format off
33         imageFormat.image_channel_data_type = CL_UNORM_INT8;
34         imageFormat.image_channel_order = CL_RGBA;
35 
36         imageDesc.image_type = types;
37         imageDesc.image_width = testImageDimensions;
38         imageDesc.image_height = testImageDimensions;
39         imageDesc.image_depth = 0;
40         imageDesc.image_array_size = 10;
41         imageDesc.image_row_pitch = 0;
42         imageDesc.image_slice_pitch = 0;
43         imageDesc.num_mip_levels = 0;
44         imageDesc.num_samples = 0;
45         imageDesc.mem_object = NULL;
46         // clang-format on
47 
48         context = new MockContext(pClDevice);
49 
50         if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
51             imageDesc.mem_object = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, testImageDimensions, nullptr, nullptr);
52         }
53     }
54 
TearDown()55     void TearDown() override {
56         if (types == CL_MEM_OBJECT_IMAGE1D_BUFFER) {
57             clReleaseMemObject(imageDesc.mem_object);
58         }
59         delete context;
60         ClDeviceFixture::TearDown();
61     }
62 
63     cl_image_format imageFormat;
64     cl_image_desc imageDesc;
65     cl_int retVal = CL_SUCCESS;
66     MockContext *context;
67     cl_mem_object_type types = 0;
68 };
69 
70 typedef ImageArraySizeTest CreateImageArraySize;
71 
HWTEST_P(CreateImageArraySize,GivenArrayTypeWhenCreatingImageThenImageCreatedWithCorrectParams)72 HWTEST_P(CreateImageArraySize, GivenArrayTypeWhenCreatingImageThenImageCreatedWithCorrectParams) {
73 
74     cl_mem_flags flags = CL_MEM_READ_WRITE;
75     auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
76     auto image = Image::create(
77         context,
78         ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()),
79         flags,
80         0,
81         surfaceFormat,
82         &imageDesc,
83         nullptr,
84         retVal);
85 
86     ASSERT_EQ(CL_SUCCESS, retVal);
87     ASSERT_NE(nullptr, image);
88 
89     if (types == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
90         EXPECT_TRUE(image->isMemObjZeroCopy());
91         auto address = image->getCpuAddress();
92         EXPECT_NE(nullptr, address);
93 
94     } else if (types == CL_MEM_OBJECT_IMAGE2D_ARRAY) {
95         EXPECT_EQ(!UnitTestHelper<FamilyType>::tiledImagesSupported, image->isMemObjZeroCopy());
96     }
97     ASSERT_EQ(10u, image->getImageDesc().image_array_size);
98 
99     delete image;
100 }
101 
102 static cl_mem_object_type ArrayImageTypes[] = {
103     CL_MEM_OBJECT_IMAGE1D_ARRAY,
104     CL_MEM_OBJECT_IMAGE2D_ARRAY};
105 
106 INSTANTIATE_TEST_CASE_P(
107     ImageArraySizeTestCreate,
108     CreateImageArraySize,
109     testing::ValuesIn(ArrayImageTypes));
110 
111 typedef ImageArraySizeTest CreateImageNonArraySize;
112 
HWTEST_P(CreateImageNonArraySize,GivenNonArrayTypeWhenCreatingImageThenImageCreatedWithCorrectParams)113 HWTEST_P(CreateImageNonArraySize, GivenNonArrayTypeWhenCreatingImageThenImageCreatedWithCorrectParams) {
114 
115     cl_mem_flags flags = CL_MEM_READ_WRITE;
116     auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
117     auto image = Image::create(
118         context,
119         ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()),
120         flags,
121         0,
122         surfaceFormat,
123         &imageDesc,
124         nullptr,
125         retVal);
126 
127     ASSERT_EQ(CL_SUCCESS, retVal);
128     ASSERT_NE(nullptr, image);
129     if (types == CL_MEM_OBJECT_IMAGE2D || types == CL_MEM_OBJECT_IMAGE3D) {
130         EXPECT_EQ(!UnitTestHelper<FamilyType>::tiledImagesSupported, image->isMemObjZeroCopy());
131     } else {
132         EXPECT_TRUE(image->isMemObjZeroCopy());
133         auto address = image->getCpuAddress();
134         EXPECT_NE(nullptr, address);
135     }
136     ASSERT_EQ(0u, image->getImageDesc().image_array_size);
137 
138     delete image;
139 }
140 
141 static cl_mem_object_type NonArrayImageTypes[] = {
142     CL_MEM_OBJECT_IMAGE1D,
143     CL_MEM_OBJECT_IMAGE1D_BUFFER,
144     CL_MEM_OBJECT_IMAGE2D,
145     CL_MEM_OBJECT_IMAGE3D};
146 
147 INSTANTIATE_TEST_CASE_P(
148     ImageArraySizeTest_Create,
149     CreateImageNonArraySize,
150     testing::ValuesIn(NonArrayImageTypes));
151 
152 typedef ImageArraySizeTest CreateImageSize;
153 
HWTEST_P(CreateImageSize,GivenImageTypeAndRegionWhenAskedForHostPtrSizeThenProperSizeIsBeingReturned)154 HWTEST_P(CreateImageSize, GivenImageTypeAndRegionWhenAskedForHostPtrSizeThenProperSizeIsBeingReturned) {
155     size_t region[3] = {100, 200, 300};
156     auto rowPitch = 1000;
157     auto slicePitch = 4000;
158     auto pixelSize = 4;
159     auto imageType = GetParam();
160     auto size = Image::calculateHostPtrSize(region, rowPitch, slicePitch, pixelSize, imageType);
161 
162     if ((imageType == CL_MEM_OBJECT_IMAGE1D) || (imageType == CL_MEM_OBJECT_IMAGE1D_BUFFER)) {
163         EXPECT_EQ(region[0] * pixelSize, size);
164     } else if (imageType == CL_MEM_OBJECT_IMAGE2D) {
165         EXPECT_EQ((region[1] - 1) * rowPitch + region[0] * pixelSize, size);
166     } else if (imageType == CL_MEM_OBJECT_IMAGE1D_ARRAY) {
167         EXPECT_EQ((region[1] - 1) * slicePitch + region[0] * pixelSize, size);
168     } else if ((imageType == CL_MEM_OBJECT_IMAGE3D) || (imageType == CL_MEM_OBJECT_IMAGE2D_ARRAY)) {
169         EXPECT_EQ((region[2] - 1) * slicePitch + (region[1] - 1) * rowPitch + region[0] * pixelSize, size);
170     } else {
171         EXPECT_EQ(0u, size);
172     }
173 }
174 
175 typedef ImageArraySizeTest CreateImageOffset;
176 
HWTEST_P(CreateImageOffset,GivenImageTypeAndRegionWhenAskedForHostPtrOffsetThenProperOffsetIsBeingReturned)177 HWTEST_P(CreateImageOffset, GivenImageTypeAndRegionWhenAskedForHostPtrOffsetThenProperOffsetIsBeingReturned) {
178     size_t region[3] = {100, 1, 1};
179     size_t origin[3] = {0, 0, 0};
180     auto rowPitch = 1000;
181     auto slicePitch = 0;
182     auto pixelSize = 4;
183     size_t imageOffset;
184     auto imageType = GetParam();
185     switch (imageType) {
186     case CL_MEM_OBJECT_IMAGE1D:
187     case CL_MEM_OBJECT_IMAGE1D_BUFFER:
188         Image::calculateHostPtrOffset(&imageOffset, origin, region, rowPitch, slicePitch, imageType, pixelSize);
189         EXPECT_EQ(origin[0] * pixelSize, imageOffset);
190         break;
191     case CL_MEM_OBJECT_IMAGE2D:
192         region[1] = 200;
193         Image::calculateHostPtrOffset(&imageOffset, origin, region, rowPitch, slicePitch, imageType, pixelSize);
194         EXPECT_EQ(origin[1] * rowPitch + origin[0] * pixelSize, imageOffset);
195         break;
196     case CL_MEM_OBJECT_IMAGE1D_ARRAY:
197         slicePitch = 4000;
198         Image::calculateHostPtrOffset(&imageOffset, origin, region, rowPitch, slicePitch, imageType, pixelSize);
199         EXPECT_EQ(origin[1] * slicePitch + origin[0] * pixelSize, imageOffset);
200         break;
201     case CL_MEM_OBJECT_IMAGE3D:
202     case CL_MEM_OBJECT_IMAGE2D_ARRAY:
203         region[2] = 300;
204         Image::calculateHostPtrOffset(&imageOffset, origin, region, rowPitch, slicePitch, imageType, pixelSize);
205         EXPECT_EQ(origin[2] * slicePitch + origin[1] * rowPitch + origin[0] * pixelSize, imageOffset);
206         break;
207     case CL_MEM_OBJECT_BUFFER:
208         Image::calculateHostPtrOffset(&imageOffset, origin, region, rowPitch, slicePitch, imageType, pixelSize);
209         EXPECT_EQ(0u, imageOffset);
210         break;
211     }
212 }
213 
214 typedef ImageArraySizeTest CheckImageType;
215 
TEST_P(CheckImageType,GivenImageTypeWhenImageTypeIsCheckedThenProperValueIsReturned)216 TEST_P(CheckImageType, GivenImageTypeWhenImageTypeIsCheckedThenProperValueIsReturned) {
217     auto imageType = GetParam();
218     switch (imageType) {
219     case CL_MEM_OBJECT_IMAGE2D:
220         EXPECT_TRUE(Image::isImage2d(imageType));
221         EXPECT_TRUE(Image::isImage2dOr2dArray(imageType));
222         break;
223     case CL_MEM_OBJECT_IMAGE2D_ARRAY:
224         EXPECT_FALSE(Image::isImage2d(imageType));
225         EXPECT_TRUE(Image::isImage2dOr2dArray(imageType));
226         break;
227     default:
228         EXPECT_FALSE(Image::isImage2d(imageType));
229         EXPECT_FALSE(Image::isImage2dOr2dArray(imageType));
230         break;
231     }
232 }
233 
234 static cl_mem_object_type AllImageTypes[] = {
235     0, //negative scenario
236     CL_MEM_OBJECT_IMAGE1D,
237     CL_MEM_OBJECT_IMAGE1D_BUFFER,
238     CL_MEM_OBJECT_IMAGE2D,
239     CL_MEM_OBJECT_IMAGE1D_ARRAY,
240     CL_MEM_OBJECT_IMAGE3D,
241     CL_MEM_OBJECT_IMAGE2D_ARRAY};
242 
243 INSTANTIATE_TEST_CASE_P(
244     ImageArraySizeTest_Create,
245     CreateImageSize,
246     testing::ValuesIn(AllImageTypes));
247 
248 static cl_mem_object_type AllImageTypesWithBadOne[] = {
249     0, //negative scenario
250     CL_MEM_OBJECT_BUFFER,
251     CL_MEM_OBJECT_IMAGE1D,
252     CL_MEM_OBJECT_IMAGE1D_BUFFER,
253     CL_MEM_OBJECT_IMAGE2D,
254     CL_MEM_OBJECT_IMAGE1D_ARRAY,
255     CL_MEM_OBJECT_IMAGE3D,
256     CL_MEM_OBJECT_IMAGE2D_ARRAY};
257 
258 INSTANTIATE_TEST_CASE_P(
259     ImageArraySizeTest_Create,
260     CreateImageOffset,
261     testing::ValuesIn(AllImageTypesWithBadOne));
262