| 484 | } |
| 485 | |
| 486 | void VKRenderSystem::ReadTexture(Texture& texture, const TextureRegion& textureRegion, const DstImageDescriptor& imageDesc) |
| 487 | { |
| 488 | auto& textureVK = LLGL_CAST(VKTexture&, texture); |
| 489 | |
| 490 | /* Determine size of image for staging buffer */ |
| 491 | const auto& offset = textureRegion.offset; |
| 492 | const auto& extent = textureRegion.extent; |
| 493 | const auto format = VKTypes::Unmap(textureVK.GetVkFormat()); |
| 494 | |
| 495 | auto image = textureVK.GetVkImage(); |
| 496 | const auto imageSize = extent.width * extent.height * extent.depth; |
| 497 | const auto imageDataSize = static_cast<VkDeviceSize>(GetMemoryFootprint(format, imageSize)); |
| 498 | |
| 499 | /* Create staging buffer */ |
| 500 | VkBufferCreateInfo stagingCreateInfo; |
| 501 | BuildVkBufferCreateInfo(stagingCreateInfo, imageDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| 502 | auto stagingBuffer = CreateStagingBuffer(stagingCreateInfo); |
| 503 | |
| 504 | /* Copy staging buffer into hardware texture, then transfer image into sampling-ready state */ |
| 505 | auto cmdBuffer = device_.AllocCommandBuffer(); |
| 506 | { |
| 507 | device_.TransitionImageLayout( |
| 508 | cmdBuffer, |
| 509 | image, |
| 510 | textureVK.GetVkFormat(), |
| 511 | VK_IMAGE_LAYOUT_UNDEFINED, |
| 512 | VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 513 | textureRegion.subresource |
| 514 | ); |
| 515 | |
| 516 | device_.CopyImageToBuffer( |
| 517 | cmdBuffer, |
| 518 | image, |
| 519 | stagingBuffer.GetVkBuffer(), |
| 520 | VkOffset3D{ offset.x, offset.y, offset.z }, |
| 521 | VkExtent3D{ extent.width, extent.height, extent.depth }, |
| 522 | textureRegion.subresource |
| 523 | ); |
| 524 | |
| 525 | device_.TransitionImageLayout( |
| 526 | cmdBuffer, |
| 527 | image, |
| 528 | textureVK.GetVkFormat(), |
| 529 | VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| 530 | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, |
| 531 | textureRegion.subresource |
| 532 | ); |
| 533 | } |
| 534 | device_.FlushCommandBuffer(cmdBuffer); |
| 535 | |
| 536 | /* Map staging buffer to CPU memory space */ |
| 537 | if (auto region = stagingBuffer.GetMemoryRegion()) |
| 538 | { |
| 539 | /* Map buffer memory to host memory */ |
| 540 | auto deviceMemory = region->GetParentChunk(); |
| 541 | if (auto memory = deviceMemory->Map(device_, region->GetOffset(), imageDataSize)) |
| 542 | { |
| 543 | /* Copy data to buffer object */ |
no test coverage detected