DirectX11中的纹理流,不可变与动态

时间:2015-04-09 21:50:50

标签: directx directx-11

我们经常遇到需要将纹理流式传输到显卡的情况(在游戏情况下:地形,在我的情况下来自不同输入源的图像,如相机/采集卡/视频)

当然在相机的情况下,我在一个单独的线程中接收我的数据,但仍然需要将该数据上传到GPU进行显示。

我知道2个型号。

  • 使用动态资源: 您创建一个与输入图像具有相同大小和格式的动态纹理,当您收到一个新图像时,您设置一个标志,告诉您需要上传,然后在设备上下文中使用map上传纹理数据(最终加倍)缓冲当然)。

    优点是你有一个内存位置,因此随着时间的推移你没有内存碎片。

    缺点是您需要立即上传,因此您的上传必须在渲染循环中。

  • 使用immutable和load / discard 在这种情况下,您在图像接收线程中上传,通过创建新资源,推送数据并丢弃旧资源。

    优点是你应该有一个免费上传(不需要立即上下文,你仍然可以在上传纹理时运行你的命令列表),资源可以使用一个简单的触发器一旦可用(交换SRV)。

    缺点是你可以随着时间的推移分割内存(通过以恒定的方式分配和释放资源(例如标准相机为30 fps)。

    此外,你必须自己处理节流(但这部分并不是什么大问题)。

那么我在这些技术中错过了什么,或者有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

这是更新纹理D3D11的两种主要方法。

但是,假设第一种方法不会导致内存使用模式与第二种情况相同,这取决于驱动程序,可能并非如此。如果要覆盖整个图像(听起来就像你正在做的那样),你可以使用D3D11_MAP_WRITE_DISCARD,这意味着缓冲区的当前内容变得不确定。但是,这只能从CPU的角度来看。如果它们可能用于挂起的绘制操作,则它们将保留用于GPU。在这种情况下,大多数(可能是所有?)驱动程序实际上将为映射纹理的写入位置分配新存储,否则命令缓冲区处理将需要停止。如果您不使用discard标志,则同样适用。相反,当在命令缓冲区中处理map命令时,资源的缓冲区将更新为D3D11_MAPPED_SUBRESOURCE中Map返回的值。

此外,您必须在直接上下文中更新动态纹理。只有在延迟上下文中更新它们时,才必须使用D3D11_MAP_DISCARD标志。这意味着如果要覆盖整个纹理,可以更新工作线程上的纹理。

最重要的是,由于PC上的CPU / GPU系统不是统一的内存系统,因此更新来自CPU的GPU资源会出现同步问题。