这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@kainino0x
Copy link
Contributor

@kainino0x kainino0x commented Jan 28, 2019

(with attributes inside the vertex buffer descriptor)

For alternatives, examples, and a little analysis, see here (this one is OPTION 4).

@kainino0x kainino0x requested review from kvark and litherum January 29, 2019 00:20
sequence<GPUVertexInputDescriptor> inputs;
// This object has keys of 0..15 and values of type GPUVertexBufferDescriptor.
// (It's not possible in WebIDL to describe a dictionary with keys "0" through "15".)
object vertexBuffers;
Copy link
Contributor

Choose a reason for hiding this comment

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

@heycam Is this really not possible?

Copy link

Choose a reason for hiding this comment

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

Yes, this is not possible. (There is an escaping prefix _ for identifiers but the characters following must still look like a normal identifier, and this is only used for escaping existing keywords.)

I think it's odd for a Web API to have array-index-like members like this. What's the downside of using sequence<GPUVertexInputDescriptor> here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please take a look at the alternatives doc.

If by sequence<GPUVertexInputDescriptor> you mean WITH the index parameter, that is option 2. The additional indirection was opposed by some in favor of the relatively more straightforward-looking keys-as-indices.

If you mean WITHOUT the index parameter, that's option 3 and the sequence must be sparse - that is, sequence<GPUVertexBufferDescriptor?> (since afaik WebIDL doesn't really have sparse arrays).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All that said, I'm currently not that strongly in favor of any of these proposals over any of the others. It is up for discussion.

Copy link

Choose a reason for hiding this comment

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

Thanks for that pointer. Do you think authors will tend to pass an Array object (with holes or explicit undefined values) or a plain object with index-like keys, if the IDL used object? One of the points made about option 3 is that it obscures the index of each descriptor but even with the object and in-prose handling of reading things off the object, the author could still pass an Array object and have it work. Unless the prose explicitly checked for an Array and threw an exception I suppose.

If requiring the index to be specified is not a hard requirement, then I think using sequence<GPUVertexBufferDescriptor?> is the most straightforward thing.

Another option would be to use a dictionary with names that aren't array-index-like, e.g.

dictionary GPUVertexInputBuffers {
    optional GPUVertexBufferDescriptor v0;
    optional GPUVertexBufferDescriptor v1;
    ...
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the input. I envisioned primarily using object syntax and passing raw objects to the API. We could allow or disallow arrays.

Your last suggestion looks like Option 5 (the last one in the PR I linked). It is definitely possible, but I think applications will sometimes want to e.g. have a for loop over slots 2-5, which would be harder and slower with the valid identifier names.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you mean WITHOUT the index parameter, that's option 3 and the sequence must be sparse - that is, sequence<GPUVertexBufferDescriptor?> (since afaik WebIDL doesn't really have sparse arrays).

There is no need for it to be sparse, no need for ?. If no vertex attributes are using a buffer at some index, the corresponding GPUVertexBufferDescriptor would just have an empty list of attributes.

object vertexBuffers; doesn't look appealing at all to me

@litherum
Copy link
Contributor

See also: #151

Copy link
Contributor

@kvark kvark left a comment

Choose a reason for hiding this comment

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

all good, minus the object vertexBuffers bit :)

@grorg
Copy link
Contributor

grorg commented Mar 4, 2019

Discussed in the 4 March 2019 meeting

@kainino0x kainino0x force-pushed the vertex-inputs-opt4 branch from 3e8b17f to e6507ca Compare March 15, 2019 17:24
@kainino0x
Copy link
Contributor Author

Updated: VertexBufferState -> VertexInput, and rebased.

@kvark kvark self-requested a review March 15, 2019 17:57
Copy link
Contributor

@kvark kvark left a comment

Choose a reason for hiding this comment

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

Status: still don't understand why we need to go with the object hack here.

@kainino0x
Copy link
Contributor Author

Sorry, didn't reevaluate the alternatives yet.

@kainino0x
Copy link
Contributor Author

Assuming GPUVertexBufferDescriptor has defaults:

dictionary GPUVertexBufferDescriptor {
    u64 stride = 0;
    GPUInputStepMode stepMode = "vertex";
    sequence<GPUVertexAttributeDescriptor> attributes = [];
};

things still look kind of ugly in cases when there are holes:

const vertexBuffers = [vb0, {}, {}, {}, {}, {}, {}, vb7];

WDYT?

@kvark
Copy link
Contributor

kvark commented Mar 23, 2019

I can't stress this enough - this isn't the case to optimize usability for. Users who want many different vertex buffers mixed and matched in their pipelines can find ways for this to be sound, i.e.

var vertexBuffers = Array(MAX_VERTEX_BUFFERS).fill({});
vertexBuffers[0] = vb0;
vertexBuffers[7] = vb7;

