| 1088 | } |
| 1089 | |
| 1090 | void VltContext::uploadImage( |
| 1091 | const Rc<VltImage>& image, |
| 1092 | const VkImageSubresourceLayers& subresources, |
| 1093 | const void* data, |
| 1094 | VkDeviceSize pitchPerRow, |
| 1095 | VkDeviceSize pitchPerLayer) |
| 1096 | { |
| 1097 | const VltFormatInfo* formatInfo = image->formatInfo(); |
| 1098 | |
| 1099 | VkOffset3D imageOffset = { 0, 0, 0 }; |
| 1100 | VkExtent3D imageExtent = image->mipLevelExtent(subresources.mipLevel); |
| 1101 | |
| 1102 | // Allocate staging buffer slice and copy data to it |
| 1103 | VkExtent3D elementCount = vutil::computeBlockCount( |
| 1104 | imageExtent, formatInfo->blockSize); |
| 1105 | elementCount.depth *= subresources.layerCount; |
| 1106 | |
| 1107 | auto stagingSlice = m_staging.alloc(formatInfo->elementSize * vutil::flattenImageExtent(elementCount), |
| 1108 | CACHE_LINE_SIZE); |
| 1109 | auto stagingHandle = stagingSlice.getSliceHandle(); |
| 1110 | |
| 1111 | vutil::packImageData(stagingHandle.mapPtr, data, |
| 1112 | elementCount, formatInfo->elementSize, |
| 1113 | pitchPerRow, pitchPerLayer); |
| 1114 | |
| 1115 | // Discard previous subresource contents |
| 1116 | m_transAcquires.accessImage(image, |
| 1117 | vutil::makeSubresourceRange(subresources), |
| 1118 | VK_IMAGE_LAYOUT_UNDEFINED, 0, 0, |
| 1119 | image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), |
| 1120 | VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 1121 | VK_ACCESS_TRANSFER_WRITE_BIT); |
| 1122 | |
| 1123 | m_transAcquires.recordCommands(m_cmd); |
| 1124 | |
| 1125 | // Perform copy on the transfer queue |
| 1126 | VkBufferImageCopy region; |
| 1127 | region.bufferOffset = stagingHandle.offset; |
| 1128 | region.bufferRowLength = 0; |
| 1129 | region.bufferImageHeight = 0; |
| 1130 | region.imageSubresource = subresources; |
| 1131 | region.imageOffset = imageOffset; |
| 1132 | region.imageExtent = imageExtent; |
| 1133 | |
| 1134 | m_cmd->cmdCopyBufferToImage(VltCmdType::TransferBuffer, |
| 1135 | stagingHandle.handle, image->handle(), |
| 1136 | image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), |
| 1137 | 1, ®ion); |
| 1138 | |
| 1139 | uint32_t acquireQueueFamily = m_cmd->type() == VltQueueType::Graphics |
| 1140 | ? m_device->queues().graphics.queueFamily |
| 1141 | : m_device->queues().compute.queueFamily; |
| 1142 | |
| 1143 | // Transfer ownership to graphics queue |
| 1144 | m_transBarriers.releaseImage(m_initBarriers, |
| 1145 | image, vutil::makeSubresourceRange(subresources), |
| 1146 | m_device->queues().transfer.queueFamily, |
| 1147 | image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), |
no test coverage detected