Skip to content

GPU Web 2020 01 06

François Daoust edited this page Dec 1, 2020 · 1 revision

Chair: Corentin

Scribe: Ken and Austin

Location: Google Meet

TL;DR

  • Changes to adapter discovery
    • Pluralize requestAdapters and adjacent changes #524
      • Makes requestAdapter return a list of adapters instead of a single one.
      • Doesn’t add more fingerprinting than getting adapters for all combinations of adapterOptions.
      • Consensus that device 0 should be the recommended device.
      • Would help developers check for interaction with WebML or compute only devices.
      • User agents can still choose to expose whichever adapters they want.
      • Needs more discussion.
    • RequestDevice returns null if adapter is lost #521
      • Helps developers know they should retry requesting an adapter.
      • Promise rejection would mean they did something wrong.
      • General agreement but needs more reviewing.
    • GPU.onAdapterAdded #522
      • Avoids applications having to poll for new devices.
      • D3D12 has a changed event instead or added/removed.
      • No resolution.
  • PR Burndown
    • Add [EnforceRange] to all integers #498
      • Approved without semantic typedefs
    • Make imageHeight optional #517
      • Approved with the tight packing semantic.
    • imageHeight -> zPitch #519
      • No resolution, discussion about 2D array and 3D textures converging but maybe having different memory layouts.

Tentative agenda

  • Changes to adapter discovery #521 #522 #523
  • Keeping data on chip #435
  • PR burndown
  • (stretch) buffer mapping
  • Agenda for next meeting

Attendance

  • Apple
    • Justin Fan
  • Google
    • Austin Eng
    • Corentin Wallez
    • James Darpinian
    • Kai Ninomiya
    • Ken Russell
    • Shrek Shao
    • Ryan Harrisson
  • Intel
    • Yunchao He
  • Microsoft
    • Chas Boyd
    • Damyan Pepper
    • Rafael Cintron
  • Mozilla
    • Dzmitry Malyshau
    • Jeff Gilbert
  • Mehmet Oguz Derin

Administrative

  • CW: Jan 20 and Feb 17 are US holidays. Skip WebGPU meetings these days?
    • KN: Feb 17 is right after the F2F anyway
    • CW: will skip.
  • RC: D3D team update:
    • Spoke with the D3D team, they’re willing to come and have a panel discussion with all of us where we can ask questions about D3D, why it is the way it is, where things are going, etc. Would appreciate a list of topics ahead of time. Damyan will be here both days.
    • DM: thanks, sounds great
  • CW: please let Rafael know if you’re coming to the WebGL or WebGPU F2F. Date / time / dietary restrictions, etc.

