- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个 OpenGL 包装器,它允许我使用所有现有的图形代码(为 OpenGL 编写的)并将 OpenGL 调用路由到 Direct3D 等效项。到目前为止,这种方法的效果出奇的好,只是性能变成了一个相当大的问题。
现在,我承认我很可能以从未设计过的方式使用 D3D。我在每个渲染循环中更新了数千次单个顶点缓冲区。每次我绘制一个“ Sprite ”时,我都会使用纹理坐标等向 GPU 发送 4 个顶点,当屏幕上的“ Sprite ”数量一次达到 1k 到 1.5k 左右时,我的应用程序的 FPS 下降到低于 10 帧/秒。
使用 VS2012 性能分析(这很棒,顺便说一句),我可以看到 ID3D11DeviceContext->Draw 方法占用了大部分时间:
Screenshot Here
在设置顶点缓冲区或绘制方法期间,是否有一些设置我没有正确使用?为我的所有 Sprite 使用相同的顶点缓冲区真的非常糟糕吗?如果是这样,我还有哪些其他选项不会彻底改变我现有图形代码库的架构(围绕 OpenGL 范例构建......每帧都将所有内容发送到 GPU!)
我游戏中最大的 FPS 杀手是当我在屏幕上显示大量文本时。每个字符都是一个带纹理的四边形,每个字符都需要单独更新顶点缓冲区并单独调用 Draw。如果 D3D 或硬件不喜欢多次调用 Draw,那么你怎么能一次在屏幕上绘制大量文本呢?
如果您想查看更多代码来帮助我诊断此问题,请告诉我。
谢谢!
这是我正在运行的硬件:
void OpenGL::Draw(const std::vector<OpenGLVertex>& vertices)
{
auto matrix = *_matrices.top();
_constantBufferData.view = DirectX::XMMatrixTranspose(matrix);
_context->UpdateSubresource(_constantBuffer, 0, NULL, &_constantBufferData, 0, 0);
_context->IASetInputLayout(_inputLayout);
_context->VSSetShader(_vertexShader, nullptr, 0);
_context->VSSetConstantBuffers(0, 1, &_constantBuffer);
D3D11_PRIMITIVE_TOPOLOGY topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
ID3D11ShaderResourceView* texture = _textures[_currentTextureId];
// Set shader texture resource in the pixel shader.
_context->PSSetShader(_pixelShaderTexture, nullptr, 0);
_context->PSSetShaderResources(0, 1, &texture);
D3D11_MAPPED_SUBRESOURCE mappedResource;
D3D11_MAP mapType = D3D11_MAP::D3D11_MAP_WRITE_DISCARD;
auto hr = _context->Map(_vertexBuffer, 0, mapType, 0, &mappedResource);
if (SUCCEEDED(hr))
{
OpenGLVertex *pData = reinterpret_cast<OpenGLVertex *>(mappedResource.pData);
memcpy(&(pData[_currentVertex]), &vertices[0], sizeof(OpenGLVertex) * vertices.size());
_context->Unmap(_vertexBuffer, 0);
}
UINT stride = sizeof(OpenGLVertex);
UINT offset = 0;
_context->IASetVertexBuffers(0, 1, &_vertexBuffer, &stride, &offset);
_context->IASetPrimitiveTopology(topology);
_context->Draw(vertices.size(), _currentVertex);
_currentVertex += (int)vertices.size();
}
void OpenGL::CreateVertexBuffer()
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = _maxVertices * sizeof(OpenGLVertex);
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
bd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA initData;
ZeroMemory(&initData, sizeof(initData));
_device->CreateBuffer(&bd, NULL, &_vertexBuffer);
}
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
struct VertexShaderInput
{
float3 pos : POSITION;
float4 color : COLOR0;
float2 tex : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 pos : SV_POSITION;
float4 color : COLOR0;
float2 tex : TEXCOORD0;
};
VertexShaderOutput main(VertexShaderInput input)
{
VertexShaderOutput output;
float4 pos = float4(input.pos, 1.0f);
// Transform the vertex position into projected space.
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
// Pass through the color without modification.
output.color = input.color;
output.tex = input.tex;
return output;
}
最佳答案
您需要做的是尽可能积极地批处理顶点,然后绘制大块。我很幸运地将它 retrofit 到旧的即时模式 OpenGL 游戏中。不幸的是,这样做有点痛苦。
最简单的概念解决方案是使用某种设备状态(您可能已经在跟踪)为一组特定的顶点创建一个唯一的标记。混合模式和绑定(bind)纹理之类的东西是一个很好的集合。如果你能找到一个快速的散列算法在其中的结构上运行,你可以非常有效地存储它。
接下来,您需要进行顶点缓存。有两种方法可以解决这个问题,两者都有优势。最激进、最复杂,并且在许多具有相似属性的顶点集的情况下,最有效的是创建一个设备状态结构,分配一个大的(比如 4KB)缓冲区,然后继续存储具有匹配状态的顶点。大批。然后,您可以将整个数组转储到帧末尾的顶点缓冲区中,并绘制缓冲区的 block (以重新创建原始顺序)。然而,跟踪所有缓冲区、状态和顺序是很困难的。
更简单的方法可以在良好的情况下提供良好的缓存,将顶点缓存在一个大缓冲区中,直到设备状态发生变化。此时,在实际更改状态之前,将数组转储到顶点缓冲区并绘制。然后重置数组索引,提交状态更改,然后重新开始。
如果您的应用程序有大量相似的顶点,这很可能与 Sprite 一起使用(纹理坐标和颜色可能会改变,但好的 Sprite 将使用单个纹理图集和很少的混合模式),即使是第二种方法也可以提供一些性能提升。
这里的技巧是在系统内存中建立一个缓存,最好是一大块预先分配的内存,然后在绘图之前将其转储到视频内存中。这允许您对视频内存和绘图调用执行更少的写入,这往往是昂贵的(尤其是在一起)。正如您所看到的,您调用的电话数量变得很慢,而批处理很有可能帮助解决这个问题。诀窍是如果你能帮助它,不要在每帧分配内存,批量处理足够大的 block 是值得的,并为每次绘制保持正确的设备状态和顺序。
关于performance - 当我每帧写入单个顶点缓冲区数千次时,如何提高 Direct3D 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12117287/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 8年前关闭。 Improve t
暂时忘记能力的定义,只关注能力的“检查”(使用“授权!”),我看到 CanCan 添加了大约 400 毫秒,用于简单地检查用户是否具有特定的能力主题/模型。 这是预期的吗(我假设不是)?或者,有没有可
我正在阅读有关 Swift 的教程 ( http://www.raywenderlich.com/74438/swift-tutorial-a-quick-start ),它预定义为不显式设置类型,因
这主要是由于对 SQL 问题的回答。由于性能原因,有意省略了 UDF 和子查询。我没有包括可靠性并不是说它应该被视为理所当然,但代码必须工作。 性能永远是第一位的吗?提供了许多以性能为主要优先事项的答
我已经编写了一个简单的测试平台来测量三种阶乘实现的性能:基于循环的,非尾递归的和尾递归的。 Surprisingly to me the worst performant was the loop o
我已将 ui-performance 插件应用到我的应用程序中。不幸的是,在开发模式下运行应用程序时它似乎不起作用。例如,我的 javascript 导入是用“vnull”版本呈现的。 例如 不会
我有一个我操作的 F# 引用(我在各处添加对象池以回收经常创建和删除的短期对象)。我想运行结果报价;现在我使用了 F# PowerPack,它提供了将引用转换为表达式树和委托(delegate)的方法
我正在尝试在 Spark 服务器上运行 SparklyR 库中的机器学习算法。 1 个簇 8 核 24G内存 Ubuntu 16.04 星火2.2 独立配置 1名师傅/2名 worker 每个执行器的
我有一个数据库(准确地说是在 postgres 上运行),具有以下结构: user1 (schema) | - cars (table) - airplanes (table, again) .
我的应用程序在我的 iPad 上运行。但它的表现非常糟糕——我的速度低于 15fps。谁能帮我优化一下? 它基本上是一个轮子(派生自 UIView),包含 12 个按钮(派生自 UIControl)。
在完成“Scala 中的函数式编程原则”@coursera 类(class)第 3 周的作业时,我发现当我实现视频类(class)中所示的函数联合时: override def union(tha
我正在重构我的一个 Controller 以使其成为一项服务,我想知道不将整个服务容器注入(inject)我的 Controller 是否会对性能产生影响。 这样效率更高吗: innova.path.
我有一个要显示的内容很大的文件。例如在显示用户配置文件时, 中的每个 EL 表达式需要一个 userId 作为 bean 的参数,该参数取自 session 上下文。我在 xhtml 文件中将这个 u
我非常了解 mipmapping。我不明白(在硬件/驱动程序级别)是 mipmapping 如何提高应用程序的性能(至少这是经常声称的)。在执行片段着色器之前,驱动程序不知道要访问哪个 mipmap
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: What's the (hidden) cost of lazy val? (Scala) Scala 允许定义惰
一些文章建议现在 build() 包含在 perform() 本身中,而其他人则建议当要链接多个操作时使用 build().perform()一起。 最佳答案 build() 包含在 perform(
Postgres docs说 For best optimization results, you should label your functions with the strictest vol
阅读Zero-cost abstractions看着 Introduction to rust: a low-level language with high-level abstractions我尝
我想在 MQ 服务器上部署 SSL,但我想知道我当前的 CPU 容量是否支持 SSL。 (我没有预算增加 CPU 内核和 MQ PVU 的数量) 我的规范: Windows 2003 服务器 SP2,
因此,我在 Chrome 开发者工具 的性能 选项卡内的时间 部分成功地监控了我的 React Native 应用程序的性能。 突然在应用程序的特定重新加载时,Timings 标签丢失。 我已尝试重置
我是一名优秀的程序员,十分优秀!