Skip to content
This repository was archived by the owner on May 9, 2018. It is now read-only.

Buffer binding#35

Merged
davepagurek merged 12 commits intomasterfrom
buffer-binding
Nov 13, 2017
Merged

Buffer binding#35
davepagurek merged 12 commits intomasterfrom
buffer-binding

Conversation

@davepagurek
Copy link
Copy Markdown
Member

@davepagurek davepagurek commented Nov 12, 2017

screen shot 2017-11-12 at 10 41 22 pm

Comment thread src/shaderpipeline.ts Outdated
import Shader from './shader';
import Qualifier from './qualifier';
import Set from './util/set';
import InterfaceVariable from './interface';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: could you do these imports alphabetically, please? (just a convention I like)

Copy link
Copy Markdown
Member

@abhimadan abhimadan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of my comments refer to #36, in case that gets merged first. I don't mind either way, but we should talk about how to resolve the merge conflicts beforehand, since both PRs are pretty large.

Comment thread src/interface.ts Outdated
return this.declaration();
}

public wrapAttributeValue(value: any[]): any {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename wrapAttributeValue to something more descriptive, like wrapAttributeBufferInTypedArray? It took a while to figure out what this was actually doing.

Comment thread src/shader.ts Outdated
}

public inputs(): Set<Variable> {
public inputs(): Set<InterfaceVariable> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my pending PR for adding local variables, I remove dependencies and just use inputs() and outputs() to get VariableSources (just the variable name and type). There are other fields inputDecls and outputDecls which contain VariableDeclaration[]s to use in code generation. If I submit first, you can change these to inputVars() and outputVars() and use them the way you are now (but you would need to cast to get back that they're InterfaceVariables, so maybe there should be InterfaceVariableDeclaration and LocalVariableDeclaration nodes?)

Comment thread src/shaderpipeline.ts Outdated
this.attributeBuffers = new Map();
this.uniformPositions = new Map();
this.inputs = new Map();
[...vertexShader.inputs().union(fragmentShader.inputs())].forEach(input => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect there to be common inputs between vertex and fragment shaders? I think fragment shader inputs come from vertex shader outputs. We don't bind buffers for those inputs.

Copy link
Copy Markdown
Member Author

@davepagurek davepagurek Nov 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only does stuff for uniforms, which you get for both, and attributes, which should only be inputs for the vertex shader (but we don't check that), and currently ignores in and out variables. Haven't thought too much yet about those but there aren't buffers being made for them anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that makes sense. Although I still don't understand the purpose of the inputs map, which takes inputs from both the fragment and vertex shader, and doesn't check whether or not those inputs are attributes. If you're only using it for attribute variables, can you
a) just get inputs from the vertex shader, and
b) filter by qualifier so that you only add attributes to the map?

Comment thread src/shaderpipeline.ts
this.createBuffers();
}

public setAttribute(input: string, value: any[], usage: GLenum = this.gl.STATIC_DRAW) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems awkward to key input interface variables by their declaration string. Why can't we just iterate over the set of inputs?

Also, can we change the signature of this to take all input variables, and all buffers? Maybe something like this:

public setAttributes(inputVars: InterfaceVariable[], buffer: any[], usage: GLenum);

If we do this, we can figure out the stride and offset for each attribute.

Copy link
Copy Markdown
Member Author

@davepagurek davepagurek Nov 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the end user to bind a value to a variable, which they may not want to do all at once, e.g. shader.bindAttribute('position', [1, -1, 0, ... ]). From the user's perspective, they'd be naming their variables by strings anyway, so wouldn't it be weird to make them pass in an object as a key?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the map was keyed by declaration for some reason, which is why I thought it was awkward. I'm okay with just variable names, because as you said, they're naming these variables with strings anyway.

Can we also support binding for multiple attributes at once (taking a string[] instead of InterfaceVariable[])? Binding separately in this way with multiple buffers will be less performant than interleaving the data if we want multiple attributes, so it's good to at least leave the option open.

Also, FWIW, I think we need to think more carefully about what buffer-related work we want users to do outside of our library. Right now, they have to gather each attribute's data in separate buffers, which is simple on their end, but leads to inefficient GPU cache use. On the other hand, they gather every attribute's data in a single buffer and pass it in to avoid cache problems, but this might be too restrictive to use. However, I'm fine with your current approach, and I'll make a separate issue for this.

Comment thread src/shaderpipeline.ts
this.gl.enableVertexAttribArray(position);
}

// TODO: support variadic args
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why do we want variadic args?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to, but there are the non-v versions of all the uniform functions that maybe people want to call directly instead of wrapping in an array, so our call might mirror that. Definitely not a key feature or anything, just something that we might consider doing in the name of not limiting the library's usage

Comment thread src/shaderpipelinebuilder.ts Outdated
// Might want to enforce equality (need to check the standard), but for now, this should be sufficient.
const inVars = this.fragmentShader.inputs();
const outVars = this.vertexShader.outputs();
const inVars = new Set<Variable>([...this.fragmentShader.inputs()].map(v => v.variable));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My pending PR will redefine inputs and outputs to return what you want here, so you won't need a map.

Comment thread src/type.ts Outdated
return true;
}

public wrapAttributeValue(value: any[]): any {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above: can you rename to wrapAttributeBufferInTypedArray?

Comment thread src/shaderpipeline.ts Outdated
.filter(input => input.variable.qualifier == Qualifier.Attribute)
.forEach(input => this.attributes.set(input.variable.name(), input.variable));
this.uniforms = new Set(
[...vertexShader.inputDecls]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implies we're going to expect users to pass in uniforms to the inputs parameter in a Shader constructor. Would it be better to have a separate uniforms constructor parameter? Shader inputs and uniforms are used for different purposes (vertex/fragment-specific vs static for entire pipeline), so it could be less confusing to split them at the Shader level.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to think about this more in another PR I think

@davepagurek
Copy link
Copy Markdown
Member Author

davepagurek commented Nov 13, 2017

Ok so changes I made:

  • It's no longer just the vertex shader's inputs. The fragment shader can reference uniforms that the vertex shader doesn't because the vertex shader might not care about them. The uniforms can maybe be a separate section in the shader but I'm going to leave that until later.
  • Matrices multiplied by vectors is allowed, but throws an error right now, so I commented out the error and those tests until we fix.
  • Added code to build samples for a browser
  • Have to specify float precision in shaders. TODO: allow this to change.

Copy link
Copy Markdown
Member

@armcburney armcburney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

}

public source(): string {
console.log(this);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this console.log?

@davepagurek davepagurek merged commit 85aed02 into master Nov 13, 2017
@davepagurek davepagurek deleted the buffer-binding branch November 13, 2017 14:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants