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/test_macros/test.h"
10
11 #include "opencl/source/helpers/cl_memory_properties_helpers.h"
12 #include "opencl/source/mem_obj/buffer.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 #include <memory>
18 using namespace NEO;
19
20 // Tests for cl_khr_image2d_from_buffer
21 class ImageFromSubBufferTest : public ClDeviceFixture, public ::testing::Test {
22 public:
ImageFromSubBufferTest()23 ImageFromSubBufferTest() {}
24
25 protected:
SetUp()26 void SetUp() override {
27 imageFormat.image_channel_data_type = CL_UNORM_INT8;
28 imageFormat.image_channel_order = CL_RGBA;
29
30 imageDesc.image_array_size = 0;
31 imageDesc.image_depth = 0;
32 imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
33 imageDesc.image_height = 128 / 2;
34 imageDesc.image_width = 256 / 2;
35 imageDesc.num_mip_levels = 0;
36 imageDesc.image_row_pitch = 0;
37 imageDesc.image_slice_pitch = 0;
38 imageDesc.num_samples = 0;
39
40 size = 128 * 256 * 4;
41 hostPtr = alignedMalloc(size, 16);
42 ASSERT_NE(nullptr, hostPtr);
43
44 parentBuffer = clCreateBuffer(&context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size, hostPtr, &retVal);
45 ASSERT_EQ(CL_SUCCESS, retVal);
46
47 const cl_buffer_region region = {size / 2, size / 2};
48
49 subBuffer = clCreateSubBuffer(parentBuffer, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION,
50 reinterpret_cast<const void *>(®ion), &retVal);
51 ASSERT_EQ(CL_SUCCESS, retVal);
52
53 imageDesc.mem_object = subBuffer;
54 ASSERT_NE(nullptr, imageDesc.mem_object);
55 }
TearDown()56 void TearDown() override {
57 clReleaseMemObject(subBuffer);
58 clReleaseMemObject(parentBuffer);
59 alignedFree(hostPtr);
60 }
61
createImage()62 Image *createImage() {
63 cl_mem_flags flags = CL_MEM_READ_ONLY;
64 auto surfaceFormat = Image::getSurfaceFormatFromTable(
65 flags, &imageFormat, context.getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features);
66 return Image::create(&context, ClMemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context.getDevice(0)->getDevice()),
67 flags, 0, surfaceFormat, &imageDesc, NULL, retVal);
68 }
69 cl_image_format imageFormat;
70 cl_image_desc imageDesc;
71 cl_int retVal = CL_SUCCESS;
72 MockContext context;
73 void *hostPtr;
74 size_t size;
75 cl_mem parentBuffer;
76 cl_mem subBuffer;
77 };
78
TEST_F(ImageFromSubBufferTest,GivenSubBufferWithOffsetWhenCreatingImageThenOffsetsAreCorrect)79 TEST_F(ImageFromSubBufferTest, GivenSubBufferWithOffsetWhenCreatingImageThenOffsetsAreCorrect) {
80 std::unique_ptr<Image> imageFromSubBuffer(createImage());
81 EXPECT_NE(nullptr, imageFromSubBuffer);
82
83 SurfaceOffsets surfaceOffsets = {0};
84 imageFromSubBuffer->getSurfaceOffsets(surfaceOffsets);
85
86 uint32_t offsetExpected = static_cast<uint32_t>(size) / 2;
87
88 EXPECT_EQ(offsetExpected, surfaceOffsets.offset);
89 EXPECT_EQ(0u, surfaceOffsets.xOffset);
90 EXPECT_EQ(0u, surfaceOffsets.yOffset);
91 EXPECT_EQ(0u, surfaceOffsets.yOffsetForUVplane);
92 }
93
TEST_F(ImageFromSubBufferTest,GivenSubBufferWithOffsetGreaterThan4gbWhenCreatingImageThenSurfaceOffsetsAreCorrect)94 TEST_F(ImageFromSubBufferTest, GivenSubBufferWithOffsetGreaterThan4gbWhenCreatingImageThenSurfaceOffsetsAreCorrect) {
95 Buffer *buffer = castToObject<Buffer>(parentBuffer);
96 uint64_t offsetExpected = 0;
97 cl_buffer_region region = {0, size / 2};
98
99 if constexpr (is64bit) {
100 offsetExpected = 8 * GB;
101 region = {static_cast<size_t>(offsetExpected), size / 2};
102 }
103
104 Buffer *subBufferWithBigOffset = buffer->createSubBuffer(CL_MEM_READ_WRITE, 0, ®ion, retVal);
105 imageDesc.mem_object = subBufferWithBigOffset;
106
107 std::unique_ptr<Image> imageFromSubBuffer(createImage());
108 EXPECT_NE(nullptr, imageFromSubBuffer);
109
110 SurfaceOffsets surfaceOffsets = {0};
111 imageFromSubBuffer->getSurfaceOffsets(surfaceOffsets);
112
113 EXPECT_EQ(offsetExpected, surfaceOffsets.offset);
114 EXPECT_EQ(0u, surfaceOffsets.xOffset);
115 EXPECT_EQ(0u, surfaceOffsets.yOffset);
116 EXPECT_EQ(0u, surfaceOffsets.yOffsetForUVplane);
117 subBufferWithBigOffset->release();
118 }
119