track

package
v0.31.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package track provides resource state tracking infrastructure.

TrackerIndex provides dense indexing for efficient O(1) access to resource tracking state. Unlike resource IDs (which use epochs and may be sparse), tracker indices are always dense (0, 1, 2, ...) for efficient array access.

Architecture

Each Device owns a TrackerIndexAllocators which manages separate allocators for each resource type. When a resource is created, it gets a TrackerIndex from the appropriate allocator. When destroyed, the index is returned for reuse.

Thread Safety

SharedTrackerIndexAllocator provides thread-safe allocation/deallocation. The underlying TrackerIndexAllocator uses mutex-based synchronization.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SkipBarrier added in v0.31.0

func SkipBarrier(old, next TextureUses) bool

SkipBarrier returns true if transitioning from old to new does NOT require a barrier.

A barrier can be skipped when:

  1. The state did not change, AND
  2. All usages in the state are ordered by hardware

Reference: wgpu-core track/mod.rs skip_barrier()

Types

type BufferState

type BufferState struct {
	// contains filtered or unexported fields
}

BufferState holds the tracked state for a single buffer.

func (BufferState) Usage

func (s BufferState) Usage() BufferUses

Usage returns the current usage.

type BufferTracker

type BufferTracker struct {
	// contains filtered or unexported fields
}

BufferTracker tracks buffer usage states for a device. Used to validate usage transitions and generate barriers.

func NewBufferTracker

func NewBufferTracker() *BufferTracker

NewBufferTracker creates a new buffer tracker.

func (*BufferTracker) GetUsage

func (t *BufferTracker) GetUsage(index TrackerIndex) BufferUses

GetUsage returns the current usage of a buffer.

func (*BufferTracker) InsertSingle

func (t *BufferTracker) InsertSingle(index TrackerIndex, usage BufferUses)

InsertSingle tracks a new buffer with initial usage.

func (*BufferTracker) IsTracked

func (t *BufferTracker) IsTracked(index TrackerIndex) bool

IsTracked returns true if the buffer is being tracked.

func (*BufferTracker) Merge

Merge merges usage from scope into tracker, returning needed transitions. This is called during queue submit to synchronize command buffer state with device state.

func (*BufferTracker) Remove

func (t *BufferTracker) Remove(index TrackerIndex)

Remove stops tracking a buffer.

func (*BufferTracker) SetUsage

func (t *BufferTracker) SetUsage(index TrackerIndex, usage BufferUses)

SetUsage updates the usage of a tracked buffer.

func (*BufferTracker) Size

func (t *BufferTracker) Size() int

Size returns the number of tracked buffers.

type BufferUsageScope

type BufferUsageScope struct {
	// contains filtered or unexported fields
}

BufferUsageScope tracks buffer usage within a command buffer or pass. Each command buffer has its own scope that gets merged into the device tracker on submit.

func NewBufferUsageScope

func NewBufferUsageScope() *BufferUsageScope

NewBufferUsageScope creates a new usage scope.

func (*BufferUsageScope) Clear

func (s *BufferUsageScope) Clear()

Clear resets the scope for reuse.

func (*BufferUsageScope) GetUsage

func (s *BufferUsageScope) GetUsage(index TrackerIndex) BufferUses

GetUsage returns the current usage in this scope.

func (*BufferUsageScope) IsUsed

func (s *BufferUsageScope) IsUsed(index TrackerIndex) bool

IsUsed returns true if the buffer is used in this scope.

func (*BufferUsageScope) ReplaceUsage added in v0.31.6

func (s *BufferUsageScope) ReplaceUsage(index TrackerIndex, usage BufferUses)

ReplaceUsage unconditionally replaces the usage recorded for a buffer. It is intended only after every resource in a multi-resource command has passed preflight validation, so committing the command cannot partially fail.

func (*BufferUsageScope) SetUsage

func (s *BufferUsageScope) SetUsage(index TrackerIndex, usage BufferUses) error

SetUsage sets the usage for a buffer in this scope. Returns error if the buffer already has an incompatible usage.

type BufferUses

type BufferUses uint32

BufferUses represents internal buffer usage states for tracking. These are more granular than gputypes.BufferUsage for precise barrier insertion.

