(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});Where these words come from
Section titled “Where these words come from”Every key and value on this page traced to the WebGPU name it stands for, with a link to the definition. How the tracing is made, and what keeps it from rotting, is the subject of Where the Words Come From.
(texture …) mirrors GPUTextureDescriptor (MDN).
| Key | WebGPU | Note |
|---|---|---|
:name |
GPUObjectDescriptorBase.label |
the label of GPUObjectDescriptorBase, and the name every cross-reference resolves |
:size |
GPUTextureDescriptor.size |
|
:format |
GPUTextureDescriptor.format |
|
:usage |
GPUTextureDescriptor.usage |
|
:sample-count |
GPUTextureDescriptor.sampleCount |
|
:dimension |
GPUTextureDescriptor.dimension |
|
:mip-level-count |
GPUTextureDescriptor.mipLevelCount |
|
:pool |
PNGine’s own | ping-pong: N instances, one selected per frame |
Not expressible in PNGine yet: GPUTextureDescriptor.viewFormats, GPUTextureDescriptor.textureBindingViewDimension.
Values
Section titled “Values”texture-format (:format on (texture …)) spells the GPUTextureFormat enum.
50 values
| Value | WebGPU | Note |
|---|---|---|
rgba8unorm |
"rgba8unorm" |
|
rgba8snorm |
"rgba8snorm" |
|
bgra8unorm |
"bgra8unorm" |
|
rgba16float |
"rgba16float" |
|
rgba32float |
"rgba32float" |
|
depth24plus |
"depth24plus" |
|
depth24plus-stencil8 |
"depth24plus-stencil8" |
|
depth32float |
"depth32float" |
|
stencil8 |
"stencil8" |
|
depth16unorm |
"depth16unorm" |
|
r8unorm |
"r8unorm" |
|
rg8unorm |
"rg8unorm" |
|
r16float |
"r16float" |
|
rg16float |
"rg16float" |
|
r32float |
"r32float" |
|
r32uint |
"r32uint" |
|
rgba8unorm-srgb |
"rgba8unorm-srgb" |
|
rgba8uint |
"rgba8uint" |
|
rgba8sint |
"rgba8sint" |
|
r8snorm |
"r8snorm" |
|
r8uint |
"r8uint" |
|
r8sint |
"r8sint" |
|
rg8snorm |
"rg8snorm" |
|
rg8uint |
"rg8uint" |
|
rg8sint |
"rg8sint" |
|
r16uint |
"r16uint" |
|
r16sint |
"r16sint" |
|
rg16uint |
"rg16uint" |
|
rg16sint |
"rg16sint" |
|
r32sint |
"r32sint" |
|
rg32uint |
"rg32uint" |
|
rg32sint |
"rg32sint" |
|
rg32float |
"rg32float" |
|
rgba16uint |
"rgba16uint" |
|
rgba16sint |
"rgba16sint" |
|
rgba32uint |
"rgba32uint" |
|
rgba32sint |
"rgba32sint" |
|
rgb10a2unorm |
"rgb10a2unorm" |
|
rgb10a2uint |
"rgb10a2uint" |
|
rg11b10ufloat |
"rg11b10ufloat" |
|
rgb9e5ufloat |
"rgb9e5ufloat" |
|
bgra8unorm-srgb |
"bgra8unorm-srgb" |
|
r16unorm |
"r16unorm" |
|
r16snorm |
"r16snorm" |
|
rg16unorm |
"rg16unorm" |
|
rg16snorm |
"rg16snorm" |
|
rgba16unorm |
"rgba16unorm" |
|
rgba16snorm |
"rgba16snorm" |
|
depth32float-stencil8 |
"depth32float-stencil8" |
|
preferred-canvas-format |
PNGine’s own | the runtime’s negotiated canvas format; see References |
52 of the spec's 101 values PNGine does not offer
bc1-rgba-unorm, bc1-rgba-unorm-srgb, bc2-rgba-unorm, bc2-rgba-unorm-srgb, bc3-rgba-unorm, bc3-rgba-unorm-srgb, bc4-r-unorm, bc4-r-snorm, bc5-rg-unorm, bc5-rg-snorm, bc6h-rgb-ufloat, bc6h-rgb-float, bc7-rgba-unorm, bc7-rgba-unorm-srgb, etc2-rgb8unorm, etc2-rgb8unorm-srgb, etc2-rgb8a1unorm, etc2-rgb8a1unorm-srgb, etc2-rgba8unorm, etc2-rgba8unorm-srgb, eac-r11unorm, eac-r11snorm, eac-rg11unorm, eac-rg11snorm, astc-4x4-unorm, astc-4x4-unorm-srgb, astc-5x4-unorm, astc-5x4-unorm-srgb, astc-5x5-unorm, astc-5x5-unorm-srgb, astc-6x5-unorm, astc-6x5-unorm-srgb, astc-6x6-unorm, astc-6x6-unorm-srgb, astc-8x5-unorm, astc-8x5-unorm-srgb, astc-8x6-unorm, astc-8x6-unorm-srgb, astc-8x8-unorm, astc-8x8-unorm-srgb, astc-10x5-unorm, astc-10x5-unorm-srgb, astc-10x6-unorm, astc-10x6-unorm-srgb, astc-10x8-unorm, astc-10x8-unorm-srgb, astc-10x10-unorm, astc-10x10-unorm-srgb, astc-12x10-unorm, astc-12x10-unorm-srgb, astc-12x12-unorm, astc-12x12-unorm-srgb
texture-usage (:usage on (texture …)) spells the GPUTextureUsage flags (MDN).
| Value | WebGPU | Note |
|---|---|---|
copy-src |
GPUTextureUsage.COPY_SRC |
|
copy-dst |
GPUTextureUsage.COPY_DST |
|
texture-binding |
GPUTextureUsage.TEXTURE_BINDING |
|
storage-binding |
GPUTextureUsage.STORAGE_BINDING |
|
render-attachment |
GPUTextureUsage.RENDER_ATTACHMENT |
Not offered by PNGine (1 of the spec’s 6 values): transient-attachment.
texture-dimension (:dimension on (texture …)) spells the GPUTextureDimension enum.
| Value | WebGPU | Note |
|---|---|---|
1d |
"1d" |
|
2d |
"2d" |
|
3d |
"3d" |
Checked against the WebGPU specification at revision b8c0fa9; the links go to the current draft.
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