| 1555 | } |
| 1556 | |
| 1557 | void GPUContextVulkan::CopyTexture(GPUTexture* dstResource, uint32 dstSubresource, uint32 dstX, uint32 dstY, uint32 dstZ, GPUTexture* srcResource, uint32 srcSubresource) |
| 1558 | { |
| 1559 | ASSERT(dstResource && srcResource); |
| 1560 | const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); |
| 1561 | |
| 1562 | // Ensure to end active render pass |
| 1563 | if (cmdBuffer->IsInsideRenderPass()) |
| 1564 | EndRenderPass(); |
| 1565 | |
| 1566 | const auto dstTextureVulkan = static_cast<GPUTextureVulkan*>(dstResource); |
| 1567 | const auto srcTextureVulkan = static_cast<GPUTextureVulkan*>(srcResource); |
| 1568 | |
| 1569 | const int32 dstMipIndex = (int32)dstSubresource % dstTextureVulkan->MipLevels(); |
| 1570 | const int32 dstArrayIndex = (int32)dstSubresource / dstTextureVulkan->MipLevels(); |
| 1571 | const int32 srcMipIndex = (int32)srcSubresource % srcTextureVulkan->MipLevels(); |
| 1572 | const int32 srcArrayIndex = (int32)srcSubresource / srcTextureVulkan->MipLevels(); |
| 1573 | int32 mipWidth, mipHeight, mipDepth; |
| 1574 | srcTextureVulkan->GetMipSize(srcMipIndex, mipWidth, mipHeight, mipDepth); |
| 1575 | |
| 1576 | if (dstTextureVulkan->IsStaging()) |
| 1577 | { |
| 1578 | // Staging Texture -> Staging Texture |
| 1579 | if (srcTextureVulkan->IsStaging()) |
| 1580 | { |
| 1581 | ASSERT(dstTextureVulkan->StagingBuffer && srcTextureVulkan->StagingBuffer); |
| 1582 | CopyResource(dstTextureVulkan->StagingBuffer, srcTextureVulkan->StagingBuffer); |
| 1583 | } |
| 1584 | // Texture -> Staging Texture |
| 1585 | else |
| 1586 | { |
| 1587 | // Transition resources |
| 1588 | ASSERT(dstTextureVulkan->StagingBuffer); |
| 1589 | AddBufferBarrier(dstTextureVulkan->StagingBuffer, VK_ACCESS_TRANSFER_WRITE_BIT); |
| 1590 | AddImageBarrier(srcTextureVulkan, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
| 1591 | FlushBarriers(); |
| 1592 | |
| 1593 | // Copy |
| 1594 | VkBufferImageCopy region; |
| 1595 | Platform::MemoryClear(®ion, sizeof(VkBufferImageCopy)); |
| 1596 | region.bufferOffset = 0; // TODO: calculate it based on dstSubresource and dstX/dstY/dstZ |
| 1597 | ASSERT(dstX == dstY == dstZ == 0); |
| 1598 | ASSERT(dstSubresource == 0); |
| 1599 | region.bufferRowLength = mipWidth; |
| 1600 | region.bufferImageHeight = mipHeight; |
| 1601 | region.imageOffset.x = 0; |
| 1602 | region.imageOffset.y = 0; |
| 1603 | region.imageOffset.z = 0; |
| 1604 | region.imageExtent.width = mipWidth; |
| 1605 | region.imageExtent.height = mipHeight; |
| 1606 | region.imageExtent.depth = mipDepth; |
| 1607 | region.imageSubresource.baseArrayLayer = srcArrayIndex; |
| 1608 | region.imageSubresource.layerCount = 1; |
| 1609 | region.imageSubresource.mipLevel = srcMipIndex; |
| 1610 | region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| 1611 | vkCmdCopyImageToBuffer(cmdBuffer->GetHandle(), srcTextureVulkan->GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstTextureVulkan->StagingBuffer->GetHandle(), 1, ®ion); |
| 1612 | } |
| 1613 | } |
| 1614 | else |
no test coverage detected