如何在Vulkan中创建一个缓冲区来存储不同大小的多个纹理

休闲凯尔

在我的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,所以我只选择第一张图像。每个纹理唯一的图像属性是扩展区的宽度和高度,因此我希望它不会影响每个图像的内存类型位。我假设每个图像将具有相同的内存类型位,因此我可以使用第一个图像的内存类型位来获取内存类型索引。关于这个假设的想法也会很好。

尼科尔·波拉斯(Nicol Bolas)

对于每次VkImage使用,它都必须存储在适合该特定VkImage对象的内存中这意味着偏移量/大小必须与该图像对象的对齐方式和大小匹配,并且绑定到的内存类型必须是可与该图像一起使用的内存类型之一。

必须您使用的每个对象独立查询VkImage或通常 两个相同的VkImage对象(即:从相同的VkImageCreateInfo结构创建)将具有相同的需求,因此,如果重复相同创建VkImage的,则无需再次查询其需求。在其他情况下,允许具有不同创建参数的图像具有相同的要求,因此,如果要利用它,则需要查找细节。

如果您在可以控制图像的大小,格式,用法和其他创建参数的环境中操作,则可以提前确定这几种图像的要求,并在这些限制内工作。否则,你将不得不做的查询需求信息为你的形象的工作之前分配的内存中,然后,一旦你知道你需要什么为他们分配内存。

另外,您也可以根据需要在大型slab中分配内存。也就是说,如果您需要为特定的内存分配新的内存VkImage(因为最后一个平板已满,或者映像需要新的内存类型),则分配一个较大的内存块,然后可以将以后的映像放入同一存储中。这要求您跟踪放入哪些内存块中的内容。

