Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[webgpu] Add Surface API #21939

Merged
merged 14 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/generated_struct_info32.json
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,29 @@
"limits": 8,
"nextInChain": 0
},
"WGPUSurfaceCapabilities": {
"__size__": 28,
"alphaModeCount": 20,
"alphaModes": 24,
"formatCount": 4,
"formats": 8,
"nextInChain": 0,
"presentModeCount": 12,
"presentModes": 16
},
"WGPUSurfaceConfiguration": {
"__size__": 40,
"alphaMode": 24,
"device": 4,
"format": 8,
"height": 32,
"nextInChain": 0,
"presentMode": 36,
"usage": 12,
"viewFormatCount": 16,
"viewFormats": 20,
"width": 28
},
"WGPUSurfaceDescriptor": {
"__size__": 8,
"label": 4,
Expand All @@ -1270,6 +1293,12 @@
"chain": 0,
"selector": 8
},
"WGPUSurfaceTexture": {
"__size__": 12,
"status": 8,
"suboptimal": 4,
"texture": 0
},
"WGPUSwapChainDescriptor": {
"__size__": 28,
"format": 12,
Expand Down
29 changes: 29 additions & 0 deletions src/generated_struct_info64.json
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,29 @@
"limits": 8,
"nextInChain": 0
},
"WGPUSurfaceCapabilities": {
"__size__": 56,
"alphaModeCount": 40,
"alphaModes": 48,
"formatCount": 8,
"formats": 16,
"nextInChain": 0,
"presentModeCount": 24,
"presentModes": 32
},
"WGPUSurfaceConfiguration": {
"__size__": 56,
"alphaMode": 40,
"device": 8,
"format": 16,
"height": 48,
"nextInChain": 0,
"presentMode": 52,
"usage": 20,
"viewFormatCount": 24,
"viewFormats": 32,
"width": 44
},
"WGPUSurfaceDescriptor": {
"__size__": 16,
"label": 8,
Expand All @@ -1270,6 +1293,12 @@
"chain": 0,
"selector": 16
},
"WGPUSurfaceTexture": {
"__size__": 16,
"status": 12,
"suboptimal": 8,
"texture": 0
},
"WGPUSwapChainDescriptor": {
"__size__": 40,
"format": 20,
Expand Down
4 changes: 4 additions & 0 deletions src/library_sigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1711,9 +1711,13 @@ sigs = {
wgpuShaderModuleReference__sig: 'vp',
wgpuShaderModuleRelease__sig: 'vp',
wgpuShaderModuleSetLabel__sig: 'vpp',
wgpuSurfaceConfigure__sig: 'vpp',
wgpuSurfaceGetCurrentTexture__sig: 'vpp',
wgpuSurfaceGetPreferredFormat__sig: 'ipp',
wgpuSurfacePresent__sig: 'vp',
wgpuSurfaceReference__sig: 'vp',
wgpuSurfaceRelease__sig: 'vp',
wgpuSurfaceUnconfigure__sig: 'vp',
wgpuSwapChainGetCurrentTexture__sig: 'pp',
wgpuSwapChainGetCurrentTextureView__sig: 'pp',
wgpuSwapChainPresent__sig: 'vp',
Expand Down
82 changes: 81 additions & 1 deletion src/library_webgpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ wgpu${type}Release: (id) => WebGPU.mgr${type}.release(id),`;
DeviceLost: 2,
Unknown: 3,
},
CompositeAlphaMode: {
Auto: 0,
Opaque: 1,
},
CreatePipelineAsyncStatus: {
Success: 0,
ValidationError: 1,
Expand Down Expand Up @@ -154,6 +158,10 @@ wgpu${type}Release: (id) => WebGPU.mgr${type}.release(id),`;
RenderPassDescriptorMaxDrawCount: 0xF,
TextureBindingViewDimensionDescriptor: 0x11,
},
SurfaceGetCurrentTextureStatus: {
Success: 0,
DeviceLost: 5,
},
QueueWorkDoneStatus: {
Success: 0,
Error: 1,
Expand Down Expand Up @@ -2664,7 +2672,7 @@ var LibraryWebGPU = {
// WGPUAdapterProperties

wgpuAdapterPropertiesFreeMembers: (value) => {
// wgpuAdapterGetProperties does currently allocate anything
// wgpuAdapterGetProperties doesn't currently allocate anything.
},

// WGPUSampler
Expand All @@ -2676,11 +2684,83 @@ var LibraryWebGPU = {

// WGPUSurface

wgpuSurfaceConfigure: (surfaceId, config) => {
{{{ gpu.makeCheckDescriptor('config') }}}
var deviceId = {{{ makeGetValue('config', C_STRUCTS.WGPUSurfaceConfiguration.device, '*') }}};
var context = WebGPU.mgrSurface.get(surfaceId);

#if ASSERTIONS
var viewFormatCount = {{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.viewFormatCount) }}};
var viewFormats = {{{ makeGetValue('config', C_STRUCTS.WGPUSurfaceConfiguration.viewFormats, '*') }}};
assert(viewFormatCount === 0 && viewFormats === 0, "TODO: Support viewFormats.");
var alphaMode = {{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.alphaMode) }}};
assert(alphaMode === {{{ gpu.CompositeAlphaMode.Auto }}} ||
alphaMode === {{{ gpu.CompositeAlphaMode.Opaque }}},
"TODO: Support WGPUCompositeAlphaMode_Premultiplied.");
assert({{{ gpu.PresentMode.Fifo }}} ===
{{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.presentMode) }}});
#endif

