Skip to content

Minutes 2019 03 04

Corentin Wallez edited this page Jan 4, 2022 · 1 revision

GPU Web 2019-03-04

Chair: Corentin

Scribe: Ken

Location: Google Meet

TL;DR

  • #188 WHLSL and binding model
    • Problem is that HLSL allows overlapping register indices if they are for different resources, WebGPU’s current binding model doesn’t support that.
    • Discussion: HLSL for D3D11 doesn’t have spaceN declaration so would use a single bind group layout, and this is worked around in D3D12 using the root signature layout.
    • Consensus: keep the current binding model and have apps either use spaceN declarations and non-overlapping register indices, or provide the equivalent of an ID3D12RootSignatureLayout at WHLSL compilation time.
  • Vertex and input descriptor changes #186, #151
    • Either use a sparse array or an int-keyed structure.
    • Only hot functions like this is SetVertexBuffers, need benchmarking to know if the perf difference is worth special casing.
    • For cold functions, write out examples and see what is the nicest.

Tentative agenda

  • #188 WHLSL and binding model
  • More error handling
  • Vertex and input descriptor changes
  • Case for existing GLSL on the Web #219
  • Agenda for next meeting

Attendance

  • Apple
    • Dean Jackson
    • Justin Fan
    • Myles C. Maxfield
  • Google
    • Austin Eng
    • Corentin Wallez
    • Dan Sinclair
    • James Darpinian
    • Kai Ninomiya
    • Ken Russell
    • Shrek Shao
    • Victor Miura
  • Microsoft
    • Chas Boyd
    • Jungkee Song
    • Rafael Cintron
  • Mozilla
    • Dzmitry Malyshau
    • Jeff Gilbert
  • Mehmet Oguz Derin

Administrative items

  • CW: Scheduling of WebGPU F2F in May 13th 17th in the Bay area.
  • CW: Would be two days, let me know if you have conflicts / constraints that week.

