首页 文章

用金属渲染四边形性能

提问于
浏览
3

我是'm trying to render a large number of very small 2D quads as fast as possible on an Apple A7 GPU using the Metal API. Researching that GPU'的三角形吞吐量数字,例如here,并且在他们的主题演示期间,Apple在屏幕上引用了> 1M三角形,我认为GPU是超级优化的用例 . 也许那个Apple演示以30fps的速度运行,所以假设~200,000应该是可行的 . 当然是10万......对吧?

但是,在我的测试应用程序中,最大值仅为~2,000 - 超过此值,并且iPad Air上的帧速率降至60以下 . 使用100,000个四边形时,它以14 fps运行,即吞吐量为2.8M trianlges / sec(与AnandTech文章中引用的68.1M屏幕三角形相比!) .

即使我使用一个简单的片段着色器使四边形像素变小,性能也不会提高 . 因此我们可以假设这是顶点绑定的,并且Xcode中的GPU报告同意(“Tiler”为100%) . 顶点着色器也是微不足道的,只做一点缩放和翻译数学,所以我假设瓶颈是一些固定功能阶段...?

仅仅为了更多背景信息,我使用单个实例绘制调用渲染所有几何体,每个实例一个四边形,即每个实例4个顶点 . 四边形的位置来自一个单独的缓冲区,该缓冲区由顶点着色器中的实例id索引 . 我也尝试过其他一些方法(非实例化,所有顶点都经过预转换,实例化索引等),但这并没有帮助 . 没有复杂的顶点属性,缓冲区/表面格式,或者我能想到的任何其他可能在驱动程序/ GPU中遇到缓慢路径的东西(尽管我当然不能确定) . 混合是关闭的 . 几乎所有其他东西都处于默认状态(如视口,剪刀,ztest,剔除等) .

该应用程序是用Swift编写的,但希望这无关紧要;)

我想要了解的是,在渲染像这样的四边形(与“适当的”3D场景相对)时,我所看到的性能是否是预期的,或者是否需要一些更先进的技术来获得接近广告三角形的位置吞吐量 . 人们认为这可能是限制瓶颈吗?

此外,如果有人知道为什么这可能在OpenGL中比在Metal中更快(我没有尝试过,也无法想到任何原因),那么我也很乐意听到它 .

谢谢

编辑:添加着色器代码 .

vertex float4 vertex_shader(
        const constant float2* vertex_array [[ buffer(0) ]],
        const device QuadState* quads [[ buffer(1) ]],
        constant const Parms& parms [[ buffer(2) ]],
        unsigned int vid [[ vertex_id ]],
        unsigned int iid [[ instance_id ]] )
{
    float2 v = vertex_array[vid]*0.5f;

    v += quads[iid].position;

    // ortho cam and projection transform
    v += parms.cam.position;
    v *= parms.cam.zoom * parms.proj.scaling;

    return float4(v, 0, 1.0);
}


fragment half4 fragment_shader()
{
    return half4(0.773,0.439,0.278,0.4);
}

1 回答

  • 1

    没有看到你的Swift / Objective-C代码,我无法确定,但我猜你是在花太多时间调用你的实例代码 . 当您拥有包含数百个三角形的模型时,实例化很有用,而不是两个 .

    尝试创建一个包含1000个四边形的顶点缓冲区,并查看性能是否会提高 .

相关问题