Fix for compressed textures when using CopyCommands2
Test: Running dEQP-VK.api.copy_and_blit.copy_commands2.image_to_image.all_formats.{eac|astc|etc).*
Bug: 300460096
Change-Id: I56b094411e7cf6dbe7323796338e4032c42ebd71
diff --git a/host/vulkan/VkDecoder.cpp b/host/vulkan/VkDecoder.cpp
index 6a23cb9..8d8692a 100644
--- a/host/vulkan/VkDecoder.cpp
+++ b/host/vulkan/VkDecoder.cpp
@@ -12001,15 +12001,12 @@
android::base::beginTrace("vkCmdCopyImage2 decode");
VkCommandBuffer commandBuffer;
const VkCopyImageInfo2* pCopyImageInfo;
- // Begin non wrapped dispatchable handle unboxing for commandBuffer;
+ // Begin global wrapped dispatchable handle unboxing for commandBuffer;
uint64_t cgen_var_0;
memcpy((uint64_t*)&cgen_var_0, *readStreamPtrPtr, 1 * 8);
*readStreamPtrPtr += 1 * 8;
*(VkCommandBuffer*)&commandBuffer =
(VkCommandBuffer)(VkCommandBuffer)((VkCommandBuffer)(*&cgen_var_0));
- auto unboxed_commandBuffer = unbox_VkCommandBuffer(commandBuffer);
- auto vk = dispatch_VkCommandBuffer(commandBuffer);
- // End manual dispatchable handle unboxing for commandBuffer;
vkReadStream->alloc((void**)&pCopyImageInfo, sizeof(const VkCopyImageInfo2));
reservedunmarshal_VkCopyImageInfo2(vkReadStream, VK_STRUCTURE_TYPE_MAX_ENUM,
(VkCopyImageInfo2*)(pCopyImageInfo),
@@ -12021,7 +12018,7 @@
fprintf(stderr, "stream %p: call vkCmdCopyImage2 0x%llx 0x%llx \n", ioStream,
(unsigned long long)commandBuffer, (unsigned long long)pCopyImageInfo);
}
- vk->vkCmdCopyImage2(unboxed_commandBuffer, pCopyImageInfo);
+ m_state->on_vkCmdCopyImage2(&m_pool, commandBuffer, pCopyImageInfo);
vkStream->unsetHandleMapping();
vkReadStream->setReadPos((uintptr_t)(*readStreamPtrPtr) -
(uintptr_t)snapshotTraceBegin);
@@ -12040,15 +12037,12 @@
android::base::beginTrace("vkCmdCopyBufferToImage2 decode");
VkCommandBuffer commandBuffer;
const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo;
- // Begin non wrapped dispatchable handle unboxing for commandBuffer;
+ // Begin global wrapped dispatchable handle unboxing for commandBuffer;
uint64_t cgen_var_0;
memcpy((uint64_t*)&cgen_var_0, *readStreamPtrPtr, 1 * 8);
*readStreamPtrPtr += 1 * 8;
*(VkCommandBuffer*)&commandBuffer =
(VkCommandBuffer)(VkCommandBuffer)((VkCommandBuffer)(*&cgen_var_0));
- auto unboxed_commandBuffer = unbox_VkCommandBuffer(commandBuffer);
- auto vk = dispatch_VkCommandBuffer(commandBuffer);
- // End manual dispatchable handle unboxing for commandBuffer;
vkReadStream->alloc((void**)&pCopyBufferToImageInfo,
sizeof(const VkCopyBufferToImageInfo2));
reservedunmarshal_VkCopyBufferToImageInfo2(
@@ -12063,7 +12057,8 @@
ioStream, (unsigned long long)commandBuffer,
(unsigned long long)pCopyBufferToImageInfo);
}
- vk->vkCmdCopyBufferToImage2(unboxed_commandBuffer, pCopyBufferToImageInfo);
+ m_state->on_vkCmdCopyBufferToImage2(&m_pool, commandBuffer, pCopyBufferToImageInfo,
+ context);
vkStream->unsetHandleMapping();
vkReadStream->setReadPos((uintptr_t)(*readStreamPtrPtr) -
(uintptr_t)snapshotTraceBegin);
@@ -12083,15 +12078,12 @@
android::base::beginTrace("vkCmdCopyImageToBuffer2 decode");
VkCommandBuffer commandBuffer;
const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo;
- // Begin non wrapped dispatchable handle unboxing for commandBuffer;
+ // Begin global wrapped dispatchable handle unboxing for commandBuffer;
uint64_t cgen_var_0;
memcpy((uint64_t*)&cgen_var_0, *readStreamPtrPtr, 1 * 8);
*readStreamPtrPtr += 1 * 8;
*(VkCommandBuffer*)&commandBuffer =
(VkCommandBuffer)(VkCommandBuffer)((VkCommandBuffer)(*&cgen_var_0));
- auto unboxed_commandBuffer = unbox_VkCommandBuffer(commandBuffer);
- auto vk = dispatch_VkCommandBuffer(commandBuffer);
- // End manual dispatchable handle unboxing for commandBuffer;
vkReadStream->alloc((void**)&pCopyImageToBufferInfo,
sizeof(const VkCopyImageToBufferInfo2));
reservedunmarshal_VkCopyImageToBufferInfo2(
@@ -12106,7 +12098,7 @@
ioStream, (unsigned long long)commandBuffer,
(unsigned long long)pCopyImageToBufferInfo);
}
- vk->vkCmdCopyImageToBuffer2(unboxed_commandBuffer, pCopyImageToBufferInfo);
+ m_state->on_vkCmdCopyImageToBuffer2(&m_pool, commandBuffer, pCopyImageToBufferInfo);
vkStream->unsetHandleMapping();
vkReadStream->setReadPos((uintptr_t)(*readStreamPtrPtr) -
(uintptr_t)snapshotTraceBegin);
@@ -22311,15 +22303,12 @@
android::base::beginTrace("vkCmdCopyImage2KHR decode");
VkCommandBuffer commandBuffer;
const VkCopyImageInfo2* pCopyImageInfo;
- // Begin non wrapped dispatchable handle unboxing for commandBuffer;
+ // Begin global wrapped dispatchable handle unboxing for commandBuffer;
uint64_t cgen_var_0;
memcpy((uint64_t*)&cgen_var_0, *readStreamPtrPtr, 1 * 8);
*readStreamPtrPtr += 1 * 8;
*(VkCommandBuffer*)&commandBuffer =
(VkCommandBuffer)(VkCommandBuffer)((VkCommandBuffer)(*&cgen_var_0));
- auto unboxed_commandBuffer = unbox_VkCommandBuffer(commandBuffer);
- auto vk = dispatch_VkCommandBuffer(commandBuffer);
- // End manual dispatchable handle unboxing for commandBuffer;
vkReadStream->alloc((void**)&pCopyImageInfo, sizeof(const VkCopyImageInfo2));
reservedunmarshal_VkCopyImageInfo2(vkReadStream, VK_STRUCTURE_TYPE_MAX_ENUM,
(VkCopyImageInfo2*)(pCopyImageInfo),
@@ -22331,7 +22320,7 @@
fprintf(stderr, "stream %p: call vkCmdCopyImage2KHR 0x%llx 0x%llx \n", ioStream,
(unsigned long long)commandBuffer, (unsigned long long)pCopyImageInfo);
}
- vk->vkCmdCopyImage2KHR(unboxed_commandBuffer, pCopyImageInfo);
+ m_state->on_vkCmdCopyImage2KHR(&m_pool, commandBuffer, pCopyImageInfo);
vkStream->unsetHandleMapping();
vkReadStream->setReadPos((uintptr_t)(*readStreamPtrPtr) -
(uintptr_t)snapshotTraceBegin);
@@ -22350,15 +22339,12 @@
android::base::beginTrace("vkCmdCopyBufferToImage2KHR decode");
VkCommandBuffer commandBuffer;
const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo;
- // Begin non wrapped dispatchable handle unboxing for commandBuffer;
+ // Begin global wrapped dispatchable handle unboxing for commandBuffer;
uint64_t cgen_var_0;
memcpy((uint64_t*)&cgen_var_0, *readStreamPtrPtr, 1 * 8);
*readStreamPtrPtr += 1 * 8;
*(VkCommandBuffer*)&commandBuffer =
(VkCommandBuffer)(VkCommandBuffer)((VkCommandBuffer)(*&cgen_var_0));
- auto unboxed_commandBuffer = unbox_VkCommandBuffer(commandBuffer);
- auto vk = dispatch_VkCommandBuffer(commandBuffer);
- // End manual dispatchable handle unboxing for commandBuffer;
vkReadStream->alloc((void**)&pCopyBufferToImageInfo,
sizeof(const VkCopyBufferToImageInfo2));
reservedunmarshal_VkCopyBufferToImageInfo2(
@@ -22373,7 +22359,8 @@
ioStream, (unsigned long long)commandBuffer,
(unsigned long long)pCopyBufferToImageInfo);
}
- vk->vkCmdCopyBufferToImage2KHR(unboxed_commandBuffer, pCopyBufferToImageInfo);
+ m_state->on_vkCmdCopyBufferToImage2KHR(&m_pool, commandBuffer,
+ pCopyBufferToImageInfo, context);
vkStream->unsetHandleMapping();
vkReadStream->setReadPos((uintptr_t)(*readStreamPtrPtr) -
(uintptr_t)snapshotTraceBegin);
@@ -22393,15 +22380,12 @@
android::base::beginTrace("vkCmdCopyImageToBuffer2KHR decode");
VkCommandBuffer commandBuffer;
const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo;
- // Begin non wrapped dispatchable handle unboxing for commandBuffer;
+ // Begin global wrapped dispatchable handle unboxing for commandBuffer;
uint64_t cgen_var_0;
memcpy((uint64_t*)&cgen_var_0, *readStreamPtrPtr, 1 * 8);
*readStreamPtrPtr += 1 * 8;
*(VkCommandBuffer*)&commandBuffer =
(VkCommandBuffer)(VkCommandBuffer)((VkCommandBuffer)(*&cgen_var_0));
- auto unboxed_commandBuffer = unbox_VkCommandBuffer(commandBuffer);
- auto vk = dispatch_VkCommandBuffer(commandBuffer);
- // End manual dispatchable handle unboxing for commandBuffer;
vkReadStream->alloc((void**)&pCopyImageToBufferInfo,
sizeof(const VkCopyImageToBufferInfo2));
reservedunmarshal_VkCopyImageToBufferInfo2(
@@ -22416,7 +22400,8 @@
ioStream, (unsigned long long)commandBuffer,
(unsigned long long)pCopyImageToBufferInfo);
}
- vk->vkCmdCopyImageToBuffer2KHR(unboxed_commandBuffer, pCopyImageToBufferInfo);
+ m_state->on_vkCmdCopyImageToBuffer2KHR(&m_pool, commandBuffer,
+ pCopyImageToBufferInfo);
vkStream->unsetHandleMapping();
vkReadStream->setReadPos((uintptr_t)(*readStreamPtrPtr) -
(uintptr_t)snapshotTraceBegin);
diff --git a/host/vulkan/VkDecoderGlobalState.cpp b/host/vulkan/VkDecoderGlobalState.cpp
index 608a757..aabd957 100644
--- a/host/vulkan/VkDecoderGlobalState.cpp
+++ b/host/vulkan/VkDecoderGlobalState.cpp
@@ -2717,6 +2717,152 @@
}
}
+ void on_vkCmdCopyImage2(android::base::BumpPool* pool,
+ VkCommandBuffer boxed_commandBuffer,
+ const VkCopyImageInfo2* pCopyImageInfo) {
+ auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
+ auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
+
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ auto* srcImg = android::base::find(mImageInfo, pCopyImageInfo->srcImage);
+ auto* dstImg = android::base::find(mImageInfo, pCopyImageInfo->dstImage);
+ if (!srcImg || !dstImg) return;
+
+ VkDevice device = srcImg->cmpInfo.device();
+ auto* deviceInfo = android::base::find(mDeviceInfo, device);
+ if (!deviceInfo) return;
+
+ bool needEmulatedSrc = deviceInfo->needEmulatedDecompression(srcImg->cmpInfo);
+ bool needEmulatedDst = deviceInfo->needEmulatedDecompression(dstImg->cmpInfo);
+ if (!needEmulatedSrc && !needEmulatedDst) {
+ vk->vkCmdCopyImage2(commandBuffer, pCopyImageInfo);
+ return;
+ }
+ VkImage srcImageMip = pCopyImageInfo->srcImage;
+ VkImage dstImageMip = pCopyImageInfo->dstImage;
+ for (uint32_t r = 0; r < pCopyImageInfo->regionCount; r++) {
+ if (needEmulatedSrc) {
+ srcImageMip = srcImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].srcSubresource.mipLevel);
+ }
+ if (needEmulatedDst) {
+ dstImageMip = dstImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].dstSubresource.mipLevel);
+ }
+
+ VkCopyImageInfo2 inf2 = *pCopyImageInfo;
+ inf2.regionCount = 1;
+ inf2.srcImage = srcImageMip;
+ inf2.dstImage = dstImageMip;
+
+ VkImageCopy2 region = CompressedImageInfo::getCompressedMipmapsImageCopy(
+ pCopyImageInfo->pRegions[r], srcImg->cmpInfo, dstImg->cmpInfo, needEmulatedSrc, needEmulatedDst);
+ inf2.pRegions = ®ion;
+
+ vk->vkCmdCopyImage2(commandBuffer, &inf2);
+ }
+ }
+
+ void on_vkCmdCopyImageToBuffer2(android::base::BumpPool* pool,
+ VkCommandBuffer boxed_commandBuffer,
+ const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
+ auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
+ auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
+
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ auto* imageInfo = android::base::find(mImageInfo, pCopyImageToBufferInfo->srcImage);
+ auto* bufferInfo = android::base::find(mBufferInfo, pCopyImageToBufferInfo->dstBuffer);
+ if (!imageInfo || !bufferInfo) return;
+ auto* deviceInfo = android::base::find(mDeviceInfo, bufferInfo->device);
+ if (!deviceInfo) return;
+ CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
+ if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
+ vk->vkCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo);
+ return;
+ }
+ for (uint32_t r = 0; r < pCopyImageToBufferInfo->regionCount; r++) {
+ uint32_t mipLevel = pCopyImageToBufferInfo->pRegions[r].imageSubresource.mipLevel;
+ VkBufferImageCopy2 region = cmpInfo.getBufferImageCopy(pCopyImageToBufferInfo->pRegions[r]);
+ VkCopyImageToBufferInfo2 inf = *pCopyImageToBufferInfo;
+ inf.regionCount = 1;
+ inf.pRegions = ®ion;
+ inf.srcImage = cmpInfo.compressedMipmap(mipLevel);
+
+ vk->vkCmdCopyImageToBuffer2(commandBuffer, &inf);
+ }
+ }
+
+ void on_vkCmdCopyImage2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer boxed_commandBuffer,
+ const VkCopyImageInfo2KHR* pCopyImageInfo) {
+ auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
+ auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
+
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ auto* srcImg = android::base::find(mImageInfo, pCopyImageInfo->srcImage);
+ auto* dstImg = android::base::find(mImageInfo, pCopyImageInfo->dstImage);
+ if (!srcImg || !dstImg) return;
+
+ VkDevice device = srcImg->cmpInfo.device();
+ auto* deviceInfo = android::base::find(mDeviceInfo, device);
+ if (!deviceInfo) return;
+
+ bool needEmulatedSrc = deviceInfo->needEmulatedDecompression(srcImg->cmpInfo);
+ bool needEmulatedDst = deviceInfo->needEmulatedDecompression(dstImg->cmpInfo);
+ if (!needEmulatedSrc && !needEmulatedDst) {
+ vk->vkCmdCopyImage2KHR(commandBuffer, pCopyImageInfo);
+ return;
+ }
+ VkImage srcImageMip = pCopyImageInfo->srcImage;
+ VkImage dstImageMip = pCopyImageInfo->dstImage;
+ for (uint32_t r = 0; r < pCopyImageInfo->regionCount; r++) {
+ if (needEmulatedSrc) {
+ srcImageMip = srcImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].srcSubresource.mipLevel);
+ }
+ if (needEmulatedDst) {
+ dstImageMip = dstImg->cmpInfo.compressedMipmap(pCopyImageInfo->pRegions[r].dstSubresource.mipLevel);
+ }
+
+ VkCopyImageInfo2KHR inf2 = *pCopyImageInfo;
+ inf2.regionCount = 1;
+ inf2.srcImage = srcImageMip;
+ inf2.dstImage = dstImageMip;
+
+ VkImageCopy2KHR region = CompressedImageInfo::getCompressedMipmapsImageCopy(
+ pCopyImageInfo->pRegions[r], srcImg->cmpInfo, dstImg->cmpInfo, needEmulatedSrc, needEmulatedDst);
+ inf2.pRegions = ®ion;
+
+ vk->vkCmdCopyImage2KHR(commandBuffer, &inf2);
+ }
+ }
+
+ void on_vkCmdCopyImageToBuffer2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer boxed_commandBuffer,
+ const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo) {
+ auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
+ auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
+
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ auto* imageInfo = android::base::find(mImageInfo, pCopyImageToBufferInfo->srcImage);
+ auto* bufferInfo = android::base::find(mBufferInfo, pCopyImageToBufferInfo->dstBuffer);
+ if (!imageInfo || !bufferInfo) return;
+ auto* deviceInfo = android::base::find(mDeviceInfo, bufferInfo->device);
+ if (!deviceInfo) return;
+ CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
+ if (!deviceInfo->needEmulatedDecompression(cmpInfo)) {
+ vk->vkCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo);
+ return;
+ }
+ for (uint32_t r = 0; r < pCopyImageToBufferInfo->regionCount; r++) {
+ uint32_t mipLevel = pCopyImageToBufferInfo->pRegions[r].imageSubresource.mipLevel;
+ VkBufferImageCopy2KHR region = cmpInfo.getBufferImageCopy(pCopyImageToBufferInfo->pRegions[r]);
+ VkCopyImageToBufferInfo2KHR inf = *pCopyImageToBufferInfo;
+ inf.regionCount = 1;
+ inf.pRegions = ®ion;
+ inf.srcImage = cmpInfo.compressedMipmap(mipLevel);
+
+ vk->vkCmdCopyImageToBuffer2KHR(commandBuffer, &inf);
+ }
+ }
+
void on_vkGetImageMemoryRequirements(android::base::BumpPool* pool, VkDevice boxed_device,
VkImage image, VkMemoryRequirements* pMemoryRequirements) {
auto device = unbox_VkDevice(boxed_device);
@@ -2857,6 +3003,120 @@
}
}
+ void on_vkCmdCopyBufferToImage2(android::base::BumpPool* pool,
+ VkCommandBuffer boxed_commandBuffer,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
+ const VkDecoderContext& context) {
+ auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
+ auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
+
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ auto* imageInfo = android::base::find(mImageInfo, pCopyBufferToImageInfo->dstImage);
+ if (!imageInfo) return;
+ auto* bufferInfo = android::base::find(mBufferInfo, pCopyBufferToImageInfo->srcBuffer);
+ if (!bufferInfo) {
+ return;
+ }
+ VkDevice device = bufferInfo->device;
+ auto* deviceInfo = android::base::find(mDeviceInfo, device);
+ if (!deviceInfo) {
+ return;
+ }
+ if (!deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
+ vk->vkCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo);
+ return;
+ }
+ auto* cmdBufferInfo = android::base::find(mCmdBufferInfo, commandBuffer);
+ if (!cmdBufferInfo) {
+ return;
+ }
+ CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
+
+ for (uint32_t r = 0; r < pCopyBufferToImageInfo->regionCount; r++) {
+ VkCopyBufferToImageInfo2 inf;
+ uint32_t mipLevel = pCopyBufferToImageInfo->pRegions[r].imageSubresource.mipLevel;
+ inf.dstImage = cmpInfo.compressedMipmap(mipLevel);
+ VkBufferImageCopy2 region = cmpInfo.getBufferImageCopy(pCopyBufferToImageInfo->pRegions[r]);
+ inf.regionCount = 1;
+ inf.pRegions = ®ion;
+
+ vk->vkCmdCopyBufferToImage2(commandBuffer, &inf);
+ }
+
+ if (cmpInfo.canDecompressOnCpu()) {
+ // Get a pointer to the compressed image memory
+ const MemoryInfo* memoryInfo = android::base::find(mMemoryInfo, bufferInfo->memory);
+ if (!memoryInfo) {
+ WARN("ASTC CPU decompression: couldn't find mapped memory info");
+ return;
+ }
+ if (!memoryInfo->ptr) {
+ WARN("ASTC CPU decompression: VkBuffer memory isn't host-visible");
+ return;
+ }
+ uint8_t* astcData = (uint8_t*)(memoryInfo->ptr) + bufferInfo->memoryOffset;
+
+ cmpInfo.decompressOnCpu(commandBuffer, astcData, bufferInfo->size, pCopyBufferToImageInfo, context);
+ }
+ }
+
+ void on_vkCmdCopyBufferToImage2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer boxed_commandBuffer,
+ const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo,
+ const VkDecoderContext& context) {
+ auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
+ auto vk = dispatch_VkCommandBuffer(boxed_commandBuffer);
+
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+ auto* imageInfo = android::base::find(mImageInfo, pCopyBufferToImageInfo->dstImage);
+ if (!imageInfo) return;
+ auto* bufferInfo = android::base::find(mBufferInfo, pCopyBufferToImageInfo->srcBuffer);
+ if (!bufferInfo) {
+ return;
+ }
+ VkDevice device = bufferInfo->device;
+ auto* deviceInfo = android::base::find(mDeviceInfo, device);
+ if (!deviceInfo) {
+ return;
+ }
+ if (!deviceInfo->needEmulatedDecompression(imageInfo->cmpInfo)) {
+ vk->vkCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo);
+ return;
+ }
+ auto* cmdBufferInfo = android::base::find(mCmdBufferInfo, commandBuffer);
+ if (!cmdBufferInfo) {
+ return;
+ }
+ CompressedImageInfo& cmpInfo = imageInfo->cmpInfo;
+
+ for (uint32_t r = 0; r < pCopyBufferToImageInfo->regionCount; r++) {
+ VkCopyBufferToImageInfo2KHR inf;
+ uint32_t mipLevel = pCopyBufferToImageInfo->pRegions[r].imageSubresource.mipLevel;
+ inf.dstImage = cmpInfo.compressedMipmap(mipLevel);
+ VkBufferImageCopy2KHR region = cmpInfo.getBufferImageCopy(pCopyBufferToImageInfo->pRegions[r]);
+ inf.regionCount = 1;
+ inf.pRegions = ®ion;
+
+ vk->vkCmdCopyBufferToImage2KHR(commandBuffer, &inf);
+ }
+
+ if (cmpInfo.canDecompressOnCpu()) {
+ // Get a pointer to the compressed image memory
+ const MemoryInfo* memoryInfo = android::base::find(mMemoryInfo, bufferInfo->memory);
+ if (!memoryInfo) {
+ WARN("ASTC CPU decompression: couldn't find mapped memory info");
+ return;
+ }
+ if (!memoryInfo->ptr) {
+ WARN("ASTC CPU decompression: VkBuffer memory isn't host-visible");
+ return;
+ }
+ uint8_t* astcData = (uint8_t*)(memoryInfo->ptr) + bufferInfo->memoryOffset;
+
+ cmpInfo.decompressOnCpu(commandBuffer, astcData, bufferInfo->size, pCopyBufferToImageInfo, context);
+ }
+ }
+
inline void convertQueueFamilyForeignToExternal(uint32_t* queueFamilyIndexPtr) {
if (*queueFamilyIndexPtr == VK_QUEUE_FAMILY_FOREIGN_EXT) {
*queueFamilyIndexPtr = VK_QUEUE_FAMILY_EXTERNAL;
@@ -6912,6 +7172,44 @@
regionCount, pRegions);
}
+void VkDecoderGlobalState::on_vkCmdCopyBufferToImage2(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
+ const VkDecoderContext& context) {
+ mImpl->on_vkCmdCopyBufferToImage2(pool, commandBuffer, pCopyBufferToImageInfo, context);
+}
+
+void VkDecoderGlobalState::on_vkCmdCopyImage2(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageInfo2* pCopyImageInfo) {
+ mImpl->on_vkCmdCopyImage2(pool, commandBuffer, pCopyImageInfo);
+}
+
+void VkDecoderGlobalState::on_vkCmdCopyImageToBuffer2(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo) {
+ mImpl->on_vkCmdCopyImageToBuffer2(pool, commandBuffer, pCopyImageToBufferInfo);
+}
+
+void VkDecoderGlobalState::on_vkCmdCopyBufferToImage2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo,
+ const VkDecoderContext& context) {
+ mImpl->on_vkCmdCopyBufferToImage2KHR(pool, commandBuffer, pCopyBufferToImageInfo, context);
+}
+
+void VkDecoderGlobalState::on_vkCmdCopyImage2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageInfo2KHR* pCopyImageInfo) {
+ mImpl->on_vkCmdCopyImage2KHR(pool, commandBuffer, pCopyImageInfo);
+}
+
+void VkDecoderGlobalState::on_vkCmdCopyImageToBuffer2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo) {
+ mImpl->on_vkCmdCopyImageToBuffer2KHR(pool, commandBuffer, pCopyImageToBufferInfo);
+}
+
void VkDecoderGlobalState::on_vkGetImageMemoryRequirements(
android::base::BumpPool* pool, VkDevice device, VkImage image,
VkMemoryRequirements* pMemoryRequirements) {
diff --git a/host/vulkan/VkDecoderGlobalState.h b/host/vulkan/VkDecoderGlobalState.h
index 7eec8e1..7706fd0 100644
--- a/host/vulkan/VkDecoderGlobalState.h
+++ b/host/vulkan/VkDecoderGlobalState.h
@@ -319,6 +319,30 @@
VkBuffer dstBuffer, uint32_t regionCount,
const VkBufferImageCopy* pRegions);
+ void on_vkCmdCopyBufferToImage2(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
+ const VkDecoderContext& context);
+
+ void on_vkCmdCopyImage2(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageInfo2* pCopyImageInfo);
+ void on_vkCmdCopyImageToBuffer2(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo);
+
+ void on_vkCmdCopyBufferToImage2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo,
+ const VkDecoderContext& context);
+
+ void on_vkCmdCopyImage2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageInfo2KHR* pCopyImageInfo);
+ void on_vkCmdCopyImageToBuffer2KHR(android::base::BumpPool* pool,
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo);
+
void on_vkGetImageMemoryRequirements(android::base::BumpPool* pool, VkDevice device,
VkImage image, VkMemoryRequirements* pMemoryRequirements);
diff --git a/host/vulkan/VkSubDecoder.cpp b/host/vulkan/VkSubDecoder.cpp
index 4b4a1f4..08c919f 100644
--- a/host/vulkan/VkSubDecoder.cpp
+++ b/host/vulkan/VkSubDecoder.cpp
@@ -1680,7 +1680,8 @@
transform_tohost_VkCopyImageInfo2(globalstate,
(VkCopyImageInfo2*)(pCopyImageInfo));
}
- vk->vkCmdCopyImage2((VkCommandBuffer)dispatchHandle, pCopyImageInfo);
+ this->on_vkCmdCopyImage2(pool, (VkCommandBuffer)(boxed_dispatchHandle),
+ pCopyImageInfo);
android::base::endTrace();
break;
}
@@ -1696,8 +1697,8 @@
transform_tohost_VkCopyBufferToImageInfo2(
globalstate, (VkCopyBufferToImageInfo2*)(pCopyBufferToImageInfo));
}
- vk->vkCmdCopyBufferToImage2((VkCommandBuffer)dispatchHandle,
- pCopyBufferToImageInfo);
+ this->on_vkCmdCopyBufferToImage2(pool, (VkCommandBuffer)(boxed_dispatchHandle),
+ pCopyBufferToImageInfo, context);
android::base::endTrace();
break;
}
@@ -1713,8 +1714,8 @@
transform_tohost_VkCopyImageToBufferInfo2(
globalstate, (VkCopyImageToBufferInfo2*)(pCopyImageToBufferInfo));
}
- vk->vkCmdCopyImageToBuffer2((VkCommandBuffer)dispatchHandle,
- pCopyImageToBufferInfo);
+ this->on_vkCmdCopyImageToBuffer2(pool, (VkCommandBuffer)(boxed_dispatchHandle),
+ pCopyImageToBufferInfo);
android::base::endTrace();
break;
}
@@ -2742,7 +2743,8 @@
transform_tohost_VkCopyImageInfo2(globalstate,
(VkCopyImageInfo2*)(pCopyImageInfo));
}
- vk->vkCmdCopyImage2KHR((VkCommandBuffer)dispatchHandle, pCopyImageInfo);
+ this->on_vkCmdCopyImage2KHR(pool, (VkCommandBuffer)(boxed_dispatchHandle),
+ pCopyImageInfo);
android::base::endTrace();
break;
}
@@ -2758,8 +2760,8 @@
transform_tohost_VkCopyBufferToImageInfo2(
globalstate, (VkCopyBufferToImageInfo2*)(pCopyBufferToImageInfo));
}
- vk->vkCmdCopyBufferToImage2KHR((VkCommandBuffer)dispatchHandle,
- pCopyBufferToImageInfo);
+ this->on_vkCmdCopyBufferToImage2KHR(pool, (VkCommandBuffer)(boxed_dispatchHandle),
+ pCopyBufferToImageInfo, context);
android::base::endTrace();
break;
}
@@ -2775,8 +2777,8 @@
transform_tohost_VkCopyImageToBufferInfo2(
globalstate, (VkCopyImageToBufferInfo2*)(pCopyImageToBufferInfo));
}
- vk->vkCmdCopyImageToBuffer2KHR((VkCommandBuffer)dispatchHandle,
- pCopyImageToBufferInfo);
+ this->on_vkCmdCopyImageToBuffer2KHR(pool, (VkCommandBuffer)(boxed_dispatchHandle),
+ pCopyImageToBufferInfo);
android::base::endTrace();
break;
}
diff --git a/host/vulkan/emulated_textures/AstcTexture.cpp b/host/vulkan/emulated_textures/AstcTexture.cpp
index b7c1ecf..0749da2 100644
--- a/host/vulkan/emulated_textures/AstcTexture.cpp
+++ b/host/vulkan/emulated_textures/AstcTexture.cpp
@@ -157,13 +157,14 @@
}
}
-void AstcTexture::on_vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, uint8_t* srcAstcData,
+template<typename T>
+void AstcTexture::on_vkCmdCopyBufferToImageImpl(VkCommandBuffer commandBuffer, uint8_t* srcAstcData,
size_t astcDataSize, VkImage dstImage,
VkImageLayout dstImageLayout, uint32_t regionCount,
- const VkBufferImageCopy* pRegions,
+ const T* pRegions,
const VkDecoderContext& context) {
auto watchdog =
- WATCHDOG_BUILDER(context.healthMonitor, "AstcTexture::on_vkCmdCopyBufferToImage").build();
+ WATCHDOG_BUILDER(context.healthMonitor, "AstcTexture::on_vkCmdCopyBufferToImageImpl").build();
auto start_time = std::chrono::steady_clock::now();
mSuccess = false;
size_t decompSize = 0; // How many bytes we need to hold the decompressed data
@@ -180,7 +181,17 @@
// Make a copy of the regions and update the buffer offset of each to reflect the
// correct location of the decompressed data
- std::vector<VkBufferImageCopy> decompRegions(pRegions, pRegions + regionCount);
+ std::vector<VkBufferImageCopy> decompRegions(regionCount);
+ for (size_t i = 0; i < regionCount; ++i) {
+ decompRegions[i] = VkBufferImageCopy {
+ pRegions[i].bufferOffset,
+ pRegions[i].bufferRowLength,
+ pRegions[i].bufferImageHeight,
+ pRegions[i].imageSubresource,
+ pRegions[i].imageOffset,
+ pRegions[i].imageExtent
+ };
+ }
for (auto& decompRegion : decompRegions) {
const uint32_t mipLevel = decompRegion.imageSubresource.mipLevel;
const uint32_t width = mipmapSize(mImgSize.width, mipLevel);
@@ -255,5 +266,26 @@
}
}
+void AstcTexture::on_vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, uint8_t* srcAstcData,
+ size_t astcDataSize, VkImage dstImage,
+ VkImageLayout dstImageLayout, uint32_t regionCount,
+ const VkBufferImageCopy* pRegions,
+ const VkDecoderContext& context) {
+ on_vkCmdCopyBufferToImageImpl(commandBuffer, srcAstcData, astcDataSize, dstImage, dstImageLayout, regionCount, pRegions, context);
+}
+
+void AstcTexture::on_vkCmdCopyBufferToImage2(VkCommandBuffer commandBuffer, uint8_t* srcAstcData,
+ size_t astcDataSize, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
+ const VkDecoderContext& context) {
+ on_vkCmdCopyBufferToImageImpl(commandBuffer,
+ srcAstcData,
+ astcDataSize,
+ pCopyBufferToImageInfo->dstImage,
+ pCopyBufferToImageInfo->dstImageLayout,
+ pCopyBufferToImageInfo->regionCount,
+ pCopyBufferToImageInfo->pRegions,
+ context);
+}
+
} // namespace vk
} // namespace gfxstream
diff --git a/host/vulkan/emulated_textures/AstcTexture.h b/host/vulkan/emulated_textures/AstcTexture.h
index 5aa688d..3fead51 100644
--- a/host/vulkan/emulated_textures/AstcTexture.h
+++ b/host/vulkan/emulated_textures/AstcTexture.h
@@ -41,8 +41,19 @@
VkImageLayout dstImageLayout, uint32_t regionCount,
const VkBufferImageCopy* pRegions,
const VkDecoderContext& context);
+ void on_vkCmdCopyBufferToImage2(VkCommandBuffer commandBuffer, uint8_t* srcAstcData,
+ size_t astcDataSize, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo,
+ const VkDecoderContext& context);
private:
+
+ template<typename T>
+ void on_vkCmdCopyBufferToImageImpl(VkCommandBuffer commandBuffer, uint8_t* srcAstcData,
+ size_t astcDataSize, VkImage dstImage,
+ VkImageLayout dstImageLayout, uint32_t regionCount,
+ const T* pRegions,
+ const VkDecoderContext& context);
+
uint8_t* createVkBufferAndMapMemory(size_t bufferSize);
void destroyVkBuffer();
diff --git a/host/vulkan/emulated_textures/CompressedImageInfo.cpp b/host/vulkan/emulated_textures/CompressedImageInfo.cpp
index 40e9b7c..6e179b3 100644
--- a/host/vulkan/emulated_textures/CompressedImageInfo.cpp
+++ b/host/vulkan/emulated_textures/CompressedImageInfo.cpp
@@ -513,6 +513,11 @@
dstImageLayout, regionCount, pRegions, context);
}
+void CompressedImageInfo::decompressOnCpu(VkCommandBuffer commandBuffer, uint8_t* srcAstcData, size_t astcDataSize,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo, const VkDecoderContext& context) {
+ mAstcTexture->on_vkCmdCopyBufferToImage2(commandBuffer, srcAstcData, astcDataSize, pCopyBufferToImageInfo, context);
+}
+
VkMemoryRequirements CompressedImageInfo::getMemoryRequirements() const {
return mMemoryRequirements;
}
@@ -541,6 +546,19 @@
return region;
}
+VkBufferImageCopy2 CompressedImageInfo::getBufferImageCopy(
+ const VkBufferImageCopy2& origRegion) const {
+ VkBufferImageCopy2 region = origRegion;
+ uint32_t mipLevel = region.imageSubresource.mipLevel;
+ region.imageSubresource.mipLevel = 0;
+ region.bufferRowLength /= mBlock.width;
+ region.bufferImageHeight /= mBlock.height;
+ region.imageOffset.x /= mBlock.width;
+ region.imageOffset.y /= mBlock.height;
+ region.imageExtent = compressedMipmapPortion(region.imageExtent, mipLevel);
+ return region;
+}
+
// static
VkImageCopy CompressedImageInfo::getCompressedMipmapsImageCopy(const VkImageCopy& origRegion,
const CompressedImageInfo& srcImg,
@@ -563,6 +581,27 @@
return region;
}
+VkImageCopy2 CompressedImageInfo::getCompressedMipmapsImageCopy(const VkImageCopy2& origRegion,
+ const CompressedImageInfo& srcImg,
+ const CompressedImageInfo& dstImg,
+ bool needEmulatedSrc,
+ bool needEmulatedDst) {
+ VkImageCopy2 region = origRegion;
+ if (needEmulatedSrc) {
+ uint32_t mipLevel = region.srcSubresource.mipLevel;
+ region.srcSubresource.mipLevel = 0;
+ region.srcOffset.x /= srcImg.mBlock.width;
+ region.srcOffset.y /= srcImg.mBlock.height;
+ region.extent = srcImg.compressedMipmapPortion(region.extent, mipLevel);
+ }
+ if (needEmulatedDst) {
+ region.dstSubresource.mipLevel = 0;
+ region.dstOffset.x /= dstImg.mBlock.width;
+ region.dstOffset.y /= dstImg.mBlock.height;
+ }
+ return region;
+}
+
void CompressedImageInfo::destroy(VulkanDispatch* vk) {
for (const auto& image : mCompressedMipmaps) {
vk->vkDestroyImage(mDevice, image, nullptr);
diff --git a/host/vulkan/emulated_textures/CompressedImageInfo.h b/host/vulkan/emulated_textures/CompressedImageInfo.h
index 9d75ad1..0f0ddfa 100644
--- a/host/vulkan/emulated_textures/CompressedImageInfo.h
+++ b/host/vulkan/emulated_textures/CompressedImageInfo.h
@@ -20,7 +20,6 @@
#include <vector>
#include "host/vulkan/emulated_textures/AstcTexture.h"
-#include "host/vulkan/emulated_textures/AstcTexture.h"
#include "host/vulkan/emulated_textures/GpuDecompressionPipeline.h"
#include "vulkan/cereal/common/goldfish_vk_dispatch.h"
#include "vulkan/vulkan.h"
@@ -47,6 +46,11 @@
const CompressedImageInfo& srcImg,
const CompressedImageInfo& dstImg,
bool needEmulatedSrc, bool needEmulatedDst);
+ static VkImageCopy2 getCompressedMipmapsImageCopy(const VkImageCopy2& origRegion,
+ const CompressedImageInfo& srcImg,
+ const CompressedImageInfo& dstImg,
+ bool needEmulatedSrc, bool needEmulatedDst);
+
// Constructors
@@ -87,6 +91,9 @@
VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
const VkBufferImageCopy* pRegions, const VkDecoderContext& context);
+ void decompressOnCpu(VkCommandBuffer commandBuffer, uint8_t* srcAstcData, size_t astcDataSize,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo, const VkDecoderContext& context);
+
VkMemoryRequirements getMemoryRequirements() const;
VkResult bindCompressedMipmapsMemory(VulkanDispatch* vk, VkDeviceMemory memory,
@@ -95,6 +102,7 @@
// Given a VkBufferImageCopy object for the original image, returns a new
// VkBufferImageCopy that points to the same location in the compressed mipmap images.
VkBufferImageCopy getBufferImageCopy(const VkBufferImageCopy& origRegion) const;
+ VkBufferImageCopy2 getBufferImageCopy(const VkBufferImageCopy2& origRegion) const;
// Releases all the resources used by this class. It may no longer be used after calling this.
void destroy(VulkanDispatch* vk);