#188 WHLSL and binding model

  • MM: is a recap necessary?
  • RC: yes plz
  • MM: topic is: how are resources identified in the shading language and the JS API?
    • Original reason for opening this is a mismatch.
    • JavaScript: resources specified by tuple, binding no. and descriptor set
    • In HLSL, variables are a triple: binding number, type and space
    • How do we merge these things together?
    • Was a lot of discussion and options.
  • RC: we should go over the proposals we’re considering.
  • MM: can mention one proposal. The whole thing is a pull request. The solution there is for variables not to be identified by a tuple, but by their position inside the array. Or, another way: add in another type label. Approach here is to change the binding model to match the language. Goal is to preserve compatibility with existing HLSL source code.
  • CW: other proposal: we keep the current binding model. Reason: this specific issue is because of HLSL for D3D11. D3D11 has a flat binding model, and even if it has spaces, it’s an extension for D3D12. Here, we are being influenced by something for D3D11. The solution that MSFT deployed for D3D12 was to retrofit a 2D binding model onto that register-based binding model of D3D11, using root signature layouts, specified either in the HLSL source code, or in code. Our understanding is that this is done where HLSL is used in other domains. Every explicit API out there that supports HLSL retrofits its binding model on top of HLSL and I think we should do the same to avoid a mismatch and to look forward to the future instead of the past.
  • MM: this is still a recap. A few options. Adding a step in the middle would make it artificially more difficult for web developers to use the officially supported language because we couldn’t make the two ends match each other. We agree that the existing HLSL out there doesn’t use the “space” keyword and that’s because it supports D3D11.
  • CW: in D3D12 you have the root signature layout that lets you map from D3D11 to D3D12. That’s what people are using for D3D12. Otherwise you’d have root signature layouts in your corpus. I don’t see it being important to be compatible with HLSL for D3D11. That’s not the goal - the goal is that all of your code works, but people already have solutions for these parts./
  • JG: these legacy HLSL shaders - how does D3D12 handle it?
  • MM: they added an intermediary step. Either specify it in the source code itself, or you use the RootSignature API object to do that mapping.
  • CW: our suggestion is - if the client ingests HLSL - the WebGPU-first way to do this would be to use disjoint registers and space keywords. But if you don’t do this, we provide a way to use root signatures. That would let their existing backends work.
  • MM: really interested to hear Rafael’s thoughts.
  • RC: I spent most time understanding how the bindings work across different APIs. The “space” concept doesn’t work with the old HLSL compiler that Chrome and FF use. Only DXC. So we would either need to renumber things or do a #define thing. MM is your official opinion to do things the D3D11 way, and will that make it more difficult to convert to Vulkan?
  • MM: more that resource binding points in shader source should be identified by type, binding number and space. It’s common for HLSL authors to make a resource that says register b0, and another that says register t0, and it would be great to make them work./
  • CW: but these won’t work in D3D12. Every time you use such a variable with an explicit API you need to provide add’l information to split the usage across different descriptor tables. In WebGPU we shouldn’t pretend to be an explicit API but then use the flat binding model of D3D11.
  • KN: might be repeating RC, but: if we change the binding model to be D3D11’s then D3D12 shaders won’t work in our API. Correct?
  • MM: no, that’s not correct.
  • CW: so the root signature wouldn’t work because it maps to root descriptor?
  • KN: if shader had root descriptor in it would we drop it on the floor?
  • MM: yes.
  • CW: the root signature is usually provided out-of-band to the shader, either as big attribute to main() or as an API-supplied object.
  • RC: it is true that outside of the HLSL shader you can use whatever root signature you want. Can also use metadata APIs to query whatever root signature layout the shader provided. Using the root signature defined in the shader is off-putting because it uses D3D12 terminology, unless we have a mapping between terms there and the terms we decide to use.
  • MM: in the issue, the last 4-5 comments seem to be coalescing around changing the shading language so that the binding numbers all have to be distinct regardless of the types. That’s a solution we’re willing to accept.
  • KN: not so much changing the language, but rather having a default root signature you don’t need to specify. If you write HLSL for WebGPU then you don’t need to specify it. But if you port in a D3D11 or D3D12 HLSL shader you have to.
  • RC: and that’s where you have the mapping dictionary thing?
  • KN: yes. Has same function as root descriptor. Make root descriptor optional, so you don’t have to have it if you don’t want to, and it’s completely transparent.
  • CW: to recap Kai’s proposal: if you have an HLSL shader with disjoint registers, it has an implicit root signature layout and it works with the WebGPU binding model right now. If you have HLSL for D3D11 that you really don’t want to change, you can provide your own root signature remapping registers to spaces / slots. But if you write your code in a style for WebGPU then you get an implicit root signature you want.
  • MM: why not modify one or the other directly?
  • JG: it makes D3D11 style shaders work. D3D12 style shaders, that actually specify spaces, also work.
  • MM: we can make them work by adding in this root signature. Why is this better than changing the binding model? What is the benefit?
  • KN: I’m saying that the WebGPU author wouldn’t need to use this unless they use old shaders.
  • JG: question
  • KN: they’d need it for old shaders if they specified e.g. b0 and t0.
  • MM: my question still stands. Why not make the API and shading language match?
  • JG: i’m a fan of them matching, but not making our binding model match D3D11’s.
  • CW: right now our binding model is 2 dimensional. This would make it 3D. Also, it’s not good practice to use a single bind group. They will have to edit their shader because the space concept doesn’t exist in HLSL for D3D11.
  • KN: either that or use a root descriptor.
  • MM: think that the root descriptor does let you do that. In DX12 program you can map these arbitrarily.
  • CW: the reason here is: looking at pure D3D11 HLSL compatibility: fxc doesn’t know how to parse the “space” declaration. You’re making it so HLSL for D3D11 and code that is in linear register tables per resource type works on WebGPU, and that will strongly encourage people to use a single BindGroup, which is not what we want. You want to encourage people to either modify their shader, or provide a mapping to the correct binding model. Do we do a 2D binding model, or a 3D bindign model with an extra dimension for the register type?
  • KN: had another thought. D3D11 has a 2D binding model between type and register index. D3D12 has a 2D binding model but it’s register number / space number. No API has a 3D binding model. We’d be inventing that. We would not even be going back to D3D11, but doing something new, because there aren’t APIs with 3D binding models now.
  • DM: there’s something I don’t quite understand about the vision of D3D11 HLSL compatibility. Users can specify the space in HLSL, but D3D11 shaders won’t specify the space. Will all D3D11 shaders be using one BindGroup?
  • MM: D3D doesn’t have bindgroups.
  • DM: we implemented via bindgroups. How do you see the binding model working for those D3D11 shaders?
  • MM: are you asking how HLSL without space keywords maps onto Vulkan?
  • CW: onto WebGPU, in your mind
  • MM: the “space” keyword maps to a descriptor set. In Descriptor set, mapped both to type and binding number.
  • DM: so single BindGroup if space is eliminated?
  • MM: yes
  • DM: is that the way you see them being used? Because that’s not the way people want them to run. People have D3D12 root signatures so they can bind different parts of shader inputs separately, in groups. Nobody binds all the shader inputs at once.
  • MM: ok, makes sense.
  • RC: makes sense to me too. Corentin makes a compelling argument that we need some mapping layer.
  • CW: OK. So does this sound OK? We’ll need to figure out what the root signature layout looks like. Kai’s proposal is a good starting point that we can decide what IDL we need. But that IDL would be unnecessary if we ingest SPIR-V. So we need to discuss.
  • KR: for the situation where shader doesn’t have disjoint register numbers, can we look at in-shader representation? That way we can avoid HLSL specific APIs in WebGPU.
  • KN: probably not ideal to use in-shader representation because there are plenty of apps that use one shader source for both D3D11 and 12.
  • MM: agree with Kai. Adding micro-syntaxes is a bad idea when we can represent things with object hierarchies.