var canvasSize = [
{{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.width) }}},
{{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.height) }}}
];

if (canvasSize[0] !== 0) {
context["canvas"]["width"] = canvasSize[0];
}

if (canvasSize[1] !== 0) {
context["canvas"]["height"] = canvasSize[1];
}

var configuration = {
"device": WebGPU.mgrDevice.get(deviceId),
"format": WebGPU.TextureFormat[
{{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.format) }}}],
"usage": {{{ gpu.makeGetU32('config', C_STRUCTS.WGPUSurfaceConfiguration.usage) }}},
"alphaMode": "opaque",
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be either "opaque" or "premultiplied" depending on the configuration, and there should be an assert that it's one of the values that's valid in JS (auto, opaque, premultiplied). (Just look it up in the table above and then assert that the result is not undefined.)

Alternatively, assert the alphaMode is Opaque for now with a TODO, and implement this later if you'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've assert alphaMode is Opaque with a TODO.

};
context.configure(configuration);
},

wgpuSurfaceGetCurrentTexture: (surfaceId, surfaceTexturePtr) => {
{{{ gpu.makeCheck('surfaceTexturePtr') }}}
var context = WebGPU.mgrSurface.get(surfaceId);

try {
var texture = WebGPU.mgrTexture.create(context.getCurrentTexture());
{{{ makeSetValue('surfaceTexturePtr', C_STRUCTS.WGPUSurfaceTexture.texture, 'texture', '*') }}};
{{{ makeSetValue('surfaceTexturePtr', C_STRUCTS.WGPUSurfaceTexture.suboptimal, '0', 'i32') }}};
{{{ makeSetValue('surfaceTexturePtr', C_STRUCTS.WGPUSurfaceTexture.status,
gpu.SurfaceGetCurrentTextureStatus.Success, 'i32') }}};
} catch (ex) {
#if ASSERTIONS
err(`wgpuSurfaceGetCurrentTexture() failed: ${ex}`);
#endif
{{{ makeSetValue('surfaceTexturePtr', C_STRUCTS.WGPUSurfaceTexture.texture, '0', '*') }}};
{{{ makeSetValue('surfaceTexturePtr', C_STRUCTS.WGPUSurfaceTexture.suboptimal, '0', 'i32') }}};
// TODO(https://github.com/webgpu-native/webgpu-headers/issues/291): What should the status be here?
{{{ makeSetValue('surfaceTexturePtr', C_STRUCTS.WGPUSurfaceTexture.status,
gpu.SurfaceGetCurrentTextureStatus.DeviceLost, 'i32') }}};
}
},

wgpuSurfaceGetPreferredFormat: (surfaceId, adapterId) => {
var format = navigator["gpu"]["getPreferredCanvasFormat"]();
return WebGPU.Int_PreferredFormat[format];
},