const (
	BufferUsesNone         BufferUses = 0
	BufferUsesCopySrc      BufferUses = 1 << 0  // Being read by copy operation
	BufferUsesCopyDst      BufferUses = 1 << 1  // Being written by copy operation
	BufferUsesIndex        BufferUses = 1 << 2  // Bound as index buffer
	BufferUsesVertex       BufferUses = 1 << 3  // Bound as vertex buffer
	BufferUsesUniform      BufferUses = 1 << 4  // Bound in bind group for reading
	BufferUsesStorageRead  BufferUses = 1 << 5  // Storage buffer read-only
	BufferUsesStorageWrite BufferUses = 1 << 6  // Storage buffer read-write
	BufferUsesIndirect     BufferUses = 1 << 7  // Indirect command buffer
	BufferUsesMapRead      BufferUses = 1 << 8  // Mapped for CPU read
	BufferUsesMapWrite     BufferUses = 1 << 9  // Mapped for CPU write
	BufferUsesQueryResolve BufferUses = 1 << 10 // Query result destination
)

Buffer usage flags for state tracking.

func (BufferUses) Contains

func (u BufferUses) Contains(other BufferUses) bool

Contains returns true if all flags in other are present in u.

func (BufferUses) IsCompatible

func (u BufferUses) IsCompatible(other BufferUses) bool

IsCompatible returns true if two usages can coexist without a barrier. Read-only usages are compatible with each other. Write usages require exclusive access.

func (BufferUses) IsEmpty

func (u BufferUses) IsEmpty() bool

IsEmpty returns true if no usage flags are set.

func (BufferUses) IsReadOnly

func (u BufferUses) IsReadOnly() bool

IsReadOnly returns true if the usage contains only read-only operations.

func (BufferUses) ToBufferUsage

func (u BufferUses) ToBufferUsage() gputypes.BufferUsage

ToBufferUsage converts internal uses to gputypes.BufferUsage for HAL.

type PendingTransition

type PendingTransition struct {
	Index TrackerIndex
	Usage StateTransition
}

PendingTransition represents a state transition that needs a barrier.

func (PendingTransition) IntoHAL

func (p PendingTransition) IntoHAL(buffer hal.Buffer) hal.BufferBarrier

IntoHAL converts a pending transition to a HAL buffer barrier.

type ResourceMetadata

type ResourceMetadata struct {
	// contains filtered or unexported fields
}

ResourceMetadata tracks which resources are owned/present.

func NewResourceMetadata

func NewResourceMetadata() ResourceMetadata

NewResourceMetadata creates new metadata.

func (*ResourceMetadata) Clear

func (m *ResourceMetadata) Clear()

Clear resets the metadata.

func (*ResourceMetadata) Count

func (m *ResourceMetadata) Count() int

Count returns the number of owned resources.

func (*ResourceMetadata) IsOwned

func (m *ResourceMetadata) IsOwned(index TrackerIndex) bool

IsOwned returns true if the resource is owned.

func (*ResourceMetadata) SetOwned

func (m *ResourceMetadata) SetOwned(index TrackerIndex, owned bool)

SetOwned marks a resource as owned/not owned.

type SharedTrackerIndexAllocator

type SharedTrackerIndexAllocator struct {
	// contains filtered or unexported fields
}

SharedTrackerIndexAllocator is a thread-safe wrapper for sharing between device and resources. It's essentially a reference-counted pointer to a TrackerIndexAllocator.

func NewSharedTrackerIndexAllocator

func NewSharedTrackerIndexAllocator() *SharedTrackerIndexAllocator

NewSharedTrackerIndexAllocator creates a new shared allocator.

func (*SharedTrackerIndexAllocator) Alloc

Alloc allocates a new tracker index.

func (*SharedTrackerIndexAllocator) Free

Free releases a tracker index for reuse.

func (*SharedTrackerIndexAllocator) HighWaterMark

func (s *SharedTrackerIndexAllocator) HighWaterMark() TrackerIndex

HighWaterMark returns the highest index ever allocated.

func (*SharedTrackerIndexAllocator) Size

func (s *SharedTrackerIndexAllocator) Size() int

Size returns the number of currently allocated indices.

type StateTransition

type StateTransition struct {
	From BufferUses
	To   BufferUses
}

StateTransition represents a from→to state change.

func (StateTransition) NeedsBarrier

func (t StateTransition) NeedsBarrier() bool

NeedsBarrier returns true if this transition requires a barrier.

type TexturePendingTransition added in v0.31.0

type TexturePendingTransition struct {
	Index TrackerIndex
	Usage TextureStateTransition
}