Changes to adapter discovery

  • #521 #522 #523
  • KN: biggest: changing requestAdapter to requestAdapters, plural
    • Wish Myles could be here, was originally involved in the discussion
  • KN: Originally, we made it requestAdapter singular due to fingerprinting concerns. Should make it plural to make it more flexible. No reason browser can’t reduce fingerprinting using requestAdapters API. More flexible API for situations where we want to expose multiple adapters to the page: off the web, trusted context (Electron), etc.
  • KN: still allows easy default. With singular version, you just get the default. Plural version gives you an array. By spec, the first element would be the default one. Would return an array of length at least one.
  • KN: open questions about what RequestAdapterOptions means. Does it filter list? Reorder it? How much does app need to do its own filtering? E.g., to find high-performance GPU. Should app reorder it or should browser return that as adapters[0]? These are details that don’t need to be decided on to determine whether we want to go with the plural version of the API.
  • KN: I think apps will likely do many requestAdapter calls and try to find the result they want themselves. That would be an anti-pattern.
  • DM: why would apps do that?
  • KN: I don’t think they’d do a lot of requestAdapter calls, but can see them doing lowPower / highPerformance calls and then seeing whether the device has two GPUs in the first place. Or whether they should advise user to plug in their laptop for better perf. Don’t think this improves the experience for developers.
  • RC: if we do have it return an array, I’d strongly prefer to tell people to use the zeroth one, and reorder them based on RequestAdapterOptions to e.g. put the high-perf adapter first.
  • JG: that’s the way D3D does it.
  • RC: a little concerned that if sites say that the Intel adapter will be the worse one - what may be true today won’t be true in the future. Concerned developers will make bad assumptions if we give them too much information. Will complain if they pick the wrong one, and 360 degree videos are poor because they make too many copies between GPUs.
  • KN: if a developer wanted to do this, they could request both lowPower and highPerformance, make a decision between them, and still do the wrong thing. Having this return both adapters makes it a little easier for them. If we know the discrete GPU will perform poorly due to extra copies then maybe the browser shouldn’t expose it at all.
  • JG: it is unfortunate Myles isn’t here. Like Kai said, don’t want devs doing this antipattern to enumerate the GPUs anyway. If they’re trying to do that they’ll do their best to do it. So we might as well give them an entrypoint to do it. If we don’t give them this API they’ll need to do weird things to request multiple adapters. Having ordered via powerPreference is a good way to handle it. If someone really wants to run on Intel they’ll figure out how to do that.
  • DM: concern: it’s a half-measure to solve the problem. If we expose the list why do we expose the preferences? Don’t impose any order, let them do it? JG mentioned this on another call today.
  • RC: I definitely think, if we have an array, we should have the option to put high-performance first. My desktop machine has an Intel integrated GPU, a discrete GPU, monitors plugged into the discrete GPU. App should always use the high-perf GPU. Shouldn’t leave it in the hands of developers to pick one.
  • CW: two questions here:
    • Do we give devs a list?
    • What sort of detailed information about the adapter do we give them?
  • CW: if we do this then maybe the name should not be queryable from the adapter - or maybe it should only be in DevTools’ view. If we just give adapters that say “high-perf” or “low-power”, then you can’t tell and maybe that works.
  • JG: I don’t know.
  • KN: In situation Rafael described it’s still wrong. If Intel’s low-power and NVIDIA’s high-performance...
  • RC: In the desktop case, low power and high perf both return the discrete NVIDIA GPU.
  • KN: if list isn’t sorted, either exclude Intel one from list (good option, IMO), or give it some indication of which one it should use. Order is a good indication.
  • DM: Not a good option. Shouldn’t hide it because it can still be used.
  • JG: gets into a less-common use case, where people want to enumerate headless adapters that don’t have any output. How do you quantify those with low-power and high-performance?
  • KN: I think it’s in here - the idea of having adapter options like “allow compute only adapters”. Think those have to be passed into requestAdapters, but it’s orthogonal to high-perf and low-power.
  • CW: will we end up with adapter usage flags? “This one supports rendering to screen”. “This one supports sharing data with WebML”.
  • JG: pre-sorting can be useful - but if you return randomized list (low/high-power, supports swap chains, etc.)...
  • KN: What I had in mind was that power preference influences order, but there are additive flags like allowComputeOnly that adds things to the list, or supportsWebML, etc. But the default thing (index 0) should support swapchain, rendering, and be reasonably efficient.
  • DM: I don’t think there’s compute-only adapter.
  • KN: there is.
  • DM: it’s not what Rafael is describing.
  • KN: I think it’s related.
  • CW: D3D has a thing called DXCore which lets you export compute-only adapters.
  • DM: that’s cool. But if you can’t present a swap chain it doesn’t mean you’re compute-only
  • CW: correct. Different usage flag.
  • JG: Different usage flag than high/low-power. If we add these flags, wondering about people trying to do hashcache-mining. Will want to enumerate all GPUs on system and shove data through them. If they have to do this by getting both low/high-power, compute-only, etc., they’ll do it. Easiest for them if we say “here are all the adapters” and let them choose.
  • CW: is making it easier for them a good or bad thing?
  • JG: I think we shouldn’t add arbitrary hoops for people to jump through. API seems easiest if you say, here are all the adapters.
  • CW: So Kai had a proposal internally like gpu.requestAdapterList -> GPUAdapterList. Which is opaque, but hides the asynchrony of requesting everything. Then, you can ask that opaque object for high perf, low power, etc. Asynchronous initialization for discovery, then you have the opaque object that you can query.
  • JG: isn’t that similar to a Promise that returns sequence of adapters?
  • CW: Would persistently have the list of adapters so if they are added/removed the internals change.
  • JG: couldn’t that just be the instance?
  • CW: potentially, but you don’t want navigator.gpu to be a Promise. But maybe.
  • JG: would allow us to collect it. Right now it’s a global.
  • CW: ...yes.
  • KN: Had trouble designing something like that because one situation:
    • Tab is backgrounded and the UA wants to give you an adapter later (once foregrounded). Today we do that by not resolving requestAdapter yet. If we had an opaque object like GPUAdapterList, then we wouldn’t have a nice async signal like that.
  • KR: How would you know how many adapters you would get back if it’s backgrounded? The length of the result would change, right?
  • KN: Yea.
  • CW: JF, any thoughts on this?
  • JF: Think we should ask Myles about this.
  • CW: definitely can’t resolve this any time soon - big topic.
  • RC: is rationale for making it an Array that we have the information and we should expose it? Or has someone come to us and asked for the whole list?
  • KN: It’s just because it’s a better way to expose the information that is already there and queryable.
  • RC: OK, so it’s there and we might as well give it to them.
  • KN: some people at least will try to grab them all.
  • JG: this will definitely be in some sort of “pixel tracker” that asks what % of people have WebGPU with various options. Those use cases are the ones that would want to track this.
  • RC: If you have more than two adapters, then exposing the list will give you more information than just the two low/high flags.
  • JG: the idea is that in theory you could expose three. If you only wanted to expose the two we aren’t forcing you to expose three.
  • KN: think it’s likely you’d have three because of allowMajorPerformanceCaveat, and the software rasterizer isn’t exposed.
  • CW: Another example is if you have a compute-only GPU connected to a laptop. If I say high performance + allowComputeOnly, I might get that one instead of the internal AMD discrete GPU or Intel integrated.
  • CW: let’s let this bake for a bit. Maybe revisit next week.

