我有一个维度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)
{ //...
我使用此临时缓冲区来处理顶点和索引缓冲区(我将其作为具有偏移的单个缓冲区)以及我尝试复制到的图像。分配的内存取决于最大数据结构的大小。
答案 0 :(得分:3)
如评论中所述。使用VK_REMAINING_ARRAY_LAYERS
对layerCount
的{{1}}无效,因此您必须明确将VkImageSubresourceRange
设置为要复制的实际层数。