TexturePendingTransition represents a texture state transition that needs a barrier. Produced by TextureTracker.Merge() when a command buffer's usage scope requires a different state than the device tracker's current state.

Reference: wgpu-core track/mod.rs PendingTransition<TextureUses>

func (TexturePendingTransition) IntoHAL added in v0.31.0

IntoHAL converts a pending transition to a HAL texture barrier. The caller provides the hal.Texture handle.

type TextureState added in v0.31.0

type TextureState struct {
	// contains filtered or unexported fields
}

TextureState holds the tracked state for a single texture.

func (TextureState) Usage added in v0.31.0

func (s TextureState) Usage() TextureUses

Usage returns the current usage.

type TextureStateTransition added in v0.31.0

type TextureStateTransition struct {
	From TextureUses
	To   TextureUses
}

TextureStateTransition represents a from-to state change for a texture.

func (TextureStateTransition) NeedsBarrier added in v0.31.0

func (t TextureStateTransition) NeedsBarrier() bool

NeedsBarrier returns true if this transition requires a barrier.

type TextureTracker added in v0.31.0

type TextureTracker struct {
	// contains filtered or unexported fields
}

TextureTracker tracks texture usage states for a device. It is the device-level source of truth: each submitted command buffer's usage scope is merged into this tracker, which produces the barrier list.

This mirrors Rust wgpu-core's DeviceTracker for textures (simplified to whole-texture granularity; per-subresource tracking is deferred to a future phase).

Reference: wgpu-core track/texture.rs TextureTracker

func NewTextureTracker added in v0.31.0

func NewTextureTracker() *TextureTracker

NewTextureTracker creates a new texture tracker.

func (*TextureTracker) GetUsage added in v0.31.0

func (t *TextureTracker) GetUsage(index TrackerIndex) TextureUses

GetUsage returns the current usage of a texture.

func (*TextureTracker) InsertSingle added in v0.31.0

func (t *TextureTracker) InsertSingle(index TrackerIndex, usage TextureUses)

InsertSingle tracks a new texture with initial usage.

func (*TextureTracker) IsTracked added in v0.31.0

func (t *TextureTracker) IsTracked(index TrackerIndex) bool

IsTracked returns true if the texture is being tracked.

func (*TextureTracker) Merge added in v0.31.0

Merge merges usage from scope into tracker, returning needed transitions. Called during queue submit to synchronize command buffer state with device state. Each returned TexturePendingTransition should be converted to a hal.TextureBarrier and emitted before the corresponding command buffer.

Reference: wgpu-core track/texture.rs TextureTracker::set_from_usage_scope

func (*TextureTracker) Remove added in v0.31.0

func (t *TextureTracker) Remove(index TrackerIndex)

Remove stops tracking a texture.

func (*TextureTracker) SetUsage added in v0.31.0

func (t *TextureTracker) SetUsage(index TrackerIndex, usage TextureUses)

SetUsage updates the usage of a tracked texture.

func (*TextureTracker) Size added in v0.31.0

func (t *TextureTracker) Size() int

Size returns the number of tracked textures.

type TextureUsageConflictError added in v0.31.0

type TextureUsageConflictError struct {
	Index    TrackerIndex
	Existing TextureUses
	New      TextureUses
}

TextureUsageConflictError is returned when incompatible texture usages are detected within the same scope.

func (*TextureUsageConflictError) Error added in v0.31.0

func (e *TextureUsageConflictError) Error() string

Error implements the error interface.

type TextureUsageScope added in v0.31.0

type TextureUsageScope struct {
	// contains filtered or unexported fields
}

TextureUsageScope tracks texture usage within a command buffer or pass. Each command buffer has its own scope that gets merged into the device tracker on submit.

Reference: wgpu-core track/texture.rs TextureUsageScope

func NewTextureUsageScope added in v0.31.0

func NewTextureUsageScope() *TextureUsageScope

NewTextureUsageScope creates a new usage scope.

func (*TextureUsageScope) Clear added in v0.31.0

func (s *TextureUsageScope) Clear()

Clear resets the scope for reuse.

func (*TextureUsageScope) GetUsage added in v0.31.0

func (s *TextureUsageScope) GetUsage(index TrackerIndex) TextureUses

GetUsage returns the current usage in this scope.

func (*TextureUsageScope) IsEmpty added in v0.31.0

