Skip to content

Instantly share code, notes, and snippets.

@CodyJasonBennett
Created August 5, 2022 03:26
Show Gist options
  • Save CodyJasonBennett/fedde93b69b8ecaefa402ee306189761 to your computer and use it in GitHub Desktop.
Save CodyJasonBennett/fedde93b69b8ecaefa402ee306189761 to your computer and use it in GitHub Desktop.
KHR_parallel_shader_compile vs WebGL 2 fence-checking
import { GUI } from 'https://unpkg.com/three@0.143.0/examples/jsm/libs/lil-gui.module.min.js'
const canvas = document.createElement('canvas')
const gl = canvas.getContext('webgl2')
const ext = gl.getExtension('KHR_parallel_shader_compile')
const parameters = {
count: 1000,
series: false,
KHR: false,
}
async function benchmark() {
if (parameters.KHR && !ext) console.warn('KHR_parallel_shader_compile unsupported')
const start = performance.now()
await Promise.all(
Array.from({ length: parameters.count }).map(async () => {
const vSource = 'attribute vec2 position; void main() {\ngl_Position = vec4(position, 0, 1); }'
const fSource = 'precision mediump float; void main() { gl_FragColor = vec4(1,0,0,1); }'
const vShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vShader, vSource)
gl.compileShader(vShader)
const fShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fShader, fSource)
gl.compileShader(fShader)
const program = gl.createProgram()
gl.attachShader(program, vShader)
gl.attachShader(program, fShader)
gl.linkProgram(program)
if (!parameters.series) {
if (parameters.KHR && ext) {
while (!gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR)) {
await new Promise((resolve) => setTimeout(resolve, 10))
}
} else {
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0)
gl.flush()
while (gl.getSyncParameter(sync, gl.SYNC_STATUS) === gl.UNSIGNALED) {
await new Promise((resolve) => setTimeout(resolve, 10))
}
gl.deleteSync(sync)
}
}
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const error = gl.getProgramInfoLog(program)
throw `Error compiling program: ${error}`
}
}),
)
console.log(`${performance.now() - start}ms`)
}
const gui = new GUI()
gui.add(parameters, 'count', 1, 1000).step(100)
gui.add(parameters, 'series')
gui.add(parameters, 'KHR')
gui.onFinishChange(() => setTimeout(benchmark, 0)) // requestIdleCallback
benchmark()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment