(texture …)
Creates a GPU texture for sampling, render targets, or storage.
Syntax
Section titled “Syntax”(texture :name name :size canvas :format rgba8unorm :usage [texture-binding render-attachment] :sample-count 4)| Key | Type | Required | Default | Description |
|---|---|---|---|---|
:name |
symbol | Yes | - | Unique texture name |
:size |
vector / symbol / reference | Yes | - | Texel size (see below) |
:format |
symbol | Yes | - | Texel format |
:usage |
array | Yes | - | Usage flags, at least one |
:sample-count |
number | No | 1 |
Samples per texel: 1 or 4 (MSAA, multisample anti-aliasing) |
:dimension |
symbol | No | 2d |
1d, 2d or 3d |
:mip-level-count |
number | No | 1 |
Mip levels to allocate |
:pool |
number | No | 1 |
Ping-pong texture pool size (1 to 255) |
:size, :format and :usage are required, as the three required members of
GPUTextureDescriptor are. A texture that names no size is a validation error,
not a texture of some guessed default size.
Type: vector | symbol | reference
One key with three spellings, because GPUTextureDescriptor.size is one
member:
- An extent vector:
[w],[w h]or[w h d], in texels. The missing dimensions are WebGPU’s own defaults of 1, and each element is at least 1. The third element isdepthOrArrayLayers: the slice count of a3dtexture, or the layer count of a 2d array. canvas: track the canvas size at runtime, so the texture resizes with it.- An
(image-bitmap …)name: take the decoded image’s dimensions, so they are not restated.
Each element may be a literal, an expression, or a (define …) constant.
; Canvas-relative render target(texture :name renderTarget :size canvas :format preferred-canvas-format :usage [render-attachment])
; Static size(texture :name image :size [512 512] :format rgba8unorm :usage [texture-binding])
; Sized from a decoded image(data :name logoFile :file "assets/logo.png" :mime "image/png")(image-bitmap :name logo :data logoFile)
(texture :name diffuseMap :size logo :format rgba8unorm :usage [texture-binding copy-dst render-attachment]):format
Section titled “:format”Type: symbol
Texture format. Common formats:
| Format | Description |
|---|---|
rgba8unorm |
8-bit RGBA, normalized |
bgra8unorm |
8-bit BGRA, normalized |
rgba16float |
16-bit float RGBA |
rgba32float |
32-bit float RGBA |
r8unorm |
8-bit red channel |
r32float |
32-bit float red channel |
depth24plus |
24-bit depth |
depth32float |
32-bit float depth |
depth24plus-stencil8 |
Depth + stencil |
preferred-canvas-format |
Browser preferred format |
:usage
Section titled “:usage”Type: array of symbols
Texture usage flags. At least one required.
| Flag | Description |
|---|---|
texture-binding |
Sample in shaders |
storage-binding |
Read/write in compute |
render-attachment |
Render target |
copy-src |
Copy from texture |
copy-dst |
Copy to texture |
:sample-count
Section titled “:sample-count”Type: number (1 or 4)
Samples per texel. WebGPU takes 1 or 4 and nothing between, and the compiler
says so where the value is written. Above 1 the texture is multisampled, which
constrains the rest of its descriptor: it must be 2d, have one mip level and
one array layer, carry render-attachment usage (multisampling happens during
rasterization, so the texture has to be attachable), and not carry
storage-binding (a storage write addresses one texel, and a multisampled
texel is four samples). Each of those is a separate located error.
(define :name SAMPLE_COUNT :value 4)
(texture :name msaaTarget :size canvas :format preferred-canvas-format :usage [render-attachment] :sample-count SAMPLE_COUNT):dimension
Section titled “:dimension”Type: symbol (1d | 2d | 3d)
Texture dimensionality, spelled as the WebGPU specification spells it: 1d,
2d (the default), or 3d. A number there is a wrong_underlying error and a
spelling outside the three is a not_member that lists them.
A 3d texture takes its slice count from the third :size element. A 2d
array keeps :dimension 2d and puts the layer count in that same third
element.
A 1d texture cannot carry render-attachment usage: a render pass
rasterizes into a 2d or 3d target.
Sampling a 1d, 3d, or array texture requires a texture view whose dimension matches; a default view (used when a texture is bound directly) is always 2d.
:mip-level-count
Section titled “:mip-level-count”Type: number (≥ 1)
Number of mip levels to allocate (default 1). Levels beyond what you write stay
uninitialized until generated (e.g. by a mip-generation pass).
(texture :name mipped :size [256 256] :mip-level-count 4 :format rgba8unorm :usage [texture-binding copy-dst])Type: number (1 to 255)
Creates N sequential ping-pong texture instances, alternating each frame
between the one being read and the one being written (feedback render targets,
for example). The same mechanism as a (buffer …) pool.
(texture :name feedbackTex :size canvas :format rgba8unorm :usage [texture-binding render-attachment] :pool 2)Examples
Section titled “Examples”Render Target
Section titled “Render Target”(texture :name colorTarget :size canvas :format preferred-canvas-format :usage [render-attachment texture-binding])Depth Buffer
Section titled “Depth Buffer”(texture :name depthTexture :size canvas :format depth24plus :usage [render-attachment])
(render-pass :name main (depth-stencil-attachment :view depthTexture :depth-clear-value 1.0 :depth-load-op clear :depth-store-op store) :pipeline cubePipeline (draw :vertex-count 36))MSAA with Resolve
Section titled “MSAA with Resolve”(define :name SAMPLE_COUNT :value 4)
(texture :name msaaTexture :size canvas :format preferred-canvas-format :usage [render-attachment] :sample-count SAMPLE_COUNT)
(render-pass :name msaaPass (color-attachment :view msaaTexture :resolve-target context-current-texture :clear-value [0 0 0 1] :load-op clear :store-op discard) :pipeline pipeline (draw :vertex-count 3))External Image Texture
Section titled “External Image Texture”(data :name imageData :file "texture.png" :mime "image/png")
(image-bitmap :name image :data imageData)
(texture :name diffuseMap :size image :format rgba8unorm :usage [texture-binding copy-dst render-attachment])
(queue :name loadTexture (copy-external-image-to-texture (source :image image) (destination :texture diffuseMap)))Validation Rules
Section titled “Validation Rules”| Rule | Error |
|---|---|
| A name is declared once, across every form kind | duplicate_cross_ref_target, or duplicate name 'x': already declared as a (texture …) at line N |
:size, :format and :usage are required |
missing_required_key |
:size is an extent vector, canvas, or an (image-bitmap …) name |
union_no_branch_matched |
:usage needs at least one flag |
vector_too_short |
:dimension is 1d, 2d or 3d |
not_member; wrong_underlying for a number |
Each :size element and :mip-level-count are ≥ 1 |
number_below_min |
:pool must be in [1,255] |
number_below_min / number_above_max |
:sample-count is 1 or 4 |
texture 't' sets :sample-count 2 |
| Above 1 it means 2d, one mip level, one layer, attachable and not storage | texture 't' is :sample-count 4 without render-attachment usage |
render-attachment needs a 2d or 3d texture |
texture 't' is :dimension 1d with render-attachment usage |
| A copy endpoint carries the usage the copy needs | texture 't' is the destination of a copy but its :usage has no copy-dst |
The rows with a code are schema checks; the rows with a message are compiler checks that read a value rather than a shape, and they report the line the form is written on.
WebGPU Mapping
Section titled “WebGPU Mapping”Maps to GPUTexture via:
device.createTexture({ size: [width, height, depthOrArrayLayers], dimension: "3d", // when :dimension 3d (omitted for the 2d default) mipLevelCount: mipLevelCount, sampleCount: sampleCount, format: format, usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT});Related
Section titled “Related”(texture-view …)- Explicit view (required to sample 1d/3d/array/cube)(sampler …)- Configure texture sampling(image-bitmap …)- Decode images into textures(bind-group …)- Bind textures to shaders(render-pass …)- Use as render target(queue …)- Copy images to textures