vam

package module
v0.0.0-...-df451fa Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2024 License: MIT Imports: 28 Imported by: 0

README

vam

A pure-go port of VulkanMemoryAllocator. The ported code is split between this package and arsenal/memutils, which contains the portion of VulkanMemoryAllocator which seemed like it could be reused with another manual memory management library. In particular, the TLSF implementation, the linear manager implementation, and the lion's share of the defragmentation code all live in memutils.

This seems to be implemented (see full_test.go for examples) but there are goals still unmet, zero automated tests, and no documentation.

What's left:

  • Missing extension support added to vkngwrapper/extensions and supported here
  • Incorporate a RWLock into allocation.Map/Unmap, and make use of it for the defrag process
  • Automated tests
  • Documentation

Documentation

Index

Constants

View Source
const (
	MaxLowBufferImageGranularity uint = 256
)

Variables

View Source
var ErrAllocationAlreadyFreed = cerrors.New("already freed")

ErrAllocationAlreadyFreed is an error that is wrapped and returned when carrying out device-memory-accessing operations against an Allocation that has already been freed. If one of these operations returns an error, you can use errors.Is and errors.As to determine whether the error occurred because you were attempting to interact with an already-freed allocation.

Functions

This section is empty.

Types

type AllocateDeviceMemoryCallback

type AllocateDeviceMemoryCallback func(
	allocator *Allocator,
	memoryType int,
	memory core1_0.DeviceMemory,
	size int,
	userData interface{},
)

AllocateDeviceMemoryCallback is a callback that fires when new device memory is allocated from Vulkan. It does not fire with every new Allocation object, since device memory is frequently reused for block allocations.

type Allocation

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

Allocation represents a single logical memory allocation made with Vulkan. This object *may* represent a single core1_0.DeviceMemory object, if it is a dedicated allocation, but more likely represents a small portion of a larger memory object. Your must allocate these on your own using whatever method you wish, and then pass a pointer to an Allocator to populate this object with useful data. This process will cause the Allocation to escape the stack, so Allocations will always live on the heap. However, reusing a freed Allocation is completely legal, so using object pools to manage the Allocation objects works just fine.

func (*Allocation) Alignment

func (a *Allocation) Alignment() uint

Alignment is the alignment of this allocation's offset in the larger memory block, if any

func (*Allocation) BindBufferMemory

func (a *Allocation) BindBufferMemory(buffer core1_0.Buffer) (common.VkResult, error)

BindBufferMemory will bind this Allocation's memory to a provided core1_0.Buffer

As a device-memory-accessing method, BindBufferMemory will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

Other error types came from Vulkan.

func (*Allocation) BindBufferMemoryWithOffset

func (a *Allocation) BindBufferMemoryWithOffset(offset int, buffer core1_0.Buffer, next common.Options) (common.VkResult, error)

BindBufferMemoryWithOffset will bind a portion of this Allocation's memory, beginning at the provided offset, to a provided core1_0.Buffer.

As a device-memory-accessing method, BindBufferMemoryWithOffset will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

Other error types came from Vulkan.

offset - The offset to the beginning of the portion of memory to bind

buffer - The core1_0.Buffer to bind the memory to

next - A common.Options chain to add to the end of the BindBufferMemory2 options chain created by vam. nil is an acceptable value

func (*Allocation) BindImageMemory

func (a *Allocation) BindImageMemory(image core1_0.Image) (common.VkResult, error)

BindImageMemory will bind this Allocation's memory to a provided core1_0.Image

As a device-memory-accessing method, BindImageMemory will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

Other error types came from Vulkan.

func (*Allocation) BindImageMemoryWithOffset

func (a *Allocation) BindImageMemoryWithOffset(offset int, image core1_0.Image, next common.Options) (common.VkResult, error)

BindImageMemoryWithOffset will bind a portion of this Allocation's memory, beginning at the provided offset, to a provided core1_0.Image.

As a device-memory-accessing method, BindImageMemoryWithOffset will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

Other error types came from Vulkan.

offset - The offset to the beginning of the portion of memory to bind

image - The core1_0.Image to bind the memory to

next - A common.Options chain to add to the end of the BindImageMemory2 options chain created by vam. nil is an acceptable value

func (*Allocation) CreateAliasingBuffer

func (a *Allocation) CreateAliasingBuffer(bufferInfo core1_0.BufferCreateInfo) (core1_0.Buffer, common.VkResult, error)

CreateAliasingBuffer creates and binds a new core1_0.Buffer for this Allocation. It can be used for anything, but it is usually used for Aliasing Buffers, which you can read about [here](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/resource_aliasing.html).

As a device-memory-accessing method, CreateAliasingBuffer will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

This method will return VKErrorExtensionNotPresent if the bufferInfo.Usage attempts to use Shader Device Address but the khr_buffer_device_address extension is not available (and core 1.2 is not active). Other VKErrorUnknown errors indicate an issue with the bufferInfo object, such as 0 size or a requested size that cannot fit within this Allocation. Other errors come from Vulkan.

bufferInfo - the core1_0.BufferCreateInfo that will be passed to core1_0.Device.CreateBuffer

func (*Allocation) CreateAliasingBufferWithOffset

func (a *Allocation) CreateAliasingBufferWithOffset(offset int, bufferInfo core1_0.BufferCreateInfo) (core1_0.Buffer, common.VkResult, error)

CreateAliasingBufferWithOffset creates and binds a new core1_0.Buffer for a portion of this Allocation that begins at the provided offset. It can be used for anything, but it is usually used for Aliasing Buffers, which you can read about [here](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/resource_aliasing.html).

As a device-memory-accessing method, CreateAliasingBufferWithOffset will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

This method will return VKErrorExtensionNotPresent if the bufferInfo.Usage attempts to use Shader Device Address but the khr_buffer_device_address extension is not available (and core 1.2 is not active). Other VKErrorUnknown errors indicate an issue with the bufferInfo object, such as 0 size or a requested size that cannot fit within this Allocation. Other errors come from Vulkan.

offset - The offset from the beginning of this Allocation to the start of the created core1_0.Buffer

bufferInfo - the core1_0.BufferCreateInfo that will be passed to core1_0.Device.CreateBuffer

func (*Allocation) CreateAliasingImage

func (a *Allocation) CreateAliasingImage(imageInfo core1_0.ImageCreateInfo) (core1_0.Image, common.VkResult, error)

CreateAliasingImage creates and binds a new core1_0.Image for this Allocation. It can be used for anything, but it is usually used for Aliasing Images, which you can read about [here](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/resource_aliasing.html).

As a device-memory-accessing method, CreateAliasingImage will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

Other VKErrorUnknown errors indicate an issue with the imageInfo object, such as 0-sized dimensions. Other errors come from Vulkan.