More error handling

  • CW: should we discuss this week?
  • KN: would prefer to not, this week.

Vertex and input descriptor changes

  • CW: which PR?
  • KN: #186, #151
  • CW: the question is how we map from indices in the shader to indices in the IDL. If you have a shader with a lot of vertex attributes, how do you pass in the descriptor for #N?
  • CW: lots of discussion. Two proposals:
      1. Use potentially sparse JavaScript arrays. Says set vertex attribs 0, 1, and 24.
      1. Use an int-keyed object, which is basically a dictionary
  • JG: would a sparse array count as this? Duck-typed?
  • KN: I believe so.
  • JG: great, I like that.
  • CW: the two proposals are basically a sparse structure, where you can set a subset of the indices and they don’t have to be contiguous. What will be nicest to use?
  • JG: is this hot code?
  • CW: it might be.
  • KN: SetVertexBuffers is definitely hot.
  • CW: used for bind group indices; indices of bindings in bind group; vertex buffers; color attachment indices. (TODO: fill out this list). Only hot point would be SetVertexBuffers.
  • CW: is there precedent on web APIs for having sparse arrays or int-keyed objects?
  • KN: no idea. Haven’t seen anything like that. Didn’t search very hard.
  • RC: when you say int-keyed object you mean what Kai said in #186?
  • KN: might have mentioned it in the other issue but yes. It’s at least in a comment in the IDL in the pull request. That’s the main place where it’s described.
  • JD: object keys are always strings right?
  • KN: yes, true for arrays too. Non-sparse arrays are almost surely faster than int-keyed objects. Sparse arrays, maybe not. Not as optimized.
  • JD: object keys are definitely not optimized?
  • KN: that’s correct. Being passed directly into an API entry point. Even sparse arrays would be going through a bunch of bindings code.
  • JD: but if it’s a bottleneck we could potentially optimize it?
  • KN: sequences (non-sparse arrays) do come into the browser engine in a more optimized way because sequences are better specified in IDL. If we had a non-sparse sequence (like we had before this pull request) it would be more optimizable.
  • CW: would it make sense for sequence to take an array of these objects? Less optimal path for sparse arrays?
  • JD: also maps that you can key with an integer.
  • KN: true. didn’t find any IDL that uses maps.
  • DM: why do we have to choose between sparse and non-sparse? Why not sequence of descriptors for a buffer?
  • JG: DM’s proposal is that if you don’t fill it you get default values.
  • KN: I don’t have anything against this.
  • JG: can I ask about hotness? Part of RenderPipelineDescriptor, which should be cold code?
  • CW: right. The only hot thing would be SetVertexBuffers, which is on an encoder.
  • DM: I don’t see a problem having some of the default values in there. Most of the time the user would have contiugous numbers.
  • JG: performance is paramount.
  • DM: this PR is not about SetVertexBuffers.
  • JG: if it’s not about SetVertexBuffers than performance doesn’t matter.
  • CW: for SetVertexBuffers we have a sequence of things, and for the other we don’t care because the code is cold?
  • KN: I agree that we should use non-sparse sequences for SetVertexBuffers, and consider the other part separately.
  • RC: so for the other part, if you’re missing some keys, those things you’re missing are un-set? Or unchanged?
  • KN: we can decide.
  • MM: do we know what the performance cliffs are for sparse arrays? If the perf cost is negligible, then we can use it in SetVertexBuffers, too.
  • KN: an additional unboxing is always required. If we get a sequence of objects then in C++ we get a sequence of objects. “sequence?” is something we have to unbox. Not sure of the perf diff.
  • MM: if the extra stuff is 5 assembly instructions then the additional developer convenience is worth it.
  • JG: not if it’s pointer chasing and invalidating cache lines.
  • KN: if we require non sparse sequences for SetVertexBuffers, is it worse for JS developers? Not sure.
  • MM: I think it would be, but maybe pretty small issue.
  • CW: don’t think we’re going to be able to make a decision on this now. Can people do a perf investigation and we’ll discuss next week?
  • JG: not sure perf investigation will help
  • CW: I’m saying to compare the perf of the things across browser engines.
  • MM: I’d like to know whether the add’l lost perf from unboxing is measurable at all.
  • JG: hard to say.
  • KN: all of the encoders are considered hot code. Have been thinking that instead of bindings from JS to C++, we do them entirely in JS, and that would change the perf characteristics. It would make things more complex too. Chrome’s bindings are extremely expensive and we’re thinking about bypassing them.
  • MM: what is the serialization code you’re describing?
  • KN: encoding / decoding.
  • CW: thinking about putting cmdbuf encoding logic in the JS VM. Impl detail, but would change perf characteristics.
  • MM: because you encode to an intermediary format and then later to Vulkan?
  • KN: yes. Avoids lots of bindings cost for us.
  • CW: how do we progress on this?
  • KR: can we prototype two IDL variants and call them in a loop? Concerned won’t be representative.
  • JG: I’m concerned about that too.
  • CW / KN: we could probably do that.
  • CW: for the cold code issue the perf won’t matter so we should do the simplest thing for the developer.
  • KN: we should write out examples more thoroughly.
  • CW: sounds good. So, quick benchmarks for hot code, and see how easy it is to write the cold code.

