v0.4.0 2de4e1d

modifier.go RawHistoryFolder

1//go:build linux
2
3package vkdevice
4
5import (
6	"fmt"
7	"unsafe"
8
9	"github.com/bnema/purego-vulkan/vulkan"
10	"github.com/bnema/wlturbo/protocol/linuxdmabuf"
11)
12
13// Modifier is the one-plane GPU/compositor common image layout chosen in
14// compositor tranche order. XRGB and ARGB both use B8G8R8A8_UNORM on Vulkan.
15type Modifier struct {
16	DRMFormat uint32
17	Value     uint64
18}
19
20const (
21	XRGB8888 uint32 = 0x34325258
22	ARGB8888 uint32 = 0x34325241
23)
24
25func ChooseModifier(tranches [][]linuxdmabuf.FormatEntry, transparent bool, supported map[uint64]bool) (Modifier, error) {
26	format := XRGB8888
27	if transparent {
28		format = ARGB8888
29	}
30	for _, tranche := range tranches {
31		for _, entry := range tranche {
32			if entry.Format == format && supported[entry.Modifier] {
33				return Modifier{format, entry.Modifier}, nil
34			}
35		}
36	}
37	return Modifier{}, fmt.Errorf("no one-plane exportable B8G8R8A8 modifier shared with compositor for DRM format %#x", format)
38}
39
40// ExportableModifiers checks the exact usage required by drawing and readback;
41// the presence of a modifier alone is not sufficient to allocate a DMA-BUF.
42func (d *Device) ExportableModifiers() (map[uint64]bool, error) {
43	props := vulkan.FormatProperties2{SType: vulkan.StructureTypeFormatProperties2}
44	mods := vulkan.DrmFormatModifierPropertiesList2EXT{SType: vulkan.StructureTypeDRMFormatModifierPropertiesList2EXT}
45	props.Next = unsafe.Pointer(&mods)
46	d.InstanceDispatch.GetPhysicalDeviceFormatProperties2(d.Physical, vulkan.FormatB8g8r8a8Unorm, &props)
47	out := make(map[uint64]bool)
48	if mods.DrmFormatModifierCount == 0 {
49		return out, nil
50	}
51	list := make([]vulkan.DrmFormatModifierProperties2EXT, mods.DrmFormatModifierCount)
52	mods.DrmFormatModifierProperties = &list[0]
53	d.InstanceDispatch.GetPhysicalDeviceFormatProperties2(d.Physical, vulkan.FormatB8g8r8a8Unorm, &props)
54	for _, m := range list[:mods.DrmFormatModifierCount] {
55		features := m.DrmFormatModifierTilingFeatures
56		if m.DrmFormatModifierPlaneCount != 1 || features&vulkan.FormatFeature2ColorAttachmentBit == 0 || features&vulkan.FormatFeature2TransferSrcBit == 0 {
57			continue
58		}
59		modifierInfo := vulkan.PhysicalDeviceImageDrmFormatModifierInfoEXT{SType: vulkan.StructureTypePhysicalDeviceImageDRMFormatModifierInfoEXT, DrmFormatModifier: m.DrmFormatModifier, SharingMode: vulkan.SharingModeExclusive}
60		externalInfo := vulkan.PhysicalDeviceExternalImageFormatInfo{SType: vulkan.StructureTypePhysicalDeviceExternalImageFormatInfo, Next: unsafe.Pointer(&modifierInfo), HandleType: vulkan.ExternalMemoryHandleTypeDMABUFBitEXT}
61		info := vulkan.PhysicalDeviceImageFormatInfo2{SType: vulkan.StructureTypePhysicalDeviceImageFormatInfo2, Next: unsafe.Pointer(&externalInfo), Format: vulkan.FormatB8g8r8a8Unorm, Type: vulkan.ImageType2d, Tiling: vulkan.ImageTilingDRMFormatModifierEXT, Usage: vulkan.ImageUsageColorAttachmentBit | vulkan.ImageUsageTransferSrcBit}
62		externalProps := vulkan.ExternalImageFormatProperties{SType: vulkan.StructureTypeExternalImageFormatProperties}
63		imageProps := vulkan.ImageFormatProperties2{SType: vulkan.StructureTypeImageFormatProperties2, Next: unsafe.Pointer(&externalProps)}
64		r := d.InstanceDispatch.GetPhysicalDeviceImageFormatProperties2(d.Physical, &info, &imageProps)
65		if r == vulkan.ErrorFormatNotSupported {
66			continue
67		}
68		if err := vulkan.Check(r); err != nil {
69			return nil, fmt.Errorf("query DRM modifier %#x: %w", m.DrmFormatModifier, err)
70		}
71		if externalProps.ExternalMemoryProperties.ExternalMemoryFeatures&vulkan.ExternalMemoryFeatureExportableBit != 0 {
72			out[m.DrmFormatModifier] = true
73		}
74	}
75	return out, nil
76}

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