我正在追踪性能瓶颈。为了缩小原因,我使用Xbox ATG 示例存储库中的 SimpleTrianglePC 示例创建了一个测试。
我只做了一些更改:我改为Draw
渲染DrawInstanced
多个三角形,并修改了顶点着色器以根据 SV_InstanceID 稍微改变每个三角形的位置和颜色。总共渲染了 265 个三角形,但我的 GPU 在此过程中达到了 100%:
这是输出。请注意,我将三角形的形状更改为直角三角形。顶部三角形为黑色:
这个问题似乎与所有三角形都在彼此之上的事实有关。如果三角形在不重叠的情况下渲染,则不会发生此问题。我已经对数千个三角形进行了测试,正如预期的那样,没有问题。
为了解决这个问题,我尝试了 DirectXTK 中的各种CommonState 。例如,我将混合状态设置为 Opaque(),将深度模板状态设置为 DepthNone(),将光栅化状态设置为 CullNone()。没有区别。
如果有人想知道:我使用的是硬件设备,而不是 WARP 设备。我的 GPU 很弱(华硕 EAH 5450),但这不是问题;我确实在这台机器上玩游戏。它不应该超过 265 个三角形。
这是修改后的顶点着色器。假定默认窗口大小为 1280 x 720:
struct Vertex
{
float4 position : SV_Position;
float4 color : COLOR0;
uint instanceId : SV_InstanceID;
};
struct Interpolants
{
float4 position : SV_Position;
float4 color : COLOR0;
};
Interpolants main( Vertex In )
{
Interpolants Out;
float2 offset = float( In.instanceId ) * float2( 2.0f / 1280.0f, 2.0f / 720.f );
Out.position = In.position + float4( offset, 0, 0 );
Out.color = float4( In.color.xyz * (In.instanceId & 0x1), 1 );
return Out;
}
这是我对 SimpleTrianglePC.cpp 所做的两个更改。首先,创建顶点缓冲区:
// Create vertex buffer.
float xScalar = 2.0f / 1280.0f;
float yScalar = 2.0f / 720.0f;
static const Vertex s_vertexData[3] =
{
{ { 1.0f * xScalar - 1.0f, 1.0f * yScalar - 1.0f, 0.5f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // Top / Red
{ { 1.0f * xScalar - 1.0f, 719.0f * yScalar - 1.0f, 0.5f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } }, // Right / Green
{ { 719.0f * xScalar - 1.0f, 1.0f * yScalar - 1.0f, 0.5f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } } // Left / Blue
};
二、绘制命令:
// Draw triangle.
context->DrawInstanced(3, 265, 0, 0);
正如我之前提到的,我创建了这个测试,因为当有许多重叠的原语时,我的原始代码会变慢。这种放缓是不可避免的吗?我应该怎么做才能避免这种情况?提前致谢。
编辑:
这是 GPU 使用细节的屏幕截图:
编辑2:
Visual Studio 的 GPU 使用工具似乎错误地报告了此图形驱动程序支持的功能级别。调用D3D11CreateDevice
返回功能级别 11.0。Dxdiag 证实了这一点:
我分析了一个框架,看看我是否可以获得任何额外的信息。看来 DrawInstance 需要 22 毫秒才能完成:
编辑3:
过去几天我一直在测试,但我没有看到对这种行为的很好解释。有没有人看到示例代码/我的更改有问题,或者我应该将其归结为有问题/性能不佳的显卡?