@@ -1340,9 +1340,22 @@ bool VulkanContext::GetLastFrame(std::vector<u8>& data, int& width, int& height)
1340
1340
else
1341
1341
width = w;
1342
1342
}
1343
+
1344
+ vk::Format imageFormat = vk::Format::eR8G8B8A8Unorm;
1345
+ const vk::ImageUsageFlags imageUsage = vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc;
1346
+
1347
+ // Test if RGB8 is natively supported to avoid having to do a format conversion
1348
+ bool nativeRgb8 = false ;
1349
+ vk::ImageFormatProperties rgb8Properties{};
1350
+ if (physicalDevice.getImageFormatProperties (vk::Format::eR8G8B8Unorm, vk::ImageType::e2D, vk::ImageTiling::eOptimal, imageUsage, {}, &rgb8Properties) == vk::Result::eSuccess)
1351
+ {
1352
+ nativeRgb8 = true ;
1353
+ imageFormat = vk::Format::eR8G8B8Unorm;
1354
+ }
1355
+
1343
1356
// color attachment
1344
1357
FramebufferAttachment attachment (physicalDevice, *device);
1345
- attachment.Init (width, height, vk::Format::eR8G8B8A8Unorm, vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc , " screenshot" );
1358
+ attachment.Init (width, height, imageFormat, imageUsage , " screenshot" );
1346
1359
// command buffer
1347
1360
vk::UniqueCommandBuffer commandBuffer = std::move (device->allocateCommandBuffersUnique (
1348
1361
vk::CommandBufferAllocateInfo (*commandPools.back (), vk::CommandBufferLevel::ePrimary, 1 )).front ());
@@ -1352,7 +1365,7 @@ bool VulkanContext::GetLastFrame(std::vector<u8>& data, int& width, int& height)
1352
1365
CommandBufferDebugScope _ (commandBuffer.get (), " GetLastFrame" , scopeColor);
1353
1366
1354
1367
// render pass
1355
- vk::AttachmentDescription attachmentDescription = vk::AttachmentDescription (vk::AttachmentDescriptionFlags (), vk::Format::eR8G8B8A8Unorm , vk::SampleCountFlagBits::e1 ,
1368
+ vk::AttachmentDescription attachmentDescription = vk::AttachmentDescription (vk::AttachmentDescriptionFlags (), imageFormat , vk::SampleCountFlagBits::e1 ,
1356
1369
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
1357
1370
vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferSrcOptimal);
1358
1371
vk::AttachmentReference colorReference (0 , vk::ImageLayout::eColorAttachmentOptimal);
@@ -1417,15 +1430,25 @@ bool VulkanContext::GetLastFrame(std::vector<u8>& data, int& width, int& height)
1417
1430
1418
1431
const u8 *img = (const u8 *)attachment.GetBufferData ()->MapMemory ();
1419
1432
data.clear ();
1420
- data.reserve (width * height * 3 );
1421
- for (int y = 0 ; y < height; y++)
1433
+ if (nativeRgb8)
1422
1434
{
1423
- for (int x = 0 ; x < width; x++)
1435
+ // Format is already RGB, can be directly copied
1436
+ data.resize (width * height * 3 );
1437
+ std::memcpy (data.data (), img, width* height * 3 );
1438
+ }
1439
+ else
1440
+ {
1441
+ data.reserve (width * height * 3 );
1442
+ // RGBA -> RGB
1443
+ for (int y = 0 ; y < height; y++)
1424
1444
{
1425
- data.push_back (*img++);
1426
- data.push_back (*img++);
1427
- data.push_back (*img++);
1428
- img++;
1445
+ for (int x = 0 ; x < width; x++)
1446
+ {
1447
+ data.push_back (*img++);
1448
+ data.push_back (*img++);
1449
+ data.push_back (*img++);
1450
+ img++;
1451
+ }
1429
1452
}
1430
1453
}
1431
1454
attachment.GetBufferData ()->UnmapMemory ();
0 commit comments