Skip to content
Snippets Groups Projects
Commit 3a1befb5 authored by Alexander Rose's avatar Alexander Rose
Browse files

tweaked gpu gaussian density calculation

parent f4558de9
No related branches found
No related tags found
No related merge requests found
...@@ -43,7 +43,7 @@ const vec3 color = vec3(1.0, 1.0, 1.0); ...@@ -43,7 +43,7 @@ const vec3 color = vec3(1.0, 1.0, 1.0);
void main() { void main() {
float radiusSq = radius * radius; float radiusSq = radius * radius;
vec2 v = gl_FragCoord.xy - vec2(uCurrentX, uCurrentY) - 0.5; vec2 v = gl_FragCoord.xy - vec2(uCurrentX, uCurrentY) - 0.5;
out_FragColor = vec4(color, calcDensity(v.x, v.y, uCurrentSlice, radiusSq)); gl_FragColor = vec4(color, calcDensity(v.x, v.y, uCurrentSlice, radiusSq));
#if dDrawBuffers >= 4 #if dDrawBuffers >= 4
out1 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 1.0, radiusSq)); out1 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 1.0, radiusSq));
out2 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 2.0, radiusSq)); out2 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 2.0, radiusSq));
......
...@@ -51,6 +51,35 @@ function unbindFramebuffer(gl: GLRenderingContext) { ...@@ -51,6 +51,35 @@ function unbindFramebuffer(gl: GLRenderingContext) {
gl.bindFramebuffer(gl.FRAMEBUFFER, null) gl.bindFramebuffer(gl.FRAMEBUFFER, null)
} }
const tmpPixel = new Uint8Array(1 * 4);
async function waitForGpuCommandsComplete(gl: GLRenderingContext) {
if (isWebGL2(gl)) {
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
if (sync) {
// TODO too slow in Firefox
// await new Promise(resolve => {
// const check = async () => {
// if (gl.getSyncParameter(sync, gl.SYNC_STATUS) === gl.SIGNALED) {
// gl.deleteSync(sync)
// resolve();
// } else {
// setTimeout(check, 50)
// }
// };
// setTimeout(check, 10)
// })
gl.deleteSync(sync)
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
} else {
console.warn('unable to get webgl sync object')
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
}
} else {
console.info('webgl sync object not supported in webgl 1')
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, tmpPixel)
}
}
export function createImageData(buffer: ArrayLike<number>, width: number, height: number) { export function createImageData(buffer: ArrayLike<number>, width: number, height: number) {
const w = width * 4 const w = width * 4
const h = height const h = height
...@@ -66,6 +95,8 @@ export function createImageData(buffer: ArrayLike<number>, width: number, height ...@@ -66,6 +95,8 @@ export function createImageData(buffer: ArrayLike<number>, width: number, height
return new ImageData(data, width, height); return new ImageData(data, width, height);
} }
//
type Extensions = { type Extensions = {
instancedArrays: COMPAT_instanced_arrays instancedArrays: COMPAT_instanced_arrays
standardDerivatives: COMPAT_standard_derivatives standardDerivatives: COMPAT_standard_derivatives
...@@ -100,11 +131,10 @@ export interface Context { ...@@ -100,11 +131,10 @@ export interface Context {
unbindFramebuffer: () => void unbindFramebuffer: () => void
readPixels: (x: number, y: number, width: number, height: number, buffer: Uint8Array) => void readPixels: (x: number, y: number, width: number, height: number, buffer: Uint8Array) => void
waitForGpuCommandsComplete: () => Promise<void>
destroy: () => void destroy: () => void
} }
export function createContext(gl: GLRenderingContext): Context { export function createContext(gl: GLRenderingContext): Context {
const instancedArrays = getInstancedArrays(gl) const instancedArrays = getInstancedArrays(gl)
if (instancedArrays === null) { if (instancedArrays === null) {
...@@ -178,6 +208,7 @@ export function createContext(gl: GLRenderingContext): Context { ...@@ -178,6 +208,7 @@ export function createContext(gl: GLRenderingContext): Context {
// console.error('Reading pixels failed. Framebuffer not complete.') // console.error('Reading pixels failed. Framebuffer not complete.')
// } // }
}, },
waitForGpuCommandsComplete: () => waitForGpuCommandsComplete(gl),
destroy: () => { destroy: () => {
unbindResources(gl) unbindResources(gl)
......
...@@ -113,6 +113,9 @@ async function GaussianDensitySingleDrawBuffer(ctx: RuntimeContext, webgl: Conte ...@@ -113,6 +113,9 @@ async function GaussianDensitySingleDrawBuffer(ctx: RuntimeContext, webgl: Conte
framebuffer.destroy() // clean up framebuffer.destroy() // clean up
await ctx.update({ message: 'gpu gaussian density calculation' });
await webgl.waitForGpuCommandsComplete()
return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim } return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim }
} }
...@@ -133,29 +136,15 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex ...@@ -133,29 +136,15 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex
const framebuffer = createFramebuffer(webgl) const framebuffer = createFramebuffer(webgl)
framebuffer.bind() framebuffer.bind()
setDrawBuffers(gl, drawBuffers)
gl.viewport(0, 0, dx, dy)
setRenderingDefaults(gl)
if (!texture) { if (!texture) {
texture = createTexture(webgl, 'volume-uint8', 'rgba', 'ubyte', 'linear') texture = createTexture(webgl, 'volume-uint8', 'rgba', 'ubyte', 'linear')
} }
texture.define(dx, dy, dz) texture.define(dx, dy, dz)
if (drawBuffers === 1) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0,
]);
} else if (drawBuffers === 4) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3,
]);
} else if (drawBuffers === 8) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3,
gl.COLOR_ATTACHMENT4, gl.COLOR_ATTACHMENT5, gl.COLOR_ATTACHMENT6, gl.COLOR_ATTACHMENT7,
]);
}
gl.viewport(0, 0, dx, dy)
setRenderingDefaults(gl)
// z-slices to be render with multi render targets // z-slices to be render with multi render targets
const dzMulti = Math.floor(dz / drawBuffers) * drawBuffers const dzMulti = Math.floor(dz / drawBuffers) * drawBuffers
...@@ -167,7 +156,7 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex ...@@ -167,7 +156,7 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex
for (let k = 0; k < drawBuffers; ++k) { for (let k = 0; k < drawBuffers; ++k) {
texture.attachFramebuffer(framebuffer, k as TextureAttachment, i + k) texture.attachFramebuffer(framebuffer, k as TextureAttachment, i + k)
} }
renderable.render('draw') renderable.render('draw');
} }
// render single target // render single target
...@@ -188,6 +177,9 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex ...@@ -188,6 +177,9 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex
framebuffer.destroy() // clean up framebuffer.destroy() // clean up
await ctx.update({ message: 'gpu gaussian density calculation' });
await webgl.waitForGpuCommandsComplete()
return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim } return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim }
} }
...@@ -288,6 +280,23 @@ function setRenderingDefaults(gl: GLRenderingContext) { ...@@ -288,6 +280,23 @@ function setRenderingDefaults(gl: GLRenderingContext) {
gl.enable(gl.BLEND) gl.enable(gl.BLEND)
} }
function setDrawBuffers(gl: WebGL2RenderingContext, drawBuffers: number) {
if (drawBuffers === 1) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0,
]);
} else if (drawBuffers === 4) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3,
]);
} else if (drawBuffers === 8) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3,
gl.COLOR_ATTACHMENT4, gl.COLOR_ATTACHMENT5, gl.COLOR_ATTACHMENT6, gl.COLOR_ATTACHMENT7,
]);
}
}
function fieldFromTexture2d(ctx: Context, texture: Texture, dim: Vec3) { function fieldFromTexture2d(ctx: Context, texture: Texture, dim: Vec3) {
console.time('fieldFromTexture2d') console.time('fieldFromTexture2d')
const { gl } = ctx const { gl } = ctx
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment