package drm
//go:generate ./fourcc.py
import (
"fmt"
"strings"
)
type Format uint32
func (f Format) Name() string {
if name := f.str(); name != "" {
return name
}
return "unknown"
}
func (f Format) String() string {
return fmt.Sprintf("%s (0x%X)", f.Name(), uint32(f))
}
type ModifierVendor uint8
func (vendor ModifierVendor) String() string {
if name := vendor.str(); name != "" {
return name
}
return "unknown"
}
type Modifier uint64
func (mod Modifier) Vendor() ModifierVendor {
return ModifierVendor(mod >> 56)
}
func (mod Modifier) Name() string {
var name string
switch mod.Vendor() {
case ModifierVendorNVIDIA:
name = modifierNameNVIDIA(uint64(mod))
case ModifierVendorARM:
name = modifierNameARM(uint64(mod))
case ModifierVendorAmlogic:
name = modifierNameAmlogic(uint64(mod))
}
if name != "" {
return name
}
if name := mod.str(); name != "" {
return name
}
if vendor := mod.Vendor().str(); vendor != "" {
return fmt.Sprintf("%s(unknown)", strings.ToUpper(vendor))
}
return "unknown"
}
func (mod Modifier) String() string {
return fmt.Sprintf("%s (0x%X)", mod.Name(), uint64(mod))
}
func modifierNameNVIDIA(mod uint64) string {
if mod&0x10 == 0 {
return ""
}
h := mod & 0xF
k := (mod >> 12) & 0xFF
g := (mod >> 20) & 0x3
s := (mod >> 22) & 0x1
c := (mod >> 23) & 0x7
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"
}
}
type (
amlogicFBCLayout uint64
amlogicFBCOption uint64
)
func modifierNameAmlogic(mod uint64) string {
layout := amlogicFBCLayout(mod & 0xFF)
options := amlogicFBCOption((mod >> 8) & 0xFF)
return fmt.Sprintf("AMLOGIC_FBC(layout = %v, options = %v)", amlogicFBCLayoutStr(layout), amlogicFBCOptionsStr(options))
}
func amlogicFBCLayoutStr(layout amlogicFBCLayout) string {
switch layout {
case amlogicFBCLayoutBASIC:
return "BASIC"
case amlogicFBCLayoutSCATTER:
return "SCATTER"
default:
return "unknown"
}
}
func amlogicFBCOptionsStr(options amlogicFBCOption) string {
if options == 0 {
return "0"
}
if options == amlogicFBCOptionMEM_SAVING {
return "MEM_SAVING"
}
return "unknown"
}