Adreno GPU上的DirectX平台优化 (2)

Adreno GPU上的DirectX平台优化 (2)

5.2 基于图块的渲染的注意事项

在基于图块的渲染架构上,尽量减少从 GMEM 加载和存储数据非常重要。 如前几节所述,渲染到 GMEM 中的所有数据必须先复制回系统内存中,然后才能进一步使用。 将数据从 GMEM 复制到系统内存的过程称为 GMEM 存储。 在某些情况下,当驱动程序无法确定渲染目标是否会用不透明像素覆盖每个像素(渲染剪刀内)时,它必须在渲染之前将先前的渲染目标数据加载到 GMEM 中。 从系统内存复制到 GMEM 的过程称为 GMEM 加载。 将数据从一个内存区域复制到另一个内存区域是最昂贵的操作之一,应尽可能减少。

切换渲染目标时或在呈现帧之前需要 GMEM 存储。 最小化渲染目标切换是在任何基于 tile 的渲染器上实现良好性能的关键。 仅当渲染目标被绑定时才需要 GMEM 加载,并且在绘制到它之前不会被清除或丢弃。 刷新被视为与绑定渲染目标相同,并且为了避免 GMEM 加载,必须在绘制之前清除/丢弃。 需要 GMEM 加载的典型场景是从渲染目标复制到新缓冲区以进行后处理效果。 一个不需要 GMEM 加载但经常被应用程序开发人员忽略的典型场景是渲染到屏幕外渲染目标,然后切换到交换链并渲染场景,而不在任一渲染目标上调用 clear/discard。

Direct3D11.1 中有许多操作会导致 GMEM 加载。 下面列出了一些示例:

  • IDirect3D11DeviceContext::CopyResource 或 IDirect3D11DeviceContext::CopySubresourceRegion 其中源是渲染目标
  • IDirect3D11DeviceContext::CopyResource 或
    IDirect3D11DeviceContext::CopySubresourceRegion,其中目的地已用作渲染到当前渲染目标的纹理
  • 使用绑定一个新的渲染目标 IDirect3D11DeviceContext::OMSetRenderTarget 并绘制到它
  • 使用 IDXGISwapChain1::Present 呈现帧缓冲区
  • 使用 IDirect3D11DeviceContext::Flush 显式调用刷新

应用程序开发人员可以采取许多重要步骤来避免不必要的解析并从 Adreno GPU 中获得最佳性能。 下面是一组应遵循的准则,以尽量减少不必要的解决。

使用 DiscardView 和/或 DiscardResource
Direct3D11.1 提供了两个对于实现 TBR 最佳性能非常重要的函数:IDirect3D11Context::DiscardView 和 IDirect3D11Context::DiscardResource。 这两个函数通知驱动程序不再需要资源视图或资源中的内容。 驱动程序可以使用此信息来避免在渲染到丢弃的目标时恢复 GMEM。

例如,应用程序可能知道它将向帧缓冲区的每个像素写入一个不透明的值。 因此,应用程序不会在渲染帧之前清除屏幕内容。 虽然这种行为是正确的,但如果没有调用 DiscardView,驱动程序将被迫在渲染之前恢复渲染目标的内容(重量级解决方案)。 否则,驱动程序无法知道应用程序打算覆盖每个像素值。 通过调用 DiscardView,驱动程序可以避免进行重量级解析,因为它知道应用程序不依赖于正在恢复的内容。

最小化渲染目标开关
每次切换渲染目标时,都会导致性能损失。 在可能的情况下,应用程序应在切换到新渲染目标之前将所有渲染发送到单个渲染目标。 至少切换目标会导致 GMEM 存储……如果您没有清除渲染目标更改之间的内容,则会导致 GMEM 加载。

适当设置剪刀矩形
如果您的应用程序需要在渲染目标之间频繁切换,您可以通过设置剪刀矩形以匹配正在更新的区域(使用 ID3D11DeviceContext::RSSetScissorRects)来显着提高性能。 这允许驱动程序跟踪已更新的区域,并将通过 GMEM 的流量最小化到仅渲染所需的部分。 驱动程序将单独跟踪剪刀并在处理场景时应用所有剪刀的并集。 不建议在每次绘制调用中更改剪刀以紧密匹配对象的边界。 应用程序应该尝试看看需要多少剪刀才能消除对未更改像素的不必要处理。 根据经验,应用程序不应为每个渲染目标设置超过 16 个不同的剪刀。

避免显式冲洗
避免显式调用 IDirect3D11DeviceContext::Flush。 例外情况是如果不再向当前绑定的渲染目标发出渲染。

延迟读取渲染目标数据
从当前渲染目标复制数据可能会导致刷新。 如果不是立即需要数据,请考虑推迟来自渲染目标的副本,直到为该渲染目标发出所有渲染命令。 如果立即需要数据,并且渲染目标未更改(例如,渲染目标的快照用作后续渲染命令的纹理),则可能会导致刷新和 GMEM 加载操作。

有几个选项可用于最小化 GMEM 加载操作的成本:

  • 如果渲染目标数据将被完全覆盖,请在调用任何渲染命令之前调用 DiscardResource/DiscardView。
  • 如果后续渲染未覆盖整个屏幕,请设置剪刀矩形以匹配将更新的屏幕部分。
  • 使用来自先前渲染目标的数据。

避免映射资源
CPU 对资源的访问不是流水线式的,因此在对性能敏感的代码中应谨慎行事。 如果资源已被用于纹理或 blt 到当前渲染目标,则对该资源发出锁定,并且在允许 CPU 访问资源之前必须刷新当前工作。 刷新将导致 GMEM 存储,如果继续使用渲染目标,它将在锁定之后的渲染命令之前导致 GMEM 加载。 如果应用程序正在映射用于写入的资源,则可以使用 D3D11_MAP_WRITE_DISCARD 或 D3D11_MAP_WRITE_NO_OVERWRITE 避免刷新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值