Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
2 contributors

Users who have contributed to this file

@litherum @grorg
954 lines (783 sloc) 21.8 KB
<pre class='metadata'>
Title: WebGPU
Shortname: webgpu
Level: 1
Status: w3c/ED
Group: webgpu
URL: https://github.com/gpuweb/gpuweb/spec/
Editor: The GPU for the Web Community Group, W3C https://github.com/gpuweb/
Abstract: WebGPU exposes an API for performing operations, such as rendering and computation, on a Graphics Processing Unit.
</pre>
Introduction {#intro}
=====================
This specification rocks.
Type Definitions {#typedefs}
============================
<script type=idl>
typedef long i32;
typedef unsigned long u32;
typedef unsigned long long u64;
dictionary GPUColor {
required float r;
required float g;
required float b;
required float a;
};
dictionary GPUOrigin3D {
u32 x = 0;
u32 y = 0;
u32 z = 0;
};
dictionary GPUExtent3D {
required u32 width;
required u32 height;
required u32 depth;
};
</script>
Buffers {#buffers}
==================
<script type=idl>
typedef u32 GPUBufferUsageFlags;
interface GPUBufferUsage {
const u32 NONE = 0;
const u32 MAP_READ = 1;
const u32 MAP_WRITE = 2;
const u32 TRANSFER_SRC = 4;
const u32 TRANSFER_DST = 8;
const u32 INDEX = 16;
const u32 VERTEX = 32;
const u32 UNIFORM = 64;
const u32 STORAGE = 128;
};
dictionary GPUBufferDescriptor {
required u64 size;
required GPUBufferUsageFlags usage;
};
interface GPUBuffer {
void setSubData(u64 offset, ArrayBuffer data);
Promise<ArrayBuffer> mapReadAsync();
Promise<ArrayBuffer> mapWriteAsync();
void unmap();
void destroy();
};
</script>
Textures {#textures}
====================
<script type=idl>
enum GPUTextureDimension {
"1d",
"2d",
"3d"
};
// Texture formats
// The name of the format specifies the order of components, bits per component, and data type for
// the component.
// r, g, b, a = red, green, blue, alpha
// unorm = unsigned normalized
// snorm = signed normalized
// uint = unsigned int
// sint = signed int
// float = floating point
// If the format has the "-srgb" suffix, then sRGB gamma compression and decompression are
// applied during the reading and writing of color values in the pixel.
// Compressed texture formats are provided by extensions. Their naming should follow the
// convention here, with the texture name as a prefix. e.g. "etc2-rgba8unorm".
enum GPUTextureFormat {
/* Normal 8 bit formats */
"r8unorm",
"r8unorm-srgb",
"r8snorm",
"r8uint",
"r8sint",
/* Normal 16 bit formats */
"r16unorm",
"r16snorm",
"r16uint",
"r16sint",
"r16float",
"rg8unorm",
"rg8unorm-srgb",
"rg8snorm",
"rg8uint",
"rg8sint",
/* Packed 16 bit formats */
"b5g6r5unorm",
/* Normal 32 bit formats */
"r32uint",
"r32sint",
"r32float",
"rg16unorm",
"rg16snorm",
"rg16uint",
"rg16sint",
"rg16float",
"rgba8unorm",
"rgba8unorm-srgb",
"rgba8snorm",
"rgba8uint",
"rgba8sint",
"bgra8unorm",
"bgra8unorm-srgb",
/* Packed 32 bit formats */
"rgb10a2unorm",
"rg11b10float",
/* Normal 64 bit formats */
"rg32uint",
"rg32sint",
"rg32float",
"rgba16unorm",
"rgba16snorm",
"rgba16uint",
"rgba16sint",
"rgba16float",
/* Normal 128 bit formats */
"rgba32uint",
"rgba32sint",
"rgba32float",
/* Depth and Stencil formats */
"depth32float",
"depth32float-stencil8"
};
typedef u32 GPUTextureUsageFlags;
interface GPUTextureUsage {
const u32 NONE = 0;
const u32 TRANSFER_SRC = 1;
const u32 TRANSFER_DST = 2;
const u32 SAMPLED = 4;
const u32 STORAGE = 8;
const u32 OUTPUT_ATTACHMENT = 16;
};
dictionary GPUTextureDescriptor {
required GPUExtent3D size;
u32 arrayLayerCount = 1;
u32 mipLevelCount = 1;
u32 sampleCount = 1;
GPUTextureDimension dimension = "2d";
required GPUTextureFormat format;
required GPUTextureUsageFlags usage;
};
// Texture view
enum GPUTextureViewDimension {
"1d",
"2d",
"2d-array",
"cube",
"cube-array",
"3d"
};
enum GPUTextureAspect {
"all",
"stencil-only",
"depth-only"
};
dictionary GPUTextureViewDescriptor {
required GPUTextureFormat format;
required GPUTextureViewDimension dimension;
required GPUTextureAspect aspect;
u32 baseMipLevel = 0;
u32 mipLevelCount = 1;
u32 baseArrayLayer = 0;
u32 arrayLayerCount = 1;
};
interface GPUTextureView {
};
interface GPUTexture {
GPUTextureView createView(GPUTextureViewDescriptor desc);
GPUTextureView createDefaultView();
void destroy();
};
</script>
Samplers {#samplers}
====================
<script type=idl>
enum GPUAddressMode {
"clamp-to-edge",
"repeat",
"mirror-repeat"
};
enum GPUFilterMode {
"nearest",
"linear"
};
enum GPUCompareFunction {
"never",
"less",
"equal",
"less-equal",
"greater",
"not-equal",
"greater-equal",
"always"
};
dictionary GPUSamplerDescriptor {
GPUAddressMode addressModeU = "clamp-to-edge";
GPUAddressMode addressModeV = "clamp-to-edge";
GPUAddressMode addressModeW = "clamp-to-edge";
GPUFilterMode magFilter = "nearest";
GPUFilterMode minFilter = "nearest";
GPUFilterMode mipmapFilter = "nearest";
float lodMinClamp = 0;
float lodMaxClamp = 0xffffffff; // TODO: What should this be? Was Number.MAX_VALUE.
GPUCompareFunction compareFunction = "never";
};
interface GPUSampler {
};
</script>
Binding and Layout {#binding}
=============================
<script type=idl>
typedef u32 GPUShaderStageFlags;
interface GPUShaderStageBit {
const u32 NONE = 0;
const u32 VERTEX = 1;
const u32 FRAGMENT = 2;
const u32 COMPUTE = 4;
};
enum GPUBindingType {
"uniform-buffer",
"dynamic-uniform-buffer",
"sampler",
"sampled-texture",
"storage-buffer",
"dynamic-storage-buffer"
// TODO other binding types
};
dictionary GPUBindGroupLayoutBinding {
required u32 binding;
required GPUShaderStageFlags visibility;
required GPUBindingType type;
};
dictionary GPUBindGroupLayoutDescriptor {
required sequence<GPUBindGroupLayoutBinding> bindings;
};
interface GPUBindGroupLayout {
};
dictionary GPUPipelineLayoutDescriptor {
required sequence<GPUBindGroupLayout> bindGroupLayouts;
};
interface GPUPipelineLayout {
};
dictionary GPUBufferBinding {
required GPUBuffer buffer;
u64 offset = 0;
required u64 size;
};
typedef (GPUSampler or GPUTextureView or GPUBufferBinding) GPUBindingResource;
dictionary GPUBindGroupBinding {
required u32 binding;
required GPUBindingResource resource;
};
dictionary GPUBindGroupDescriptor {
required GPUBindGroupLayout layout;
required sequence<GPUBindGroupBinding> bindings;
};
interface GPUBindGroup {
};
</script>
Shader Module {#shader}
=======================
<script type=idl>
// Note: While the choice of shader language is undecided,
// GPUShaderModuleDescriptor will temporarily accept both
// text and binary input.
typedef (ArrayBuffer or DOMString) ArrayBufferOrDOMString;
dictionary GPUShaderModuleDescriptor {
required ArrayBufferOrDOMString code;
};
interface GPUShaderModule {
};
</script>
Pipeline Creation {#pipeline-creation}
======================================
<script type=idl>
// RasterizationState
enum GPUFrontFace {
"ccw",
"cw"
};
enum GPUCullMode {
"none",
"front",
"back"
};
dictionary GPURasterizationStateDescriptor {
required GPUFrontFace frontFace;
GPUCullMode cullMode = "none";
i32 depthBias = 0;
float depthBiasSlopeScale = 0;
float depthBiasClamp = 0;
};
// BlendState
enum GPUBlendFactor {
"zero",
"one",
"src-color",
"one-minus-src-color",
"src-alpha",
"one-minus-src-alpha",
"dst-color",
"one-minus-dst-color",
"dst-alpha",
"one-minus-dst-alpha",
"src-alpha-saturated",
"blend-color",
"one-minus-blend-color"
};
enum GPUBlendOperation {
"add",
"subtract",
"reverse-subtract",
"min",
"max"
};
typedef u32 GPUColorWriteFlags;
interface GPUColorWriteBits {
const u32 NONE = 0;
const u32 RED = 1;
const u32 GREEN = 2;
const u32 BLUE = 4;
const u32 ALPHA = 8;
const u32 ALL = 15;
};
dictionary GPUBlendDescriptor {
GPUBlendFactor srcFactor = "one";
GPUBlendFactor dstFactor = "zero";
GPUBlendOperation operation = "add";
};
dictionary GPUColorStateDescriptor {
required GPUTextureFormat format;
required GPUBlendDescriptor alphaBlend;
required GPUBlendDescriptor colorBlend;
GPUColorWriteFlags writeMask = GPUColorWriteBits.ALL;
};
enum GPUStencilOperation {
"keep",
"zero",
"replace",
"invert",
"increment-clamp",
"decrement-clamp",
"increment-wrap",
"decrement-wrap"
};
dictionary GPUStencilStateFaceDescriptor {
GPUCompareFunction compare = "always";
GPUStencilOperation failOp = "keep";
GPUStencilOperation depthFailOp = "keep";
GPUStencilOperation passOp = "keep";
};
dictionary GPUDepthStencilStateDescriptor {
required GPUTextureFormat format;
boolean depthWriteEnabled = false;
GPUCompareFunction depthCompare = "always";
required GPUStencilStateFaceDescriptor stencilFront;
required GPUStencilStateFaceDescriptor stencilBack;
u32 stencilReadMask = 0xFFFFFFFF;
u32 stencilWriteMask = 0xFFFFFFFF;
};
// InputState
enum GPUIndexFormat {
"uint16",
"uint32"
};
// Vertex formats
// The name of the format specifies the data type of the component, the number of
// values, and whether the data is normalized.
// uchar = unsigned 8-bit value
// char = signed 8-bit value
// ushort = unsigned 16-bit value
// short = signed 16-bit value
// half = half-precision 16-bit floating point value
// float = 32-bit floating point value
// uint = unsigned 32-bit integer value
// int = signed 32-bit integer value
// If no number of values is given in the name, a single value is provided.
// If the format has the "-bgra" suffix, it means the values are arranged as
// blue, green, red and alpha values.
enum GPUVertexFormat {
"uchar2",
"uchar4",
"char2",
"char4",
"uchar2norm",
"uchar4norm",
"char2norm",
"char4norm",
"ushort2",
"ushort4",
"short2",
"short4",
"ushort2norm",
"ushort4norm",
"short2norm",
"short4norm",
"half2",
"half4",
"float",
"float2",
"float3",
"float4",
"uint",
"uint2",
"uint3",
"uint4",
"int",
"int2",
"int3",
"int4"
};
enum GPUInputStepMode {
"vertex",
"instance"
};
dictionary GPUVertexAttributeDescriptor {
required u32 shaderLocation;
required u32 inputSlot;
u64 offset = 0;
required GPUVertexFormat format;
};
dictionary GPUVertexInputDescriptor {
required u32 inputSlot;
required u64 stride;
GPUInputStepMode stepMode = "vertex";
};
dictionary GPUInputStateDescriptor {
required GPUIndexFormat indexFormat;
required sequence<GPUVertexAttributeDescriptor> attributes;
required sequence<GPUVertexInputDescriptor> inputs;
};
</script>
Pipeline Descriptors {#pipeline-descriptors}
============================================
<script type=idl>
dictionary GPUPipelineStageDescriptor {
required GPUShaderModule module;
required DOMString entryPoint;
// TODO other stuff like specialization constants?
};
dictionary GPUPipelineDescriptorBase {
required GPUPipelineLayout layout;
};
</script>
Compute Pipeline {#compute-pipeline}
===========================
<script type=idl>
dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
required GPUPipelineStageDescriptor computeStage;
};
interface GPUComputePipeline {
};
</script>
Render Pipeline {#render-pipeline}
==================================
<script type=idl>
enum GPUPrimitiveTopology {
"point-list",
"line-list",
"line-strip",
"triangle-list",
"triangle-strip"
};
dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase {
required GPUPipelineStageDescriptor vertexStage;
GPUPipelineStageDescriptor? fragmentStage = null;
required GPUPrimitiveTopology primitiveTopology;
required GPURasterizationStateDescriptor rasterizationState;
required sequence<GPUColorStateDescriptor> colorStates;
GPUDepthStencilStateDescriptor? depthStencilState = null;
required GPUInputStateDescriptor inputState;
// Number of MSAA samples
u32 sampleCount = 1;
// TODO other properties
};
interface GPURenderPipeline {
};
</script>
Command Recording {#command-recording}
======================================
<script type=idl>
interface GPUProgrammablePassEncoder {
void endPass();
// Allowed in both compute and render passes
void setBindGroup(u32 index, GPUBindGroup bindGroup, optional sequence<u64> dynamicOffsets);
};
interface GPURenderPassEncoder : GPUProgrammablePassEncoder {
void setPipeline(GPURenderPipeline pipeline);
void setBlendColor(GPUColor color);
void setStencilReference(u32 reference);
// The default viewport is (0.0, 0.0, w, h, 0.0, 1.0), where w and h are the dimensions of back buffer
void setViewport(float x, float y, float width, float height, float minDepth, float maxDepth);
// The default scissor rectangle is (0, 0, w, h), where w and h are the dimensions of back buffer.
// Width and height must be greater than 0. Otherwise, an error will be generated.
void setScissorRect(u32 x, u32 y, u32 width, u32 height);
void setIndexBuffer(GPUBuffer buffer, u64 offset);
void setVertexBuffers(u32 startSlot, sequence<GPUBuffer> buffers, sequence<u64> offsets);
void draw(u32 vertexCount, u32 instanceCount, u32 firstVertex, u32 firstInstance);
void drawIndexed(u32 indexCount, u32 instanceCount, u32 firstIndex, i32 baseVertex, u32 firstInstance);
// TODO add missing commands
};
interface GPUComputePassEncoder : GPUProgrammablePassEncoder {
void setPipeline(GPUComputePipeline pipeline);
void dispatch(u32 x, u32 y, u32 z);
// TODO add missing commands
};
enum GPULoadOp {
"clear",
"load"
};
enum GPUStoreOp {
"store"
};
dictionary GPURenderPassColorAttachmentDescriptor {
required GPUTextureView attachment;
GPUTextureView? resolveTarget = null;
required GPULoadOp loadOp;
required GPUStoreOp storeOp;
GPUColor clearColor = {r: 0.0, g: 0.0, b: 0.0, a: 1.0};
};
dictionary GPURenderPassDepthStencilAttachmentDescriptor {
required GPUTextureView attachment;
required GPULoadOp depthLoadOp;
required GPUStoreOp depthStoreOp;
required float clearDepth;
required GPULoadOp stencilLoadOp;
required GPUStoreOp stencilStoreOp;
u32 clearStencil = 0;
};
dictionary GPURenderPassDescriptor {
required sequence<GPURenderPassColorAttachmentDescriptor> colorAttachments;
GPURenderPassDepthStencilAttachmentDescriptor? depthStencilAttachment = null;
};
dictionary GPUBufferCopyView {
required GPUBuffer buffer;
u64 offset = 0;
required u32 rowPitch;
required u32 imageHeight;
};
dictionary GPUTextureCopyView {
required GPUTexture texture;
u32 mipLevel = 0;
u32 arrayLayer = 0;
GPUOrigin3D origin = {x: 0, y: 0, z: 0};
};
interface GPUCommandBuffer {
};
interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass();
// Commands allowed outside of "passes"
void copyBufferToBuffer(
GPUBuffer src,
u64 srcOffset,
GPUBuffer dst,
u64 dstOffset,
u64 size);
void copyBufferToTexture(
GPUBufferCopyView source,
GPUTextureCopyView destination,
GPUExtent3D copySize);
void copyTextureToBuffer(
GPUTextureCopyView source,
GPUBufferCopyView destination,
GPUExtent3D copySize);
void copyTextureToTexture(
GPUTextureCopyView source,
GPUTextureCopyView destination,
GPUExtent3D copySize);
GPUCommandBuffer finish();
};
dictionary GPUCommandEncoderDescriptor {
//TODO: reusability flag?
};
</script>
Fences {#fences}
================
<script type=idl>
dictionary GPUFenceDescriptor {
u64 initialValue = 0;
};
interface GPUFence {
u64 getCompletedValue();
Promise<void> onCompletion(u64 completionValue);
};
</script>
Queues {#queues}
================
<script type=idl>
interface GPUQueue {
void submit(sequence<GPUCommandBuffer> buffers);
GPUFence createFence(GPUFenceDescriptor descriptor);
void signal(GPUFence fence, u64 signalValue);
};
</script>
Canvas Rendering and Swap Chain {#swapchain}
============================================
<script type=idl>
interface GPUCanvasContext {
// Calling configureSwapChain a second time invalidates the previous one,
// and all of the textures it’s produced.
GPUSwapChain configureSwapChain(GPUSwapChainDescriptor descriptor);
Promise<GPUTextureFormat> getSwapChainPreferredFormat(GPUDevice device);
}
dictionary GPUSwapChainDescriptor {
required GPUDevice device;
required GPUTextureFormat format;
GPUTextureUsageFlags usage = GPUTextureUsage.OUTPUT_ATTACHMENT;
};
interface GPUSwapChain {
GPUTexture getCurrentTexture();
};
</script>
Device {#device}
================
<script type=idl>
dictionary GPUExtensions {
boolean anisotropicFiltering = false;
};
dictionary GPULimits {
u32 maxBindGroups = 4;
};
// Device
interface GPUDevice {
readonly attribute GPUExtensions extensions;
readonly attribute GPULimits limits;
readonly attribute GPUAdapter adapter;
GPUBuffer createBuffer(GPUBufferDescriptor descriptor);
(GPUBuffer, ArrayBuffer) createBufferMapped(GPUBufferDescriptor descriptor);
Promise<(GPUBuffer, ArrayBuffer)> createBufferMappedAsync(GPUBufferDescriptor descriptor);
GPUTexture createTexture(GPUTextureDescriptor descriptor);
GPUSampler createSampler(GPUSamplerDescriptor descriptor);
GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor);
GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
GPUCommandEncoder createCommandEncoder(GPUCommandEncoderDescriptor descriptor);
GPUQueue getQueue();
};
dictionary GPUDeviceDescriptor {
GPUExtensions extensions;
GPULimits limits;
// TODO are other things configurable like queues?
};
interface GPUAdapter {
readonly attribute DOMString name;
readonly attribute GPUExtensions extensions;
//readonly attribute GPULimits limits; Don't expose higher limits for now.
// May reject with DOMException // TODO: DOMException("OperationError")?
Promise<GPUDevice> requestDevice(GPUDeviceDescriptor descriptor);
};
enum GPUPowerPreference {
"low-power",
"high-performance"
};
dictionary GPURequestAdapterOptions {
GPUPowerPreference? powerPreference;
};
[Exposed=Window]
interface GPU {
// May reject with DOMException // TODO: DOMException("OperationError")?
Promise<GPUAdapter> requestAdapter(optional GPURequestAdapterOptions options);
};
[Exposed=Window]
partial interface Navigator {
[SameObject] readonly attribute GPU gpu;
};
[Exposed=DedicatedWorker]
partial interface WorkerNavigator {
[SameObject] readonly attribute GPU gpu;
};
</script>
Fatal Errors {#fatal}
=====================
<script type=idl>
interface GPUDeviceLostInfo {
readonly attribute DOMString message;
};
partial interface GPUDevice {
readonly attribute Promise<GPUDeviceLostInfo> lost;
};
</script>
Error Scopes {#errors}
======================
<script type=idl>
enum GPUErrorFilter {
"none",
"out-of-memory",
"validation"
};
[
Constructor()
]
interface GPUOutOfMemoryError {};
[
Constructor(DOMString message)
]
interface GPUValidationError {
readonly attribute DOMString message;
};
typedef (GPUOutOfMemoryError or GPUValidationError) GPUError;
partial interface GPUDevice {
void pushErrorScope(GPUErrorFilter filter);
Promise<GPUError?> popErrorScope();
};
</script>
Telemetry {#telemetry}
======================
<script type=idl>
[
Constructor(DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict),
Exposed=Window
]
interface GPUUncapturedErrorEvent : Event {
readonly attribute GPUError error;
};
dictionary GPUUncapturedErrorEventInit : EventInit {
required GPUError error;
};
// TODO: is it possible to expose the EventTarget only on the main thread?
partial interface GPUDevice : EventTarget {
[Exposed=Window]
attribute EventHandler onuncapturederror;
};
</script>
Debugging Assistance {#debugging}
=================================
<script type=idl>
partial interface GPUProgrammablePassEncoder {
void pushDebugGroup(DOMString groupLabel);
void popDebugGroup();
void insertDebugMarker(DOMString markerLabel);
};
interface mixin GPUDebugLabel {
attribute DOMString label;
};
GPUBindGroup includes GPUDebugLabel;
GPUBindGroupLayout includes GPUDebugLabel;
GPUBuffer includes GPUDebugLabel;
GPUCommandBuffer includes GPUDebugLabel;
GPUCommandEncoder includes GPUDebugLabel;
GPUComputePipeline includes GPUDebugLabel;
GPUFence includes GPUDebugLabel;
GPUPipelineLayout includes GPUDebugLabel;
GPUProgrammablePassEncoder includes GPUDebugLabel;
GPUQueue includes GPUDebugLabel;
GPURenderPipeline includes GPUDebugLabel;
GPUSampler includes GPUDebugLabel;
GPUShaderModule includes GPUDebugLabel;
GPUTexture includes GPUDebugLabel;
GPUTextureView includes GPUDebugLabel;
partial dictionary GPUCommandEncoderDescriptor {
DOMString label;
};
partial dictionary GPUFenceDescriptor {
DOMString label;
};
partial dictionary GPUPipelineDescriptorBase {
DOMString label;
};
partial dictionary GPUShaderModuleDescriptor {
DOMString label;
};
</script>
You can’t perform that action at this time.