WebGl 不相交计时器查询峰值
WebGl disjoint timer query spikes
我在尝试使用不相交计时器查询扩展为某些 WebGL 计时时看到了一些奇怪的结果。
我已经编写了一些简单的 WebGL 代码来重现我们在这里看到的问题:https://jsfiddle.net/d79q3mag/2/。
const texImage2DQuery = gl.createQuery();
gl.beginQuery(ext.TIME_ELAPSED_EXT, texImage2DQuery);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 512, 512, 0, gl.RGBA, gl.FLOAT, buffer);
gl.endQuery(ext.TIME_ELAPSED_EXT);
tex2dQuerys.push(texImage2DQuery);
const drawQuery = gl.createQuery();
gl.beginQuery(ext.TIME_ELAPSED_EXT, drawQuery);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
gl.endQuery(ext.TIME_ELAPSED_EXT);
drawQuerys.push(drawQuery);
tryGetNextQueryResult(tex2dQuerys, tex2dQueryResults);
tryGetNextQueryResult(drawQuerys, drawQueryResults);
渲染函数使用计时器扩展分别对 texImage2D 调用和 drawArrays 调用进行计时。如果我绘制绘图调用的结果图表,我会看到一些相当大的尖峰(有些高达 12 毫秒!但大多数尖峰在 2 毫秒到 4 毫秒范围内):
但是,如果我将帧速率从 30fps 增加到 60fps,结果会改善(最大尖峰 1.8ms,大多数尖峰在 1ms 和 0.4ms 之间):
我还注意到,如果我不为 texImage2D 函数计时 (https://jsfiddle.net/q01aejnv/2/),那么 drawArrays 调用的时间峰值也会在 30FPS 时消失(峰值在 1.6 毫秒和 0.2 毫秒之间)。
我正在使用 chrome 81 的 Quadro P4000。
在 Nvidia 控制面板中,低延迟模式设置为 Ultra,电源管理模式设置为 Prefer maximum performance。
这些结果是在 chrome.
中使用 D3D11 作为 ANGLE 图形后端收集的
这里似乎有两处令人困惑的地方。首先是更高的帧率似乎可以缩短绘制时间。其次是 texImage2D 的计时似乎影响了绘制时间。
在进行计时时,您可能需要在 gl.endQuery
之后 gl.flush
说明:WebGL 函数将命令添加到命令缓冲区。其他一些进程读取该缓冲区,但在告知其他进程时存在开销 "hey! I added some commands for you!"。因此,一般来说,WebGL 命令并不总是执行 "Hey!" 部分,它们只是插入命令。 WebGL 将在不同的点自动执行自动刷新(“嘿!执行此操作!”),但在计时时您可能需要添加 gl.flush
.
注意:就像我上面说的,刷新有开销。在普通程序中,执行 flush
.
很少重要
我在尝试使用不相交计时器查询扩展为某些 WebGL 计时时看到了一些奇怪的结果。 我已经编写了一些简单的 WebGL 代码来重现我们在这里看到的问题:https://jsfiddle.net/d79q3mag/2/。
const texImage2DQuery = gl.createQuery();
gl.beginQuery(ext.TIME_ELAPSED_EXT, texImage2DQuery);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 512, 512, 0, gl.RGBA, gl.FLOAT, buffer);
gl.endQuery(ext.TIME_ELAPSED_EXT);
tex2dQuerys.push(texImage2DQuery);
const drawQuery = gl.createQuery();
gl.beginQuery(ext.TIME_ELAPSED_EXT, drawQuery);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
gl.endQuery(ext.TIME_ELAPSED_EXT);
drawQuerys.push(drawQuery);
tryGetNextQueryResult(tex2dQuerys, tex2dQueryResults);
tryGetNextQueryResult(drawQuerys, drawQueryResults);
渲染函数使用计时器扩展分别对 texImage2D 调用和 drawArrays 调用进行计时。如果我绘制绘图调用的结果图表,我会看到一些相当大的尖峰(有些高达 12 毫秒!但大多数尖峰在 2 毫秒到 4 毫秒范围内):
但是,如果我将帧速率从 30fps 增加到 60fps,结果会改善(最大尖峰 1.8ms,大多数尖峰在 1ms 和 0.4ms 之间):
我还注意到,如果我不为 texImage2D 函数计时 (https://jsfiddle.net/q01aejnv/2/),那么 drawArrays 调用的时间峰值也会在 30FPS 时消失(峰值在 1.6 毫秒和 0.2 毫秒之间)。
我正在使用 chrome 81 的 Quadro P4000。 在 Nvidia 控制面板中,低延迟模式设置为 Ultra,电源管理模式设置为 Prefer maximum performance。 这些结果是在 chrome.
中使用 D3D11 作为 ANGLE 图形后端收集的这里似乎有两处令人困惑的地方。首先是更高的帧率似乎可以缩短绘制时间。其次是 texImage2D 的计时似乎影响了绘制时间。
在进行计时时,您可能需要在 gl.endQuery
gl.flush
说明:WebGL 函数将命令添加到命令缓冲区。其他一些进程读取该缓冲区,但在告知其他进程时存在开销 "hey! I added some commands for you!"。因此,一般来说,WebGL 命令并不总是执行 "Hey!" 部分,它们只是插入命令。 WebGL 将在不同的点自动执行自动刷新(“嘿!执行此操作!”),但在计时时您可能需要添加 gl.flush
.
注意:就像我上面说的,刷新有开销。在普通程序中,执行 flush
.