了解DirectX管道优化
Understanding DirectX pipeline optimisations
我正在尝试改进我实施的一些简单的DirectX渲染代码。我的想法是绝对需要在必要时更新渲染管道,因为我的理解是尽可能最大程度地减少管道修改的数量是有益的。我的意思是以下伪代码:
ID3D11VertexShader *t_shader = getVertexShader();
ID3D11DeviceContext->VSSetShader(t_shader, nullptr, 0);
// Do some other processing/pipeline setup without modifying t_shader
ID3D11DeviceContext->VSSetShader(t_shader, nullptr, 0);
ID3D11DeviceContext->Draw(10, 0);
这是效率低下的,因为当着色器没有更改时,我们将两次调用VssetShader。这是一个过度简化的,但希望您能得到我的来源,我的基本理解是这些类型的不必要的绑定/呼叫效率低下?
如果是这种情况,那么可以在两个单独的ID3D11deviceContext :: draw呼叫之间进行以下优化吗?(再次,伪码,请原谅丢失的步骤,并假设我们要做的就是在我们绘制之前设置一个顶点& amp; amp; amp; amp; amp;
void Object1::Draw() {
ID3D11VertexShader *t_vs = ShaderMgr::vertexShader1();
ID3D11DeviceContext->VSSetShader(t_vs, nullptr, 0);
ID3D11PixelShader *t_ps = ShaderMgr::pixelShader1();
ID3D11DeviceContext->PSSetShader(t_ps, nullptr, 0);
ID3D11DeviceContext->IASetPrimitiveTopology(ID3D11_PRIMITIVE_TOPOLOGY_LINELIST);
ID3D11DeviceContext->Draw(m_vertexCount, 0);
}
void Object2::Draw() {
ID3D11VertexShader *t_vs = ShaderMgr::vertexShader1();
ID3D11DeviceContext->VSSetShader(t_vs, nullptr, 0);
// Use a different pixel shader to Object1
ID3D11PixelShader *t_ps = ShaderMgr::pixelShader2();
ID3D11DeviceContext->PSSetShader(t_ps, nullptr, 0);
ID3D11DeviceContext->IASetPrimitiveTopology(ID3D11_PRIMITIVE_TOPOLOGY_LINELIST);
ID3D11DeviceContext->Draw(m_vertexCount, 0);
}
两个抽奖调用之间的唯一区别是使用其他像素着色器。因此,以下可能的优化是否有效地重置管道?
void Object1::Draw() {
// Removed common set code
ID3D11PixelShader *t_ps = ShaderMgr::pixelShader1();
ID3D11DeviceContext->PSSetShader(t_ps, nullptr, 0);
ID3D11DeviceContext->Draw(m_vertexCount, 0);
}
void Object2::Draw() {
// Removed common set code
ID3D11PixelShader *t_ps = ShaderMgr::pixelShader2();
ID3D11DeviceContext->PSSetShader(t_ps, nullptr, 0);
ID3D11DeviceContext->Draw(m_vertexCount, 0);
}
void drawObjects() {
// Common states amongst object1 and object2
ID3D11VertexShader *t_vs = ShaderMgr::vertexShader1();
ID3D11DeviceContext->VSSetShader(t_vs, nullptr, 0);
ID3D11DeviceContext->IASetPrimitiveTopology(ID3D11_PRIMITIVE_TOPOLOGY_LINELIST);
m_object1->draw();
// Don't bother setting the vs or topology here
m_object2->draw();
}
任何反馈/信息都将不胜感激。
只是在我自己的问题上发布答案,因为我在测试代码中发现了一个错误,该错误蒙上了问题,希望这会帮助看到其他任何人。
我的困惑是因为在我的测试代码中,我只有一个我渲染的一个对象,一个简单的平面。它使用的唯一资源是顶点缓冲区,顶点着色器和像素着色器。我尝试添加上面提到的优化,以尝试尽可能减少ID3D11D11DeviceContext调用的数量。对于这个简单的对象,对我来说似乎很明智,即ID3D11D11deviceContext呼叫,例如VSSETSHADER,PSSETSHADER等只需要一次调用一次,因为这是唯一呈现的对象。但是,事实并非如此,因为一旦网格消失了,并且再也不会渲染。
在Renderdoc的帮助下,我能够捕获一个渲染的框架,并注意到当我只期待一个时,有两个打电话。我忘记了我的SpriteFont和SpriteBatch类是通过Directxtk创建的,用于写出我的相机位置进行调试。这个呼叫正在修改管道状态,同时绕过我的管道类(控制这些优化)而没有我意识到。这意味着当第二次渲染网格时,管道处于不正确的状态。
因此,事实证明这些优化是可能的,并且由于拉动呼叫的结果未清除管道。因此,如果您有上述示例类似的内容,那么它足以在呼叫之间一次调用上下文呼叫。我还了解到,诸如Renderdoc或Visual Studios内置的调试工具渲染调试器对于跟踪这些类型的问题至关重要。
- 空基优化子对象的地址
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- IPC使用多个管道和分支进程来运行Python程序
- 关闭||运算符优化
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 返回值优化:显式移动还是隐式
- 人脸跟踪arduino代码的优化
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 纯函数,为什么没有优化
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 如何以优化的方式同时迭代两个间距不相等的数组
- 如何创建函数管道,以便函数一个接一个地运行?
- 小字符串优化(调试与发布模式)
- Gstreamer 管道从命令 lne 到 c 代码
- 浮点定向舍入和优化
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- Visual Studio 调试优化如何工作?
- 将旧管道转换为现代 openGL 时出现问题
- 了解DirectX管道优化
- 英特尔Sandybridge系列CPU中管道程序的去优化