imageInfo - the core1_0.ImageCreateInfo that will be passed to core1_0.Device.CreateImage

func (*Allocation) CreateAliasingImageWithOffset

func (a *Allocation) CreateAliasingImageWithOffset(offset int, imageInfo core1_0.ImageCreateInfo) (core1_0.Image, common.VkResult, error)

CreateAliasingImageWithOffset creates and binds a new core1_0.Image for the portion of this Allocation. beginning at the provided offset. It can be used for anything, but it is usually used for Aliasing Images, which you can read about [here](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/resource_aliasing.html).

As a device-memory-accessing method, CreateAliasingImageWithOffset will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

Other VKErrorUnknown errors indicate an issue with the imageInfo object, such as 0-sized dimensions. Other errors come from Vulkan.

offset - The offset from the beginning of this Allocation to the start of the created core1_0.Image

imageInfo - the core1_0.ImageCreateInfo that will be passed to core1_0.Device.CreateImage

func (*Allocation) DestroyBuffer

func (a *Allocation) DestroyBuffer(buffer core1_0.Buffer) error

DestroyBuffer is roughly equivalent to calling buffer.Destroy() followed by Free. The main benefit of this method is that buffer.Destroy() will use the allocation callbacks passed to the Allocator that was used to allocat this memory.

func (*Allocation) DestroyImage

func (a *Allocation) DestroyImage(image core1_0.Image) error

DestroyImage is roughly equivalent to calling image.Destroy() followed by Free. The main benefit of this method is that image.Destroy() will use the allocation callbacks passed to the Allocator that was used to allocate this memory.

func (*Allocation) FindOffset

func (a *Allocation) FindOffset() int

FindOffset retrieves the offset of the allocation in the larger memory block, if any. This method may not run at O(1), so if you need access to it frequently, you should probably cache it. Be aware that defragmentation may change the return value suddenly.

func (*Allocation) Flush

func (a *Allocation) Flush(offset, size int) (common.VkResult, error)

Flush will flush the memory cache for a specified region of memory within this Allocation.

As a device-memory-accessing method, Flush will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

All other return errors with VkErrorUnknown are due to the offset and size representing an invalid region within this Allocation. Other error types came from Vulkan

offset - The offset from the start of this Allocation to begin flushing

size - The size of the region to flush

func (*Allocation) Free

func (a *Allocation) Free() error

Free frees this Allocation and, potentially, the underlying memory. It is valid to reuse this Allocation immediately after freeing it by passing it to another Allocator method that allocates memory

Free briefly takes out a write lock against this Allocation, so it will block if any device-memory-accessing methods are in flight or if this memory is currently mapped with Map. It will also block those methods from continuing while it is running (once it completes, they will fail, as the Allocation has been freed).

If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed. If this Allocation was persistently mapped, this method will also return any errors returned by Unmap.

func (*Allocation) Invalidate

func (a *Allocation) Invalidate(offset, size int) (common.VkResult, error)

Invalidate will invalidate the meory cache for a specified region of memory within this Allocation

As a device-memory-accessing method, Invalidate will briefly take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

All other return errors with VkErrorUnknown are due to the offset and size representing an invalid region within this Allocation. Other error types came from Vulkan

offset - The offset from the start of this Allocation to begin invalidating

size - The size of the region to invalidate

func (*Allocation) IsMappingAllowed

func (a *Allocation) IsMappingAllowed() bool

IsMappingAllowed returns true if Map is a legal operation, or false otherwise

func (*Allocation) Map

Map attempts to retrieve a direct unsafe.Pointer to the memory underlying this Allocation. The pointer retrieved will point directly to the first byte of this allocation's memory, not to the first byte of the larger memory block or anything like that.

As a device-memory-accessing method, Map will take out a read lock on this Allocation and may block if defragmentation is in progress or the Allocation is currently being freed. If the Allocation has already been freed, this method will return a VkResult of VkErrorUnknown, with an error that wraps ErrAllocationAlreadyFreed.

This method will return VKErrorMemoryMapFailed if the allocation was created without mapping functionality being requested. Any other error value came from Vulkan.

It is not legal for consumers of this library to Map allocations long-term, even if the memory was allocated with the persistent map option. Mapping takes out a read lock until Unmap is called, and so defragmentation and Free calls will halt until the memory is unmapped. Instead, feel free to call Map/Unmap as often as you like- you can use the Persistent Map option to prevent the underlying memory from "really" unmapping, and even if you don't, logic is in place to make the map persistent if Map/Unmap are called frequently.

It is also not legal to hold the pointer after calling Unmap, even if you are using Persistent Map. Defragmentation may relocate allocation memory, and Map/Unmap are used to ensure that this does not cause you issues.

func (*Allocation) Memory

func (a *Allocation) Memory() core1_0.DeviceMemory

Memory is the underlying core1_0.DeviceMemory this Allocation is assigned to

func (*Allocation) MemoryType

func (a *Allocation) MemoryType() core1_0.MemoryType

MemoryType retrieves the core1_0.MemoryType object for the memory type in the physical device that the underlying device memory is allocated to

func (*Allocation) MemoryTypeIndex

func (a *Allocation) MemoryTypeIndex() int

MemoryTypeIndex retrieves index of the memory type in the physical device that the underlying device memory is allocated to

func (*Allocation) Name

func (a *Allocation) Name() string

Name retrieves the name assigned with SetName

func (*Allocation) ParentPool

func (a *Allocation) ParentPool() *Pool

ParentPool returns the Pool used to create this Allocation, if anyy

func (*Allocation) SetName

func (a *Allocation) SetName(name string)

SetName applies a name to the Allocation that can be used to identify it while debugging or for other diagnostic purposes

func (*Allocation) SetUserData

func (a *Allocation) SetUserData(userData any)

SetUserData attaches a piece of arbitrary data to Allocation that can be used to identify it while debugging or for other diagnostic purposes. In particular, if you have an object used to identify a resource by, for instance combining the allocation with a core1_0.Buffer or core1_0.Image, you may find it useful to make that the attached userdata. It especially comes in handy during defragmentation, where you will be given Allocation objects and asked to copy their data elsewhere.

func (*Allocation) Size

func (a *Allocation) Size() int

Size is the number of bytes claimed by this allocation

func (*Allocation) Unmap

func (a *Allocation) Unmap() error

Unmap unmaps a pointer previously received from Map and frees the read lock that was held against this Allocation so that defragmentation and Free operations can move forward. This method will return an error if it has been called more times than Map has been called for the underlying core1_0.DeviceMemory

func (*Allocation) UserData

func (a *Allocation) UserData() any

UserData retrieves the data attached with SetUserData

type AllocationCreateFlags

