Swift 更改uv坐标对金属造成意外性能影响
下面是Swift 更改uv坐标对金属造成意外性能影响,swift,rendering,texture-mapping,sampling,metal,Swift,Rendering,Texture Mapping,Sampling,Metal,下面是metal中的一个简单顶点和片段着色器组合,用于渲染64个相同的二维四边形 vertex VertexOut vertexMain(uint k [[ vertex_id ]], uint ii [[instance_id]], device float2* tex [[buffer(2)]], device float2*
metal
中的一个简单顶点和片段着色器组合,用于渲染64个相同的二维四边形
vertex VertexOut vertexMain(uint k [[ vertex_id ]],
uint ii [[instance_id]],
device float2* tex [[buffer(2)]],
device float2* position [[buffer(1)]],
device float* state [[buffer(0)]]){
VertexOut output;
int i = 4*ii+1;
float2 pos = position[k];
pos *= float2(state[i+2],state[i+3]);
pos += float2(state[i],state[i+1]);
pos.x *= state[0];
output.position = float4(pos,0,1);
output.tex = tex[k]*float2(du,dv);
return output;
};
fragment float4 fragmentMain(VertexOut input [[stage_in]],
texture2d<float> texture [[texture(0)]],
sampler sam [[sampler(0)]] ){
return texture.sample(sam, input.tex);
};
当您增加
du
和dv
时,您的四边形将显示更多的纹理。GPU倾向于为纹理数据提供较小的缓存,当您显示更多的纹理时,您将丢弃并重新填充该缓存
抖动纹理缓存将使用更多的内存带宽,这是一个相当有限的资源,通常纹理内存带宽不是瓶颈,但由于碎片着色器除了纹理抓取之外几乎什么都不做,因此它是瓶颈也就不足为奇了。因此,改变UV对性能的影响并不奇怪
令人惊讶的是,在这些功能强大的设备上,帧速率降至60以下,而您所做的只是渲染64个四边形(尤其是iPad Pro是一款功能强大的设备)。也就是说,如果所有64个四边形都覆盖了大部分屏幕,那么帧速率下降是可以理解的
为了提高性能,您需要减少需要GPU处理的纹理数据量。从32位纹理格式(8888)更改为16位(565/4444)或4位(PVRTC压缩纹理)将产生很大影响
真正的大胜利可能是启用mipmapping。假设使用较高的值
du
和dv
,您最终会最小化纹理,那么使用mipmapping将提供巨大的性能优势,并且作为额外的好处,您的纹理也会看起来更好(它将修复混叠)。纹理内存增加33%,回报不错 你能量化你所经历的帧速率下降的程度吗?用线性抽样从60降到40。从60到50,最近的抽样。在哪个设备和操作系统版本上?iPad mini和iPad Pro 9.7都运行10.2这很有趣。我使用的是实例渲染,这意味着所有64个四边形都是通过单个纹理绑定和单个绘制调用一起绘制的。在这种情况下,这种缓存问题还会发生吗?是的,纹理缓存通常只有几KB,大多数纹理只有几百KB。这是一本很好的入门书:更好地理解渲染场景可能会很有用——也许是一个屏幕截图。64个小四边形算不了什么,如果你不能达到60帧的速度,就会发生一些有趣的事情。64个四元组,每个四元组覆盖整个屏幕,这样我就可以理解问题了。每个四元组只覆盖屏幕的1%。我添加了更多描述我的管道的代码。与屏幕覆盖率相比,纹理可能非常大,因此mipmapping将是一个巨大的胜利。但我真的很惊讶,在这样一个简单的场景中,帧速率会受到影响,即使是病理纹理采样场景。纹理格式、宽度和高度是什么?四象限的近似像素大小?原始图像到1864年为3900。光栅化的四边形约为200 x 150。我肯定会开始使用mipmapping,但显然我想了解为什么会出现这种性能冲击。
let samplerDescriptor = MTLSamplerDescriptor()
samplerDescriptor.normalizedCoordinates = true
samplerDescriptor.minFilter = .linear
samplerDescriptor.magFilter = .linear
let sampler = device.makeSamplerState(descriptor: samplerDescriptor)
let attachment = pipelineStateDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.sourceRGBBlendFactor = .one
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha