1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/os_interface/hw_info_config.h"
9 #include "shared/test/common/libult/ult_command_stream_receiver.h"
10 #include "shared/test/common/mocks/mock_gmm.h"
11 #include "shared/test/common/mocks/mock_memory_manager.h"
12 
13 #include "opencl/source/helpers/gmm_types_converter.h"
14 #include "opencl/source/mem_obj/image.h"
15 #include "opencl/source/platform/platform.h"
16 #include "opencl/source/sharings/gl/gl_texture.h"
17 #include "opencl/test/unit_test/mocks/gl/windows/mock_gl_sharing_windows.h"
18 #include "opencl/test/unit_test/mocks/mock_cl_device.h"
19 #include "opencl/test/unit_test/mocks/mock_context.h"
20 #include "opencl/test/unit_test/mocks/mock_platform.h"
21 
22 #include "gtest/gtest.h"
23 
24 using namespace NEO;
25 
26 class GlSharingTextureTests : public ::testing::Test {
27   public:
28     // temp solution - we need to query size from GMM:
29     class TempMM : public MockMemoryManager {
30       public:
31         using MockMemoryManager::MockMemoryManager;
createGraphicsAllocationFromSharedHandle(osHandle handle,const AllocationProperties & properties,bool requireSpecificBitness,bool isHostIpcAllocation)32         GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness, bool isHostIpcAllocation) override {
33             auto alloc = OsAgnosticMemoryManager::createGraphicsAllocationFromSharedHandle(handle, properties, requireSpecificBitness, isHostIpcAllocation);
34             if (useForcedGmm) {
35                 alloc->setDefaultGmm(forceGmm.get());
36             }
37             return alloc;
38         }
freeGraphicsMemoryImpl(GraphicsAllocation * gfxAllocation)39         void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation) override {
40             if (useForcedGmm) {
41                 forceGmm.release();
42             }
43             OsAgnosticMemoryManager::freeGraphicsMemoryImpl(gfxAllocation);
44         }
mapAuxGpuVA(GraphicsAllocation * graphicsAllocation)45         bool mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) override {
46             mapAuxGpuVACalled++;
47             return false;
48         }
49         uint32_t mapAuxGpuVACalled = 0u;
50         size_t forceAllocationSize;
51         std::unique_ptr<Gmm> forceGmm;
52         bool useForcedGmm = true;
53     };
54 
SetUp()55     void SetUp() override {
56         executionEnvironment = platform()->peekExecutionEnvironment();
57         imgDesc = {};
58         imgDesc.imageType = ImageType::Image1D;
59         imgDesc.imageWidth = 10;
60         auto imgInfo = MockGmm::initImgInfo(imgDesc, 0, nullptr);
61 
62         tempMM = new TempMM(*executionEnvironment);
63         executionEnvironment->memoryManager.reset(tempMM);
64         device = std::make_unique<MockClDevice>(MockDevice::create<MockDevice>(executionEnvironment, 0));
65         clContext = std::make_unique<MockContext>(device.get());
66 
67         mockGlSharingFunctions = glSharing->sharingFunctions.release();
68         clContext->setSharingFunctions(mockGlSharingFunctions);
69 
70         tempMM->forceGmm = MockGmm::queryImgParams(device->getGmmClientContext(), imgInfo, false);
71         tempMM->forceAllocationSize = textureSize;
72         textureSize = imgInfo.size;
73         textureId = 1;
74     }
75 
setUnifiedAuxSurf()76     void setUnifiedAuxSurf() {
77         tempMM->useForcedGmm = true;
78         auto mockGmmResInfo = static_cast<MockGmmResourceInfo *>(tempMM->forceGmm->gmmResourceInfo.get());
79         mockGmmResInfo->setUnifiedAuxTranslationCapable();
80     }
81 
82     ExecutionEnvironment *executionEnvironment;
83     ImageDescriptor imgDesc;
84     TempMM *tempMM;
85     std::unique_ptr<MockClDevice> device;
86     std::unique_ptr<MockContext> clContext;
87     std::unique_ptr<MockGlSharing> glSharing = std::make_unique<MockGlSharing>();
88     GlSharingFunctionsMock *mockGlSharingFunctions;
89     size_t textureSize;
90     unsigned int textureId;
91 };
92 
TEST_F(GlSharingTextureTests,givenMockGlWhen1dGlTextureIsCreatedThenMemObjectHasGlHandler)93 TEST_F(GlSharingTextureTests, givenMockGlWhen1dGlTextureIsCreatedThenMemObjectHasGlHandler) {
94     cl_int retVal = CL_INVALID_VALUE;
95 
96     glSharing->uploadDataToTextureInfo(textureId);
97 
98     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_1D, 0, textureId, &retVal);
99     ASSERT_NE(nullptr, glTexture);
100     auto graphicsAllocation = glTexture->getGraphicsAllocation(device->getRootDeviceIndex());
101     EXPECT_NE(nullptr, graphicsAllocation);
102     EXPECT_EQ(textureSize, graphicsAllocation->getUnderlyingBufferSize());
103     EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
104     EXPECT_EQ(CL_SUCCESS, retVal);
105 
106     EXPECT_EQ(textureId, glSharing->dllParam->getTextureInfo().name); //input
107 
108     auto handler = glTexture->peekSharingHandler();
109     ASSERT_NE(nullptr, handler);
110     auto glHandler = static_cast<GlSharing *>(handler);
111 
112     EXPECT_EQ(glHandler->peekFunctionsHandler(), mockGlSharingFunctions);
113 
114     delete glTexture;
115 }
116 
117 class FailingMemoryManager : public MockMemoryManager {
118   public:
createGraphicsAllocationFromSharedHandle(osHandle handle,const AllocationProperties & properties,bool requireSpecificBitness,bool isHostIpcAllocation)119     GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness, bool isHostIpcAllocation) override {
120         return nullptr;
121     }
122 };
123 
TEST_F(GlSharingTextureTests,givenMockGlWhenGlTextureIsCreatedFromWrongHandleThenErrorAndNoTextureIsReturned)124 TEST_F(GlSharingTextureTests, givenMockGlWhenGlTextureIsCreatedFromWrongHandleThenErrorAndNoTextureIsReturned) {
125     auto tempMemoryManager = clContext->getMemoryManager();
126     tempMM->useForcedGmm = false;
127     auto memoryManager = std::unique_ptr<FailingMemoryManager>(new FailingMemoryManager());
128     clContext->memoryManager = memoryManager.get();
129 
130     auto retVal = CL_SUCCESS;
131     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_1D, 0, textureId, &retVal);
132 
133     EXPECT_EQ(nullptr, glTexture);
134     EXPECT_EQ(CL_INVALID_GL_OBJECT, retVal);
135 
136     clContext->memoryManager = tempMemoryManager;
137 }
138 
mockGLAcquireSharedTexture(GLDisplay,GLContext,GLContext,GLvoid * pResourceInfo)139 GLboolean OSAPI mockGLAcquireSharedTexture(GLDisplay, GLContext, GLContext, GLvoid *pResourceInfo) {
140     auto pTextureInfo = (CL_GL_RESOURCE_INFO *)pResourceInfo;
141     GlDllHelper dllParam;
142     pTextureInfo->globalShareHandle = dllParam.getTextureInfo().globalShareHandle;
143     pTextureInfo->globalShareHandleMCS = dllParam.getTextureInfo().globalShareHandleMCS;
144 
145     if (pTextureInfo->target == GL_TEXTURE_BUFFER) {
146         // size and width for texture buffer are queried from textureInfo - not from gmm
147         pTextureInfo->textureBufferSize = dllParam.getTextureInfo().textureBufferSize;
148         pTextureInfo->textureBufferWidth = dllParam.getTextureInfo().textureBufferWidth;
149     }
150     pTextureInfo->pGmmResInfo = dllParam.getTextureInfo().pGmmResInfo;
151     pTextureInfo->glInternalFormat = 99999;
152     pTextureInfo->glHWFormat = dllParam.getTextureInfo().glHWFormat;
153     pTextureInfo->textureBufferOffset = dllParam.getTextureInfo().textureBufferOffset;
154     dllParam.loadTexture(*pTextureInfo);
155     return (GLboolean)1;
156 };
157 
TEST_F(GlSharingTextureTests,givenMockGlWhenGlTextureIsCreatedFromIncorrectFormatThenErrorAndNoTextureIsReturned)158 TEST_F(GlSharingTextureTests, givenMockGlWhenGlTextureIsCreatedFromIncorrectFormatThenErrorAndNoTextureIsReturned) {
159     mockGlSharingFunctions->setGLAcquireSharedTextureMock(mockGLAcquireSharedTexture);
160 
161     auto retVal = CL_SUCCESS;
162     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_1D, 0, textureId, &retVal);
163 
164     EXPECT_EQ(nullptr, glTexture);
165     EXPECT_EQ(CL_INVALID_GL_OBJECT, retVal);
166 }
167 
TEST_F(GlSharingTextureTests,givenMockGlWhenRenderBufferTextureIsCreatedThenMemObjectHasGlHandler)168 TEST_F(GlSharingTextureTests, givenMockGlWhenRenderBufferTextureIsCreatedThenMemObjectHasGlHandler) {
169     cl_int retVal = CL_INVALID_VALUE;
170 
171     glSharing->uploadDataToTextureInfo(textureId);
172 
173     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_RENDERBUFFER_EXT, 0, textureId, &retVal);
174     ASSERT_NE(nullptr, glTexture);
175     auto graphicsAllocation = glTexture->getGraphicsAllocation(device->getRootDeviceIndex());
176     EXPECT_NE(nullptr, graphicsAllocation);
177     EXPECT_EQ(textureSize, graphicsAllocation->getUnderlyingBufferSize());
178     EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedRenderBufferCalled"));
179     EXPECT_EQ(CL_SUCCESS, retVal);
180 
181     EXPECT_EQ(textureId, glSharing->dllParam->getTextureInfo().name);
182 
183     auto handler = glTexture->peekSharingHandler();
184     ASSERT_NE(nullptr, handler);
185     auto glHandler = static_cast<GlSharing *>(handler);
186 
187     EXPECT_EQ(glHandler->peekFunctionsHandler(), mockGlSharingFunctions);
188 
189     delete glTexture;
190 }
191 
TEST_F(GlSharingTextureTests,givenGmmResourceAsInputWhenTextureIsCreatedThenItHasGmmSet)192 TEST_F(GlSharingTextureTests, givenGmmResourceAsInputWhenTextureIsCreatedThenItHasGmmSet) {
193     cl_int retVal = CL_INVALID_VALUE;
194 
195     glSharing->m_textureInfoOutput.globalShareHandle = textureId;
196     glSharing->m_textureInfoOutput.pGmmResInfo = this->tempMM->forceGmm->gmmResourceInfo->peekGmmResourceInfo();
197     this->tempMM->useForcedGmm = false;
198     glSharing->m_textureInfoOutput.pGmmResInfo = this->tempMM->forceGmm->gmmResourceInfo->peekGmmResourceInfo();
199 
200     glSharing->uploadDataToTextureInfo();
201 
202     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), (cl_mem_flags)0, GL_TEXTURE_1D, 0, textureId, &retVal);
203     ASSERT_NE(nullptr, glTexture);
204     auto graphicsAllocation = glTexture->getGraphicsAllocation(device->getRootDeviceIndex());
205     EXPECT_NE(nullptr, graphicsAllocation);
206 
207     ASSERT_NE(nullptr, graphicsAllocation->getDefaultGmm());
208     ASSERT_NE(nullptr, graphicsAllocation->getDefaultGmm()->gmmResourceInfo->peekHandle());
209 
210     delete glTexture;
211 }
212 
TEST_F(GlSharingTextureTests,givenDifferentHwFormatWhenSurfaceFormatInfoIsSetThenOverwrite)213 TEST_F(GlSharingTextureTests, givenDifferentHwFormatWhenSurfaceFormatInfoIsSetThenOverwrite) {
214     cl_int retVal = CL_INVALID_VALUE;
215     cl_image_format imageFormat = {};
216     GlTexture::setClImageFormat(GL_DEPTH32F_STENCIL8, imageFormat);
217     auto format = Image::getSurfaceFormatFromTable(CL_MEM_READ_ONLY, &imageFormat, defaultHwInfo->capabilityTable.supportsOcl21Features);
218     ASSERT_NE(format, nullptr);
219     auto newHwFormat = 217u;
220 
221     EXPECT_TRUE(format->surfaceFormat.GenxSurfaceFormat != newHwFormat);
222 
223     glSharing->m_textureInfoOutput.glHWFormat = newHwFormat;
224     glSharing->m_textureInfoOutput.glInternalFormat = GL_DEPTH32F_STENCIL8;
225 
226     glSharing->uploadDataToTextureInfo();
227 
228     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, textureId, &retVal);
229     ASSERT_NE(nullptr, glTexture);
230     EXPECT_TRUE(newHwFormat == glTexture->getSurfaceFormatInfo().surfaceFormat.GenxSurfaceFormat);
231 
232     delete glTexture;
233 }
234 
TEST_F(GlSharingTextureTests,givenGLRGB10FormatWhenSharedGlTextureIsCreatedThenItHasCorrectGenxSurfaceFormatAssigned)235 TEST_F(GlSharingTextureTests, givenGLRGB10FormatWhenSharedGlTextureIsCreatedThenItHasCorrectGenxSurfaceFormatAssigned) {
236     cl_int retVal = CL_INVALID_VALUE;
237     glSharing->m_textureInfoOutput.glInternalFormat = GL_RGB10;
238     glSharing->m_textureInfoOutput.glHWFormat = GFX3DSTATE_SURFACEFORMAT_R16G16B16X16_UNORM;
239     glSharing->uploadDataToTextureInfo();
240 
241     std::unique_ptr<Image> glTexture(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, textureId, &retVal));
242     ASSERT_NE(nullptr, glTexture);
243     EXPECT_EQ(glTexture->getSurfaceFormatInfo().surfaceFormat.GenxSurfaceFormat, GFX3DSTATE_SURFACEFORMAT_R16G16B16A16_UNORM);
244 }
245 
TEST_F(GlSharingTextureTests,givenContextAnd1dTextureWhenClCreateFromGlTextureIsCalledThenImageIsReturned)246 TEST_F(GlSharingTextureTests, givenContextAnd1dTextureWhenClCreateFromGlTextureIsCalledThenImageIsReturned) {
247     cl_int retVal = CL_INVALID_GL_OBJECT;
248     auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_1D, 0, textureId, &retVal);
249     ASSERT_EQ(CL_SUCCESS, retVal);
250     ASSERT_NE(nullptr, glImage);
251 
252     retVal = clReleaseMemObject(glImage);
253     EXPECT_EQ(CL_SUCCESS, retVal);
254 }
255 
TEST_F(GlSharingTextureTests,givenContextWithoutSharingAnd1dTextureWhenClCreateFromGlTextureIsCalledThenErrorIsReturned)256 TEST_F(GlSharingTextureTests, givenContextWithoutSharingAnd1dTextureWhenClCreateFromGlTextureIsCalledThenErrorIsReturned) {
257     tempMM->useForcedGmm = false;
258     clContext->resetSharingFunctions(CLGL_SHARING);
259     cl_int retVal = CL_INVALID_GL_OBJECT;
260     auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_1D, 0, textureId, &retVal);
261     ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
262     ASSERT_EQ(nullptr, glImage);
263 }
264 
TEST_F(GlSharingTextureTests,givenContextAndRenderBufferTextureWhenClCreateFromGlTextureIsCalledThenImageIsReturned)265 TEST_F(GlSharingTextureTests, givenContextAndRenderBufferTextureWhenClCreateFromGlTextureIsCalledThenImageIsReturned) {
266     cl_int retVal = CL_INVALID_GL_OBJECT;
267     auto glImage = clCreateFromGLRenderbuffer(clContext.get(), 0, textureId, &retVal);
268     ASSERT_EQ(CL_SUCCESS, retVal);
269     ASSERT_NE(nullptr, glImage);
270 
271     retVal = clReleaseMemObject(glImage);
272     EXPECT_EQ(CL_SUCCESS, retVal);
273 }
274 
TEST_F(GlSharingTextureTests,givenContextWithoutSharingAndRenderBufferTextureWhenClCreateFromGlTextureIsCalledThenErrorIsReturned)275 TEST_F(GlSharingTextureTests, givenContextWithoutSharingAndRenderBufferTextureWhenClCreateFromGlTextureIsCalledThenErrorIsReturned) {
276     tempMM->useForcedGmm = false;
277     clContext->resetSharingFunctions(CLGL_SHARING);
278     cl_int retVal = CL_INVALID_GL_OBJECT;
279     auto glImage = clCreateFromGLRenderbuffer(clContext.get(), 0, textureId, &retVal);
280     ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
281     ASSERT_EQ(nullptr, glImage);
282 }
283 
TEST_F(GlSharingTextureTests,givenGlCl1dTextureWhenAskedForCLGLGetInfoThenIdAndTypeIsReturned)284 TEST_F(GlSharingTextureTests, givenGlCl1dTextureWhenAskedForCLGLGetInfoThenIdAndTypeIsReturned) {
285     auto retVal = CL_SUCCESS;
286     auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_1D, 0, textureId, &retVal);
287     ASSERT_EQ(CL_SUCCESS, retVal);
288     ASSERT_NE(nullptr, glImage);
289 
290     cl_gl_object_type objectType = 0u;
291     cl_GLuint objectId = 0u;
292 
293     retVal = clGetGLObjectInfo(glImage, &objectType, &objectId);
294     EXPECT_EQ(CL_SUCCESS, retVal);
295     EXPECT_EQ(objectType, (cl_gl_object_type)CL_GL_OBJECT_TEXTURE1D);
296     EXPECT_EQ(objectId, textureId);
297 
298     retVal = clReleaseMemObject(glImage);
299     EXPECT_EQ(CL_SUCCESS, retVal);
300 }
301 
TEST_F(GlSharingTextureTests,givenHwCommandQueueAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture2dThenImageObjectIsReturned)302 TEST_F(GlSharingTextureTests, givenHwCommandQueueAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture2dThenImageObjectIsReturned) {
303     auto retVal = CL_SUCCESS;
304     auto glImage = clCreateFromGLTexture2D(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
305     ASSERT_EQ(CL_SUCCESS, retVal);
306     ASSERT_NE(nullptr, glImage);
307 
308     cl_gl_object_type objectType = 0u;
309     cl_GLuint objectId = 0u;
310 
311     retVal = clGetGLObjectInfo(glImage, &objectType, &objectId);
312     EXPECT_EQ(CL_SUCCESS, retVal);
313     EXPECT_EQ(objectType, (cl_gl_object_type)CL_GL_OBJECT_TEXTURE2D);
314     EXPECT_EQ(objectId, textureId);
315 
316     retVal = clReleaseMemObject(glImage);
317     EXPECT_EQ(CL_SUCCESS, retVal);
318 }
319 
TEST_F(GlSharingTextureTests,givenContextWithoutSharingAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture2dThenErrorIsReturned)320 TEST_F(GlSharingTextureTests, givenContextWithoutSharingAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture2dThenErrorIsReturned) {
321     tempMM->useForcedGmm = false;
322     clContext->resetSharingFunctions(CLGL_SHARING);
323     auto retVal = CL_SUCCESS;
324     auto glImage = clCreateFromGLTexture2D(clContext.get(), 0, GL_TEXTURE_2D, 0, textureId, &retVal);
325     ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
326     ASSERT_EQ(nullptr, glImage);
327 }
328 
TEST_F(GlSharingTextureTests,givenHwCommandQueueAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture3dThenImageObjectIsReturned)329 TEST_F(GlSharingTextureTests, givenHwCommandQueueAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture3dThenImageObjectIsReturned) {
330     auto retVal = CL_SUCCESS;
331     auto glImage = clCreateFromGLTexture3D(clContext.get(), 0, GL_TEXTURE_3D, 0, textureId, &retVal);
332     ASSERT_EQ(CL_SUCCESS, retVal);
333     ASSERT_NE(nullptr, glImage);
334 
335     cl_gl_object_type objectType = 0u;
336     cl_GLuint objectId = 0u;
337 
338     retVal = clGetGLObjectInfo(glImage, &objectType, &objectId);
339     EXPECT_EQ(CL_SUCCESS, retVal);
340     EXPECT_EQ(objectType, (cl_gl_object_type)CL_GL_OBJECT_TEXTURE3D);
341     EXPECT_EQ(objectId, textureId);
342 
343     retVal = clReleaseMemObject(glImage);
344     EXPECT_EQ(CL_SUCCESS, retVal);
345 }
346 
TEST_F(GlSharingTextureTests,givenContextWithoutSharingAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture3dThenErrorIsReturned)347 TEST_F(GlSharingTextureTests, givenContextWithoutSharingAndGlTextureWhenItIsCreatedWithClCreateFromGlTexture3dThenErrorIsReturned) {
348     tempMM->useForcedGmm = false;
349     clContext->resetSharingFunctions(CLGL_SHARING);
350     auto retVal = CL_SUCCESS;
351     auto glImage = clCreateFromGLTexture3D(clContext.get(), 0, GL_TEXTURE_3D, 0, textureId, &retVal);
352     ASSERT_EQ(CL_INVALID_CONTEXT, retVal);
353     ASSERT_EQ(nullptr, glImage);
354 }
355 
TEST_F(GlSharingTextureTests,givenHwCommandQueueAndGlTextureWhenAcquireIsCalledThenAcquireCountIsIncremented)356 TEST_F(GlSharingTextureTests, givenHwCommandQueueAndGlTextureWhenAcquireIsCalledThenAcquireCountIsIncremented) {
357     glSharing->uploadDataToTextureInfo(textureId);
358 
359     auto retVal = CL_SUCCESS;
360     auto commandQueue = clCreateCommandQueue(clContext.get(), clContext->getDevice(0), 0, &retVal);
361     ASSERT_EQ(CL_SUCCESS, retVal);
362 
363     auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_1D, 0, textureId, &retVal);
364 
365     EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
366     retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
367     EXPECT_EQ(CL_SUCCESS, retVal);
368     EXPECT_EQ(2, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
369 
370     retVal = clEnqueueReleaseGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
371     EXPECT_EQ(CL_SUCCESS, retVal);
372 
373     retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
374     EXPECT_EQ(CL_SUCCESS, retVal);
375     EXPECT_EQ(3, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
376 
377     retVal = clReleaseCommandQueue(commandQueue);
378     EXPECT_EQ(CL_SUCCESS, retVal);
379     retVal = clReleaseMemObject(glImage);
380     EXPECT_EQ(CL_SUCCESS, retVal);
381 }
382 
TEST_F(GlSharingTextureTests,GivenGlTextureThenBufferOffsetIsCorrect)383 TEST_F(GlSharingTextureTests, GivenGlTextureThenBufferOffsetIsCorrect) {
384     glSharing->uploadDataToTextureInfo(textureId);
385 
386     auto rootDeviceIndex = clContext->getDevice(0)->getRootDeviceIndex();
387 
388     auto retVal = CL_SUCCESS;
389     auto commandQueue = clCreateCommandQueue(clContext.get(), clContext->getDevice(0), 0, &retVal);
390     ASSERT_EQ(CL_SUCCESS, retVal);
391 
392     auto glImage = clCreateFromGLTexture(clContext.get(), 0, GL_TEXTURE_1D, 0, textureId, &retVal);
393     EXPECT_NE(glImage, nullptr);
394 
395     retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
396     EXPECT_EQ(CL_SUCCESS, retVal);
397     auto memObj = castToObject<MemObj>(glImage);
398     EXPECT_NE(memObj, nullptr);
399     EXPECT_EQ(memObj->getGraphicsAllocation(rootDeviceIndex)->getAllocationOffset(), 0u);
400 
401     retVal = clEnqueueReleaseGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
402     EXPECT_EQ(CL_SUCCESS, retVal);
403 
404     glSharing->uploadTextureBufferOffsetToTextureInfo(0x660);
405     retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
406     EXPECT_EQ(CL_SUCCESS, retVal);
407     memObj = castToObject<MemObj>(glImage);
408     EXPECT_NE(memObj, nullptr);
409     EXPECT_EQ(memObj->getGraphicsAllocation(rootDeviceIndex)->getAllocationOffset(), 0x660u);
410 
411     retVal = clEnqueueReleaseGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
412     EXPECT_EQ(CL_SUCCESS, retVal);
413 
414     retVal = clReleaseCommandQueue(commandQueue);
415     EXPECT_EQ(CL_SUCCESS, retVal);
416 
417     retVal = clReleaseMemObject(glImage);
418     EXPECT_EQ(CL_SUCCESS, retVal);
419 }
420 
TEST_F(GlSharingTextureTests,givenHwCommandQueueAndGlRenderBufferWhenAcquireIsCalledThenAcquireCountIsIncremented)421 TEST_F(GlSharingTextureTests, givenHwCommandQueueAndGlRenderBufferWhenAcquireIsCalledThenAcquireCountIsIncremented) {
422     glSharing->uploadDataToTextureInfo(textureId);
423 
424     auto retVal = CL_SUCCESS;
425     auto commandQueue = clCreateCommandQueue(clContext.get(), clContext->getDevice(0), 0, &retVal);
426     ASSERT_EQ(CL_SUCCESS, retVal);
427 
428     auto glImage = clCreateFromGLRenderbuffer(clContext.get(), 0, textureId, &retVal);
429 
430     EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedRenderBufferCalled"));
431     retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
432     EXPECT_EQ(CL_SUCCESS, retVal);
433     EXPECT_EQ(2, glSharing->dllParam->getParam("GLAcquireSharedRenderBufferCalled"));
434 
435     retVal = clEnqueueReleaseGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
436     EXPECT_EQ(CL_SUCCESS, retVal);
437 
438     retVal = clEnqueueAcquireGLObjects(commandQueue, 1, &glImage, 0, nullptr, nullptr);
439     EXPECT_EQ(CL_SUCCESS, retVal);
440     EXPECT_EQ(3, glSharing->dllParam->getParam("GLAcquireSharedRenderBufferCalled"));
441 
442     retVal = clReleaseCommandQueue(commandQueue);
443     EXPECT_EQ(CL_SUCCESS, retVal);
444     retVal = clReleaseMemObject(glImage);
445     EXPECT_EQ(CL_SUCCESS, retVal);
446 }
447 
TEST_F(GlSharingTextureTests,givenSharedGlTextureWhenItIsAcquireCountIsDecrementedToZeroThenCallReleaseFunction)448 TEST_F(GlSharingTextureTests, givenSharedGlTextureWhenItIsAcquireCountIsDecrementedToZeroThenCallReleaseFunction) {
449     std::unique_ptr<Image> image(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, textureId, nullptr));
450     auto sharingHandler = image->peekSharingHandler();
451 
452     sharingHandler->acquire(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
453     sharingHandler->acquire(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
454 
455     sharingHandler->release(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
456     EXPECT_EQ(0, glSharing->dllParam->getParam("GLReleaseSharedTextureCalled"));
457 
458     sharingHandler->release(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
459     EXPECT_EQ(1, glSharing->dllParam->getParam("GLReleaseSharedTextureCalled"));
460     EXPECT_EQ(0, glSharing->dllParam->getParam("GLReleaseSharedRenderBufferCalled"));
461     EXPECT_EQ(textureId, glSharing->dllParam->getTextureInfo().name);
462 }
463 
TEST_F(GlSharingTextureTests,givenSharedRenderBufferWhenItIsAcquireCountIsDecrementedToZeroThenCallReleaseFunction)464 TEST_F(GlSharingTextureTests, givenSharedRenderBufferWhenItIsAcquireCountIsDecrementedToZeroThenCallReleaseFunction) {
465     std::unique_ptr<Image> image(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_WRITE, GL_RENDERBUFFER_EXT, 0, textureId, nullptr));
466     auto sharingHandler = image->peekSharingHandler();
467 
468     sharingHandler->acquire(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
469     sharingHandler->acquire(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
470 
471     sharingHandler->release(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
472     EXPECT_EQ(0, glSharing->dllParam->getParam("GLReleaseSharedRenderBufferCalled"));
473 
474     sharingHandler->release(image.get(), clContext->getDevice(0)->getRootDeviceIndex());
475     EXPECT_EQ(1, glSharing->dllParam->getParam("GLReleaseSharedRenderBufferCalled"));
476     EXPECT_EQ(0, glSharing->dllParam->getParam("GLReleaseSharedTextureCalled"));
477     EXPECT_EQ(textureId, glSharing->dllParam->getTextureInfo().name);
478 }
479 
TEST_F(GlSharingTextureTests,givenMultisampleTextureWithMoreThanOneSampleWhenAskedForNumSamplesThenReturnCorrectValue)480 TEST_F(GlSharingTextureTests, givenMultisampleTextureWithMoreThanOneSampleWhenAskedForNumSamplesThenReturnCorrectValue) {
481     GLsizei expectedNumSamples = 2;
482     glSharing->m_textureInfoOutput.numberOfSamples = expectedNumSamples;
483     glSharing->uploadDataToTextureInfo();
484     std::unique_ptr<Image> image(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_WRITE, GL_TEXTURE_2D_MULTISAMPLE, 0, textureId, nullptr));
485 
486     GLsizei numSamples = 0;
487     size_t retSize = 0;
488 
489     auto retVal = clGetGLTextureInfo(image.get(), CL_GL_NUM_SAMPLES, sizeof(GLsizei), &numSamples, &retSize);
490     EXPECT_EQ(CL_SUCCESS, retVal);
491     EXPECT_EQ(expectedNumSamples, numSamples);
492     EXPECT_EQ(sizeof(GLsizei), retSize);
493 }
494 
TEST_F(GlSharingTextureTests,givenTextureWithOneSampleWhenAskedForNumSamplesThenReturnZero)495 TEST_F(GlSharingTextureTests, givenTextureWithOneSampleWhenAskedForNumSamplesThenReturnZero) {
496     glSharing->m_textureInfoOutput.numberOfSamples = 1;
497     glSharing->uploadDataToTextureInfo();
498     std::unique_ptr<Image> image(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_WRITE, GL_TEXTURE_2D_MULTISAMPLE, 0, textureId, nullptr));
499 
500     GLenum numSamples = 0;
501     size_t retSize = 0;
502 
503     auto retVal = clGetGLTextureInfo(image.get(), CL_GL_NUM_SAMPLES, sizeof(GLsizei), &numSamples, &retSize);
504     EXPECT_EQ(CL_SUCCESS, retVal);
505     EXPECT_EQ(0, numSamples);
506     EXPECT_EQ(sizeof(GLsizei), retSize);
507 }
508 
TEST_F(GlSharingTextureTests,givenTextureWithZeroSamplesWhenAskedForNumSamplesThenReturnZero)509 TEST_F(GlSharingTextureTests, givenTextureWithZeroSamplesWhenAskedForNumSamplesThenReturnZero) {
510     glSharing->m_textureInfoOutput.numberOfSamples = 0;
511     glSharing->uploadDataToTextureInfo();
512     std::unique_ptr<Image> image(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_READ_WRITE, GL_TEXTURE_2D_MULTISAMPLE, 0, textureId, nullptr));
513 
514     GLenum numSamples = 0;
515     size_t retSize = 0;
516 
517     auto retVal = clGetGLTextureInfo(image.get(), CL_GL_NUM_SAMPLES, sizeof(GLsizei), &numSamples, &retSize);
518     EXPECT_EQ(CL_SUCCESS, retVal);
519     EXPECT_EQ(0, numSamples);
520     EXPECT_EQ(sizeof(GLsizei), retSize);
521 }
522 
TEST_F(GlSharingTextureTests,givenMockGlWhenGlTextureIsCreatedFromFormatNotIncludedInSurfaceFormatsThenErrorAndNoTextureIsReturned)523 TEST_F(GlSharingTextureTests, givenMockGlWhenGlTextureIsCreatedFromFormatNotIncludedInSurfaceFormatsThenErrorAndNoTextureIsReturned) {
524     cl_int retVal = CL_SUCCESS;
525     auto textureInfoOutput = std::make_unique<CL_GL_RESOURCE_INFO>();
526     textureInfoOutput->glInternalFormat = GL_SRGB8_ALPHA8;
527     glSharing->dllParam->loadTexture(*textureInfoOutput);
528 
529     auto glTexture = GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_WRITE_ONLY, GL_SRGB8_ALPHA8, 0, textureId, &retVal);
530 
531     EXPECT_EQ(nullptr, glTexture);
532     EXPECT_EQ(CL_INVALID_GL_OBJECT, retVal);
533 }
534 
TEST_F(GlSharingTextureTests,givenMockGlWhenGlTextureIsCreatedWithUnifiedAuxSurfThenMapAuxGpuVaIsCalled)535 TEST_F(GlSharingTextureTests, givenMockGlWhenGlTextureIsCreatedWithUnifiedAuxSurfThenMapAuxGpuVaIsCalled) {
536     CL_GL_RESOURCE_INFO textureInfoToReturn = {};
537     textureInfoToReturn.isAuxEnabled = GL_TRUE;
538     glSharing->dllParam->loadTexture(textureInfoToReturn);
539 
540     cl_int retVal = CL_SUCCESS;
541     setUnifiedAuxSurf();
542     EXPECT_EQ(0u, tempMM->mapAuxGpuVACalled);
543 
544     auto glTexture = std::unique_ptr<Image>(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_WRITE_ONLY, GL_SRGB8_ALPHA8, 0, textureId, &retVal));
545 
546     const auto &hwInfo = clContext->getDevice(0)->getHardwareInfo();
547     const auto &hwInfoConfig = *HwInfoConfig::get(hwInfo.platform.eProductFamily);
548     uint32_t expectedMapAuxGpuVaCalls = hwInfoConfig.isPageTableManagerSupported(hwInfo) ? 1 : 0;
549 
550     EXPECT_EQ(expectedMapAuxGpuVaCalls, tempMM->mapAuxGpuVACalled);
551 }
552 
TEST_F(GlSharingTextureTests,givenAuxDisabledAndUnifiedAuxCapableWhenGlTextureIsCreatedThenAllocationIsTreatedAsUncompressed)553 TEST_F(GlSharingTextureTests, givenAuxDisabledAndUnifiedAuxCapableWhenGlTextureIsCreatedThenAllocationIsTreatedAsUncompressed) {
554     CL_GL_RESOURCE_INFO textureInfoToReturn = {};
555     textureInfoToReturn.isAuxEnabled = GL_FALSE;
556     glSharing->dllParam->loadTexture(textureInfoToReturn);
557 
558     cl_int retVal = CL_SUCCESS;
559     setUnifiedAuxSurf();
560     ASSERT_EQ(0u, tempMM->mapAuxGpuVACalled);
561 
562     auto glTexture = std::unique_ptr<Image>(GlTexture::createSharedGlTexture(clContext.get(), CL_MEM_WRITE_ONLY, GL_SRGB8_ALPHA8, 0, textureId, &retVal));
563     EXPECT_EQ(0u, tempMM->mapAuxGpuVACalled);
564     auto graphicsAllocation = glTexture->getGraphicsAllocation(device->getRootDeviceIndex());
565     EXPECT_FALSE(graphicsAllocation->getDefaultGmm()->isCompressionEnabled);
566 }
567 
568 class GetGlTextureInfoTests : public GlSharingTextureTests,
569                               public ::testing::WithParamInterface<unsigned int /*cl_GLenum*/> {
570 };
571 
572 INSTANTIATE_TEST_CASE_P(
573     GetGlTextureInfoTests,
574     GetGlTextureInfoTests,
575     testing::ValuesIn(glTextureTargets::supportedTargets));
576 
TEST_P(GetGlTextureInfoTests,givenGlTextureWhenAskedForCLGetGLTextureInfoThenReturnValidInfo)577 TEST_P(GetGlTextureInfoTests, givenGlTextureWhenAskedForCLGetGLTextureInfoThenReturnValidInfo) {
578     auto retVal = CL_SUCCESS;
579     GLenum expectedTarget = GetParam();
580     GLint mipLevel = 1u;
581     auto glImage = clCreateFromGLTexture(clContext.get(), 0, expectedTarget, mipLevel, textureId, &retVal);
582     ASSERT_EQ(CL_SUCCESS, retVal);
583     ASSERT_NE(nullptr, glImage);
584 
585     auto pMemObj = castToObject<MemObj>(glImage);
586     auto glTextureObj = (GlTexture *)pMemObj->peekSharingHandler();
587 
588     GLenum textureTarget = 0u;
589 
590     size_t retSize = 0;
591 
592     retVal = clGetGLTextureInfo(glImage, CL_GL_TEXTURE_TARGET, sizeof(GLenum), &textureTarget, &retSize);
593     EXPECT_EQ(CL_SUCCESS, retVal);
594     EXPECT_EQ(expectedTarget, textureTarget);
595     EXPECT_EQ(sizeof(GLenum), retSize);
596 
597     retVal = clGetGLTextureInfo(glImage, CL_GL_MIPMAP_LEVEL, sizeof(GLenum), &mipLevel, &retSize);
598     EXPECT_EQ(CL_SUCCESS, retVal);
599     EXPECT_EQ(glTextureObj->getMiplevel(), mipLevel);
600     EXPECT_EQ(sizeof(GLint), retSize);
601 
602     retVal = clGetGLTextureInfo(glImage, CL_INVALID_VALUE, 0, nullptr, nullptr);
603     EXPECT_EQ(CL_INVALID_VALUE, retVal);
604 
605     auto image = castToObject<Image>(glImage);
606     EXPECT_EQ(mipLevel, image->peekBaseMipLevel());
607 
608     retVal = clReleaseMemObject(glImage);
609     EXPECT_EQ(CL_SUCCESS, retVal);
610 }
611 
TEST_P(GetGlTextureInfoTests,givenApiTargetTypeWhenAskedForBaseTypeThenConvertOnlyCubeMaps)612 TEST_P(GetGlTextureInfoTests, givenApiTargetTypeWhenAskedForBaseTypeThenConvertOnlyCubeMaps) {
613     tempMM->useForcedGmm = false;
614     auto apiTarget = GetParam();
615     unsigned int expectedBaseType;
616 
617     switch (apiTarget) {
618     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
619     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
620     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
621     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
622     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
623     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
624         expectedBaseType = GL_TEXTURE_CUBE_MAP_ARB;
625         break;
626     default:
627         expectedBaseType = apiTarget;
628         break;
629     }
630 
631     EXPECT_EQ(GlTexture::getBaseTargetType(apiTarget), expectedBaseType);
632 }
633 
TEST_P(GetGlTextureInfoTests,givenApiTargetTypeWhenAskedForGmmCubeFaceIndexThenReturnValidOnlyForCubeType)634 TEST_P(GetGlTextureInfoTests, givenApiTargetTypeWhenAskedForGmmCubeFaceIndexThenReturnValidOnlyForCubeType) {
635     tempMM->useForcedGmm = false;
636     auto apiTarget = GetParam();
637     auto gmmCubeFaceIndex = static_cast<unsigned int>(GmmTypesConverter::getCubeFaceIndex(apiTarget));
638 
639     switch (apiTarget) {
640     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
641         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_NEG_X));
642         break;
643     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
644         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_POS_X));
645         break;
646     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
647         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_NEG_Y));
648         break;
649     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
650         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_POS_Y));
651         break;
652     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
653         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_NEG_Z));
654         break;
655     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
656         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_CUBE_FACE_POS_Z));
657         break;
658     default:
659         EXPECT_EQ(gmmCubeFaceIndex, static_cast<unsigned int>(__GMM_NO_CUBE_MAP));
660         break;
661     }
662 }
663