0

我正在尝试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

性能警告:READ-usage 缓冲区被读回而没有在栅栏上等待。这导致了图形管道停顿。

然后,我尝试在之后添加以下代码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为中的timeoutgl.clientWaitSync,然后我得到:

WebGL:INVALID_OPERATION:clientWaitSync:超时 > MAX_CLIENT_WAIT_TIMEOUT_WEBGL

如果我设置,也会发生这种情况gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL - 1。接下来,我尝试设置gl.TIMEOUT_IGNOREDtimeout值,使用此设置,status正在获取gl.WAIT_FAILED.

为了消除该性能警告,我在这里缺少什么?

4

1 回答 1

0

感谢@gmangithub中的帮助。

我做了什么来摆脱上面链接中的指导方针的性能警告:

...
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);
于 2021-06-02T15:23:52.260 回答