RequestDevice returns null if adapter is lost #521

  • KN: The difference here is that previously if the adapter was lost, the promise rejects. Now, if the promise rejects, the developer screwed up. Null means the adapter was lost and you should fall back to a different adapter.
    • An app should never give up on getting WebGPU access due to requestDevice returning null or GPUDevice.lost resolving. It should only give up based on a requestAdapter rejection. (It should also give up on a requestDevice rejection, as that indicates an app programming error.)
  • RC: was a bit confused. Once an adapter becomes lost, doesn’t it remain permanently lost and won’t become alive again? Need to create a new adapter to render again?
  • KN: yes.
  • RC: so “shouldn’t give up” means someone should try and try forever. I think for device loss, should tell people, please give up.
  • KN: since the adapter would be lost they couldn’t get any devices from it. To see if they could create a new device they’d have to get a new adapter. If they get a new adapter then they can proceed. If fetching the adapter rejects, then they have to fall back. This is one of the case studies of the error handling document. Want app to be able to easily respond to this situation.
  • RC: if adapter’s lost and if they request a device from it, it’ll return null and they should give up?
  • KN: yes. I should clarify that in the doc.
  • RC: so long as we don’t tell people, never give up on lost devices, I think I’m fine with this. In the past, people have told me, Promise rejection is analogous to a synchronous call and an exception being raised. In this case if the adapter’s lost and getting the device returns null that seems fine. In requestAdapter there is hope that it might succeed in the future.
  • KN: means there isn’t an adapter, but doesn’t mean there will never be an adapter.
  • KN: that’s why there’s another PR, onAdapterAdded.
  • RC: So if your machine cannot do WebGPU, then requestAdapter will return null as well, correct?
  • KN: It would reject.
  • RC: so requestAdapter should reject?
  • KN: It could be null. Either is okay. The idea is you would try to use WebGPU, it fails, and then you fallback to something else.
  • RC: but in that case, you’re not doing anything wrong as the dev. You’re trying to initialize WebGPU. I think requestAdapters should return null, or the empty list, etc.
  • KN: good point, I’ll think about that.
  • DM: I haven’t had a chance to look at it yet.
  • JG: Superficially seems fine to me.
  • CW: Kai can you update the PR to have requestAdapter => null if there is none?

