不能在栅栏上等待
Can't wait on a fence
我正在尝试使用以下代码从 TRANSFORM_FEEDBACK_BUFFER
获取一些数据:
const transform_feedback = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transform_feedback);
gl.transformFeedbackVaryings(program, ['position'], gl.INTERLEAVED_ATTRIBS);
gl.linkProgram(program);
const feedback_buffer = gl.createBuffer();
const data_length = 2;
const output_data = new Float32Array(data_length);
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedback_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, output_data, gl.STATIC_READ);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, feedback_buffer);
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, data_length);
gl.endTransformFeedback();
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, output_data);
但是如果我这样做,我会在 getBufferSubData
上收到以下警告消息:
performance warning: READ-usage buffer was read back without waiting on a fence. This caused a graphics pipeline stall.
然后,我尝试在 gl.endTransformFeedback();
之后添加以下代码:
const fence = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
wait_for_results = async () => {
const status = gl.clientWaitSync(fence, 0, 0);
if (status === gl.CONDITION_SATISFIED || status === gl.ALREADY_SIGNALED) {
gl.deleteSync(fence);
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, output_data);
return true;
} else {
return false;
}
};
let result_is_ok = false;
while (!result_is_ok) {
result_is_ok = await wait_for_results();
}
我在这里遇到的问题是 status
总是返回 gl.TIMEOUT_EXPIRED
。然后我尝试将gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL
设置为gl.clientWaitSync
中的timeout
值,然后我得到:
WebGL: INVALID_OPERATION: clientWaitSync: timeout > MAX_CLIENT_WAIT_TIMEOUT_WEBGL
如果我设置 gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL - 1
,也会发生这种情况。接下来,我尝试将 gl.TIMEOUT_IGNORED
设置为 timeout
值,通过此设置,status
得到 gl.WAIT_FAILED
.
为了消除性能警告,我在这里缺少什么?
谢谢@gman for the help in github。
根据上面 link 中的指南,我做了什么来消除性能警告:
...
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, data_length);
gl.endTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
const fence = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
let aux_resolve;
const aux_promise = new Promise(resolve => aux_resolve = resolve);
checkSync = () => {
const status = gl.clientWaitSync(fence, 0, 0);
switch (status) {
case gl.TIMEOUT_EXPIRED:
return setTimeout(checkSync);
case gl.WAIT_FAILED:
throw new Error('Something went wrong...');
default:
gl.deleteSync(fence);
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, output_data);
aux_resolve();
}
}
setTimeout(checkSync);
await aux_promise;
console.log(output_data);
我正在尝试使用以下代码从 TRANSFORM_FEEDBACK_BUFFER
获取一些数据:
const transform_feedback = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transform_feedback);
gl.transformFeedbackVaryings(program, ['position'], gl.INTERLEAVED_ATTRIBS);
gl.linkProgram(program);
const feedback_buffer = gl.createBuffer();
const data_length = 2;
const output_data = new Float32Array(data_length);
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedback_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, output_data, gl.STATIC_READ);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, feedback_buffer);
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, data_length);
gl.endTransformFeedback();
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, output_data);
但是如果我这样做,我会在 getBufferSubData
上收到以下警告消息:
performance warning: READ-usage buffer was read back without waiting on a fence. This caused a graphics pipeline stall.
然后,我尝试在 gl.endTransformFeedback();
之后添加以下代码:
const fence = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
wait_for_results = async () => {
const status = gl.clientWaitSync(fence, 0, 0);
if (status === gl.CONDITION_SATISFIED || status === gl.ALREADY_SIGNALED) {
gl.deleteSync(fence);
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, output_data);
return true;
} else {
return false;
}
};
let result_is_ok = false;
while (!result_is_ok) {
result_is_ok = await wait_for_results();
}
我在这里遇到的问题是 status
总是返回 gl.TIMEOUT_EXPIRED
。然后我尝试将gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL
设置为gl.clientWaitSync
中的timeout
值,然后我得到:
WebGL: INVALID_OPERATION: clientWaitSync: timeout > MAX_CLIENT_WAIT_TIMEOUT_WEBGL
如果我设置 gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL - 1
,也会发生这种情况。接下来,我尝试将 gl.TIMEOUT_IGNORED
设置为 timeout
值,通过此设置,status
得到 gl.WAIT_FAILED
.
为了消除性能警告,我在这里缺少什么?
谢谢@gman for the help in github。
根据上面 link 中的指南,我做了什么来消除性能警告:
...
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, data_length);
gl.endTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
const fence = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
let aux_resolve;
const aux_promise = new Promise(resolve => aux_resolve = resolve);
checkSync = () => {
const status = gl.clientWaitSync(fence, 0, 0);
switch (status) {
case gl.TIMEOUT_EXPIRED:
return setTimeout(checkSync);
case gl.WAIT_FAILED:
throw new Error('Something went wrong...');
default:
gl.deleteSync(fence);
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, output_data);
aux_resolve();
}
}
setTimeout(checkSync);
await aux_promise;
console.log(output_data);