~emersion/go-drm

82ff1adfe302e1402b6ec27658d5b82a530506e9 — Simon Ser 1 year, 10 months ago 99d39c2
Generate fourcc constants from libdrm
4 files changed, 584 insertions(+), 67 deletions(-)

M const.go
A fourcc.go
A fourcc.py
A fourcc_generated.go
M const.go => const.go +0 -67
@@ 279,73 279,6 @@ func (s Subpixel) String() string {
	}
}

type Format uint32

const (
	FormatInvalid Format = 0
)

func (f Format) String() string {
	r1 := rune(uint32(f) & 0xFF)
	r2 := rune(uint32(f>>8) & 0xFF)
	r3 := rune(uint32(f>>16) & 0xFF)
	r4 := rune(uint32(f>>24) & 0xFF)
	return string([]rune{r1, r2, r3, r4})
}

type Modifier uint64

const (
	ModifierLinear  Modifier = 0
	ModifierInvalid Modifier = (1 << 56) - 1
)

func (mod Modifier) Vendor() ModifierVendor {
	return ModifierVendor(mod >> 56)
}

type ModifierVendor uint8

const (
	ModifierVendorNone      ModifierVendor = 0
	ModifierVendorIntel     ModifierVendor = 0x01
	ModifierVendorAMD       ModifierVendor = 0x02
	ModifierVendorNVIDIA    ModifierVendor = 0x03
	ModifierVendorSamsung   ModifierVendor = 0x04
	ModifierVendorQcom      ModifierVendor = 0x05
	ModifierVendorVivante   ModifierVendor = 0x06
	ModifierVendorBroadcom  ModifierVendor = 0x07
	ModifierVendorARM       ModifierVendor = 0x08
	ModifierVendorAllwinner ModifierVendor = 0x09
)

func (vendor ModifierVendor) String() string {
	switch vendor {
	case ModifierVendorNone:
		return "none"
	case ModifierVendorIntel:
		return "Intel"
	case ModifierVendorAMD:
		return "AMD"
	case ModifierVendorNVIDIA:
		return "NVIDIA"
	case ModifierVendorSamsung:
		return "Samsung"
	case ModifierVendorQcom:
		return "Qcom"
	case ModifierVendorVivante:
		return "Vivante"
	case ModifierVendorBroadcom:
		return "Broadcom"
	case ModifierVendorARM:
		return "ARM"
	case ModifierVendorAllwinner:
		return "Allwinner"
	default:
		return "unknown"
	}
}

type PlaneType uint32

