v0.4.0 2de4e1d

fence.go RawHistoryFolder

1//go:build linux
2
3package vkdevice
4
5import (
6	"fmt"
7	"unsafe"
8
9	"github.com/bnema/purego-vulkan/vulkan"
10)
11
12// BinaryFence exports a SYNC_FD after its queue submit, never an OPAQUE_FD.
13// Vulkan consumes a successfully imported SYNC_FD; a failed import leaves it
14// with the caller. Exported SYNC_FDs belong to the caller until DRM accepts.
15type BinaryFence struct {
16	Device    *Device
17	Semaphore vulkan.Semaphore
18}
19
20func (d *Device) NewBinaryFence(export bool) (*BinaryFence, error) {
21	ci := vulkan.SemaphoreCreateInfo{SType: vulkan.StructureTypeSemaphoreCreateInfo}
22	if export {
23		ex := vulkan.ExportSemaphoreCreateInfo{SType: vulkan.StructureTypeExportSemaphoreCreateInfo, HandleTypes: vulkan.ExternalSemaphoreHandleTypeSyncFDBit}
24		ci.Next = unsafe.Pointer(&ex)
25		var sem vulkan.Semaphore
26		if err := vulkan.Check(d.Dispatch.CreateSemaphore(d.Logical, &ci, nil, &sem)); err != nil {
27			return nil, fmt.Errorf("create SYNC_FD semaphore: %w", err)
28		}
29		return &BinaryFence{d, sem}, nil
30	}
31	var sem vulkan.Semaphore
32	if err := vulkan.Check(d.Dispatch.CreateSemaphore(d.Logical, &ci, nil, &sem)); err != nil {
33		return nil, err
34	}
35	return &BinaryFence{d, sem}, nil
36}
37
38func (s *BinaryFence) Export() (int, error) {
39	info := vulkan.SemaphoreGetFdInfoKHR{SType: vulkan.StructureTypeSemaphoreGetFDInfoKHR, Semaphore: s.Semaphore, HandleType: vulkan.ExternalSemaphoreHandleTypeSyncFDBit}
40	fd := int32(-1)
41	if err := vulkan.Check(s.Device.Dispatch.GetSemaphoreFdKHR(s.Device.Logical, &info, &fd)); err != nil {
42		return -1, fmt.Errorf("export Vulkan SYNC_FD: %w", err)
43	}
44	return int(fd), nil
45}
46
47func (s *BinaryFence) ImportTemporary(fd int) error {
48	info := vulkan.ImportSemaphoreFdInfoKHR{SType: vulkan.StructureTypeImportSemaphoreFDInfoKHR, Semaphore: s.Semaphore, Flags: vulkan.SemaphoreImportTemporaryBit, HandleType: vulkan.ExternalSemaphoreHandleTypeSyncFDBit, Fd: int32(fd)}
49	return vulkan.Check(s.Device.Dispatch.ImportSemaphoreFdKHR(s.Device.Logical, &info))
50}
51
52func (s *BinaryFence) Close() {
53	if s == nil || s.Semaphore == 0 {
54		return
55	}
56	s.Device.Dispatch.DestroySemaphore(s.Device.Logical, s.Semaphore, nil)
57	s.Semaphore = 0
58}
59
60// SubmitEmpty is a hardware probe for the fence bridge. The production
61// renderer must submit its draw command buffer instead of an empty submit.
62// The queue is idle before exporting so this test isolates FD interop from
63// in-flight rendering; it does not authorize a CPU-wait presentation fallback.
64func (d *Device) SubmitEmpty(signal *BinaryFence, wait *BinaryFence) error {
65	info := vulkan.SubmitInfo2{SType: vulkan.StructureTypeSubmitInfo2}
66	if signal != nil {
67		s := vulkan.SemaphoreSubmitInfo{SType: vulkan.StructureTypeSemaphoreSubmitInfo, Semaphore: signal.Semaphore, StageMask: vulkan.PipelineStage2AllCommandsBit}
68		info.SignalSemaphoreInfoCount = 1
69		info.SignalSemaphoreInfos = &s
70	}
71	if wait != nil {
72		w := vulkan.SemaphoreSubmitInfo{SType: vulkan.StructureTypeSemaphoreSubmitInfo, Semaphore: wait.Semaphore, StageMask: vulkan.PipelineStage2AllCommandsBit}
73		info.WaitSemaphoreInfoCount = 1
74		info.WaitSemaphoreInfos = &w
75	}
76	if err := vulkan.Check(d.Dispatch.QueueSubmit2(d.Queue, 1, &info, 0)); err != nil {
77		return fmt.Errorf("submit SYNC_FD semaphore: %w", err)
78	}
79	return vulkan.Check(d.Dispatch.QueueWaitIdle(d.Queue))
80}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 12

↑↓ moveenter openesc close