GPU 的主要用途之一是图像(纹理)采样和处理。GPU 内置专用硬件,用于执行最近的邻域、双线性筛选和双三次滤波(使用 VK_EXT_filter_cubic 扩展)。但是,有些用例需要使用更大的内核或自定义内核权重进行采样。这些用例可以使用现有的采样指令在片段或计算着色器中手动实现。但是,需要纹理和着色器单元之间多次往返,从功耗或性能的角度来看,并不理想。
本文将介绍最新的 高通 Adreno GPU如何使用专用硬件,对大内核和自定义内核权重进行采样。我们的Vulkan 驱动程序团队发布了一个新的 VK_QCOM_image_processing 扩展,以利用此硬件功能。经测试,我们发现,与手动编码的实现相比,运行时间下降了 75% 以上,能耗使用量降低了近 90%。
四个新的 GLSL 函数
VK_QCOM_image_processing 扩展公开了四个新的 OpenGL 着色语言(GLSL) 函数。
函数 1 – textureWeightedQCOM
vec4 textureWeightedQCOM(sampler2D tex, vec2 uv, sampler2DArray weights)
此函数将 2D 权重内核与以 uv 为中心的纹理区域相乘,并将结果汇总至返回的 vec4 值中。请注意,此处的权重纹理是 2D 值的数组。数组的每一层称为一个相位。当目标采样偏离像素精确中心时,相位允许使用不同的内核离散化。此函数对于非线性内核函数(如 sinc)非常重要,因为在有限分辨率的内核中,无法很好地捕获这些细节。
许多常见的 2D 图像过滤内核可以表示为两个 1D 过滤内核,被称为可分离过滤器,可以显著节省性能。创建可分离过滤器时,水平权重放置在第 0 层中,垂直权重打包置于纹理数组的第 1 层中。1D 权重必须以 4 个为一组排列。以下示例说明如何将尺寸为 3x3 的两相可分离过滤器打包。H 表示水平,P# 是相位数,[n]是可分离过滤器的第 n 个元素。
Layer 0:
第 0 层:
HP0[0] | HP0[1] | HP0[2] | empty | HP1[0] | HP1[1] | HP1[2] | empty |
Layer 1:
第 1 层:
VP0[0] | VP0[1] | VP0[2] | empty | VP1[0] | VP1[1] | VP1[2] | empty |
函数 2 – textureBoxFilterQCOM
vec4 textureBoxFilterQCOM(sampler2D tex, vec2 uv, vec2 boxSize)
此函数取一个框内纹素的平均值。平均值按覆盖范围加权,确保偏心采样准确。框的中心由 uv 指定,宽度由 boxSize.x 指定,高度由 boxSize.y 指定。
函数 3 – textureBlockMatchSADQCOM
vec4 textureBlockMatchSADQCOM(sampler2D target, uvec2 targetCoord, sampler2D reference, uvec2 refCoord, uvec2 blockSize)
此函数的作用是衡量目标子区域与参考子区域的相关性(相似性)。targetCoord 和 refCoord 表示图块左下角位置,而返回值则表示了每个组件的绝对差之和 (SAD):
其中 T 是目标纹理,R 是参考纹理。框的宽度和高度分别由 blockSize.x 和 blockSize.y 指定。此处的 uv 坐标指定图块左下角(而不是中心,如上面的加权和框过滤器函数)。
函数 4 – textureBlockMatchSSDQCOM
vec4 textureBlockMatchSSDQCOM(sampler2D target, uvec2 targetCoord, sampler2D reference, uvec2 refCoord, uvec2 blockSize)
此函数的工作方式与 textureBlockMatchSADQCOM 相同,但不是返回绝对差值总和,而是返回每个组件的平方差值和 (SSD):
上述四个函数都只对 2D 图像起作用。目前不支持 mipmap、多层、多采样或深度/模板纹理。
设置代码
本节介绍创建用于此扩展的纹理和采样器所需的新参数。另外,还包括 GLSL 中的示例程序。有关示例和更多详细信息,请参阅规范建议。
参数
框过滤(函数 2)
目标采样器 |
|
目标纹理 |
|
图块匹配(函数 3 和 4)
目标采样器 |
|
目标和参考纹理 |
|
目标和参考纹理描述符 |
|
加权图像采样(函数 1)
目标采样器 |
|
权重纹理 |
|
权重描述符 |
|
权重图像视图 |
|
目标纹理 |
|
使用单独纹理和采样器的示例程序片段:
#version 450
#extension GL_QCOM_image_processing : require
#extension GL_EXT_samplerless_texture_functions : require
// Inputs and outputs for fragment shader
layout (location = 0) in vec2 uv;
layout (location = 0) out vec4 fragColor;
// Texture and sampler inputs
layout(set = 0, binding = 0) uniform highp texture2D inputTex;
layout(set = 0, binding = 1) uniform highp texture2DArray kernelTex;
layout(set = 0, binding = 3) uniform highp sampler samplerLinear;
layout(set = 0, binding = 4) uniform highp sampler samplerKernel;
void main()
{
fragColor = textureWeightedQCOM(sampler2D(inputTex, samplerLinear), uv, sampler2DArray(kernelTex, samplerKernel));
}
使用组合纹理和采样器的示例程序片段
#version 450
#extension GL_QCOM_image_processing : require
#extension GL_EXT_samplerless_texture_functions : require
// Inputs and outputs for fragment shader
layout (location = 0) in vec2 uv;
layout (location = 0) out vec4 fragColor;
// Texture and sampler inputs
layout(set = 0, binding = 0) uniform highp sampler2D inputTexSampler;
layout(set = 0, binding = 1) uniform highp sampler2DArray kernelTexSampler;
void main()
{
fragColor = textureWeightedQCOM(inputTexSampler, uv, kernelTexSampler);
}
结果:运行时间更短,功耗更低
下列图表显示了使用 VK_QCOM_image_processing 扩展而不是分段程序手动实现相同操作在性能和能耗方面的巨大优势。
经在 SM8550 Android 设备上测试表明,与手动实现相比,该扩展使运行时间缩短了 75%,功耗降低了 90%。
我们衡量的工作负载使用 8x8 加权内核对 4 倍降尺度算法执行 3 次迭代以生成缩略图。图表中的值根据分段或计算机着色器的手动实现进行了调整,以便比较。
如何使用这些函数
以下是这些函数发挥作用的部分示例应用程序:
在图像模糊、锐化、边缘检测、特征检测、高阶过滤器内核应用、上采样、下采样和多级纹理(mipmap)生成时,使用 TextureWeightedQCOM(函数 1)。该函数支持不同的还原模式,如最小和最大还原,对于膨胀或侵蚀等过滤器很有用。
使用 TextureBoxFilterQCOM(函数 2)对图像进行模糊处理,检测平均曝光级别、明亮区域和黑暗区域等特征。
在特征检测、运动跟踪和图像对齐应用中使用 TextureBlockMatchSADQCOM(函数 3)和 TextureBlockMatchSSDQCOM(函数 4)。但是,对于运动估计或光流应用,我们建议使用专门为此开发的更高级别、优化更好的扩展:GL_QCOM_motion_estimation和VK_NV_optical_flow。
轮到你了 - 试用扩展
我们可以看到,尽量使用此扩展在性能和电池续航方面均有巨大的优势。
满足以下要求即可使用扩展:
- SDK – 1.3.222 及更新版本的 Vulkan SDK
- 硬件 – 支持 SM8550 及更新版本
- Adreno GPU 驱动程序 – 512.649 及更新版本
您也可以在公开的手册页面和规范提议中找到更多信息。我们很期待看到您在其他应用中也能使用这些扩展。先试用一下,告诉我们您的想法。
我们还准备了一个简单的执行泛光(bloom)操作的示例程序。它包括使用扩展的着色器和手动实现的着色器,以便进行比较。您可以在此处下载。