您的代码存在一个问题,就是您没有考虑图像(的内存对齐要求VkMemoryRequirements::alignment您也不会考虑并非所有图像都可以共享相同的分配的可能性。您假设它们都可以使用相同的内存类型。

因此,您需要相应地更改代码。

话虽这么说,Vulkan对VkImage内存要求的实现施加的限制包括一条声明,该声明有效地表明:假设许多其他创建参数相同,则图像对图像所需的存储类型对于所有颜色格式都将相同。因此,您仅需更改图像大小或使用不同格式的图像,就不必担心不同的内存类型。

可能会促使您使用不同的内存类型的事情主要是使用参数(以及颜色与深度格式)。打算用作渲染目标的图像可以具有自己的内存类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何创建一个“缓冲区”来存储每个帧的变量的先前值

来自分类Dev

如何在协议缓冲区中存储一个字节?

来自分类Dev

如何使emacs允许在不同的帧中打开一个缓冲区?

来自分类Dev

'CommandList :: DrawInstanced'如何选择多个插槽中的一个顶点缓冲区?

来自分类Dev

如何在 Vulkan 深度缓冲区中存储不受限制的深度范围

来自分类Dev

如何在Vulkan中重新分配缓冲区

来自分类Dev

如何创建一个RxJS缓冲区来对NodeJS中的元素进行分组,但不依赖于永远的运行间隔?

来自分类Dev

Arcpy-创建一个缓冲区,然后溶解在一个脚本中

来自分类Dev

在emacs中的两个不同的缓冲区中编辑一个文件

来自分类Dev

如何将多个行从缓冲区复制到Emacs中的另一个行?

来自分类Dev

我如何在Flex中窥视下一个令牌而不将其从缓冲区中删除

来自分类Dev

将来自 rxjs 的多个 observable 组合到一个缓冲区中

来自分类Dev

如何在java中删除字符串缓冲区的最后一个字符?

来自分类Dev

没有GNU -z选项,如何在sed的一个缓冲区中处理整个文件?

来自分类Dev

如何增加一个缓冲区?

来自分类Dev

如何在Python中合并多个缓冲区对象?

来自分类Dev

如何在C ++中用新行输出一个缓冲区

来自分类Dev

当我重新分配一个较小的缓冲区时,它会删除缓冲区中的数据直到达到正确的大小吗?

来自分类Dev

iOS 9.1 AudioQueueAllocateBuffer请求修复缓冲区大小,它返回一个较小的缓冲区

来自分类Dev

创建一个缓冲区并在Python中为其分配一个指针

来自分类Dev

创建一个缓冲区并在Python中为其分配一个指针

来自分类Dev

如何在 WebGL 中为输出纹理或帧缓冲区提供偏移量?

来自分类Dev

SDL2-如何使用一个缓冲区而不是两个缓冲区进行渲染?

来自分类Dev

不同大小的着色器存储缓冲区内容“转移”到阵列缓冲区

来自分类Dev

在emacs中,如何在不单独打开每个缓冲区的情况下杀死多个缓冲区

来自分类Dev

如何在flink中实现一个触发器,该缓冲区一直缓存到超时,并在超时后触发?

来自分类Dev

绘制一个对象,比较两个不同的模板缓冲区值

来自分类Dev

如何通过使用统一的缓冲区对象和实例渲染来绘制多个对象?

来自分类Dev

如何在多个存储库之间共享协议缓冲区.proto文件

Related 相关文章

  1. 1

    如何创建一个“缓冲区”来存储每个帧的变量的先前值

  2. 2

    如何在协议缓冲区中存储一个字节?

  3. 3

    如何使emacs允许在不同的帧中打开一个缓冲区?

  4. 4

    'CommandList :: DrawInstanced'如何选择多个插槽中的一个顶点缓冲区?

  5. 5

    如何在 Vulkan 深度缓冲区中存储不受限制的深度范围

  6. 6

    如何在Vulkan中重新分配缓冲区

  7. 7

    如何创建一个RxJS缓冲区来对NodeJS中的元素进行分组,但不依赖于永远的运行间隔?

  8. 8

    Arcpy-创建一个缓冲区,然后溶解在一个脚本中

  9. 9

    在emacs中的两个不同的缓冲区中编辑一个文件

  10. 10

    如何将多个行从缓冲区复制到Emacs中的另一个行?

  11. 11

    我如何在Flex中窥视下一个令牌而不将其从缓冲区中删除

  12. 12

    将来自 rxjs 的多个 observable 组合到一个缓冲区中

  13. 13

    如何在java中删除字符串缓冲区的最后一个字符?

  14. 14

    没有GNU -z选项,如何在sed的一个缓冲区中处理整个文件?

  15. 15

    如何增加一个缓冲区?

  16. 16

    如何在Python中合并多个缓冲区对象?

  17. 17

    如何在C ++中用新行输出一个缓冲区

  18. 18

    当我重新分配一个较小的缓冲区时,它会删除缓冲区中的数据直到达到正确的大小吗?

  19. 19

    iOS 9.1 AudioQueueAllocateBuffer请求修复缓冲区大小,它返回一个较小的缓冲区

  20. 20

    创建一个缓冲区并在Python中为其分配一个指针

  21. 21

    创建一个缓冲区并在Python中为其分配一个指针

  22. 22

    如何在 WebGL 中为输出纹理或帧缓冲区提供偏移量?

  23. 23

    SDL2-如何使用一个缓冲区而不是两个缓冲区进行渲染?

  24. 24

    不同大小的着色器存储缓冲区内容“转移”到阵列缓冲区

  25. 25

    在emacs中,如何在不单独打开每个缓冲区的情况下杀死多个缓冲区

  26. 26

    如何在flink中实现一个触发器,该缓冲区一直缓存到超时,并在超时后触发?

  27. 27

    绘制一个对象,比较两个不同的模板缓冲区值

  28. 28

    如何通过使用统一的缓冲区对象和实例渲染来绘制多个对象?

  29. 29

    如何在多个存储库之间共享协议缓冲区.proto文件

热门标签

归档