//go:build linux package vkdevice import ( "fmt" "image" "math" "unsafe" "github.com/bnema/purego-vulkan/vulkan" ) // Readback is only allocated for tests. Its transfer copy is // recorded after drawing and before the acquire semaphore signals; mapping // waits for the submission fence, never for compositor release. type Readback struct { device *Device Buffer vulkan.Buffer Memory vulkan.DeviceMemory width, height int32 region vulkan.BufferImageCopy // reused: bindings heap-allocate pointer arguments } func (d *Device) NewReadback(width, height int32) (r *Readback, err error) { if width <= 0 || height <= 0 || uint64(width)*uint64(height) > math.MaxInt/4 { return nil, fmt.Errorf("invalid readback dimensions %dx%d", width, height) } r = &Readback{device: d, width: width, height: height} defer func() { if err != nil { r.Close() } }() ci := vulkan.BufferCreateInfo{SType: vulkan.StructureTypeBufferCreateInfo, Size: vulkan.DeviceSize(width) * vulkan.DeviceSize(height) * 4, Usage: vulkan.BufferUsageTransferDstBit, SharingMode: vulkan.SharingModeExclusive} if err = vulkan.Check(d.Dispatch.CreateBuffer(d.Logical, &ci, nil, &r.Buffer)); err != nil { return nil, err } var req vulkan.MemoryRequirements d.Dispatch.GetBufferMemoryRequirements(d.Logical, r.Buffer, &req) var memory vulkan.PhysicalDeviceMemoryProperties d.InstanceDispatch.GetPhysicalDeviceMemoryProperties(d.Physical, &memory) // Prefer host-cached memory: CPU reads from uncached (write-combined) // memory are orders of magnitude slower for window-sized images. index := uint32(math.MaxUint32) coherent := vulkan.MemoryPropertyFlags(vulkan.MemoryPropertyHostVisibleBit | vulkan.MemoryPropertyHostCoherentBit) for _, want := range []vulkan.MemoryPropertyFlags{coherent | vulkan.MemoryPropertyHostCachedBit, coherent} { for i := uint32(0); i < memory.MemoryTypeCount && index == math.MaxUint32; i++ { if req.MemoryTypeBits&(1<