D3D9学习笔记(三) Device

2.1架构

2.2类型

基本的device类型:hal:硬件渲染(发布)。这也不是直接访问硬件驱动,而是访问在上一层的hal。(在顶点处理过程中,如果硬件处理失败,可尝试混合处理及纯软处理,设定标志D3DCREATE_MIXED_VERTEXPROCESSING)

                                       soft软件渲染(但是这种软渲染并不一定拥有同当前硬件相同的渲染能力,所以要经常检查)

                                       ref完全精密的实现所有特征的软渲染可以,可用于验证feature,使用那些还没被做到硬件的feature,也可以用来验证是不是硬件驱动有bug,因为它是最规范完整的按feature来渲染。

2.3一些问题

xp与vista的显示的一些问题

 

1.在安全桌面下:如屏保、锁定、未登入状态等,hal device是不能访问的,D3D9的device会创建失败。但是vista可以使用系统service来创建

2.远程桌面:XP下不能再远程桌面上创建DEVICE vista可以通过remote desktop session来创建

 

2.4选择硬件设备

1 枚举硬件

IDirect3D9:: GetAdapterCount()获取显卡数量,D3D9中的显卡表示为0-GetAdapterCount()-1的整数,主显卡也可用D3DADAPTER_DEFAULT表示。

另外可以用IDirect3D9::GetAdapterIdentifier获取显卡的厂商类型等信息。

2.获取指定显卡支持的显示模式

IDirect3D9::EnumAdapterModes.

IDirect3D9::GetAdapterDisplayMode可获取硬件当前的显示模式

3.(可选)查询设备是否支持要用到的一些硬件加速,他还能查询设备是否支持swap chain

IDirect3D9::CheckDeviceType(窗口模式可省)

4.获取当前硬件的渲染能力

IDirect3D9::GetDeviceCaps

5,当渲染到一个surface时,通常要检查这个surface的格式是是否可以用于texture、rendertarget、depth-stenil
buffer

IDirect3D9::CheckDeviceFormat.(窗口模式可省)

 

6.查询一个硬件是否支持某种多采样技术(反走样)

IDirect3D9::CheckDeviceMultiSampleType(窗口模式可省)

 

较高的多采样和多backbuffer会严重增加显存的使用

 

2.5创建device

创建操作只能在当前激活的窗口显示的同一个线程中

1.创建一个D3D object,(这个创建多个会严重影响性能)。

IDirect3D9 *Direct3DCreate9(UINT
SDKVersion),失败返回null。参数永远是D3D_SDK_VERSION

2.创建device