func (s *TextureUsageScope) IsEmpty() bool

IsEmpty returns true if no textures are tracked in this scope.

func (*TextureUsageScope) IsUsed added in v0.31.0

func (s *TextureUsageScope) IsUsed(index TrackerIndex) bool

IsUsed returns true if the texture is used in this scope.

func (*TextureUsageScope) ReplaceUsage added in v0.31.6

func (s *TextureUsageScope) ReplaceUsage(index TrackerIndex, usage TextureUses)

ReplaceUsage unconditionally replaces the usage recorded for a texture. It is intended only after preflight validation, or after an explicit transition where the scope must describe the state after the encoded barrier.

func (*TextureUsageScope) SetUsage added in v0.31.0

func (s *TextureUsageScope) SetUsage(index TrackerIndex, usage TextureUses) error

SetUsage sets the usage for a texture in this scope. Returns error if the texture already has an incompatible usage.

Reference: wgpu-core track/texture.rs TextureUsageScope::merge_single

type TextureUses added in v0.31.0

type TextureUses uint32

TextureUses represents internal texture usage states for tracking. These are more granular than gputypes.TextureUsage for precise barrier insertion and usage conflict detection.

The flags mirror Rust wgpu-types TextureUses (wgpu-types/src/texture.rs:215). Two composite constants partition the flags:

  • Ordered — hardware guarantees access order; no barrier when state unchanged
  • Exclusive — require sole access; barrier always needed on transition

Reference: wgpu-core track/texture.rs (ResourceUses impl for TextureUses)

const (
	TextureUsesNone              TextureUses = 0
	TextureUsesUninitialized     TextureUses = 1 << 0 // Unknown/junk contents
	TextureUsesPresent           TextureUses = 1 << 1 // Ready for surface presentation
	TextureUsesCopySrc           TextureUses = 1 << 2 // Source of a hardware copy
	TextureUsesCopyDst           TextureUses = 1 << 3 // Destination of a hardware copy
	TextureUsesResource          TextureUses = 1 << 4 // Read-only sampled or fetched
	TextureUsesColorTarget       TextureUses = 1 << 5 // Render pass color target
	TextureUsesDepthStencilRead  TextureUses = 1 << 6 // Read-only depth/stencil
	TextureUsesDepthStencilWrite TextureUses = 1 << 7 // Read-write depth/stencil
	TextureUsesStorageRead       TextureUses = 1 << 8 // Storage texture read-only
	TextureUsesStorageWrite      TextureUses = 1 << 9 // Storage texture write-only
)

Texture usage flags for state tracking.

func (TextureUses) AllOrdered added in v0.31.0

func (u TextureUses) AllOrdered() bool

AllOrdered returns true if all set flags are in the ordered set. When all usages are ordered, hardware guarantees access ordering. Reference: wgpu-core track/mod.rs ResourceUses::all_ordered()

func (TextureUses) Contains added in v0.31.0

func (u TextureUses) Contains(other TextureUses) bool

Contains returns true if all flags in other are present in u.

func (TextureUses) IsCompatible added in v0.31.0

func (u TextureUses) IsCompatible(other TextureUses) bool

IsCompatible returns true if two usages can coexist without a barrier. Read-only (inclusive) usages are compatible with each other. Any exclusive usage requires sole access unless the exact same flag.

Implements the Rust wgpu-core rule: any(inclusive) XOR one(exclusive). Reference: wgpu-core track/mod.rs invalid_resource_state()

func (TextureUses) IsEmpty added in v0.31.0

func (u TextureUses) IsEmpty() bool

IsEmpty returns true if no usage flags are set.

func (TextureUses) IsExclusive added in v0.31.0

func (u TextureUses) IsExclusive() bool

IsExclusive returns true if any exclusive usage flag is set. Reference: wgpu-core track/mod.rs ResourceUses::any_exclusive()

func (TextureUses) IsReadOnly added in v0.31.0

func (u TextureUses) IsReadOnly() bool

IsReadOnly returns true if the usage contains only read-only operations.

func (TextureUses) ToTextureUsage added in v0.31.0

func (u TextureUses) ToTextureUsage() gputypes.TextureUsage

ToTextureUsage converts internal uses to gputypes.TextureUsage for HAL.

type TrackerIndex

type TrackerIndex uint32

