xref: /aosp_15_r20/external/angle/src/tests/gl_tests/VulkanImageTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // VulkanImageTest.cpp : Tests of EGL_ANGLE_vulkan_image & GL_ANGLE_vulkan_image extensions.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/VulkanHelper.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/angle_test_instantiate.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker namespace angle
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint kWidth  = 64u;
20*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint kHeight = 64u;
21*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint kWhite  = 0xffffffff;
22*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint kRed    = 0xff0000ff;
23*8975f5c5SAndroid Build Coastguard Worker 
24*8975f5c5SAndroid Build Coastguard Worker class VulkanImageTest : public ANGLETest<>
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker   protected:
VulkanImageTest()27*8975f5c5SAndroid Build Coastguard Worker     VulkanImageTest() { setRobustResourceInit(true); }
28*8975f5c5SAndroid Build Coastguard Worker };
29*8975f5c5SAndroid Build Coastguard Worker 
30*8975f5c5SAndroid Build Coastguard Worker class VulkanMemoryTest : public ANGLETest<>
31*8975f5c5SAndroid Build Coastguard Worker {
32*8975f5c5SAndroid Build Coastguard Worker   protected:
VulkanMemoryTest()33*8975f5c5SAndroid Build Coastguard Worker     VulkanMemoryTest() { setRobustResourceInit(true); }
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker     bool compatibleMemorySizesForDeviceOOMTest(VkPhysicalDevice physicalDevice,
36*8975f5c5SAndroid Build Coastguard Worker                                                VkDeviceSize *totalDeviceMemorySizeOut);
37*8975f5c5SAndroid Build Coastguard Worker 
getPerfCounters()38*8975f5c5SAndroid Build Coastguard Worker     angle::VulkanPerfCounters getPerfCounters()
39*8975f5c5SAndroid Build Coastguard Worker     {
40*8975f5c5SAndroid Build Coastguard Worker         if (mIndexMap.empty())
41*8975f5c5SAndroid Build Coastguard Worker         {
42*8975f5c5SAndroid Build Coastguard Worker             mIndexMap = BuildCounterNameToIndexMap();
43*8975f5c5SAndroid Build Coastguard Worker         }
44*8975f5c5SAndroid Build Coastguard Worker 
45*8975f5c5SAndroid Build Coastguard Worker         return GetPerfCounters(mIndexMap);
46*8975f5c5SAndroid Build Coastguard Worker     }
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker     CounterNameToIndexMap mIndexMap;
49*8975f5c5SAndroid Build Coastguard Worker };
50*8975f5c5SAndroid Build Coastguard Worker 
compatibleMemorySizesForDeviceOOMTest(VkPhysicalDevice physicalDevice,VkDeviceSize * totalDeviceMemorySizeOut)51*8975f5c5SAndroid Build Coastguard Worker bool VulkanMemoryTest::compatibleMemorySizesForDeviceOOMTest(VkPhysicalDevice physicalDevice,
52*8975f5c5SAndroid Build Coastguard Worker                                                              VkDeviceSize *totalDeviceMemorySizeOut)
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker     // Acquire the sizes and memory property flags for all available memory types. There should be
55*8975f5c5SAndroid Build Coastguard Worker     // at least one memory heap without the device local bit (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).
56*8975f5c5SAndroid Build Coastguard Worker     // Otherwise, the test should be skipped.
57*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceMemoryProperties memoryProperties;
58*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker     *totalDeviceMemorySizeOut                 = 0;
61*8975f5c5SAndroid Build Coastguard Worker     uint32_t heapsWithoutLocalDeviceMemoryBit = 0;
62*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; i++)
63*8975f5c5SAndroid Build Coastguard Worker     {
64*8975f5c5SAndroid Build Coastguard Worker         if ((memoryProperties.memoryHeaps[i].flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0)
65*8975f5c5SAndroid Build Coastguard Worker         {
66*8975f5c5SAndroid Build Coastguard Worker             heapsWithoutLocalDeviceMemoryBit++;
67*8975f5c5SAndroid Build Coastguard Worker         }
68*8975f5c5SAndroid Build Coastguard Worker         else
69*8975f5c5SAndroid Build Coastguard Worker         {
70*8975f5c5SAndroid Build Coastguard Worker             *totalDeviceMemorySizeOut += memoryProperties.memoryHeaps[i].size;
71*8975f5c5SAndroid Build Coastguard Worker         }
72*8975f5c5SAndroid Build Coastguard Worker     }
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker     bool isCompatible = heapsWithoutLocalDeviceMemoryBit != 0 && *totalDeviceMemorySizeOut != 0;
75*8975f5c5SAndroid Build Coastguard Worker     return isCompatible;
76*8975f5c5SAndroid Build Coastguard Worker }
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker // Check extensions with Vukan backend.
TEST_P(VulkanImageTest,HasVulkanImageExtensions)79*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, HasVulkanImageExtensions)
80*8975f5c5SAndroid Build Coastguard Worker {
81*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsVulkan());
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
84*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_EXT_device_query"));
87*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
88*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(IsGLExtensionEnabled("GL_ANGLE_vulkan_image"));
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib result = 0;
91*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result));
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker     EGLDeviceEXT device = reinterpret_cast<EGLDeviceEXT>(result);
94*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(EGL_NO_DEVICE_EXT, device);
95*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(IsEGLDeviceExtensionEnabled(device, "EGL_ANGLE_device_vulkan"));
96*8975f5c5SAndroid Build Coastguard Worker }
97*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(VulkanImageTest,DeviceVulkan)98*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, DeviceVulkan)
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsVulkan());
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
103*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib result = 0;
106*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result));
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     EGLDeviceEXT device = reinterpret_cast<EGLDeviceEXT>(result);
109*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(EGL_NO_DEVICE_EXT, device);
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_INSTANCE_ANGLE, &result));
112*8975f5c5SAndroid Build Coastguard Worker     VkInstance instance = reinterpret_cast<VkInstance>(result);
113*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(instance, static_cast<VkInstance>(VK_NULL_HANDLE));
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_PHYSICAL_DEVICE_ANGLE, &result));
116*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(result);
117*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(physical_device, static_cast<VkPhysicalDevice>(VK_NULL_HANDLE));
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_DEVICE_ANGLE, &result));
120*8975f5c5SAndroid Build Coastguard Worker     VkDevice vk_device = reinterpret_cast<VkDevice>(result);
121*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(vk_device, static_cast<VkDevice>(VK_NULL_HANDLE));
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_QUEUE_ANGLE, &result));
124*8975f5c5SAndroid Build Coastguard Worker     VkQueue queue = reinterpret_cast<VkQueue>(result);
125*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(queue, static_cast<VkQueue>(VK_NULL_HANDLE));
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE, &result));
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     {
130*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EGL_TRUE(
131*8975f5c5SAndroid Build Coastguard Worker             eglQueryDeviceAttribEXT(device, EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE, &result));
132*8975f5c5SAndroid Build Coastguard Worker         const char *const *extensions = reinterpret_cast<const char *const *>(result);
133*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(extensions, nullptr);
134*8975f5c5SAndroid Build Coastguard Worker         int extension_count = 0;
135*8975f5c5SAndroid Build Coastguard Worker         while (extensions[extension_count])
136*8975f5c5SAndroid Build Coastguard Worker         {
137*8975f5c5SAndroid Build Coastguard Worker             extension_count++;
138*8975f5c5SAndroid Build Coastguard Worker         }
139*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(extension_count, 0);
140*8975f5c5SAndroid Build Coastguard Worker     }
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker     {
143*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EGL_TRUE(
144*8975f5c5SAndroid Build Coastguard Worker             eglQueryDeviceAttribEXT(device, EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE, &result));
145*8975f5c5SAndroid Build Coastguard Worker         const char *const *extensions = reinterpret_cast<const char *const *>(result);
146*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(extensions, nullptr);
147*8975f5c5SAndroid Build Coastguard Worker         int extension_count = 0;
148*8975f5c5SAndroid Build Coastguard Worker         while (extensions[extension_count])
149*8975f5c5SAndroid Build Coastguard Worker         {
150*8975f5c5SAndroid Build Coastguard Worker             extension_count++;
151*8975f5c5SAndroid Build Coastguard Worker         }
152*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(extension_count, 0);
153*8975f5c5SAndroid Build Coastguard Worker     }
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_FEATURES_ANGLE, &result));
156*8975f5c5SAndroid Build Coastguard Worker     const VkPhysicalDeviceFeatures2 *features =
157*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<const VkPhysicalDeviceFeatures2 *>(result);
158*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(features, nullptr);
159*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(features->sType, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(device, EGL_VULKAN_GET_INSTANCE_PROC_ADDR, &result));
162*8975f5c5SAndroid Build Coastguard Worker     PFN_vkGetInstanceProcAddr get_instance_proc_addr =
163*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<PFN_vkGetInstanceProcAddr>(result);
164*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(get_instance_proc_addr, nullptr);
165*8975f5c5SAndroid Build Coastguard Worker }
166*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(VulkanImageTest,ExportVKImage)167*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, ExportVKImage)
168*8975f5c5SAndroid Build Coastguard Worker {
169*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
170*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
171*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
172*8975f5c5SAndroid Build Coastguard Worker 
173*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
174*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
175*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
176*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
177*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
178*8975f5c5SAndroid Build Coastguard Worker 
179*8975f5c5SAndroid Build Coastguard Worker     EGLContext context   = window->getContext();
180*8975f5c5SAndroid Build Coastguard Worker     EGLImageKHR eglImage = eglCreateImageKHR(
181*8975f5c5SAndroid Build Coastguard Worker         display, context, EGL_GL_TEXTURE_2D_KHR,
182*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), nullptr);
183*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(eglImage, EGL_NO_IMAGE_KHR);
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker     VkImage vkImage        = VK_NULL_HANDLE;
186*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo info = {};
187*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglExportVkImageANGLE(display, eglImage, &vkImage, &info));
188*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(vkImage, static_cast<VkImage>(VK_NULL_HANDLE));
189*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.sType, VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
190*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.pNext, nullptr);
191*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.imageType, VK_IMAGE_TYPE_2D);
192*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.format, VK_FORMAT_R8G8B8A8_UNORM);
193*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.extent.width, kWidth);
194*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.extent.height, kHeight);
195*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.extent.depth, 1u);
196*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.queueFamilyIndexCount, 0u);
197*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.pQueueFamilyIndices, nullptr);
198*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(info.initialLayout, VK_IMAGE_LAYOUT_UNDEFINED);
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglDestroyImageKHR(display, eglImage));
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker // Check pixels after glTexImage2D
TEST_P(VulkanImageTest,PixelTestTexImage2D)204*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, PixelTestTexImage2D)
205*8975f5c5SAndroid Build Coastguard Worker {
206*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
207*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
210*8975f5c5SAndroid Build Coastguard Worker 
211*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
212*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
213*8975f5c5SAndroid Build Coastguard Worker 
214*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kColor = 0xafbfcfdf;
215*8975f5c5SAndroid Build Coastguard Worker 
216*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker     {
219*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
220*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLuint> pixels(kWidth * kHeight, kColor);
221*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
222*8975f5c5SAndroid Build Coastguard Worker                      pixels.data());
223*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, 0);
224*8975f5c5SAndroid Build Coastguard Worker     }
225*8975f5c5SAndroid Build Coastguard Worker 
226*8975f5c5SAndroid Build Coastguard Worker     EGLContext context   = window->getContext();
227*8975f5c5SAndroid Build Coastguard Worker     EGLImageKHR eglImage = eglCreateImageKHR(
228*8975f5c5SAndroid Build Coastguard Worker         display, context, EGL_GL_TEXTURE_2D_KHR,
229*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), nullptr);
230*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(eglImage, EGL_NO_IMAGE_KHR);
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker     VkImage vkImage        = VK_NULL_HANDLE;
233*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo info = {};
234*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglExportVkImageANGLE(display, eglImage, &vkImage, &info));
235*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(vkImage, static_cast<VkImage>(VK_NULL_HANDLE));
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker     GLuint textures[1] = {texture};
238*8975f5c5SAndroid Build Coastguard Worker     GLenum layouts[1]  = {GL_NONE};
239*8975f5c5SAndroid Build Coastguard Worker     glReleaseTexturesANGLE(1, textures, layouts);
240*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(layouts[0], static_cast<GLenum>(GL_LAYOUT_TRANSFER_DST_EXT));
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker     {
243*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLuint> pixels(kWidth * kHeight);
244*8975f5c5SAndroid Build Coastguard Worker         helper.readPixels(vkImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, info.format, {},
245*8975f5c5SAndroid Build Coastguard Worker                           info.extent, pixels.data(), pixels.size() * sizeof(GLuint));
246*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(pixels, std::vector<GLuint>(kWidth * kHeight, kColor));
247*8975f5c5SAndroid Build Coastguard Worker     }
248*8975f5c5SAndroid Build Coastguard Worker 
249*8975f5c5SAndroid Build Coastguard Worker     layouts[0] = GL_LAYOUT_TRANSFER_SRC_EXT;
250*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
253*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglDestroyImageKHR(display, eglImage));
254*8975f5c5SAndroid Build Coastguard Worker }
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker // Check pixels after glClear
TEST_P(VulkanImageTest,PixelTestClear)257*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, PixelTestClear)
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
260*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
261*8975f5c5SAndroid Build Coastguard Worker 
262*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
265*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
266*8975f5c5SAndroid Build Coastguard Worker 
267*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
268*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
269*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
270*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     EGLContext context   = window->getContext();
273*8975f5c5SAndroid Build Coastguard Worker     EGLImageKHR eglImage = eglCreateImageKHR(
274*8975f5c5SAndroid Build Coastguard Worker         display, context, EGL_GL_TEXTURE_2D_KHR,
275*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), nullptr);
276*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(eglImage, EGL_NO_IMAGE_KHR);
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker     VkImage vkImage        = VK_NULL_HANDLE;
279*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo info = {};
280*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglExportVkImageANGLE(display, eglImage, &vkImage, &info));
281*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(vkImage, static_cast<VkImage>(VK_NULL_HANDLE));
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
284*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
285*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
286*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
287*8975f5c5SAndroid Build Coastguard Worker 
288*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, kWidth, kHeight);
289*8975f5c5SAndroid Build Coastguard Worker     // clear framebuffer with white color.
290*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.f, 1.f, 1.f, 1.f);
291*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker     GLuint textures[1] = {texture};
294*8975f5c5SAndroid Build Coastguard Worker     GLenum layouts[1]  = {GL_NONE};
295*8975f5c5SAndroid Build Coastguard Worker     glReleaseTexturesANGLE(1, textures, layouts);
296*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(layouts[0], static_cast<GLenum>(GL_LAYOUT_TRANSFER_DST_EXT));
297*8975f5c5SAndroid Build Coastguard Worker 
298*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> pixels(kWidth * kHeight);
299*8975f5c5SAndroid Build Coastguard Worker     helper.readPixels(vkImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, info.format, {}, info.extent,
300*8975f5c5SAndroid Build Coastguard Worker                       pixels.data(), pixels.size() * sizeof(GLuint));
301*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pixels, std::vector<GLuint>(kWidth * kHeight, kWhite));
302*8975f5c5SAndroid Build Coastguard Worker 
303*8975f5c5SAndroid Build Coastguard Worker     layouts[0] = GL_LAYOUT_TRANSFER_SRC_EXT;
304*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
305*8975f5c5SAndroid Build Coastguard Worker 
306*8975f5c5SAndroid Build Coastguard Worker     // clear framebuffer with red color.
307*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.f, 0.f, 0.f, 1.f);
308*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker     glReleaseTexturesANGLE(1, textures, layouts);
311*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(layouts[0], static_cast<GLenum>(GL_LAYOUT_TRANSFER_DST_EXT));
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     helper.readPixels(vkImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, info.format, {}, info.extent,
314*8975f5c5SAndroid Build Coastguard Worker                       pixels.data(), pixels.size() * sizeof(GLuint));
315*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pixels, std::vector<GLuint>(kWidth * kHeight, kRed));
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker     layouts[0] = GL_LAYOUT_TRANSFER_SRC_EXT;
318*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
319*8975f5c5SAndroid Build Coastguard Worker 
320*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
321*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglDestroyImageKHR(display, eglImage));
322*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
323*8975f5c5SAndroid Build Coastguard Worker }
324*8975f5c5SAndroid Build Coastguard Worker 
325*8975f5c5SAndroid Build Coastguard Worker // Check pixels after GL draw.
TEST_P(VulkanImageTest,PixelTestDrawQuad)326*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, PixelTestDrawQuad)
327*8975f5c5SAndroid Build Coastguard Worker {
328*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
329*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
330*8975f5c5SAndroid Build Coastguard Worker 
331*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
332*8975f5c5SAndroid Build Coastguard Worker 
333*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
334*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
335*8975f5c5SAndroid Build Coastguard Worker 
336*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
337*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
338*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
339*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker     EGLContext context   = window->getContext();
342*8975f5c5SAndroid Build Coastguard Worker     EGLImageKHR eglImage = eglCreateImageKHR(
343*8975f5c5SAndroid Build Coastguard Worker         display, context, EGL_GL_TEXTURE_2D_KHR,
344*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), nullptr);
345*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(eglImage, EGL_NO_IMAGE_KHR);
346*8975f5c5SAndroid Build Coastguard Worker 
347*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
348*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
349*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
350*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
351*8975f5c5SAndroid Build Coastguard Worker 
352*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, kWidth, kHeight);
353*8975f5c5SAndroid Build Coastguard Worker     // clear framebuffer with black color.
354*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.f, 0.f, 0.f, 0.f);
355*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
356*8975f5c5SAndroid Build Coastguard Worker 
357*8975f5c5SAndroid Build Coastguard Worker     // draw red quad
358*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
359*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     GLuint textures[1] = {texture};
362*8975f5c5SAndroid Build Coastguard Worker     GLenum layouts[1]  = {GL_NONE};
363*8975f5c5SAndroid Build Coastguard Worker     glReleaseTexturesANGLE(1, textures, layouts);
364*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(layouts[0], static_cast<GLenum>(GL_LAYOUT_COLOR_ATTACHMENT_EXT));
365*8975f5c5SAndroid Build Coastguard Worker 
366*8975f5c5SAndroid Build Coastguard Worker     VkImage vkImage        = VK_NULL_HANDLE;
367*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo info = {};
368*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglExportVkImageANGLE(display, eglImage, &vkImage, &info));
369*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(vkImage, static_cast<VkImage>(VK_NULL_HANDLE));
370*8975f5c5SAndroid Build Coastguard Worker 
371*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> pixels(kWidth * kHeight);
372*8975f5c5SAndroid Build Coastguard Worker     helper.readPixels(vkImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, info.format, {},
373*8975f5c5SAndroid Build Coastguard Worker                       info.extent, pixels.data(), pixels.size() * sizeof(GLuint));
374*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pixels, std::vector<GLuint>(kWidth * kHeight, kRed));
375*8975f5c5SAndroid Build Coastguard Worker 
376*8975f5c5SAndroid Build Coastguard Worker     layouts[0] = GL_LAYOUT_TRANSFER_SRC_EXT;
377*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
378*8975f5c5SAndroid Build Coastguard Worker 
379*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
380*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglDestroyImageKHR(display, eglImage));
381*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
382*8975f5c5SAndroid Build Coastguard Worker }
383*8975f5c5SAndroid Build Coastguard Worker 
384*8975f5c5SAndroid Build Coastguard Worker // Test importing VkImage with eglCreateImageKHR
TEST_P(VulkanImageTest,ClientBuffer)385*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, ClientBuffer)
386*8975f5c5SAndroid Build Coastguard Worker {
387*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
388*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
389*8975f5c5SAndroid Build Coastguard Worker 
390*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
393*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
394*8975f5c5SAndroid Build Coastguard Worker 
395*8975f5c5SAndroid Build Coastguard Worker     constexpr VkImageUsageFlags kDefaultImageUsageFlags =
396*8975f5c5SAndroid Build Coastguard Worker         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
397*8975f5c5SAndroid Build Coastguard Worker         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
398*8975f5c5SAndroid Build Coastguard Worker         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
399*8975f5c5SAndroid Build Coastguard Worker 
400*8975f5c5SAndroid Build Coastguard Worker     VkImage vkImage                   = VK_NULL_HANDLE;
401*8975f5c5SAndroid Build Coastguard Worker     VkDeviceMemory vkDeviceMemory     = VK_NULL_HANDLE;
402*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize deviceSize           = 0u;
403*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo imageCreateInfo = {};
404*8975f5c5SAndroid Build Coastguard Worker 
405*8975f5c5SAndroid Build Coastguard Worker     VkResult result = VK_SUCCESS;
406*8975f5c5SAndroid Build Coastguard Worker     result          = helper.createImage2D(VK_FORMAT_R8G8B8A8_UNORM, 0, kDefaultImageUsageFlags,
407*8975f5c5SAndroid Build Coastguard Worker                                            {kWidth, kHeight, 1}, &vkImage, &vkDeviceMemory, &deviceSize,
408*8975f5c5SAndroid Build Coastguard Worker                                            &imageCreateInfo);
409*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(result, VK_SUCCESS);
410*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(imageCreateInfo.sType, VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker     uint64_t info    = reinterpret_cast<uint64_t>(&imageCreateInfo);
413*8975f5c5SAndroid Build Coastguard Worker     EGLint attribs[] = {
414*8975f5c5SAndroid Build Coastguard Worker         EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE,
415*8975f5c5SAndroid Build Coastguard Worker         static_cast<EGLint>((info >> 32) & 0xffffffff),
416*8975f5c5SAndroid Build Coastguard Worker         EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE,
417*8975f5c5SAndroid Build Coastguard Worker         static_cast<EGLint>(info & 0xffffffff),
418*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
419*8975f5c5SAndroid Build Coastguard Worker     };
420*8975f5c5SAndroid Build Coastguard Worker     EGLImageKHR eglImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_VULKAN_IMAGE_ANGLE,
421*8975f5c5SAndroid Build Coastguard Worker                                              reinterpret_cast<EGLClientBuffer>(&vkImage), attribs);
422*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(eglImage, EGL_NO_IMAGE_KHR);
423*8975f5c5SAndroid Build Coastguard Worker 
424*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
425*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
426*8975f5c5SAndroid Build Coastguard Worker     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
427*8975f5c5SAndroid Build Coastguard Worker 
428*8975f5c5SAndroid Build Coastguard Worker     GLuint textures[1] = {texture};
429*8975f5c5SAndroid Build Coastguard Worker     GLenum layouts[1]  = {GL_NONE};
430*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
431*8975f5c5SAndroid Build Coastguard Worker 
432*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
433*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
434*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
435*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
436*8975f5c5SAndroid Build Coastguard Worker 
437*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, kWidth, kHeight);
438*8975f5c5SAndroid Build Coastguard Worker     // clear framebuffer with white color.
439*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.f, 1.f, 1.f, 1.f);
440*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
441*8975f5c5SAndroid Build Coastguard Worker 
442*8975f5c5SAndroid Build Coastguard Worker     textures[0] = texture;
443*8975f5c5SAndroid Build Coastguard Worker     layouts[0]  = GL_NONE;
444*8975f5c5SAndroid Build Coastguard Worker     glReleaseTexturesANGLE(1, textures, layouts);
445*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(layouts[0], static_cast<GLenum>(GL_LAYOUT_TRANSFER_DST_EXT));
446*8975f5c5SAndroid Build Coastguard Worker 
447*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> pixels(kWidth * kHeight);
448*8975f5c5SAndroid Build Coastguard Worker     helper.readPixels(vkImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageCreateInfo.format, {},
449*8975f5c5SAndroid Build Coastguard Worker                       imageCreateInfo.extent, pixels.data(), pixels.size() * sizeof(GLuint));
450*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pixels, std::vector<GLuint>(kWidth * kHeight, kWhite));
451*8975f5c5SAndroid Build Coastguard Worker 
452*8975f5c5SAndroid Build Coastguard Worker     layouts[0] = GL_LAYOUT_TRANSFER_SRC_EXT;
453*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
454*8975f5c5SAndroid Build Coastguard Worker 
455*8975f5c5SAndroid Build Coastguard Worker     // clear framebuffer with red color.
456*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.f, 0.f, 0.f, 1.f);
457*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
458*8975f5c5SAndroid Build Coastguard Worker 
459*8975f5c5SAndroid Build Coastguard Worker     glReleaseTexturesANGLE(1, textures, layouts);
460*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(layouts[0], static_cast<GLenum>(GL_LAYOUT_TRANSFER_DST_EXT));
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker     helper.readPixels(vkImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageCreateInfo.format, {},
463*8975f5c5SAndroid Build Coastguard Worker                       imageCreateInfo.extent, pixels.data(), pixels.size() * sizeof(GLuint));
464*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pixels, std::vector<GLuint>(kWidth * kHeight, kRed));
465*8975f5c5SAndroid Build Coastguard Worker 
466*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
467*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
468*8975f5c5SAndroid Build Coastguard Worker     framebuffer.reset();
469*8975f5c5SAndroid Build Coastguard Worker     texture.reset();
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker     glFinish();
472*8975f5c5SAndroid Build Coastguard Worker 
473*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglDestroyImageKHR(display, eglImage));
474*8975f5c5SAndroid Build Coastguard Worker     vkDestroyImage(helper.getDevice(), vkImage, nullptr);
475*8975f5c5SAndroid Build Coastguard Worker     vkFreeMemory(helper.getDevice(), vkDeviceMemory, nullptr);
476*8975f5c5SAndroid Build Coastguard Worker }
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker // Test importing VkImage with eglCreateImageKHR and drawing to make sure no errors occur in setting
479*8975f5c5SAndroid Build Coastguard Worker // up the framebuffer, including an imageless framebuffer.
TEST_P(VulkanImageTest,ClientBufferWithDraw)480*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanImageTest, ClientBufferWithDraw)
481*8975f5c5SAndroid Build Coastguard Worker {
482*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
483*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
484*8975f5c5SAndroid Build Coastguard Worker 
485*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_vulkan_image"));
486*8975f5c5SAndroid Build Coastguard Worker 
487*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
488*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
489*8975f5c5SAndroid Build Coastguard Worker 
490*8975f5c5SAndroid Build Coastguard Worker     constexpr VkImageUsageFlags kDefaultImageUsageFlags =
491*8975f5c5SAndroid Build Coastguard Worker         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
492*8975f5c5SAndroid Build Coastguard Worker         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
493*8975f5c5SAndroid Build Coastguard Worker         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
494*8975f5c5SAndroid Build Coastguard Worker 
495*8975f5c5SAndroid Build Coastguard Worker     VkImage vkImage                   = VK_NULL_HANDLE;
496*8975f5c5SAndroid Build Coastguard Worker     VkDeviceMemory vkDeviceMemory     = VK_NULL_HANDLE;
497*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize deviceSize           = 0u;
498*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateInfo imageCreateInfo = {};
499*8975f5c5SAndroid Build Coastguard Worker 
500*8975f5c5SAndroid Build Coastguard Worker     VkResult result = VK_SUCCESS;
501*8975f5c5SAndroid Build Coastguard Worker     result          = helper.createImage2D(VK_FORMAT_R8G8B8A8_UNORM, 0, kDefaultImageUsageFlags,
502*8975f5c5SAndroid Build Coastguard Worker                                            {kWidth, kHeight, 1}, &vkImage, &vkDeviceMemory, &deviceSize,
503*8975f5c5SAndroid Build Coastguard Worker                                            &imageCreateInfo);
504*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(result, VK_SUCCESS);
505*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(imageCreateInfo.sType, VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
506*8975f5c5SAndroid Build Coastguard Worker 
507*8975f5c5SAndroid Build Coastguard Worker     uint64_t info    = reinterpret_cast<uint64_t>(&imageCreateInfo);
508*8975f5c5SAndroid Build Coastguard Worker     EGLint attribs[] = {
509*8975f5c5SAndroid Build Coastguard Worker         EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE,
510*8975f5c5SAndroid Build Coastguard Worker         static_cast<EGLint>((info >> 32) & 0xffffffff),
511*8975f5c5SAndroid Build Coastguard Worker         EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE,
512*8975f5c5SAndroid Build Coastguard Worker         static_cast<EGLint>(info & 0xffffffff),
513*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
514*8975f5c5SAndroid Build Coastguard Worker     };
515*8975f5c5SAndroid Build Coastguard Worker     EGLImageKHR eglImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_VULKAN_IMAGE_ANGLE,
516*8975f5c5SAndroid Build Coastguard Worker                                              reinterpret_cast<EGLClientBuffer>(&vkImage), attribs);
517*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(eglImage, EGL_NO_IMAGE_KHR);
518*8975f5c5SAndroid Build Coastguard Worker 
519*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
520*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
521*8975f5c5SAndroid Build Coastguard Worker     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
522*8975f5c5SAndroid Build Coastguard Worker 
523*8975f5c5SAndroid Build Coastguard Worker     GLuint textures[1] = {texture};
524*8975f5c5SAndroid Build Coastguard Worker     GLenum layouts[1]  = {GL_NONE};
525*8975f5c5SAndroid Build Coastguard Worker     glAcquireTexturesANGLE(1, textures, layouts);
526*8975f5c5SAndroid Build Coastguard Worker 
527*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
528*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
529*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
530*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
531*8975f5c5SAndroid Build Coastguard Worker 
532*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
533*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.5f);
534*8975f5c5SAndroid Build Coastguard Worker 
535*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
536*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
537*8975f5c5SAndroid Build Coastguard Worker     framebuffer.reset();
538*8975f5c5SAndroid Build Coastguard Worker     texture.reset();
539*8975f5c5SAndroid Build Coastguard Worker 
540*8975f5c5SAndroid Build Coastguard Worker     glFinish();
541*8975f5c5SAndroid Build Coastguard Worker 
542*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_TRUE(eglDestroyImageKHR(display, eglImage));
543*8975f5c5SAndroid Build Coastguard Worker     vkDestroyImage(helper.getDevice(), vkImage, nullptr);
544*8975f5c5SAndroid Build Coastguard Worker     vkFreeMemory(helper.getDevice(), vkDeviceMemory, nullptr);
545*8975f5c5SAndroid Build Coastguard Worker }
546*8975f5c5SAndroid Build Coastguard Worker 
547*8975f5c5SAndroid Build Coastguard Worker // Test that when VMA image suballocation is used, image memory can be allocated from the system in
548*8975f5c5SAndroid Build Coastguard Worker // case the device memory runs out.
TEST_P(VulkanMemoryTest,AllocateVMAImageWhenDeviceOOM)549*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanMemoryTest, AllocateVMAImageWhenDeviceOOM)
550*8975f5c5SAndroid Build Coastguard Worker {
551*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker     GLPerfMonitor monitor;
554*8975f5c5SAndroid Build Coastguard Worker     glBeginPerfMonitorAMD(monitor);
555*8975f5c5SAndroid Build Coastguard Worker 
556*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
557*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
558*8975f5c5SAndroid Build Coastguard Worker     uint64_t expectedAllocationFallbacks =
559*8975f5c5SAndroid Build Coastguard Worker         getPerfCounters().deviceMemoryImageAllocationFallbacks + 1;
560*8975f5c5SAndroid Build Coastguard Worker     uint64_t expectedAllocationFallbacksAfterLastTexture =
561*8975f5c5SAndroid Build Coastguard Worker         getPerfCounters().deviceMemoryImageAllocationFallbacks + 2;
562*8975f5c5SAndroid Build Coastguard Worker 
563*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize totalDeviceLocalMemoryHeapSize = 0;
564*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!compatibleMemorySizesForDeviceOOMTest(helper.getPhysicalDevice(),
565*8975f5c5SAndroid Build Coastguard Worker                                                               &totalDeviceLocalMemoryHeapSize));
566*8975f5c5SAndroid Build Coastguard Worker 
567*8975f5c5SAndroid Build Coastguard Worker     // Device memory is the first choice for image memory allocation. However, in case it runs out,
568*8975f5c5SAndroid Build Coastguard Worker     // memory should be allocated from the system if available. Therefore, we want to make sure that
569*8975f5c5SAndroid Build Coastguard Worker     // we can still allocate image memory even if the device memory is full.
570*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureWidth  = 2048;
571*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureHeight = 2048;
572*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureSize   = kTextureWidth * kTextureHeight * 4;
573*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize textureCount             = (totalDeviceLocalMemoryHeapSize / kTextureSize) + 1;
574*8975f5c5SAndroid Build Coastguard Worker 
575*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLTexture> textures;
576*8975f5c5SAndroid Build Coastguard Worker     textures.resize(textureCount);
577*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < textureCount; i++)
578*8975f5c5SAndroid Build Coastguard Worker     {
579*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, textures[i]);
580*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
581*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_POINTS, 0, 1);
582*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
583*8975f5c5SAndroid Build Coastguard Worker 
584*8975f5c5SAndroid Build Coastguard Worker         // This process only needs to continue until the allocation is no longer on the device.
585*8975f5c5SAndroid Build Coastguard Worker         if (getPerfCounters().deviceMemoryImageAllocationFallbacks == expectedAllocationFallbacks)
586*8975f5c5SAndroid Build Coastguard Worker         {
587*8975f5c5SAndroid Build Coastguard Worker             break;
588*8975f5c5SAndroid Build Coastguard Worker         }
589*8975f5c5SAndroid Build Coastguard Worker     }
590*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks, expectedAllocationFallbacks);
591*8975f5c5SAndroid Build Coastguard Worker 
592*8975f5c5SAndroid Build Coastguard Worker     // Verify that the texture allocated on the system memory can attach to a framebuffer correctly.
593*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
594*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> textureColor(kTextureWidth * kTextureHeight, GLColor::magenta);
595*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
596*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
597*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RGBA,
598*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, textureColor.data());
599*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks,
600*8975f5c5SAndroid Build Coastguard Worker               expectedAllocationFallbacksAfterLastTexture);
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker     glEndPerfMonitorAMD(monitor);
603*8975f5c5SAndroid Build Coastguard Worker 
604*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
605*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
606*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
607*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
608*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::magenta);
609*8975f5c5SAndroid Build Coastguard Worker }
610*8975f5c5SAndroid Build Coastguard Worker 
611*8975f5c5SAndroid Build Coastguard Worker // Test that when VMA image suballocation is used, it is possible to free space for a new image on
612*8975f5c5SAndroid Build Coastguard Worker // the device by freeing garbage memory from a 2D texture array.
TEST_P(VulkanMemoryTest,AllocateVMAImageAfterFreeing2DArrayGarbageWhenDeviceOOM)613*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanMemoryTest, AllocateVMAImageAfterFreeing2DArrayGarbageWhenDeviceOOM)
614*8975f5c5SAndroid Build Coastguard Worker {
615*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
616*8975f5c5SAndroid Build Coastguard Worker 
617*8975f5c5SAndroid Build Coastguard Worker     GLPerfMonitor monitor;
618*8975f5c5SAndroid Build Coastguard Worker     glBeginPerfMonitorAMD(monitor);
619*8975f5c5SAndroid Build Coastguard Worker 
620*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
621*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
622*8975f5c5SAndroid Build Coastguard Worker     uint64_t expectedAllocationFallbacks =
623*8975f5c5SAndroid Build Coastguard Worker         getPerfCounters().deviceMemoryImageAllocationFallbacks + 1;
624*8975f5c5SAndroid Build Coastguard Worker 
625*8975f5c5SAndroid Build Coastguard Worker     VkPhysicalDeviceMemoryProperties memoryProperties;
626*8975f5c5SAndroid Build Coastguard Worker     vkGetPhysicalDeviceMemoryProperties(helper.getPhysicalDevice(), &memoryProperties);
627*8975f5c5SAndroid Build Coastguard Worker 
628*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize totalDeviceLocalMemoryHeapSize = 0;
629*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!compatibleMemorySizesForDeviceOOMTest(helper.getPhysicalDevice(),
630*8975f5c5SAndroid Build Coastguard Worker                                                               &totalDeviceLocalMemoryHeapSize));
631*8975f5c5SAndroid Build Coastguard Worker 
632*8975f5c5SAndroid Build Coastguard Worker     // Use a 2D texture array to allocate some of the available device memory and draw with it.
633*8975f5c5SAndroid Build Coastguard Worker     GLuint texture2DArray;
634*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureWidth  = 512;
635*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureHeight = 512;
636*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize texture2DArrayLayerCount = 10;
637*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &texture2DArray);
638*8975f5c5SAndroid Build Coastguard Worker 
639*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D_ARRAY, texture2DArray);
640*8975f5c5SAndroid Build Coastguard Worker     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, kTextureWidth, kTextureHeight,
641*8975f5c5SAndroid Build Coastguard Worker                  static_cast<GLsizei>(texture2DArrayLayerCount), 0, GL_RGBA, GL_UNSIGNED_BYTE,
642*8975f5c5SAndroid Build Coastguard Worker                  nullptr);
643*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
644*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
645*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
646*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
647*8975f5c5SAndroid Build Coastguard Worker 
648*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < texture2DArrayLayerCount; i++)
649*8975f5c5SAndroid Build Coastguard Worker     {
650*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> textureColor(kTextureWidth * kTextureHeight, GLColor::green);
651*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, static_cast<GLint>(i), kTextureWidth,
652*8975f5c5SAndroid Build Coastguard Worker                         kTextureHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, textureColor.data());
653*8975f5c5SAndroid Build Coastguard Worker     }
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawTex2DArray, essl1_shaders::vs::Texture2DArray(),
656*8975f5c5SAndroid Build Coastguard Worker                      essl1_shaders::fs::Texture2DArray());
657*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawTex2DArray, essl1_shaders::PositionAttrib(), 0.5f);
658*8975f5c5SAndroid Build Coastguard Worker 
659*8975f5c5SAndroid Build Coastguard Worker     // Fill up the device memory until we start allocating on the system memory.
660*8975f5c5SAndroid Build Coastguard Worker     // Device memory is the first choice for image memory allocation. However, in case it runs out,
661*8975f5c5SAndroid Build Coastguard Worker     // memory should be allocated from the system if available.
662*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLTexture> textures2D;
663*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureSize = kTextureWidth * kTextureHeight * 4;
664*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize texture2DCount         = (totalDeviceLocalMemoryHeapSize / kTextureSize) + 1;
665*8975f5c5SAndroid Build Coastguard Worker     textures2D.resize(texture2DCount);
666*8975f5c5SAndroid Build Coastguard Worker 
667*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < texture2DCount; i++)
668*8975f5c5SAndroid Build Coastguard Worker     {
669*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, textures2D[i]);
670*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
671*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
672*8975f5c5SAndroid Build Coastguard Worker 
673*8975f5c5SAndroid Build Coastguard Worker         // This process only needs to continue until the allocation is no longer on the device.
674*8975f5c5SAndroid Build Coastguard Worker         if (getPerfCounters().deviceMemoryImageAllocationFallbacks == expectedAllocationFallbacks)
675*8975f5c5SAndroid Build Coastguard Worker         {
676*8975f5c5SAndroid Build Coastguard Worker             break;
677*8975f5c5SAndroid Build Coastguard Worker         }
678*8975f5c5SAndroid Build Coastguard Worker     }
679*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks, expectedAllocationFallbacks);
680*8975f5c5SAndroid Build Coastguard Worker 
681*8975f5c5SAndroid Build Coastguard Worker     // Wait until GPU finishes execution.
682*8975f5c5SAndroid Build Coastguard Worker     GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
683*8975f5c5SAndroid Build Coastguard Worker     glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
684*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
685*8975f5c5SAndroid Build Coastguard Worker 
686*8975f5c5SAndroid Build Coastguard Worker     // Delete the 2D array texture. This frees the memory due to context flushing from the memory
687*8975f5c5SAndroid Build Coastguard Worker     // allocation fallbacks.
688*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &texture2DArray);
689*8975f5c5SAndroid Build Coastguard Worker 
690*8975f5c5SAndroid Build Coastguard Worker     // The next texture should be allocated on the device, which will only be possible after freeing
691*8975f5c5SAndroid Build Coastguard Worker     // the garbage.
692*8975f5c5SAndroid Build Coastguard Worker     GLTexture lastTexture;
693*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> lastTextureColor(kTextureWidth * kTextureHeight, GLColor::blue);
694*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, lastTexture);
695*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
696*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RGBA,
697*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, lastTextureColor.data());
698*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks, expectedAllocationFallbacks);
699*8975f5c5SAndroid Build Coastguard Worker 
700*8975f5c5SAndroid Build Coastguard Worker     glEndPerfMonitorAMD(monitor);
701*8975f5c5SAndroid Build Coastguard Worker 
702*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
703*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
704*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lastTexture, 0);
705*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
706*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::blue);
707*8975f5c5SAndroid Build Coastguard Worker }
708*8975f5c5SAndroid Build Coastguard Worker 
709*8975f5c5SAndroid Build Coastguard Worker // Test that when VMA image suballocation is used, it is possible to free space for a new image on
710*8975f5c5SAndroid Build Coastguard Worker // the device by freeing finished garbage memory from a 2D texture.
TEST_P(VulkanMemoryTest,AllocateVMAImageAfterFreeingFinished2DGarbageWhenDeviceOOM)711*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanMemoryTest, AllocateVMAImageAfterFreeingFinished2DGarbageWhenDeviceOOM)
712*8975f5c5SAndroid Build Coastguard Worker {
713*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
714*8975f5c5SAndroid Build Coastguard Worker 
715*8975f5c5SAndroid Build Coastguard Worker     GLPerfMonitor monitor;
716*8975f5c5SAndroid Build Coastguard Worker     glBeginPerfMonitorAMD(monitor);
717*8975f5c5SAndroid Build Coastguard Worker 
718*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
719*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
720*8975f5c5SAndroid Build Coastguard Worker     uint64_t expectedAllocationFallbacks =
721*8975f5c5SAndroid Build Coastguard Worker         getPerfCounters().deviceMemoryImageAllocationFallbacks + 1;
722*8975f5c5SAndroid Build Coastguard Worker 
723*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize totalDeviceLocalMemoryHeapSize = 0;
724*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!compatibleMemorySizesForDeviceOOMTest(helper.getPhysicalDevice(),
725*8975f5c5SAndroid Build Coastguard Worker                                                               &totalDeviceLocalMemoryHeapSize));
726*8975f5c5SAndroid Build Coastguard Worker 
727*8975f5c5SAndroid Build Coastguard Worker     // Use a large 2D texture to allocate some of the available device memory and draw with it.
728*8975f5c5SAndroid Build Coastguard Worker     GLuint largeTexture;
729*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kLargeTextureWidth  = 2048;
730*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kLargeTextureHeight = 2048;
731*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> firstTextureColor(kLargeTextureWidth * kLargeTextureHeight,
732*8975f5c5SAndroid Build Coastguard Worker                                            GLColor::green);
733*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &largeTexture);
734*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, largeTexture);
735*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kLargeTextureWidth, kLargeTextureHeight, 0, GL_RGBA,
736*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
737*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
738*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
739*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
740*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
741*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLargeTextureWidth, kLargeTextureHeight, GL_RGBA,
742*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, firstTextureColor.data());
743*8975f5c5SAndroid Build Coastguard Worker 
744*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawTex2D, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
745*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawTex2D, essl1_shaders::PositionAttrib(), 0.5f);
746*8975f5c5SAndroid Build Coastguard Worker 
747*8975f5c5SAndroid Build Coastguard Worker     // Fill up the device memory until we start allocating on the system memory.
748*8975f5c5SAndroid Build Coastguard Worker     // Device memory is the first choice for image memory allocation. However, in case it runs out,
749*8975f5c5SAndroid Build Coastguard Worker     // memory should be allocated from the system if available.
750*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLTexture> textures2D;
751*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureWidth  = 512;
752*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureHeight = 512;
753*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureSize   = kTextureWidth * kTextureHeight * 4;
754*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize texture2DCount           = (totalDeviceLocalMemoryHeapSize / kTextureSize) + 1;
755*8975f5c5SAndroid Build Coastguard Worker     textures2D.resize(texture2DCount);
756*8975f5c5SAndroid Build Coastguard Worker 
757*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < texture2DCount; i++)
758*8975f5c5SAndroid Build Coastguard Worker     {
759*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, textures2D[i]);
760*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
761*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
762*8975f5c5SAndroid Build Coastguard Worker 
763*8975f5c5SAndroid Build Coastguard Worker         // This process only needs to continue until the allocation is no longer on the device.
764*8975f5c5SAndroid Build Coastguard Worker         if (getPerfCounters().deviceMemoryImageAllocationFallbacks == expectedAllocationFallbacks)
765*8975f5c5SAndroid Build Coastguard Worker         {
766*8975f5c5SAndroid Build Coastguard Worker             break;
767*8975f5c5SAndroid Build Coastguard Worker         }
768*8975f5c5SAndroid Build Coastguard Worker     }
769*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks, expectedAllocationFallbacks);
770*8975f5c5SAndroid Build Coastguard Worker 
771*8975f5c5SAndroid Build Coastguard Worker     // Wait until GPU finishes execution.
772*8975f5c5SAndroid Build Coastguard Worker     GLsync syncOne = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
773*8975f5c5SAndroid Build Coastguard Worker     glWaitSync(syncOne, 0, GL_TIMEOUT_IGNORED);
774*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
775*8975f5c5SAndroid Build Coastguard Worker 
776*8975f5c5SAndroid Build Coastguard Worker     // Delete the large 2D texture. It should free the memory due to context flushing performed
777*8975f5c5SAndroid Build Coastguard Worker     // during memory allocation fallbacks. Then we allocate and draw with this texture again.
778*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &largeTexture);
779*8975f5c5SAndroid Build Coastguard Worker 
780*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, largeTexture);
781*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kLargeTextureWidth, kLargeTextureHeight, 0, GL_RGBA,
782*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
783*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
784*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
785*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
786*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
787*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLargeTextureWidth, kLargeTextureHeight, GL_RGBA,
788*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, firstTextureColor.data());
789*8975f5c5SAndroid Build Coastguard Worker 
790*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawTex2D, essl1_shaders::PositionAttrib(), 0.5f);
791*8975f5c5SAndroid Build Coastguard Worker 
792*8975f5c5SAndroid Build Coastguard Worker     // Wait until GPU finishes execution one more time.
793*8975f5c5SAndroid Build Coastguard Worker     GLsync syncTwo = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
794*8975f5c5SAndroid Build Coastguard Worker     glWaitSync(syncTwo, 0, GL_TIMEOUT_IGNORED);
795*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
796*8975f5c5SAndroid Build Coastguard Worker 
797*8975f5c5SAndroid Build Coastguard Worker     // Delete the large 2D texture. Even though it is marked as deallocated, the device memory is
798*8975f5c5SAndroid Build Coastguard Worker     // not freed from the garbage yet.
799*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &largeTexture);
800*8975f5c5SAndroid Build Coastguard Worker 
801*8975f5c5SAndroid Build Coastguard Worker     // The next texture should be allocated on the device, which will only be possible after freeing
802*8975f5c5SAndroid Build Coastguard Worker     // the garbage from the finished commands. There should be no context flushing.
803*8975f5c5SAndroid Build Coastguard Worker     uint64_t expectedSubmitCalls = getPerfCounters().commandQueueSubmitCallsTotal;
804*8975f5c5SAndroid Build Coastguard Worker     GLTexture lastTexture;
805*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> textureColor(kLargeTextureWidth * kLargeTextureWidth, GLColor::red);
806*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, lastTexture);
807*8975f5c5SAndroid Build Coastguard Worker     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kLargeTextureWidth, kLargeTextureWidth);
808*8975f5c5SAndroid Build Coastguard Worker     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLargeTextureWidth, kLargeTextureWidth, GL_RGBA,
809*8975f5c5SAndroid Build Coastguard Worker                     GL_UNSIGNED_BYTE, textureColor.data());
810*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks, expectedAllocationFallbacks);
811*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedSubmitCalls);
812*8975f5c5SAndroid Build Coastguard Worker 
813*8975f5c5SAndroid Build Coastguard Worker     glEndPerfMonitorAMD(monitor);
814*8975f5c5SAndroid Build Coastguard Worker 
815*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
816*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
817*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lastTexture, 0);
818*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
819*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
820*8975f5c5SAndroid Build Coastguard Worker }
821*8975f5c5SAndroid Build Coastguard Worker 
822*8975f5c5SAndroid Build Coastguard Worker // Test that when VMA image suballocation is used, it is possible to free space for a new buffer on
823*8975f5c5SAndroid Build Coastguard Worker // the device by freeing garbage memory from a 2D texture.
TEST_P(VulkanMemoryTest,AllocateBufferAfterFreeing2DGarbageWhenDeviceOOM)824*8975f5c5SAndroid Build Coastguard Worker TEST_P(VulkanMemoryTest, AllocateBufferAfterFreeing2DGarbageWhenDeviceOOM)
825*8975f5c5SAndroid Build Coastguard Worker {
826*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!getEGLWindow()->isFeatureEnabled(Feature::UseVmaForImageSuballocation));
827*8975f5c5SAndroid Build Coastguard Worker 
828*8975f5c5SAndroid Build Coastguard Worker     GLPerfMonitor monitor;
829*8975f5c5SAndroid Build Coastguard Worker     glBeginPerfMonitorAMD(monitor);
830*8975f5c5SAndroid Build Coastguard Worker 
831*8975f5c5SAndroid Build Coastguard Worker     VulkanHelper helper;
832*8975f5c5SAndroid Build Coastguard Worker     helper.initializeFromANGLE();
833*8975f5c5SAndroid Build Coastguard Worker     uint64_t expectedAllocationFallbacks =
834*8975f5c5SAndroid Build Coastguard Worker         getPerfCounters().deviceMemoryImageAllocationFallbacks + 1;
835*8975f5c5SAndroid Build Coastguard Worker 
836*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize totalDeviceLocalMemoryHeapSize = 0;
837*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!compatibleMemorySizesForDeviceOOMTest(helper.getPhysicalDevice(),
838*8975f5c5SAndroid Build Coastguard Worker                                                               &totalDeviceLocalMemoryHeapSize));
839*8975f5c5SAndroid Build Coastguard Worker 
840*8975f5c5SAndroid Build Coastguard Worker     // Use a large 2D texture to allocate some of the available device memory and draw with it.
841*8975f5c5SAndroid Build Coastguard Worker     GLuint firstTexture;
842*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kFirstTextureWidth  = 2048;
843*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kFirstTextureHeight = 2048;
844*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &firstTexture);
845*8975f5c5SAndroid Build Coastguard Worker 
846*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, firstTexture);
847*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kFirstTextureWidth, kFirstTextureHeight, 0, GL_RGBA,
848*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
849*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
850*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
851*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
852*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
853*8975f5c5SAndroid Build Coastguard Worker 
854*8975f5c5SAndroid Build Coastguard Worker     {
855*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> firstTextureColor(kFirstTextureWidth * kFirstTextureHeight,
856*8975f5c5SAndroid Build Coastguard Worker                                                GLColor::green);
857*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kFirstTextureWidth, kFirstTextureHeight, GL_RGBA,
858*8975f5c5SAndroid Build Coastguard Worker                         GL_UNSIGNED_BYTE, firstTextureColor.data());
859*8975f5c5SAndroid Build Coastguard Worker     }
860*8975f5c5SAndroid Build Coastguard Worker 
861*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawTex2D, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
862*8975f5c5SAndroid Build Coastguard Worker     drawQuad(drawTex2D, essl1_shaders::PositionAttrib(), 0.5f);
863*8975f5c5SAndroid Build Coastguard Worker 
864*8975f5c5SAndroid Build Coastguard Worker     // Fill up the device memory until we start allocating on the system memory.
865*8975f5c5SAndroid Build Coastguard Worker     // Device memory is the first choice for image memory allocation. However, in case it runs out,
866*8975f5c5SAndroid Build Coastguard Worker     // memory should be allocated from the system if available.
867*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLTexture> textures2D;
868*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureWidth  = 512;
869*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureHeight = 512;
870*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kTextureSize   = kTextureWidth * kTextureHeight * 4;
871*8975f5c5SAndroid Build Coastguard Worker     VkDeviceSize texture2DCount           = (totalDeviceLocalMemoryHeapSize / kTextureSize) + 1;
872*8975f5c5SAndroid Build Coastguard Worker     textures2D.resize(texture2DCount);
873*8975f5c5SAndroid Build Coastguard Worker 
874*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < texture2DCount; i++)
875*8975f5c5SAndroid Build Coastguard Worker     {
876*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, textures2D[i]);
877*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureWidth, kTextureHeight);
878*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
879*8975f5c5SAndroid Build Coastguard Worker 
880*8975f5c5SAndroid Build Coastguard Worker         // This process only needs to continue until the allocation is no longer on the device.
881*8975f5c5SAndroid Build Coastguard Worker         if (getPerfCounters().deviceMemoryImageAllocationFallbacks == expectedAllocationFallbacks)
882*8975f5c5SAndroid Build Coastguard Worker         {
883*8975f5c5SAndroid Build Coastguard Worker             break;
884*8975f5c5SAndroid Build Coastguard Worker         }
885*8975f5c5SAndroid Build Coastguard Worker     }
886*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(getPerfCounters().deviceMemoryImageAllocationFallbacks, expectedAllocationFallbacks);
887*8975f5c5SAndroid Build Coastguard Worker 
888*8975f5c5SAndroid Build Coastguard Worker     glEndPerfMonitorAMD(monitor);
889*8975f5c5SAndroid Build Coastguard Worker 
890*8975f5c5SAndroid Build Coastguard Worker     // Wait until GPU finishes execution.
891*8975f5c5SAndroid Build Coastguard Worker     GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
892*8975f5c5SAndroid Build Coastguard Worker     glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
893*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
894*8975f5c5SAndroid Build Coastguard Worker 
895*8975f5c5SAndroid Build Coastguard Worker     // Delete the 2D array texture. This frees the memory due to context flushing from the memory
896*8975f5c5SAndroid Build Coastguard Worker     // allocation fallbacks.
897*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &firstTexture);
898*8975f5c5SAndroid Build Coastguard Worker 
899*8975f5c5SAndroid Build Coastguard Worker     // The buffer should be allocated on the device, which will only be possible after freeing the
900*8975f5c5SAndroid Build Coastguard Worker     // garbage.
901*8975f5c5SAndroid Build Coastguard Worker     GLBuffer lastBuffer;
902*8975f5c5SAndroid Build Coastguard Worker     constexpr VkDeviceSize kBufferSize = kTextureWidth * kTextureHeight * 4;
903*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> bufferData(kBufferSize, 255);
904*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, lastBuffer);
905*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, kBufferSize, bufferData.data(), GL_STATIC_DRAW);
906*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
907*8975f5c5SAndroid Build Coastguard Worker }
908*8975f5c5SAndroid Build Coastguard Worker 
909*8975f5c5SAndroid Build Coastguard Worker // Use this to select which configurations (e.g. which renderer, which GLES major version) these
910*8975f5c5SAndroid Build Coastguard Worker // tests should be run against.
911*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(VulkanImageTest);
912*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(VulkanMemoryTest);
913*8975f5c5SAndroid Build Coastguard Worker 
914*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
915