IDirect3D9::CreateDevice(

  [in]           UINT Adapter,--显卡

  [in]           D3DDEVTYPE DeviceType, --类型

  [in]           HWND hFocusWindow,--窗口

  [in]           DWORD
BehaviorFlags,

  [in, out]      D3DPRESENT_PARAMETERS *pPresentationParameters,--设备的主要参数

  [out, retval]  IDirect3DDevice9 **ppReturnedDeviceInterface

*UINT Adapter显卡:D3DADAPTER_DEFAULT为主显卡

* D3DDEVTYPE

  D3DDEVTYPE_HAL           = 1, hal

  D3DDEVTYPE_NULLREF       = 4,--只创建资源,所有要求传入D3DDEVTYPE类型参数的函数都会失败

  D3DDEVTYPE_REF           = 2,ref

  D3DDEVTYPE_SW            = 3,使用插件的软渲染,插件要用,IDirect3D9::RegisterSoftwareDevice注册

* BehaviorFlags

D3DCREATE_ADAPTERGROUP_DEVICE只对主显卡有效,让设备驱动输出给它所拥有的所有显示输出

D3DCREATE_DISABLE_DRIVER_MANAGEMENT代替设备驱动来管理资源,这样在发生资源不足时D3D调用不会失败

D3DCREATE_DISABLE_PRINTSCREEN:不注册截屏快捷键,只对Direct3D 9Ex

D3DCREATE_DISABLE_PSGP_THREADING:强制计算工作必须在主线程上,vista以上有效

D3DCREATE_ENABLE_PRESENTSTATS:允许GetPresentStatistics收集统计信息只对Direct3D 9Ex

D3DCREATE_FPU_PRESERVE;强制D3D与线程使用相同的浮点精度,会降低性能

D3DCREATE_HARDWARE_VERTEXPROCESSING:指定硬件进行顶点处理,必须跟随D3DCREATE_PUREDEVICE

D3DCREATE_MIXED_VERTEXPROCESSING:指定混合顶点处理

D3DCREATE_SOFTWARE_VERTEXPROCESSING:指定纯软的顶点处理

D3DCREATE_MULTITHREADED:要求D3D是线程安全的,多线程时

D3DCREATE_NOWINDOWCHANGES:拥有不改变窗口焦点

D3DCREATE_PUREDEVICE:只试图使用纯硬件的渲染

D3DCREATE_SCREENSAVER:允许被屏保打断只对Direct3D 9Ex

D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING中至少有一个一定要设置

*D3DPRESENT_PARAMETERS  pPresentationParameters

typedef struct D3DPRESENT_PARAMETERS {

  UINT                BackBufferWidth;

  UINT                BackBufferHeight; --back buffer的长宽注意如果是全屏模式必须等于显卡的其中一种分辨率如果是窗口不填就用这个窗口的大小

  D3DFORMAT           BackBufferFormat; --backbuffer的格式(主要是颜色格式),必须与当前的render target相同。在窗口模式D3DFMT_UNKNOWN可以直接使用去匹配当前的显示格式,全屏不行

  UINT                BackBufferCount;   --backbuffer的数量0 -D3DPRESENT_BACK_BUFFERS_MAX之间,0代表创建一个(就是创建到0号缓存),函数调用返回失败时,将返回实际可以创建的backbuffer的数量

 

  D3DMULTISAMPLE_TYPE  MultiSampleType;--只有swapchain是D3DSWAPEFFECT_DISCARD才能使用多采样(用于反走样),否则都必须设置D3DMULTISAMPLE_TYPE

  DWORD               MultiSampleQuality;     -多采样的质量,0-CheckDeviceMultiSampleType之间,越大越高质量

 

 

  D3DSWAPEFFECT       SwapEffect;--swapchain在交换buffer时的参数,swapchain要按照顺序从backbuffer
n 往前到front buffer 交换数据

  HWND                hDeviceWindow; --窗口;窗口模式,就是显示的窗口,如果null,则使用当前的激活窗口。全屏模式,主显示器使用当前的激活窗口,其他显示器必须使用一个确定的窗口。当窗口重置时back buffer不会被重置。

  BOOL                Windowed; --是否全屏

  BOOL                EnableAutoDepthStencil;--是否让D3D自动管理depth buffer,如果true则下一个参数必须是个正确的参数

  D3DFORMAT           AutoDepthStencilFormat;

  DWORD               Flags; --一些在present显示时的参数

  UINT                FullScreen_RefreshRateInHz;--全屏时硬件刷新屏幕的频率,EnumAdapterModes返回的模式中选其一,窗口模式要填0,

  UINT                PresentationInterval; backbuffer交换给frontbuffer的最大频率

}

 

*D3DSWAPEFFECT 交换链参数

D3DSWAPEFFECT_DISCARD       = 1,

当使用flip和copy的时候,present会保证不影响每个buffer的内容,这会带来大量的显存开销,同时使用这个标记可以采取效率最高的交换方式,当buffer的东西被有效显示后,某些buffer里的数据就不保证正确性了,所以在present之前一定要先update整个backbuffer。如果采样方式不是用的D3DMULTISAMPLE_NONE一定都要用这个标记。

D3DSWAPEFFECT_FLIP          = 2,见1.3.1

  D3DSWAPEFFECT_COPY          = 3,见1.3.1

  D3DSWAPEFFECT_OVERLAY       = 4,

使用显存中特定的一块区域(overlay)当使用这块区域时不会发生从显存copy到内存中的操作,效率高,这只可以用于win7之后并且是D3D9ex的

  D3DSWAPEFFECT_FLIPEX        = 5,

D3DSWAPEFFECT_FLIP的更高效模式只可以用于win7之后并且是D3D9ex的

 

*DWORD   Flags

D3DPRESENTFLAG_DEVICECLIP

限制了window模式下客户端区域present操作的结构,暗示了back buffer包含有video。

D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL

在调用present后discard depth/stencil surface里面的内容。这样就使depth/stencil
surface是一个可写的surface。如果depth/stencil surface的格式是D3DFMT_D16_LOCKABLE或者
D3DFMT_D32_LOCKABLE设置这个标记将会返回一个错误。

D3DPRESENTFLAG_LOCKABLE_BACKBUFFER

backbuffer可以被锁定

D3DPRESENTFLAG_NOAUTOROTATE

不允许自动旋转显示器自动选择显示内容提高效率 D3D9ex可用

D3DPRESENTFLAG_VIDEO

说明backbuffer
有video

 

*UINT        PresentationInterval它说明了硬件的显示刷新率与present进行缓存swap的频率的二者的关系,这个参数会影响屏幕的实际的FPS等属性。显卡的刷新率不是真的FPS,那只是显卡给屏幕的重绘频率,真正的FPS是实际的swap的频率结合显卡的刷新频率,要看屏幕上最终是每秒显示了几次SWAP交换。

这里是为了解决gpu和显示输出对frontbuffer的冲突解决方式

 

D3DPRESENT_DONOTWAIT

present不被hal device处理,如果硬件在忙于处理或等待垂直同步(防止被撕裂),那么执行present会马上失败返回,即不发生交换缓存操作。也就是硬件忙的时候会保证垂直同步而不进行重绘制,它可能是可以保证画面不会出现撕裂,但是是以卡帧为代价。它的意思也是不要去锁定FPS。

D3DPRESENT_INTERVAL_ONE/~FOUR present等待垂直同步,但是保证present最多每1~4帧被打扰一次。这里是提高帧率与放置撕裂的权衡

D3DPRESENT_INTERVAL_IMMEDIATE

能present
就立即present,完全不管垂直同步了,最贴近实际的swap帧率。

D3DPRESENT_LINEAR_CONTENT

back buffer format is
X8R8G8B8.

其中

D3DPRESENT_INTERVAL_DEFAULT
基本机遇是D3DPRESENT_INTERVAL_ONE

 

垂直同步质量与FPS的关系(越往下FPS变高,垂直同步变差)

 

    D3DPRESENT_DONOTWAIT

         D3DPRESENT_INTERVAL_ONE

         D3DPRESENT_INTERVAL_TWO

         D3DPRESENT_INTERVAL_。。

         D3DPRESENT_INTERVAL_IMMEDIATE

 

 

2.6清理资源

当程序要退出或者需要废弃当前device重建新的时候,要清理D3D9资源,调用

VOID Cleanup()

{

    if( g_pd3dDevice != NULL)

        g_pd3dDevice->Release();

    if( g_pD3D != NULL)

        g_pD3D->Release();

}

时间: 2024-10-25 02:23:06

D3D9学习笔记(三) Device的相关文章

kvm虚拟化学习笔记(三)之windows kvm虚拟机安装

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1290191 KVM虚拟化学习笔记系列文章列表 ---------------------------------------- kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51cto.com/703525/1288795 kvm虚拟化学习笔记(二)之linux kvm虚拟机安装 h

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(Automation Executables) 2.Office加载项(COM or Excel Add-In) 3.Office文档代码或模板(Code Behind an Office Document or Template) 4.Office 智能标签(Smart Tags) 本次我们将学习使

Bootstrap3学习笔记(三)之表格_javascript技巧

在上篇文章给大家介绍了 BootStrap3学习笔记(一)之网格系统       Bootstrap3学习笔记(二)之排版 只需要在table标签上使用.table类,就可以使用bootstrap默认的表格样式 如果需要行背景有交替变化,可以这样设定: 复制代码 代码如下: <table class="table table-striped"> 如果需要边框,可以这样设定: 复制代码 代码如下: <table class="table table-borde

JavaScript学习笔记(三):JavaScript也有入口Main函数_javascript技巧

在C和Java中,都有一个程序的入口函数或方法,即main函数或main方法.而在JavaScript中,程序是从JS源文件的头部开始运行的.但是某种意义上,我们仍然可以虚构出一个main函数来作为程序的起点,这样一来不仅可以跟其他语言统一了,而且说不定你会对JS有更深的理解. 1. 实际的入口 当把一个JavaScript文件交给JS引擎执行时,JS引擎就是从上到下逐条执行每条语句的,直到执行完所有代码. 2. 作用域链.全局作用域和全局对象 我们知道,JS中的每个函数在执行时都会产生一个新的

DB2 UDB V8.1管理学习笔记(三)_DB2

正在看的db2教程是:DB2 UDB V8.1管理学习笔记(三).强制断开已有连接,停止实例并删除.  $ db2idrop -f instance_name 用于在UNIX下迁移实例. $ db2imigr instance_name 更新实例,用于实例获得一些新的产品选项或修订包的访问权. $ db2iupdt instance_name 获取当前所处的实例. $ db2 get instance 当更新实例级别或数据库级别的参数后,有些可以立即生效,有些需要重新启动实例才可生效.immed

Paint.Net学习笔记——三、窗体(下)

近1个月没有更新了,不能再懒了,继续更新PDN的学习笔记!本节将说明PDN中窗体的继承关系,实 现过程等. 如上图所示,在PDN中,所有窗体都继承自PdnBaseForm类,该类继承自Form类与ISnapManagerHost接 口,该接口定义了SnapManager的get方法,SnapManager是管理界面窗口"粘靠"效果的,该实现方法之 后文章中讲述. 现在快速地过一下各个窗体的作用及特点. BaseForm: 所有PDN里窗体的基类,主要提供常用窗体方法及注册.卸载热键.

Promise学习笔记(三):源码core.js解析(上)

源码阅读阶段 先理解Promise根本吧,想快点理解的话可以直接跳到下个标题.这部分根据理解将持续修改. Promise(fn) function noop() {}  /*  空函数,用于判断传入Promise构造器的函数是否为空函数,如果为空函数构造一个promise对象并初始化状态为pending,终值null,回调状态0和队列null.  */  var LAST_ERROR = null;//记录Promise内部最后的一次错误  var IS_ERROR = {}; //空对象,标识

cmake 学习笔记(三)

转自:http://blog.csdn.net/dbzhang800/article/details/6329314 接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我们需要知道: 去哪儿找头文件 .h 对比GCC的 -I 参数 去哪儿找库文件 (.so/.dll/.lib/.dylib/...) 对比GCC的 -L 参数 需要链接的库文件的名字

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle&lt;T&gt;

Caliburn.Micro学习笔记目录 今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子 看一它的的实现和源码 下一篇用它们做一个多语言的demo 这两个是事件的订阅和广播,很强大,但用的时候要小心发生不必要的冲突. 先看一下它的实现思想 在Caliburn.Micro里EventAggregator要以单例的形式出现这样可以做到对广播做到统一的管理 对象实现IHand<T>接口后通过EventAg