Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.

Commit 5808682

Browse files
authored
cache attribute locations in gpgpu binary (#169)
* cache attribute locations in gpgpu binary * address review * fix typo
1 parent 9b8949f commit 5808682

File tree

4 files changed

+35
-24
lines changed

4 files changed

+35
-24
lines changed

src/math/webgl/gpgpu_context.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,13 @@ export class GPGPUContext {
198198
this.gl, program, uniformName);
199199
}
200200

201+
public getAttributeLocation(program: WebGLProgram, attribute: string):
202+
number {
203+
this.throwIfDisposed();
204+
return webgl_util.callAndCheck(
205+
this.gl, () => this.gl.getAttribLocation(program, attribute));
206+
}
207+
201208
public getUniformLocationNoThrow(program: WebGLProgram, uniformName: string):
202209
WebGLUniformLocation {
203210
this.throwIfDisposed();
@@ -247,12 +254,12 @@ export class GPGPUContext {
247254
webgl_util.validateFramebuffer(this.gl);
248255
}
249256

250-
public executeProgram() {
257+
public executeProgram(attribLocations?: {[name: string]: number}) {
251258
this.throwIfDisposed();
252259
this.throwIfNoProgram();
253260
const gl = this.gl;
254261
gpgpu_util.bindVertexProgramAttributeStreams(
255-
gl, this.program, this.vertexBuffer);
262+
gl, this.program, this.vertexBuffer, attribLocations);
256263
if (this.autoDebugValidate) {
257264
this.debugValidate();
258265
}

src/math/webgl/gpgpu_math.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {GPGPUContext} from './gpgpu_context';
2222
import * as shader_compiler from './shader_compiler';
2323
import {ShapeInfo} from './shader_compiler';
2424

25+
const ATTRIBUTE_NAMES = ['uv', 'clipSpacePos'];
26+
2527
export interface GPGPUProgram {
2628
variableNames: string[];
2729
outputShape: number[];
@@ -34,6 +36,7 @@ export interface GPGPUBinary {
3436
webGLProgram: WebGLProgram;
3537
program: GPGPUProgram;
3638
uniformLocations: {[name: string]: WebGLUniformLocation};
39+
attributeLocations: {[name: string]: number};
3740
gpgpu: GPGPUContext;
3841
source: string;
3942
inShapeInfos: ShapeInfo[];
@@ -68,12 +71,18 @@ export function compileProgram<T extends NDArray, K extends NDArray>(
6871
uniformLocations[uniformName] =
6972
gpgpu.getUniformLocation(webGLProgram, uniformName);
7073
}
74+
const attributeLocations: {[name: string]: number} = {};
75+
ATTRIBUTE_NAMES.forEach(attribute => {
76+
attributeLocations[attribute] =
77+
gpgpu.getAttributeLocation(webGLProgram, attribute);
78+
});
7179

7280
return {
7381
program,
7482
source,
7583
webGLProgram,
7684
uniformLocations,
85+
attributeLocations,
7786
gpgpu,
7887
inShapeInfos,
7988
outShapeInfo
@@ -127,7 +136,7 @@ export function runProgram<T extends NDArray, K extends NDArray>(
127136
if (customSetup != null) {
128137
customSetup(gpgpu, binary.webGLProgram);
129138
}
130-
gpgpu.executeProgram();
139+
gpgpu.executeProgram(binary.attributeLocations);
131140
}
132141

133142
export function makeShaderKey(

src/math/webgl/gpgpu_util.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -156,26 +156,18 @@ export function createPackedMatrixTexture(
156156
}
157157

158158
export function bindVertexProgramAttributeStreams(
159-
gl: WebGLRenderingContext, program: WebGLProgram,
160-
vertexBuffer: WebGLBuffer) {
159+
gl: WebGLRenderingContext, program: WebGLProgram, vertexBuffer: WebGLBuffer,
160+
attribLocations?: {[name: string]: number}) {
161161
const posOffset = 0; // x is the first buffer element
162162
const uvOffset = 3 * 4; // uv comes after [x y z]
163163
const stride = (3 * 4) + (2 * 4); // xyz + uv, each entry is 4-byte float.
164164
webgl_util.callAndCheck(
165165
gl, () => gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer));
166166
webgl_util.bindVertexBufferToProgramAttribute(
167-
gl, program, 'clipSpacePos', vertexBuffer, 3, stride, posOffset);
168-
try {
169-
webgl_util.bindVertexBufferToProgramAttribute(
170-
gl, program, 'uv', vertexBuffer, 2, stride, uvOffset);
171-
} catch (e) {
172-
// Programs with 1x1 output textures don't use the uv attribute.
173-
// This can cause the shader linker to dead-strip it, so we shouldn't
174-
// complain or fail if it's not present.
175-
if (!e.hasOwnProperty('namedVertexAttributeNotFound')) {
176-
throw e;
177-
}
178-
}
167+
gl, program, 'clipSpacePos', vertexBuffer, 3, stride, posOffset,
168+
attribLocations);
169+
webgl_util.bindVertexBufferToProgramAttribute(
170+
gl, program, 'uv', vertexBuffer, 2, stride, uvOffset, attribLocations);
179171
}
180172

181173
export function uploadPixelDataToTexture(

src/math/webgl/webgl_util.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,17 @@ export function createFramebuffer(gl: WebGLRenderingContext): WebGLFramebuffer {
257257
export function bindVertexBufferToProgramAttribute(
258258
gl: WebGLRenderingContext, program: WebGLProgram, attribute: string,
259259
buffer: WebGLBuffer, arrayEntriesPerItem: number, itemStrideInBytes: number,
260-
itemOffsetInBytes: number) {
261-
const loc = gl.getAttribLocation(program, attribute);
260+
itemOffsetInBytes: number, attribLocations?: {[name: string]: number}) {
261+
let loc = -1;
262+
if ((attribLocations != null) && (attribute in attribLocations)) {
263+
loc = attribLocations[attribute];
264+
} else {
265+
loc = gl.getAttribLocation(program, attribute);
266+
}
262267
if (loc === -1) {
263-
const error = new Error(
264-
'Unable to get attribute "' + attribute + '" on WebGLProgram.');
265-
// tslint:disable-next-line:no-any
266-
(error as any).namedVertexAttributeNotFound = attribute;
267-
throw error;
268+
// The GPU compiler decided to strip out this attribute because it's unused,
269+
// thus no need to bind.
270+
return;
268271
}
269272
callAndCheck(gl, () => gl.bindBuffer(gl.ARRAY_BUFFER, buffer));
270273
callAndCheck(

0 commit comments

Comments
 (0)