Documentation
¶
Overview ¶
Package mslmap builds the naga MSL binding map for the Metal backend.
Metal binds resources by slot in three argument tables: buffers, textures and samplers. The slots of a pipeline's shaders come from its pipeline layout, as in Rust wgpu-hal: every stage numbers the bindings visible to it in binding order, group after group (StageLayout), and the encoder binds a bind group at the same slots (GroupSlots). The slots never depend on which bindings a shader declares, so one shader module serves pipeline layouts that place its bindings differently.
naga translates WGSL arrayLength() and the bounds checks of runtime-sized arrays into arithmetic on an extra entry point argument named `_buffer_sizes`. It goes to the buffer slot after the layout's buffers.
The package has no build tags and does not call Objective-C, so its tests run on any CI runner.
Reference: Rust wgpu-hal metal/device.rs create_pipeline_layout (per_stage_map, sizes_buffer) and load_shader (one entry point per stage with the layout's map).
Index ¶
- func BaseOptions() msl.Options
- func CompileLanguageVersion(v msl.Version) uint64
- func IsStorageBuffer(entry *gputypes.BindGroupLayoutEntry) bool
- func LanguageVersion(platform Platform, os OSVersion) msl.Version
- func PreserveInvariance(platform Platform, os OSVersion) bool
- func RuntimeArrayBindings(module *ir.Module) ([]ir.ResourceBinding, error)
- func SortEntries(entries []gputypes.BindGroupLayoutEntry) []gputypes.BindGroupLayoutEntry
- type Counts
- type Kind
- type OSVersion
- type Platform
- type StageLayout
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BaseOptions ¶
BaseOptions returns the MSL options every Metal shader starts from, before any binding map. The bounds checks are Rust wgpu-hal's (metal/device.rs:186-222): Restrict on indices, buffers and image loads, Unchecked on binding arrays. naga's zero value would check binding arrays too.
func CompileLanguageVersion ¶
CompileLanguageVersion returns the MTLLanguageVersion value of v for MTLCompileOptions.languageVersion: the major version in the high 16 bits and the minor in the low ones (MTLLanguageVersion2_4 = 0x20004).
func IsStorageBuffer ¶
func IsStorageBuffer(entry *gputypes.BindGroupLayoutEntry) bool
IsStorageBuffer reports whether entry is a storage buffer: only those can hold a runtime-sized array, whose length naga reads from `_buffer_sizes`.
func LanguageVersion ¶
LanguageVersion returns the newest MSL version the Metal compiler of the given system accepts, as Rust wgpu-hal picks it (wgpu-hal/src/metal/adapter.rs, PrivateCapabilities::new, msl_version). Shaders are written for it (msl.Options.LangVersion) and compiled at it (MTLCompileOptions.languageVersion): naga refuses a feature that needs a newer version instead of raising it.
func PreserveInvariance ¶
PreserveInvariance reports whether the system has MTLCompileOptions.preserveInvariance (macOS 11, iOS 13), which Rust wgpu-hal sets wherever it exists (metal/device.rs load_shader) so that @invariant outputs are computed the same way in every pipeline.
func RuntimeArrayBindings ¶
func RuntimeArrayBindings(module *ir.Module) ([]ir.ResourceBinding, error)
RuntimeArrayBindings returns the bindings of the global variables whose type holds a runtime-sized array. The order is the IR declaration order.
naga builds one uint32 field per such global of the module, in this same order, whichever entry point it writes. Each field must hold the byte size of the binding that is bound to it.
Reference: naga v0.18.0 msl/internal/codegen/writer.go:786-797 (scanBufferSizeGlobals).
func SortEntries ¶
func SortEntries(entries []gputypes.BindGroupLayoutEntry) []gputypes.BindGroupLayoutEntry
SortEntries returns a copy of entries sorted by binding number. WebGPU gives the dynamic offsets in binding order, and the slots below are assigned in that order too, so they never depend on the order the caller listed the entries in. Rust wgpu-core hands wgpu-hal the entries sorted.
Types ¶
type Counts ¶
Counts holds a number of slots per argument table.
func GroupSlots ¶
func GroupSlots(entries []gputypes.BindGroupLayoutEntry, stage gputypes.ShaderStages) (slots []int, counts Counts)
GroupSlots returns, for each entry of one bind group layout (sorted by SortEntries), its slot in its argument table counted from the group's first slot in stage, or -1 if the entry is not visible to stage or takes no slot. counts is the number of slots the group takes in stage.
The Metal device binds a bind group with these slots and compiles the pipeline's shaders with StageLayout, which counts the same way.
Reference: Rust wgpu-hal metal/device.rs create_bind_group (the per-stage counters of BindGroup).
type Kind ¶
type Kind uint8
Kind is the Metal argument table a binding takes a slot in.
const ( // KindNone marks a layout entry that takes no slot. KindNone Kind = iota // KindBuffer is the buffer argument table: uniform and storage buffers // and acceleration structures. KindBuffer // KindTexture is the texture argument table: sampled and storage // textures. KindTexture // KindSampler is the sampler argument table. KindSampler )
func EntryKind ¶
func EntryKind(entry *gputypes.BindGroupLayoutEntry) Kind
EntryKind returns the argument table of a bind group layout entry, as Rust wgpu-hal's Metal create_pipeline_layout sorts the binding types.
type OSVersion ¶
type OSVersion struct {
Major, Minor, Patch int
}
OSVersion is an operating system version, as NSProcessInfo.operatingSystemVersion reports it.
type Platform ¶
type Platform int
Platform is the Apple operating system a Metal device runs on. Go targets only macOS and iOS among Apple's systems.
type StageLayout ¶
type StageLayout struct {
// Resources maps each binding visible to the stage to its slot.
Resources map[ir.ResourceBinding]msl.BindTarget
// GroupBase holds, per bind group of the pipeline layout, the first slot
// of the group in each argument table.
GroupBase []Counts
// SizesSlot is the buffer slot of naga's `_buffer_sizes` argument: the
// first buffer slot after the bindings, reserved when a storage buffer
// is visible to the stage. It is -1 when none is.
SizesSlot int
}
StageLayout is where one shader stage finds its resources under one pipeline layout.
func NewStageLayout ¶
func NewStageLayout(groups [][]gputypes.BindGroupLayoutEntry, stage gputypes.ShaderStages) (StageLayout, error)
NewStageLayout lays out the bindings of a pipeline layout for one stage: groups holds the entries of each bind group layout, sorted by SortEntries (nil for a group without entries). Each argument table is numbered from 0 over the bindings visible to the stage, group after group, in binding order.
Reference: Rust wgpu-hal metal/device.rs create_pipeline_layout (per_stage_map, base_resource_indices, sizes_buffer).
func (*StageLayout) Options ¶
func (l *StageLayout) Options(stage ir.ShaderStage, entryPoint string) msl.Options
Options returns the MSL options that write only entryPoint of the given stage, with this layout's slots. naga refuses a resource the entry point uses that the layout does not hold (backend.ErrMissingBinding).