平铺资源 API

本部分中介绍的 API 适用于平铺资源和磁贴池。

将磁贴池中的磁贴分配到资源

ID3D11DeviceContext2::UpdateTileMappingsID3D11DeviceContext2::CopyTileMappings API 操作和查询磁贴映射。 更新调用仅影响调用中标识的磁贴,而其他磁贴则保留如前所述。

磁贴池中的任何给定磁贴都可以映射到资源中的多个位置,甚至多个资源。 此映射包括资源中的磁贴,这些图块具有实现选择的布局 (Mipmap 打包) 其中多个 mipmap 一起打包到单个磁贴中。 收获是,如果数据通过一个映射写入磁贴,但通过不同配置的映射读取,则结果未定义。 不过,谨慎使用这种灵活性对应用程序仍然很有用,例如在不会同时使用的资源之间共享磁贴,其中磁贴的内容始终通过随后从中读取的同一资源映射进行初始化。 同样,映射为保存具有相同表面尺寸的多个不同资源的打包 mipmap 的磁贴将正常工作 - 数据在两个映射中看起来相同。

可以随时在即时或延迟的上下文中更改资源的磁贴分配。

查询资源平铺和支持

若要查询资源平铺,请使用 ID3D11Device2::GetResourceTiling

对于其他资源平铺支持,请使用 ID3D11Device2::CheckMultisampleQualityLevels1

复制平铺数据

Direct3D 中用于移动数据的任何方法都与平铺资源一样工作,只是删除对未映射区域的写入操作,从未映射区域读取将产生 0。 如果复制操作涉及多次写入同一内存位置,因为目标资源中的多个位置映射到同一磁贴内存,则生成的对多映射磁贴的写入是不确定且不可重复的。 也就是说,无论硬件执行复制的顺序如何,访问都会发生。

Direct3D 11.2 引入了以下其他复制方法的方法:

这些方法根据需要重排/取消重排,并在调用方承诺目标内存不由正在进行的 GPU 工作引用时允许使用D3D11_TILE_COPY_NO_OVERWRITE标志。

复制中涉及的磁贴不能包含包含打包的 mipmap 或具有未定义结果的磁贴。 若要向/从硬件打包到一个磁贴的 mipmap 传输数据,必须使用标准 (非磁贴特定的) 复制/更新 API 或 ID3D11DeviceContext::GenerateMips 用于整个 mip 链。

关于 GenerateMips 的注释:在具有部分映射磁贴的资源上使用 ID3D11DeviceContext::GenerateMips 将生成结果,这些结果仅遵循应用于硬件和显示驱动程序恰好用于 GenerateMips 的任何算法的读取和写入 NULL 的规则。 因此,除非 NULL 映射的区域 以某种方式 (,以及它们在生成阶段对其他 mips 的影响,否则应用程序这样做并不特别有用,) 不会对应用程序所关注的表面部分产生任何影响。

例如,从过渡图面或从应用程序内存复制磁贴数据是上传可能已从磁盘流式传输的磁贴的方式。 流出磁盘时的一个变化是将某种压缩数据上传到 GPU 内存,然后在 GPU 上解码。 解码目标可以是 GPU 内存中的缓冲区资源, CopyTiles 随后会从该资源复制到实际的平铺资源。 此复制步骤允许 GPU 在重排模式未知时重排。 例如,如果平铺资源本身是缓冲区资源 (,而不是纹理) ,则不需要重排。

副本的非平铺缓冲区资源端的磁贴的内存布局在 64KB 磁贴内的内存中只是线性的,硬件和显示驱动程序在向/从平铺资源传输时会根据需要按磁贴重排/取消重排。 对于多采样抗锯齿 (MSAA) 图面,在移动到下一个像素之前,将按样本索引顺序遍历每个像素的样本。 对于在右侧部分填充的磁贴, (图面的宽度不是以像素) 为图块宽度的倍数,如果磁贴已满,则下行的俯仰/步幅是磁贴上可容纳的数字像素的完整大小(以字节为单位)。 因此,内存中每一行像素之间可能存在间隔。 为简单起见,小于磁贴的 mipmap 不会在线性布局中打包在一起。 这似乎浪费了内存空间,但如复制到 mips 所述,不允许通过 CopyTilesUpdateTiles 将硬件打包在一起。 应用程序只能使用泛型 UpdateSubresource* () 或 CopySubresource* () API 单独复制小型 mips,但在 CopySubresource* () 的情况下,这意味着线性内存必须与平铺资源维度相同 - CopySubresource* () 不能从缓冲区资源复制到 Texture2D 例如。

如果定义了硬件标准重排,可以添加标志来指示缓冲区中的数据将采用该格式进行解释, (传输) 时不需要重排,但上传数据的替代方法在这种情况下可能也有意义,例如允许应用程序直接访问磁贴池内存。

可以在即时或延迟的上下文上执行复制操作。

调整磁贴池大小

若要调整磁贴池的大小,请使用 ID3D11DeviceContext2::ResizeTilePool

平铺资源屏障

若要在多个平铺资源之间指定数据访问排序约束,请使用 ID3D11DeviceContext2::TiledResourceBarrier

平铺资源