导出 (0) 打印
全部展开
信息
您所需的主题如下所示。但此主题未包含在此库中。

优化 Windows Phone 8 基于磁贴的呈现

2014/6/18

仅适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1

Windows Phone 8 设备使用的 GPU 利用基于磁贴的呈现方法。该呈现方法针对非常占用内存的呈现操作利用内部磁贴缓存,避免否则会需要到的许多片外内存事务,力图提高 GPU 性能和减少耗电量。从概念上说,基于磁贴的呈现涉及将呈现目标划分为磁贴缓存大小的块,即磁贴,而且要多次重播定向在呈现目标的呈现命令,每次一个磁贴。基于磁贴的 GPU 的驱动程序可以敏捷地确定在给定磁贴上需要呈现哪些顶点,在必要的地方剪裁三角形和线段,以及使用“binning”进程。但是,对于该驱动程序来说,为含有多重或复合呈现目标的应用程序方案优化磁贴呈现的挑战性更大,这主要因为它并不一定知道应用程序何时完成当前呈现目标的磁贴。在默认情况下,移至新的呈现目标磁贴时,驱动程序将保留磁贴内容,即在加载下一个磁贴之前将此磁贴解析回至内存,这可能引起不必要的内存开销。

基于磁贴的 GPU 的磁贴缓存结构得到高度优化,以便非常高效地从事缓存内图形内存事务。例如,Alpha 混合实际上有意不占用基于磁贴的 GPU,而如果使用传统 GPU,则会因所需的与外部图像内存之间的读-修改-写事务而产生额外开销。类似地,多示例抗锯齿 (MSAA) 呈现目标对基于磁贴的 GPU 的开销大大小于对传统 GPU 的,这仍然得益于经优化的磁贴缓存结构。

Direct3D11 (D3D 11) 包含一些 API,这些 API 让应用程序能够向 GPU 驱动程序提供提示,帮助驱动程序避免与磁贴相关的不必要内存事务。在以下部分,将在常见应用程序方案和基于磁贴的呈现上下文中解释现有的和新的 D3D 11.1 GPU 提示 API。

通常,为了避免不必要的磁贴解析和涉及的性能损失,采用多个呈现目标的应用程序应在为给定场景处理完一个呈现目标后再处理下一个。例如,采用一个或多个屏幕外呈现目标(在为当前帧呈现缓冲区时对呈现目标生成的纹理进行采样)的应用,应在向后备缓冲区呈现之前完成每一个纹理的呈现。

对于要组合多个纹理层的应用程序方案,应避免增量合并,以避免“增量呈现”,“增量呈现”涉及会损害性能的不必要的外部内存事务和不必要的 D3D11 调用。例如,考虑一下增量合并 4 个纹理层而不是推迟合并的后果:

首选方法

低效方法

  1. 设置呈现对象 A、清理 A、绘制至 A

  2. 设置呈现对象 B、清理 B、绘制至 B

  3. 设置呈现对象 C、清理 C、绘制至 C

  4. 设置呈现对象 D、清理 D、使用 A、B 和 C 绘制至 D

该方法需要 4 个调用来设置呈现目标。

  1. 设置呈现对象 A、清理 A、绘制至 A

  2. 设置呈现对象 D、清理 D、将 A 绘制至 D

  3. 设置呈现对象 B、清理 B、绘制至 B

  4. 设置呈现对象 D,将 B 绘制至 D

  5. 设置呈现对象 C、清理 C、绘制至 C

  6. 设置呈现对象 D,将 C 绘制至 D

该方法需要 6 个调用来设置呈现目标。

在以上所演示的首选方法中,请注意,切换至每一个呈现对象之后立即调用 Clear。这向 GPU 驱动程序指示,给定呈现对象不需要“增量呈现”,即不必在呈现之前读取每一个呈现目标磁贴。请在下一节中参阅 Clear 的替换项。在低效方法示例中,除了要更多地调用 OMSetRenderTarget,呈现目标 D 的磁贴还必须多次读回至内存。

如果在一些方案中,应用程序提前知道现有呈现目标资源中的每一个像素都将被替代,即后续呈现操作中不需要它们,则两个新的“Discard”方法已被添加至 D3D 11.1,使之可以向 GPU 驱动程序指示该情况。以前该应用程序在此方案中有两个替换选项:

  1. 在不清理的情况下绘制场景,这对于基于磁贴的 GPU 开销较大,因为 GPU 必须还原每一个磁贴,即在绘制前将每一个磁贴读入磁贴缓存中。显然,如果应用程序将不使用之前的内容,那么这些还原意味着大量的不必要开销。

  2. 绘制前清理,这允许驱动程序避免还原磁贴,但却要求呈现目标写入操作执行 Clear 命令。同样,如果应用程序将不使用之前的内容,这些都不必要。

新的 D3D 11.1 Discard 方法为应用程序提供更有效的第三种选择,如下表所示:

ID3D11DeviceContext1::DiscardResource

不再定义向 GPU 指示资源当前内容和所有视图的信号,而且不需要在后续呈现通道上保留这些信号。

ID3D11DeviceContext1::DiscardView

从本质上说是与 DiscardResource 相同的操作,但是限定在特定的呈现目标视图中。

请注意,一旦应用程序在呈现目标资源或视图上调用了 Discard,则 Draw 调用将在每个正被更新的像素中遵循该结果。Discard 之后的呈现目标内容未被定义,因此应用程序无法在它们上面执行 Alpha 混合或仅仅绘制被覆盖形状的部分。

中途调用 ID3D11DeviceContext::Flush 可能导致过早的磁贴解析,进而导致不必要的磁贴读取。有关更多信息,请参见 ID3D11DeviceContext::Flush 参考主题中的“备注”部分。

如果应用提前知道只有限定范围的呈现目标部分将为给定场景更新,则应用应使用 ID3D11DeviceContext::RSSetScissorRects 方法,使 GPU 驱动程序可以提前确定哪些磁贴不需要处理。

显示:
© 2015 Microsoft