Direct3D的一些小贴士收藏(转载)

GPU性能调试:

通常来说,使用CPU时间事件来调试GPU是低效并且是不准确的。D3D API在多数命令下会阻塞,甚至是Draw函数。它会在一些时间片上做一些真正的工作,而这往往是不可预知的。因此,GPU的性能调试只能用PIX或者是其他专用产品,例如NVIDIA’s NVPerfHUD来进行。

显卡所用的内存:

显卡所用的内存可以分为两大类:本地的和非本地的(相对于显卡来说)。在显卡处理的某些数据类型的时候,需要本地内存,例如 帧缓冲。 非本地内存,有时也成为AGP卡槽内存(AGP aperture),可以被显卡访问的某些数据类型所在的系统内存,例如顶点缓冲。本地内存要比非本地内存快。

本地内存通常是在显卡内的,但是有些显卡可以共享系统内存,这通常是平衡速度和价格之间的选择。在这种情况下,帧缓存可以存在于系统内存中,而不是在本地内存中。这种技术下,显卡处理某些数据的速度比不使用共享内存的要慢,因为数据必须从I/O Bus(例如PCI-Express)上传输过来。但是这可以使显卡成本大大降低。在NVIDIA,这种技术被称为TurboCache,而ATI称之为HyperMemory。

着色器和着色模型:

Shader是运行在GPU上的,处理一些D3D流水管线上一些任务的程序。有三种类型的shader,他们分别对应三种可编程的stage:

Vertex shader (顶点着色器VS) stage, geometry shader (几何着色器GS) stage, 还有pixel shader(像素着色器PS) stage。其中几何着色器只能在DX10平台上使用。

着色模型(shader model)是在GPU上运行的虚拟机。每个虚拟机定义被称为一种shader profile。并且包含了特定的汇编语言。

着色器的职责:

着色器通常是流水管线中描述物体表面的部分。例如,一种看起来像木头的材质被称为木头着色器(wood shader)。而在D3D中,这些着色语言指令集可以做的事情远不止描述物体表面。他们可以用来计算光照,矩阵转换,顶点动画,进行裁切,动态生成新的几何物体,等等。在Mental ray中,shader按照职责可以划分为surface shader, light shader, shader shader, output shader等等。

在D3D中,这三种着色器的职责划分并不是很明确。例如,光照计算过可以在顶点着色器,或者是像素着色器中完成,这取决于应用程序的需求。因此,包含各种着色器的着色器集合应运而生。他们链接起来定义了一个工作流水线。

关于Direct3D 9 资源和内存类型:

D3D支持下列类型的资源:纹理(包括常规的和渲染目标render target),顶点缓冲,索引缓冲,字体,交换链(swap chain),状态组,深度模板缓冲,特效等等。

有四种内存类型(池),资源可以在这里分配:

·         默认Default:在显卡内存中,包括AGP卡槽内存和本地显存。在设备丢失之后,必须被释放,重构。

·         托管Managed:存在于系统内存中,按需拷贝到显存。

·         系统SystemMem:永远存在于系统内存中,并且不能直接用于渲染。可以当作源或者目标拷贝。例如UpdateSurface和UpdateTexture。

·         Scrach: 永远存在于系统内存中,并且不会被设备大小或格式限制,例如纹理的2的幂限制。不能把它放到显存中。

查找资源泄露:

在关闭一个基于D3D的应用程序时,D3D调试运行库会报告内存泄露。按照以下步骤定位泄漏点。

1.       在DirectX Control Panel中(通常在DXSDK安装目录中可以找到),启用“Use Debug Version of Direct3D 9”并且将Debug Output Level设置为”More”。确保Break on Memory Leaks被禁用。点击Apply。

2.       在VS中调试运行应用程序。在关闭应用程序之后,查看VS的输出窗口Direct 3D9: (WARN) : Memory Address:  00xxxxxx,  IAllocID= xx dwSize = xxxxxxxx;(pid = xxxxx)

3.       每条记录对应了一个资源泄漏,查看并记住ID,然后在DirectX Control Panel中输入ID并且点击Apply。

4.       再次运行程序,重复以上步骤。程序会在分配点中断,你可以检查哪里遗忘释放。

5.       当你调试完成之后,别忘了将Break On AllocID设置为0。

处理设备丢失(Device Lost)

一个D3D设备可以在很多情况下丢失,例如从全屏向窗口转换,一个电源管理事件,按CTRL+DEL+ALT返回Windows Security Dialog。

必须采取措施去检查一个设备是否丢失,丢失了之后如何恢复。

