技术经验分享:d3d9查询(QueriesDirect3d9)

简介: 技术经验分享:d3d9查询(QueriesDirect3d9)

D3D9查询(Queries Direct3d9)


来源:d3d9帮助文档 Queries(Direct3d9)


翻译:游蓝海(


说明:费了好大劲,终于看懂了d3d9 queries,翻译一下跟大家共享。第一次翻译文章,有很多地方不准确,请多多见谅。


概述


有很多种查询,用来查询资源的状态,这些资源状态包括图形处理单元(GPU)的状态、驱动状态、运行时状态。为了理解不同类型的查询,你需要先理解查询状态。下面的状态流图,说明了每个查询的状态。


查询状态图


图表列举出了3种状态(Signaled State, Building State, Issued State),分别用圆圈表示。实线表示应用程序驱动事件引发的状态传递,虚线表示资源驱动事件将一个查询从完成状态(Issued State)切换到了就绪状态(Signaled State),每种状态都有不同的用处:


·就绪状态(Signaled State):像是一个空闲的状态。查询对象已经生成,等待应用程序来完成此次查询。当查询结束,查询状态转变为就绪状态时,就可以获取到查询结果了。


·创建状态(Building State): 像是一个暂存区域。在创建状态,查询已经被发起(通过调用D3DISSUE_BEGIN),但还没有转换到完成状态。当应用程序申明查询结束(通过调用D3DISSUE_END),查询便转换到了完成状态。


·完成状态(Issued State): 表示被查询的资源已经接管了查询。当资源完成工作后,会将状态机转换到就绪状态。在完成阶段,应用程序必须检测是否已经转变成就绪状态,如果是就绪状态,那么GetData返回的就是需要的查询结果了。


一些查询需要开始和结束事件,但是有些仅需要结束事件。仅需要一个结束事件的查询,会在一些暗含的事件发生后自动开始。所有的查询都会返回一个结果,除了事件查询(event query)总是会返回TRUE。


创建查询(Create a query)


在创建查询之前,你可以检查运行时(runtime)是否支持此查询,调用CreateQuery,并传入一个NULL,如下:


IDirect3DQuery9 pEventQuery;


// Create a device pointer m_pd3dDevice


// Create a query object


HRESULT hr = m_pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, NULL);


如果该查询可以被创建,改方法返回成功码;否则,返回一个错误码。一旦CreateQuery调用成功,你可以这样创建一个查询:


IDirect3DQuery9 pEventQuery;


m_pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery);


如果函数调用成功,一个查询对象就创建完成了。查询初始为就绪状态,等待被激活。当查询对象使用完毕之后,像其他d3d对象一样,释放掉它。


发起查询Issue a Query


应用程序通过发起查询来改变一个查询的状态,这里有一个发起查询的例子:


IDirect3DQuery9 pEventQuery;


m_pD3DDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery);


// Issue a Begin event


pEventQuery->Issue(D3DISSUE_BEGIN);


or


// Issue an End event


pEventQuery->Issue(D3DISSUE_END);


当发起之后,一个处于就绪状态的查询,将会这样改变:


发起类型


查询变成这样 . . .


D3DISSUE_BEGIN


创建状态(Building state).


D3DISSUE_END


完成状态(Issued state).


发起之后,一个处于创建状态的查询,将会这样改变:


发起类型


查询变成这样 . . .


D3DISSUE_BEGIN


(仍然是创建状态,会 重置查询框架 .)


D3DISSUE_END


完成状态.


发起之后,一个处于完成状态的查询,将会这样改变:


发起类型


查询变成这样 . . .


D3DISSUE_BEGIN


创建状态并且重置查询框架。


D3DISSUE_END


放弃已经存在的查询,仍然是完成状态。


检查查询状态以及获得查询结果(Check the Query State and Get the Answer to the Query)


GetData做了两件事情:


1.通过函数返回值,返回查询状态。


2.通过参数pData,返回查询结果。


针对三种查询状态,GetData的返回值如下:


查询状态


GetData 返回值


Signaled


S_OK


Building


Error code


Issued


S_FALSE


例如,当查询处于完成状态时,查询结果不可用,GetData会返回S_FALSE。当资源完成它的工作并且应用程序已经发起过查询结束事件,资源将使查询状态转为就绪状态。在就绪状态中,如果GetData返回S_OK,则表示查询结果已经写入了pData中。举个例子,以下查询事件,返回了一次渲染中绘制的像素个数:


·创建查询。


·发起查询开始事件。


·渲染一些东西。


·发起查询结束事件。


下面是该查询的源码:


IDirect3DQuery9 pOcclusionQuery;


DWORD numberOfPixelsDrawn;


m_pD3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &pOcclusionQuery);


// Add an end marker to the command buffer queue.


pOcclusionQuery->Issue(D3DISSUE_BEGIN);


// API render loop


...


Draw(...)


...


// Add an end marker to the command buffer queue.


pOcclusionQuery->Issue(D3DISSUE_END);


// Force the driver to execute the commands from the command buffer.


// Empty the command buffer and wait until the GPU is idle.


while(S_FALSE == pOcclusionQuery->GetData( &numberOfPixelsDrawn,


sizeof(DWORD), D3DGETDATA_FLUSH ))


;


这些代码做了这些事情:


·调用GetData获取已经绘制的像素个数。