GPU.onAdapterAdded #522

  • KN: if an adapter becomes available to the page it fires this event. Page can requestAdapter again, look through the list again, etc., to see if it wants to switch from WebGL to WebGPU, or from one adapter to another, or start using the adapter for physics acceleration, etc.
  • KN: apps wouldn’t be expected to handle this but could if they wanted to.
  • JG: sounds useful. Would it make more sense to have onAdaptersChanged? Maybe you only care about adding, because if something you cared about was removed, you’d notice.
  • KN: Originally that was the idea. It became “added” because I didn’t want multiple signals to the app at the same time for the same event. If an adapter was lost, you would both lose the devices and get onAdaptersChanged. Could result in races, need to specify order, etc.
  • JG: what’s the signal we get upon device lost? Adapter goes away?
  • KN: yes, I believe so.
  • JG: In that case, if you wanted to know if an adapter went away, you need to create a device first. Is there a use case to know this without needing to make a device? ex.) For the SurfaceBook, there’s a physical lock for the GPU/keyboard
    • CW: there’s a GPU in the keyboard?
    • KN: yes, there can be. Have to eject the GPU in order to detach the keyboard.
    • RC: there are 2 GPUs. The NVIDIA one is in the keyboard, Intel one in the monitor.
    • KN: it’s very cool.
  • CW: guess Adapters themselves could have a lost property.
  • KN: reason they don’t is that I didn’t need it for my case studies.
  • JG: feel that there might be. Would prefer if this were onAdaptersChanged.
  • KN: maybe we want two signals, onAdaptersAdded and onAdaptersRemoved. App would probably want to handle added without handling removed.
  • JG: think I generally prefer fewer events.
  • KN: we could have one event and pass in a type.
  • JG: annotation on the event? deviceAdded, deviceRemoved, both?
  • KN: think so. Concern: one appears and one disappears at the same time. Doesn’t have to be physically in the system. UA could decide, system’s been unplugged, so we hide the high-perf GPU even though it’s still physically available.
  • JG: if you want to see if an adapter was added, an easy way to do this in onAdaptersChanged, you redo your queries and decide if you want to use the same adapter you’re currently using, you do nothing. But at least having this event / signal means you don’t have to poll.
  • KN: agree we don’t want people to poll.
  • DP: on Windows you only get an event when adapters changed. Impl would have to scan through and dispatch added/removed events. Would definitely have to handle case where something’s both added and removed simultaneously.
  • RC: Immersive Web spec has devices changed event. It’s “onDeviceChanged”.
  • CW: Single device though?
  • RC: That’s true today.

Delaying requestAdapter

  • KN: #523 is very simple. requestAdapter can delay. Want UA to be able to not give an answer until later when adapters are available. Doesn’t change API. Just documents how things should work.
  • RC: fine with this one - example you gave is a good one - but think that should be the only example. Don’t think we should say you can delay no matter what. Pages will try WebGPU, then WebGL, etc.
  • KN: something that would only happen if the page weren’t in use in some way.
  • RC: think we shouldn’t arbitrarily delay the promise resolution.
  • CW: let’s review offline.

