【问题标题】:unable to copy from buffer to image无法从缓冲区复制到图像
【发布时间】:2018-02-27 14:18:36
【问题描述】:

我有一个尺寸为4096*4096(所以67108864 字节,因为有4 个通道)的图像,我想将其从暂存缓冲区复制到设备本地图像。缓冲区已经存储了数据,并且我已经正确设置了图像屏障,所以现在我想执行复制操作......除非它不起作用。当我调用 vkCmdCopyBufferToImage() 时,验证层给了我这个错误信息 -

IMAGE(ERROR): object: 0x0 type: 6 location: 3903 msgCode: 417333590: vkCmdCopyBufferToImage(): pRegion[0] exceeds buffer size of 67108864 bytes. The spec valid usage text states 'The buffer region specified by each element of pRegions mustbe a region that is contained within srcBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkCmdCopyBufferToImage-pRegions-00171).

我找不到我给它的值有什么问题。我传递给它的VkBufferImageCopy 结构看起来像这样-

        VkBufferImageCopy bufImgCopy;
        bufImgCopy.bufferOffset = 0;
        bufImgCopy.bufferImageHeight = 0;
        bufImgCopy.bufferRowLength = 0;
        bufImgCopy.imageExtent = modelTexture.imgExtents; // 4096 * 4096 * 1
        bufImgCopy.imageOffset = {0, 0, 0};
        bufImgCopy.imageSubresource.aspectMask = modelTexture.subResource.aspectMask; // Colour attachment
        bufImgCopy.imageSubresource.baseArrayLayer = modelTexture.subResource.baseArrayLayer; // 0
        bufImgCopy.imageSubresource.layerCount = VK_REMAINING_ARRAY_LAYERS;
        bufImgCopy.imageSubresource.mipLevel = 0;

我无法弄清楚为什么 api 认为结构指定的大小大于缓冲区大小。图片格式为VK_FORMAT_B8G8R8A8_UNORM

编辑

这是设置暂存缓冲区的代码-

stageBuf.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
stageBuf.shareMode = VK_SHARING_MODE_EXCLUSIVE;
stageBuf.bufSize = static_cast<VkDeviceSize>(verts.size() * sizeof(vert) + indices.size() * sizeof(u32)) > modelImage.size ? static_cast<VkDeviceSize>(verts.size() * sizeof(vert) + indices.size() * sizeof(u32)) : modelImage.size;

// filled from the previous struct.
VkBufferCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.queueFamilyIndexCount = bufInfo.qFCount;
info.pQueueFamilyIndices = bufInfo.qFIndices;
info.usage = bufInfo.usage;
info.sharingMode = bufInfo.shareMode;
info.size = bufInfo.bufSize;

if (vkCreateBuffer(device, &info, nullptr, &(bufInfo.buf)) != VK_SUCCESS)
{ //...

VkMemoryRequirements memReqs;
vkGetBufferMemoryRequirements(device, buf, &memReqs);

for (u32 type = 0; type < memProps.memoryTypeCount; ++type)
    if ((memReqs.memoryTypeBits & (1 << type)) &&
        ((memProps.memoryTypes[type].propertyFlags & memFlags) == memFlags)) // The usual things to set buffers up.
    {
        VkMemoryAllocateInfo info;
        info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
        info.pNext = nullptr;
        info.allocationSize = memReqs.size;
        info.memoryTypeIndex = type;

        if (vkAllocateMemory(device, &info, nullptr, &mem.memory) == VK_SUCCESS)
        { //....

    // All this works perfectly except for the texture copy.
    if (vkBindBufferMemory(device, buf, mem.memory, mem.offset) != VK_SUCCESS)
    { //...

我将这个暂存缓冲区用于顶点缓冲区和索引缓冲区(我已将其作为具有偏移量的单个缓冲区)以及我试图复制到的图像。分配的内存是根据最大数据结构的大小来分配的。

【问题讨论】:

  • 图像有多少层数组?只有一个或多个?
  • 只有一个。它还有 4 个 mipmap 层。
  • 您在哪里提供要复制的 mipmap 级别数?我现在没有规范,我不记得缓冲区图像复制的所有参数。以及为什么会有两个变量bufImgCopybufImgCopies
  • 您能否添加设置和上传暂存缓冲区的实际代码。缓冲区图像复制结构看起来不错,因此有趣的部分可能是您上传数据的位置。也尝试将 layerCount 设置为 1 而不是使用 VK_REMAINING_ARRAY_LAYERS。
  • @SaschaWillems VK_REMAINING_ARRAY_LAYERSVkImageSubresourceLayers 无效。你应该这样回答。

标签: vulkan


【解决方案1】:

如 cmets 中所述。使用VK_REMAINING_ARRAY_LAYERSVkImageSubresourceRangelayerCount 无效,因此您必须将layerCount 显式设置为实际要复制的层数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多