在我的Vulkan应用程序中,我希望有一个内存缓冲区可以存储多个不同大小的纹理。然后,我想VkImageView
在缓冲区中有一个与每个纹理相对应的对象。我不确定如何创建这样的缓冲区,这是我想到的:
// Create images
VkImage images[TEXTURE_COUNT];
for (int i = 0; i < TEXTURE_COUNT, i++) {
VkImageCreateInfo imageCreateInfo{};
// Specific to texture i
imageCreateInfo.extent.width = ...
iamgeCreateInfo.extent.height = ...
// Other imageCreateInfo properties are constant across all textures
...
VkCreateImage(device, &imageCreateInfo, nullptr, &images[i]);
}
// Find total size of memory buffer & image offsets
int totalSize = 0;
int offsets[TEXTURE_COUNT];
for (int i = 0; i < TEXTURE_COUNT; i++) {
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(device, images[i], &memoryRequirements);
offsets[i] = totalSize;
totalSize += memoryRequirements.size;
}
// Get memory type index of memory buffer
VkMemoryRequirements firstImageMemoryRequirements;
vkGetImageMemoryRequirements(device, images[0], &firstImageMemoryRequirements);
int memoryTypeIndex = ... // Get memory type index using firstImageMemoryRequirements.memoryTypeBits
// Allocate memory
VkMemoryAllocateInfo memoryAllocateInfo{};
memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memoryAllocateInfo.allocationSize = totalSize;
memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
VkMemory memory;
vkAllocateMemory(device, &memoryAllocateInfo, nullptr, &memory)
// Bind images to memory at corresponding offset
VkBindImageMemoryInfo bindImageMemoryInfos[TEXTURE_COUNT];
for (int i = 0; i < TEXTURE_COUNT, i++) {
VkBindImageMemoryInfo bindImageMemoryInfo{};
bindImageMemoryInfo.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
bindImageMemoryInfo.image = images[i];
bindImageMemoryInfo.memory = memory;
bindImageMemoryInfo.memoryOffset = offsets[i];
bindImageMemoryInfos[i] = bindImageMemoryInfo;
}
vkBindImageMemory2(device, TEXTURE_COUNT, &bindImageMemoryInfos);
// Create image views
VkImageView imageViews[TEXTURE_COUNT];
for (int i = 0; i < TEXTURE_COUNT; i++) {
VkImageViewCreateInfo imageViewCreateInfo{};
imageViewCreateInfo.image = images[i];
...
VkCreateImageView(device, &imageViewCreateInfo, nullptr, &imageViews[i]);
}
// Now I have a bunch of image views tied to each texture,
// where each texture is stored in one memory buffer at a certain offset.
这看起来合理吗,或者这不是正确的方法?对我来说似乎有些奇怪的是,当我获取内存缓冲区的内存类型索引时。为此,您需要一张我拥有的图像TEXTURE_COUNT
,所以我只选择第一张图像。每个纹理唯一的图像属性是扩展区的宽度和高度,因此我希望它不会影响每个图像的内存类型位。我假设每个图像将具有相同的内存类型位,因此我可以使用第一个图像的内存类型位来获取内存类型索引。关于这个假设的想法也会很好。
对于每次VkImage
使用,它都必须存储在适合该特定VkImage
对象的内存中。这意味着偏移量/大小必须与该图像对象的对齐方式和大小匹配,并且绑定到的内存类型必须是可与该图像一起使用的内存类型之一。
必须为您使用的每个对象独立查询VkImage
。或通常 两个相同的VkImage
对象(即:从相同的VkImageCreateInfo
结构创建)将具有相同的需求,因此,如果重复相同创建VkImage
的,则无需再次查询其需求。在其他情况下,允许具有不同创建参数的图像具有相同的要求,因此,如果要利用它,则需要查找细节。
如果您在可以控制图像的大小,格式,用法和其他创建参数的环境中操作,则可以提前确定这几种图像的要求,并在这些限制内工作。否则,你将不得不做的查询需求信息为你的形象的工作之前分配的内存中,然后,一旦你知道你需要什么为他们分配内存。
另外,您也可以根据需要在大型slab中分配内存。也就是说,如果您需要为特定的内存分配新的内存VkImage
(因为最后一个平板已满,或者映像需要新的内存类型),则分配一个较大的内存块,然后可以将以后的映像放入同一存储中。这要求您跟踪放入哪些内存块中的内容。
您的代码存在一个问题,就是您没有考虑图像()的内存对齐要求VkMemoryRequirements::alignment
。您也不会考虑并非所有图像都可以共享相同的分配的可能性。您假设它们都可以使用相同的内存类型。
因此,您需要相应地更改代码。
话虽这么说,Vulkan对VkImage
内存要求的实现施加的限制包括一条声明,该声明有效地表明:假设许多其他创建参数相同,则图像对图像所需的存储类型对于所有颜色格式都将相同。因此,您仅需更改图像大小或使用不同格式的图像,就不必担心不同的内存类型。
可能会促使您使用不同的内存类型的事情主要是使用参数(以及颜色与深度格式)。打算用作渲染目标的图像可以具有自己的内存类型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句