PR Burndown

  • Add [EnforceRange] to all integers #498
    • CW: was resolution that should do bikeshedding, then land. Haven’t done the bikeshedding yet. There are questions about granularity.
    • KN: DM wanted semantic types but JG didn’t.
    • JG: I don’t mind - but it’s harder for me to read specs when I have to remember that texture dimensions are 32-bit and buffer sizes are 64-bit. Signed/unsigned, etc. Like to have that directly in the IDL definitions.
    • KN: I’m pretty neutral.
    • DM: do you have to remember it? For what use?
    • JG: not as important for this, but feels more valuable to me to have the types directly in there. Questions like, can I copy a buffer of 64-bit size? Can dynamic offsets be large, or do they have to be smaller? These are all hints to me. Putting them under BufferSize/BufferOffset I haven’t found very helpful because they don’t say what the constraints are. When copying between buffers / textures it can get weird with offsets, etc. Like to say, this is an unsigned 32-bit integer.
    • CW: it helps with dimensionality. If it’s a “slot” you can search for “slot” in the spec and find the e.g. two uses. Tenuous advantage that can be achieved via proper naming, too.
    • DM: different ways to compute semantic: type, name and documentation. Names don’t have to be consistent, but types are. Easier to navigate when there are types.
    • JG: problem: overloads, where you can receive multiple types at a certain point.
    • DM: like size/offset?
    • JG: yes.
    • DM: agree that’s a tricky spot. Buffer address is one spot. Confused some people that it’s both an offset and size at the same time.
    • CW: I think the path of least resistance is to not have type safety / typedefs there.
    • KN: it’s just naming.
    • DM: ok.
  • Make imageHeight optional #517
    • CW: is imageHeight==0 only valid with copyHeight==1, or does imageHeight==0 mean “tightly packed”?
    • JG: I prefer “tightly packed”.
    • DM: it’ll be the most likely case.
    • JF: I like tightly packed because it’s one less computation we need to do.
  • imageHeight -> zPitch #519
    • KN: this is the hardest bikeshedding issue in the spec.
    • JG: yes, and these are some of the grossest things. Every time I have to touch these in WebGL I shudder. From that spec, I recommend names be a little verbose to be clearer.
    • KN: the reason I picked Z was to make it match another place in the spec where Z means either “layer” or “depth”: in “Extents3D”.
    • Discussion - think that’s wrong.
    • CW: in copySize, for the Origin3D, the Z can mean both the base texture layer in the array texture, or … Basically, it means both array layer and 3D slice in 3D textures.
    • DM: what about cubes which have both slices and 3D indices?
    • JG: think it’s a previous PR which enables arrays of cube maps.
    • CW: think Z and array layers should be the same thing. In GPU APIs you can convert / reinterpret cast 2D arrays into 3D textures. Cube map arrays too. They’re just images stored one after the other.
    • KN: think we should close #520. Q about whether we should merge the two in other places.
    • CW: like?
    • KN: TextureDescriptor.
    • DM: wouldn’t separating it be clearer now? Should use same terms they used to create the texture.
    • CW: because in the future a 2D array and 3D texture would be the same. Should TextureViews be able to reinterpret_cast between the two? All APIs have ways to make that happen.
    • DM: I don’t remember but are the tiling modes for 3D textures the same for 2D textures?
    • JG: thought they did have different swizzling mode.
    • DM: thought they did have different swizzling because locality of reference is different for 3D usage than 2D. Slightly different semantics. 3D works best for 3D, 2D array best for 2D array.
    • JG: D3D12 does seem to have different swizzling for 3D textures, in the standard swizzled layouts. Think we need more time on this.
  • Add a validation rule for buffer binding #526
  • Add read-only storage textures as new binding type and texture usage #532

Agenda for next meeting

  • requestAdapters and friends
    • Same as this week essentially.
  • Add a validation rule for buffer binding #526
  • Add read-only storage textures as new binding type and texture usage #532
Clone this wiki locally