const (

A fourcc.go => fourcc.go +13 -0
@@ 0,0 1,13 @@
package drm

//go:generate ./fourcc.py

type Format uint32

type ModifierVendor uint8

type Modifier uint64

func (mod Modifier) Vendor() ModifierVendor {
	return ModifierVendor(mod >> 56)
}

A fourcc.py => fourcc.py +123 -0
@@ 0,0 1,123 @@
#!/usr/bin/env python3

import os
import subprocess
import sys
import tempfile

cc = os.getenv("CC", "cc")
pkg_config = os.getenv("PKG_CONFIG", "pkg-config")

version = subprocess.check_output([pkg_config, "libdrm", "--modversion"]).decode().strip()
cflags = subprocess.check_output([pkg_config, "libdrm", "--cflags-only-I"]).decode().strip().split()
if not cflags[0].startswith("-I"):
	raise Exception("Expected one include dir for libdrm")
libdrm_include = cflags[0][2:]
fourcc_include = libdrm_include + "/drm_fourcc.h"

ident_list = []
with open(fourcc_include) as input_file:
	for l in input_file.readlines():
		parts = l.split()
		if len(parts) < 3 or parts[0] != "#define":
			continue
		ident = parts[1]
		if not ident.startswith("DRM_FORMAT_") and not ident.startswith("I915_FORMAT_"):
			continue
		if "(" in ident:
			# Some complicated formats use a macro with parameters
			continue
		ident_list.append(ident)

idents = {}
with tempfile.TemporaryDirectory() as work_dir:
	c_file_name = work_dir + "/main.c"
	exe_file_name = work_dir + "/main"

	with open(c_file_name, "w+") as c_file:
		c_file.write('#include <inttypes.h>\n')
		c_file.write('#include <stdint.h>\n')
		c_file.write('#include <stdio.h>\n')
		c_file.write('#include <drm_fourcc.h>\n')
		c_file.write('\n')
		c_file.write('int main(void) {\n')
		for ident in ident_list:
			c_file.write('printf("0x%" PRIX64 "\\n", (uint64_t)' + ident + ');\n')
		c_file.write('}\n')


	subprocess.check_call([cc, "-Wall", "-Wextra", "-o", exe_file_name, c_file_name] + cflags)
	output = subprocess.check_output([exe_file_name]).decode().strip()
	for (i, l) in enumerate(output.splitlines()):
		idents[ident_list[i]] = l

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

def to_camel_case(s):
	parts = s.split("_")
	for (i, part) in enumerate(parts):
		if not part in initialisms:
			parts[i] = part.lower().capitalize()
	return "".join(parts)

consts = []
for (ident, val) in idents.items():
	if "_MOD_" in ident:
		t = "Modifier"
		if ident.startswith("DRM_FORMAT_MOD_"):
			ident = ident[len("DRM_FORMAT_MOD_"):]
			if ident.startswith("VENDOR_"):
				t = "ModifierVendor"
				ident = ident[len("VENDOR_"):]
		else:
			parts = ident.split("_FORMAT_MOD_")
			assert(len(parts) == 2)
			ident = parts[0] + "_" + parts[1]
		if ident in ["NONE"]:
			continue
	elif ident.startswith("DRM_FORMAT_"):
		t = "Format"
		ident = ident[len("DRM_FORMAT_"):]
		if ident in ["BIG_ENDIAN", "RESERVED"]:
			continue
	else:
		assert(False)

	name = ident
	if ident.lower() in words:
		name = ident.lower()
	elif t == "ModifierVendor":
		name = to_camel_case(ident)

	if t == "ModifierVendor" or ident.lower() in words:
		ident = to_camel_case(ident)

	consts.append({"name": name, "go_ident": t + ident, "value": val, "type": t})

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')
	go_file.write('\n')
	go_file.write('package drm\n')
	for t in types:
		go_file.write('\n')
		go_file.write('const (\n')
		for cst in consts:
			if cst["type"] != t:
				continue
			go_file.write('\t' + cst["go_ident"] + ' ' + cst["type"] + ' = ' + cst["value"] + '\n')
		go_file.write(')\n')
		go_file.write('\n')
		go_file.write('func (v ' + t + ') String() string {\n')
		go_file.write('\tswitch v {\n')
		for cst in consts:
			if cst["type"] != t:
				continue
			go_file.write('\tcase ' + cst["go_ident"] + ':\n')
			go_file.write('\t\treturn "' + cst["name"] + '"\n')
		go_file.write('\tdefault:\n')
		go_file.write('\t\treturn "unknown"\n')
		go_file.write('\t}\n')
		go_file.write('}\n')

A fourcc_generated.go => fourcc_generated.go +448 -0
@@ 0,0 1,448 @@
// Code generated by fourcc.py - DO NOT EDIT
// libdrm 2.4.98

package drm

const (
	FormatInvalid Format = 0x0
	FormatC8 Format = 0x20203843
	FormatR8 Format = 0x20203852
	FormatR16 Format = 0x20363152
	FormatRG88 Format = 0x38384752
	FormatGR88 Format = 0x38385247
	FormatRG1616 Format = 0x32334752
	FormatGR1616 Format = 0x32335247
	FormatRGB332 Format = 0x38424752
	FormatBGR233 Format = 0x38524742
	FormatXRGB4444 Format = 0x32315258
	FormatXBGR4444 Format = 0x32314258
	FormatRGBX4444 Format = 0x32315852
	FormatBGRX4444 Format = 0x32315842
	FormatARGB4444 Format = 0x32315241
	FormatABGR4444 Format = 0x32314241
	FormatRGBA4444 Format = 0x32314152
	FormatBGRA4444 Format = 0x32314142
	FormatXRGB1555 Format = 0x35315258
	FormatXBGR1555 Format = 0x35314258
	FormatRGBX5551 Format = 0x35315852
	FormatBGRX5551 Format = 0x35315842
	FormatARGB1555 Format = 0x35315241
	FormatABGR1555 Format = 0x35314241
	FormatRGBA5551 Format = 0x35314152
	FormatBGRA5551 Format = 0x35314142
	FormatRGB565 Format = 0x36314752
	FormatBGR565 Format = 0x36314742
	FormatRGB888 Format = 0x34324752
	FormatBGR888 Format = 0x34324742
	FormatXRGB8888 Format = 0x34325258
	FormatXBGR8888 Format = 0x34324258
	FormatRGBX8888 Format = 0x34325852
	FormatBGRX8888 Format = 0x34325842
	FormatARGB8888 Format = 0x34325241
	FormatABGR8888 Format = 0x34324241
	FormatRGBA8888 Format = 0x34324152
	FormatBGRA8888 Format = 0x34324142
	FormatXRGB2101010 Format = 0x30335258
	FormatXBGR2101010 Format = 0x30334258
	FormatRGBX1010102 Format = 0x30335852
	FormatBGRX1010102 Format = 0x30335842
	FormatARGB2101010 Format = 0x30335241
	FormatABGR2101010 Format = 0x30334241
	FormatRGBA1010102 Format = 0x30334152
	FormatBGRA1010102 Format = 0x30334142
	FormatXRGB16161616F Format = 0x48345258
	FormatXBGR16161616F Format = 0x48344258
	FormatARGB16161616F Format = 0x48345241
	FormatABGR16161616F Format = 0x48344241
	FormatYUYV Format = 0x56595559
	FormatYVYU Format = 0x55595659
	FormatUYVY Format = 0x59565955
	FormatVYUY Format = 0x59555956
	FormatAYUV Format = 0x56555941
	FormatXYUV8888 Format = 0x56555958
	FormatVUY888 Format = 0x34325556
	FormatVUY101010 Format = 0x30335556
	FormatY210 Format = 0x30313259
	FormatY212 Format = 0x32313259
	FormatY216 Format = 0x36313259
	FormatY410 Format = 0x30313459
	FormatY412 Format = 0x32313459
	FormatY416 Format = 0x36313459
	FormatXVYU2101010 Format = 0x30335658
	FormatXVYU12_16161616 Format = 0x36335658
	FormatXVYU16161616 Format = 0x38345658
	FormatY0L0 Format = 0x304C3059
	FormatX0L0 Format = 0x304C3058
	FormatY0L2 Format = 0x324C3059
	FormatX0L2 Format = 0x324C3058
	FormatYUV420_8BIT Format = 0x38305559
	FormatYUV420_10BIT Format = 0x30315559
	FormatXRGB8888_A8 Format = 0x38415258
	FormatXBGR8888_A8 Format = 0x38414258
	FormatRGBX8888_A8 Format = 0x38415852
	FormatBGRX8888_A8 Format = 0x38415842
	FormatRGB888_A8 Format = 0x38413852
	FormatBGR888_A8 Format = 0x38413842
	FormatRGB565_A8 Format = 0x38413552
	FormatBGR565_A8 Format = 0x38413542
	FormatNV12 Format = 0x3231564E
	FormatNV21 Format = 0x3132564E
	FormatNV16 Format = 0x3631564E
	FormatNV61 Format = 0x3136564E
	FormatNV24 Format = 0x3432564E
	FormatNV42 Format = 0x3234564E
	FormatP210 Format = 0x30313250
	FormatP010 Format = 0x30313050
	FormatP012 Format = 0x32313050
	FormatP016 Format = 0x36313050
	FormatYUV410 Format = 0x39565559
	FormatYVU410 Format = 0x39555659
	FormatYUV411 Format = 0x31315559
	FormatYVU411 Format = 0x31315659
	FormatYUV420 Format = 0x32315559
	FormatYVU420 Format = 0x32315659
	FormatYUV422 Format = 0x36315559
	FormatYVU422 Format = 0x36315659
	FormatYUV444 Format = 0x34325559
	FormatYVU444 Format = 0x34325659
)

func (v Format) String() string {
	switch v {
	case FormatInvalid:
		return "invalid"
	case FormatC8:
		return "C8"
	case FormatR8:
		return "R8"
	case FormatR16:
		return "R16"
	case FormatRG88:
		return "RG88"
	case FormatGR88:
		return "GR88"
	case FormatRG1616:
		return "RG1616"
	case FormatGR1616:
		return "GR1616"
	case FormatRGB332:
		return "RGB332"
	case FormatBGR233:
		return "BGR233"
	case FormatXRGB4444:
		return "XRGB4444"
	case FormatXBGR4444:
		return "XBGR4444"
	case FormatRGBX4444:
		return "RGBX4444"
	case FormatBGRX4444:
		return "BGRX4444"
	case FormatARGB4444:
		return "ARGB4444"
	case FormatABGR4444:
		return "ABGR4444"
	case FormatRGBA4444:
		return "RGBA4444"
	case FormatBGRA4444:
		return "BGRA4444"
	case FormatXRGB1555:
		return "XRGB1555"
	case FormatXBGR1555:
		return "XBGR1555"
	case FormatRGBX5551:
		return "RGBX5551"
	case FormatBGRX5551:
		return "BGRX5551"
	case FormatARGB1555:
		return "ARGB1555"
	case FormatABGR1555:
		return "ABGR1555"
	case FormatRGBA5551:
		return "RGBA5551"
	case FormatBGRA5551:
		return "BGRA5551"
	case FormatRGB565:
		return "RGB565"
	case FormatBGR565:
		return "BGR565"
	case FormatRGB888:
		return "RGB888"
	case FormatBGR888:
		return "BGR888"
	case FormatXRGB8888:
		return "XRGB8888"
	case FormatXBGR8888:
		return "XBGR8888"
	case FormatRGBX8888:
		return "RGBX8888"
	case FormatBGRX8888:
		return "BGRX8888"
	case FormatARGB8888:
		return "ARGB8888"
	case FormatABGR8888:
		return "ABGR8888"
	case FormatRGBA8888:
		return "RGBA8888"
	case FormatBGRA8888:
		return "BGRA8888"
	case FormatXRGB2101010:
		return "XRGB2101010"
	case FormatXBGR2101010:
		return "XBGR2101010"
	case FormatRGBX1010102:
		return "RGBX1010102"
	case FormatBGRX1010102:
		return "BGRX1010102"
	case FormatARGB2101010:
		return "ARGB2101010"
	case FormatABGR2101010:
		return "ABGR2101010"
	case FormatRGBA1010102:
		return "RGBA1010102"
	case FormatBGRA1010102:
		return "BGRA1010102"
	case FormatXRGB16161616F:
		return "XRGB16161616F"
	case FormatXBGR16161616F:
		return "XBGR16161616F"
	case FormatARGB16161616F:
		return "ARGB16161616F"
	case FormatABGR16161616F:
		return "ABGR16161616F"
	case FormatYUYV:
		return "YUYV"
	case FormatYVYU:
		return "YVYU"
	case FormatUYVY:
		return "UYVY"
	case FormatVYUY:
		return "VYUY"
	case FormatAYUV:
		return "AYUV"
	case FormatXYUV8888:
		return "XYUV8888"
	case FormatVUY888:
		return "VUY888"
	case FormatVUY101010:
		return "VUY101010"
	case FormatY210:
		return "Y210"
	case FormatY212:
		return "Y212"
	case FormatY216:
		return "Y216"
	case FormatY410:
		return "Y410"
	case FormatY412:
		return "Y412"
	case FormatY416:
		return "Y416"
	case FormatXVYU2101010:
		return "XVYU2101010"
	case FormatXVYU12_16161616:
		return "XVYU12_16161616"
	case FormatXVYU16161616:
		return "XVYU16161616"
	case FormatY0L0:
		return "Y0L0"
	case FormatX0L0:
		return "X0L0"
	case FormatY0L2:
		return "Y0L2"
	case FormatX0L2:
		return "X0L2"
	case FormatYUV420_8BIT:
		return "YUV420_8BIT"
	case FormatYUV420_10BIT:
		return "YUV420_10BIT"
	case FormatXRGB8888_A8:
		return "XRGB8888_A8"
	case FormatXBGR8888_A8:
		return "XBGR8888_A8"
	case FormatRGBX8888_A8:
		return "RGBX8888_A8"
	case FormatBGRX8888_A8:
		return "BGRX8888_A8"
	case FormatRGB888_A8:
		return "RGB888_A8"
	case FormatBGR888_A8:
		return "BGR888_A8"
	case FormatRGB565_A8:
		return "RGB565_A8"
	case FormatBGR565_A8:
		return "BGR565_A8"
	case FormatNV12:
		return "NV12"
	case FormatNV21:
		return "NV21"
	case FormatNV16:
		return "NV16"
	case FormatNV61:
		return "NV61"
	case FormatNV24:
		return "NV24"
	case FormatNV42:
		return "NV42"
	case FormatP210:
		return "P210"
	case FormatP010:
		return "P010"
	case FormatP012:
		return "P012"
	case FormatP016:
		return "P016"
	case FormatYUV410:
		return "YUV410"
	case FormatYVU410:
		return "YVU410"
	case FormatYUV411:
		return "YUV411"
	case FormatYVU411:
		return "YVU411"
	case FormatYUV420:
		return "YUV420"
	case FormatYVU420:
		return "YVU420"
	case FormatYUV422:
		return "YUV422"
	case FormatYVU422:
		return "YVU422"
	case FormatYUV444:
		return "YUV444"
	case FormatYVU444:
		return "YVU444"
	default:
		return "unknown"
	}
}

const (
	ModifierVendorIntel ModifierVendor = 0x1
	ModifierVendorAMD ModifierVendor = 0x2
	ModifierVendorNVIDIA ModifierVendor = 0x3
	ModifierVendorSamsung ModifierVendor = 0x4
	ModifierVendorQcom ModifierVendor = 0x5
	ModifierVendorVivante ModifierVendor = 0x6
	ModifierVendorBroadcom ModifierVendor = 0x7
	ModifierVendorARM ModifierVendor = 0x8
	ModifierVendorAllwinner ModifierVendor = 0x9
)

func (v ModifierVendor) String() string {
	switch v {
	case ModifierVendorIntel:
		return "Intel"
	case ModifierVendorAMD:
		return "AMD"
	case ModifierVendorNVIDIA:
		return "NVIDIA"
	case ModifierVendorSamsung:
		return "Samsung"
	case ModifierVendorQcom:
		return "Qcom"
	case ModifierVendorVivante:
		return "Vivante"
	case ModifierVendorBroadcom:
		return "Broadcom"
	case ModifierVendorARM:
		return "ARM"
	case ModifierVendorAllwinner:
		return "Allwinner"
	default:
		return "unknown"
	}
}

const (
	ModifierInvalid Modifier = 0xFFFFFFFFFFFFFF
	ModifierLinear Modifier = 0x0
	ModifierI915_X_TILED Modifier = 0x100000000000001
	ModifierI915_Y_TILED Modifier = 0x100000000000002
	ModifierI915_Yf_TILED Modifier = 0x100000000000003
	ModifierI915_Y_TILED_CCS Modifier = 0x100000000000004
	ModifierI915_Yf_TILED_CCS Modifier = 0x100000000000005
	ModifierSAMSUNG_64_32_TILE Modifier = 0x400000000000001
	ModifierSAMSUNG_16_16_TILE Modifier = 0x400000000000002
	ModifierQCOM_COMPRESSED Modifier = 0x500000000000001
	ModifierVIVANTE_TILED Modifier = 0x600000000000001
	ModifierVIVANTE_SUPER_TILED Modifier = 0x600000000000002
	ModifierVIVANTE_SPLIT_TILED Modifier = 0x600000000000003
	ModifierVIVANTE_SPLIT_SUPER_TILED Modifier = 0x600000000000004
	ModifierNVIDIA_TEGRA_TILED Modifier = 0x300000000000001
	ModifierNVIDIA_16BX2_BLOCK_ONE_GOB Modifier = 0x300000000000010
	ModifierNVIDIA_16BX2_BLOCK_TWO_GOB Modifier = 0x300000000000011
	ModifierNVIDIA_16BX2_BLOCK_FOUR_GOB Modifier = 0x300000000000012
	ModifierNVIDIA_16BX2_BLOCK_EIGHT_GOB Modifier = 0x300000000000013
	ModifierNVIDIA_16BX2_BLOCK_SIXTEEN_GOB Modifier = 0x300000000000014
	ModifierNVIDIA_16BX2_BLOCK_THIRTYTWO_GOB Modifier = 0x300000000000015
	ModifierBROADCOM_VC4_T_TILED Modifier = 0x700000000000001
	ModifierBROADCOM_SAND32 Modifier = 0x700000000000002
	ModifierBROADCOM_SAND64 Modifier = 0x700000000000003
	ModifierBROADCOM_SAND128 Modifier = 0x700000000000004
	ModifierBROADCOM_SAND256 Modifier = 0x700000000000005
	ModifierBROADCOM_UIF Modifier = 0x700000000000006
	ModifierALLWINNER_TILED Modifier = 0x900000000000001
)

func (v Modifier) String() string {
	switch v {
	case ModifierInvalid:
		return "invalid"
	case ModifierLinear:
		return "linear"
	case ModifierI915_X_TILED:
		return "I915_X_TILED"
	case ModifierI915_Y_TILED:
		return "I915_Y_TILED"
	case ModifierI915_Yf_TILED:
		return "I915_Yf_TILED"
	case ModifierI915_Y_TILED_CCS:
		return "I915_Y_TILED_CCS"
	case ModifierI915_Yf_TILED_CCS:
		return "I915_Yf_TILED_CCS"
	case ModifierSAMSUNG_64_32_TILE:
		return "SAMSUNG_64_32_TILE"
	case ModifierSAMSUNG_16_16_TILE:
		return "SAMSUNG_16_16_TILE"
	case ModifierQCOM_COMPRESSED:
		return "QCOM_COMPRESSED"
	case ModifierVIVANTE_TILED:
		return "VIVANTE_TILED"
	case ModifierVIVANTE_SUPER_TILED:
		return "VIVANTE_SUPER_TILED"
	case ModifierVIVANTE_SPLIT_TILED:
		return "VIVANTE_SPLIT_TILED"
	case ModifierVIVANTE_SPLIT_SUPER_TILED:
		return "VIVANTE_SPLIT_SUPER_TILED"
	case ModifierNVIDIA_TEGRA_TILED:
		return "NVIDIA_TEGRA_TILED"
	case ModifierNVIDIA_16BX2_BLOCK_ONE_GOB:
		return "NVIDIA_16BX2_BLOCK_ONE_GOB"
	case ModifierNVIDIA_16BX2_BLOCK_TWO_GOB:
		return "NVIDIA_16BX2_BLOCK_TWO_GOB"
	case ModifierNVIDIA_16BX2_BLOCK_FOUR_GOB:
		return "NVIDIA_16BX2_BLOCK_FOUR_GOB"
	case ModifierNVIDIA_16BX2_BLOCK_EIGHT_GOB:
		return "NVIDIA_16BX2_BLOCK_EIGHT_GOB"
	case ModifierNVIDIA_16BX2_BLOCK_SIXTEEN_GOB:
		return "NVIDIA_16BX2_BLOCK_SIXTEEN_GOB"
	case ModifierNVIDIA_16BX2_BLOCK_THIRTYTWO_GOB:
		return "NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB"
	case ModifierBROADCOM_VC4_T_TILED:
		return "BROADCOM_VC4_T_TILED"
	case ModifierBROADCOM_SAND32:
		return "BROADCOM_SAND32"
	case ModifierBROADCOM_SAND64:
		return "BROADCOM_SAND64"
	case ModifierBROADCOM_SAND128:
		return "BROADCOM_SAND128"
	case ModifierBROADCOM_SAND256:
		return "BROADCOM_SAND256"
	case ModifierBROADCOM_UIF:
		return "BROADCOM_UIF"
	case ModifierALLWINNER_TILED:
		return "ALLWINNER_TILED"
	default:
		return "unknown"
	}
}