@kainino0x
Copy link
Contributor Author

kainino0x commented Mar 25, 2019

Another issue is that this does not work for other sequences in the API. So we need to come up with something for those, too.

  • GPUBindGroupLayoutDescriptor.bindings
  • GPUBindGroupDescriptor.bindings
  • GPUPipelineLayoutDescriptor.bindGroupLayouts
  • GPURenderPipelineDescriptor.colorStates
  • GPURenderPassDescriptor.colorAttachments

(not 100% sure everything on this list has the problem)

@kvark
Copy link
Contributor

kvark commented Mar 25, 2019

@kainino0x vertex buffers are different from the all the states you mentioned in that they are bound in ranges (e.g. we can bind all the vertex buffers from slot 1 to slot 4 in one command).

Stuff like GPUBindGroupDescriptor.bindings (vs GPUBindGroupLayoutDescriptor.bindings) refers to arbitrary binding points in the shader that are not in a specific range and no expectation is provided that they are near each other.

GPUPipelineLayoutDescriptor.bindGroupLayouts is already a sequence that is ordered by the bind group ID. We currently don't have a way of saying that a particular ID isn't used, so I think we just need to turn those into nullable, i.e.

dictionary GPUPipelineLayoutDescriptor {
    sequence<GPUBindGroupLayout?> bindGroupLayouts;
};

GPURenderPipelineDescriptor.colorStates and GPURenderPassDescriptor.colorAttachments - I don't see how the holes would be useful there at all, so we don't need any defaults.

@kainino0x
Copy link
Contributor Author

Ok, I think I agree with you about bindGroupLayouts and colorStates/colorAttachments.

The GPUBindGroupDescriptor and GPUBindGroupLayoutDescriptor, though, currently use the [{binding: 0, ...}, {binding: 1, ...}] style. For BindGroupDescriptor, unfortunately BindGroupBinding doesn't have a good default value the way GPUVertexBufferDescriptor does. I don't see why it should be different from vertex input. There are two obvious options aside from what we have now:

dictionary GPUBindGroupBinding {
    required GPUBindingResource resource;
};

dictionary GPUBindGroupDescriptor {
    GPUBindGroupLayout layout;
    sequence<GPUBindGroupBinding?> bindings;
};
dictionary GPUBindGroupBinding {
    GPUBindingResource resource = null;
};

dictionary GPUBindGroupDescriptor {
    GPUBindGroupLayout layout;
    sequence<GPUBindGroupBinding> bindings;
};

Or even:

dictionary GPUBindGroupBinding {
   required GPUBindingResource resource;
};

dictionary GPUBindGroupDescriptor {
    GPUBindGroupLayout layout;
    object bindings;
};

(😛)

@kvark
Copy link
Contributor

kvark commented Mar 25, 2019

@kainino0x we need to talk about the order of bindings in a bind group. As it stands right now, they are defined individually (in GPUBindGroupLayoutDescriptor) and provided individually (in GPUBindGroupDescriptor), which is different from how the vertex buffers are provided (sequentially).

There is a case to be made about sequential binding IDs for the following reason:

  • Vulkan API works with ranges of descriptors, so this would be potential optimization (disclaimer: nothing stops us from doing this today, but exposing an API that favors sequential bindings would hit this code path more often)
  • depends on how we decide to expose arrays in inside descriptors. In DX12 and Metal each array element occupies a separate ID (in the respective heap or an MTLArgumentBuffer). In Vulkan the array dimension is extra (i.e full address of a descriptor consists of the trio (set, binding, array_index)).
  • is there a good use case where this would be limiting?

@grorg
Copy link
Contributor

grorg commented Mar 25, 2019

Discussed at 25 March teleconference

@kainino0x
Copy link
Contributor Author

TODO(me): Agreed to update this to Option 3 (here).

@kainino0x kainino0x closed this Mar 25, 2019
@kainino0x kainino0x changed the title Vertex inputs: refactor to int-keyed object Vertex inputs: push model with int-keyed object Mar 25, 2019
@kainino0x
Copy link
Contributor Author

@kvark since I've closed this, would you mind posting your last comment as an issue or PR?

@kvark
Copy link
Contributor

kvark commented Mar 26, 2019

@kainino0x moved to #251

@kainino0x kainino0x mentioned this pull request Oct 30, 2019
13 tasks
ben-clayton pushed a commit to ben-clayton/gpuweb that referenced this pull request Sep 6, 2022
…PublicParamsPaths (gpuweb#186)

* only checkForDuplicateCases during crawl(); slightly speed up comparePublicParamsPaths

* use Set

* un-delete error message

* expand tests, go back to n^2 (instead of Set) to pass tests

* more testing, rename method

* nit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants