You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何ID3D11DeviceContext::Map得到的映射子资源与原纹理分辨率不一致

现象底层原因

你遇到的是现代图形API的通用显存对齐规则,属于正常设计,并非异常:
GPU访问显存时要求每行数据的起始地址对齐到特定字节边界(通常为2的整数次幂),以此提升显存访问效率、减少带宽浪费,该要求由GPU架构、驱动、纹理格式、纹理绑定标志共同决定。

你给出的案例完全符合64字节对齐规则:

  • 1559宽度的BGRA8格式纹理,单像素占4字节,无对齐时行字节数为 1559 * 4 = 6236
  • 6236无法被64整除,驱动会自动将行字节数向上取整到最近的64的倍数,也就是6272,对应你拿到的RowPitch值,折算成像素宽度就是 6272 /4 =1568
  • 1568宽度的纹理无对齐行字节数刚好为6272,满足对齐要求,因此RowPitch符合预期。
RowPitch计算通用逻辑

微软官方没有公开固定的RowPitch计算方法,该值由驱动动态生成,但所有实现都会遵循以下逻辑:

  1. 计算基础行字节数:基础行字节数 = 纹理宽度 * 单像素字节数
  2. 确认当前场景下的对齐边界:
    • 普通非压缩2D纹理:常见对齐边界为16、32、64字节
    • 多采样MSAA纹理:对齐边界通常为256字节及以上
    • BC系列块压缩纹理:除了行对齐,还需要满足压缩块的尺寸对齐要求
  3. 将基础行字节数向上取整到对齐边界的整数倍,最终结果即为返回的RowPitch值。

你遇到的场景可直接用64字节对齐验证:向上取整公式为 (基础行字节数 + 对齐边界 -1) & ~(对齐边界 -1),代入数值(6236 +63) & ~63 = 6272,和你拿到的结果完全一致。

适配规则建议

如果你要避免对齐带来的差异,可遵循以下规则:

  • 生成源纹理时,提前将宽度向上取整到对齐边界对应的像素值,比如64字节对齐的BGRA8格式,像素对齐值为64 /4 =16,将所有纹理宽度设置为16的整数倍即可保证RowPitch等于宽度*4
  • 无论什么场景,访问映射后的子资源数据时,都不要硬编码RowPitch的计算逻辑,始终使用D3D11_MAPPED_SUBRESOURCE返回的RowPitch值计算行偏移:第y行数据起始地址 = pData + y * RowPitch
  • 如果需要将映射数据导出为无对齐的连续内存,逐行拷贝有效数据即可,每次拷贝长度为纹理宽度*单像素字节数,跳过RowPitch末尾的Padding字节即可。

内容的提问来源于stack exchange,提问作者wflznrxkuf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:06:04