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