type AllocationCreateFlags int32

AllocationCreateFlags exposes several options for allocation behavior that can be applied.

const (
	// AllocationCreateDedicatedMemory instructs the allocator to give this allocate its own memory block
	AllocationCreateDedicatedMemory AllocationCreateFlags = 1 << iota
	// AllocationCreateNeverAllocate instructs the allocator to only try to allocate from existing
	// DeviceMemory blocks and never create new blocks
	//
	// If a new allocation cannot be placed in any of the existing blocks, allocation fails with
	// core1_0.VKErrorOutOfDeviceMemory
	AllocationCreateNeverAllocate
	// AllocationCreateMapped instructs the allocator to use memory that will be persistently mapped
	// and retrieve a pointer to it
	//
	// The pointer will be available via Allocation.mappedData()
	//
	// It is valid to use this flag for an allocation made from a memory type that is not HOST_VISIBLE.
	// This flag is then ignored and the memory is not mapped. This is useful if you need an allocation
	// that is efficient to use on GPU (DEVICE_LOCAL) and want to map it if possible on platforms that
	// support it (i.e. integrated memory).
	AllocationCreateMapped
	// AllocationCreateUpperAddress will instruct the allocator to create the allocation from the upper
	// stack in a double stack pool. This flag is only allowed for custom pools created with the
	// PoolCreateLinearAlgorithm flag
	AllocationCreateUpperAddress
	// AllocationCreateDontBind instructs the allocator to create both buffer/image and allocation, but
	// don't bind them together. This is useful when you want to make the binding yourself to do more advanced
	// binding such as using some extension. This flag is only useful in functions that bind by default:
	// Allocator.CreateBuffer, Allocator.CreateImage, etc. Otherwise, it is ignored.
	//
	// If you want to make sure the buffer/image are not tied to the new allocation through
	// MemoryDedicatedAllocateInfo structure in case the allocation ends up in its own memory block,
	// also use AllocationCreateCanAlias
	AllocationCreateDontBind
	// AllocationCreateWithinBudget instructs the allocator to only create the allocation if additional
	// device memory required for it won't exceed memory budget. Otherwise, return  core1_0.VKErrorOutOfDeviceMemory
	AllocationCreateWithinBudget
	// AllocationCreateCanAlias indicates whether the allocated memory will have aliasing resources.
	//
	// Using this flag prevents supplying MemoryDedicatedAllocateInfo when AllocationCreateDedicatedMemory
	// is specified. Otherwise, created dedicated memory will not be suitable for aliasing resources.
	AllocationCreateCanAlias
	// AllocationCreateHostAccessSequentialWrite requests the possibility to map the allocation
	//
	// If you use MemoryUsageAuto* you must use this flag to be able to map the allocation. If
	// you use other values of MemoryUsage, this flag is ignored and mapping is always possible
	// in memory types that are HostVisible. This includes allocations created in custom memory pools.
	//
	// This declares that mapped memory will only be written sequentially, never read or accessed randomly,
	// so a memory type can be selected that is uncached and write-combined. Violating this restriction
	// may or may not work correctly, but will likely be very slow
	AllocationCreateHostAccessSequentialWrite
	// AllocationCreateHostAccessRandom requests the possibility to map the allocation
	//
	// If you use MemoryUsageAuto* you must use this flag to be able to map the allocation. If
	// you use other values of MemoryUsage, this flag is ignored and mapping is always possible in memory
	// types that are HostVisible. This includes allocations created in custom memory pools.
	//
	// This declares that mapped memory can be read, written, and accessed in random order, so a HostCached
	// memory type is required.
	AllocationCreateHostAccessRandom
	// AllocationCreateHostAccessAllowTransferInstead combines with AllocationCreateHostAccessSequentialWrite
	// or AllocationCreateHostAccessRandom to indicate that despite request for host access, a non-HostVisible
	// memory type can be selected if it may improve performance.
	//
	// By using this flag, you declare that you will check if the allocation ended up in a HostVisible memory
	// type and if not, you will create some "staging" buffer and issue an explicit transfer to write/read your
	// data. To prepare for this possibility, don't forget to add appropriate flags like core1_0.BufferUsageTransferDst
	// and core1_0.BufferUsageTransferSrc to the parameters of the created Buffer or Image.
	AllocationCreateHostAccessAllowTransferInstead
	// AllocationCreateStrategyMinMemory selects the allocation strategy that chooses the smallest-possible
	// free range for the allocation to minimize memory usage and fragmentation, possibly at the expense of
	// allocation time
	AllocationCreateStrategyMinMemory
	// AllocationCreateStrategyMinTime selects the allocation strategy that chooses the first suitable free
	// range for the allocation- not necessarily in terms of the smallest offset, but the one that is easiest
	// and fastest to find to minimize allocation time, possibly at the expense of allocation quality.
	AllocationCreateStrategyMinTime
	// AllocationCreateStrategyMinOffset selects the allocation strategy that chooses the lowest offset in
	// available space. This is not the most efficient strategy, but achieves highly packed data. Used internally
	// by defragmentation, not recommended in typical usage.
	AllocationCreateStrategyMinOffset

	AllocationCreateStrategyMask = AllocationCreateStrategyMinMemory |
		AllocationCreateStrategyMinTime |
		AllocationCreateStrategyMinOffset
)

func (AllocationCreateFlags) Register

func (f AllocationCreateFlags) Register(str string)

func (AllocationCreateFlags) String

func (f AllocationCreateFlags) String() string

type AllocationCreateInfo

type AllocationCreateInfo struct {
	// Flags is a memutils.AllocationCreateFlags value that describes the intended behavior of the
	// created Allocation
	Flags AllocationCreateFlags
	// Usage indicates how the new allocation will be used, allowing vam to decide what memory
	// type to use
	Usage MemoryUsage

	// RequiredFlags indicates what flags must be on the memory type. If no type with these flags can be found with
	// enough free memory, the allocation will fail
	RequiredFlags core1_0.MemoryPropertyFlags
	// PreferredFlags indicates a set of flags that should be on the memory type. Each specified flag are considered
	// equally important: that is, if two flags are specified and no memory type contains both, an arbitrary memory
	// type with one of the two will be chosen, if it exists.
	PreferredFlags core1_0.MemoryPropertyFlags

	// MemoryTypeBits is a bitmask of memory types that may be chosen for the requested allocation. If this is left
	// 0, all memory types are permitted.
	MemoryTypeBits uint32
	// Pool is the custom memory pool to allocate from. This is usually nil, in which case the memory will be
	// allocated directly from the Allocator.
	Pool *Pool

	// UserData is an arbitrary value that will be applied to the Allocation. Allocation.UserData() will return
	// this value after the allocation is complete. It's often helpful to place a resource object that ties the
	// Allocation to a Buffer or Image here.
	UserData interface{}
	// Priority is the ext_memory_priority priority value applied to the allocated memory. This only has
	// an effect for dedicated allocations, it is ignored for block allocations.
	Priority float32
}

