blob: 370b48c40141e6fb9fed7bd77a1f12f76f6f1c66 [file] [log] [blame]
Yahan Zhou537664b2024-01-24 15:38:01 -08001// Copyright (C) 2023 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <string>
16
Yahan Zhou5dce73f2024-05-09 11:46:15 -070017#include "GfxstreamEnd2EndTestUtils.h"
Yahan Zhou537664b2024-01-24 15:38:01 -080018#include "GfxstreamEnd2EndTests.h"
19#include "gfxstream/RutabagaLayerTestUtils.h"
20
21namespace gfxstream {
22namespace tests {
23namespace {
24
25using testing::Eq;
26using testing::Ge;
27using testing::IsEmpty;
28using testing::IsNull;
29using testing::Not;
30using testing::NotNull;
31
32class GfxstreamEnd2EndVkSnapshotImageTest : public GfxstreamEnd2EndTest {};
33
Yahan Zhoud6daa4b2024-01-30 15:23:59 -080034TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, PreserveImageHandle) {
Yahan Zhou537664b2024-01-24 15:38:01 -080035 auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
36 VK_ASSERT(SetUpTypicalVkTestEnvironment());
37
38 const uint32_t width = 32;
39 const uint32_t height = 32;
40
41 const vkhpp::ImageCreateInfo imageCreateInfo = {
42 .pNext = nullptr,
43 .imageType = vkhpp::ImageType::e2D,
44 .extent.width = width,
45 .extent.height = height,
46 .extent.depth = 1,
47 .mipLevels = 1,
48 .arrayLayers = 1,
49 .format = vkhpp::Format::eR8G8B8A8Unorm,
50 .tiling = vkhpp::ImageTiling::eOptimal,
51 .initialLayout = vkhpp::ImageLayout::eUndefined,
52 .usage = vkhpp::ImageUsageFlagBits::eSampled | vkhpp::ImageUsageFlagBits::eTransferDst |
53 vkhpp::ImageUsageFlagBits::eTransferSrc,
54 .sharingMode = vkhpp::SharingMode::eExclusive,
55 .samples = vkhpp::SampleCountFlagBits::e1,
56 };
57 auto image = device->createImageUnique(imageCreateInfo).value;
58
59 vkhpp::MemoryRequirements imageMemoryRequirements{};
60 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
61
Yahan Zhou5dce73f2024-05-09 11:46:15 -070062 const uint32_t imageMemoryIndex = utils::getMemoryType(
63 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
Yahan Zhou537664b2024-01-24 15:38:01 -080064 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
65
66 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
67 .allocationSize = imageMemoryRequirements.size,
68 .memoryTypeIndex = imageMemoryIndex,
69 };
70
71 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
72 ASSERT_THAT(imageMemory, IsValidHandle());
73
74 SnapshotSaveAndLoad();
75
76 ASSERT_THAT(device->bindImageMemory(*image, *imageMemory, 0), IsVkSuccess());
77}
78
Yahan Zhou36c3a5e2024-06-10 10:21:17 -070079// b/346415931
80// We used to have an issue that the handles mismatch when running more device
81// create calls. The first device always work but the second might break.
82TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, MultipleDevicesPreserveHandles) {
83 auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
84 VK_ASSERT(SetUpTypicalVkTestEnvironment());
85
86 uint32_t graphicsQueueFamilyIndex = -1;
87 {
88 const auto props = physicalDevice.getQueueFamilyProperties();
89 for (uint32_t i = 0; i < props.size(); i++) {
90 const auto& prop = props[i];
91 if (prop.queueFlags & vkhpp::QueueFlagBits::eGraphics) {
92 graphicsQueueFamilyIndex = i;
93 break;
94 }
95 }
96 }
97 ASSERT_THAT(graphicsQueueFamilyIndex, Not(Eq(-1)));
98 const float queuePriority = 1.0f;
99 const vkhpp::DeviceQueueCreateInfo deviceQueueCreateInfo = {
100 .queueFamilyIndex = graphicsQueueFamilyIndex,
101 .queueCount = 1,
102 .pQueuePriorities = &queuePriority,
103 };
104 std::vector<const char*> deviceExtensions = {
105 VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME,
106 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
107 };
108 const vkhpp::DeviceCreateInfo deviceCreateInfo = {
109 .pNext = nullptr,
110 .pQueueCreateInfos = &deviceQueueCreateInfo,
111 .queueCreateInfoCount = 1,
112 .enabledLayerCount = 0,
113 .ppEnabledLayerNames = nullptr,
114 .enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size()),
115 .ppEnabledExtensionNames = deviceExtensions.data(),
116 };
117 auto device2 = physicalDevice.createDeviceUnique(deviceCreateInfo).value;
118 ASSERT_THAT(device2, IsValidHandle());
119
120 const uint32_t width = 32;
121 const uint32_t height = 32;
122
123 const vkhpp::ImageCreateInfo imageCreateInfo = {
124 .pNext = nullptr,
125 .imageType = vkhpp::ImageType::e2D,
126 .extent.width = width,
127 .extent.height = height,
128 .extent.depth = 1,
129 .mipLevels = 1,
130 .arrayLayers = 1,
131 .format = vkhpp::Format::eR8G8B8A8Unorm,
132 .tiling = vkhpp::ImageTiling::eOptimal,
133 .initialLayout = vkhpp::ImageLayout::eUndefined,
134 .usage = vkhpp::ImageUsageFlagBits::eSampled | vkhpp::ImageUsageFlagBits::eTransferDst |
135 vkhpp::ImageUsageFlagBits::eTransferSrc,
136 .sharingMode = vkhpp::SharingMode::eExclusive,
137 .samples = vkhpp::SampleCountFlagBits::e1,
138 };
139 auto image = device->createImageUnique(imageCreateInfo).value;
140
141 vkhpp::MemoryRequirements imageMemoryRequirements{};
142 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
143
144 const uint32_t imageMemoryIndex = utils::getMemoryType(
145 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
146 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
147
148 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
149 .allocationSize = imageMemoryRequirements.size,
150 .memoryTypeIndex = imageMemoryIndex,
151 };
152
153 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
154 ASSERT_THAT(imageMemory, IsValidHandle());
155
156 ASSERT_THAT(device->bindImageMemory(*image, *imageMemory, 0), IsVkSuccess());
157
158 // No device lost on snapshot load.
159 SnapshotSaveAndLoad();
160}
161
Yahan Zhou505f0292024-03-08 15:39:38 -0800162TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, ImageViewDependency) {
163 auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
164 VK_ASSERT(SetUpTypicalVkTestEnvironment());
165
166 const uint32_t width = 32;
167 const uint32_t height = 32;
168
169 const vkhpp::ImageCreateInfo imageCreateInfo = {
170 .pNext = nullptr,
171 .imageType = vkhpp::ImageType::e2D,
172 .extent.width = width,
173 .extent.height = height,
174 .extent.depth = 1,
175 .mipLevels = 1,
176 .arrayLayers = 1,
177 .format = vkhpp::Format::eR8G8B8A8Unorm,
178 .tiling = vkhpp::ImageTiling::eOptimal,
179 .initialLayout = vkhpp::ImageLayout::eUndefined,
180 .usage = vkhpp::ImageUsageFlagBits::eSampled | vkhpp::ImageUsageFlagBits::eTransferDst |
181 vkhpp::ImageUsageFlagBits::eTransferSrc,
182 .sharingMode = vkhpp::SharingMode::eExclusive,
183 .samples = vkhpp::SampleCountFlagBits::e1,
184 };
185 auto image = device->createImageUnique(imageCreateInfo).value;
186 ASSERT_THAT(image, IsValidHandle());
187
188 vkhpp::MemoryRequirements imageMemoryRequirements{};
189 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
190
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700191 const uint32_t imageMemoryIndex = utils::getMemoryType(
192 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
Yahan Zhou505f0292024-03-08 15:39:38 -0800193 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
194
195 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
196 .allocationSize = imageMemoryRequirements.size,
197 .memoryTypeIndex = imageMemoryIndex,
198 };
199
200 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
201 ASSERT_THAT(imageMemory, IsValidHandle());
202
203 ASSERT_THAT(device->bindImageMemory(*image, *imageMemory, 0), IsVkSuccess());
204
Yahan Zhou2d7e1a52024-03-26 13:02:30 -0700205 // b/331677615
206 // Create and delete a buffer handle right before creating image view.
207 // Gfxstream recycle handles. We trick the VkImageView handle to collide with
208 // a destroyed buffer handle and verify there is no bug snapshotting recycled
209 // handles.
210 const vkhpp::BufferCreateInfo bufferCreateInfo = {
211 .size = 1024,
212 .usage = vkhpp::BufferUsageFlagBits::eTransferSrc,
213 };
214 auto buffer = device->createBufferUnique(bufferCreateInfo).value;
215 ASSERT_THAT(buffer, IsValidHandle());
216 buffer.reset();
217
Yahan Zhou505f0292024-03-08 15:39:38 -0800218 const vkhpp::ImageViewCreateInfo imageViewCreateInfo = {
219 .image = *image,
220 .viewType = vkhpp::ImageViewType::e2D,
221 .format = vkhpp::Format::eR8G8B8A8Unorm,
222 .subresourceRange =
223 {
224 .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
225 .baseMipLevel = 0,
226 .levelCount = 1,
227 .baseArrayLayer = 0,
228 .layerCount = 1,
229 },
230 };
231 auto imageView = device->createImageViewUnique(imageViewCreateInfo).value;
232 ASSERT_THAT(imageView, IsValidHandle());
233 // Make sure it doesn't crash on load
234 SnapshotSaveAndLoad();
235}
236
Yahan Zhoud4ef70e2024-06-28 22:59:27 +0000237// Use vkBindImageMemory2 instead of vkBindImageMemory
238TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, ImageViewDependency2) {
239 auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
240 VK_ASSERT(SetUpTypicalVkTestEnvironment());
241
242 const uint32_t width = 32;
243 const uint32_t height = 32;
244
245 const vkhpp::ImageCreateInfo imageCreateInfo = {
246 .pNext = nullptr,
247 .imageType = vkhpp::ImageType::e2D,
248 .extent.width = width,
249 .extent.height = height,
250 .extent.depth = 1,
251 .mipLevels = 1,
252 .arrayLayers = 1,
253 .format = vkhpp::Format::eR8G8B8A8Unorm,
254 .tiling = vkhpp::ImageTiling::eOptimal,
255 .initialLayout = vkhpp::ImageLayout::eUndefined,
256 .usage = vkhpp::ImageUsageFlagBits::eSampled | vkhpp::ImageUsageFlagBits::eTransferDst |
257 vkhpp::ImageUsageFlagBits::eTransferSrc,
258 .sharingMode = vkhpp::SharingMode::eExclusive,
259 .samples = vkhpp::SampleCountFlagBits::e1,
260 };
261 auto image = device->createImageUnique(imageCreateInfo).value;
262 ASSERT_THAT(image, IsValidHandle());
263
264 vkhpp::MemoryRequirements imageMemoryRequirements{};
265 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
266
267 const uint32_t imageMemoryIndex = utils::getMemoryType(
268 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
269 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
270
271 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
272 .allocationSize = imageMemoryRequirements.size,
273 .memoryTypeIndex = imageMemoryIndex,
274 };
275
276 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
277 ASSERT_THAT(imageMemory, IsValidHandle());
278
279 const vkhpp::BindImageMemoryInfo imageBindMemoryInfo = {
280 .pNext = nullptr,
281 .image = *image,
282 .memory = *imageMemory,
283 .memoryOffset = 0,
284 };
285
286 ASSERT_THAT(device->bindImageMemory2({imageBindMemoryInfo}), IsVkSuccess());
287
288 // b/331677615
289 // Create and delete a buffer handle right before creating image view.
290 // Gfxstream recycle handles. We trick the VkImageView handle to collide with
291 // a destroyed buffer handle and verify there is no bug snapshotting recycled
292 // handles.
293 const vkhpp::BufferCreateInfo bufferCreateInfo = {
294 .size = 1024,
295 .usage = vkhpp::BufferUsageFlagBits::eTransferSrc,
296 };
297 auto buffer = device->createBufferUnique(bufferCreateInfo).value;
298 ASSERT_THAT(buffer, IsValidHandle());
299 buffer.reset();
300
301 const vkhpp::ImageViewCreateInfo imageViewCreateInfo = {
302 .image = *image,
303 .viewType = vkhpp::ImageViewType::e2D,
304 .format = vkhpp::Format::eR8G8B8A8Unorm,
305 .subresourceRange =
306 {
307 .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
308 .baseMipLevel = 0,
309 .levelCount = 1,
310 .baseArrayLayer = 0,
311 .layerCount = 1,
312 },
313 };
314 auto imageView = device->createImageViewUnique(imageViewCreateInfo).value;
315 ASSERT_THAT(imageView, IsValidHandle());
316 // Make sure it doesn't crash on load
317 SnapshotSaveAndLoad();
318}
319
Yahan Zhou77d84112024-04-11 14:45:18 -0700320TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, MultiSampleImage) {
321 auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
322 VK_ASSERT(SetUpTypicalVkTestEnvironment());
323
324 const uint32_t width = 32;
325 const uint32_t height = 32;
326
327 const vkhpp::ImageCreateInfo imageCreateInfo = {
328 .pNext = nullptr,
329 .imageType = vkhpp::ImageType::e2D,
330 .extent.width = width,
331 .extent.height = height,
332 .extent.depth = 1,
333 .mipLevels = 1,
334 .arrayLayers = 1,
335 .format = vkhpp::Format::eR8G8B8A8Unorm,
336 .tiling = vkhpp::ImageTiling::eOptimal,
337 .initialLayout = vkhpp::ImageLayout::eUndefined,
338 .usage = vkhpp::ImageUsageFlagBits::eColorAttachment |
339 vkhpp::ImageUsageFlagBits::eTransferDst | vkhpp::ImageUsageFlagBits::eTransferSrc,
340 .sharingMode = vkhpp::SharingMode::eExclusive,
341 .samples = vkhpp::SampleCountFlagBits::e8,
342 };
343 auto image = device->createImageUnique(imageCreateInfo).value;
344 ASSERT_THAT(image, IsValidHandle());
345
346 vkhpp::MemoryRequirements imageMemoryRequirements{};
347 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
348
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700349 const uint32_t imageMemoryIndex = utils::getMemoryType(
350 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
Yahan Zhou77d84112024-04-11 14:45:18 -0700351 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
352
353 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
354 .allocationSize = imageMemoryRequirements.size,
355 .memoryTypeIndex = imageMemoryIndex,
356 };
357
358 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
359 ASSERT_THAT(imageMemory, IsValidHandle());
360
361 // Make sure it doesn't crash on load
362 SnapshotSaveAndLoad();
363}
364
Yahan Zhou1006a862024-04-09 16:39:07 -0700365TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, ImageViewDependencyWithDedicatedMemory) {
366 auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
367 VK_ASSERT(SetUpTypicalVkTestEnvironment());
368
369 const uint32_t width = 32;
370 const uint32_t height = 32;
371
372 const vkhpp::ImageCreateInfo imageCreateInfo = {
373 .pNext = nullptr,
374 .imageType = vkhpp::ImageType::e2D,
375 .extent.width = width,
376 .extent.height = height,
377 .extent.depth = 1,
378 .mipLevels = 1,
379 .arrayLayers = 1,
380 .format = vkhpp::Format::eR8G8B8A8Unorm,
381 .tiling = vkhpp::ImageTiling::eOptimal,
382 .initialLayout = vkhpp::ImageLayout::eUndefined,
383 .usage = vkhpp::ImageUsageFlagBits::eSampled | vkhpp::ImageUsageFlagBits::eTransferDst |
384 vkhpp::ImageUsageFlagBits::eTransferSrc,
385 .sharingMode = vkhpp::SharingMode::eExclusive,
386 .samples = vkhpp::SampleCountFlagBits::e1,
387 };
388 auto image = device->createImageUnique(imageCreateInfo).value;
389 ASSERT_THAT(image, IsValidHandle());
390
391 vkhpp::MemoryRequirements imageMemoryRequirements{};
392 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
393
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700394 const uint32_t imageMemoryIndex = utils::getMemoryType(
395 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
Yahan Zhou1006a862024-04-09 16:39:07 -0700396 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
397
398 const vkhpp::MemoryDedicatedAllocateInfo dedicatedAllocateInfo = {
399 .image = *image,
400 };
401
402 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
403 .pNext = &dedicatedAllocateInfo,
404 .allocationSize = imageMemoryRequirements.size,
405 .memoryTypeIndex = imageMemoryIndex,
406 };
407
408 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
409 ASSERT_THAT(imageMemory, IsValidHandle());
410
411 ASSERT_THAT(device->bindImageMemory(*image, *imageMemory, 0), IsVkSuccess());
412
413 const vkhpp::ImageViewCreateInfo imageViewCreateInfo = {
414 .image = *image,
415 .viewType = vkhpp::ImageViewType::e2D,
416 .format = vkhpp::Format::eR8G8B8A8Unorm,
417 .subresourceRange =
418 {
419 .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
420 .baseMipLevel = 0,
421 .levelCount = 1,
422 .baseArrayLayer = 0,
423 .layerCount = 1,
424 },
425 };
426 auto imageView = device->createImageViewUnique(imageViewCreateInfo).value;
427 ASSERT_THAT(imageView, IsValidHandle());
428 // Make sure it doesn't crash on load
429 SnapshotSaveAndLoad();
430}
431
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800432TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, ImageContent) {
433 static constexpr int kWidth = 256;
434 static constexpr int kHeight = 256;
435 static constexpr vkhpp::DeviceSize kSize = 4 * kWidth * kHeight;
436
437 std::vector<uint8_t> srcBufferContent(kSize);
438 for (size_t i = 0; i < kSize; i++) {
439 srcBufferContent[i] = static_cast<uint8_t>(i & 0xff);
440 }
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700441 TypicalVkTestEnvironment testEnvironment = VK_ASSERT(SetUpTypicalVkTestEnvironment());
442 auto& instance = testEnvironment.instance;
443 auto& physicalDevice = testEnvironment.physicalDevice;
444 auto& device = testEnvironment.device;
445 auto& queue = testEnvironment.queue;
446 auto queueFamilyIndex = testEnvironment.queueFamilyIndex;
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800447
448 // Staging buffer
449 const vkhpp::BufferCreateInfo bufferCreateInfo = {
450 .size = static_cast<VkDeviceSize>(kSize),
451 .usage = vkhpp::BufferUsageFlagBits::eTransferSrc,
452 .sharingMode = vkhpp::SharingMode::eExclusive,
453 };
454 auto stagingBuffer = device->createBufferUnique(bufferCreateInfo).value;
455 ASSERT_THAT(stagingBuffer, IsValidHandle());
456
457 vkhpp::MemoryRequirements stagingBufferMemoryRequirements{};
458 device->getBufferMemoryRequirements(*stagingBuffer, &stagingBufferMemoryRequirements);
459
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700460 const auto stagingBufferMemoryType = utils::getMemoryType(
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800461 physicalDevice, stagingBufferMemoryRequirements,
462 vkhpp::MemoryPropertyFlagBits::eHostVisible | vkhpp::MemoryPropertyFlagBits::eHostCoherent);
463
464 // Staging memory
465 const vkhpp::MemoryAllocateInfo stagingBufferMemoryAllocateInfo = {
466 .allocationSize = stagingBufferMemoryRequirements.size,
467 .memoryTypeIndex = stagingBufferMemoryType,
468 };
469 auto stagingBufferMemory = device->allocateMemoryUnique(stagingBufferMemoryAllocateInfo).value;
470 ASSERT_THAT(stagingBufferMemory, IsValidHandle());
471 ASSERT_THAT(device->bindBufferMemory(*stagingBuffer, *stagingBufferMemory, 0), IsVkSuccess());
472
473 // Fill memory content
474 void* mapped = nullptr;
475 auto mapResult =
476 device->mapMemory(*stagingBufferMemory, 0, VK_WHOLE_SIZE, vkhpp::MemoryMapFlags{}, &mapped);
477 ASSERT_THAT(mapResult, IsVkSuccess());
478 ASSERT_THAT(mapped, NotNull());
479
480 auto* bytes = reinterpret_cast<uint8_t*>(mapped);
481 std::memcpy(bytes, srcBufferContent.data(), kSize);
482
483 const vkhpp::MappedMemoryRange range = {
484 .memory = *stagingBufferMemory,
485 .offset = 0,
486 .size = kSize,
487 };
488 device->unmapMemory(*stagingBufferMemory);
489
490 // Image
491 const vkhpp::ImageCreateInfo imageCreateInfo = {
492 .pNext = nullptr,
493 .imageType = vkhpp::ImageType::e2D,
494 .extent.width = kWidth,
495 .extent.height = kHeight,
496 .extent.depth = 1,
497 .mipLevels = 1,
498 .arrayLayers = 1,
499 .format = vkhpp::Format::eR8G8B8A8Unorm,
500 .tiling = vkhpp::ImageTiling::eOptimal,
Yahan Zhou505f0292024-03-08 15:39:38 -0800501 .initialLayout = vkhpp::ImageLayout::ePreinitialized,
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800502 .usage = vkhpp::ImageUsageFlagBits::eTransferDst | vkhpp::ImageUsageFlagBits::eTransferSrc,
503 .sharingMode = vkhpp::SharingMode::eExclusive,
504 .samples = vkhpp::SampleCountFlagBits::e1,
505 };
506 auto image = device->createImageUnique(imageCreateInfo).value;
Yahan Zhou505f0292024-03-08 15:39:38 -0800507 ASSERT_THAT(image, IsValidHandle());
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800508
509 vkhpp::MemoryRequirements imageMemoryRequirements{};
510 device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
511
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700512 const uint32_t imageMemoryIndex = utils::getMemoryType(
513 physicalDevice, imageMemoryRequirements, vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800514 ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
515
516 const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
517 .allocationSize = imageMemoryRequirements.size,
518 .memoryTypeIndex = imageMemoryIndex,
519 };
520
521 auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
522 ASSERT_THAT(imageMemory, IsValidHandle());
523
524 ASSERT_THAT(device->bindImageMemory(*image, *imageMemory, 0), IsVkSuccess());
525
526 // Command buffer
527 const vkhpp::CommandPoolCreateInfo commandPoolCreateInfo = {
528 .queueFamilyIndex = queueFamilyIndex,
529 };
530
531 auto commandPool = device->createCommandPoolUnique(commandPoolCreateInfo).value;
532 ASSERT_THAT(commandPool, IsValidHandle());
533
534 const vkhpp::CommandBufferAllocateInfo commandBufferAllocateInfo = {
535 .level = vkhpp::CommandBufferLevel::ePrimary,
536 .commandPool = *commandPool,
537 .commandBufferCount = 1,
538 };
539 auto commandBuffers = device->allocateCommandBuffersUnique(commandBufferAllocateInfo).value;
540 ASSERT_THAT(commandBuffers, Not(IsEmpty()));
541 auto commandBuffer = std::move(commandBuffers[0]);
542 ASSERT_THAT(commandBuffer, IsValidHandle());
543
544 const vkhpp::CommandBufferBeginInfo commandBufferBeginInfo = {
545 .flags = vkhpp::CommandBufferUsageFlagBits::eOneTimeSubmit,
546 };
547 commandBuffer->begin(commandBufferBeginInfo);
548
549 const vkhpp::ImageMemoryBarrier barrier{
550 .oldLayout = vkhpp::ImageLayout::eUndefined,
551 .newLayout = vkhpp::ImageLayout::eTransferDstOptimal,
552 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
553 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
554 .image = *image,
555 .subresourceRange =
556 {
557 .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
558 .levelCount = 1,
559 .layerCount = 1,
560 },
561 };
562
563 commandBuffer->pipelineBarrier(vkhpp::PipelineStageFlagBits::eAllCommands,
564 vkhpp::PipelineStageFlagBits::eAllCommands,
565 vkhpp::DependencyFlags(), nullptr, nullptr, barrier);
566
567 const vkhpp::BufferImageCopy bufferImageCopy = {
568 .imageSubresource =
569 {
570 .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
571 .layerCount = 1,
572 },
573 .imageExtent =
574 {
575 .width = kWidth,
576 .height = kHeight,
577 .depth = 1,
578 },
579 };
580 commandBuffer->copyBufferToImage(*stagingBuffer, *image,
581 vkhpp::ImageLayout::eTransferDstOptimal, 1, &bufferImageCopy);
582
583 commandBuffer->end();
584
585 auto transferFence = device->createFenceUnique(vkhpp::FenceCreateInfo()).value;
586 ASSERT_THAT(transferFence, IsValidHandle());
587
588 // Execute the command to copy image
589 const vkhpp::SubmitInfo submitInfo = {
590 .commandBufferCount = 1,
591 .pCommandBuffers = &commandBuffer.get(),
592 };
593 queue.submit(submitInfo, *transferFence);
594
595 auto waitResult = device->waitForFences(*transferFence, VK_TRUE, 3000000000L);
596 ASSERT_THAT(waitResult, IsVkSuccess());
597
598 // Snapshot
599 SnapshotSaveAndLoad();
600
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700601 std::vector<uint8_t> dst(kSize);
602 utils::readImageData(*image, kWidth, kHeight, vkhpp::ImageLayout::eTransferDstOptimal,
603 dst.data(), kSize, testEnvironment);
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800604
605 for (uint32_t i = 0; i < kSize; ++i) {
Yahan Zhou5dce73f2024-05-09 11:46:15 -0700606 ASSERT_THAT(dst[i], Eq(srcBufferContent[i]));
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800607 }
Yahan Zhoud6daa4b2024-01-30 15:23:59 -0800608}
609
Yahan Zhou537664b2024-01-24 15:38:01 -0800610INSTANTIATE_TEST_CASE_P(GfxstreamEnd2EndTests, GfxstreamEnd2EndVkSnapshotImageTest,
611 ::testing::ValuesIn({
612 TestParams{
613 .with_gl = false,
614 .with_vk = true,
Jason Macnak244fd722024-04-02 13:26:50 -0700615 .with_features = {"VulkanSnapshots"},
Yahan Zhou537664b2024-01-24 15:38:01 -0800616 },
617 }),
618 &GetTestName);
619
620} // namespace
621} // namespace tests
622} // namespace gfxstream