特定尺寸的图像具有奇怪的内存大小

Image of specific dimensions has strange memory size

本文关键字:内存 图像      更新时间:2023-10-16

我有一个奇怪的行为,格式为R8G8B8A8_UNORM的大小为500x500的图像需要额外的8000字节的内存量,而其他尺寸正好需要宽度*高度*4字节。我正在做以下事情:

  1. 画color-attachment
  2. 复制颜色附件到主机可见图像并映射它(在所有布局过渡之后)。
这工作得很好,但是,当在映射之前检查主机可见映像的内存需求时,我得到以下结果:
  • w=1000,h=1000: 4,000,000字节
  • w=600,h=600: 1440000 byte
  • w=500,h=500: 1,008,000字节(应该是1,000,000)

最后一种情况下生成的图像是畸形的。除了w*h*4之外,我是否遗漏了任何可能导致内存大小不同公式的明显内容?主机可见图像具有线性平铺,并且在vkMapMemory命令之前已转换为布局VK_IMAGE_LAYOUT_GENERAL

这是颜色附件的创建信息:

VkImageCreateInfo color_image_info = {
  VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType,
  nullptr, // pNext (see documentation, must be null)
  0, // image flags
  VK_IMAGE_TYPE_2D, // image type
  this->color_format_, // image format
  {this->render_width_, this->render_height_, 1}, // image extent
  1, // level of detail = 1
  1, // layers = 1
  VK_SAMPLE_COUNT_1_BIT, // sampling
  VK_IMAGE_TILING_OPTIMAL, // optimal tiling
  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // used for color
  VK_SHARING_MODE_EXCLUSIVE, // sharing between queue families
  1, // number queue families
  &this->queue_family_index_, // queue family index
  VK_IMAGE_LAYOUT_PREINITIALIZED // initial layout
};

这是主机可见图像:

VkImageCreateInfo host_visible_image_info = {
  VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType,
  nullptr, // pNext (see documentation, must be null)
  0, // image flags
  VK_IMAGE_TYPE_2D, // image type
  this->color_format_, // image format
  {this->render_width_, this->render_height_, 1}, // image extent
  1, // level of detail = 1
  1, // layers = 1
  VK_SAMPLE_COUNT_1_BIT, // sampling
  VK_IMAGE_TILING_LINEAR, // linear tiling
  VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // used for color
  VK_SHARING_MODE_EXCLUSIVE, // sharing between queue families
  1, // number queue families
  &this->queue_family_index_, // queue family index
  VK_IMAGE_LAYOUT_PREINITIALIZED // initial layout // TODO: !!!Find out whether this has to be transisition first
};

所以我想我只需要计算padding = (required_size - computed_size)/width/4.

Vulkan允许您通过vkGetImageSubresourceLayout查询图像的布局(线性平铺)。当你试图映射纹理并访问它的位时,这就是你应该使用的。

VkSubresourceLayout将告诉您图像的行间距(即:您必须偏移的字节数,以获得直接低于/高于它的像素)。这个值是,不需要为宽度*像素大小。您必须查询您想要访问的每个图像。