AllocationCreateInfo is an options struct that is used to define the specifics of a new allocation created by Allocator.AllocateMemory, Allocator.AllocateMemorySlice, Allocator.AllocateMemoryForBuffer, Allocator.AllocateMemoryForImage, etc.

type Allocator

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

Allocator is vam's root object and is used to create Pool and Allocation objects

func New

func New(logger *slog.Logger, instance core1_0.Instance, physicalDevice core1_0.PhysicalDevice, device core1_0.Device, options CreateOptions) (*Allocator, error)

New creates a new Allocator

logger - The Allocator, along with Allocation and Pool objects created from it, will write to this logger when it has something to say.

instance - The instance that owns the provided Device

physicalDevice - The PhysicalDevice that owns the provided Device

device - The Device that memory will be allocated into

options - Optional parameters: it is valid to leave all the fields blank

func (*Allocator) AllocateMemory

func (a *Allocator) AllocateMemory(memoryRequirements *core1_0.MemoryRequirements, o AllocationCreateInfo, outAlloc *Allocation) (common.VkResult, error)

AllocateMemory allocates memory according to provided memory requirements and AllocationCreateInfo and assigns it to a provided Allocation object.

Because this method does not accept a core1_0.BufferCreateInfo or core1_0.ImageCreateInfo, it can't be all that intelligent about how it chooses the memory type. You can help it by providing RequiredFlags and PreferredFlags in the AllocationCreateInfo object.

Return errors will mostly come from Vulkan, but key parameter validation will also return errors: if any parameter is nil, if memoryRequirements has a zero or negative size, if memoryRequirements has an alignment that is not a power of 2, or if outAlloc already contains an active allocation.

memoryRequirements - A pointer to a populated core1_0.MemoryRequirements object indicating the size and other properties the allocation should have

o - Options indicating the sort of allocation being made

outAlloc - A pointer to a valid Allocation that has not yet been allocated to (or has been recently freed). Passing an Allocation object to this method will cause it to escape to the heap, but because freed allocations can be reused, it is valid to get them from a sync.Pool

func (*Allocator) AllocateMemoryForBuffer

func (a *Allocator) AllocateMemoryForBuffer(buffer core1_0.Buffer, o AllocationCreateInfo, outAlloc *Allocation) (common.VkResult, error)

AllocateMemoryForBuffer allocates memory ideal for the provided core1_0.Buffer and AllocationCreateInfo and assigns it to a provided Allocation object. The buffer is not bound to the allocated memory.

Return errors will mostly come from Vulkan, but key parameter validation will also return errors: if any parameter is nil or if outAlloc already contains an active allocation.

buffer - A core1_0.Buffer object indicating the buffer that memory will be allocated for

o - Options indicating the sort of allocation being made

outAlloc - A pointer to a valid Allocation that has not yet been allocated to (or has been recently freed). Passing an Allocation object to this method will cause it to escape to the heap, but because freed allocations can be reused, it is valid to get them from a sync.Pool

func (*Allocator) AllocateMemoryForImage

func (a *Allocator) AllocateMemoryForImage(image core1_0.Image, o AllocationCreateInfo, outAlloc *Allocation) (common.VkResult, error)

AllocateMemoryForImage allocates memory ideal for the provided core1_0.Image and AllocationCreateInfo and assigns it to a provided Allocation object. The image is not bound to the allocated memory.

Return errors will mostly come from Vulkan, but key parameter validation will also return errors: if any parameter is nil or if outAlloc already contains an active allocation.

image - A core1_0.Image object indicating the image that memory will be allocated for

o - Options indicating the sort of allocation being made

outAlloc - A pointer to a valid Allocation that has not yet been allocated to (or has been recently freed). Passing an Allocation object to this method will cause it to escape to the heap, but because freed allocations can be reused, it is valid to get them from a sync.Pool

func (*Allocator) AllocateMemorySlice

func (a *Allocator) AllocateMemorySlice(memoryRequirements *core1_0.MemoryRequirements, o AllocationCreateInfo, allocations []Allocation) (common.VkResult, error)

AllocateMemorySlice allocates several tranches of memory according to a provided core1_0.MemoryRequirements and AllocationCreateInfo and assigns them to a slice of provided Allocation objects.

Because this method does not accept a core1_0.BufferCreateInfo or core1_0.ImageCreateInfo, it can't be all that intelligent about how it chooses the memory type. You can help it by providing RequiredFlags and PreferredFlags in the AllocationCreateInfo object.

Return errors will mostly come from Vulkan, but key parameter validation will also return errors: if any memoryRequirements is nil, if memoryRequirements has a zero or negative size, if memoryRequirements has an alignment that is not a power of 2, or if any element of allocations already contains an active allocation.

memoryRequirements - A pointer to a populated core1_0.MemoryRequirements object indicating the size and other properties the allocation should have

o - Options indicating the sort of allocation being made

outAlloc - A slice of Allocation objects that have not yet been allocated to (or have been recently freed). Passing a slice to this method will cause it to escape to the heap.

func (*Allocator) BeginDefragmentation

func (a *Allocator) BeginDefragmentation(o DefragmentationInfo, defragContext *DefragmentationContext) (common.VkResult, error)

BeginDefragmentation populates a provided DefragmentationContext object and prepares it to run a defragmentation process. See the README for more information about defragmentation.

This method will return an error if defragContext is nil. defragContext will escape to the heap if passed to this method, but it can be reused multiple times.

func (*Allocator) BuildStatsString

func (a *Allocator) BuildStatsString(detailed bool) string

BuildStatsString will return a json string representing the full state of this Allocator for debugging purposes.

detailed - A boolean indicating how much data to provide. If false, basic statistical information will be printed. If true, full information about all allocations will be printed.

func (*Allocator) CalculateStatistics

func (a *Allocator) CalculateStatistics(stats *AllocatorStatistics) error

CalculateStatistics populates an AllocatorStatistics struct with the current state of this Allocator. This method will return an error if the provided stats object is nil.

func (*Allocator) CheckCorruption

func (a *Allocator) CheckCorruption(memoryTypeBits uint32) (common.VkResult, error)

CheckCorruption verifies the internal consistency and integrity of a set of memory types indicated by the memoryTypeBits mask. This will return VKErrorFeatureNotPresent if there are no memory types in the mask that have corruption-checking active, or VKSuccess if at least one memory type was checked for corruption, and no corruption was found. All other errors indicate some form of corruption.