TrackerIndex is a dense index for efficient resource state tracking. Unlike resource IDs (which use epochs and may be sparse), tracker indices are always dense (0, 1, 2, ...) for efficient array access.

const InvalidTrackerIndex TrackerIndex = ^TrackerIndex(0)

InvalidTrackerIndex represents an unassigned tracker index. Using max uint32 ensures it won't conflict with valid indices.

func (TrackerIndex) IsValid

func (i TrackerIndex) IsValid() bool

IsValid returns true if this is a valid tracker index.

type TrackerIndexAllocator

type TrackerIndexAllocator struct {
	// contains filtered or unexported fields
}

TrackerIndexAllocator allocates dense tracker indices. Indices are reused after being freed to maintain density.

func NewTrackerIndexAllocator

func NewTrackerIndexAllocator() *TrackerIndexAllocator

NewTrackerIndexAllocator creates a new allocator.

func (*TrackerIndexAllocator) Alloc

Alloc allocates a new tracker index. Reuses released indices when available for optimal density.

func (*TrackerIndexAllocator) Free

func (a *TrackerIndexAllocator) Free(idx TrackerIndex)

Free releases a tracker index for reuse. Safe to call with InvalidTrackerIndex (no-op).

func (*TrackerIndexAllocator) HighWaterMark

func (a *TrackerIndexAllocator) HighWaterMark() TrackerIndex

HighWaterMark returns the highest index ever allocated. Useful for sizing tracking arrays.

func (*TrackerIndexAllocator) Reset

func (a *TrackerIndexAllocator) Reset()

Reset clears the allocator, invalidating all previously allocated indices. Use with caution - all resources using old indices become invalid.

func (*TrackerIndexAllocator) Size

func (a *TrackerIndexAllocator) Size() int

Size returns the number of currently allocated indices. This equals the total allocated minus the freed count.

type TrackerIndexAllocators

type TrackerIndexAllocators struct {
	Buffers          *SharedTrackerIndexAllocator
	Textures         *SharedTrackerIndexAllocator
	TextureViews     *SharedTrackerIndexAllocator
	Samplers         *SharedTrackerIndexAllocator
	BindGroups       *SharedTrackerIndexAllocator
	BindGroupLayouts *SharedTrackerIndexAllocator
	RenderPipelines  *SharedTrackerIndexAllocator
	ComputePipelines *SharedTrackerIndexAllocator
}

TrackerIndexAllocators manages all tracker index allocators for a device. Each resource type has its own allocator to maintain separate namespaces.

func NewTrackerIndexAllocators

func NewTrackerIndexAllocators() *TrackerIndexAllocators

NewTrackerIndexAllocators creates allocators for all resource types.

type TrackingData

type TrackingData struct {
	// contains filtered or unexported fields
}

TrackingData holds per-resource tracking information. This struct is embedded in each tracked resource (Buffer, Texture, etc.) to provide efficient O(1) access to tracking state.

Lifecycle

  1. Created with NewTrackingData during resource creation
  2. Index() used during command encoding for state tracking
  3. Release() called during resource destruction to recycle the index

Thread Safety

TrackingData is safe for concurrent use. The index is immutable after creation, and Release() uses atomic operations to prevent double-free.

func NewTrackingData

func NewTrackingData(allocator *SharedTrackerIndexAllocator) *TrackingData

NewTrackingData creates tracking data and allocates an index. The allocator must not be nil.

func (*TrackingData) Index

func (t *TrackingData) Index() TrackerIndex

Index returns the tracker index. Returns InvalidTrackerIndex if the tracking data was created with a nil allocator or has been released.

func (*TrackingData) IsReleased

func (t *TrackingData) IsReleased() bool

IsReleased returns true if Release() has been called.

func (*TrackingData) Release

func (t *TrackingData) Release()

Release frees the tracker index for reuse. Called when the resource is destroyed. Safe to call multiple times (subsequent calls are no-ops).

type TrackingDataInit

type TrackingDataInit interface {
	// InitTracking initializes the tracking data for this resource.
	InitTracking(allocator *SharedTrackerIndexAllocator)
}

TrackingDataInit is a convenience interface for resources that need tracking data initialization.

type UsageConflictError

type UsageConflictError struct {
	Index    TrackerIndex
	Existing BufferUses
	New      BufferUses
}

UsageConflictError is returned when incompatible usages are detected.

func (*UsageConflictError) Error

func (e *UsageConflictError) Error() string

Error implements the error interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL