首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DirectX 11中的渲染

DirectX 11中的渲染
EN

Stack Overflow用户
提问于 2015-06-24 07:43:48
回答 1查看 2.5K关注 0票数 4

当框架启动时,我执行逻辑更新并在此之后进行呈现。在我的渲染代码中,我会做一些平常的事情。我设置了几个状态,buffors,纹理,并通过调用绘图结束。

代码语言:javascript
复制
m_deviceContext->Draw(
        nbVertices,
        0);

在帧结束时,我调用present来显示呈现的帧。

代码语言:javascript
复制
// Present the back buffer to the screen since rendering is complete.
if(m_vsync_enabled)
{
    // Lock to screen refresh rate.
    m_swapChain->Present(1, 0);
}
else
{
    // Present as fast as possible.
    m_swapChain->Present(0, 0);
}

平常的事。现在,当我调用call时,根据MSDN

绘制提交工作到呈现管道。

这是否意味着数据被发送到GPU和主线程(称为绘图)继续?还是等待渲染完成?

在我看来,只有现在的函数应该使主线程等待渲染完成。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-25 08:31:42

有许多调用可以触发GPU开始工作,Draw就是其中之一。其他的包括DispatchCopyResource等。MSDN文档想要说的是像PSSetShader这样的东西。IASetPrimitiveTopology等在你打电话给Draw之前什么也不做。

当您调用Present时,它被视为“框架结束”的隐式指示符,但是您的程序通常可以在完成第一个帧并显示之前继续设置下一个帧的呈现调用。默认情况下,Windows允许您在Present调用中阻塞CPU线程之前排队最多3帧,以便GPU实时呈现您通常不希望输入和呈现之间的延迟非常高。

然而,事实是,GPU/CPU同步非常复杂,Direct3D运行时也在处理请求,以最小化内核调用开销,因此在将许多抽签提交到命令队列之后,实际工作就可以进行了。这篇旧文章为您提供了这方面的工作方式。在现代GPU上,您还可以进行各种内存操作,以便在内存中分页、设置物理视频内存区域等。

顺便说一句,所有这些“魔力”都不存在于Direct3D 12中,但这意味着应用程序必须在“正确的时间”做任何事情,以确保它既高效又实用。程序员更直接地建立命令队列,触发各种像素和计算GPU引擎的工作,并完成由Direct3 11运行时处理的所有杂乱无章的操作。即使是这样,最终视频驱动程序也是真正与硬件对话的驱动程序,这样他们也可以进行其他类型的优化。

这里要记住的一般经验法则是:

  • 创建资源非常昂贵,特别是运行时着色器编译(由HLSL编译器编写)和运行时着色器blob优化(通过驱动程序)。
  • 将资源复制到GPU (即从CPU内存加载纹理数据)需要有限的总线带宽:更愿意将纹理、VB和IB数据保存在静态缓冲区中,您可以重用。
  • 从GPU复制资源(即将GPU内存移动到CPU内存)使用一个比到GPU慢的反向通道:尽量避免从GPU读取数据。
  • 每次绘制调用提交更大的几何图形块有助于摊销开销(例如,对于具有相同状态/着色器的10 000个三角形调用一次绘图比调用10次绘制1000个三角形的速度要快得多,每个三角形之间的状态/着色器都在变化)。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31020638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档