For corruption detection to be active, the memory type has to support memory mapping, and the binary needs to have been built with the debug_mem_utils build tag

func (*Allocator) CreateBuffer

func (a *Allocator) CreateBuffer(bufferInfo core1_0.BufferCreateInfo, allocInfo AllocationCreateInfo, outAlloc *Allocation) (core1_0.Buffer, common.VkResult, error)

CreateBuffer creates a brand new core1_0.Buffer for the provided core1_0.BufferCreateInfo, allocates memory to support it using the core1_0.BufferCreateInfo and AllocationCreateInfo, assigns the allocation to the provided Allocation, and binds the Buffer to the Allocation.

This method will return VKErrorExtensionNotPresent if the bufferInfo.Usage attempts to use Shader Device Address but the khr_buffer_device_address extension is not available (and core 1.2 is not active). Validation errors will return if any parameter is nil or if outAlloc already contains an active allocation. Other VKErrorUnknown errors indicate an issue with the bufferInfo object, such as 0 size or a requested size that cannot fit within this Allocation. Other errors come from Vulkan.

bufferInfo - A core1_0.BufferCreateInfo describing the Buffer to create

allocInfo - Options indicating the sort of allocation being made

outAlloc - A pointer to a valid Allocation that has not yet been allocated to (or has been recently freed). Passing an Allocation object to this method will cause it to escape to the heap, but because freed allocations can be reused, it is valid to get them from a sync.Pool

func (*Allocator) CreateBufferWithAlignment

func (a *Allocator) CreateBufferWithAlignment(bufferInfo core1_0.BufferCreateInfo, allocInfo AllocationCreateInfo, minAlignment int, outAlloc *Allocation) (core1_0.Buffer, common.VkResult, error)

CreateBufferWithAlignment creates a brand new core1_0.Buffer for the provided core1_0.BufferCreateInfo, allocates memory to support it using the core1_0.BufferCreateInfo and AllocationCreateInfo, assigns the allocation to the provided Allocation, and binds the Buffer to the Allocation.

This method will return VKErrorExtensionNotPresent if the bufferInfo.Usage attempts to use Shader Device Address but the khr_buffer_device_address extension is not available (and core 1.2 is not active). Validation errors will return if any parameter is nil or if outAlloc already contains an active allocation. Other VKErrorUnknown errors indicate an issue with the bufferInfo object, such as 0 size, a requested size that cannot fit within this Allocation, or a minimum alignment that is not a power of 2. Other errors come from Vulkan.

bufferInfo - A core1_0.BufferCreateInfo describing the Buffer to create

allocInfo - Options indicating the sort of allocation being made

minAlignment - The allocated memory will use this alignment if it is greater than the alignment for the buffer's memory requirements

outAlloc - A pointer to a valid Allocation that has not yet been allocated to (or has been recently freed). Passing an Allocation object to this method will cause it to escape to the heap, but because freed allocations can be reused, it is valid to get them from a sync.Pool

func (*Allocator) CreateImage

func (a *Allocator) CreateImage(imageInfo core1_0.ImageCreateInfo, allocInfo AllocationCreateInfo, outAlloc *Allocation) (image core1_0.Image, res common.VkResult, err error)

CreateImage creates a brand new core1_0.Image for the provided core1_0.ImageCreateInfo, allocates memory to support it using the core1_0.ImageCreateInfo and AllocationCreateInfo, assigns the allocation to the provided Allocation, and binds the Image to the Allocation.

Validation errors will return if outALloc is nil or if outAlloc already contains an active allocation. Other VKErrorUnknown errors indicate an issue with the imageInfo object, such as 0-sized dimensions

imageInfo - A core1_0.ImageCreateInfo describing the Image to create

allocInfo - Options indicating the sort of allocation being made

outAlloc - A pointer to a valid Allocation that has not yet been allocated to (or has been recently freed). Passing an Allocation object to this method will cause it to escape to the heap, but because freed allocations can be reused, it is valid to get them from a sync.Pool

func (*Allocator) CreatePool

func (a *Allocator) CreatePool(createInfo PoolCreateInfo) (*Pool, common.VkResult, error)

CreatePool creates a custom memory pool that can be used for unusual allocation cases. See Pool for more information.

VKErrorFeatureNotPresent will be returned if the provided MemoryTypeIndex is invalid or not present in this Allocator. Other errors are for other obvious forms of parameter validation.

func (*Allocator) Destroy

func (a *Allocator) Destroy() error

Destroy annihilates this allocator. It should be called before the end of your application. It will fail if any Pool objects created from it have not yet been destroyed, and it will fail if any Allocation objects have not yet been freed, so it's a reasonably good way to locate memory leaks.

func (*Allocator) FindMemoryTypeIndex

func (a *Allocator) FindMemoryTypeIndex(
	memoryTypeBits uint32,
	o AllocationCreateInfo,
) (int, common.VkResult, error)

FindMemoryTypeIndex gets the memory type that should be used for a requested allocation, as provided by an AllocationCreateInfo. This can be used to decide what memoryTypeIndex to use when creating a Pool, or in any situation where you want a good memory type to be intelligently selected without actually allocating memory.

Because this method does not accept a core1_0.BufferCreateInfo or core1_0.ImageCreateInfo, it can't be all that intelligent about how it chooses the memory type. You can help it by providing RequiredFlags and PreferredFlags in the AllocationCreateInfo object.

memoryTypeBits - You can use this bitmask to prevent this method from returning memory types you don't want.

o - Options indicating the sort of allocation being made

func (*Allocator) FindMemoryTypeIndexForBufferInfo

func (a *Allocator) FindMemoryTypeIndexForBufferInfo(
	bufferInfo core1_0.BufferCreateInfo,
	o AllocationCreateInfo,
) (int, common.VkResult, error)

FindMemoryTypeIndexForBufferInfo gets the memory type that should be used for a requested allocation, as provided by the combination of an AllocationCreateInfo and a core1_0.BufferCreateInfo. This can be used to decide what memory type index to use when creating a Pool, or in any situation where you want a good memory type to be intelligently selected without actually allocating memory. The memory type index returned will be for the memory type that is best for a buffer created with the provided core1_0.BufferCreateInfo.

bufferInfo - The core1_0.BufferCreateInfo that will be used to create the eventual buffer

o - Options indicating the sort of allocation being made

func (*Allocator) FindMemoryTypeIndexForImageInfo

func (a *Allocator) FindMemoryTypeIndexForImageInfo(
	imageInfo core1_0.ImageCreateInfo,
	o AllocationCreateInfo,
) (int, common.VkResult, error)

