diff --git a/doc/articles/Surfaces.md b/doc/articles/Surfaces.md new file mode 100644 index 00000000..66ea2025 --- /dev/null +++ b/doc/articles/Surfaces.md @@ -0,0 +1,256 @@ +# Surfaces {#Surfaces} + +Surfaces are used to continuously present color texture data to users in an OS Window, HTML ``, or other similar outputs. +The `webgpu.h` concept of @ref WGPUSurface is similar to WebGPU's [`GPUCanvasContext`](https://gpuweb.github.io/gpuweb/#canvas-context) but includes additional options to control behavior or query options that are specific to the environment the application runs in. In other GPU APIs, similar concepts are called "default framebuffer", "swapchain" or "presentable". + +To use a surface, there is a one-time setup, then additional per-frame operations. +The one time setup is: environment-specific creation (to wrap a ``, `HWND`, `Window`, etc.), querying capabilities of the surface, and configuring the surface. +Per-frame operations are: getting a current @ref WGPUSurfaceTexture to render content to, rendering content, presenting the surface, and when appropriate reconfiguring the surface (typically when the window is resized). + +Sections below give more details about these operations, including the specification of their behavior. + +## Surface Creation {#Surface-Creation} + +A @ref WGPUSurface is child object of a @ref WGPUInstance and created using `::wgpuInstanceCreateSurface`. +The description of a @ref WGPUSurface is a @ref WGPUSurfaceDescriptor with a sub-descriptor chained containing the environment-specific objects used to identify the surface. + +Surfaces that can be presented to using webgpu.h (but not necessarily by all implementations) are: + + - `ANativeWindow` on Android with @ref WGPUSurfaceSourceAndroidNativeWindow + - `CAMetalLayer` on various Apple OSes like macOS and iOS with @ref WGPUSurfaceSourceMetalLayer + - `` HTML elements in Emscripten (targeting WebAssembly) with `WGPUSurfaceSourceCanvasHTMLSelector_Emscripten` + - `HWND` on Windows with @ref WGPUSurfaceSourceWindowsHWND + - `Window` using Xlib with @ref WGPUSurfaceSourceXlibWindow + - `wl_surface` on Wayland systems with @ref WGPUSurfaceSourceWaylandSurface + - `xcb_window_t` using XCB windows with @ref WGPUSurfaceSourceXCBWindow + +For example, creating an @ref WGPUSurface from an `HWND` is done like so: + +```c +WGPUSurfaceSourceWindowsHWND hwndDesc = { + .chain = { .sType = WGPUSType_SurfaceSourceWindowsHWND, }, + .hinstance = GetModuleHandle(nullptr), + .hwnd = myHWND, +}; +WGPUSurfaceDescriptor desc { + .nextInChain = &hwndDesc.chain, + .label = "Main window", +}; +WGPUSurface surface = wgpuInstanceCreateSurface(myInstance, &desc); +``` + +In addition, @ref WGPUSurfaces have a bunch of internal fields that could be represented like this (in C/Rust-like pseudocode): + +```cpp +struct WGPUSurface { + // The parent object + WGPUInstance instance; + + // The current configuration + Option config = None; + + // The frame, if any. + Option currentFrame = None; +}; +``` + +The behavior of `::wgpuInstanceCreateSurface``(instance, descriptor)` is: + + - If any of these validation steps fails, return an error @ref WGPUSurface: + + - Validate that all the sub-descriptors in the chain for `descriptor` are known to this implementation. + - Validate that `descriptor` contains information about exactly one OS surface. + - As best as possible, validate that the OS surface described in the descriptor is valid (for example a zero `HWND` doesn't exist and isn't valid). + + - Return a new @ref WGPUSurface with its `instance` member initialized with the `instance` parameter and other values defaulted. + +## Querying Surface Capabilities {#Surface-Capabilities} + +Depending on the OS, GPU used, backing API for WebGPU and other factors, different capabilities are available to render and present the @ref WGPUSurface. +For this reason, negotiation is done between the WebGPU implementation and the application to choose how to use the @ref WGPUSurface. +This first step of the negotiation is querying what capabilities are available using `::wgpuSurfaceGetCapabilities` that fills an @ref WGPUSurfaceCapabilities structure with the following information: + + - A bit set of supported @ref WGPUTextureUsage that are guaranteed to contains @ref WGPUTextureUsage_RenderAttachment. + - A list of supported @ref WGPUTextureFormat values, in order of preference. + - A list of supported @ref WGPUPresentMode values (guaranteed to contain @ref WGPUPresentMode_Fifo). + - A list of supported @ref WGPUCompositeAlphaMode values (@ref WGPUCompositeAlphaMode_Auto is always supported but never listed in capabilities as it just lets the implementation decide what to use). + +The call to `::wgpuSurfaceGetCapabilities` may allocate memory for pointers filled in the @ref WGPUSurfaceCapabilities structure so `::wgpuSurfaceCapabilitiesFreeMembers` must be called to avoid leaking memory once the capabilities are no longer needed. + +This is an example of how to query the capabilities or a @ref WGPUSurface: + +```c +// Get the capabilities +WGPUSurfaceCapabilities caps; +if (!wgpuSurfaceGetCapabilities(mySurface, myAdapter, &caps)) { + // Either a validation error happened or the adapter doesn't support the surface. + // TODO: This should be a WGPUStatus. + return; +} + +// Do things with capabilities +bool canSampleSurface = caps.usages & WGPUTextureUsage_TextureBinding; +WGPUTextureFormat preferredFormat = caps.format[0]; + +bool supportsMailbox = false; +for (size_t i = 0; i < caps.presentModeCount; i++) { + if (caps.presentModes[i] == WGPUPresentMode_Mailbox) supportsMailbox = true; +} + +// Cleanup +wgpuSurfaceCapabilitiesFreeMembers(caps); +``` + +The behavior of `::wgpuSurfaceGetCapabilities``(surface, adapter, caps)` is: + + - If any of these validation steps fails, return false. (TODO return an error WGPUStatus): + + - Validate that all the sub-descriptors in the chain for `caps` are known to this implementation. + - Validate that `surface` and `adapter` are created from the same @ref WGPUInstance. + + - Fill `caps` with `adapter`'s capabilities to render to `surface`. + - Return true. (TODO return WGPUStatus_Success) + +## Surface Configuration {#Surface-Configuration} + +Before it can use it for rendering, the application must configure the surface. +The configuration is the second step of the negotiation, done after analyzing the results of `::wgpuSurfaceGetCapabilities`. +It contains the following kinds of parameters: + + - The @ref WGPUDevice that will be used to render to the surface. + - Parameters for the textures returned by `::wgpuSurfaceGetCurrentTexture`. + - @ref WGPUPresentMode and @ref WGPUCompositeAlphaMode parameters for how and when the surface will be presented to the user. + +This is an example of how to configure a @ref WGPUSurface: + +```c +WGPUSurfaceConfiguration config = { + nextInChain = nullptr, + device = myDevice, + format = preferredFormat, + width = 640, // Depending on the window size. + height = 480, + usage = WGPUTextureUsage_RenderAttachment, + presentMode = supportsMailbox ? WGPUPresentMode_Mailbox : WGPUPresentMode_Fifo, + alphaMode = WGPUCompositeAlphaMode_Auto, +}; +wgpuSurfaceConfigure(mySurface, &config); +``` + +The parameters for the texture are used to create the texture each frame (see @ref Surface-Presenting) with the equivalent @ref WGPUTextureDescriptor computed like this: + +```c +WGPUTextureDescriptor GetSurfaceEquivalentTextureDescriptor(const WGPUSurfaceConfiguration* config) { + return { + // Parameters controlled by the surface configuration. + .size = {config->width, config->height, 1}, + .usage = config->usage, + .format = config->format, + .viewFormatCount = config->viewFormatCount, + .viewFormats = config->viewFormats, + + // Parameters that cannot be changed. + .nextInChain = nullptr, + .label = "", + .dimension = WGPUTextureDimension_2D, + .sampleCount = 1, + .mipLevelCount = 1, + }; +} +``` + +When a surface is successfully configured, the new configuration overrides any previous configuration and destroys the previous current texture (if any) so it can no longer be used. + +The behavior of `::wgpuSurfaceConfigure``(surface, config)` is: + + - If any of these validation steps fails, TODO: what should happen on failure? + + - Validate that `surface` is not an error. + - Let `adapter` be the adapter used to create `device`. + - Let `caps` be the @ref WGPUSurfaceCapabilities filled with `::wgpuSurfaceGetCapabilities``(surface, adapter, &caps)`. + - Validate that all the sub-descriptors in the chain for `caps` are known to this implementation. + - Validate that `device` is alive. + - Validate that `config->presentMode` is in `caps->presentModes`. + - Validate that `config->alphaMode` is either `WGPUCompositeAlphaMode_Auto` or in `caps->alphaModes`. + - Validate that `config->format` if in `caps->formats`. + - Validate that `config->usage` is a subset of `caps->usages`. + - Let `textureDesc` be `GetSurfaceEquivalentTextureDescriptor(config)`. + - Validate that `wgpuDeviceCreateTexture(device, &textureDesc)` would succeed. + + - Set `surface.config` to a deep copy of `config`. + - If `surface.currentFrame` is not `None`: + + - Do as if `::wgpuTextureDestroy``(surface.currentFrame)` was called. + - Set `surface.currentFrame` to `None`. + +It can also be useful to remove the configuration of a @ref WGPUSurface without replacing it with a valid one. +Without removing the configuration, the @ref WGPUSurface will keep referencing the @ref WGPUDevice that cannot be totally reclaimed. + +The behavior of `::wgpuSurfaceUnconfigure``()` is: + + - Set `surface.config` to `None`. + - If `surface.currentFrame` is not `None`: + + - Do as if `::wgpuTextureDestroy``(surface.currentFrame)` was called. + - Set `surface.currentFrame` to `None`. + +## Presenting to Surface {#Surface-Presenting} + +Each frame, the application retrieves the @ref WGPUTexture for the frame with `::wgpuSurfaceGetCurrentTexture`, renders to it and then presents it on the screen with `::wgpuSurfacePresent`. + +Issues can happen when trying to retrieve the frame's @ref WGPUTexture, so the application must check @ref WGPUSurfaceTexture `.status` to see if the surface or the device was lost, or some other windowing system issue caused a timeout. +The environment can also change the surface without breaking it, but making the current configuration suboptimal. +In this case, @ref WGPUSurfaceTexture `.suboptimal` will be `true` and the application should (but isn't required to) handle it. +Surfaces often become suboptimal when the window is resized (so presenting requires resizing a texture, which is both performance overhead, and a visual quality degradation). + +This is an example of how to render to a @ref WGPUSurface each frame: + +```c +// Get the texture and handle exceptional cases. +WGPUSurfaceTexture surfaceTexture; +wgpuSurfaceGetCurrentTexture(mySurface, &surfaceTexture); + +if (surfaceTexture.status != WGPUSurfaceGetCurrentTextureStatus_Success) { + // Recover if possible. + return; +} +if (surfaceTexture.suboptimal) { + HandleResize(); + return; +} + +// The application renders to the texture. +RenderTo(surfaceTexture.texture); + +// Present the texture, it is no longer accessible after that point. +wgpuSurfacePresent(mySurface); +``` + +The behavior of `::wgpuSurfaceGetCurrentTexture``(surface, surfaceTexture)` is: + + - Set `surfaceTexture->texture` to `NULL`. + - Set `surfaceTexture->suboptimal` to `false`. + + - If any of these validation steps fails, set `surfaceTexture->status` to `WGPUSurfaceGetCurrentTextureStatus_Error` and return (TODO send error to device?). + + - Validate that `surface` is not an error. + - Validate that `surface.config` is not `None`. + - Validate that `surface.currentFrame` is `None`. + + - If `surface.config.device` is not alive, set `surfaceTexture->status` to `WGPUSurfaceGetCurrentTextureStatus_DeviceLost` and return. + - If the implementation detects any other problem preventing use of the surface, set `surfaceTexture->status` to an appropriate status (other than `Success`, `Error`, or `DeviceLost`) and return. + - Let `textureDesc` be `GetSurfaceEquivalentTextureDescriptor(surface.config)`. + - Create a new @ref WGPUTexture `t`, as if calling `wgpuDeviceCreateTexture(surface.config.device, &textureDesc)`, but wrapping the appropriate backing resource. + - Set `surface.currentFrame` to `t`. + - If the implementation detects a reason why the current configuration is suboptimal, set `surfaceTexture->suboptimal` to `true`. + +The behavior of `::wgpuSurfacePresent``(surface)` is: + + - If any of these validation steps fails, TODO send error to device? + + - Validate that `surface` is not an error. + - Validate that `surface.currentFrame` is not `None`. + + - Do as if `::wgpuTextureDestroy``(surface.currentFrame)` was called. + - Present `surface.currentFrame` to the `surface`. + - Set `surface.currentFrame` to `None`. diff --git a/doc/articles/index.md b/doc/articles/index.md index cbd9b351..ca2e8cdf 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -1,3 +1,4 @@ \page articles Articles -- \subpage Asynchronous-Operations \ No newline at end of file +- \subpage Asynchronous-Operations +- \subpage Surfaces diff --git a/webgpu.h b/webgpu.h index 1ee9a8c4..aba280ff 100644 --- a/webgpu.h +++ b/webgpu.h @@ -112,6 +112,9 @@ typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder WGPU_OBJECT_ATTR typedef struct WGPURenderPipelineImpl* WGPURenderPipeline WGPU_OBJECT_ATTRIBUTE; typedef struct WGPUSamplerImpl* WGPUSampler WGPU_OBJECT_ATTRIBUTE; typedef struct WGPUShaderModuleImpl* WGPUShaderModule WGPU_OBJECT_ATTRIBUTE; +/** + * An object used to continuously present image data to the user, see @ref Surfaces for more details. + */ typedef struct WGPUSurfaceImpl* WGPUSurface WGPU_OBJECT_ATTRIBUTE; typedef struct WGPUTextureImpl* WGPUTexture WGPU_OBJECT_ATTRIBUTE; typedef struct WGPUTextureViewImpl* WGPUTextureView WGPU_OBJECT_ATTRIBUTE; @@ -356,11 +359,34 @@ typedef enum WGPUCompilationMessageType { WGPUCompilationMessageType_Force32 = 0x7FFFFFFF } WGPUCompilationMessageType WGPU_ENUM_ATTRIBUTE; +/** + * Describes how frames are composited with other contents on the screen when `::wgpuSurfacePresent` is called. + */ typedef enum WGPUCompositeAlphaMode { + /** + * `0x00000000` + * Lets the WebGPU implementation choose the best mode (supported, and with the best performance) between @ref WGPUCompositeAlphaMode_Opaque or @ref WGPUCompositeAlphaMode_Inherit. + */ WGPUCompositeAlphaMode_Auto = 0x00000000, + /** + * `0x00000001` + * The alpha component of the image is ignored and teated as if it is always 1.0. + */ WGPUCompositeAlphaMode_Opaque = 0x00000001, + /** + * `0x00000002` + * The alpha component is respected and non-alpha components are assumed to be already multiplied with the alpha component. For example, (0.5, 0, 0, 0.5) is semi-transparent bright red. + */ WGPUCompositeAlphaMode_Premultiplied = 0x00000002, + /** + * `0x00000003` + * The alpha component is respected and non-alpha components are assumed to NOT be already multiplied with the alpha component. For example, (1.0, 0, 0, 0.5) is semi-transparent bright red. + */ WGPUCompositeAlphaMode_Unpremultiplied = 0x00000003, + /** + * `0x00000004` + * The handling of the alpha component is unknown to WebGPU and should be handled by the application using system-specific APIs. This mode may be unavailable (for example on Wasm). + */ WGPUCompositeAlphaMode_Inherit = 0x00000004, WGPUCompositeAlphaMode_Force32 = 0x7FFFFFFF } WGPUCompositeAlphaMode WGPU_ENUM_ATTRIBUTE; @@ -486,10 +512,35 @@ typedef enum WGPUPowerPreference { WGPUPowerPreference_Force32 = 0x7FFFFFFF } WGPUPowerPreference WGPU_ENUM_ATTRIBUTE; +/** + * Describes when and in which order frames are presented on the screen when `::wgpuSurfacePresent` is called. + */ typedef enum WGPUPresentMode { + /** + * `0x00000000` + * The presentation of the image to the user waits for the next vertical blanking period to update in a first-in, first-out manner. + * Tearing cannot be observed and frame-loop will be limited to the display's refresh rate. + * This is the only mode that's always available. + */ WGPUPresentMode_Fifo = 0x00000000, + /** + * `0x00000001` + * The presentation of the image to the user tries to wait for the next vertical blanking period but may decide to not wait if a frame is presented late. + * Tearing can sometimes be observed but late-frame don't produce a full-frame stutter in the presentation. + * This is still a first-in, first-out mechanism so a frame-loop will be limited to the display's refresh rate. + */ WGPUPresentMode_FifoRelaxed = 0x00000001, + /** + * `0x00000002` + * The presentation of the image to the user is updated immediately without waiting for a vertical blank. + * Tearing can be observed but latency is minimized. + */ WGPUPresentMode_Immediate = 0x00000002, + /** + * `0x00000003` + * The presentation of the image to the user waits for the next vertical blanking period to update to the latest provided image. + * Tearing cannot be observed and a frame-loop is not limited to the display's refresh rate. + */ WGPUPresentMode_Mailbox = 0x00000003, WGPUPresentMode_Force32 = 0x7FFFFFFF } WGPUPresentMode WGPU_ENUM_ATTRIBUTE; @@ -585,12 +636,39 @@ typedef enum WGPUStoreOp { WGPUStoreOp_Force32 = 0x7FFFFFFF } WGPUStoreOp WGPU_ENUM_ATTRIBUTE; +/** + * The status enum for `::wgpuSurfaceGetCurrentTexture`. + */ typedef enum WGPUSurfaceGetCurrentTextureStatus { + /** + * `0x00000000` + * Yay! Everything is good and we can render this frame. + */ WGPUSurfaceGetCurrentTextureStatus_Success = 0x00000000, + /** + * `0x00000001` + * Some operation timed out while trying to acquire the frame. + */ WGPUSurfaceGetCurrentTextureStatus_Timeout = 0x00000001, + /** + * `0x00000002` + * The surface is too different to be used, compared to when it was originally created. + */ WGPUSurfaceGetCurrentTextureStatus_Outdated = 0x00000002, + /** + * `0x00000003` + * The connection to whatever owns the surface was lost. + */ WGPUSurfaceGetCurrentTextureStatus_Lost = 0x00000003, + /** + * `0x00000004` + * The system ran out of memory. + */ WGPUSurfaceGetCurrentTextureStatus_OutOfMemory = 0x00000004, + /** + * `0x00000005` + * The @ref WGPUDevice configured on the @ref WGPUSurface was lost. + */ WGPUSurfaceGetCurrentTextureStatus_DeviceLost = 0x00000005, WGPUSurfaceGetCurrentTextureStatus_Force32 = 0x7FFFFFFF } WGPUSurfaceGetCurrentTextureStatus WGPU_ENUM_ATTRIBUTE; @@ -1295,77 +1373,200 @@ typedef struct WGPUStorageTextureBindingLayout { WGPUTextureViewDimension viewDimension; } WGPUStorageTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; +/** + * Filled by `::wgpuSurfaceGetCapabilities` with what's supported for `::wgpuSurfaceConfigure` for a pair of @ref WGPUSurface and @ref WGPUAdapter. + */ typedef struct WGPUSurfaceCapabilities { WGPUChainedStructOut * nextInChain; + /** + * The bit set of supported @ref WGPUTextureUsage bits. + * Guaranteed to contain @ref WGPUTextureUsage_RenderAttachment. + */ WGPUTextureUsageFlags usages; + /** + * A list of supported @ref WGPUTextureFormat values, in order of preference. + */ size_t formatCount; WGPUTextureFormat const * formats; + /** + * A list of supported @ref WGPUPresentMode values. + * Guaranteed to contain @ref WGPUPresentMode_Fifo. + */ size_t presentModeCount; WGPUPresentMode const * presentModes; + /** + * A list of supported @ref WGPUCompositeAlphaMode values. + * @ref WGPUCompositeAlphaMode_Auto will be an alias for the first element and will never be present in this array. + */ size_t alphaModeCount; WGPUCompositeAlphaMode const * alphaModes; } WGPUSurfaceCapabilities WGPU_STRUCTURE_ATTRIBUTE; +/** + * Options to `::wgpuSurfaceConfigure` for defining how a @ref WGPUSurface will be rendered to and presented to the user. + * See @ref Surface-Configuration for more details. + */ typedef struct WGPUSurfaceConfiguration { WGPUChainedStruct const * nextInChain; + /** + * The @ref WGPUDevice to use to render to surface's textures. + */ WGPUDevice device; + /** + * The @ref WGPUTextureFormat of the surface's textures. + */ WGPUTextureFormat format; + /** + * The @ref WGPUTextureUsage of the surface's textures. + */ WGPUTextureUsageFlags usage; + /** + * The width of the surface's textures. + */ + uint32_t width; + /** + * The height of the surface's textures. + */ + uint32_t height; + /** + * The additional @ref WGPUTextureFormat for @ref WGPUTextureView format reinterpretation of the surface's textures. + */ size_t viewFormatCount; WGPUTextureFormat const * viewFormats; + /** + * How the surface's frames will be composited on the screen. + */ WGPUCompositeAlphaMode alphaMode; - uint32_t width; - uint32_t height; + /** + * When and in which order the surface's frames will be shown on the screen. + */ WGPUPresentMode presentMode; } WGPUSurfaceConfiguration WGPU_STRUCTURE_ATTRIBUTE; +/** + * The root descriptor for the creation of an @ref WGPUSurface with `::wgpuInstanceCreateSurface`. + * It isn't sufficient by itself and must have one of the `WGPUSurfaceSource*` in its chain. + * See @ref Surface-Creation for more details. + */ typedef struct WGPUSurfaceDescriptor { WGPUChainedStruct const * nextInChain; + /** + * Label used to refer to the object. + */ WGPU_NULLABLE char const * label; } WGPUSurfaceDescriptor WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an Android [`ANativeWindow`](https://developer.android.com/ndk/reference/group/a-native-window). + */ typedef struct WGPUSurfaceSourceAndroidNativeWindow { WGPUChainedStruct chain; + /** + * The pointer to the [`ANativeWindow`](https://developer.android.com/ndk/reference/group/a-native-window) that will be wrapped by the @ref WGPUSurface. + */ void * window; } WGPUSurfaceSourceAndroidNativeWindow WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an [HTML `` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas). + */ typedef struct WGPUSurfaceSourceCanvasHTMLSelector_Emscripten { WGPUChainedStruct chain; + /** + * The [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors) for the `` element that will be wrapped by the @ref WGPUSurface. + * Most commonly `"#id_of_the_canvas"`. + */ char const * selector; } WGPUSurfaceSourceCanvasHTMLSelector_Emscripten WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping a [`CAMetalLayer`](https://developer.apple.com/documentation/quartzcore/cametallayer?language=objc). + */ typedef struct WGPUSurfaceSourceMetalLayer { WGPUChainedStruct chain; + /** + * The pointer to the [`CAMetalLayer`](https://developer.apple.com/documentation/quartzcore/cametallayer?language=objc) that will be wrapped by the @ref WGPUSurface. + */ void * layer; } WGPUSurfaceSourceMetalLayer WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping a [Wayland](https://wayland.freedesktop.org/) [`wl_surface`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_surface). + */ typedef struct WGPUSurfaceSourceWaylandSurface { WGPUChainedStruct chain; + /** + * A [`wl_display`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_display) for this Wayland instance. + */ void * display; + /** + * A [`wl_surface`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_surface) that will be wrapped by the @ref WGPUSurface + */ void * surface; } WGPUSurfaceSourceWaylandSurface WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping a Windows [`HWND`](https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd). + */ typedef struct WGPUSurfaceSourceWindowsHWND { WGPUChainedStruct chain; + /** + * The [`HINSTANCE`](https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-point) for this application. + * Most commonly `GetModuleHandle(nullptr)`. + */ void * hinstance; + /** + * The [`HWND`](https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd) that will be wrapped by the @ref WGPUSurface. + */ void * hwnd; } WGPUSurfaceSourceWindowsHWND WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an [XCB](https://xcb.freedesktop.org/) `xcb_window_t`. + */ typedef struct WGPUSurfaceSourceXCBWindow { WGPUChainedStruct chain; + /** + * The `xcb_connection_t` for the connection to the X server. + */ void * connection; + /** + * The `xcb_window_t` for the window that will be wrapped by the @ref WGPUSurface. + */ uint32_t window; } WGPUSurfaceSourceXCBWindow WGPU_STRUCTURE_ATTRIBUTE; +/** + * Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an [Xlib](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html) `Window`. + */ typedef struct WGPUSurfaceSourceXlibWindow { WGPUChainedStruct chain; + /** + * A pointer to the [`Display`](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Opening_the_Display) connected to the X server. + */ void * display; + /** + * The [`Window`](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Creating_Windows) that will be wrapped by the @ref WGPUSurface. + */ uint64_t window; } WGPUSurfaceSourceXlibWindow WGPU_STRUCTURE_ATTRIBUTE; +/** + * Queried each frame from a @ref WGPUSurface to get a @ref WGPUTexture to render to along with some metadata. + * See @ref Surface-Presenting for more details. + */ typedef struct WGPUSurfaceTexture { + /** + * The @ref WGPUTexture representing the frame that will be shown on the surface. + */ WGPUTexture texture; + /** + * True if the surface can present the frame, but in a suboptimal way. + */ WGPUBool suboptimal; + /** + * Whether the call to `::wgpuSurfaceGetCurrentTexture` succeeded and a hint as to why it might not have. + */ WGPUSurfaceGetCurrentTextureStatus status; } WGPUSurfaceTexture WGPU_STRUCTURE_ATTRIBUTE; @@ -1736,6 +1937,9 @@ typedef void (*WGPUProcDeviceReference)(WGPUDevice device) WGPU_FUNCTION_ATTRIBU typedef void (*WGPUProcDeviceRelease)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; // Procs of Instance +/** + * Creates a @ref WGPUSurface, see @ref Surface-Creation for more details. + */ typedef WGPUSurface (*WGPUProcInstanceCreateSurface)(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; typedef WGPUBool (*WGPUProcInstanceHasWGSLLanguageFeature)(WGPUInstance instance, WGPUWGSLFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; /** @@ -1840,11 +2044,34 @@ typedef void (*WGPUProcShaderModuleReference)(WGPUShaderModule shaderModule) WGP typedef void (*WGPUProcShaderModuleRelease)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; // Procs of Surface +/** + * Configures parameters for rendering to `surface`. + * See @ref Surface-Configuration for more details. + */ typedef void (*WGPUProcSurfaceConfigure)(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE; -typedef void (*WGPUProcSurfaceGetCapabilities)(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +/** + * Provides information on how `adapter` is able to use `surface`. + * See @ref Surface-Capabilities for more details. + */ +typedef WGPUBool (*WGPUProcSurfaceGetCapabilities)(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +/** + * Returns the @ref WGPUTexture to render to `surface` this frame along with metadata on the frame. + * See @ref Surface-Presenting for more details. + */ typedef void (*WGPUProcSurfaceGetCurrentTexture)(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture) WGPU_FUNCTION_ATTRIBUTE; +/** + * Shows `surface`'s current texture to the user. + * See @ref Surface-Presenting for more details. + */ typedef void (*WGPUProcSurfacePresent)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +/** + * Modifies the label used to refer to `surface`. + */ typedef void (*WGPUProcSurfaceSetLabel)(WGPUSurface surface, char const * label) WGPU_FUNCTION_ATTRIBUTE; +/** + * Removes the configuration for `surface`. + * See @ref Surface-Configuration for more details. + */ typedef void (*WGPUProcSurfaceUnconfigure)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; typedef void (*WGPUProcSurfaceReference)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; typedef void (*WGPUProcSurfaceRelease)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; @@ -2090,6 +2317,9 @@ WGPU_EXPORT void wgpuDeviceRelease(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; * * @{ */ +/** + * Creates a @ref WGPUSurface, see @ref Surface-Creation for more details. + */ WGPU_EXPORT WGPUSurface wgpuInstanceCreateSurface(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; WGPU_EXPORT WGPUBool wgpuInstanceHasWGSLLanguageFeature(WGPUInstance instance, WGPUWGSLFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; /** @@ -2274,11 +2504,34 @@ WGPU_EXPORT void wgpuShaderModuleRelease(WGPUShaderModule shaderModule) WGPU_FUN * * @{ */ +/** + * Configures parameters for rendering to `surface`. + * See @ref Surface-Configuration for more details. + */ WGPU_EXPORT void wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE; -WGPU_EXPORT void wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +/** + * Provides information on how `adapter` is able to use `surface`. + * See @ref Surface-Capabilities for more details. + */ +WGPU_EXPORT WGPUBool wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +/** + * Returns the @ref WGPUTexture to render to `surface` this frame along with metadata on the frame. + * See @ref Surface-Presenting for more details. + */ WGPU_EXPORT void wgpuSurfaceGetCurrentTexture(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture) WGPU_FUNCTION_ATTRIBUTE; +/** + * Shows `surface`'s current texture to the user. + * See @ref Surface-Presenting for more details. + */ WGPU_EXPORT void wgpuSurfacePresent(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +/** + * Modifies the label used to refer to `surface`. + */ WGPU_EXPORT void wgpuSurfaceSetLabel(WGPUSurface surface, char const * label) WGPU_FUNCTION_ATTRIBUTE; +/** + * Removes the configuration for `surface`. + * See @ref Surface-Configuration for more details. + */ WGPU_EXPORT void wgpuSurfaceUnconfigure(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; WGPU_EXPORT void wgpuSurfaceReference(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; WGPU_EXPORT void wgpuSurfaceRelease(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; diff --git a/webgpu.yml b/webgpu.yml index 61c79aba..e67f358b 100644 --- a/webgpu.yml +++ b/webgpu.yml @@ -319,24 +319,18 @@ enums: doc: | TODO - name: composite_alpha_mode - doc: | - TODO + doc: Describes how frames are composited with other contents on the screen when `::wgpuSurfacePresent` is called. entries: - name: auto - doc: | - TODO + doc: Lets the WebGPU implementation choose the best mode (supported, and with the best performance) between @ref WGPUCompositeAlphaMode_Opaque or @ref WGPUCompositeAlphaMode_Inherit. - name: opaque - doc: | - TODO + doc: The alpha component of the image is ignored and teated as if it is always 1.0. - name: premultiplied - doc: | - TODO + doc: The alpha component is respected and non-alpha components are assumed to be already multiplied with the alpha component. For example, (0.5, 0, 0, 0.5) is semi-transparent bright red. - name: unpremultiplied - doc: | - TODO + doc: The alpha component is respected and non-alpha components are assumed to NOT be already multiplied with the alpha component. For example, (1.0, 0, 0, 0.5) is semi-transparent bright red. - name: inherit - doc: | - TODO + doc: The handling of the alpha component is unknown to WebGPU and should be handled by the application using system-specific APIs. This mode may be unavailable (for example on Wasm). - name: create_pipeline_async_status doc: | TODO @@ -599,21 +593,26 @@ enums: doc: | TODO - name: present_mode - doc: | - TODO + doc: Describes when and in which order frames are presented on the screen when `::wgpuSurfacePresent` is called. entries: - name: fifo doc: | - TODO + The presentation of the image to the user waits for the next vertical blanking period to update in a first-in, first-out manner. + Tearing cannot be observed and frame-loop will be limited to the display's refresh rate. + This is the only mode that's always available. - name: fifo_relaxed doc: | - TODO + The presentation of the image to the user tries to wait for the next vertical blanking period but may decide to not wait if a frame is presented late. + Tearing can sometimes be observed but late-frame don't produce a full-frame stutter in the presentation. + This is still a first-in, first-out mechanism so a frame-loop will be limited to the display's refresh rate. - name: immediate doc: | - TODO + The presentation of the image to the user is updated immediately without waiting for a vertical blank. + Tearing can be observed but latency is minimized. - name: mailbox doc: | - TODO + The presentation of the image to the user waits for the next vertical blanking period to update to the latest provided image. + Tearing cannot be observed and a frame-loop is not limited to the display's refresh rate. - name: primitive_topology doc: | TODO @@ -823,27 +822,20 @@ enums: doc: | TODO - name: surface_get_current_texture_status - doc: | - TODO + doc: The status enum for `::wgpuSurfaceGetCurrentTexture`. entries: - name: success - doc: | - TODO + doc: Yay! Everything is good and we can render this frame. - name: timeout - doc: | - TODO + doc: Some operation timed out while trying to acquire the frame. - name: outdated - doc: | - TODO + doc: The surface is too different to be used, compared to when it was originally created. - name: lost - doc: | - TODO + doc: The connection to whatever owns the surface was lost. - name: out_of_memory - doc: | - TODO + doc: The system ran out of memory. - name: device_lost - doc: | - TODO + doc: The @ref WGPUDevice configured on the @ref WGPUSurface was lost. - name: texture_aspect doc: | TODO @@ -2696,195 +2688,174 @@ structs: TODO type: struct.limits - name: surface_capabilities - doc: | - TODO + doc: Filled by `::wgpuSurfaceGetCapabilities` with what's supported for `::wgpuSurfaceConfigure` for a pair of @ref WGPUSurface and @ref WGPUAdapter. type: base_out free_members: true members: - name: usages doc: | - TODO + The bit set of supported @ref WGPUTextureUsage bits. + Guaranteed to contain @ref WGPUTextureUsage_RenderAttachment. type: bitflag.texture_usage - name: formats - doc: | - TODO + doc: A list of supported @ref WGPUTextureFormat values, in order of preference. type: array pointer: immutable - name: present_modes doc: | - TODO + A list of supported @ref WGPUPresentMode values. + Guaranteed to contain @ref WGPUPresentMode_Fifo. type: array pointer: immutable - name: alpha_modes doc: | - TODO + A list of supported @ref WGPUCompositeAlphaMode values. + @ref WGPUCompositeAlphaMode_Auto will be an alias for the first element and will never be present in this array. type: array pointer: immutable - name: surface_configuration doc: | - TODO + Options to `::wgpuSurfaceConfigure` for defining how a @ref WGPUSurface will be rendered to and presented to the user. + See @ref Surface-Configuration for more details. type: base_in members: - name: device - doc: | - TODO + doc: The @ref WGPUDevice to use to render to surface's textures. type: object.device - name: format - doc: | - TODO + doc: The @ref WGPUTextureFormat of the surface's textures. type: enum.texture_format - name: usage - doc: | - TODO + doc: The @ref WGPUTextureUsage of the surface's textures. type: bitflag.texture_usage + - name: width + doc: The width of the surface's textures. + type: uint32 + - name: height + doc: The height of the surface's textures. + type: uint32 - name: view_formats - doc: | - TODO + doc: The additional @ref WGPUTextureFormat for @ref WGPUTextureView format reinterpretation of the surface's textures. type: array pointer: immutable - name: alpha_mode - doc: | - TODO + doc: How the surface's frames will be composited on the screen. type: enum.composite_alpha_mode - - name: width - doc: | - TODO - type: uint32 - - name: height - doc: | - TODO - type: uint32 - name: present_mode - doc: | - TODO + doc: When and in which order the surface's frames will be shown on the screen. type: enum.present_mode - name: surface_descriptor doc: | - TODO + The root descriptor for the creation of an @ref WGPUSurface with `::wgpuInstanceCreateSurface`. + It isn't sufficient by itself and must have one of the `WGPUSurfaceSource*` in its chain. + See @ref Surface-Creation for more details. type: base_in members: - name: label - doc: | - TODO + doc: Label used to refer to the object. type: string optional: true - name: surface_source_android_native_window - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an Android [`ANativeWindow`](https://developer.android.com/ndk/reference/group/a-native-window). type: extension_in extends: - surface_descriptor members: - name: window - doc: | - TODO + doc: The pointer to the [`ANativeWindow`](https://developer.android.com/ndk/reference/group/a-native-window) that will be wrapped by the @ref WGPUSurface. type: c_void pointer: mutable - name: surface_source_canvas_HTML_selector__Emscripten - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an [HTML `` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas). type: extension_in extends: - surface_descriptor members: - name: selector doc: | - TODO + The [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors) for the `` element that will be wrapped by the @ref WGPUSurface. + Most commonly `"#id_of_the_canvas"`. type: string - name: surface_source_metal_layer - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping a [`CAMetalLayer`](https://developer.apple.com/documentation/quartzcore/cametallayer?language=objc). type: extension_in extends: - surface_descriptor members: - name: layer - doc: | - TODO + doc: The pointer to the [`CAMetalLayer`](https://developer.apple.com/documentation/quartzcore/cametallayer?language=objc) that will be wrapped by the @ref WGPUSurface. type: c_void pointer: mutable - name: surface_source_wayland_surface - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping a [Wayland](https://wayland.freedesktop.org/) [`wl_surface`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_surface). type: extension_in extends: - surface_descriptor members: - name: display - doc: | - TODO + doc: A [`wl_display`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_display) for this Wayland instance. type: c_void pointer: mutable - name: surface - doc: | - TODO + doc: A [`wl_surface`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_surface) that will be wrapped by the @ref WGPUSurface type: c_void pointer: mutable - name: surface_source_windows_HWND - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping a Windows [`HWND`](https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd). type: extension_in extends: - surface_descriptor members: - name: hinstance doc: | - TODO + The [`HINSTANCE`](https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-point) for this application. + Most commonly `GetModuleHandle(nullptr)`. type: c_void pointer: mutable - name: hwnd - doc: | - TODO + doc: The [`HWND`](https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd) that will be wrapped by the @ref WGPUSurface. type: c_void pointer: mutable - name: surface_source_XCB_window - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an [XCB](https://xcb.freedesktop.org/) `xcb_window_t`. type: extension_in extends: - surface_descriptor members: - name: connection - doc: | - TODO + doc: The `xcb_connection_t` for the connection to the X server. type: c_void pointer: mutable - name: window - doc: | - TODO + doc: The `xcb_window_t` for the window that will be wrapped by the @ref WGPUSurface. type: uint32 - name: surface_source_xlib_window - doc: | - TODO + doc: Chained in @ref WGPUSurfaceDescriptor to make an @ref WGPUSurface wrapping an [Xlib](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html) `Window`. type: extension_in extends: - surface_descriptor members: - name: display - doc: | - TODO + doc: A pointer to the [`Display`](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Opening_the_Display) connected to the X server. type: c_void pointer: mutable - name: window - doc: | - TODO + doc: The [`Window`](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Creating_Windows) that will be wrapped by the @ref WGPUSurface. type: uint64 - name: surface_texture doc: | - TODO + Queried each frame from a @ref WGPUSurface to get a @ref WGPUTexture to render to along with some metadata. + See @ref Surface-Presenting for more details. type: standalone members: - name: texture - doc: | - TODO + doc: The @ref WGPUTexture representing the frame that will be shown on the surface. type: object.texture - name: suboptimal - doc: | - TODO + doc: True if the surface can present the frame, but in a suboptimal way. type: bool - name: status - doc: | - TODO + doc: Whether the call to `::wgpuSurfaceGetCurrentTexture` succeeded and a hint as to why it might not have. type: enum.surface_get_current_texture_status - name: texture_binding_layout doc: | @@ -3995,16 +3966,13 @@ objects: TODO methods: - name: create_surface - doc: | - TODO + doc: Creates a @ref WGPUSurface, see @ref Surface-Creation for more details. returns: - doc: | - TODO + doc: A new @ref WGPUSurface for this descriptor (or an error @ref WGPUSurface). type: object.surface args: - name: descriptor - doc: | - TODO + doc: The description of the @ref WGPUSurface to create. type: struct.surface_descriptor pointer: immutable - name: has_WGSL_language_feature @@ -4673,53 +4641,56 @@ objects: TODO type: string - name: surface - doc: | - TODO + doc: An object used to continuously present image data to the user, see @ref Surfaces for more details. methods: - name: configure doc: | - TODO + Configures parameters for rendering to `surface`. + See @ref Surface-Configuration for more details. args: - name: config - doc: | - TODO + doc: The new configuration to use. type: struct.surface_configuration pointer: immutable - name: get_capabilities doc: | - TODO + Provides information on how `adapter` is able to use `surface`. + See @ref Surface-Capabilities for more details. + returns: + doc: TODO make this WGPUStatus instead of a boolean. + type: bool args: - name: adapter - doc: | - TODO + doc: The @ref WGPUAdapter to get capabilities for presenting to this @ref WGPUSurface. type: object.adapter - name: capabilities doc: | - TODO + The structure to fill capabilities in. + It may contain memory allocations so `::wgpuSurfaceCapabilitiesFreeMembers` must be called to avoid memory leaks. type: struct.surface_capabilities pointer: mutable - name: get_current_texture doc: | - TODO + Returns the @ref WGPUTexture to render to `surface` this frame along with metadata on the frame. + See @ref Surface-Presenting for more details. args: - name: surface_texture - doc: | - TODO + doc: The structure to fill the @ref WGPUTexture and metadata in. type: struct.surface_texture pointer: mutable - name: present doc: | - TODO + Shows `surface`'s current texture to the user. + See @ref Surface-Presenting for more details. - name: unconfigure doc: | - TODO + Removes the configuration for `surface`. + See @ref Surface-Configuration for more details. - name: set_label - doc: | - TODO + doc: Modifies the label used to refer to `surface`. args: - name: label - doc: | - TODO + doc: The new label. type: string - name: texture doc: |