~emersion/go-drm

8e5be5ed85406cb0f3e906d4d6aaa3bae5a2452b — Simon Ser 3 months ago 2fc5fd8
Parse ARM modifiers
3 files changed, 118 insertions(+), 6 deletions(-)

M fourcc.go
M fourcc.py
M fourcc_generated.go
M fourcc.go => fourcc.go +72 -1
@@ 40,6 40,8 @@ func (mod Modifier) Name() string {
	switch mod.Vendor() {
	case ModifierVendorNVIDIA:
		name = modifierNameNVIDIA(uint64(mod))
	case ModifierVendorARM:
		name = modifierNameARM(uint64(mod))
	}
	if name != "" {
		return name


@@ 59,7 61,7 @@ func (mod Modifier) String() string {
}

func modifierNameNVIDIA(mod uint64) string {
	if mod & 0x10 == 0 {
	if mod&0x10 == 0 {
		return ""
	}



@@ 71,3 73,72 @@ func modifierNameNVIDIA(mod uint64) string {

	return fmt.Sprintf("NVIDIA_BLOCK_LINEAR_2D(h=%v, k=%v, g=%v, s=%v, c=%v)", h, k, g, s, c)
}

type (
	armModifierType uint64
	armAFBC         uint64
)

func modifierNameARM(mod uint64) string {
	typ := armModifierType((mod >> 52) & 0xF)
	value := mod & 0x000FFFFFFFFFFFFF

	switch typ {
	case armModifierTypeAFBC:
		blockSize := armAFBC(value) & armAFBC_BLOCK_SIZE_MASK

		props := []string{
			fmt.Sprintf("BLOCK_SIZE = %v", armAFBCBlockSizeStr(blockSize)),
		}

		if armAFBC(value)&armAFBC_YTR != 0 {
			props = append(props, "YTR")
		}
		if armAFBC(value)&armAFBC_SPLIT != 0 {
			props = append(props, "SPLIT")
		}
		if armAFBC(value)&armAFBC_SPARSE != 0 {
			props = append(props, "SPARSE")
		}
		if armAFBC(value)&armAFBC_CBR != 0 {
			props = append(props, "CBR")
		}
		if armAFBC(value)&armAFBC_TILED != 0 {
			props = append(props, "TILED")
		}
		if armAFBC(value)&armAFBC_SC != 0 {
			props = append(props, "SC")
		}
		if armAFBC(value)&armAFBC_DB != 0 {
			props = append(props, "DB")
		}
		if armAFBC(value)&armAFBC_BCH != 0 {
			props = append(props, "BCH")
		}
		if armAFBC(value)&armAFBC_USM != 0 {
			props = append(props, "USM")
		}

		return fmt.Sprintf("ARM_AFBC(%v)", strings.Join(props, ", "))
	case armModifierTypeMISC:
		// Simple modifiers handled by the fallback path
		return ""
	default:
		return ""
	}
}

func armAFBCBlockSizeStr(blockSize armAFBC) string {
	switch blockSize {
	case armAFBC_BLOCK_SIZE_16x16:
		return "16x16"
	case armAFBC_BLOCK_SIZE_32x8:
		return "32x8"
	case armAFBC_BLOCK_SIZE_64x4:
		return "64x4"
	case armAFBC_BLOCK_SIZE_32x8_64x4:
		return "32x8_64x4"
	default:
		return "unknown"
	}
}

M fourcc.py => fourcc.py +24 -5
@@ 24,6 24,8 @@ for flag in cflags:
if not found:
	raise Exception("Failed to find drm_fourcc.h in libdrm -I cflags")

prefixes = ["DRM_FORMAT_", "I915_FORMAT_", "AFBC_FORMAT_MOD_"]

ident_list = []
with open(fourcc_include) as input_file:
	for l in input_file.readlines():


@@ 31,11 33,19 @@ with open(fourcc_include) as input_file:
		if len(parts) < 3 or parts[0] != "#define":
			continue
		ident = parts[1]
		if not ident.startswith("DRM_FORMAT_") and not ident.startswith("I915_FORMAT_"):

		found = False
		for prefix in prefixes:
			if ident.startswith(prefix):
				found = True
				break
		if not found:
			continue

		if "(" in ident:
			# Some complicated formats use a macro with parameters
			continue

		ident_list.append(ident)

idents = {}


@@ 60,7 70,7 @@ with tempfile.TemporaryDirectory() as work_dir:
	for (i, l) in enumerate(output.splitlines()):
		idents[ident_list[i]] = l

types = ["Format", "ModifierVendor", "Modifier"]
types = ["Format", "ModifierVendor", "Modifier", "armModifierType", "armAFBC"]
words = ["none", "invalid", "linear"]
initialisms = ["AMD", "NVIDIA", "ARM"]



@@ 77,11 87,15 @@ for (ident, val) in idents.items():
		t = "Modifier"
		if ident.startswith("DRM_FORMAT_MOD_"):
			ident = ident[len("DRM_FORMAT_MOD_"):]
			if ident.startswith("VENDOR_"):
			if ident.startswith("ARM_TYPE_"):
				t = "armModifierType"
				ident = ident[len("ARM_TYPE_"):]
			elif ident.startswith("VENDOR_"):
				t = "ModifierVendor"
				ident = ident[len("VENDOR_"):]
			if ident.startswith("ARM_TYPE_"):
				continue
		elif ident.startswith("AFBC_FORMAT_MOD_"):
			t = "armAFBC"
			ident = ident[len("AFBC_FORMAT_MOD"):]
		else:
			parts = ident.split("_FORMAT_MOD_")
			assert(len(parts) == 2)


@@ 120,6 134,7 @@ for t, l in consts.items():
		out.append(cst)
	consts[t] = out

stringers = {"Format", "ModifierVendor", "Modifier"}
with open("fourcc_generated.go", "w+") as go_file:
	go_file.write('// Code generated by fourcc.py - DO NOT EDIT\n')
	go_file.write('// libdrm ' + version + '\n')


@@ 132,6 147,10 @@ with open("fourcc_generated.go", "w+") as go_file:
			go_file.write('\t' + cst["go_ident"] + ' ' + cst["type"] + ' = ' + cst["value"] + '\n')
		go_file.write(')\n')
		go_file.write('\n')

		if t not in stringers:
			continue

		go_file.write('func (v ' + t + ') str() string {\n')
		go_file.write('\tswitch v {\n')
		for cst in consts[t]:

M fourcc_generated.go => fourcc_generated.go +22 -0
@@ 470,3 470,25 @@ func (v Modifier) str() string {
		return ""
	}
}

const (
	armModifierTypeAFBC armModifierType = 0x0
	armModifierTypeMISC armModifierType = 0x1
)

const (
	armAFBC_BLOCK_SIZE_MASK      armAFBC = 0xF
	armAFBC_BLOCK_SIZE_16x16     armAFBC = 0x1
	armAFBC_BLOCK_SIZE_32x8      armAFBC = 0x2
	armAFBC_BLOCK_SIZE_64x4      armAFBC = 0x3
	armAFBC_BLOCK_SIZE_32x8_64x4 armAFBC = 0x4
	armAFBC_YTR                  armAFBC = 0x10
	armAFBC_SPLIT                armAFBC = 0x20
	armAFBC_SPARSE               armAFBC = 0x40
	armAFBC_CBR                  armAFBC = 0x80
	armAFBC_TILED                armAFBC = 0x100
	armAFBC_SC                   armAFBC = 0x200
	armAFBC_DB                   armAFBC = 0x400
	armAFBC_BCH                  armAFBC = 0x800
	armAFBC_USM                  armAFBC = 0x1000
)