我正在创建一个简单的框架,用于在C ++ / D3D11下教授基本的图形概念。需要该框架以通过简单的界面功能(例如Putpixel( x,y,r,g,b )
)直接操纵屏幕栅格内容。
在D3D9下,这是一个相对简单的目标,方法是在CPU组成表面的堆上分配表面缓冲区。然后将锁定后缓冲区,并将堆缓冲区的内容传输到后缓冲区。据我了解,在D3D11下不可能直接从CPU访问后缓冲区。必须准备纹理资源,然后通过某种全屏几何图形将其绘制到后缓冲区。
我已经考虑过用于这种程序的两个系统。第一个包括D3D11_USAGE_DEFAULT
纹理和D3D11_USAGE_STAGING
纹理。首先映射过渡纹理,然后从CPU提取过渡纹理。场景完成后,将取消映射临时纹理并将其复制到默认纹理CopyResource
(如果我没记错的话,它将使用GPU进行复制),然后通过全屏纹理四边形将默认纹理绘制到后缓冲区。
第二系统包括D3D11_USAGE_DYNAMIC
纹理和分配在堆上的帧缓冲器。组成场景时,将映射动态纹理,通过CPU将堆缓冲区的内容复制到动态纹理,取消映射动态纹理,然后通过全屏纹理四边形将其绘制到后缓冲区。
我给人的印象是,通过读写访问创建的纹理D3D11_USAGE_STAGING
将驻留在系统内存中,但是我进行的性能测试似乎表明情况并非如此。即,通过CPU用暂存纹理绘制一个简单的200x200填充矩形比使用堆缓冲区慢大约3倍(两种情况下都需要完全相同的反汇编(紧密rep stos
循环)),这强烈暗示了暂存纹理驻留在图形适配器内存中。
我更喜欢使用暂存纹理系统,因为它可以将渲染到后缓冲区的工作以及从系统内存到图形内存的复制工作都卸载到GPU上。但是,在任何情况下,我都希望将CPU访问速度优先于这种能力。
那么对于这种使用情况,哪种方法是最佳的呢?我的两种方法的任何暗示,修改或完全不同的方法的建议,将不胜感激。
动态和暂存都可能在系统内存中,但是您的问题很有可能是写入组合内存。这是一种缓存模式,其中将单个写入合并在一起,但是如果您尝试读取(因为它是未缓存的),则每次加载都要付出全部内存访问的代价。您甚至必须非常小心,因为c ++*data=something;
有时可能还会导致不必要的读取。
动态纹理没有问题,GPU可以读取系统内存,但是您需要小心,创建一些内存,并使用map_nooverwrite循环每个帧,以禁止代价高昂的驱动程序缓冲区重命名丢弃对象。当然,永远不要在读写中进行映射,仅在写入时进行映射,否则您将引入gpu / cpu同步并杀死并行性。
最后,如果您想要一个持久的表面,并且每帧只有几个putpixel(甚至很多),我将使用无序访问视图和一个计算着色器,该着色器会消耗具有更新颜色的像素位置缓冲区。该缓冲区将再次成为没有覆盖覆盖映射的动态缓冲区。使用该解决方案,主表面将驻留在视频存储器中。
就个人而言,我什至不会去教CPU表面操纵,这几乎总是一种不好的做法,并且是性能的杀手,而不是现代gpu架构中的必经之路。十年前,这还不是一个基本的图形概念。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句