mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-26 03:48:12 +02:00
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41664>
245 lines
8.3 KiB
Python
245 lines
8.3 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (C) 2026 Valve Corporation
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import sys
|
|
import xml.etree.ElementTree as ET
|
|
|
|
from enum import Enum
|
|
from mako.template import Template
|
|
|
|
class DrircOptionType(Enum):
|
|
BOOL = 0,
|
|
INT = 1,
|
|
UINT64 = 2,
|
|
FLOAT = 3,
|
|
STRING = 4,
|
|
STRING_NODEF = 5,
|
|
ENUM = 6,
|
|
|
|
type_to_ctype: dict[DrircOptionType, str] = {
|
|
DrircOptionType.BOOL: "bool",
|
|
DrircOptionType.INT: "int",
|
|
DrircOptionType.UINT64: "uint64_t",
|
|
DrircOptionType.FLOAT: "float",
|
|
DrircOptionType.STRING: "char *",
|
|
DrircOptionType.STRING_NODEF: "char *",
|
|
DrircOptionType.ENUM: "int",
|
|
}
|
|
|
|
type_to_macro: dict[DrircOptionType, str] = {
|
|
DrircOptionType.BOOL: "DRI_CONF_OPT_B",
|
|
DrircOptionType.INT: "DRI_CONF_OPT_I",
|
|
DrircOptionType.UINT64: "DRI_CONF_OPT_U64",
|
|
DrircOptionType.FLOAT: "DRI_CONF_OPT_F",
|
|
DrircOptionType.STRING: "DRI_CONF_OPT_S",
|
|
DrircOptionType.STRING_NODEF: "DRI_CONF_OPT_S_NODEF",
|
|
DrircOptionType.ENUM: "DRI_CONF_OPT_E",
|
|
}
|
|
|
|
type_to_queryfn: dict[DrircOptionType, str] = {
|
|
DrircOptionType.BOOL: "driQueryOptionb",
|
|
DrircOptionType.INT: "driQueryOptioni",
|
|
DrircOptionType.UINT64: "driQueryOptionu64",
|
|
DrircOptionType.FLOAT: "driQueryOptionf",
|
|
DrircOptionType.STRING: "driQueryOptionstr",
|
|
DrircOptionType.STRING_NODEF: "driQueryOptionstr",
|
|
DrircOptionType.ENUM: "driQueryOptioni",
|
|
}
|
|
|
|
class DrircOption(object):
|
|
def __init__(self, dtype, name, description, c_name):
|
|
self.dtype = dtype
|
|
self.name = name
|
|
self.description = description
|
|
self.c_name = c_name
|
|
self.c_args = []
|
|
|
|
class DrircBool(DrircOption):
|
|
def __init__(self, name, value, description="", c_name=None):
|
|
super().__init__(DrircOptionType.BOOL, name, description, c_name)
|
|
self.value = value
|
|
self.c_args = ["true" if value else "false", f"\"{self.description}\""]
|
|
|
|
class DrircInt(DrircOption):
|
|
def __init__(self, name, value, min_value, max_value, description="", c_name=None):
|
|
super().__init__(DrircOptionType.INT, name, description, c_name)
|
|
self.value = value
|
|
self.min_value = min_value
|
|
self.max_value = max_value
|
|
self.c_args = [f"{value}", f"{min_value}", f"{max_value}", f"\"{self.description}\""]
|
|
|
|
class DrircUint64(DrircOption):
|
|
def __init__(self, name, value, min_value, max_value, description="", c_name=None):
|
|
super().__init__(DrircOptionType.UINT64, name, description, c_name)
|
|
self.value = value
|
|
self.min_value = min_value
|
|
self.max_value = max_value
|
|
self.c_args = [f"{value}", f"{min_value}", f"{max_value}", f"\"{self.description}\""]
|
|
|
|
class DrircFloat(DrircOption):
|
|
def __init__(self, name, value, min_value, max_value, description="", c_name=None):
|
|
super().__init__(DrircOptionType.FLOAT, name, description, c_name)
|
|
self.value = value
|
|
self.min_value = min_value
|
|
self.max_value = max_value
|
|
self.c_args = [f"{value}", f"{min_value}", f"{max_value}", f"\"{self.description}\""]
|
|
|
|
class DrircString(DrircOption):
|
|
def __init__(self, name, value=None, description="", c_name=None):
|
|
dtype = DrircOptionType.STRING if value is not None else DrircOptionType.STRING_NODEF
|
|
super().__init__(dtype, name, description, c_name)
|
|
self.value = value
|
|
if value is not None:
|
|
self.c_args = [f'"{value}"', f'"{self.description}"']
|
|
else:
|
|
self.c_args = [f'"{self.description}"']
|
|
|
|
class DrircEnumValue(object):
|
|
def __init__(self, value, description=""):
|
|
self.value = value
|
|
self.description = description
|
|
|
|
class DrircEnum(DrircOption):
|
|
def __init__(self, name, value, min_value, max_value, values, description="", c_name=None):
|
|
super().__init__(DrircOptionType.ENUM, name, description, c_name)
|
|
self.values = values
|
|
self.value = value
|
|
self.min_value = min_value
|
|
self.max_value = max_value
|
|
self.c_args = [f"{value}", f"{min_value}", f"{min_value}", f"\"{self.description}\""]
|
|
vals = []
|
|
for v in values:
|
|
vals.append(f"DRI_CONF_ENUM({v.value}, \"{v.description}\")")
|
|
self.c_args.append(''.join(vals))
|
|
|
|
class DrircSection(object):
|
|
"""Class that represents a DRIRC section
|
|
"""
|
|
def __init__(self, name, options=[], c_name=None):
|
|
"""Parameters:
|
|
|
|
- options: list of DrircOption
|
|
"""
|
|
self.name = name
|
|
self.options = options
|
|
self.c_name = c_name if c_name is not None else name.lower()
|
|
|
|
|
|
TEMPLATE_H = """\
|
|
/* This file is autogenerated. Do not edit. */
|
|
|
|
#ifndef ${driver_prefix.upper()}_DRIRC_H
|
|
#define ${driver_prefix.upper()}_DRIRC_H
|
|
|
|
#include "util/driconf.h"
|
|
|
|
struct ${driver_prefix}_drirc {
|
|
struct driOptionCache options;
|
|
struct driOptionCache available_options;
|
|
|
|
% for section in sections:
|
|
struct {
|
|
% for option in section.options:
|
|
% if option.c_name is not None:
|
|
${type_to_ctype(option.dtype)} ${option.c_name};
|
|
% endif
|
|
% endfor
|
|
} ${section.c_name};
|
|
% endfor
|
|
};
|
|
|
|
void ${driver_prefix}_parse_dri_options(struct ${driver_prefix}_drirc *drirc,
|
|
const driConfigFileParseParams *params);
|
|
|
|
#endif /* ${driver_prefix.upper()}_DRIRC_H */
|
|
"""
|
|
|
|
TEMPLATE_C = """\
|
|
/* This file is autogenerated. Do not edit. */
|
|
|
|
#include "${include_file}"
|
|
|
|
static const driOptionDescription dri_options[] = {
|
|
% for section in sections:
|
|
DRI_CONF_SECTION("${section.name}")
|
|
% for option in section.options:
|
|
${type_to_macro(option.dtype)}(${option.name}
|
|
% for arg in option.c_args:
|
|
, ${arg}
|
|
% endfor
|
|
)
|
|
% endfor
|
|
DRI_CONF_SECTION_END
|
|
% endfor
|
|
};
|
|
|
|
void
|
|
${driver_prefix}_parse_dri_options(struct ${driver_prefix}_drirc *drirc,
|
|
const driConfigFileParseParams *params)
|
|
{
|
|
driParseOptionInfo(&drirc->available_options, dri_options, ARRAY_SIZE(dri_options));
|
|
driParseConfigFiles(&drirc->options, &drirc->available_options, params);
|
|
|
|
% for section in sections:
|
|
% for option in section.options:
|
|
% if option.c_name is not None:
|
|
drirc->${section.c_name}.${option.c_name} = ${type_to_queryfn(option.dtype)}(&drirc->options, "${option.name}");
|
|
% endif
|
|
% endfor
|
|
% endfor
|
|
}
|
|
"""
|
|
|
|
def drirc_validate(conf_paths, sections, driver=None):
|
|
declared = {opt.name for section in sections for opt in section.options}
|
|
conf_names = set()
|
|
for conf_path in conf_paths:
|
|
tree = ET.parse(conf_path)
|
|
if driver is None:
|
|
for option in tree.iter('option'):
|
|
name = option.get('name')
|
|
if name:
|
|
conf_names.add(name)
|
|
else:
|
|
for device in tree.iter('device'):
|
|
if device.get('driver') != driver:
|
|
continue
|
|
for option in device.iter('option'):
|
|
name = option.get('name')
|
|
if name:
|
|
conf_names.add(name)
|
|
missing = conf_names - declared
|
|
if missing:
|
|
print('ERROR: options used in conf but not declared:', file=sys.stderr)
|
|
for name in sorted(missing):
|
|
print(f' {name}', file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def drirc_generate(cpath, hpath, driver_prefix, sections):
|
|
environment = {
|
|
'driver_prefix': driver_prefix,
|
|
'sections': sections,
|
|
'type_to_ctype': lambda dtype: type_to_ctype[dtype],
|
|
'type_to_macro': lambda dtype: type_to_macro[dtype],
|
|
'type_to_queryfn': lambda dtype: type_to_queryfn[dtype],
|
|
'include_file': os.path.basename(hpath),
|
|
}
|
|
|
|
with open(cpath, 'w', encoding='utf-8') as f:
|
|
try:
|
|
result = f.write(Template(TEMPLATE_C).render(**environment))
|
|
except Exception:
|
|
from mako import exceptions
|
|
print(exceptions.text_error_template().render(), file=sys.stderr)
|
|
sys.exit(1)
|
|
with open(hpath, 'w', encoding='utf-8') as f:
|
|
try:
|
|
result = f.write(Template(TEMPLATE_H).render(**environment))
|
|
except Exception:
|
|
from mako import exceptions
|
|
print(exceptions.text_error_template().render(), file=sys.stderr)
|
|
sys.exit(1)
|