wgpuSurfacePresent: (surfaceId) => {
// TODO: This could probably be emulated with ASYNCIFY.
abort('wgpuSurfacePresent is unsupported (use requestAnimationFrame via html5.h instead)');
},

wgpuSurfaceUnconfigure: (surfaceId) => {
var context = WebGPU.mgrSurface.get(surfaceId);
context.unconfigure();
},

// WGPUSwapChain

wgpuDeviceCreateSwapChain: (deviceId, surfaceId, descriptor) => {
Expand Down
26 changes: 26 additions & 0 deletions src/struct_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,27 @@
"format",
"viewDimension"
],
"WGPUSurfaceCapabilities": [
"nextInChain",
"formatCount",
"formats",
"presentModeCount",
"presentModes",
"alphaModeCount",
"alphaModes"
],
"WGPUSurfaceConfiguration": [
"nextInChain",
"device",
"format",
"usage",
"viewFormatCount",
"viewFormats",
"alphaMode",
"width",
"height",
"presentMode"
],
"WGPUSurfaceDescriptor": [
"nextInChain",
"label"
Expand All @@ -1488,6 +1509,11 @@
"chain",
"selector"
],
"WGPUSurfaceTexture": [
"texture",
"suboptimal",
"status"
],
"WGPUSwapChainDescriptor": [
"nextInChain",
"label",
Expand Down
8 changes: 4 additions & 4 deletions system/include/webgpu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ These files, and several snippets of other files, are generated by Dawn
(Chromium's WebGPU library):
- [Generator](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/generator/)
- [Generator input](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/dawn.json)
- [Generator output](https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/emscripten-bits/)
- [Generator output](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/emscripten-bits/)

The C header is intended to be mostly the same as the "upstream"
[`webgpu.h`](https://github.com/webgpu-native/webgpu-headers/blob/main/webgpu.h),
Expand All @@ -16,13 +16,13 @@ is included here because it is strongly tied to an exact `webgpu.h` revision.
To update these bindings from Dawn:
1. Copy [`webgpu_enum_class_bitmasks.h`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/include/webgpu/webgpu_enum_class_bitmasks.h) from Dawn's source to `system/include/webgpu/webgpu_enum_class_bitmasks.h`
1. Build Dawn's `emscripten_bits_gen` target (in a gn or CMake build of Dawn, or a build of Chromium) - or, use the Chromium Code Search copy of the generated files if no changes are needed
1. Copy the generated [`emscripten-bits/system`](https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/emscripten-bits/system/) files into Emscripten's `system` directory
1. Copy the generated [`emscripten-bits/system`](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/emscripten-bits/system/) files into Emscripten's `system` directory
- `system/include/webgpu/webgpu.h`
- `system/include/webgpu/webgpu_cpp.h`
- `system/include/webgpu/webgpu_cpp_chained_struct.h`
- `system/lib/webgpu/webgpu_cpp.cpp`
1. Paste the contents of [`library_webgpu_enum_tables.js`](https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/emscripten-bits/library_webgpu_enum_tables.js) over the "Map from enum number to enum string" section of [`library_webgpu.js`](../../../src/library_webgpu.js)
1. Paste [`webgpu_struct_info.json`](https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/emscripten-bits/webgpu_struct_info.json) over the "WebGPU" section of [`struct_info.json`](../../../src/struct_info.json).
1. Paste the contents of [`library_webgpu_enum_tables.js`](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/emscripten-bits/library_webgpu_enum_tables.js) over the "Map from enum number to enum string" section of [`library_webgpu.js`](../../../src/library_webgpu.js)
1. Paste [`webgpu_struct_info.json`](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/emscripten-bits/webgpu_struct_info.json) over the "WebGPU" section of [`struct_info.json`](../../../src/struct_info.json).
1. **Manually update the `globalThis.gpu` compile-time enum tables (AdapterType, BackendType, etc.)**:
- Inspect the `webgpu.h` diff for changes to the integer values of any enums used here. (It's not necessary to add new enum values to these tables until they're needed for something.)
1. **Manually update the "Map from enum string back to enum number" tables.**
Expand Down
Loading
Loading