I am trying to add the ability to take a screenshot in my renderer, but vkMapMemory keeps producing an error in the debug validation layer, and does not return VK_SUCCESS.
Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT. The Vulkan spec states: memory must have been created with a memory type that reports VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
However, the memory allocation is being created with this flag set in the memory requirements. Here is my code that creates the image to copy the screen data to:
VkAssert(vkCreateImage(device->device, &imageInfo, nullptr, &core->vkimage));
vkGetImageMemoryRequirements(device->device, core->vkimage, &memRequirements[0]);
if ((flags & TEXTURE_LINEARTILING) != 0)
{
memRequirements[0].memoryTypeBits |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
}
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
VmaAllocationInfo alllocation = {};
VmaAllocationInfo allocinfo = {};
VkAssert(vmaAllocateMemory(UltraEngine::Core::GameEngine::Get()->renderingthreadmanager->device->allocator, &memRequirements[0], &allocCreateInfo, &core->memoryallocation, &allocinfo));
VkAssert(vmaBindImageMemory(this->device->allocator, core->memoryallocation, core->vkimage));
And this is my code that takes the screenshot. There is presently no copy/blit of the framebuffer to the screenshot image. At this point I am just trying to map/unmap the screenshot image memory:
auto pixmap = CreatePixmap(size.x, size.y, TextureFormat(chaininfo.imageFormat));
screencaptureimage = std::make_shared<RenderTexture>();
screencaptureimage->Initialize(TEXTURE_2D, TextureFormat(chaininfo.imageFormat), size.x, size.y, 1, 0, false, 1, TEXTURE_LINEARTILING);
device->WaitIdle();
VmaAllocationInfo meminfo = {};
vmaGetAllocationInfo(device->allocator, screencaptureimage->core->memoryallocation, &meminfo);
// Get layout of the image (including row pitch)
const char* data = nullptr;
VkImageSubresource subResource{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
VkSubresourceLayout subResourceLayout;
vkGetImageSubresourceLayout(device->device, screencaptureimage->core->vkimage, &subResource, &subResourceLayout);
if (VK_SUCCESS == vkMapMemory(device->device, meminfo.deviceMemory, 0, VK_WHOLE_SIZE, 0, (void**)&data))
{
data += subResourceLayout.offset;
Assert(data, subResourceLayout.size == pixmap->pixels->GetSize());
memcpy(pixmap->pixels->Data(), data, subResourceLayout.size);
vkUnmapMemory(device->device, meminfo.deviceMemory);
capturedframes.push_back(pixmap);
}
Any idea what I am doing wrong?