zoukankan      html  css  js  c++  java
  • 我对D3D中的顶点缓存的概念感到迷惑,特别是其分配和锁定的操作,不知道这些名称的含义是什么(转载)?

    当"allocating vertex buffers_分配顶点缓存"时:

    当使用 STATIC(这个是.net 情况,对于非.net版本dx是没有指定D3DUSAGE_DYNAMIC)标识分配顶点缓存时,这块缓存位于显存中。它的典型应用是只写一次并不被读回内存的情况。
    只有当标志 D3DUSAGE_DYNAMIC被设置时 D3DUSAGE_WRITEONLY标志才有意义。
    如果使用DYNAMIC标志创建缓存 (使用D3DUSAGE_DYNAMIC创建的缓存) ,并且D3DUSAGE_WRITEONLY 被使用,缓存被分配到显存中。

    如果使用DYNAMIC标志创建缓存 (使用D3DUSAGE_DYNAMIC创建的缓存) ,并且D3DUSAGE_WRITEONLY 不被使用, 缓存被分配到AGP 缓存中。(CPU从AGP缓存中读取的速度比显存中快,但比内存慢,是个很好的折中)
    如果没有足够的显存,顶点缓存被分配到AGP缓存中;如果AGP缓存也不够时,创建失败,除非使用POOL_ MANAGED 创建。在这种情况下,D3D的运行库会释放足够多的显存,用来创建顶点缓存,并在内存中保存创建的缓存的一个拷贝。那些被运行库释放的显存,在需要它们时可以从内存中复制到显存中。注意标志POOL_ MANAGED 并不被发送到驱动程序,因为这是D3D的附加的功能。

    对于NV1X 系列的GPUs, 在进行多数据流渲染得时候,如果有一个顶点缓存位于AGP缓存中,所有的其他位于显存中的顶点缓存会被移动到AGP缓存中。 

    当" locking vertex buffers_锁定顶点缓存"时:

    如果顶点缓存的创建标志是POOL_DEFAULT: 

    如果没有指定任何标志,程序将被暂停,因为它强制程序和GPU同步操作。->低效

    如果指定D3DLOCK_NOOVERWRITE 标志,应用程序不会改变缓存区已存在的内容,运行库会在以后继续使用这块缓存。当应用程序调用这个函数时,驱动程序立即返回。->高效

    如果指定D3DLOCK_DISCARD 标志,程序将会更新整个缓存的值,实际上是分配一块新的缓存,即驱动程序重命名它。->高效

    [注解:因为CPU和GPU是异步的操作,所以当CPU通过系统总线和GPU同步时,需要等到GPU把当前的工作做完。例如,当GPU正在对一块缓存进行DMA操作时,但往往CPU并不对GPU操作的那块缓存进行操作,所以CPU可以和GPU一起工作。当不指定操作标志时,CPU等待GPU完成绘制工作才更新顶点缓存,所以低效。如果指定D3DLOCK_NOOVERWRITE,表示CPU只更新顶点缓存中剩余的缓存,不考虑是否有其他图形绘制是正在使用这个的缓冲区段绘制图形,强制更新那段缓存并返回,而不像默认参数0那样等待前面的绘制结束,而不更新已经写入的顶点值,所以在CPU写入的时候,GPU可以并行的对那些已经存在的顶点值进行DMA等操作,所以高效;如果使用D3DLOCK_DISCARD 标志,说明当前分配的缓存大小不够了,需要重新使用缓存,CPU对这些新分配的缓存区域进行写操作,GPU这时可能还在异步处理旧的缓存区,所以这种调用也是高效的。调用完毕,收回释放的缓存。]


    来自 GameRes 说明了 Lock 的标志含义,我改了一部分内容。因为 D3DLOCK_NOOVERWRITE 和 D3DLOCK_DISCARD 是要经常使用的。越熟练越好
    NOOVERWRITE 并不是不覆盖数据,如果2个三角形在缓存中地址相同。后面定点内容会覆盖前面的。而前面的三角形将不能画出来。

    如果缓冲区开的足够大,render 几帧才能使用完这个缓冲。可以一直使用NOOVERWRITE 就可以。当不够使用时在从头开始使用这个顶点缓冲。如果足够大。开头的顶点基本确定已经画完(都是前几帧的图形顶点内容了。被覆盖也无所谓),如果缓冲很小lock时可以调用DISCARD,表示丢弃缓冲区内容(被丢弃的内容如果在使用中还可以被GPU继续使用。NOOVERWRITE 不会保留,所以速度更好)。如下使用开头的6个顶点画2个四边形。但该用NOOVERWRITE 将之后后面的四边形

       Quad->Lock(0, 6*sizeof(Vertex), (void**)&v, D3DLOCK_DISCARD);

       // quad built from two triangles, note texture coordinates:
       //v += 6;
       v[0] = Vertex(0.0f, 0.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
       v[1] = Vertex(0.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
       v[2] = Vertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

       v[3] = Vertex(0.0f, 0.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
       v[4] = Vertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
       v[5] = Vertex( 1.0f, 0.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);

       Quad->Unlock();

       Device->SetTexture(0, Tex1);
       Device->SetStreamSource(0, Quad, 0, sizeof(Vertex));
       Device->SetFVF(Vertex::FVF);
       Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

       Quad->Lock(0, 6*sizeof(Vertex), (void**)&v, D3DLOCK_DISCARD);
         // quad built from two triangles, note texture coordinates:
       v[0] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
       v[1] = Vertex(-1.0f,  0.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
       v[2] = Vertex( 0.0f,  0.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

       v[3] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
       v[4] = Vertex( 0.0f,  0.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
       v[5] = Vertex( 0.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);

       Quad->Unlock();

       Device->SetTexture(0, Tex);
       Device->SetStreamSource(0, Quad, 0, sizeof(Vertex));
       Device->SetFVF(Vertex::FVF);
       Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

    当使用 D3DLOCK_NOOVERWRITE  标志时,似乎Lock 使用偏移地址没什么意义.或许可以提高性能

  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/lancidie/p/1848116.html
Copyright © 2011-2022 走看看