FindMemoryTypeIndexForImageInfo gets the memory type that should be used for a requested allocation, as provided by the combination of an AllocationCreateInfo and a core1_0.ImageCreateInfo. This can be used to decide what memory type index to use when creating a Pool, or in any situation where you want a good memory type to be intelligently selected without actually allocating memory. The memory type index returned will be for the memory type that is best for an image created with the provided core1_0.ImageCreateInfo

imageInfo - The core1_0.ImageCreateInfo that will be used to create the eventual image

o - Options indicating the sort of allocation being made

func (*Allocator) FlushAllocationSlice

func (a *Allocator) FlushAllocationSlice(allocations []Allocation, offsets []int, sizes []int) (common.VkResult, error)

FlushAllocationSlice is a convenience method that is roughly equivalent to, but may be slightly more performant than, calling Allocation.Flush on a slice of allocations.

func (*Allocator) FreeAllocationSlice

func (a *Allocator) FreeAllocationSlice(allocs []Allocation) error

FreeAllocationSlice is a convenience method that is roughly equivalent to calling Allocation.Free on an entire slice of allocations.

func (*Allocator) InvalidateAllocationSlice

func (a *Allocator) InvalidateAllocationSlice(allocations []Allocation, offsets []int, sizes []int) (common.VkResult, error)

InvalidateAllocationSlice is a convenience method that is roughly equivalent to, but may be slightly more performant than, calling Allocation.Invalidate on a slice of allocations

type AllocatorStatistics

type AllocatorStatistics struct {
	MemoryTypes [common.MaxMemoryTypes]memutils.DetailedStatistics
	MemoryHeaps [common.MaxMemoryHeaps]memutils.DetailedStatistics
	Total       memutils.DetailedStatistics
}

AllocatorStatistics is used to get the current state of memory within an Allocator, including breakdowns by memory type and heap of currently-allocated memory

type BlockBufferImageGranularity

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

func (*BlockBufferImageGranularity) AllocRegions

func (g *BlockBufferImageGranularity) AllocRegions(allocType uint32, offset, size int)

func (*BlockBufferImageGranularity) AllocationsConflict

func (g *BlockBufferImageGranularity) AllocationsConflict(
	firstAllocType uint32,
	secondAllocType uint32,
) bool

func (*BlockBufferImageGranularity) CheckConflictAndAlignUp

func (g *BlockBufferImageGranularity) CheckConflictAndAlignUp(
	allocOffset, allocSize, regionOffset, regionSize int,
	allocType uint32,
) (int, bool)

func (*BlockBufferImageGranularity) Clear

func (g *BlockBufferImageGranularity) Clear()

func (*BlockBufferImageGranularity) Destroy

func (g *BlockBufferImageGranularity) Destroy()

func (*BlockBufferImageGranularity) FinishValidation

func (g *BlockBufferImageGranularity) FinishValidation(anyCtx any) error

func (*BlockBufferImageGranularity) FreeRegions

func (g *BlockBufferImageGranularity) FreeRegions(offset, size int)

func (*BlockBufferImageGranularity) Init

func (g *BlockBufferImageGranularity) Init(size int)

func (*BlockBufferImageGranularity) IsEnabled

func (g *BlockBufferImageGranularity) IsEnabled() bool

func (*BlockBufferImageGranularity) RoundUpAllocRequest

func (g *BlockBufferImageGranularity) RoundUpAllocRequest(allocType uint32, allocSize int, allocAlignment uint) (int, uint)

func (*BlockBufferImageGranularity) StartValidation

func (g *BlockBufferImageGranularity) StartValidation() any

func (*BlockBufferImageGranularity) Validate

func (g *BlockBufferImageGranularity) Validate(anyCtx any, offset, size int) error

type CreateFlags

type CreateFlags int32

CreateFlags indicate specific allocator behaviors to activate or deactivate

const (
	// AllocatorCreateExternallySynchronized ensures that this allocator and all objects created from it
	// will not be synchronized internally. The consumer must guarantee they are used from only one
	// thread at a time or are synchronized by some other mechanism, but performance may improve because
	// internal mutexes are not used.
	AllocatorCreateExternallySynchronized CreateFlags = 1 << iota
)

func (CreateFlags) Register

func (f CreateFlags) Register(str string)

func (CreateFlags) String

func (f CreateFlags) String() string

type CreateOptions

type CreateOptions struct {
	// Flags indicates specific allocator behaviors to activate or deactivate
	Flags CreateFlags
	// PreferredLargeHeapBlockSize is the block size to use when allocating from heaps larger
	// than a gigabyte
	PreferredLargeHeapBlockSize int

	// VulkanCallbacks is an optional set of callbacks that will be executed from Vulkan on memory
	// created from this allocator. Allocations & frees performed by this allocator do not map 1:1
	// with allocations & frees performed by Vulkan, so these will not always be called
	VulkanCallbacks *driver.AllocationCallbacks

	// MemoryCallbackOptions is an optional set of callbacks that will be executed when Vulkan memory
	// is allocated from this Allocator. It can be helpful in cases when the consumer requires allocator-
	// level info about allocated memory
	MemoryCallbackOptions *MemoryCallbackOptions

	// HeapSizeLimits can be left empty. If it is provided, though, it must be a slice
	// with a number of entries corresponding to the number of heaps in the PhysicalDevice
	// used to create this Allocator. Each entry must be either the maximum number of bytes
	// that should be allocated from the corresponding device memory heap, or 0 indicating
	// no limit.
	//
	// Heap memory limits will be enforced at runtime (the allocator will go so far as to
	// return an out of memory error when attempting to allocate beyond the limit).
	HeapSizeLimits []int

	// ExternalMemoryHandleTypes can be left empty. If it is provided though, it must be a slice
	// with a number of entries corresponding to the number of memory types in the PhysicalDevice
	// used to create this Allocator. Each entry must be either 0, indicating not to use external
	// memory, or a memory handle type, indicating which type of memory handles to use for
	// the memory type
	ExternalMemoryHandleTypes []khr_external_memory_capabilities.ExternalMemoryHandleTypeFlags
}

CreateOptions contains optional settings when creating an allocator

type DefragmentationContext

type DefragmentationContext struct {
	MaxPassBytes       int
	MaxPassAllocations int
	// contains filtered or unexported fields
}

DefragmentationContext is an object that represents a single run of the defragmentation algorithm, although that run will consist of multiple passes that may be spread out over an extended period of time. This object is populated by Allocator.BeginDefragmentation. DefragmentationContext objects can be reused for multiple defragmentation runs in order to reduce allocations, if desired.

func (*DefragmentationContext) BeginDefragPass