方法:在某些地方调用IDirect3DDevice9::TestCooperativeLevel,例如在每帧开始渲染之前调用。当发现设备丢失之后,采取下列措施:

1.       释放所有在Default内存中的资源

2.       释放其他没有和Default, Managed, SystemMem绑定的资源

3.       调用IDirect3DDevice9::TestCooperativeLevel去确认设备是否可以被重置如果能,那么调用IDirect3DDevice9::Reset 如果不能,继续等待,然后再尝试

4.       重新创建需要的资源

渲染目标和交换链(Render Targets and Swap Chains)

一个渲染目标是一个用于保存在图形流水线输出像素的表面。也就是说,它是一个颜色数组。一个设备可以有一个或者多个活动的渲染目标,可以通过SetRenderTarget来启用。一个用于渲染目标的表面只能放在Default池中,有三种渲染目标:

·         渲染目标表面Render target surfaces(通过CreateRenderTarget创建)

·         渲染目标纹理Render target textures(tongguo D3DUSAGE_RENDERTARGET标识来创建)

·         交换链Swap chains 交换链就是后备缓冲的集合,它们能够相继渲染到前缓冲,也就是屏幕上。一个在交换链中的后备缓冲可以当作一个渲染目标赋给一个设备。但是,不像其他的渲染目标,交换链可以渲染到屏幕上,因为交换链是和窗口/全屏大小绑定的。可以创建多个交换链,注意更改默认交换链大小会造成设备丢失,所以窗口程序会忽略默认的交换链,而使用一个附加的交换链来避免这个问题。渲染目标可以被锁定(用来读取),但是当这个渲染目标是活动的话,会影响系统性能。我们可以根据需要用IDirect3DDevice9::GetRenderTargetData来将一个在Default池中的渲染目标拷贝出来。可以使用IDirect3DDevice9::StrechRectangle在两个在显卡内存中的渲染目标中进行高效拷贝。

批处理(Batching)

D3D的效率在很大程度上受制于传给API的几何模型数据的批次上。一个批处理就是调用一次DrawPrimitive或者DrawIndexPrimitive。在GPU可以处理数据前,CPU花相当长时间来处理每批数据。现在常见的CPU和GPU,可以参考以下数据:

·         使用DX9,CPU每秒可以处理50000批次;使用DX10,这个数据是200000。

·         在DX9中,处理2000个三角形在CPU和GPU所花的时间大致相等。在DX10中,这个数据是500。简单的着色程序使这个数字增加,复杂的着色程序使这个数字减少。在CPU和GPU在同一个批次上花相同时间的情况下,实例化(Instancing)可以提高三角形的输出能力。因为以上原因,每个批次中处理数据的数量越大越好,这样能够将三角形的吞吐量最大化。

在实践中,具体有两种方式:

·         Consolidation合并:将相同性质的几何元素合并起来,通常是将一些属性进行排序的结果

·         Instancing实例化:将相同的几何物体,经过一些细微的,不同的变换后画出多个实例来。例如世界坐标系的转换和颜色转换。

顶点,索引缓冲Vertex / Index Buffer

顶点和索引缓冲有两种类型:静态和动态的。

一旦创建之后,静态的缓冲使用起来比动态的快一倍。但是,动态缓冲的加锁和解锁要比静态的快,它们是为更改的每一帧设计的,通常被存储在AGP卡槽内存中。经常对静态缓冲加解锁是不明智的,因为只有等驱动完成了所有挂起的命令之后才能返回该缓冲的指针。如果经常这样做,这会导致CPU和GPU很多不必要的同步,这样性能将会变得很差。

为了得到最好的性能,必须采用动态缓存。这样驱动可以继续进行并行渲染。使用DISCARD或者是NOOVERWRITING标志可以实现这一点,这样驱动可以在更新数据的同时继续处理老的数据。

DISCARD:这个标志说明应用程序不关心当前缓冲的内容。所以在缓冲被渲染的同时,驱动可以给应用程序一个全新的缓冲。这个处理称之为“buffer renaming”。注意,在实践中,驱动倾向于不去释放“缓冲重命名”中所用的内存,因此这个标志必须尽量少用。

NOOVERWRITE:这表示,对于之前添加的,不带这个标志的数据,应用程序不会更改它。例如应用程序只会在现有缓冲之后添加数据。所以驱动可以继续使用现有数据进行渲染。

CPU和GPU的并行处理

