v0.5.0 5fd5066

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

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