·设定 D3DGETDATA_FLUSH参数,表明允许资源将查询转换成就绪状态。


·不断的检查资源,只要返回S_FALSE,就表示还没有拿到结果。


GetData返回了当前的查询状态。他的返回值可能是S_OK,S_FALSE或者是一个错误码。注意,不要在创建状态调用GetData.


S_OK表示资源 (GPU or driver, or runtime) 已经完成了工作,此时查询已经变成了就绪状态,GetData已经返回了查询结果。


S_FALSE 表示资源 (GPU or driver, or runtime) 目前还不能返回结果.。这表示GPU还没完成工作或者还没执行到查询。出现错误,表示查询出现了致命错误,这可能是设备丢失导致的。如果查询已经出现了错误(不是S_FALSE),查询必须要重新创建,然后从就绪状态重新开始。


除了指定 //代码效果参考:http://www.jhylw.com.cn/330319977.html

D3DGETDATA_FLUSH参数外,也可以传入0,进行轻量级的查询状态检测。传入0时,GetData将不会刷新命令缓冲区,因此,需要小心查询陷入死循环。当运行时工作在命令缓冲区时,D3DGETDATA_FLUSH模式将有一次机会刷新缓冲区,将查询转变成就绪状态。

例子: 事件查询


事件查询不支持begin event.


创建查询。产生一个结束事件。一直检测,直到GPU完成工作。产生一个结束事件。


IDirect3DQuery9 pEventQuery = NULL;


m_pD3DDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery);


// Add an end marker to the command buffer queue.


pEventQuery->Issue(D3DISSUE_END);


// Empty the command buffer and wait until the GPU is idle.


while(S_FALSE == pEventQuery->GetData( NULL, 0, D3DGETDATA_FLUSH ))


;


... // API calls


// Add an end marker to the command buffer queue.


pEventQuery->Issue(D3DISSUE_END);


// Force the driver to execute the commands from the command buffer.


// Empty the command buffer and wait until the GPU is idle.


while(S_FALSE == pEventQuery->GetData( NULL, 0, D3DGETDATA_FLUSH ))


;


应用程序需要特别注意刷新命令缓冲区产生的开销,这源于操作系统会切换到内核模式,因此产生了相当大的性能损耗。应用程序也应该意识到等待查询结束时浪费的cpu循环。


在渲染期间,查询可作为优化来增加性能。花费时间等待查询结束没有益处。取代上面循环的位置,如果查询已经是完成状态,但是应用程序还没有拿到查询结果,优化尝试失败,渲染应该像平常一样继续进行。经典的例子就是隐藏面剔除。如果查询完成,应用程序可以使用查询结果来实现隐藏面剔除;如果查询没有完成,这时跳过隐藏面剔除测试,直接渲染物体,就仿佛是测试不成立,物体没有被裁减。


IDirect3DQuery9 pOcclusionQuery = NULL;


m_pD3DDevice->CreateQuery( D3DQUERYTYPE_OCCLUSION, &pOcclusionQuery );


// Add a begin marker to the command buffer queue.


pOcclusionQuery->Issue( D3DISSUE_BEGIN );


... // API calls


// Add an end marker to the command buffer queue.


pOcclusionQuery->Issue( D3DISSUE_END );


// Avoid flushing and letting the CPU go idle by not using a while loop.


// Check if queries are finished:


DWORD dwOccluded = 0;


if( S_FALSE == pOcclusionQuery->GetData( &dwOccluded, sizeof(DWORD), 0 ) )


{


// Query is not done yet or object not occluded; avoid flushing/wait by continuing with worst-case scenario


pSomeComplexMesh->Render();


}


else if( dwOccluded != 0 )


{


// Query is done and object is not occluded.


pSomeComplexMesh->Render();


}

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
5月前
|
存储 监控 安全
【实战经验】记录项目开发常见的8个难题
风沙席地起,战马踏风归!
273 21
|
6月前
|
SQL 存储 数据可视化
技术经验分享:ArcGISEngine开发之属性查询
技术经验分享:ArcGISEngine开发之属性查询
74 0
|
7月前
|
Java 数据库
阿里后台开发面经分析:如何才能更好地回答问题?
阿里后台开发面经分析:如何才能更好地回答问题?
54 0
|
7月前
|
安全 数据挖掘
|
Cloud Native Go 项目管理
如何在技术面试中展示领导能力
如何在技术面试中展示领导能力
187 0
|
消息中间件 Cloud Native 中间件
盘点2022:开源热度居高,技术思考与经验分享是开发者的最爱
阿里巴巴中间件陪伴大家又是一年了,春节即将到来,我们不禁回望,这一年我们留下了什么,又收获了什么。
156 7
|
SQL 数据采集 数据可视化
用户数据分析与最佳实践以手游为例|青训营笔记
在企业竞争越来越激烈,获客成本越来越高的背景下,如何高效地优化产品和精细化投放运营是当前企业竞争的关键,而用户数据分析正是我们保持此竞争力的重要手段。
259 0
用户数据分析与最佳实践以手游为例|青训营笔记
|
数据采集 自然语言处理 数据可视化
|
存储 SQL 分布式计算
【小白视角】大数据基础实践(二)Hadoop环境搭建与测试
【小白视角】大数据基础实践(二)Hadoop环境搭建与测试
321 0
【小白视角】大数据基础实践(二)Hadoop环境搭建与测试
下一篇
DataWorks