diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 5692d2096..9e05c386e 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1265,44 +1265,30 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) const SwapchainInfo &swapInfo = *swaprecord->swapInfo; - // since this happens during capture, we don't want to start serialising extra image creates, + // since this happens during capture, we don't want to start serialising extra buffer creates, // so we manually create & then just wrap. - VkImage readbackIm = VK_NULL_HANDLE; + VkBuffer readbackBuf = VK_NULL_HANDLE; VkResult vkr = VK_SUCCESS; - // create identical image - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + // create readback buffer + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, - swapInfo.format, - {swapInfo.extent.width, swapInfo.extent.height, 1}, - 1, - 1, - VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_LINEAR, - VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, - NULL, - VK_IMAGE_LAYOUT_UNDEFINED, + GetByteSize(swapInfo.extent.width, swapInfo.extent.height, 1, swapInfo.format, 0), + VK_BUFFER_USAGE_TRANSFER_DST_BIT, }; - vt->CreateImage(Unwrap(device), &imInfo, NULL, &readbackIm); + vt->CreateBuffer(Unwrap(device), &bufInfo, NULL, &readbackBuf); RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(Unwrap(device), readbackIm); - - VkImageSubresource subr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0}; - VkSubresourceLayout layout = {0}; - vt->GetImageSubresourceLayout(Unwrap(device), Unwrap(readbackIm), &subr, &layout); + GetResourceManager()->WrapResource(Unwrap(device), readbackBuf); MemoryAllocation readbackMem = - AllocateMemoryForResource(readbackIm, MemoryScope::InitialContents, MemoryType::Readback); + AllocateMemoryForResource(readbackBuf, MemoryScope::InitialContents, MemoryType::Readback); - vkr = vt->BindImageMemory(Unwrap(device), Unwrap(readbackIm), Unwrap(readbackMem.mem), - readbackMem.offs); + vkr = vt->BindBufferMemory(Unwrap(device), Unwrap(readbackBuf), Unwrap(readbackMem.mem), + readbackMem.offs); RDCASSERTEQUAL(vkr, VK_SUCCESS); VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, @@ -1312,10 +1298,17 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkImageCopy cpy = { - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, - {imInfo.extent.width, imInfo.extent.height, 1}, + uint32_t rowPitch = GetByteSize(swapInfo.extent.width, 1, 1, swapInfo.format, 0); + + VkBufferImageCopy cpy = { + 0, + 0, + 0, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + { + 0, 0, 0, + }, + {swapInfo.extent.width, swapInfo.extent.height, 1}, }; uint32_t swapQueueIndex = m_ImageLayouts[GetResID(backbuffer)].queueFamilyIndex; @@ -1333,21 +1326,7 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, }; - VkImageMemoryBarrier readBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - NULL, - 0, - VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, - VK_QUEUE_FAMILY_IGNORED, - Unwrap(readbackIm), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, - }; - DoPipelineBarrier(cmd, 1, &bbBarrier); - DoPipelineBarrier(cmd, 1, &readBarrier); if(swapQueueIndex != m_QueueFamilyIdx) { @@ -1363,21 +1342,28 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) SubmitAndFlushExtQueue(swapQueueIndex); } - vt->CmdCopyImage(Unwrap(cmd), Unwrap(backbuffer), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - Unwrap(readbackIm), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy); + vt->CmdCopyImageToBuffer(Unwrap(cmd), Unwrap(backbuffer), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + Unwrap(readbackBuf), 1, &cpy); // barrier to switch backbuffer back to present layout std::swap(bbBarrier.oldLayout, bbBarrier.newLayout); std::swap(bbBarrier.srcAccessMask, bbBarrier.dstAccessMask); std::swap(bbBarrier.srcQueueFamilyIndex, bbBarrier.dstQueueFamilyIndex); - readBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - readBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - readBarrier.oldLayout = readBarrier.newLayout; - readBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + VkBufferMemoryBarrier bufBarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_HOST_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(readbackBuf), + 0, + bufInfo.size, + }; DoPipelineBarrier(cmd, 1, &bbBarrier); - DoPipelineBarrier(cmd, 1, &readBarrier); + DoPipelineBarrier(cmd, 1, &bufBarrier); vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); @@ -1420,18 +1406,16 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) // point sample info into raw buffer { - ResourceFormat fmt = MakeResourceFormat(imInfo.format); + ResourceFormat fmt = MakeResourceFormat(swapInfo.format); byte *data = (byte *)pData; - data += layout.offset; - - float widthf = float(imInfo.extent.width); - float heightf = float(imInfo.extent.height); + float widthf = float(swapInfo.extent.width); + float heightf = float(swapInfo.extent.height); float aspect = widthf / heightf; - thwidth = (uint16_t)RDCMIN(maxSize, imInfo.extent.width); + thwidth = (uint16_t)RDCMIN(maxSize, swapInfo.extent.width); thwidth &= ~0x7; // align down to multiple of 8 thheight = uint16_t(float(thwidth) / aspect); @@ -1469,8 +1453,7 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) float xf = float(x) / float(thwidth); float yf = float(y) / float(thheight); - byte *src = - &data[stride * uint32_t(xf * widthf) + layout.rowPitch * uint32_t(yf * heightf)]; + byte *src = &data[stride * uint32_t(xf * widthf) + rowPitch * uint32_t(yf * heightf)]; if(buf1010102) { @@ -1540,8 +1523,8 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) vt->UnmapMemory(Unwrap(device), Unwrap(readbackMem.mem)); // delete all - vt->DestroyImage(Unwrap(device), Unwrap(readbackIm), NULL); - GetResourceManager()->ReleaseWrappedResource(readbackIm); + vt->DestroyBuffer(Unwrap(device), Unwrap(readbackBuf), NULL); + GetResourceManager()->ReleaseWrappedResource(readbackBuf); } byte *jpgbuf = NULL;