1/*
2 * Copyright (C) 2018-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8#include "opencl/source/command_queue/command_queue.h"
9#include "opencl/test/unit_test/api/cl_api_tests.h"
10#include "opencl/test/unit_test/fixtures/buffer_fixture.h"
11#include "opencl/test/unit_test/fixtures/image_fixture.h"
12
13#include <memory>
14
15using namespace NEO;
16
17typedef api_tests clEnqueueUnmapMemObjTests;
18
19TEST_F(clEnqueueUnmapMemObjTests, givenValidAddressWhenUnmappingThenReturnSuccess) {
20    auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext));
21    cl_int retVal = CL_SUCCESS;
22
23    auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
24    EXPECT_EQ(CL_SUCCESS, retVal);
25
26    retVal = clEnqueueUnmapMemObject(
27        pCommandQueue,
28        buffer.get(),
29        mappedPtr,
30        0,
31        nullptr,
32        nullptr);
33    EXPECT_EQ(CL_SUCCESS, retVal);
34}
35
36TEST_F(clEnqueueUnmapMemObjTests, GivenQueueIncapableWhenUnmappingBufferThenInvalidOperationIsReturned) {
37    auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext));
38    cl_int retVal = CL_SUCCESS;
39
40    auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
41    EXPECT_EQ(CL_SUCCESS, retVal);
42
43    disableQueueCapabilities(CL_QUEUE_CAPABILITY_MAP_BUFFER_INTEL);
44    retVal = clEnqueueUnmapMemObject(
45        pCommandQueue,
46        buffer.get(),
47        mappedPtr,
48        0,
49        nullptr,
50        nullptr);
51    EXPECT_EQ(CL_INVALID_OPERATION, retVal);
52}
53
54TEST_F(clEnqueueUnmapMemObjTests, givenInvalidAddressWhenUnmappingOnCpuThenReturnError) {
55    auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext));
56    EXPECT_TRUE(buffer->mappingOnCpuAllowed());
57    cl_int retVal = CL_SUCCESS;
58
59    auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
60    EXPECT_EQ(CL_SUCCESS, retVal);
61
62    retVal = clEnqueueUnmapMemObject(
63        pCommandQueue,
64        buffer.get(),
65        ptrOffset(mappedPtr, buffer->getSize() + 1),
66        0,
67        nullptr,
68        nullptr);
69    EXPECT_EQ(CL_INVALID_VALUE, retVal);
70}
71
72TEST_F(clEnqueueUnmapMemObjTests, givenInvalidAddressWhenUnmappingOnGpuThenReturnError) {
73    auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext));
74    buffer->setSharingHandler(new SharingHandler());
75    EXPECT_FALSE(buffer->mappingOnCpuAllowed());
76    cl_int retVal = CL_SUCCESS;
77
78    auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
79    EXPECT_EQ(CL_SUCCESS, retVal);
80
81    retVal = clEnqueueUnmapMemObject(
82        pCommandQueue,
83        buffer.get(),
84        ptrOffset(mappedPtr, buffer->getSize() + 1),
85        0,
86        nullptr,
87        nullptr);
88    EXPECT_EQ(CL_INVALID_VALUE, retVal);
89}
90
91TEST_F(clEnqueueUnmapMemObjTests, GivenInvalidMemObjectTypeWhenUnmappingImageThenInvalidMemObjectIsReturned) {
92    MockContext context{};
93    MockGraphicsAllocation allocation{};
94    MockBuffer buffer{&context, allocation};
95    cl_int retVal = CL_SUCCESS;
96
97    auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, &buffer, CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
98    EXPECT_EQ(CL_SUCCESS, retVal);
99
100    buffer.memObjectType = 0x123456;
101    retVal = clEnqueueUnmapMemObject(
102        pCommandQueue,
103        &buffer,
104        mappedPtr,
105        0,
106        nullptr,
107        nullptr);
108    EXPECT_EQ(CL_INVALID_MEM_OBJECT, retVal);
109}
110
111struct clEnqueueUnmapImageTests : clEnqueueUnmapMemObjTests,
112                                  ::testing::WithParamInterface<uint32_t> {
113    void SetUp() override {
114        clEnqueueUnmapMemObjTests::SetUp();
115        const auto imageType = static_cast<cl_mem_object_type>(GetParam());
116        this->image.reset(createImage(imageType));
117        EXPECT_NE(nullptr, image.get());
118    }
119
120    Image *createImage(cl_mem_object_type type) {
121        switch (type) {
122        case CL_MEM_OBJECT_IMAGE1D:
123            return Image1dHelper<>::create(pContext);
124        case CL_MEM_OBJECT_IMAGE1D_BUFFER:
125            return Image1dBufferHelper<>::create(pContext);
126        case CL_MEM_OBJECT_IMAGE1D_ARRAY:
127            return Image1dArrayHelper<>::create(pContext);
128        case CL_MEM_OBJECT_IMAGE2D:
129            return Image2dHelper<>::create(pContext);
130        case CL_MEM_OBJECT_IMAGE2D_ARRAY:
131            return Image2dArrayHelper<>::create(pContext);
132        case CL_MEM_OBJECT_IMAGE3D:
133            return Image3dHelper<>::create(pContext);
134        default:
135            return nullptr;
136        }
137    }
138
139    std::unique_ptr<Image> image;
140
141    const size_t origin[3] = {0, 0, 0};
142    const size_t region[3] = {1, 1, 1};
143    size_t imageRowPitch = 0;
144    size_t imageSlicePitch = 0;
145};
146
147TEST_P(clEnqueueUnmapImageTests, GivenValidParametersWhenUnmappingImageThenSuccessIsReturned) {
148    void *mappedImage = clEnqueueMapImage(
149        pCommandQueue,
150        image.get(),
151        CL_TRUE,
152        CL_MAP_READ,
153        origin,
154        region,
155        &imageRowPitch,
156        &imageSlicePitch,
157        0,
158        nullptr,
159        nullptr,
160        &retVal);
161    EXPECT_EQ(CL_SUCCESS, retVal);
162
163    retVal = clEnqueueUnmapMemObject(
164        pCommandQueue,
165        image.get(),
166        mappedImage,
167        0,
168        nullptr,
169        nullptr);
170    EXPECT_EQ(CL_SUCCESS, retVal);
171}
172
173TEST_P(clEnqueueUnmapImageTests, GivenQueueIncapableParametersWhenUnmappingImageThenInvalidOperationIsReturned) {
174    void *mappedImage = clEnqueueMapImage(
175        pCommandQueue,
176        image.get(),
177        CL_TRUE,
178        CL_MAP_READ,
179        origin,
180        region,
181        &imageRowPitch,
182        &imageSlicePitch,
183        0,
184        nullptr,
185        nullptr,
186        &retVal);
187    EXPECT_EQ(CL_SUCCESS, retVal);
188
189    this->disableQueueCapabilities(CL_QUEUE_CAPABILITY_MAP_IMAGE_INTEL);
190    retVal = clEnqueueUnmapMemObject(
191        pCommandQueue,
192        image.get(),
193        mappedImage,
194        0,
195        nullptr,
196        nullptr);
197    EXPECT_EQ(CL_INVALID_OPERATION, retVal);
198}
199
200INSTANTIATE_TEST_SUITE_P(
201    clEnqueueUnmapImageTests,
202    clEnqueueUnmapImageTests,
203    ::testing::Values(
204        CL_MEM_OBJECT_IMAGE2D,
205        CL_MEM_OBJECT_IMAGE3D,
206        CL_MEM_OBJECT_IMAGE2D_ARRAY,
207        CL_MEM_OBJECT_IMAGE1D,
208        CL_MEM_OBJECT_IMAGE1D_ARRAY,
209        CL_MEM_OBJECT_IMAGE1D_BUFFER));
210