繁体   English   中英

用金属渲染四边形性能

[英]Rendering Quads Performance with Metal

我正在尝试使用Metal API在Apple A7 GPU上尽可能快地渲染大量非常小的2D四边形。 研究GPU的三角形吞吐量数字,例如这里 ,以及Apple在主题演示期间在屏幕上引用> 1M三角形,我希望能够以60fps每帧渲染500,000个这样的四边形。 也许少一点,因为所有这些都是可见的(在屏幕上,没有被z缓冲区隐藏)和微小的(光栅化器很棘手),所以这可能不是GPU超级优化的用例。 也许那个Apple演示以30fps的速度运行,所以假设~200,000应该是可行的。 当然是100,000 ......对吧?

但是,在我的测试应用程序中,最大值仅为~20,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);
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM