我有一个非常复杂的HLSL着色器进行大量纹理读取,使用Direct3D9中的着色器模型3。复杂的代码只在某些像素上使用,所以我在该代码块周围放置了一个if语句。令我惊讶的是,这丝毫没有提高性能。如果我使用剪辑(-1),我确实看到了一个巨大的性能提升,因此这个着色器确实是我的程序的瓶颈。为什么分支不提高我的性能没有剪辑(-1)行?
我发现了这个主题:条件和未使用的采样器/纹理为SM2/3像素着色器增加了多少性能?这个主题说,在着色模型3中,可以通过分支优化,但性能是最坏的每一批像素。在可能的情况下,慢分支主要在屏幕的边缘,而快速分支主要在屏幕的中心。我认为这意味着像素批次通常都会使用相同的分支,所以我希望这样可以获得性能的提高。
在伪代码中,像素着色器如下所示:
float4 colour = tex2D(texture, uv);
if (colour.a < 0.5f)
{
//I only get a performance boost if I replace this line with clip(-1);
oColour = colour;
}
else
{
complexSlowCodeWithTonsOfTextureReadsGoesHere;
oColour = result;
}
oColour *= 2;这给了我完全相同的性能,当我删除分支,并始终在缓慢的其他分支中使用代码。如果我用剪辑(-1)替换第五行,我会看到一个巨大的性能提升(主要是一个黑色的屏幕),所以If -语句实际上起作用了。
我在这里是不是做错了什么,还是不可能在着色器模型3中优化这样的着色器?
发布于 2014-10-19 18:34:04
问题是,您的if将被扁平化(由于错误的分支被丢弃,两者都会被执行),因为您在一个分支(文档)中使用了梯度函数(如文档)。如果从分支中删除这些函数或用非梯度函数(如tex2Dlod或tex2Dgrad )替换这些函数,您应该会看到性能的提高。如果在if之前添加[branch],编译器将帮助查找有问题的行。这将提示编译器,如果使用梯度函数,则需要真正的分支(如果),这将在编译中失败。
就我的经验而言,gpu用2x2片段计算输出。这是需要计算正确的miplevel用于纹理查找,因此需要邻居的信息。这防止了tex2D函数分支化,因为它们是相邻操作所需要的。如果您通过传递miplevel来给gpu所需的信息,那么其他片段就不再需要了,这样就可以跳过真正的分支了。
发布于 2019-11-06 06:35:51
使用Z/模板缓冲区屏蔽不希望着色器运行的区域。
https://stackoverflow.com/questions/26452540
复制相似问题