无法从缓冲区复制到图像

时间:2018-02-26 15:36:31

标签: vulkan

我有一个维度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)
    { //...

我使用此临时缓冲区来处理顶点和索引缓冲区(我将其作为具有偏移的单个缓冲区)以及我尝试复制到的图像。分配的内存取决于最大数据结构的大小。

1 个答案:

答案 0 :(得分:3)

如评论中所述。使用VK_REMAINING_ARRAY_LAYERSlayerCount的{​​{1}}无效,因此您必须明确将VkImageSubresourceRange设置为要复制的实际层数。