BeginDefragPass collects a number of relocations to be performed for a single pass of the defragmentation run and returns those relocations. Before returning, the Allocation objects being relocated (defrag.DefragmentationMove.SrcAllocation) will be write-locked, causing any device-memory-accessing method calls to block until EndDefragPass is called. Before calling EndDefragPass, the caller should copy the memory data from SrcAllocation to DstTmpAllocation and rebind any relevant resources (buffers, images, etc.) to the DstTmpAllocation. If it is necessary to map SrcAllocation's memory in order to accomplish that, then MapSourceAllocation and UnmapSourceAllocation are available for use, since Allocation.Map will block forever.

Alternatively, defrag.DefragmentationMove.MoveOperation can be set to defrag.DefragmentationMoveIgnore or defrag.DefragmentationMoveDestroy instead to prevent the relocation or simply destroy SrcAllocation without moving it.

func (*DefragmentationContext) EndDefragPass

func (c *DefragmentationContext) EndDefragPass() (bool, error)

EndDefragPass will complete the relocation of the allocations collected in BeginDefragPass, inject DstTmpAllocation's data into SrcAllocation (so the old Allocation object can continue to be used), release the write lock on SrcAllocation, and free the old memory that was relocated.

This method may return any error that Allocation.Unmap does if any of the various Unmap operations it performs fail. Otherwise, it will return true if the defragmentation run has ended after this pass, or false if additional passes are necessary.

func (*DefragmentationContext) Finish

func (c *DefragmentationContext) Finish(outStats *defrag.DefragmentationStats)

Finish performs some vital cleanup duties after the last defragmentation pass has run. This should be called whenever EndDefragPass returns true.

func (*DefragmentationContext) MapSourceAllocation

func (c *DefragmentationContext) MapSourceAllocation(alloc *Allocation) (unsafe.Pointer, common.VkResult, error)

MapSourceAllocation is roughly equivalent to calling Allocation.Map- however, Allocation.Map cannot be called on an Allocation object in the midst of being relocated as part of a defragmentation pass, because a write lock has been taken out on the Allocation. If it is necessary to map data as part of the relocation process, use this method. Because this ignores Allocation thread-safety primitives, calling this on an Allocation that is not currently being relocated by this DefragmentationContext is dangerous.

func (*DefragmentationContext) UnmapSourceAllocation

func (c *DefragmentationContext) UnmapSourceAllocation(alloc *Allocation) error

UnmapSourceAllocation should be called after MapSourceAllocation to clean up the mapping

type DefragmentationFlags

type DefragmentationFlags uint32

DefragmentationFlags is a set of bitflags that specify behavior for the DefragmentationContext

const (
	// DefragmentationFlagAlgorithmFast indicates that the DefragmentationContext should use a "fast"
	// algorithm that is less thorough about compacting data within blocks, but requires fewer passes
	// to complete a full run. It is not compatible with DefragmentationFlagAlgorithmFull
	DefragmentationFlagAlgorithmFast DefragmentationFlags = 1 << iota
	// DefragmentationFlagAlgorithmFull indicates that the DefragmentationContext should use an algorithm
	// that is somewhat slower than DefragmentationFlagAlgorithmFast but will compact memory within blocks,
	// allowing subsequent passes to compact memory across blocks to use the space that was just freed up.
	//
	// This is the default algorithm if none is specified. It is not compatible with DefragmentationFlagAlgorithmFast
	DefragmentationFlagAlgorithmFull

	DefragmentationFlagAlgorithmMask = DefragmentationFlagAlgorithmFast |
		DefragmentationFlagAlgorithmFull
)

func (DefragmentationFlags) String

func (f DefragmentationFlags) String() string

type DefragmentationInfo

type DefragmentationInfo struct {
	// Flags specifies optional DefragmentationFlags
	Flags DefragmentationFlags
	// Pool indicates a custom memory pool to defragment. This is usually nil, in which case the
	// Allocator will be defragmented
	Pool *Pool

	// MaxBytesPerPass is the maximum number of bytes to relocate in each pass. This can be used to restrict the amount of compute
	// and GPU that will be spent on a single pass of the defragmentation algorithm. If one pass is performed per
	// frame (or some other mechanism to limit throughput), then the amount of resources spent on the defragmentation
	// process can be controlled.
	MaxBytesPerPass int
	// MaxAllocationsPerPass is the maximum number of Allocation objects to relocate in each pass. Since the number
	// of relocations is almost a direct proxy for the number of go allocations made, this is an important value
	// for managing go memory throughput and CPU usage spent on the defragmentation process.
	MaxAllocationsPerPass int
}

DefragmentationInfo is used to specify options for a defragmentation run when populating a DefragmentationContext.

type FreeDeviceMemoryCallback

type FreeDeviceMemoryCallback func(
	allocator *Allocator,
	memoryType int,
	memory core1_0.DeviceMemory,
	size int,
	userData interface{},
)

FreeDeviceMemoryCallback is a callback that fires when device memory is freed from Vulkan. It does not fire with every call to Allocation.Free(), since device memory is frequently reused for block allocations.

type MemoryCallbackOptions

type MemoryCallbackOptions struct {
	Allocate AllocateDeviceMemoryCallback
	Free     FreeDeviceMemoryCallback
	UserData interface{}
}

MemoryCallbackOptions allows optional Allocate and Free callbacks to be fired from an Allocator. The UserData field indicates the userData parameter that will be passed to Allocate and Free callbacks.

type MemoryUsage

type MemoryUsage uint32
const (
	// MemoryUsageUnknown indicates no intended memory usage was specified. When choosing a memory type,
	// the Allocator uses only the Required and Preferred flags specified in AllocationCreateInfo to
	// find an appropriate memory index and nothing else. This may be desirable when using Allocator.AllocateMemory
	// and Allocator.AllocateMemorySlice, since the allocator does not have BufferUsage or ImageUsage flags
	// to make decisions with. Bear in mind that it is possible, in this case, for the allocator to
	// select a memory type that is not compatible with your AllocationCreateFlags if you do not
	// specify appropriate RequiredFlags/PreferredFlags. For instance, if AllocationCreateFlags contains
	// AllocationCreateMapped, but you do not specify HostVisible in your RequiredFlags, then
	// the allocation may fail when it attempts to map your new memory.
	MemoryUsageUnknown MemoryUsage = iota
	// MemoryUsageGPULazilyAllocated indicates lazily-allocated GPU memory. Exists mostly
	// on mobile platforms. Using it on desktop PC or other GPUs with no such memory type present
	// will fail the allocation.
	//
	// Usage: Memory for transient attachment images (color attachments, depth attachments, etc.) created
	// with core1_0.ImageUsageTransientAttachment
	//
	// Allocations with this usage are always created as dedicated - it implies AllocationCreateDedicatedMemory
	MemoryUsageGPULazilyAllocated
	// MemoryUsageAuto selects the best memory type automatically. This flag is recommended for most
	// common use cases.
	//
	// When using this flag, if you want to map the allocation, you must pass one of the flags
	// AllocationCreateHostAccessSequentialWrite or AllocationCreateHostAccessRandom in AllocationCreateInfo.Flags
	//
	// It can be used only with functions indicate a Buffer or Image and not with generic memory allocation
	// functions.
	MemoryUsageAuto
	// MemoryUsageAutoPreferDevice selects the best memory type automatically with preference for GPU (device)
	// memory. When using this flag, if you want to map the allocation, you must pass one of the flags
	// AllocationCreateHostAccessSequentialWrite or AllocationCreateHostAccessRandom in AllocationCreateInfo.Flags
	//
	// It can be used only with functions indicate a Buffer or Image and not with generic memory allocation
	// functions.
	MemoryUsageAutoPreferDevice
	// MemoryUsageAutoPreferHost selects the best memory type automatically with preference for CPU (host)
	// memory. When using this flag, if you want to map the allocation, you must pass one of the flags
	// AllocationCreateHostAccessSequentialWrite or AllocationCreateHostAccessRandom in AllocationCreateInfo.Flags
	//
	// It can be used only with functions indicate a Buffer or Image and not with generic memory allocation
	// functions.
	MemoryUsageAutoPreferHost
)

