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/source/memory_manager/os_agnostic_memory_manager.h"
10
11 #include "opencl/source/helpers/cl_memory_properties_helpers.h"
12 #include "opencl/source/helpers/surface_formats.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/fixtures/image_fixture.h"
16 #include "opencl/test/unit_test/mocks/mock_context.h"
17
18 #include "gtest/gtest.h"
19 #include "igfxfmid.h"
20
21 extern GFXCORE_FAMILY renderCoreFamily;
22
23 using namespace NEO;
24
25 class ImageRedescribeTest : public testing::TestWithParam<std::tuple<size_t, uint32_t>> {
26 protected:
SetUp()27 void SetUp() override {
28
29 cl_image_format imageFormat;
30 cl_image_desc imageDesc;
31
32 std::tie(indexImageFormat, ImageType) = this->GetParam();
33
34 ArrayRef<const ClSurfaceFormatInfo> readWriteSurfaceFormats = SurfaceFormats::readWrite();
35 auto &surfaceFormatInfo = readWriteSurfaceFormats[indexImageFormat];
36 imageFormat = surfaceFormatInfo.OCLImageFormat;
37
38 auto imageHeight = ImageType == CL_MEM_OBJECT_IMAGE1D_ARRAY ? 0 : 32;
39 auto imageArrays = ImageType == CL_MEM_OBJECT_IMAGE1D_ARRAY || ImageType == CL_MEM_OBJECT_IMAGE2D_ARRAY ? 7 : 1;
40
41 imageDesc.image_type = ImageType;
42 imageDesc.image_width = 32;
43 imageDesc.image_height = imageHeight;
44 imageDesc.image_depth = 1;
45 imageDesc.image_array_size = imageArrays;
46 imageDesc.image_row_pitch = 0;
47 imageDesc.image_slice_pitch = 0;
48 imageDesc.num_mip_levels = 0;
49 imageDesc.num_samples = 0;
50 imageDesc.mem_object = NULL;
51
52 retVal = CL_INVALID_VALUE;
53 cl_mem_flags flags = CL_MEM_READ_WRITE;
54 auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, context.getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
55 image.reset(Image::create(
56 &context,
57 ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context.getDevice(0)->getDevice()),
58 flags,
59 0,
60 surfaceFormat,
61 &imageDesc,
62 nullptr,
63 retVal));
64
65 ASSERT_NE(nullptr, image);
66 }
67
68 cl_int retVal = CL_SUCCESS;
69 MockContext context;
70 std::unique_ptr<Image> image;
71 size_t indexImageFormat = 0;
72 uint32_t ImageType;
73 };
74
TEST_P(ImageRedescribeTest,givenImageWhenItIsRedescribedThenItContainsProperFormatFlagsAddressAndSameElementSizeInBytes)75 TEST_P(ImageRedescribeTest, givenImageWhenItIsRedescribedThenItContainsProperFormatFlagsAddressAndSameElementSizeInBytes) {
76 std::unique_ptr<Image> imageNew(image->redescribe());
77 ASSERT_NE(nullptr, imageNew);
78 ASSERT_NE(image, imageNew);
79
80 EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_USE_HOST_PTR), imageNew->getFlags() & CL_MEM_USE_HOST_PTR);
81 EXPECT_EQ(image->getCpuAddress(), imageNew->getCpuAddress());
82 EXPECT_NE(static_cast<cl_channel_type>(CL_FLOAT), imageNew->getSurfaceFormatInfo().OCLImageFormat.image_channel_data_type);
83 EXPECT_NE(static_cast<cl_channel_type>(CL_HALF_FLOAT), imageNew->getSurfaceFormatInfo().OCLImageFormat.image_channel_data_type);
84 EXPECT_EQ(imageNew->getSurfaceFormatInfo().surfaceFormat.NumChannels * imageNew->getSurfaceFormatInfo().surfaceFormat.PerChannelSizeInBytes,
85 imageNew->getSurfaceFormatInfo().surfaceFormat.ImageElementSizeInBytes);
86 EXPECT_EQ(image->getSurfaceFormatInfo().surfaceFormat.ImageElementSizeInBytes,
87 imageNew->getSurfaceFormatInfo().surfaceFormat.ImageElementSizeInBytes);
88 }
89
TEST_P(ImageRedescribeTest,givenImageWhenItIsRedescribedThenNewImageFormatHasNumberOfChannelsDependingOnBytesPerPixel)90 TEST_P(ImageRedescribeTest, givenImageWhenItIsRedescribedThenNewImageFormatHasNumberOfChannelsDependingOnBytesPerPixel) {
91 std::unique_ptr<Image> imageNew(image->redescribe());
92 ASSERT_NE(nullptr, imageNew);
93
94 size_t bytesPerPixel = image->getSurfaceFormatInfo().surfaceFormat.NumChannels * image->getSurfaceFormatInfo().surfaceFormat.PerChannelSizeInBytes;
95 size_t channelsExpected = 0;
96 switch (bytesPerPixel) {
97 case 1:
98 case 2:
99 case 4:
100 channelsExpected = 1;
101 break;
102 case 8:
103 channelsExpected = 2;
104 break;
105 case 16:
106 channelsExpected = 4;
107 break;
108 }
109 EXPECT_EQ(channelsExpected, imageNew->getSurfaceFormatInfo().surfaceFormat.NumChannels);
110 }
111
TEST_P(ImageRedescribeTest,givenImageWhenItIsRedescribedThenNewImageDimensionsAreMatchingTheRedescribedImage)112 TEST_P(ImageRedescribeTest, givenImageWhenItIsRedescribedThenNewImageDimensionsAreMatchingTheRedescribedImage) {
113 std::unique_ptr<Image> imageNew(image->redescribe());
114 ASSERT_NE(nullptr, imageNew);
115
116 auto bytesWide = image->getSurfaceFormatInfo().surfaceFormat.ImageElementSizeInBytes * image->getImageDesc().image_width;
117 auto bytesWideNew = imageNew->getSurfaceFormatInfo().surfaceFormat.ImageElementSizeInBytes * imageNew->getImageDesc().image_width;
118
119 EXPECT_EQ(bytesWide, bytesWideNew);
120 EXPECT_EQ(imageNew->getImageDesc().image_height, image->getImageDesc().image_height);
121 EXPECT_EQ(imageNew->getImageDesc().image_array_size, image->getImageDesc().image_array_size);
122 EXPECT_EQ(imageNew->getImageDesc().image_depth, image->getImageDesc().image_depth);
123 EXPECT_EQ(imageNew->getImageDesc().image_type, image->getImageDesc().image_type);
124 EXPECT_EQ(imageNew->getQPitch(), image->getQPitch());
125 EXPECT_EQ(imageNew->getImageDesc().image_width, image->getImageDesc().image_width);
126 }
127
TEST_P(ImageRedescribeTest,givenImageWhenItIsRedescribedThenCubeFaceIndexIsProperlySet)128 TEST_P(ImageRedescribeTest, givenImageWhenItIsRedescribedThenCubeFaceIndexIsProperlySet) {
129 std::unique_ptr<Image> imageNew(image->redescribe());
130 ASSERT_NE(nullptr, imageNew);
131 ASSERT_EQ(imageNew->getCubeFaceIndex(), __GMM_NO_CUBE_MAP);
132
133 for (uint32_t n = __GMM_CUBE_FACE_POS_X; n < __GMM_MAX_CUBE_FACE; n++) {
134 image->setCubeFaceIndex(n);
135 imageNew.reset(image->redescribe());
136 ASSERT_NE(nullptr, imageNew);
137 ASSERT_EQ(imageNew->getCubeFaceIndex(), n);
138 imageNew.reset(image->redescribeFillImage());
139 ASSERT_NE(nullptr, imageNew);
140 ASSERT_EQ(imageNew->getCubeFaceIndex(), n);
141 }
142 }
143
TEST_P(ImageRedescribeTest,givenImageWithMaxSizesWhenItIsRedescribedThenNewImageDoesNotExceedMaxSizes)144 TEST_P(ImageRedescribeTest, givenImageWithMaxSizesWhenItIsRedescribedThenNewImageDoesNotExceedMaxSizes) {
145 cl_image_format imageFormat;
146 cl_image_desc imageDesc;
147
148 auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
149 const auto &caps = device->getDeviceInfo();
150 const auto &sharedCaps = device->getSharedDeviceInfo();
151
152 auto memoryManager = (OsAgnosticMemoryManager *)context.getMemoryManager();
153 memoryManager->turnOnFakingBigAllocations();
154
155 ArrayRef<const ClSurfaceFormatInfo> readWriteSurfaceFormats = SurfaceFormats::readWrite();
156 auto &surfaceFormatInfo = readWriteSurfaceFormats[indexImageFormat];
157 imageFormat = surfaceFormatInfo.OCLImageFormat;
158
159 auto imageWidth = 1;
160 auto imageHeight = 1;
161 auto imageArrays = ImageType == CL_MEM_OBJECT_IMAGE1D_ARRAY || ImageType == CL_MEM_OBJECT_IMAGE2D_ARRAY ? 7 : 1;
162
163 size_t maxImageWidth = 0;
164 size_t maxImageHeight = 0;
165 switch (ImageType) {
166 case CL_MEM_OBJECT_IMAGE1D:
167 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
168 imageWidth = 16384;
169 maxImageWidth = static_cast<size_t>(sharedCaps.maxMemAllocSize);
170 maxImageHeight = 1;
171 break;
172 case CL_MEM_OBJECT_IMAGE2D:
173 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
174 imageHeight = 16384;
175 maxImageWidth = sharedCaps.image2DMaxWidth;
176 maxImageHeight = sharedCaps.image2DMaxHeight;
177 break;
178 case CL_MEM_OBJECT_IMAGE3D:
179 imageHeight = 16384;
180 maxImageWidth = caps.image3DMaxWidth;
181 maxImageHeight = caps.image3DMaxHeight;
182 break;
183 }
184
185 imageDesc.image_type = ImageType;
186 imageDesc.image_width = imageWidth;
187 imageDesc.image_height = imageHeight;
188 imageDesc.image_depth = 1;
189 imageDesc.image_array_size = imageArrays;
190 imageDesc.image_row_pitch = 0;
191 imageDesc.image_slice_pitch = 0;
192 imageDesc.num_mip_levels = 0;
193 imageDesc.num_samples = 0;
194 imageDesc.mem_object = NULL;
195 cl_mem_flags flags = CL_MEM_READ_WRITE;
196 auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, context.getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
197 auto bigImage = std::unique_ptr<Image>(Image::create(
198 &context,
199 ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context.getDevice(0)->getDevice()),
200 flags,
201 0,
202 surfaceFormat,
203 &imageDesc,
204 nullptr,
205 retVal));
206
207 std::unique_ptr<Image> imageNew(bigImage->redescribe());
208
209 ASSERT_NE(nullptr, imageNew);
210
211 EXPECT_GE(maxImageWidth,
212 imageNew->getImageDesc().image_width);
213 EXPECT_GE(maxImageHeight,
214 imageNew->getImageDesc().image_height);
215 }
216
217 static uint32_t ImageTypes[] = {
218 CL_MEM_OBJECT_IMAGE1D,
219 CL_MEM_OBJECT_IMAGE2D,
220 CL_MEM_OBJECT_IMAGE1D_ARRAY,
221 CL_MEM_OBJECT_IMAGE2D_ARRAY};
222
223 decltype(SurfaceFormats::readWrite().size()) readWriteSurfaceFormatsStart = 0u;
224 INSTANTIATE_TEST_CASE_P(
225 Redescribe,
226 ImageRedescribeTest,
227 testing::Combine(
228 ::testing::Range(readWriteSurfaceFormatsStart, SurfaceFormats::readWrite().size()),
229 ::testing::ValuesIn(ImageTypes)));
230
TEST(ImageRedescribeTestSimple,givenImageWhenItIsRedescribedThenCreateFunctionIsSameAsInOriginalImage)231 TEST(ImageRedescribeTestSimple, givenImageWhenItIsRedescribedThenCreateFunctionIsSameAsInOriginalImage) {
232 MockContext context;
233 std::unique_ptr<Image> image(ImageHelper<Image1dDefaults>::create(&context));
234 std::unique_ptr<Image> imageNew(image->redescribe());
235 ASSERT_NE(nullptr, imageNew);
236 EXPECT_EQ(image->createFunction, imageNew->createFunction);
237 }
238