Vulkan纹理数组与单纹理内存占用差异问题咨询
纹理数组内存占用远超原纹理的原因分析
原纹理尺寸为72x64,拆分为96个6x8的纹理数组后,二者像素总量完全一致,但内存占用差异极大:
- BigTexture:Size 8196,Alignment 1024
- TextureArray:Size 49152,Alignment 1024
纹理数组创建代码如下:
VkImageCreateInfo fontImageInfo{}; fontImageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; fontImageInfo.imageType = VK_IMAGE_TYPE_2D; fontImageInfo.format = VK_FORMAT_R8_UNORM; fontImageInfo.extent = { 6, 8, 1U }; fontImageInfo.mipLevels = 1; fontImageInfo.arrayLayers = 12 * 8; fontImageInfo.samples = VK_SAMPLE_COUNT_1_BIT; fontImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; fontImageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; fontImageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; fontImageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
核心原因:最优布局与内存对齐规则
最优布局的硬件填充
你使用的VK_IMAGE_TILING_OPTIMAL是显卡硬件优化后的布局,会根据硬件纹理单元的要求添加额外填充,并非严格按像素数计算内存。对于6x8这种小尺寸纹理,填充的比例远高于72x64的大纹理——硬件的最小内存块或对齐要求是固定的,小纹理会被强制填充到满足该要求的最小内存单元。数组层的独立对齐
纹理数组的每个层都会单独遵循内存对齐规则。你的对齐要求是1024字节,单个6x8的R8_UNORM纹理仅占48字节像素数据,但硬件会把每个层的内存大小对齐到1024字节。96个层的总内存就是96×1024=49152字节,正好和你看到的TextureArray Size一致。大纹理的内存效率优势
原72x64纹理的像素数为4608字节,加上对齐到1024的填充后,实际占用8196字节(接近8×1024=8192,多4字节为硬件特定填充或元数据),远低于96个小纹理层的总对齐内存。
优化建议
- 若对采样性能要求不高,可尝试使用
VK_IMAGE_TILING_LINEAR布局,这种线性布局的内存占用更接近实际像素数,但会牺牲硬件采样效率。 - 若必须保留最优布局,可调整单个纹理层的尺寸,使其内存大小刚好匹配硬件要求的块大小,减少填充浪费;或重新设计纹理分组逻辑,减少数组层数。
内容的提问来源于stack exchange,提问作者yigitEmre
相关产品推荐
相关产品推荐