func (MemoryUsage) String

func (u MemoryUsage) String() string

type Pool

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

Pool is a structure that can be created to allow allocations that have unusual properties compared to the default behavior of allocations made via the Allocator. There are many features that can be unliked using Pool objects, but it is almost always better, more performant, and more straightforward to use the Allocator instead. Only use a Pool if there is no way you can do without them.

Some possibilities:

* Perform some allocations with the PoolCreateLinearAlgorithm in order to create an arena, stack, or queue of quickly allocated-and-deallocated tiny allocations without having to worry about defragmentation. * Have a managed pool of memory that is allocated differently from ordinary memory using PoolCreateInfo.MemoryAllocateNext * Have a pool of memory that is allocated to blocks but has a different ext_memory_priority priority than Allocator memory.

func (*Pool) CheckCorruption

func (p *Pool) CheckCorruption() (common.VkResult, error)

CheckCorruption verifies the internal consistency and integrity of this pool's memory. This will return VKErrorFeatureNotPresent if the pool's memory type does not have corruption check active, or VKSuccess if no corruption was found. All other errors indicate some form of corruption.

For corruption detection to be active, the memory type has to support memory mapping, and the binary needs to have been built with the debug_mem_utils build tag

func (*Pool) Destroy

func (p *Pool) Destroy() error

Destroy annihilates this Pool. It should be called before calling Allocator.Destroy. It will if any Allocation objects have not yet been freed, so it's a reasonably good way to locate memory leaks.

func (*Pool) ID

func (p *Pool) ID() int

ID returns an integer id that is unique to this pool across the life of your application. It can be used for debugging or other purposes.

func (*Pool) Name

func (p *Pool) Name() string

Name returns a string name that was previously set with SetName

func (*Pool) SetName

func (p *Pool) SetName(name string)

SetName applies a name to the Pool that can be used to identify it while debugging or for other diagnostic purposes

type PoolCreateFlags

type PoolCreateFlags int32

PoolCreateFlags is a set of flags that each correspond to a single option related to a Pool object's behavior

const (
	// PoolCreateIgnoreBufferImageGranularity indicates to the memory pool that you always allocate
	// only buffers and linear images or only optimal images out of this pool, so Buffer/Image Granularity
	// can be ignored.
	//
	// Some allocator methods (CreateBuffer, CreateImage, AllocateMemoryForBuffer) have enough info to
	// set buffer/image granularity precisely, so this flag is unnecessarily.  However, some methods
	// (AllocateMemoryForImage and AllocateMemory) may defensively allocate memory subptimally since
	// they do not have this information. You can set this flag to notify images that you only
	// intend to allocate buffers, linear images, and optimal images so that these defensiv emeasures
	// are unnecessary. Allocations will be faster and more optimal
	PoolCreateIgnoreBufferImageGranularity PoolCreateFlags = 1 << iota
	// PoolCreateLinearAlgorithm enables alternative, linear allocation algorithm in this pool.
	// The algorithm always creates new allocations after the last one and doesn't reuse space from
	// allocations freed in between. It trades memory consumption for a simplifies algorithm and data
	// structure, which has better performance and uses less memory for metadata. This flag can be used
	// to achieve the behavior of free-at-once, stack, ring buffer, and double stack.
	PoolCreateLinearAlgorithm

	PoolCreateAlgorithmMask = PoolCreateLinearAlgorithm
)

func (PoolCreateFlags) Register

func (f PoolCreateFlags) Register(str string)

func (PoolCreateFlags) String

func (f PoolCreateFlags) String() string

type PoolCreateInfo

type PoolCreateInfo struct {
	// MemoryTypeIndex indicates the memory type to be used by the new Pool. A Pool can only
	// use a single memory type, unlike Allocator objects, which will select the correct one
	// to use during an allocation.
	MemoryTypeIndex int
	// Flags indicates optional behaviors to use.
	Flags PoolCreateFlags

	// BlockSize indicates a static size to use for each block in a custom Pool. If 0, block sizes
	// will be chosen based on the same heuristics used when creating new memory blocks for an Allocator,
	// which is usually the right decision.
	BlockSize int
	// MinBlockCount indicates the minimum number of memory blocks that will remain in this Pool at all times.
	// This many blocks will be pre-allocated upon Pool creation and freeing Allocation objects will not
	// cause the number of blocks to drop below this level.
	MinBlockCount int
	// MaxBlockCount indicates the maximum number of memory blocks that will be in this Pool at a time. If
	// an allocation would require the number of blocks to increase beyond this amount, the allocation will
	// fail with VKErrorOutOfDeviceMemory. 0 indicates no maximum.
	MaxBlockCount int

	// Priority is the ext_memory_priority priority value used for memory blocks created with this Pool
	Priority float32
	// MinAllocationAlignment is the alignment that memory allocated to this Pool will use if it is greater
	// than the alignment that would otherwise be chosen for an Allocation
	MinAllocationAlignment uint
	// MemoryAllocateNext is an option stack that will be added to the end of allocation operations for this
	// Pool
	MemoryAllocateNext common.Options
}

PoolCreateInfo is an options structure that is used to specify the behavior for a new custom Pool object.

type SuballocationType

type SuballocationType uint32
const (
	SuballocationFree SuballocationType = iota
	SuballocationUnknown
	SuballocationBuffer
	SuballocationImageUnknown
	SuballocationImageLinear
	SuballocationImageOptimal
)

func (SuballocationType) String

func (s SuballocationType) String() string

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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