Case for existing GLSL on the Web #219

  • CW: skipping this this week because it’ll take a long time

PR burndown

  • Already talked about depth bias
  • #222
    • Only valid values for texture aspects are: setting something that gets the whole texture, or something that gets just the depth or stencil. Change to get depth/stencil, or just have a mask?
    • JG: will this ever change?
    • CW: if we ever have planar textures we will have planes.
    • RC: can you have packed depth-stencil?
    • CW: yes. That would be “everything”.
    • RC: so “everything” depends on the kind of texture. So creating color texture with stencil?
    • CW: that would be illegal.
    • CW: we can bikeshed on the name. Would be a simplification.
    • CW: no strong opinions, so can we get +/- reviews on it? Thanks.
  • #223
    • CW: for fences, you’d pass SignalQueue during construction. Otherwise create fence from queue.
    • JG: does this mean submitting micro-command-buffers on some backends? Like to create the fence?
    • KN: no, just a rephrasing. Does same operation internally.
    • MM: sounds fine.
    • JG: sure.
    • RC: so fence descriptor already has signal queue b/c of descriptor? OK, sounds fine.

Agenda for next meeting

  • Error handling PR Kai will put up
  • Case for existing GLSL on the Web #219
  • DM: getSubData / setSubData? #213
    • Our native users are using setSubData and asking if that’s the right thing to do.
  • Have several things we put in the snapshot tracker. Need to talk about: remove u32 and u64 types in IDL? Also, what do we do with masks? Bitmasks, sequences of enums, etc.
  • PR burndown
  • CW: Dean do you think you could chair next meeting?
    • DJ: yes.
Clone this wiki locally