D3D runtime会将一堆命令做成命令串传给GPU,这就允许GPU和CPU进行并行处理。这样也是硬件加速渲染这么高效的原因之一。但是,在很多情况下,CPU和GPU必须进行同步之后才能做进一步的处理。通常来说,应该尽量避免这种情况,因为这会导致整个流水管线的刷新,大幅降低性能。例如,对静态缓冲加锁,这要求GPU先处理完所有的命令之后,才能返回被锁缓冲的指针。如果用动态缓冲,就可以避免,就像前面讲过的一样。

有一些同步是不可避免的,例如,CPU可能会需要一些GPU还来不及处理的命令结果。在这种情况下,用户会感到画面延迟Lag。要避免这种情况,可以在GPU落后两三帧的情况下调用Present来强迫CPU等待GPU。因此,调用Present可能比较慢,但是正式它处理了必要的同步。

状态的更换State Changes

不管冗余还是不冗余,状态的转换在到达驱动层的时候,开销总是很大。所以在某些层面,状态转换必须被过滤。一个对状态进行更换的函数调用并不一定会开销很大,因为D3D Runtime很有可能缓冲这些转换请求,在真正调用DrawPrimitive函数之前不会去执行它。多次的状态转换也不会加大开销,因为只使用最后一个状态值。尽管如此,状态转换还是应该尽量避免。某些状态转换会比其他的转换的开销更大。例如,对于更改处于活动状态的顶点缓冲和像素缓冲会导致整个流水管线的刷新。因为在某些显卡上,同一时间每个类型只有一个着色器可以处于活动状态。一个图形流水线可以很长,花一段时间才能完成一个像素的渲染。因此,整个流水线的刷新需要尽量避免。在不同的显卡上,某个状态的更新的花费差别可能会很大。另外,D3D的函数调用个数也必须尽量的少,虽然它的开销不如达到驱动层的状态更改那么大。可以使用状态块来减少D3D API的调用,状态块可以将状态的更改集中在一起,并且可以重用。

转载于:https://www.cnblogs.com/ComputerG/archive/2011/03/10/1979608.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字图像处理同态滤波(matlab)

定义 一幅图像可看成由两部分组成,即 fi代表随空间位置不同的亮度(Illumination)分量,其特点是缓慢变化,集中在图像的低频部分。fr代表景物反射到人眼的反射(Reflectance)分量,其特…

Java并发编程-ReentrantLock源码分析

一、前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到过ReentrantLock,ReentrantLock表示下面具体分析ReentrantLock源码。 二、ReentrantLock数…

谷歌浏览器好用的复制粘贴插件_copybetter增强复制 很好用的chrome复制粘贴插件 解除页面复制限制...

使用说明:增强复制(copybetter) 简介增强复制(copybetter)是一款国人开发的chrome浏览器复制增强扩展插件,作者参考了Copy Fixer和Autocopy两个扩展插件开发而成的。这里是他的个人网站:kodango.com。插件集成了关于复制粘贴功能的几个非常常…

绿色vmware 安装后看不到虚拟的网卡

绿色vmware 安装后看不到虚拟的网卡,按下面方法就可以添加。 1. 到Vmware 安装目录,运行 vmnetcfg,运行后出现虚拟网络编辑器 2. 转到主机虚拟适配器,单击添加 3. 转到网络连接就可以看到新增的vmware 虚拟网卡 转载于:https://www.cnblogs.c…

C语言strtok函数的用法

strtok是字符串切割函数 定义 参数一:待切割字符串参数二:分隔符集合首次调用时传递参数为: strtok(str,seps);之后再次调用时传递参数为: strtok(NULL,seps);​ 若可以切割,函数返回值为字符指针,各段切割好的字符串…

webservice接口等待时间_调用webservice超时问题的解决

1、web.config配置,里面增加:2、扩大代理类的超时限制,默认是90秒YourWebService yws new YourWebService();yws.Timeout 1200000; //20分钟3、IIS属性-网站 连接超时时间 1200秒1、修改 app.config 文件,添加如下代码&#x…

UItableViewCell滑动删除时,调整cell子视图的位置大小

UItableViewCell滑动删除时,调整cell的位置大小是否显示等。CustomTableViewCell为UITableViewCell的子类,在实现文件中重写willTransitionToState方法。willTransitionToState是在cell改变显示状态的时候调用,有三种状态:typedef…

表的转置

表的转置useSSISdroptablePTVgocreatetablePTV(TimeID nvarchar(10),ResourceID int,KPI1 numeric(38,2),KPI2 numeric(38,2),KPI3 numeric(38,2),KPI4 numeric(38,2),KPI5 numeric(38,2))goinsertintoptv values(101,1,2.78,3,5,4,4)insertintoptv values(102,2,2.7,50,95,44,…

51单片机C语言led流水灯及数码管实现秒表

51单片机C语言练习题 单片机型号 普中科技的 led练习题 led小灯闪烁 #include<reg52.h> sbit LED P0^0; void main() {unsigned int i0;while(1){LED 1;for(i0;i<60000;i);LED 0;for(i0;i<60000;i);} }led流水灯 #include<reg52.h>void main() {un…

extjs中元数据_Extjs中Store小总结

http://blog.csdn.net/without0815/article/details/77981701.什么是store&#xff1f;Store类似于一个本地仓库(即数据存储器),包括有 ArrayStore,DirectStore,GroupingStore,JsonStore,XmlStore(都是store的子类)最终主要用于提供给panel去显示.Store由Proxy(数据源)和DataRe…

内聚和耦合(自己的理解)

网上对于内聚和耦合的资料太多&#xff0c;这里结合我的感受和其他人的答案http://blog.csdn.net/zhiquan/article/details/4255161谈谈自己的理解 以下是我对内聚和耦合的理解&#xff08;例子来源于生活&#xff09;。 1.内聚&#xff1a; i.偶然内聚&#xff1a;如果一个模块…

UIButton return(textField textView)

首先设置TextField 或 TextView的 delegate /UITextView - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {if ([text isEqualToString:"\n"]) {NSLog("点击return");return NO;}retur…

(转)交换机攻击方法描述

利用交换机漏洞的攻击方法如下&#xff1a;一、生成树攻击生成树协议(STP)可以防止冗余的交换环境出现回路。要是网络有回路&#xff0c;就会变得拥塞不堪&#xff0c;从而出现广播风暴&#xff0c;引起MAC表不一致&#xff0c;最终使网络崩溃。使用STP的所有交换机都通过网桥协…

数据结构-顺序表(C语言实现)

主函数代码&#xff08;main.c&#xff09; #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include "sqlist.h" int main() {sqlist *list NULL,*list_next NULL;int pos 0;int i, err, value;int arr[10] { 10,20,30,40,50,60,70,80,90,100 };i…

shell的logo含义_Shell(壳牌石油)标志历史

荷兰皇家壳牌集团(Royal Dutch Shell&#xff0c;又译蚬壳)是世界第二大石油公司&#xff0c;总部位于荷兰海牙。荷兰皇家壳牌集团由荷兰皇家石油与英国的壳牌两家公司合并组成。荷兰皇家石油于1890年创立&#xff0c;并获得荷兰女王特别授权&#xff0c;因此被命名为荷兰皇家石…

无用的设计模式之装饰者模式

为什么80%的码农都做不了架构师&#xff1f;>>> 前言 装饰者设计模式本来是很常用的模式&#xff0c;常用到随处可见&#xff0c;jdk的bio设计都是遵循这个模式的&#xff0c;偶然的机会发现&#xff0c;貌似jdk中bio的装饰者模式和设计模式中的装饰者设计模式却有…

winform 程序制作自己的数字签名(续)

在上一篇文章《winform 程序制作自己的数字签名》中我们已经可以得到我们程序定制的数字签名了&#xff0c;但是比较讨厌的是每次编译之后&#xff0c;数字签名需要重新手动添加。 我们需要的是在程序编译时自动添加数字签名。 那实际上vs已经提供了此功能&#xff0c;具体操作…

转-HTC 手机生产日期,产地查询 以及 SN码 IMEI码 查询等问题汇总

问&#xff1a;什么是IMEI码&#xff1f;什么是SN码&#xff1f; 答&#xff1a;IMEI码&#xff0c;国际移动装备辨识码&#xff08;International Mobile Equipment Identity number&#xff0c;IMEI&#xff09;。SN码即Serial Number&#xff0c;产品序列号。 问&#xff1a…

数据结构带头结点单向不循环链表(C语言版)

main.c,负责测试 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include<stdlib.h> #include "linklist.h" int main() {LNode* listNULL;int i 0,err 0;datatype a 40,return_value0;datatype arr[] { 20,10,90,100,50,40,20,60,70,80 }…

Django设置TIME_ZONE和LANGUAGE_CODE为中国区域

Django默认的timezone是 TIME_ZONE America/Chicago LANGUAGE_CODE en-us 设置为中国区域&#xff1a; TIME_ZONE Asia/Shanghai LANGUAGE_CODE zh-cn 另外你可以根据情况设置 \Lib\site-packages\django\conf\global_settings.py 里面的时区转载于:https://www.cnblogs.co…