xref: /aosp_15_r20/external/angle/src/tests/gl_tests/VulkanExternalImageTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // VulkanExternalImageTest.cpp : Tests of images allocated externally using Vulkan.
8 
9 #include "test_utils/ANGLETest.h"
10 
11 #include "common/debug.h"
12 #include "test_utils/VulkanHelper.h"
13 #include "test_utils/gl_raii.h"
14 
15 namespace angle
16 {
17 
18 namespace
19 {
20 
21 constexpr int kInvalidFd = -1;
22 
23 constexpr VkImageUsageFlags kDefaultImageUsageFlags =
24     VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
25     VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
26     VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
27 constexpr VkImageCreateFlags kDefaultImageCreateFlags = 0;
28 
29 constexpr VkImageUsageFlags kNoStorageImageUsageFlags =
30     kDefaultImageUsageFlags & ~VK_IMAGE_USAGE_STORAGE_BIT;
31 constexpr VkImageCreateFlags kMutableImageCreateFlags =
32     kDefaultImageCreateFlags | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
33 
34 // List of VkFormat/internalformat combinations Chrome uses.
35 // This is compiled from the maps in
36 // components/viz/common/resources/resource_format_utils.cc.
37 const struct ImageFormatPair
38 {
39     VkFormat vkFormat;
40     GLenum internalFormat;
41     const char *requiredExtension;
42 } kChromeFormats[] = {
43     {VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8_OES},                    // RGBA_8888
44     {VK_FORMAT_B8G8R8A8_UNORM, GL_BGRA8_EXT},                    // BGRA_8888
45     {VK_FORMAT_R4G4B4A4_UNORM_PACK16, GL_RGBA4},                 // RGBA_4444
46     {VK_FORMAT_R16G16B16A16_SFLOAT, GL_RGBA16F_EXT},             // RGBA_F16
47     {VK_FORMAT_R8_UNORM, GL_R8_EXT},                             // RED_8
48     {VK_FORMAT_R5G6B5_UNORM_PACK16, GL_RGB565},                  // RGB_565
49     {VK_FORMAT_R16_UNORM, GL_R16_EXT, "GL_EXT_texture_norm16"},  // R16_EXT
50     {VK_FORMAT_A2B10G10R10_UNORM_PACK32, GL_RGB10_A2_EXT},       // RGBA_1010102
51     {VK_FORMAT_R8_UNORM, GL_ALPHA8_EXT},                         // ALPHA_8
52     {VK_FORMAT_R8_UNORM, GL_LUMINANCE8_EXT},                     // LUMINANCE_8
53     {VK_FORMAT_R8G8_UNORM, GL_RG8_EXT},                          // RG_88
54     {VK_FORMAT_R8G8B8A8_UNORM, GL_RGB8_OES},                     // RGBX_8888
55 };
56 
57 struct OpaqueFdTraits
58 {
59     using Handle = int;
InvalidHandleangle::__anon91eea5720111::OpaqueFdTraits60     static Handle InvalidHandle() { return kInvalidFd; }
61 
MemoryObjectExtensionangle::__anon91eea5720111::OpaqueFdTraits62     static const char *MemoryObjectExtension() { return "GL_EXT_memory_object_fd"; }
SemaphoreExtensionangle::__anon91eea5720111::OpaqueFdTraits63     static const char *SemaphoreExtension() { return "GL_EXT_semaphore_fd"; }
64 
CanCreateSemaphoreangle::__anon91eea5720111::OpaqueFdTraits65     static bool CanCreateSemaphore(const VulkanHelper &helper)
66     {
67         return helper.canCreateSemaphoreOpaqueFd();
68     }
69 
CreateSemaphoreangle::__anon91eea5720111::OpaqueFdTraits70     static VkResult CreateSemaphore(VulkanHelper *helper, VkSemaphore *semaphore)
71     {
72         return helper->createSemaphoreOpaqueFd(semaphore);
73     }
74 
ExportSemaphoreangle::__anon91eea5720111::OpaqueFdTraits75     static VkResult ExportSemaphore(VulkanHelper *helper, VkSemaphore semaphore, Handle *handle)
76     {
77         return helper->exportSemaphoreOpaqueFd(semaphore, handle);
78     }
79 
ImportSemaphoreangle::__anon91eea5720111::OpaqueFdTraits80     static void ImportSemaphore(GLuint semaphore, Handle handle)
81     {
82         glImportSemaphoreFdEXT(semaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, handle);
83     }
84 
CanCreateImageangle::__anon91eea5720111::OpaqueFdTraits85     static bool CanCreateImage(const VulkanHelper &helper,
86                                VkFormat format,
87                                VkImageType type,
88                                VkImageTiling tiling,
89                                VkImageCreateFlags createFlags,
90                                VkImageUsageFlags usageFlags)
91     {
92         return helper.canCreateImageOpaqueFd(format, type, tiling, createFlags, usageFlags);
93     }
94 
CreateImage2Dangle::__anon91eea5720111::OpaqueFdTraits95     static VkResult CreateImage2D(VulkanHelper *helper,
96                                   VkFormat format,
97                                   VkImageCreateFlags createFlags,
98                                   VkImageUsageFlags usageFlags,
99                                   const void *imageCreateInfoPNext,
100                                   VkExtent3D extent,
101                                   VkImage *imageOut,
102                                   VkDeviceMemory *deviceMemoryOut,
103                                   VkDeviceSize *deviceMemorySizeOut)
104     {
105         return helper->createImage2DOpaqueFd(format, createFlags, usageFlags, imageCreateInfoPNext,
106                                              extent, imageOut, deviceMemoryOut,
107                                              deviceMemorySizeOut);
108     }
109 
ExportMemoryangle::__anon91eea5720111::OpaqueFdTraits110     static VkResult ExportMemory(VulkanHelper *helper, VkDeviceMemory deviceMemory, Handle *handle)
111     {
112         return helper->exportMemoryOpaqueFd(deviceMemory, handle);
113     }
114 
ImportMemoryangle::__anon91eea5720111::OpaqueFdTraits115     static void ImportMemory(GLuint memoryObject, GLuint64 size, Handle handle)
116     {
117         glImportMemoryFdEXT(memoryObject, size, GL_HANDLE_TYPE_OPAQUE_FD_EXT, handle);
118     }
119 };
120 
121 struct FuchsiaTraits
122 {
123     using Handle = zx_handle_t;
124 
InvalidHandleangle::__anon91eea5720111::FuchsiaTraits125     static Handle InvalidHandle() { return ZX_HANDLE_INVALID; }
126 
MemoryObjectExtensionangle::__anon91eea5720111::FuchsiaTraits127     static const char *MemoryObjectExtension() { return "GL_ANGLE_memory_object_fuchsia"; }
SemaphoreExtensionangle::__anon91eea5720111::FuchsiaTraits128     static const char *SemaphoreExtension() { return "GL_ANGLE_semaphore_fuchsia"; }
129 
CanCreateSemaphoreangle::__anon91eea5720111::FuchsiaTraits130     static bool CanCreateSemaphore(const VulkanHelper &helper)
131     {
132         return helper.canCreateSemaphoreZirconEvent();
133     }
134 
CreateSemaphoreangle::__anon91eea5720111::FuchsiaTraits135     static VkResult CreateSemaphore(VulkanHelper *helper, VkSemaphore *semaphore)
136     {
137         return helper->createSemaphoreZirconEvent(semaphore);
138     }
139 
ExportSemaphoreangle::__anon91eea5720111::FuchsiaTraits140     static VkResult ExportSemaphore(VulkanHelper *helper, VkSemaphore semaphore, Handle *handle)
141     {
142         return helper->exportSemaphoreZirconEvent(semaphore, handle);
143     }
144 
ImportSemaphoreangle::__anon91eea5720111::FuchsiaTraits145     static void ImportSemaphore(GLuint semaphore, Handle handle)
146     {
147         glImportSemaphoreZirconHandleANGLE(semaphore, GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE, handle);
148     }
149 
CanCreateImageangle::__anon91eea5720111::FuchsiaTraits150     static bool CanCreateImage(const VulkanHelper &helper,
151                                VkFormat format,
152                                VkImageType type,
153                                VkImageTiling tiling,
154                                VkImageCreateFlags createFlags,
155                                VkImageUsageFlags usageFlags)
156     {
157         return helper.canCreateImageZirconVmo(format, type, tiling, createFlags, usageFlags);
158     }
159 
CreateImage2Dangle::__anon91eea5720111::FuchsiaTraits160     static VkResult CreateImage2D(VulkanHelper *helper,
161                                   VkFormat format,
162                                   VkImageCreateFlags createFlags,
163                                   VkImageUsageFlags usageFlags,
164                                   const void *imageCreateInfoPNext,
165                                   VkExtent3D extent,
166                                   VkImage *imageOut,
167                                   VkDeviceMemory *deviceMemoryOut,
168                                   VkDeviceSize *deviceMemorySizeOut)
169     {
170         return helper->createImage2DZirconVmo(format, createFlags, usageFlags, imageCreateInfoPNext,
171                                               extent, imageOut, deviceMemoryOut,
172                                               deviceMemorySizeOut);
173     }
174 
ExportMemoryangle::__anon91eea5720111::FuchsiaTraits175     static VkResult ExportMemory(VulkanHelper *helper, VkDeviceMemory deviceMemory, Handle *handle)
176     {
177         return helper->exportMemoryZirconVmo(deviceMemory, handle);
178     }
179 
ImportMemoryangle::__anon91eea5720111::FuchsiaTraits180     static void ImportMemory(GLuint memoryObject, GLuint64 size, Handle handle)
181     {
182         glImportMemoryZirconHandleANGLE(memoryObject, size, GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE,
183                                         handle);
184     }
185 };
186 
GetPostReleaseVulkanLayout(GLenum glLayout)187 VkImageLayout GetPostReleaseVulkanLayout(GLenum glLayout)
188 {
189     switch (glLayout)
190     {
191         case GL_NONE:
192         case GL_LAYOUT_GENERAL_EXT:
193         default:
194             return VK_IMAGE_LAYOUT_GENERAL;
195         case GL_LAYOUT_COLOR_ATTACHMENT_EXT:
196             return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
197         case GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT:
198             return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
199         case GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT:
200             return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
201         case GL_LAYOUT_SHADER_READ_ONLY_EXT:
202             return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
203         case GL_LAYOUT_TRANSFER_SRC_EXT:
204             return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
205         case GL_LAYOUT_TRANSFER_DST_EXT:
206             return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
207         case GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT:
208             return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR;
209         case GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT:
210             return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR;
211     }
212 }
213 
AdjustCreateFlags(bool useMemoryObjectFlags,VkImageCreateFlags * createFlags)214 void AdjustCreateFlags(bool useMemoryObjectFlags, VkImageCreateFlags *createFlags)
215 {
216     // If the GL_ANGLE_memory_object_flags extension is not supported, GL assumes that the mutable
217     // create flag is specified.
218     if (!useMemoryObjectFlags)
219     {
220         *createFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
221     }
222 
223     // The spec is not clear about the other create flags.
224 }
225 
226 constexpr uint32_t kWidth  = 64;
227 constexpr uint32_t kHeight = 64;
228 
229 }  // namespace
230 
231 class VulkanExternalImageTest : public ANGLETest<>
232 {
233   protected:
VulkanExternalImageTest()234     VulkanExternalImageTest()
235     {
236         setWindowWidth(1);
237         setWindowHeight(1);
238         setConfigRedBits(8);
239         setConfigGreenBits(8);
240         setConfigBlueBits(8);
241         setConfigAlphaBits(8);
242     }
243 
244     template <typename Traits>
245     void runShouldDrawTest(bool isSwiftshader, bool enableDebugLayers);
246 
247     template <typename Traits>
248     void runWaitSemaphoresRetainsContentTest(bool isSwiftshader, bool enableDebugLayers);
249 };
250 
251 class VulkanExternalImageTestES31 : public VulkanExternalImageTest
252 {};
253 
254 template <typename Traits>
RunShouldImportMemoryTest(VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,bool isSwiftshader,bool enableDebugLayers)255 void RunShouldImportMemoryTest(VkImageCreateFlags createFlags,
256                                VkImageUsageFlags usageFlags,
257                                bool isSwiftshader,
258                                bool enableDebugLayers)
259 {
260     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
261 
262     VulkanHelper helper;
263     helper.initialize(isSwiftshader, enableDebugLayers);
264 
265     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
266     ANGLE_SKIP_TEST_IF(!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D,
267                                                VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags));
268 
269     VkImage image                 = VK_NULL_HANDLE;
270     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
271     VkDeviceSize deviceMemorySize = 0;
272 
273     VkExtent3D extent = {1, 1, 1};
274     VkResult result   = Traits::CreateImage2D(&helper, format, createFlags, usageFlags, nullptr,
275                                               extent, &image, &deviceMemory, &deviceMemorySize);
276     EXPECT_EQ(result, VK_SUCCESS);
277 
278     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
279     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
280     EXPECT_EQ(result, VK_SUCCESS);
281     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
282 
283     {
284         GLMemoryObject memoryObject;
285         GLint dedicatedMemory = GL_TRUE;
286         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
287                                      &dedicatedMemory);
288         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
289 
290         // Test that after calling glImportMemoryFdEXT, the parameters of the memory object cannot
291         // be changed
292         dedicatedMemory = GL_FALSE;
293         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
294                                      &dedicatedMemory);
295         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
296     }
297 
298     EXPECT_GL_NO_ERROR();
299 
300     vkDestroyImage(helper.getDevice(), image, nullptr);
301     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
302 }
303 
304 // glImportMemoryFdEXT must be able to import a valid opaque fd.
TEST_P(VulkanExternalImageTest,ShouldImportMemoryOpaqueFd)305 TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd)
306 {
307     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
308     RunShouldImportMemoryTest<OpaqueFdTraits>(kDefaultImageCreateFlags, kDefaultImageUsageFlags,
309                                               isSwiftshader(), enableDebugLayers());
310 }
311 
312 // glImportMemoryZirconHandleANGLE must be able to import a valid vmo.
TEST_P(VulkanExternalImageTest,ShouldImportMemoryZirconVmo)313 TEST_P(VulkanExternalImageTest, ShouldImportMemoryZirconVmo)
314 {
315     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
316     RunShouldImportMemoryTest<FuchsiaTraits>(kDefaultImageCreateFlags, kDefaultImageUsageFlags,
317                                              isSwiftshader(), enableDebugLayers());
318 }
319 
320 template <typename Traits>
RunShouldImportSemaphoreTest(bool isSwiftshader,bool enableDebugLayers)321 void RunShouldImportSemaphoreTest(bool isSwiftshader, bool enableDebugLayers)
322 {
323     ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
324 
325     VulkanHelper helper;
326     helper.initialize(isSwiftshader, enableDebugLayers);
327 
328     ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
329 
330     VkSemaphore vkSemaphore = VK_NULL_HANDLE;
331     VkResult result         = helper.createSemaphoreOpaqueFd(&vkSemaphore);
332     EXPECT_EQ(result, VK_SUCCESS);
333 
334     typename Traits::Handle semaphoreHandle = Traits::InvalidHandle();
335     result = Traits::ExportSemaphore(&helper, vkSemaphore, &semaphoreHandle);
336     EXPECT_EQ(result, VK_SUCCESS);
337     EXPECT_NE(semaphoreHandle, Traits::InvalidHandle());
338 
339     {
340         GLSemaphore glSemaphore;
341         Traits::ImportSemaphore(glSemaphore, semaphoreHandle);
342     }
343 
344     EXPECT_GL_NO_ERROR();
345 
346     vkDestroySemaphore(helper.getDevice(), vkSemaphore, nullptr);
347 }
348 
349 // glImportSemaphoreFdEXT must be able to import a valid opaque fd.
TEST_P(VulkanExternalImageTest,ShouldImportSemaphoreOpaqueFd)350 TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreOpaqueFd)
351 {
352     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
353     RunShouldImportSemaphoreTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
354 }
355 
356 // glImportSemaphoreZirconHandleANGLE must be able to import a valid handle.
TEST_P(VulkanExternalImageTest,ShouldImportSemaphoreZirconEvent)357 TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreZirconEvent)
358 {
359     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
360     RunShouldImportSemaphoreTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
361 }
362 
363 template <typename Traits>
RunShouldClearTest(bool useMemoryObjectFlags,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,bool isSwiftshader,bool enableDebugLayers)364 void RunShouldClearTest(bool useMemoryObjectFlags,
365                         VkImageCreateFlags createFlags,
366                         VkImageUsageFlags usageFlags,
367                         bool isSwiftshader,
368                         bool enableDebugLayers)
369 {
370     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
371 
372     VulkanHelper helper;
373     helper.initialize(isSwiftshader, enableDebugLayers);
374 
375     AdjustCreateFlags(useMemoryObjectFlags, &createFlags);
376 
377     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
378     ANGLE_SKIP_TEST_IF(!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D,
379                                                VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags));
380 
381     VkImage image                 = VK_NULL_HANDLE;
382     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
383     VkDeviceSize deviceMemorySize = 0;
384 
385     VkExtent3D extent = {1, 1, 1};
386     VkResult result   = Traits::CreateImage2D(&helper, format, createFlags, usageFlags, nullptr,
387                                               extent, &image, &deviceMemory, &deviceMemorySize);
388     EXPECT_EQ(result, VK_SUCCESS);
389 
390     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
391     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
392     EXPECT_EQ(result, VK_SUCCESS);
393     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
394 
395     {
396         GLMemoryObject memoryObject;
397         GLint dedicatedMemory = GL_TRUE;
398         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
399                                      &dedicatedMemory);
400         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
401 
402         GLTexture texture;
403         glBindTexture(GL_TEXTURE_2D, texture);
404         if (useMemoryObjectFlags)
405         {
406             glTexStorageMemFlags2DANGLE(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0,
407                                         createFlags, usageFlags, nullptr);
408         }
409         else
410         {
411             glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
412         }
413 
414         GLFramebuffer framebuffer;
415         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
416         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
417 
418         glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
419         glClear(GL_COLOR_BUFFER_BIT);
420 
421         EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
422     }
423 
424     EXPECT_GL_NO_ERROR();
425 
426     vkDestroyImage(helper.getDevice(), image, nullptr);
427     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
428 }
429 
430 // Test creating and clearing a simple RGBA8 texture in an opaque fd.
TEST_P(VulkanExternalImageTest,ShouldClearOpaqueFdRGBA8)431 TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8)
432 {
433     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
434     // http://anglebug.com/42263236
435     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL() && (IsPixel2() || IsPixel2XL()));
436     RunShouldClearTest<OpaqueFdTraits>(false, kDefaultImageCreateFlags, kDefaultImageUsageFlags,
437                                        isSwiftshader(), enableDebugLayers());
438 }
439 
440 // Test creating and clearing a simple RGBA8 texture in an opaque fd, using
441 // GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,ShouldClearOpaqueWithFlagsFdRGBA8)442 TEST_P(VulkanExternalImageTest, ShouldClearOpaqueWithFlagsFdRGBA8)
443 {
444     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
445     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
446     RunShouldClearTest<OpaqueFdTraits>(true, kDefaultImageCreateFlags, kDefaultImageUsageFlags,
447                                        isSwiftshader(), enableDebugLayers());
448 }
449 
450 // Test creating and clearing a simple RGBA8 texture without STORAGE usage in an opaque fd.
TEST_P(VulkanExternalImageTest,ShouldClearNoStorageUsageOpaqueFdRGBA8)451 TEST_P(VulkanExternalImageTest, ShouldClearNoStorageUsageOpaqueFdRGBA8)
452 {
453     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
454     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
455     RunShouldClearTest<OpaqueFdTraits>(true, kDefaultImageCreateFlags, kNoStorageImageUsageFlags,
456                                        isSwiftshader(), enableDebugLayers());
457 }
458 
459 // Test creating and clearing a simple RGBA8 texture without STORAGE usage but with MUTABLE in an
460 // opaque fd.
TEST_P(VulkanExternalImageTest,ShouldClearMutableNoStorageUsageOpaqueFdRGBA8)461 TEST_P(VulkanExternalImageTest, ShouldClearMutableNoStorageUsageOpaqueFdRGBA8)
462 {
463     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
464     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
465     RunShouldClearTest<OpaqueFdTraits>(true, kMutableImageCreateFlags, kNoStorageImageUsageFlags,
466                                        isSwiftshader(), enableDebugLayers());
467 }
468 
469 // Test creating and clearing a simple RGBA8 texture in a zircon vmo.
TEST_P(VulkanExternalImageTest,ShouldClearZirconVmoRGBA8)470 TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoRGBA8)
471 {
472     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
473     RunShouldClearTest<FuchsiaTraits>(false, kDefaultImageCreateFlags, kDefaultImageUsageFlags,
474                                       isSwiftshader(), enableDebugLayers());
475 }
476 
477 // Test creating and clearing a simple RGBA8 texture in a zircon vmo, using
478 // GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,ShouldClearZirconWithFlagsVmoRGBA8)479 TEST_P(VulkanExternalImageTest, ShouldClearZirconWithFlagsVmoRGBA8)
480 {
481     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
482     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
483     RunShouldClearTest<FuchsiaTraits>(true, kDefaultImageCreateFlags, kDefaultImageUsageFlags,
484                                       isSwiftshader(), enableDebugLayers());
485 }
486 
487 // Test creating and clearing a simple RGBA8 texture without STORAGE usage in a zircon vmo.
TEST_P(VulkanExternalImageTest,ShouldClearNoStorageUsageZirconVmoRGBA8)488 TEST_P(VulkanExternalImageTest, ShouldClearNoStorageUsageZirconVmoRGBA8)
489 {
490     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
491     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
492     RunShouldClearTest<FuchsiaTraits>(true, kDefaultImageCreateFlags, kNoStorageImageUsageFlags,
493                                       isSwiftshader(), enableDebugLayers());
494 }
495 
496 // Test creating and clearing a simple RGBA8 texture without STORAGE usage but with MUTABLE in a
497 // zircon vmo.
TEST_P(VulkanExternalImageTest,ShouldClearMutableNoStorageUsageZirconVmoRGBA8)498 TEST_P(VulkanExternalImageTest, ShouldClearMutableNoStorageUsageZirconVmoRGBA8)
499 {
500     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
501     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
502     RunShouldClearTest<FuchsiaTraits>(true, kMutableImageCreateFlags, kNoStorageImageUsageFlags,
503                                       isSwiftshader(), enableDebugLayers());
504 }
505 
506 template <typename Traits>
RunTextureFormatCompatChromiumTest(bool useMemoryObjectFlags,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,bool isSwiftshader,bool enableDebugLayers,bool isES3)507 void RunTextureFormatCompatChromiumTest(bool useMemoryObjectFlags,
508                                         VkImageCreateFlags createFlags,
509                                         VkImageUsageFlags usageFlags,
510                                         bool isSwiftshader,
511                                         bool enableDebugLayers,
512                                         bool isES3)
513 {
514     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
515 
516     AdjustCreateFlags(useMemoryObjectFlags, &createFlags);
517 
518     VulkanHelper helper;
519     helper.initialize(isSwiftshader, enableDebugLayers);
520     for (const ImageFormatPair &format : kChromeFormats)
521     {
522         // https://crbug.com/angleproject/5046
523         if ((format.vkFormat == VK_FORMAT_R4G4B4A4_UNORM_PACK16) && IsIntel())
524         {
525             continue;
526         }
527 
528         if (!Traits::CanCreateImage(helper, format.vkFormat, VK_IMAGE_TYPE_2D,
529                                     VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags))
530         {
531             continue;
532         }
533 
534         if (format.requiredExtension && !IsGLExtensionEnabled(format.requiredExtension))
535         {
536             continue;
537         }
538 
539         if (format.internalFormat == GL_RGB10_A2_EXT && !isES3 &&
540             !IsGLExtensionEnabled("GL_EXT_texture_type_2_10_10_10_REV"))
541         {
542             continue;
543         }
544 
545         VkImage image                 = VK_NULL_HANDLE;
546         VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
547         VkDeviceSize deviceMemorySize = 0;
548 
549         VkExtent3D extent = {113, 211, 1};
550         VkResult result =
551             Traits::CreateImage2D(&helper, format.vkFormat, createFlags, usageFlags, nullptr,
552                                   extent, &image, &deviceMemory, &deviceMemorySize);
553         EXPECT_EQ(result, VK_SUCCESS);
554 
555         typename Traits::Handle memoryHandle = Traits::InvalidHandle();
556         result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
557         EXPECT_EQ(result, VK_SUCCESS);
558         EXPECT_NE(memoryHandle, Traits::InvalidHandle());
559 
560         {
561             GLMemoryObject memoryObject;
562             GLint dedicatedMemory = GL_TRUE;
563             glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
564                                          &dedicatedMemory);
565             Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
566 
567             GLTexture texture;
568             glBindTexture(GL_TEXTURE_2D, texture);
569             if (useMemoryObjectFlags)
570             {
571                 glTexStorageMemFlags2DANGLE(GL_TEXTURE_2D, 1, format.internalFormat, extent.width,
572                                             extent.height, memoryObject, 0, createFlags, usageFlags,
573                                             nullptr);
574             }
575             else
576             {
577                 glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, format.internalFormat, extent.width,
578                                      extent.height, memoryObject, 0);
579             }
580         }
581 
582         EXPECT_GL_NO_ERROR();
583 
584         vkDestroyImage(helper.getDevice(), image, nullptr);
585         vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
586     }
587 }
588 
589 // Test all format combinations used by Chrome import successfully (opaque fd).
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumFd)590 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd)
591 {
592     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
593     RunTextureFormatCompatChromiumTest<OpaqueFdTraits>(
594         false, kDefaultImageCreateFlags, kDefaultImageUsageFlags, isSwiftshader(),
595         enableDebugLayers(), getClientMajorVersion() >= 3);
596 }
597 
598 // Test all format combinations used by Chrome import successfully (opaque fd), using
599 // GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumWithFlagsFd)600 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumWithFlagsFd)
601 {
602     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
603     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
604     RunTextureFormatCompatChromiumTest<OpaqueFdTraits>(
605         true, kDefaultImageCreateFlags, kDefaultImageUsageFlags, isSwiftshader(),
606         enableDebugLayers(), getClientMajorVersion() >= 3);
607 }
608 
609 // Test all format combinations used by Chrome import successfully (opaque fd), without STORAGE
610 // usage.
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumNoStorageFd)611 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumNoStorageFd)
612 {
613     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
614     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
615     RunTextureFormatCompatChromiumTest<OpaqueFdTraits>(
616         true, kDefaultImageCreateFlags, kNoStorageImageUsageFlags, isSwiftshader(),
617         enableDebugLayers(), getClientMajorVersion() >= 3);
618 }
619 
620 // Test all format combinations used by Chrome import successfully (opaque fd), without STORAGE
621 // usage but with MUTABLE.
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumMutableNoStorageFd)622 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumMutableNoStorageFd)
623 {
624     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
625     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
626 
627     // http://anglebug.com/42264218
628     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
629 
630     RunTextureFormatCompatChromiumTest<OpaqueFdTraits>(
631         true, kMutableImageCreateFlags, kNoStorageImageUsageFlags, isSwiftshader(),
632         enableDebugLayers(), getClientMajorVersion() >= 3);
633 }
634 
635 // Test all format combinations used by Chrome import successfully (fuchsia).
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumZirconVmo)636 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumZirconVmo)
637 {
638     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
639     RunTextureFormatCompatChromiumTest<FuchsiaTraits>(
640         false, kDefaultImageCreateFlags, kDefaultImageUsageFlags, isSwiftshader(),
641         enableDebugLayers(), getClientMajorVersion() >= 3);
642 }
643 
644 // Test all format combinations used by Chrome import successfully (fuchsia), using
645 // GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumWithFlagsZirconVmo)646 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumWithFlagsZirconVmo)
647 {
648     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
649     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
650     RunTextureFormatCompatChromiumTest<FuchsiaTraits>(
651         true, kDefaultImageCreateFlags, kDefaultImageUsageFlags, isSwiftshader(),
652         enableDebugLayers(), getClientMajorVersion() >= 3);
653 }
654 
655 // Test all format combinations used by Chrome import successfully (fuchsia), without STORAGE usage.
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumNoStorageZirconVmo)656 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumNoStorageZirconVmo)
657 {
658     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
659     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
660     RunTextureFormatCompatChromiumTest<FuchsiaTraits>(
661         true, kDefaultImageCreateFlags, kNoStorageImageUsageFlags, isSwiftshader(),
662         enableDebugLayers(), getClientMajorVersion() >= 3);
663 }
664 
665 // Test all format combinations used by Chrome import successfully (fuchsia), without STORAGE usage
666 // but with MUTABLE.
TEST_P(VulkanExternalImageTest,TextureFormatCompatChromiumMutableNoStorageZirconVmo)667 TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumMutableNoStorageZirconVmo)
668 {
669     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
670     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
671     RunTextureFormatCompatChromiumTest<FuchsiaTraits>(
672         true, kMutableImageCreateFlags, kNoStorageImageUsageFlags, isSwiftshader(),
673         enableDebugLayers(), getClientMajorVersion() >= 3);
674 }
675 
676 template <typename Traits>
RunShouldClearWithSemaphoresTest(bool useMemoryObjectFlags,VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags,bool isSwiftshader,bool enableDebugLayers)677 void RunShouldClearWithSemaphoresTest(bool useMemoryObjectFlags,
678                                       VkImageCreateFlags createFlags,
679                                       VkImageUsageFlags usageFlags,
680                                       bool isSwiftshader,
681                                       bool enableDebugLayers)
682 {
683     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
684     ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
685 
686     AdjustCreateFlags(useMemoryObjectFlags, &createFlags);
687 
688     VulkanHelper helper;
689     helper.initialize(isSwiftshader, enableDebugLayers);
690 
691     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
692     ANGLE_SKIP_TEST_IF(!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D,
693                                                VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags));
694     ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
695 
696     VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
697     VkResult result                = Traits::CreateSemaphore(&helper, &vkAcquireSemaphore);
698     EXPECT_EQ(result, VK_SUCCESS);
699     EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
700 
701     VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
702     result                         = Traits::CreateSemaphore(&helper, &vkReleaseSemaphore);
703     EXPECT_EQ(result, VK_SUCCESS);
704     EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
705 
706     typename Traits::Handle acquireSemaphoreHandle = Traits::InvalidHandle();
707     result = Traits::ExportSemaphore(&helper, vkAcquireSemaphore, &acquireSemaphoreHandle);
708     EXPECT_EQ(result, VK_SUCCESS);
709     EXPECT_NE(acquireSemaphoreHandle, Traits::InvalidHandle());
710 
711     typename Traits::Handle releaseSemaphoreHandle = Traits::InvalidHandle();
712     result = Traits::ExportSemaphore(&helper, vkReleaseSemaphore, &releaseSemaphoreHandle);
713     EXPECT_EQ(result, VK_SUCCESS);
714     EXPECT_NE(releaseSemaphoreHandle, Traits::InvalidHandle());
715 
716     VkImage image                 = VK_NULL_HANDLE;
717     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
718     VkDeviceSize deviceMemorySize = 0;
719 
720     VkExtent3D extent = {1, 1, 1};
721     result = Traits::CreateImage2D(&helper, format, createFlags, usageFlags, nullptr, extent,
722                                    &image, &deviceMemory, &deviceMemorySize);
723     EXPECT_EQ(result, VK_SUCCESS);
724 
725     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
726     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
727     EXPECT_EQ(result, VK_SUCCESS);
728     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
729 
730     {
731         GLMemoryObject memoryObject;
732         GLint dedicatedMemory = GL_TRUE;
733         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
734                                      &dedicatedMemory);
735         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
736 
737         GLTexture texture;
738         glBindTexture(GL_TEXTURE_2D, texture);
739         if (useMemoryObjectFlags)
740         {
741             glTexStorageMemFlags2DANGLE(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0,
742                                         createFlags, usageFlags, nullptr);
743         }
744         else
745         {
746             glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
747         }
748 
749         GLSemaphore glAcquireSemaphore;
750         Traits::ImportSemaphore(glAcquireSemaphore, acquireSemaphoreHandle);
751 
752         helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_UNDEFINED,
753                                               VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore);
754 
755         const GLuint barrierTextures[] = {
756             texture,
757         };
758         constexpr uint32_t textureBarriersCount = std::extent<decltype(barrierTextures)>();
759         const GLenum textureSrcLayouts[]        = {
760             GL_LAYOUT_GENERAL_EXT,
761         };
762         constexpr uint32_t textureSrcLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
763         static_assert(textureBarriersCount == textureSrcLayoutsCount,
764                       "barrierTextures and textureSrcLayouts must be the same length");
765         glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
766                            textureSrcLayouts);
767 
768         GLFramebuffer framebuffer;
769         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
770         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
771 
772         glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
773         glClear(GL_COLOR_BUFFER_BIT);
774 
775         GLSemaphore glReleaseSemaphore;
776         Traits::ImportSemaphore(glReleaseSemaphore, releaseSemaphoreHandle);
777 
778         const GLenum textureDstLayouts[] = {
779             GL_LAYOUT_TRANSFER_SRC_EXT,
780         };
781         constexpr uint32_t textureDstLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
782         static_assert(textureBarriersCount == textureDstLayoutsCount,
783                       "barrierTextures and textureDstLayouts must be the same length");
784         glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
785                              textureDstLayouts);
786 
787         helper.waitSemaphoreAndAcquireImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
788                                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
789                                             vkReleaseSemaphore);
790         uint8_t pixels[4];
791         VkOffset3D offset = {};
792         helper.readPixels(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, format, offset, extent,
793                           pixels, sizeof(pixels));
794 
795         EXPECT_NEAR(0x80, pixels[0], 1);
796         EXPECT_NEAR(0x80, pixels[1], 1);
797         EXPECT_NEAR(0x80, pixels[2], 1);
798         EXPECT_NEAR(0x80, pixels[3], 1);
799     }
800 
801     EXPECT_GL_NO_ERROR();
802 
803     vkDeviceWaitIdle(helper.getDevice());
804     vkDestroyImage(helper.getDevice(), image, nullptr);
805     vkDestroySemaphore(helper.getDevice(), vkAcquireSemaphore, nullptr);
806     vkDestroySemaphore(helper.getDevice(), vkReleaseSemaphore, nullptr);
807     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
808 }
809 
810 // Test creating and clearing RGBA8 texture in opaque fd with acquire/release.
TEST_P(VulkanExternalImageTest,ShouldClearOpaqueFdWithSemaphores)811 TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores)
812 {
813     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
814     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
815 
816     // http://issuetracker.google.com/173004081
817     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsLinux() &&
818                        getEGLWindow()->isFeatureEnabled(Feature::AsyncCommandQueue));
819     // http://anglebug.com/42263923
820     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
821 
822     RunShouldClearWithSemaphoresTest<OpaqueFdTraits>(false, kDefaultImageCreateFlags,
823                                                      kDefaultImageUsageFlags, isSwiftshader(),
824                                                      enableDebugLayers());
825 }
826 
827 // Test creating and clearing RGBA8 texture in opaque fd with acquire/release, using
828 // GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,ShouldClearOpaqueFdWithSemaphoresWithFlags)829 TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphoresWithFlags)
830 {
831     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
832     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
833     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
834 
835     // http://issuetracker.google.com/173004081
836     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsLinux() &&
837                        getEGLWindow()->isFeatureEnabled(Feature::AsyncCommandQueue));
838 
839     RunShouldClearWithSemaphoresTest<OpaqueFdTraits>(true, kDefaultImageCreateFlags,
840                                                      kDefaultImageUsageFlags, isSwiftshader(),
841                                                      enableDebugLayers());
842 }
843 
844 // Test creating and clearing RGBA8 texture without STORAGE usage in opaque fd with acquire/release.
TEST_P(VulkanExternalImageTest,ShouldClearOpaqueFdWithSemaphoresNoStorage)845 TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphoresNoStorage)
846 {
847     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
848     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
849     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
850 
851     // http://issuetracker.google.com/173004081
852     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsLinux() &&
853                        getEGLWindow()->isFeatureEnabled(Feature::AsyncCommandQueue));
854 
855     RunShouldClearWithSemaphoresTest<OpaqueFdTraits>(true, kDefaultImageCreateFlags,
856                                                      kNoStorageImageUsageFlags, isSwiftshader(),
857                                                      enableDebugLayers());
858 }
859 
860 // Test creating and clearing RGBA8 texture without STORAGE usage but with MUTABLE in opaque fd with
861 // acquire/release.
TEST_P(VulkanExternalImageTest,ShouldClearOpaqueFdWithSemaphoresMutableNoStorage)862 TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphoresMutableNoStorage)
863 {
864     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
865     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
866     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
867 
868     // http://issuetracker.google.com/173004081
869     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsLinux() &&
870                        getEGLWindow()->isFeatureEnabled(Feature::AsyncCommandQueue));
871 
872     RunShouldClearWithSemaphoresTest<OpaqueFdTraits>(true, kMutableImageCreateFlags,
873                                                      kNoStorageImageUsageFlags, isSwiftshader(),
874                                                      enableDebugLayers());
875 }
876 
877 // Test creating and clearing RGBA8 texture in zircon vmo with acquire/release.
TEST_P(VulkanExternalImageTest,ShouldClearZirconVmoWithSemaphores)878 TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoWithSemaphores)
879 {
880     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
881     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
882     RunShouldClearWithSemaphoresTest<FuchsiaTraits>(false, kDefaultImageCreateFlags,
883                                                     kDefaultImageUsageFlags, isSwiftshader(),
884                                                     enableDebugLayers());
885 }
886 
887 // Test creating and clearing RGBA8 texture in zircon vmo with acquire/release, using
888 // GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,ShouldClearZirconVmoWithSemaphoresWithFlags)889 TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoWithSemaphoresWithFlags)
890 {
891     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
892     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
893     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
894     RunShouldClearWithSemaphoresTest<FuchsiaTraits>(true, kDefaultImageCreateFlags,
895                                                     kDefaultImageUsageFlags, isSwiftshader(),
896                                                     enableDebugLayers());
897 }
898 
899 // Test creating and clearing RGBA8 texture without STORAGE usage in zircon vmo with
900 // acquire/release.
TEST_P(VulkanExternalImageTest,ShouldClearZirconVmoWithSemaphoresNoStorage)901 TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoWithSemaphoresNoStorage)
902 {
903     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
904     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
905     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
906     RunShouldClearWithSemaphoresTest<FuchsiaTraits>(true, kDefaultImageCreateFlags,
907                                                     kNoStorageImageUsageFlags, isSwiftshader(),
908                                                     enableDebugLayers());
909 }
910 
911 // Test creating and clearing RGBA8 texture without STORAGE usage but with MUTABLE in zircon vmo
912 // with acquire/release.
TEST_P(VulkanExternalImageTest,ShouldClearZirconVmoWithSemaphoresMutableNoStorage)913 TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoWithSemaphoresMutableNoStorage)
914 {
915     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
916     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
917     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
918     RunShouldClearWithSemaphoresTest<FuchsiaTraits>(true, kMutableImageCreateFlags,
919                                                     kNoStorageImageUsageFlags, isSwiftshader(),
920                                                     enableDebugLayers());
921 }
922 
923 template <typename Traits>
runShouldDrawTest(bool isSwiftshader,bool enableDebugLayers)924 void VulkanExternalImageTest::runShouldDrawTest(bool isSwiftshader, bool enableDebugLayers)
925 {
926     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
927     ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
928 
929     VulkanHelper helper;
930     helper.initialize(isSwiftshader, enableDebugLayers);
931 
932     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
933     ANGLE_SKIP_TEST_IF(!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D,
934                                                VK_IMAGE_TILING_OPTIMAL, kDefaultImageCreateFlags,
935                                                kDefaultImageUsageFlags));
936     ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
937 
938     VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
939     VkResult result                = Traits::CreateSemaphore(&helper, &vkAcquireSemaphore);
940     EXPECT_EQ(result, VK_SUCCESS);
941     EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
942 
943     VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
944     result                         = Traits::CreateSemaphore(&helper, &vkReleaseSemaphore);
945     EXPECT_EQ(result, VK_SUCCESS);
946     EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
947 
948     typename Traits::Handle acquireSemaphoreHandle = Traits::InvalidHandle();
949     result = Traits::ExportSemaphore(&helper, vkAcquireSemaphore, &acquireSemaphoreHandle);
950     EXPECT_EQ(result, VK_SUCCESS);
951     EXPECT_NE(acquireSemaphoreHandle, Traits::InvalidHandle());
952 
953     typename Traits::Handle releaseSemaphoreHandle = Traits::InvalidHandle();
954     result = Traits::ExportSemaphore(&helper, vkReleaseSemaphore, &releaseSemaphoreHandle);
955     EXPECT_EQ(result, VK_SUCCESS);
956     EXPECT_NE(releaseSemaphoreHandle, Traits::InvalidHandle());
957 
958     VkImage image                 = VK_NULL_HANDLE;
959     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
960     VkDeviceSize deviceMemorySize = 0;
961 
962     VkExtent3D extent = {1, 1, 1};
963     result =
964         Traits::CreateImage2D(&helper, format, kDefaultImageCreateFlags, kDefaultImageUsageFlags,
965                               nullptr, extent, &image, &deviceMemory, &deviceMemorySize);
966     EXPECT_EQ(result, VK_SUCCESS);
967 
968     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
969     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
970     EXPECT_EQ(result, VK_SUCCESS);
971     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
972 
973     {
974         GLMemoryObject memoryObject;
975         GLint dedicatedMemory = GL_TRUE;
976         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
977                                      &dedicatedMemory);
978         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
979 
980         GLTexture texture;
981         glBindTexture(GL_TEXTURE_2D, texture);
982         glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
983 
984         GLSemaphore glAcquireSemaphore;
985         Traits::ImportSemaphore(glAcquireSemaphore, acquireSemaphoreHandle);
986 
987         // Transfer ownership to GL.
988         helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_UNDEFINED,
989                                               VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore);
990 
991         const GLuint barrierTextures[] = {
992             texture,
993         };
994         constexpr uint32_t textureBarriersCount = std::extent<decltype(barrierTextures)>();
995         const GLenum textureSrcLayouts[]        = {
996             GL_LAYOUT_GENERAL_EXT,
997         };
998         constexpr uint32_t textureSrcLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
999         static_assert(textureBarriersCount == textureSrcLayoutsCount,
1000                       "barrierTextures and textureSrcLayouts must be the same length");
1001         glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
1002                            textureSrcLayouts);
1003 
1004         GLFramebuffer framebuffer;
1005         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1006         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1007         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1008 
1009         // Make the texture red.
1010         ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1011         drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
1012         EXPECT_GL_NO_ERROR();
1013 
1014         // Transfer ownership back to test.
1015         GLSemaphore glReleaseSemaphore;
1016         Traits::ImportSemaphore(glReleaseSemaphore, releaseSemaphoreHandle);
1017 
1018         const GLenum textureDstLayouts[] = {
1019             GL_LAYOUT_TRANSFER_SRC_EXT,
1020         };
1021         constexpr uint32_t textureDstLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
1022         static_assert(textureBarriersCount == textureDstLayoutsCount,
1023                       "barrierTextures and textureDstLayouts must be the same length");
1024         glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
1025                              textureDstLayouts);
1026 
1027         helper.waitSemaphoreAndAcquireImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1028                                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1029                                             vkReleaseSemaphore);
1030 
1031         uint8_t pixels[4];
1032         VkOffset3D offset = {};
1033         helper.readPixels(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, format, offset, extent,
1034                           pixels, sizeof(pixels));
1035 
1036         EXPECT_EQ(0xFF, pixels[0]);
1037         EXPECT_EQ(0x00, pixels[1]);
1038         EXPECT_EQ(0x00, pixels[2]);
1039         EXPECT_EQ(0xFF, pixels[3]);
1040     }
1041 
1042     EXPECT_GL_NO_ERROR();
1043 
1044     vkDeviceWaitIdle(helper.getDevice());
1045     vkDestroyImage(helper.getDevice(), image, nullptr);
1046     vkDestroySemaphore(helper.getDevice(), vkAcquireSemaphore, nullptr);
1047     vkDestroySemaphore(helper.getDevice(), vkReleaseSemaphore, nullptr);
1048     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
1049 }
1050 
1051 // Test drawing to RGBA8 texture in opaque fd with acquire/release.
TEST_P(VulkanExternalImageTest,ShouldDrawOpaqueFdWithSemaphores)1052 TEST_P(VulkanExternalImageTest, ShouldDrawOpaqueFdWithSemaphores)
1053 {
1054     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1055     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1056 
1057     // http://issuetracker.google.com/173004081
1058     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsLinux() &&
1059                        getEGLWindow()->isFeatureEnabled(Feature::AsyncCommandQueue));
1060     // http://anglebug.com/42263923
1061     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
1062 
1063     runShouldDrawTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
1064 }
1065 
1066 // Test drawing to RGBA8 texture in zircon vmo with acquire/release multiple times.
TEST_P(VulkanExternalImageTest,ShouldDrawZirconVmoWithSemaphores)1067 TEST_P(VulkanExternalImageTest, ShouldDrawZirconVmoWithSemaphores)
1068 {
1069     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
1070     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
1071     runShouldDrawTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
1072 }
1073 
1074 template <typename Traits>
runWaitSemaphoresRetainsContentTest(bool isSwiftshader,bool enableDebugLayers)1075 void VulkanExternalImageTest::runWaitSemaphoresRetainsContentTest(bool isSwiftshader,
1076                                                                   bool enableDebugLayers)
1077 {
1078     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
1079     ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
1080 
1081     VulkanHelper helper;
1082     helper.initialize(isSwiftshader, enableDebugLayers);
1083 
1084     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1085     ANGLE_SKIP_TEST_IF(!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D,
1086                                                VK_IMAGE_TILING_OPTIMAL, kDefaultImageCreateFlags,
1087                                                kDefaultImageUsageFlags));
1088     ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
1089 
1090     VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
1091     VkResult result                = Traits::CreateSemaphore(&helper, &vkAcquireSemaphore);
1092     EXPECT_EQ(result, VK_SUCCESS);
1093     EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
1094 
1095     VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
1096     result                         = Traits::CreateSemaphore(&helper, &vkReleaseSemaphore);
1097     EXPECT_EQ(result, VK_SUCCESS);
1098     EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
1099 
1100     typename Traits::Handle acquireSemaphoreHandle = Traits::InvalidHandle();
1101     result = Traits::ExportSemaphore(&helper, vkAcquireSemaphore, &acquireSemaphoreHandle);
1102     EXPECT_EQ(result, VK_SUCCESS);
1103     EXPECT_NE(acquireSemaphoreHandle, Traits::InvalidHandle());
1104 
1105     typename Traits::Handle releaseSemaphoreHandle = Traits::InvalidHandle();
1106     result = Traits::ExportSemaphore(&helper, vkReleaseSemaphore, &releaseSemaphoreHandle);
1107     EXPECT_EQ(result, VK_SUCCESS);
1108     EXPECT_NE(releaseSemaphoreHandle, Traits::InvalidHandle());
1109 
1110     VkImage image                 = VK_NULL_HANDLE;
1111     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
1112     VkDeviceSize deviceMemorySize = 0;
1113 
1114     VkExtent3D extent = {kWidth, kHeight, 1};
1115     result =
1116         Traits::CreateImage2D(&helper, format, kDefaultImageCreateFlags, kDefaultImageUsageFlags,
1117                               nullptr, extent, &image, &deviceMemory, &deviceMemorySize);
1118     EXPECT_EQ(result, VK_SUCCESS);
1119 
1120     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
1121     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
1122     EXPECT_EQ(result, VK_SUCCESS);
1123     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
1124 
1125     {
1126         GLMemoryObject memoryObject;
1127         GLint dedicatedMemory = GL_TRUE;
1128         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
1129                                      &dedicatedMemory);
1130         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
1131 
1132         GLTexture texture;
1133         glBindTexture(GL_TEXTURE_2D, texture);
1134         glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight, memoryObject, 0);
1135 
1136         GLSemaphore glAcquireSemaphore;
1137         Traits::ImportSemaphore(glAcquireSemaphore, acquireSemaphoreHandle);
1138 
1139         // Transfer ownership to GL.
1140         helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_UNDEFINED,
1141                                               VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore);
1142 
1143         const GLuint barrierTextures[] = {
1144             texture,
1145         };
1146         constexpr uint32_t textureBarriersCount = std::extent<decltype(barrierTextures)>();
1147         const GLenum textureSrcLayouts[]        = {
1148             GL_LAYOUT_GENERAL_EXT,
1149         };
1150         constexpr uint32_t textureSrcLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
1151         static_assert(textureBarriersCount == textureSrcLayoutsCount,
1152                       "barrierTextures and textureSrcLayouts must be the same length");
1153         glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
1154                            textureSrcLayouts);
1155 
1156         GLFramebuffer framebuffer;
1157         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1158         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1159         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1160 
1161         // Make the texture red.
1162         ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1163         glViewport(0, 0, kWidth, kHeight);
1164         drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
1165         EXPECT_GL_NO_ERROR();
1166 
1167         // Transfer ownership back to test.
1168         GLSemaphore glReleaseSemaphore;
1169         Traits::ImportSemaphore(glReleaseSemaphore, releaseSemaphoreHandle);
1170 
1171         const GLenum textureDstLayouts[] = {
1172             GL_LAYOUT_TRANSFER_SRC_EXT,
1173         };
1174         constexpr uint32_t textureDstLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
1175         static_assert(textureBarriersCount == textureDstLayoutsCount,
1176                       "barrierTextures and textureDstLayouts must be the same length");
1177         glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
1178                              textureDstLayouts);
1179 
1180         helper.waitSemaphoreAndAcquireImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1181                                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1182                                             vkReleaseSemaphore);
1183 
1184         // Transfer ownership to GL again, and make sure the contents are preserved.
1185         helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1186                                               VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore);
1187         glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
1188                            textureSrcLayouts);
1189 
1190         // Blend green
1191         ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1192         glEnable(GL_BLEND);
1193         glBlendFunc(GL_ONE, GL_ONE);
1194         drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
1195 
1196         // Transfer ownership back to test
1197         glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
1198                              textureDstLayouts);
1199         helper.waitSemaphoreAndAcquireImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1200                                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1201                                             vkReleaseSemaphore);
1202 
1203         uint8_t pixels[4 * kWidth * kHeight];
1204         VkOffset3D offset = {};
1205         helper.readPixels(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, format, offset, extent,
1206                           pixels, sizeof(pixels));
1207 
1208         EXPECT_EQ(0xFF, pixels[0]);
1209         EXPECT_EQ(0xFF, pixels[1]);
1210         EXPECT_EQ(0x00, pixels[2]);
1211         EXPECT_EQ(0xFF, pixels[3]);
1212 
1213         EXPECT_EQ(0xFF, pixels[4]);
1214         EXPECT_EQ(0xFF, pixels[5]);
1215         EXPECT_EQ(0x00, pixels[6]);
1216         EXPECT_EQ(0xFF, pixels[7]);
1217     }
1218 
1219     EXPECT_GL_NO_ERROR();
1220 
1221     vkDeviceWaitIdle(helper.getDevice());
1222     vkDestroyImage(helper.getDevice(), image, nullptr);
1223     vkDestroySemaphore(helper.getDevice(), vkAcquireSemaphore, nullptr);
1224     vkDestroySemaphore(helper.getDevice(), vkReleaseSemaphore, nullptr);
1225     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
1226 }
1227 
1228 // Test drawing to RGBA8 texture in opaque fd with acquire/release multiple times.
TEST_P(VulkanExternalImageTest,WaitSemaphoresRetainsContentOpaqueFd)1229 TEST_P(VulkanExternalImageTest, WaitSemaphoresRetainsContentOpaqueFd)
1230 {
1231     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1232     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1233 
1234     // http://issuetracker.google.com/173004081
1235     ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsLinux() &&
1236                        getEGLWindow()->isFeatureEnabled(Feature::AsyncCommandQueue));
1237     // http://anglebug.com/42263923
1238     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
1239 
1240     runWaitSemaphoresRetainsContentTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
1241 }
1242 
1243 // Test drawing to RGBA8 texture in zircon vmo with acquire/release multiple times.
TEST_P(VulkanExternalImageTest,WaitSemaphoresRetainsContentZirconVmo)1244 TEST_P(VulkanExternalImageTest, WaitSemaphoresRetainsContentZirconVmo)
1245 {
1246     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
1247     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
1248     runWaitSemaphoresRetainsContentTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
1249 }
1250 
1251 // Support for Zircon handle types is mandatory on Fuchsia.
TEST_P(VulkanExternalImageTest,ShouldSupportExternalHandlesFuchsia)1252 TEST_P(VulkanExternalImageTest, ShouldSupportExternalHandlesFuchsia)
1253 {
1254     ANGLE_SKIP_TEST_IF(!IsFuchsia());
1255     EXPECT_TRUE(EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
1256     EXPECT_TRUE(EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
1257     VulkanHelper helper;
1258     helper.initialize(isSwiftshader(), enableDebugLayers());
1259     EXPECT_TRUE(helper.canCreateSemaphoreZirconEvent());
1260     EXPECT_TRUE(helper.canCreateImageZirconVmo(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
1261                                                VK_IMAGE_TILING_OPTIMAL, kDefaultImageCreateFlags,
1262                                                kDefaultImageUsageFlags));
1263 }
1264 
1265 template <typename Traits>
RunPreInitializedOnGLImportTest(bool useMemoryObjectFlags,VkImageTiling tiling,bool isSwiftshader,bool enableDebugLayers)1266 void RunPreInitializedOnGLImportTest(bool useMemoryObjectFlags,
1267                                      VkImageTiling tiling,
1268                                      bool isSwiftshader,
1269                                      bool enableDebugLayers)
1270 {
1271     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
1272     ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
1273 
1274     VkImageCreateFlags createFlags = kDefaultImageCreateFlags;
1275     VkImageUsageFlags usageFlags   = kDefaultImageUsageFlags;
1276 
1277     AdjustCreateFlags(useMemoryObjectFlags, &createFlags);
1278 
1279     VulkanHelper helper;
1280     helper.initialize(isSwiftshader, enableDebugLayers);
1281 
1282     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1283     ANGLE_SKIP_TEST_IF(
1284         !Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D, tiling, createFlags, usageFlags));
1285     ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
1286 
1287     VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
1288     VkResult result                = Traits::CreateSemaphore(&helper, &vkAcquireSemaphore);
1289     EXPECT_EQ(result, VK_SUCCESS);
1290     EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
1291 
1292     VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
1293     result                         = Traits::CreateSemaphore(&helper, &vkReleaseSemaphore);
1294     EXPECT_EQ(result, VK_SUCCESS);
1295     EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
1296 
1297     typename Traits::Handle acquireSemaphoreHandle = Traits::InvalidHandle();
1298     result = Traits::ExportSemaphore(&helper, vkAcquireSemaphore, &acquireSemaphoreHandle);
1299     EXPECT_EQ(result, VK_SUCCESS);
1300     EXPECT_NE(acquireSemaphoreHandle, Traits::InvalidHandle());
1301 
1302     typename Traits::Handle releaseSemaphoreHandle = Traits::InvalidHandle();
1303     result = Traits::ExportSemaphore(&helper, vkReleaseSemaphore, &releaseSemaphoreHandle);
1304     EXPECT_EQ(result, VK_SUCCESS);
1305     EXPECT_NE(releaseSemaphoreHandle, Traits::InvalidHandle());
1306 
1307     VkImage image                 = VK_NULL_HANDLE;
1308     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
1309     VkDeviceSize deviceMemorySize = 0;
1310 
1311     VkExtent3D extent = {kWidth, kHeight, 1};
1312     result = Traits::CreateImage2D(&helper, format, createFlags, usageFlags, nullptr, extent,
1313                                    &image, &deviceMemory, &deviceMemorySize);
1314     EXPECT_EQ(result, VK_SUCCESS);
1315 
1316     // Initialize a pixel in the image
1317     constexpr uint32_t kPixel = 0x12345678;
1318     helper.writePixels(image, VK_IMAGE_LAYOUT_UNDEFINED, VK_FORMAT_R8G8B8A8_UNORM, {0, 0, 0},
1319                        {1, 1, 1}, static_cast<const void *>(&kPixel), sizeof(kPixel));
1320 
1321     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
1322     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
1323     EXPECT_EQ(result, VK_SUCCESS);
1324     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
1325 
1326     {
1327         GLMemoryObject memoryObject;
1328         GLint dedicatedMemory = GL_TRUE;
1329         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
1330                                      &dedicatedMemory);
1331         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
1332 
1333         GLTexture texture;
1334         glBindTexture(GL_TEXTURE_2D, texture);
1335         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1336         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1337         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1338         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1339         if (tiling == VK_IMAGE_TILING_LINEAR)
1340         {
1341             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_TILING_EXT, GL_LINEAR_TILING_EXT);
1342         }
1343         if (useMemoryObjectFlags)
1344         {
1345             glTexStorageMemFlags2DANGLE(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight, memoryObject,
1346                                         0, createFlags, usageFlags, nullptr);
1347         }
1348         else
1349         {
1350             glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight, memoryObject, 0);
1351         }
1352 
1353         GLSemaphore glAcquireSemaphore;
1354         Traits::ImportSemaphore(glAcquireSemaphore, acquireSemaphoreHandle);
1355 
1356         // Note: writePixels leaves the image in TRANSFER_DST_OPTIMAL layout.
1357         helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1358                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1359                                               vkAcquireSemaphore);
1360 
1361         const GLuint barrierTexture   = texture;
1362         const GLenum textureSrcLayout = GL_LAYOUT_COLOR_ATTACHMENT_EXT;
1363         glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, 1, &barrierTexture, &textureSrcLayout);
1364 
1365         GLFramebuffer framebuffer;
1366         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1367         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1368 
1369         // Readback the initialized pixel, ensure it contains the value written to it.
1370         uint32_t pixel = 0u;
1371         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
1372         EXPECT_EQ(pixel, kPixel);
1373         EXPECT_GL_NO_ERROR();
1374 
1375         GLSemaphore glReleaseSemaphore;
1376         Traits::ImportSemaphore(glReleaseSemaphore, releaseSemaphoreHandle);
1377 
1378         const GLenum textureDstLayout = GL_LAYOUT_TRANSFER_SRC_EXT;
1379         glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, 1, &barrierTexture, &textureDstLayout);
1380 
1381         helper.waitSemaphoreAndAcquireImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1382                                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1383                                             vkReleaseSemaphore);
1384     }
1385 
1386     EXPECT_GL_NO_ERROR();
1387 
1388     vkDeviceWaitIdle(helper.getDevice());
1389     vkDestroyImage(helper.getDevice(), image, nullptr);
1390     vkDestroySemaphore(helper.getDevice(), vkAcquireSemaphore, nullptr);
1391     vkDestroySemaphore(helper.getDevice(), vkReleaseSemaphore, nullptr);
1392     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
1393 }
1394 
1395 // Test that texture storage created from VkImage memory can be considered pre-initialized in GL.
TEST_P(VulkanExternalImageTest,PreInitializedOnGLImport)1396 TEST_P(VulkanExternalImageTest, PreInitializedOnGLImport)
1397 {
1398     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1399     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1400 
1401     RunPreInitializedOnGLImportTest<OpaqueFdTraits>(false, VK_IMAGE_TILING_OPTIMAL, isSwiftshader(),
1402                                                     enableDebugLayers());
1403 }
1404 
1405 // Test that texture storage created from VkImage memory can be considered pre-initialized in GL.
1406 // Uses linear tiling.
TEST_P(VulkanExternalImageTest,PreInitializedOnGLImportLinear)1407 TEST_P(VulkanExternalImageTest, PreInitializedOnGLImportLinear)
1408 {
1409     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1410     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1411 
1412     RunPreInitializedOnGLImportTest<OpaqueFdTraits>(false, VK_IMAGE_TILING_LINEAR, isSwiftshader(),
1413                                                     enableDebugLayers());
1414 }
1415 
1416 // Test that texture storage created from VkImage memory can be considered pre-initialized in GL,
1417 // using GL_ANGLE_memory_object_flags.
TEST_P(VulkanExternalImageTest,PreInitializedOnGLImportWithFlags)1418 TEST_P(VulkanExternalImageTest, PreInitializedOnGLImportWithFlags)
1419 {
1420     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1421     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1422     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
1423 
1424     RunPreInitializedOnGLImportTest<OpaqueFdTraits>(true, VK_IMAGE_TILING_OPTIMAL, isSwiftshader(),
1425                                                     enableDebugLayers());
1426 }
1427 
1428 // Test that texture storage created from VkImage memory can be considered pre-initialized in GL,
1429 // using GL_ANGLE_memory_object_flags.  Uses linear tiling.
TEST_P(VulkanExternalImageTest,PreInitializedOnGLImportLinearWithFlags)1430 TEST_P(VulkanExternalImageTest, PreInitializedOnGLImportLinearWithFlags)
1431 {
1432     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1433     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1434     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_flags"));
1435 
1436     RunPreInitializedOnGLImportTest<OpaqueFdTraits>(true, VK_IMAGE_TILING_LINEAR, isSwiftshader(),
1437                                                     enableDebugLayers());
1438 }
1439 
1440 template <typename Traits>
RunUninitializedOnGLImportTest(bool useMemoryObjectFlags,std::function<GLenum (GLuint)> useTexture,const uint32_t * expectInVulkan,bool isSwiftshader,bool enableDebugLayers)1441 void RunUninitializedOnGLImportTest(bool useMemoryObjectFlags,
1442                                     std::function<GLenum(GLuint)> useTexture,
1443                                     const uint32_t *expectInVulkan,
1444                                     bool isSwiftshader,
1445                                     bool enableDebugLayers)
1446 {
1447     ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
1448     ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
1449 
1450     VkImageCreateFlags createFlags = kDefaultImageCreateFlags;
1451     VkImageUsageFlags usageFlags   = kDefaultImageUsageFlags;
1452 
1453     AdjustCreateFlags(useMemoryObjectFlags, &createFlags);
1454 
1455     VulkanHelper helper;
1456     helper.initialize(isSwiftshader, enableDebugLayers);
1457 
1458     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1459     ANGLE_SKIP_TEST_IF(!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D,
1460                                                VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags));
1461     ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
1462 
1463     VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
1464     VkResult result                = Traits::CreateSemaphore(&helper, &vkAcquireSemaphore);
1465     EXPECT_EQ(result, VK_SUCCESS);
1466     EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
1467 
1468     VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
1469     result                         = Traits::CreateSemaphore(&helper, &vkReleaseSemaphore);
1470     EXPECT_EQ(result, VK_SUCCESS);
1471     EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
1472 
1473     typename Traits::Handle acquireSemaphoreHandle = Traits::InvalidHandle();
1474     result = Traits::ExportSemaphore(&helper, vkAcquireSemaphore, &acquireSemaphoreHandle);
1475     EXPECT_EQ(result, VK_SUCCESS);
1476     EXPECT_NE(acquireSemaphoreHandle, Traits::InvalidHandle());
1477 
1478     typename Traits::Handle releaseSemaphoreHandle = Traits::InvalidHandle();
1479     result = Traits::ExportSemaphore(&helper, vkReleaseSemaphore, &releaseSemaphoreHandle);
1480     EXPECT_EQ(result, VK_SUCCESS);
1481     EXPECT_NE(releaseSemaphoreHandle, Traits::InvalidHandle());
1482 
1483     VkImage image                 = VK_NULL_HANDLE;
1484     VkDeviceMemory deviceMemory   = VK_NULL_HANDLE;
1485     VkDeviceSize deviceMemorySize = 0;
1486 
1487     VkExtent3D extent = {kWidth, kHeight, 1};
1488     result = Traits::CreateImage2D(&helper, format, createFlags, usageFlags, nullptr, extent,
1489                                    &image, &deviceMemory, &deviceMemorySize);
1490     EXPECT_EQ(result, VK_SUCCESS);
1491 
1492     typename Traits::Handle memoryHandle = Traits::InvalidHandle();
1493     result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
1494     EXPECT_EQ(result, VK_SUCCESS);
1495     EXPECT_NE(memoryHandle, Traits::InvalidHandle());
1496 
1497     {
1498         GLMemoryObject memoryObject;
1499         GLint dedicatedMemory = GL_TRUE;
1500         glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
1501                                      &dedicatedMemory);
1502         Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
1503 
1504         GLTexture texture;
1505         glBindTexture(GL_TEXTURE_2D, texture);
1506         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1507         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1508         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1509         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1510         if (useMemoryObjectFlags)
1511         {
1512             glTexStorageMemFlags2DANGLE(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight, memoryObject,
1513                                         0, createFlags, usageFlags, nullptr);
1514         }
1515         else
1516         {
1517             glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight, memoryObject, 0);
1518         }
1519 
1520         GLSemaphore glAcquireSemaphore;
1521         Traits::ImportSemaphore(glAcquireSemaphore, acquireSemaphoreHandle);
1522 
1523         // Submit the semaphore without touching the image
1524         helper.signalSemaphore(vkAcquireSemaphore);
1525 
1526         const GLuint barrierTexture   = texture;
1527         const GLenum textureSrcLayout = GL_NONE;
1528         glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, 1, &barrierTexture, &textureSrcLayout);
1529 
1530         GLSemaphore glReleaseSemaphore;
1531         Traits::ImportSemaphore(glReleaseSemaphore, releaseSemaphoreHandle);
1532 
1533         const GLenum textureDstLayout = useTexture(texture);
1534         glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, 1, &barrierTexture, &textureDstLayout);
1535 
1536         const VkImageLayout imageLayout = GetPostReleaseVulkanLayout(textureDstLayout);
1537         helper.waitSemaphoreAndAcquireImage(
1538             image, imageLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vkReleaseSemaphore);
1539     }
1540 
1541     EXPECT_GL_NO_ERROR();
1542 
1543     // Verify the contents of the image from the Vulkan side too if needed
1544     if (expectInVulkan != nullptr)
1545     {
1546         uint8_t pixels[4];
1547         const VkOffset3D offset     = {};
1548         const VkExtent3D readExtent = {1, 1, 1};
1549         helper.readPixels(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_FORMAT_R8G8B8A8_UNORM,
1550                           offset, readExtent, pixels, sizeof(pixels));
1551 
1552         const uint32_t pixel = pixels[0] | pixels[1] << 8 | pixels[2] << 16 | pixels[3] << 24;
1553 
1554         EXPECT_EQ(pixel, *expectInVulkan);
1555     }
1556 
1557     vkDeviceWaitIdle(helper.getDevice());
1558     vkDestroyImage(helper.getDevice(), image, nullptr);
1559     vkDestroySemaphore(helper.getDevice(), vkAcquireSemaphore, nullptr);
1560     vkDestroySemaphore(helper.getDevice(), vkReleaseSemaphore, nullptr);
1561     vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
1562 }
1563 
1564 // Test that texture storage created from VkImage memory can be imported as uninitialized in GL.
TEST_P(VulkanExternalImageTest,UninitializedOnGLImport)1565 TEST_P(VulkanExternalImageTest, UninitializedOnGLImport)
1566 {
1567     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1568     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1569 
1570     constexpr uint32_t kExpect = 0xFF0000FF;
1571 
1572     auto render = [kExpect](GLuint texture) {
1573         GLFramebuffer framebuffer;
1574         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1575         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1576 
1577         glClearColor(1, 0, 0, 1);
1578         glClear(GL_COLOR_BUFFER_BIT);
1579 
1580         uint32_t pixel = 0u;
1581         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
1582         EXPECT_GL_NO_ERROR();
1583 
1584         EXPECT_EQ(pixel, kExpect);
1585         EXPECT_GL_NO_ERROR();
1586 
1587         return GL_LAYOUT_TRANSFER_SRC_EXT;
1588     };
1589 
1590     RunUninitializedOnGLImportTest<OpaqueFdTraits>(false, render, &kExpect, isSwiftshader(),
1591                                                    enableDebugLayers());
1592 }
1593 
1594 // Test that texture storage created from VkImage memory can be imported as uninitialized in GL and
1595 // released without being touched.
TEST_P(VulkanExternalImageTest,UninitializedOnGLImportAndExport)1596 TEST_P(VulkanExternalImageTest, UninitializedOnGLImportAndExport)
1597 {
1598     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1599     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1600 
1601     auto doNothing = [](GLuint) { return GL_NONE; };
1602 
1603     RunUninitializedOnGLImportTest<OpaqueFdTraits>(false, doNothing, nullptr, isSwiftshader(),
1604                                                    enableDebugLayers());
1605 }
1606 
1607 // Test that texture storage created from VkImage memory can be imported as uninitialized in GL and
1608 // then used as the target of a copy.
TEST_P(VulkanExternalImageTest,UninitializedOnGLImportAndCopy)1609 TEST_P(VulkanExternalImageTest, UninitializedOnGLImportAndCopy)
1610 {
1611     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1612     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1613 
1614     constexpr uint32_t kExpect = 0xFF00FF00;
1615 
1616     auto copy = [kExpect](GLuint texture) {
1617         std::vector<GLColor> initData(kWidth * kHeight, GLColor::green);
1618         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
1619                         initData.data());
1620 
1621         GLFramebuffer framebuffer;
1622         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1623         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1624 
1625         uint32_t pixel = 0u;
1626         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
1627         EXPECT_GL_NO_ERROR();
1628 
1629         EXPECT_EQ(pixel, kExpect);
1630         EXPECT_GL_NO_ERROR();
1631 
1632         return GL_LAYOUT_TRANSFER_SRC_EXT;
1633     };
1634 
1635     RunUninitializedOnGLImportTest<OpaqueFdTraits>(false, copy, &kExpect, isSwiftshader(),
1636                                                    enableDebugLayers());
1637 }
1638 
1639 // Test that texture storage created from VkImage memory can be imported as uninitialized in GL and
1640 // then used as sampler.  Because the image is initialized, sampled results would be garbage, so
1641 // this test is primarily ensuring no validation errors are generated.
TEST_P(VulkanExternalImageTest,UninitializedOnGLImportAndSample)1642 TEST_P(VulkanExternalImageTest, UninitializedOnGLImportAndSample)
1643 {
1644     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1645     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1646 
1647     auto sample = [this](GLuint texture) {
1648         GLProgram program;
1649         program.makeRaster(essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
1650         drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.0f);
1651         EXPECT_GL_NO_ERROR();
1652 
1653         return GL_LAYOUT_SHADER_READ_ONLY_EXT;
1654     };
1655 
1656     RunUninitializedOnGLImportTest<OpaqueFdTraits>(false, sample, nullptr, isSwiftshader(),
1657                                                    enableDebugLayers());
1658 }
1659 
1660 // Test that texture storage created from VkImage memory can be imported as uninitialized in GL and
1661 // then used as storage image.
TEST_P(VulkanExternalImageTestES31,UninitializedOnGLImportAndStorageWrite)1662 TEST_P(VulkanExternalImageTestES31, UninitializedOnGLImportAndStorageWrite)
1663 {
1664     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
1665     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
1666 
1667     constexpr uint32_t kExpect = 0xFF00FFFF;
1668 
1669     auto storageWrite = [kExpect](GLuint texture) {
1670         constexpr char kCS[] = R"(#version 310 es
1671 layout(local_size_x=8, local_size_y=8) in;
1672 layout(rgba8) uniform highp writeonly image2D img;
1673 void main()
1674 {
1675     imageStore(img, ivec2(gl_GlobalInvocationID.xy), vec4(1, 1, 0, 1));
1676 })";
1677 
1678         GLProgram program;
1679         program.makeCompute(kCS);
1680         glUseProgram(program);
1681 
1682         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
1683         glDispatchCompute(kWidth / 8, kHeight / 8, 1);
1684         EXPECT_GL_NO_ERROR();
1685 
1686         glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1687 
1688         GLFramebuffer framebuffer;
1689         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1690         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1691 
1692         uint32_t pixel = 0u;
1693         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
1694         EXPECT_GL_NO_ERROR();
1695 
1696         EXPECT_EQ(pixel, kExpect);
1697         EXPECT_GL_NO_ERROR();
1698 
1699         return GL_LAYOUT_TRANSFER_SRC_EXT;
1700     };
1701 
1702     RunUninitializedOnGLImportTest<OpaqueFdTraits>(false, storageWrite, &kExpect, isSwiftshader(),
1703                                                    enableDebugLayers());
1704 }
1705 
1706 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VulkanExternalImageTest);
1707 ANGLE_INSTANTIATE_TEST_ES31(VulkanExternalImageTestES31);
1708 }  // namespace angle
1709