driconf: Make the driver's declarations be structs instead of XML.
We can generate the XML if anybody actually queries it, but this reduces the amount of work in driver setup and means that we'll be able to support driconf option queries on Android without libexpat. This updates the driconf interface struct version for i965, i915, and radeon to use the new getXml entrypoint to call the on-demand xml generation. Note that our loaders (egl, glx) implement the v2 function interface and don't use .xml when that's set, and the X server doesn't use this interface at all. XML generation tested on iris and i965 using adriconf Acked-by: Eric Engestrom <eric@engestrom.ch> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6916>
This commit is contained in:
@@ -606,8 +606,7 @@ radv_handle_per_app_options(struct radv_instance *instance,
|
||||
instance->debug_flags |= RADV_DEBUG_NO_DYNAMIC_BOUNDS;
|
||||
}
|
||||
|
||||
static const char radv_dri_options_xml[] =
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription radv_dri_options[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_ADAPTIVE_SYNC("true")
|
||||
DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
|
||||
@@ -623,11 +622,11 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_OVERRIDE_VRAM_SIZE()
|
||||
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST("false")
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
};
|
||||
|
||||
static void radv_init_dri_options(struct radv_instance *instance)
|
||||
{
|
||||
driParseOptionInfo(&instance->available_dri_options, radv_dri_options_xml);
|
||||
driParseOptionInfo(&instance->available_dri_options, radv_dri_options, ARRAY_SIZE(radv_dri_options));
|
||||
driParseConfigFiles(&instance->dri_options,
|
||||
&instance->available_dri_options,
|
||||
0, "radv", NULL,
|
||||
|
@@ -51,9 +51,9 @@ static int (*backends[])(struct pipe_loader_device **, int) = {
|
||||
&pipe_loader_sw_probe
|
||||
};
|
||||
|
||||
const char gallium_driinfo_xml[] =
|
||||
const driOptionDescription gallium_driconf[] = {
|
||||
#include "driinfo_gallium.h"
|
||||
;
|
||||
};
|
||||
|
||||
int
|
||||
pipe_loader_probe(struct pipe_loader_device **devs, int ndev)
|
||||
@@ -85,45 +85,62 @@ pipe_loader_base_release(struct pipe_loader_device **dev)
|
||||
*dev = NULL;
|
||||
}
|
||||
|
||||
static driOptionDescription *
|
||||
merge_driconf(const driOptionDescription *driver_driconf, unsigned driver_count,
|
||||
unsigned *merged_count)
|
||||
{
|
||||
unsigned gallium_count = ARRAY_SIZE(gallium_driconf);
|
||||
driOptionDescription *merged = malloc((driver_count + gallium_count) *
|
||||
sizeof(*merged));
|
||||
if (!merged) {
|
||||
*merged_count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(merged, gallium_driconf, sizeof(*merged) * gallium_count);
|
||||
memcpy(&merged[gallium_count], driver_driconf, sizeof(*merged) * driver_count);
|
||||
|
||||
*merged_count = driver_count + gallium_count;
|
||||
return merged;
|
||||
}
|
||||
|
||||
void
|
||||
pipe_loader_load_options(struct pipe_loader_device *dev)
|
||||
{
|
||||
if (dev->option_info.info)
|
||||
return;
|
||||
|
||||
const char *driver_xml = dev->ops->get_driconf_xml(dev);
|
||||
unsigned driver_count, merged_count;
|
||||
const driOptionDescription *driver_driconf =
|
||||
dev->ops->get_driconf(dev, &driver_count);
|
||||
|
||||
char *xml_options;
|
||||
int ret = asprintf(&xml_options, "%s%s%s%s",
|
||||
DRI_CONF_BEGIN,
|
||||
gallium_driinfo_xml,
|
||||
driver_xml ? driver_xml : "",
|
||||
DRI_CONF_END);
|
||||
if (ret >= 0) {
|
||||
driParseOptionInfo(&dev->option_info, xml_options);
|
||||
driParseConfigFiles(&dev->option_cache, &dev->option_info, 0,
|
||||
dev->driver_name, NULL, NULL, 0, NULL, 0);
|
||||
free(xml_options);
|
||||
}
|
||||
const driOptionDescription *merged_driconf =
|
||||
merge_driconf(driver_driconf, driver_count, &merged_count);
|
||||
|
||||
driParseOptionInfo(&dev->option_info, merged_driconf, merged_count);
|
||||
driParseConfigFiles(&dev->option_cache, &dev->option_info, 0,
|
||||
dev->driver_name, NULL, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
char *
|
||||
pipe_loader_get_driinfo_xml(const char *driver_name)
|
||||
{
|
||||
unsigned driver_count = 0;
|
||||
const driOptionDescription *driver_driconf = NULL;
|
||||
|
||||
#ifdef HAVE_LIBDRM
|
||||
char *driver_xml = pipe_loader_drm_get_driinfo_xml(driver_name);
|
||||
#else
|
||||
char *driver_xml = NULL;
|
||||
driver_driconf = pipe_loader_drm_get_driconf_by_name(driver_name,
|
||||
&driver_count);
|
||||
#endif
|
||||
|
||||
char *xml;
|
||||
int ret = asprintf(&xml, "%s%s%s%s",
|
||||
DRI_CONF_BEGIN,
|
||||
gallium_driinfo_xml,
|
||||
driver_xml ? driver_xml : "",
|
||||
DRI_CONF_END);
|
||||
if (ret < 0)
|
||||
xml = NULL;
|
||||
unsigned merged_count;
|
||||
const driOptionDescription *merged_driconf =
|
||||
merge_driconf(driver_driconf, driver_count, &merged_count);
|
||||
free((void *)driver_driconf);
|
||||
|
||||
char *xml = driGetOptionsXml(merged_driconf, merged_count);
|
||||
|
||||
free((void *)merged_driconf);
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
@@ -199,14 +199,12 @@ bool
|
||||
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd);
|
||||
|
||||
/**
|
||||
* Get the driinfo XML used for the DRM driver of the given name, if any.
|
||||
* Get the dri options used for the DRM driver of the given name, if any.
|
||||
*
|
||||
* The returned string is heap-allocated.
|
||||
* The returned array is heap-allocated.
|
||||
*/
|
||||
char *
|
||||
pipe_loader_drm_get_driinfo_xml(const char *driver_name);
|
||||
|
||||
extern const char gallium_driinfo_xml[];
|
||||
const struct driOptionDescription *
|
||||
pipe_loader_drm_get_driconf_by_name(const char *driver_name, unsigned *count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_dl.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/xmlconfig.h"
|
||||
|
||||
#define DRM_RENDER_NODE_DEV_NAME_FORMAT "%s/renderD%d"
|
||||
#define DRM_RENDER_NODE_MAX_NODES 63
|
||||
@@ -241,15 +242,13 @@ pipe_loader_drm_release(struct pipe_loader_device **dev)
|
||||
pipe_loader_base_release(dev);
|
||||
}
|
||||
|
||||
static const char *
|
||||
pipe_loader_drm_get_driconf_xml(struct pipe_loader_device *dev)
|
||||
static const struct driOptionDescription *
|
||||
pipe_loader_drm_get_driconf(struct pipe_loader_device *dev, unsigned *count)
|
||||
{
|
||||
struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);
|
||||
|
||||
if (!ddev->dd->driconf_xml)
|
||||
return NULL;
|
||||
|
||||
return *ddev->dd->driconf_xml;
|
||||
*count = ddev->dd->driconf_count;
|
||||
return ddev->dd->driconf;
|
||||
}
|
||||
|
||||
static struct pipe_screen *
|
||||
@@ -261,24 +260,30 @@ pipe_loader_drm_create_screen(struct pipe_loader_device *dev,
|
||||
return ddev->dd->create_screen(ddev->fd, config);
|
||||
}
|
||||
|
||||
char *
|
||||
pipe_loader_drm_get_driinfo_xml(const char *driver_name)
|
||||
const struct driOptionDescription *
|
||||
pipe_loader_drm_get_driconf_by_name(const char *driver_name, unsigned *count)
|
||||
{
|
||||
char *xml = NULL;
|
||||
driOptionDescription *driconf = NULL;
|
||||
struct util_dl_library *lib = NULL;
|
||||
const struct drm_driver_descriptor *dd =
|
||||
get_driver_descriptor(driver_name, &lib);
|
||||
|
||||
if (dd && dd->driconf_xml && *dd->driconf_xml)
|
||||
xml = strdup(*dd->driconf_xml);
|
||||
|
||||
if (!dd) {
|
||||
*count = 0;
|
||||
} else {
|
||||
*count = dd->driconf_count;
|
||||
size_t size = sizeof(*driconf) * *count;
|
||||
driconf = malloc(size);
|
||||
memcpy(driconf, dd->driconf, size);
|
||||
}
|
||||
if (lib)
|
||||
util_dl_close(lib);
|
||||
return xml;
|
||||
|
||||
return driconf;
|
||||
}
|
||||
|
||||
static const struct pipe_loader_ops pipe_loader_drm_ops = {
|
||||
.create_screen = pipe_loader_drm_create_screen,
|
||||
.get_driconf_xml = pipe_loader_drm_get_driconf_xml,
|
||||
.get_driconf = pipe_loader_drm_get_driconf,
|
||||
.release = pipe_loader_drm_release
|
||||
};
|
||||
|
@@ -34,7 +34,8 @@ struct pipe_loader_ops {
|
||||
struct pipe_screen *(*create_screen)(struct pipe_loader_device *dev,
|
||||
const struct pipe_screen_config *config);
|
||||
|
||||
const char *(*get_driconf_xml)(struct pipe_loader_device *dev);
|
||||
const struct driOptionDescription *(*get_driconf)(struct pipe_loader_device *dev,
|
||||
unsigned *count);
|
||||
|
||||
void (*release)(struct pipe_loader_device **dev);
|
||||
};
|
||||
|
@@ -294,9 +294,10 @@ pipe_loader_sw_release(struct pipe_loader_device **dev)
|
||||
pipe_loader_base_release(dev);
|
||||
}
|
||||
|
||||
static const char *
|
||||
pipe_loader_sw_get_driconf_xml(struct pipe_loader_device *dev)
|
||||
static const struct driOptionDescription *
|
||||
pipe_loader_sw_get_driconf(struct pipe_loader_device *dev, unsigned *count)
|
||||
{
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -316,6 +317,6 @@ pipe_loader_sw_create_screen(struct pipe_loader_device *dev,
|
||||
|
||||
static const struct pipe_loader_ops pipe_loader_sw_ops = {
|
||||
.create_screen = pipe_loader_sw_create_screen,
|
||||
.get_driconf_xml = pipe_loader_sw_get_driconf_xml,
|
||||
.get_driconf = pipe_loader_sw_get_driconf,
|
||||
.release = pipe_loader_sw_release
|
||||
};
|
||||
|
@@ -10,10 +10,11 @@
|
||||
/**
|
||||
* Instantiate a drm_driver_descriptor struct.
|
||||
*/
|
||||
#define DEFINE_DRM_DRIVER_DESCRIPTOR(descriptor_name, driver, driconf, func) \
|
||||
#define DEFINE_DRM_DRIVER_DESCRIPTOR(descriptor_name, driver, _driconf, _driconf_count, func) \
|
||||
const struct drm_driver_descriptor descriptor_name = { \
|
||||
.driver_name = #driver, \
|
||||
.driconf_xml = driconf, \
|
||||
.driconf = _driconf, \
|
||||
.driconf_count = _driconf_count, \
|
||||
.create_screen = func, \
|
||||
};
|
||||
|
||||
@@ -32,17 +33,17 @@ const struct drm_driver_descriptor descriptor_name = { \
|
||||
|
||||
#ifdef PIPE_LOADER_DYNAMIC
|
||||
|
||||
#define DRM_DRIVER_DESCRIPTOR(driver, driconf) \
|
||||
PUBLIC DEFINE_DRM_DRIVER_DESCRIPTOR(driver_descriptor, driver, driconf, pipe_##driver##_create_screen)
|
||||
#define DRM_DRIVER_DESCRIPTOR(driver, driconf, driconf_count) \
|
||||
PUBLIC DEFINE_DRM_DRIVER_DESCRIPTOR(driver_descriptor, driver, driconf, driconf_count, pipe_##driver##_create_screen)
|
||||
|
||||
#define DRM_DRIVER_DESCRIPTOR_STUB(driver)
|
||||
|
||||
#define DRM_DRIVER_DESCRIPTOR_ALIAS(driver, alias, driconf)
|
||||
#define DRM_DRIVER_DESCRIPTOR_ALIAS(driver, alias, driconf, driconf_count)
|
||||
|
||||
#else
|
||||
|
||||
#define DRM_DRIVER_DESCRIPTOR(driver, driconf) \
|
||||
DEFINE_DRM_DRIVER_DESCRIPTOR(driver##_driver_descriptor, driver, driconf, pipe_##driver##_create_screen)
|
||||
#define DRM_DRIVER_DESCRIPTOR(driver, driconf, driconf_count) \
|
||||
DEFINE_DRM_DRIVER_DESCRIPTOR(driver##_driver_descriptor, driver, driconf, driconf_count, pipe_##driver##_create_screen)
|
||||
|
||||
#define DRM_DRIVER_DESCRIPTOR_STUB(driver) \
|
||||
static struct pipe_screen * \
|
||||
@@ -51,10 +52,11 @@ const struct drm_driver_descriptor descriptor_name = { \
|
||||
fprintf(stderr, #driver ": driver missing\n"); \
|
||||
return NULL; \
|
||||
} \
|
||||
DRM_DRIVER_DESCRIPTOR(driver, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(driver, NULL, 0)
|
||||
|
||||
#define DRM_DRIVER_DESCRIPTOR_ALIAS(driver, alias, driconf) \
|
||||
DEFINE_DRM_DRIVER_DESCRIPTOR(alias##_driver_descriptor, alias, driconf, pipe_##driver##_create_screen)
|
||||
#define DRM_DRIVER_DESCRIPTOR_ALIAS(driver, alias, driconf, driconf_count) \
|
||||
DEFINE_DRM_DRIVER_DESCRIPTOR(alias##_driver_descriptor, alias, driconf, \
|
||||
driconf_count, pipe_##driver##_create_screen)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,7 +77,7 @@ pipe_i915_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = i915_screen_create(iws);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(i915, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(i915, NULL, 0)
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(i915)
|
||||
#endif
|
||||
@@ -92,10 +94,10 @@ pipe_iris_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
|
||||
const char *iris_driconf_xml =
|
||||
const driOptionDescription iris_driconf[] = {
|
||||
#include "iris/driinfo_iris.h"
|
||||
;
|
||||
DRM_DRIVER_DESCRIPTOR(iris, &iris_driconf_xml)
|
||||
};
|
||||
DRM_DRIVER_DESCRIPTOR(iris, iris_driconf, ARRAY_SIZE(iris_driconf))
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(iris)
|
||||
@@ -112,16 +114,16 @@ pipe_nouveau_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = nouveau_drm_screen_create(fd);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(nouveau, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(nouveau, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(nouveau)
|
||||
#endif
|
||||
|
||||
#if defined(GALLIUM_VC4) || defined(GALLIUM_V3D)
|
||||
const char *v3d_driconf_xml =
|
||||
const driOptionDescription v3d_driconf[] = {
|
||||
#include "v3d/driinfo_v3d.h"
|
||||
;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef GALLIUM_KMSRO
|
||||
@@ -136,9 +138,9 @@ pipe_kmsro_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
#if defined(GALLIUM_VC4) || defined(GALLIUM_V3D)
|
||||
DRM_DRIVER_DESCRIPTOR(kmsro, &v3d_driconf_xml)
|
||||
DRM_DRIVER_DESCRIPTOR(kmsro, v3d_driconf, ARRAY_SIZE(v3d_driconf))
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR(kmsro, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(kmsro, NULL, 0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -158,7 +160,7 @@ pipe_r300_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
rw = radeon_drm_winsys_create(fd, config, r300_screen_create);
|
||||
return rw ? debug_screen_wrap(rw->screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(r300, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(r300, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(r300)
|
||||
@@ -177,7 +179,7 @@ pipe_r600_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
rw = radeon_drm_winsys_create(fd, config, r600_screen_create);
|
||||
return rw ? debug_screen_wrap(rw->screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(r600, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(r600, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(r600)
|
||||
@@ -194,10 +196,10 @@ pipe_radeonsi_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
|
||||
const char *radeonsi_driconf_xml =
|
||||
const driOptionDescription radeonsi_driconf[] = {
|
||||
#include "radeonsi/driinfo_radeonsi.h"
|
||||
;
|
||||
DRM_DRIVER_DESCRIPTOR(radeonsi, &radeonsi_driconf_xml)
|
||||
};
|
||||
DRM_DRIVER_DESCRIPTOR(radeonsi, radeonsi_driconf, ARRAY_SIZE(radeonsi_driconf))
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(radeonsi)
|
||||
@@ -220,7 +222,7 @@ pipe_vmwgfx_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = svga_screen_create(sws);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(vmwgfx, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(vmwgfx, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(vmwgfx)
|
||||
@@ -237,11 +239,11 @@ pipe_msm_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = fd_drm_screen_create(fd, NULL);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(msm, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(msm, NULL, 0)
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(msm)
|
||||
#endif
|
||||
DRM_DRIVER_DESCRIPTOR_ALIAS(msm, kgsl, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR_ALIAS(msm, kgsl, NULL, 0)
|
||||
|
||||
#ifdef GALLIUM_VIRGL
|
||||
#include "virgl/drm/virgl_drm_public.h"
|
||||
@@ -256,10 +258,10 @@ pipe_virtio_gpu_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
|
||||
const char *virgl_driconf_xml =
|
||||
const driOptionDescription virgl_driconf[] = {
|
||||
#include "virgl/virgl_driinfo.h.in"
|
||||
;
|
||||
DRM_DRIVER_DESCRIPTOR(virtio_gpu, &virgl_driconf_xml)
|
||||
};
|
||||
DRM_DRIVER_DESCRIPTOR(virtio_gpu, virgl_driconf, ARRAY_SIZE(virgl_driconf))
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(virtio_gpu)
|
||||
@@ -276,7 +278,7 @@ pipe_vc4_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = vc4_drm_screen_create(fd, config);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(vc4, &v3d_driconf_xml)
|
||||
DRM_DRIVER_DESCRIPTOR(vc4, v3d_driconf, ARRAY_SIZE(v3d_driconf))
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(vc4)
|
||||
#endif
|
||||
@@ -293,7 +295,7 @@ pipe_v3d_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
|
||||
DRM_DRIVER_DESCRIPTOR(v3d, &v3d_driconf_xml)
|
||||
DRM_DRIVER_DESCRIPTOR(v3d, v3d_driconf, ARRAY_SIZE(v3d_driconf))
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(v3d)
|
||||
@@ -310,7 +312,7 @@ pipe_panfrost_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = panfrost_drm_screen_create(fd);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(panfrost, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(panfrost, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(panfrost)
|
||||
@@ -327,7 +329,7 @@ pipe_etnaviv_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = etna_drm_screen_create(fd);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(etnaviv, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(etnaviv, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(etnaviv)
|
||||
@@ -345,7 +347,7 @@ pipe_tegra_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(tegra, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(tegra, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(tegra)
|
||||
@@ -362,7 +364,7 @@ pipe_lima_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = lima_drm_screen_create(fd);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(lima, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(lima, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(lima)
|
||||
@@ -378,7 +380,7 @@ pipe_zink_create_screen(int fd, const struct pipe_screen_config *config)
|
||||
screen = zink_drm_create_screen(fd);
|
||||
return screen ? debug_screen_wrap(screen) : NULL;
|
||||
}
|
||||
DRM_DRIVER_DESCRIPTOR(zink, NULL)
|
||||
DRM_DRIVER_DESCRIPTOR(zink, NULL, 0)
|
||||
|
||||
#else
|
||||
DRM_DRIVER_DESCRIPTOR_STUB(zink)
|
||||
|
@@ -7,5 +7,5 @@ DRI_CONF_SECTION_DEBUG
|
||||
DRI_CONF_SECTION_END
|
||||
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_OPT_E(bo_reuse, 1, 0, 1, "Buffer object reuse", "")
|
||||
DRI_CONF_OPT_E(bo_reuse, 1, 0, 1, "Buffer object reuse",)
|
||||
DRI_CONF_SECTION_END
|
||||
|
@@ -51,7 +51,6 @@
|
||||
|
||||
const __DRIconfigOptionsExtension gallium_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 2 },
|
||||
.xml = gallium_driinfo_xml,
|
||||
.getXml = pipe_loader_get_driinfo_xml
|
||||
};
|
||||
|
||||
|
@@ -19,11 +19,13 @@ struct drm_driver_descriptor
|
||||
const char *driver_name;
|
||||
|
||||
/**
|
||||
* Pointer to the XML string fragment describing driver-specific driconf
|
||||
* options. Use DRI_CONF_* macros to create the string, do not wrap in
|
||||
* DRI_CONF_BEGIN/END.
|
||||
* Optional pointer to the array of driOptionDescription describing
|
||||
* driver-specific driconf options.
|
||||
*/
|
||||
const char **driconf_xml;
|
||||
const struct driOptionDescription *driconf;
|
||||
|
||||
/* Number of entries in the driconf array. */
|
||||
unsigned driconf_count;
|
||||
|
||||
/**
|
||||
* Create a pipe srcreen.
|
||||
|
@@ -47,8 +47,7 @@
|
||||
|
||||
#define DBG_CHANNEL DBG_ADAPTER
|
||||
|
||||
const char __driConfigOptionsNine[] =
|
||||
DRI_CONF_BEGIN
|
||||
const driOptionDescription __driConfigOptionsNine[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
|
||||
DRI_CONF_SECTION_END
|
||||
@@ -62,7 +61,7 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_NINE_DYNAMICTEXTUREWORKAROUND("false")
|
||||
DRI_CONF_NINE_SHADERINLINECONSTANTS("false")
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
};
|
||||
|
||||
struct fallback_card_config {
|
||||
const char *name;
|
||||
@@ -249,7 +248,8 @@ drm_create_adapter( int fd,
|
||||
ctx->base.throttling_value = 2;
|
||||
ctx->base.throttling = ctx->base.throttling_value > 0;
|
||||
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsNine);
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsNine,
|
||||
ARRAY_SIZE(__driConfigOptionsNine));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"nine", NULL, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "throttle_value", DRI_INT)) {
|
||||
|
@@ -49,8 +49,7 @@
|
||||
|
||||
#include "genxml/gen7_pack.h"
|
||||
|
||||
static const char anv_dri_options_xml[] =
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription anv_dri_options[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
|
||||
DRI_CONF_VK_X11_STRICT_IMAGE_COUNT("false")
|
||||
@@ -60,7 +59,7 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_ALWAYS_FLUSH_CACHE("false")
|
||||
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST("false")
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
};
|
||||
|
||||
/* This is probably far to big but it reflects the max size used for messages
|
||||
* in OpenGLs KHR_debug.
|
||||
@@ -768,7 +767,8 @@ VkResult anv_CreateInstance(
|
||||
|
||||
VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
|
||||
|
||||
driParseOptionInfo(&instance->available_dri_options, anv_dri_options_xml);
|
||||
driParseOptionInfo(&instance->available_dri_options, anv_dri_options,
|
||||
ARRAY_SIZE(anv_dri_options));
|
||||
driParseConfigFiles(&instance->dri_options, &instance->available_dri_options,
|
||||
0, "anv", NULL,
|
||||
instance->app_info.app_name,
|
||||
|
@@ -178,13 +178,12 @@ loader_open_render_node(const char *name)
|
||||
}
|
||||
|
||||
#ifdef USE_DRICONF
|
||||
static const char __driConfigOptionsLoader[] =
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription __driConfigOptionsLoader[] = {
|
||||
DRI_CONF_SECTION_INITIALIZATION
|
||||
DRI_CONF_DEVICE_ID_PATH_TAG()
|
||||
DRI_CONF_DRI_DRIVER()
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
};
|
||||
|
||||
static char *loader_get_dri_config_driver(int fd)
|
||||
{
|
||||
@@ -193,7 +192,8 @@ static char *loader_get_dri_config_driver(int fd)
|
||||
char *dri_driver = NULL;
|
||||
char *kernel_driver = loader_get_kernel_driver_name(fd);
|
||||
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader);
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
|
||||
ARRAY_SIZE(__driConfigOptionsLoader));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"loader", kernel_driver, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "dri_driver", DRI_STRING)) {
|
||||
@@ -215,7 +215,8 @@ static char *loader_get_dri_config_device_id(void)
|
||||
driOptionCache userInitOptions;
|
||||
char *prime = NULL;
|
||||
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader);
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
|
||||
ARRAY_SIZE(__driConfigOptionsLoader));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"loader", NULL, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "device_id", DRI_STRING))
|
||||
|
@@ -51,12 +51,11 @@
|
||||
#include "main/errors.h"
|
||||
#include "main/macros.h"
|
||||
|
||||
const char __dri2ConfigOptions[] =
|
||||
DRI_CONF_BEGIN
|
||||
driOptionDescription __dri2ConfigOptions[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
};
|
||||
|
||||
/*****************************************************************/
|
||||
/** \name Screen handling functions */
|
||||
@@ -148,7 +147,8 @@ driCreateNewScreen2(int scrn, int fd,
|
||||
psp->myNum = scrn;
|
||||
|
||||
/* Option parsing before ->InitScreen(), as some options apply there. */
|
||||
driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions);
|
||||
driParseOptionInfo(&psp->optionInfo,
|
||||
__dri2ConfigOptions, ARRAY_SIZE(__dri2ConfigOptions));
|
||||
driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
|
||||
"dri2", NULL, NULL, 0, NULL, 0);
|
||||
|
||||
|
@@ -43,11 +43,7 @@
|
||||
#include "util/driconf.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
static const __DRIconfigOptionsExtension i915_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 1 },
|
||||
.xml =
|
||||
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription i915_driconf[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
/* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
|
||||
* DRI_CONF_BO_REUSE_ALL
|
||||
@@ -75,7 +71,18 @@ DRI_CONF_BEGIN
|
||||
|
||||
DRI_CONF_OPT_B(shader_precompile, "true", "Perform code generation at shader link time.")
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END
|
||||
};
|
||||
|
||||
static char *
|
||||
i915_driconf_get_xml(const char *driver_name)
|
||||
{
|
||||
return driGetOptionsXml(i915_driconf, ARRAY_SIZE(i915_driconf));
|
||||
}
|
||||
|
||||
static const __DRIconfigOptionsExtension i915_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 2 },
|
||||
.xml = NULL,
|
||||
.getXml = i915_driconf_get_xml,
|
||||
};
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
@@ -1155,7 +1162,8 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
|
||||
return false;
|
||||
}
|
||||
/* parse information in __driConfigOptions */
|
||||
driParseOptionInfo(&intelScreen->optionCache, i915_config_options.xml);
|
||||
driParseOptionInfo(&intelScreen->optionCache, i915_driconf,
|
||||
ARRAY_SIZE(i915_driconf));
|
||||
|
||||
intelScreen->driScrnPriv = psp;
|
||||
psp->driverPrivate = (void *) intelScreen;
|
||||
|
@@ -49,10 +49,7 @@
|
||||
|
||||
#include "common/gen_defines.h"
|
||||
|
||||
static const __DRIconfigOptionsExtension brw_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 1 },
|
||||
.xml =
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription brw_driconf[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
/* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
|
||||
* DRI_CONF_BO_REUSE_ALL
|
||||
@@ -100,7 +97,18 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_ALLOW_RGB565_CONFIGS("true")
|
||||
DRI_CONF_ALLOW_FP16_CONFIGS("false")
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END
|
||||
};
|
||||
|
||||
static char *
|
||||
brw_driconf_get_xml(const char *driver_name)
|
||||
{
|
||||
return driGetOptionsXml(brw_driconf, ARRAY_SIZE(brw_driconf));
|
||||
}
|
||||
|
||||
static const __DRIconfigOptionsExtension brw_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 2 },
|
||||
.xml = NULL,
|
||||
.getXml = brw_driconf_get_xml,
|
||||
};
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
@@ -2538,7 +2546,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
|
||||
driOptionCache options;
|
||||
memset(&options, 0, sizeof(options));
|
||||
|
||||
driParseOptionInfo(&options, brw_config_options.xml);
|
||||
driParseOptionInfo(&options, brw_driconf, ARRAY_SIZE(brw_driconf));
|
||||
driParseConfigFiles(&screen->optionCache, &options, dri_screen->myNum,
|
||||
"i965", NULL, NULL, 0, NULL, 0);
|
||||
driDestroyOptionCache(&options);
|
||||
|
@@ -91,10 +91,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
"Initial maximum value for anisotropic texture filtering")
|
||||
|
||||
#if defined(RADEON_R100) /* R100 */
|
||||
static const __DRIconfigOptionsExtension radeon_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 1 },
|
||||
.xml =
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription radeon_driconf[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
|
||||
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
|
||||
@@ -110,15 +107,10 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
|
||||
DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END
|
||||
};
|
||||
|
||||
#elif defined(RADEON_R200)
|
||||
|
||||
static const __DRIconfigOptionsExtension radeon_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 1 },
|
||||
.xml =
|
||||
DRI_CONF_BEGIN
|
||||
static const driOptionDescription radeon_driconf[] = {
|
||||
DRI_CONF_SECTION_PERFORMANCE
|
||||
DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
|
||||
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
|
||||
@@ -136,10 +128,21 @@ DRI_CONF_BEGIN
|
||||
DRI_CONF_OPT_F(texture_blend_quality, 1.0, 0.0, 1.0,
|
||||
"Texture filtering quality vs. speed, AKA “brilinear” texture filtering")
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END
|
||||
};
|
||||
#endif
|
||||
|
||||
static char *
|
||||
radeon_driconf_get_xml(const char *driver_name)
|
||||
{
|
||||
return driGetOptionsXml(radeon_driconf, ARRAY_SIZE(radeon_driconf));
|
||||
}
|
||||
|
||||
static const __DRIconfigOptionsExtension radeon_config_options = {
|
||||
.base = { __DRI_CONFIG_OPTIONS, 2 },
|
||||
.xml = NULL,
|
||||
.getXml = radeon_driconf_get_xml,
|
||||
};
|
||||
|
||||
static int
|
||||
radeonGetParam(__DRIscreen *sPriv, int param, void *value)
|
||||
{
|
||||
@@ -578,7 +581,8 @@ radeonCreateScreen2(__DRIscreen *sPriv)
|
||||
radeon_init_debug();
|
||||
|
||||
/* parse information in __driConfigOptions */
|
||||
driParseOptionInfo (&screen->optionCache, radeon_config_options.xml);
|
||||
driParseOptionInfo (&screen->optionCache, radeon_driconf,
|
||||
ARRAY_SIZE(radeon_driconf));
|
||||
|
||||
screen->chip_flags = 0;
|
||||
|
||||
|
@@ -33,119 +33,95 @@
|
||||
#ifndef __DRICONF_H
|
||||
#define __DRICONF_H
|
||||
|
||||
#include "xmlconfig.h"
|
||||
|
||||
/*
|
||||
* generic macros
|
||||
*/
|
||||
|
||||
/** \brief Begin __driConfigOptions */
|
||||
#define DRI_CONF_BEGIN \
|
||||
"<?xml version=\"1.0\" standalone=\"yes\"?>" \
|
||||
"<!DOCTYPE driinfo [" \
|
||||
" <!ELEMENT driinfo (section*)>" \
|
||||
" <!ELEMENT section (description+, option+)>" \
|
||||
" <!ELEMENT description (enum*)>" \
|
||||
" <!ATTLIST description lang CDATA #FIXED \"en\"" \
|
||||
" text CDATA #REQUIRED>" \
|
||||
" <!ELEMENT option (description+)>" \
|
||||
" <!ATTLIST option name CDATA #REQUIRED" \
|
||||
" type (bool|enum|int|float) #REQUIRED" \
|
||||
" default CDATA #REQUIRED" \
|
||||
" valid CDATA #IMPLIED>" \
|
||||
" <!ELEMENT enum EMPTY>" \
|
||||
" <!ATTLIST enum value CDATA #REQUIRED" \
|
||||
" text CDATA #REQUIRED>" \
|
||||
"]>" \
|
||||
"<driinfo>\n"
|
||||
|
||||
/** \brief End __driConfigOptions */
|
||||
#define DRI_CONF_END \
|
||||
"</driinfo>\n"
|
||||
|
||||
/** \brief Begin a section of related options */
|
||||
#define DRI_CONF_SECTION_BEGIN \
|
||||
"<section>\n"
|
||||
|
||||
/** \brief End a section of related options */
|
||||
#define DRI_CONF_SECTION_END \
|
||||
"</section>\n"
|
||||
|
||||
/** \brief Begin an option definition */
|
||||
#define DRI_CONF_OPT_BEGIN(name,type,def) \
|
||||
"<option name=\""#name"\" type=\""#type"\" default=\""#def"\">\n"
|
||||
|
||||
/** \brief Begin an option definition with restrictions on valid values */
|
||||
#define DRI_CONF_OPT_BEGIN_V(name,type,def,valid) \
|
||||
"<option name=\""#name"\" type=\""#type"\" default=\""#def"\" valid=\"" valid "\">\n"
|
||||
/** \brief Names a section of related options to follow */
|
||||
#define DRI_CONF_SECTION(text) { .desc = text, .info = { .type = DRI_SECTION } },
|
||||
#define DRI_CONF_SECTION_END
|
||||
|
||||
/** \brief End an option description */
|
||||
#define DRI_CONF_OPT_END \
|
||||
"</option>\n"
|
||||
#define DRI_CONF_OPT_END },
|
||||
|
||||
/** \brief A verbal description (empty version) */
|
||||
#define DRI_CONF_DESC(text) \
|
||||
"<description lang=\"en\" text=\"" text "\"/>\n"
|
||||
|
||||
/** \brief Begining of a verbal description */
|
||||
#define DRI_CONF_DESC_BEGIN(text) \
|
||||
"<description lang=\"en\" text=\"" text "\">\n"
|
||||
|
||||
/** \brief End a description */
|
||||
#define DRI_CONF_DESC_END \
|
||||
"</description>\n"
|
||||
#define DRI_CONF_DESC(text) .desc = text,
|
||||
|
||||
/** \brief A verbal description of an enum value */
|
||||
#define DRI_CONF_ENUM(value,text) \
|
||||
"<enum value=\""#value"\" text=\"" text "\"/>\n"
|
||||
#define DRI_CONF_ENUM(_value,text) { .value = _value, .desc = text },
|
||||
|
||||
#define DRI_CONF(sections) \
|
||||
DRI_CONF_BEGIN \
|
||||
sections \
|
||||
DRI_CONF_END
|
||||
#define DRI_CONF_RANGE_I(min, max) \
|
||||
.range = { \
|
||||
.start = { ._int = min }, \
|
||||
.end = { ._int = max }, \
|
||||
} \
|
||||
|
||||
#define DRI_CONF_SECTION(desc, options) \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC(desc) \
|
||||
options \
|
||||
DRI_CONF_SECTION_END
|
||||
#define DRI_CONF_RANGE_F(min, max) \
|
||||
.range = { \
|
||||
.start = { ._float = min }, \
|
||||
.end = { ._float = max }, \
|
||||
} \
|
||||
|
||||
/**
|
||||
* \brief A boolean option definition, with the default value passed in as a
|
||||
* string
|
||||
*/
|
||||
#define DRI_CONF_OPT_B(name, def, desc) \
|
||||
"<option name=\""#name"\" type=\"bool\" default="#def">\n" \
|
||||
DRI_CONF_DESC(desc) \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_OPT_I(name, def, min, max, desc) \
|
||||
DRI_CONF_OPT_BEGIN_V(name, int, def, #min ":" #max) \
|
||||
DRI_CONF_DESC(desc) \
|
||||
DRI_CONF_OPT_END
|
||||
#define DRI_CONF_OPT_B(_name, def, _desc) { \
|
||||
.desc = _desc, \
|
||||
.info = { \
|
||||
.name = #_name, \
|
||||
.type = DRI_BOOL, \
|
||||
}, \
|
||||
.value = { ._string = (char *)def }, \
|
||||
},
|
||||
|
||||
#define DRI_CONF_OPT_F(name, def, min, max, desc) \
|
||||
DRI_CONF_OPT_BEGIN_V(name, float, def, #min ":" #max) \
|
||||
DRI_CONF_DESC(desc) \
|
||||
DRI_CONF_OPT_END
|
||||
#define DRI_CONF_OPT_I(_name, def, min, max, _desc) { \
|
||||
.desc = _desc, \
|
||||
.info = { \
|
||||
.name = #_name, \
|
||||
.type = DRI_INT, \
|
||||
DRI_CONF_RANGE_I(min, max), \
|
||||
}, \
|
||||
.value = { ._int = def }, \
|
||||
},
|
||||
|
||||
/* Note that def should not be quoted in the caller! */
|
||||
#define DRI_CONF_OPT_S(name, def, desc) \
|
||||
DRI_CONF_OPT_BEGIN(name, string, def) \
|
||||
DRI_CONF_DESC(desc) \
|
||||
DRI_CONF_OPT_END
|
||||
#define DRI_CONF_OPT_F(_name, def, min, max, _desc) { \
|
||||
.desc = _desc, \
|
||||
.info = { \
|
||||
.name = #_name, \
|
||||
.type = DRI_FLOAT, \
|
||||
DRI_CONF_RANGE_F(min, max), \
|
||||
}, \
|
||||
.value = { ._float = def }, \
|
||||
},
|
||||
|
||||
#define DRI_CONF_OPT_E(name, def, min, max, desc, values) \
|
||||
DRI_CONF_OPT_BEGIN_V(name, enum, def, #min ":" #max) \
|
||||
DRI_CONF_DESC_BEGIN(desc) \
|
||||
values \
|
||||
DRI_CONF_DESC_END \
|
||||
DRI_CONF_OPT_END
|
||||
#define DRI_CONF_OPT_E(_name, def, min, max, _desc, values) { \
|
||||
.desc = _desc, \
|
||||
.info = { \
|
||||
.name = #_name, \
|
||||
.type = DRI_ENUM, \
|
||||
DRI_CONF_RANGE_I(min, max), \
|
||||
}, \
|
||||
.value = { ._int = def }, \
|
||||
.enums = { values }, \
|
||||
},
|
||||
|
||||
#define DRI_CONF_OPT_S(_name, def, _desc) { \
|
||||
.desc = _desc, \
|
||||
.info = { \
|
||||
.name = #_name, \
|
||||
.type = DRI_STRING, \
|
||||
}, \
|
||||
.value = { ._string = #def }, \
|
||||
},
|
||||
|
||||
/**
|
||||
* \brief Debugging options
|
||||
*/
|
||||
#define DRI_CONF_SECTION_DEBUG \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC("Debugging")
|
||||
#define DRI_CONF_SECTION_DEBUG DRI_CONF_SECTION("Debugging")
|
||||
|
||||
#define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \
|
||||
DRI_CONF_OPT_B(always_flush_batch, def, \
|
||||
@@ -244,9 +220,7 @@ DRI_CONF_SECTION_BEGIN \
|
||||
/**
|
||||
* \brief Image quality-related options
|
||||
*/
|
||||
#define DRI_CONF_SECTION_QUALITY \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC("Image Quality")
|
||||
#define DRI_CONF_SECTION_QUALITY DRI_CONF_SECTION("Image Quality")
|
||||
|
||||
#define DRI_CONF_PRECISE_TRIG(def) \
|
||||
DRI_CONF_OPT_B(precise_trig, def, \
|
||||
@@ -255,22 +229,22 @@ DRI_CONF_SECTION_BEGIN \
|
||||
#define DRI_CONF_PP_CELSHADE(def) \
|
||||
DRI_CONF_OPT_E(pp_celshade, def, 0, 1, \
|
||||
"A post-processing filter to cel-shade the output", \
|
||||
"")
|
||||
)
|
||||
|
||||
#define DRI_CONF_PP_NORED(def) \
|
||||
DRI_CONF_OPT_E(pp_nored, def, 0, 1, \
|
||||
"A post-processing filter to remove the red channel", \
|
||||
"")
|
||||
)
|
||||
|
||||
#define DRI_CONF_PP_NOGREEN(def) \
|
||||
DRI_CONF_OPT_E(pp_nogreen, def, 0, 1, \
|
||||
"A post-processing filter to remove the green channel", \
|
||||
"")
|
||||
)
|
||||
|
||||
#define DRI_CONF_PP_NOBLUE(def) \
|
||||
DRI_CONF_OPT_E(pp_noblue, def, 0, 1, \
|
||||
"A post-processing filter to remove the blue channel", \
|
||||
"")
|
||||
)
|
||||
|
||||
#define DRI_CONF_PP_JIMENEZMLAA(def,min,max) \
|
||||
DRI_CONF_OPT_I(pp_jimenezmlaa, def, min, max, \
|
||||
@@ -283,9 +257,7 @@ DRI_CONF_SECTION_BEGIN \
|
||||
/**
|
||||
* \brief Performance-related options
|
||||
*/
|
||||
#define DRI_CONF_SECTION_PERFORMANCE \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC("Performance")
|
||||
#define DRI_CONF_SECTION_PERFORMANCE DRI_CONF_SECTION("Performance")
|
||||
|
||||
#define DRI_CONF_VBLANK_NEVER 0
|
||||
#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
|
||||
@@ -344,9 +316,7 @@ DRI_CONF_SECTION_BEGIN \
|
||||
/**
|
||||
* \brief Miscellaneous configuration options
|
||||
*/
|
||||
#define DRI_CONF_SECTION_MISCELLANEOUS \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC("Miscellaneous")
|
||||
#define DRI_CONF_SECTION_MISCELLANEOUS DRI_CONF_SECTION("Miscellaneous")
|
||||
|
||||
#define DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER(def) \
|
||||
DRI_CONF_OPT_B(always_have_depth_buffer, def, \
|
||||
@@ -379,9 +349,7 @@ DRI_CONF_SECTION_BEGIN \
|
||||
/**
|
||||
* \brief Initialization configuration options
|
||||
*/
|
||||
#define DRI_CONF_SECTION_INITIALIZATION \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC("Initialization")
|
||||
#define DRI_CONF_SECTION_INITIALIZATION DRI_CONF_SECTION("Initialization")
|
||||
|
||||
#define DRI_CONF_DEVICE_ID_PATH_TAG(def) \
|
||||
DRI_CONF_OPT_S(device_id, def, "Define the graphic device to use if possible")
|
||||
@@ -393,9 +361,7 @@ DRI_CONF_SECTION_BEGIN \
|
||||
* \brief Gallium-Nine specific configuration options
|
||||
*/
|
||||
|
||||
#define DRI_CONF_SECTION_NINE \
|
||||
DRI_CONF_SECTION_BEGIN \
|
||||
DRI_CONF_DESC("Gallium Nine")
|
||||
#define DRI_CONF_SECTION_NINE DRI_CONF_SECTION("Gallium Nine")
|
||||
|
||||
#define DRI_CONF_NINE_THROTTLE(def) \
|
||||
DRI_CONF_OPT_I(throttle_value, def, 0, 0, \
|
||||
|
@@ -220,12 +220,16 @@ idep_xmlconfig = declare_dependency(
|
||||
)
|
||||
|
||||
if with_tests
|
||||
if host_machine.system() != 'windows'
|
||||
# DRI_CONF macros use designated initializers (required for union
|
||||
# initializaiton), so we need c++2a since gtest forces us to use c++
|
||||
if host_machine.system() != 'windows' and cpp.has_argument('--std=c++2a')
|
||||
test('xmlconfig',
|
||||
executable('xmlconfig_test',
|
||||
files('tests/xmlconfig.cpp'),
|
||||
include_directories : [inc_include, inc_src],
|
||||
dependencies : [idep_mesautil, idep_xmlconfig, idep_gtest],
|
||||
override_options : ['cpp_std=c++2a'],
|
||||
cpp_args: ['-Wno-write-strings']
|
||||
),
|
||||
suite : ['util'],
|
||||
)
|
||||
|
@@ -31,8 +31,6 @@ protected:
|
||||
~xmlconfig_test();
|
||||
|
||||
driOptionCache options;
|
||||
|
||||
void driconf(const char *driconf);
|
||||
};
|
||||
|
||||
xmlconfig_test::xmlconfig_test()
|
||||
@@ -45,23 +43,16 @@ xmlconfig_test::~xmlconfig_test()
|
||||
}
|
||||
|
||||
/* wraps a DRI_CONF_OPT_* in the required xml bits */
|
||||
#define DRI_CONF_TEST_OPT(x) \
|
||||
DRI_CONF(DRI_CONF_SECTION("section", x))
|
||||
|
||||
void
|
||||
xmlconfig_test::driconf(const char *driconf)
|
||||
{
|
||||
/* If your XML fails to parse, printing it here can help. */
|
||||
/* printf("%s", driconf); */
|
||||
|
||||
driParseOptionInfo(&options, driconf);
|
||||
}
|
||||
#define DRI_CONF_TEST_OPT(x) x
|
||||
|
||||
TEST_F(xmlconfig_test, bools)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_GLSL_ZERO_INIT("false")
|
||||
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("true")));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_GLSL_ZERO_INIT("false")
|
||||
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("true")
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
EXPECT_EQ(driQueryOptionb(&options, "glsl_zero_init"), false);
|
||||
EXPECT_EQ(driQueryOptionb(&options, "always_have_depth_buffer"), true);
|
||||
@@ -69,41 +60,56 @@ TEST_F(xmlconfig_test, bools)
|
||||
|
||||
TEST_F(xmlconfig_test, ints)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_OPT_I(opt, 2, 0, 999, "option")));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_OPT_I(opt, 2, 0, 999, "option")
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
EXPECT_EQ(driQueryOptioni(&options, "opt"), 2);
|
||||
}
|
||||
|
||||
TEST_F(xmlconfig_test, floats)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_OPT_F(opt, 2.0, 1.0, 2.0, "option")));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_OPT_F(opt, 2.0, 1.0, 2.0, "option")
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
EXPECT_EQ(driQueryOptionf(&options, "opt"), 2.0);
|
||||
}
|
||||
|
||||
TEST_F(xmlconfig_test, enums)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
EXPECT_EQ(driQueryOptioni(&options, "vblank_mode"), DRI_CONF_VBLANK_DEF_INTERVAL_1);
|
||||
}
|
||||
|
||||
TEST_F(xmlconfig_test, string)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_OPT_S(opt, value, "option")));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_OPT_S(opt, value, "option")
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
EXPECT_STREQ(driQueryOptionstr(&options, "opt"), "value");
|
||||
}
|
||||
|
||||
TEST_F(xmlconfig_test, check_option)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_GLSL_ZERO_INIT("true")
|
||||
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("true")));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_GLSL_ZERO_INIT("true")
|
||||
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("true")
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
EXPECT_EQ(driCheckOption(&options, "glsl_zero_init", DRI_BOOL), true);
|
||||
|
||||
@@ -117,9 +123,12 @@ TEST_F(xmlconfig_test, check_option)
|
||||
|
||||
TEST_F(xmlconfig_test, copy_cache)
|
||||
{
|
||||
driconf(DRI_CONF_TEST_OPT(
|
||||
DRI_CONF_OPT_B(mesa_b_option, "true", "description")
|
||||
DRI_CONF_OPT_S(mesa_s_option, value, "description")));
|
||||
driOptionDescription driconf[] = {
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_OPT_B(mesa_b_option, "true", "description")
|
||||
DRI_CONF_OPT_S(mesa_s_option, value, "description")
|
||||
};
|
||||
driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
|
||||
|
||||
driOptionCache cache;
|
||||
|
||||
|
@@ -279,6 +279,8 @@ parseValue(driOptionValue *v, driOptionType type, const XML_Char *string)
|
||||
free(v->_string);
|
||||
v->_string = strndup(string, STRING_CONF_MAXLEN);
|
||||
return true;
|
||||
case DRI_SECTION:
|
||||
unreachable("shouldn't be parsing values in section declarations");
|
||||
}
|
||||
|
||||
if (tail == string)
|
||||
@@ -323,7 +325,7 @@ parseRange(driOptionInfo *info, const XML_Char *string)
|
||||
}
|
||||
|
||||
/** \brief Check if a value is in info->range. */
|
||||
static bool
|
||||
UNUSED static bool
|
||||
checkValue(const driOptionValue *v, const driOptionInfo *info)
|
||||
{
|
||||
switch (info->type) {
|
||||
@@ -391,245 +393,12 @@ __driUtilMessage(const char *f, ...)
|
||||
(int) XML_GetCurrentColumnNumber(data->parser), \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
/** \brief Output a fatal error message and abort. */
|
||||
#define XML_FATAL1(msg) do { \
|
||||
fprintf(stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
|
||||
data->name, \
|
||||
(int) XML_GetCurrentLineNumber(data->parser), \
|
||||
(int) XML_GetCurrentColumnNumber(data->parser)); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
#define XML_FATAL(msg, ...) do { \
|
||||
fprintf(stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
|
||||
data->name, \
|
||||
(int) XML_GetCurrentLineNumber(data->parser), \
|
||||
(int) XML_GetCurrentColumnNumber(data->parser), \
|
||||
##__VA_ARGS__); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
/** \brief Parser context for __driConfigOptions. */
|
||||
struct OptInfoData {
|
||||
const char *name;
|
||||
XML_Parser parser;
|
||||
driOptionCache *cache;
|
||||
bool inDriInfo;
|
||||
bool inSection;
|
||||
bool inDesc;
|
||||
bool inOption;
|
||||
bool inEnum;
|
||||
int curOption;
|
||||
};
|
||||
|
||||
/** \brief Elements in __driConfigOptions. */
|
||||
enum OptInfoElem {
|
||||
OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT
|
||||
};
|
||||
static const XML_Char *OptInfoElems[] = {
|
||||
"description", "driinfo", "enum", "option", "section"
|
||||
};
|
||||
|
||||
/** \brief Parse attributes of an enum element.
|
||||
*
|
||||
* We're not actually interested in the data. Just make sure this is ok
|
||||
* for external configuration tools.
|
||||
*/
|
||||
static void
|
||||
parseEnumAttr(struct OptInfoData *data, const XML_Char **attr)
|
||||
{
|
||||
uint32_t i;
|
||||
const XML_Char *value = NULL, *text = NULL;
|
||||
driOptionValue v;
|
||||
uint32_t opt = data->curOption;
|
||||
for (i = 0; attr[i]; i += 2) {
|
||||
if (!strcmp(attr[i], "value")) value = attr[i+1];
|
||||
else if (!strcmp(attr[i], "text")) text = attr[i+1];
|
||||
else XML_FATAL("illegal enum attribute: %s.", attr[i]);
|
||||
}
|
||||
if (!value) XML_FATAL1("value attribute missing in enum.");
|
||||
if (!text) XML_FATAL1("text attribute missing in enum.");
|
||||
if (!parseValue(&v, data->cache->info[opt].type, value))
|
||||
XML_FATAL("illegal enum value: %s.", value);
|
||||
if (!checkValue(&v, &data->cache->info[opt]))
|
||||
XML_FATAL("enum value out of valid range: %s.", value);
|
||||
}
|
||||
|
||||
/** \brief Parse attributes of a description element.
|
||||
*
|
||||
* We're not actually interested in the data. Just make sure this is ok
|
||||
* for external configuration tools.
|
||||
*/
|
||||
static void
|
||||
parseDescAttr(struct OptInfoData *data, const XML_Char **attr)
|
||||
{
|
||||
uint32_t i;
|
||||
const XML_Char *lang = NULL, *text = NULL;
|
||||
for (i = 0; attr[i]; i += 2) {
|
||||
if (!strcmp(attr[i], "lang")) lang = attr[i+1];
|
||||
else if (!strcmp(attr[i], "text")) text = attr[i+1];
|
||||
else XML_FATAL("illegal description attribute: %s.", attr[i]);
|
||||
}
|
||||
if (!lang) XML_FATAL1("lang attribute missing in description.");
|
||||
if (!text) XML_FATAL1("text attribute missing in description.");
|
||||
}
|
||||
|
||||
/** \brief Parse attributes of an option element. */
|
||||
static void
|
||||
parseOptInfoAttr(struct OptInfoData *data, const XML_Char **attr)
|
||||
{
|
||||
enum OptAttr {OA_DEFAULT = 0, OA_NAME, OA_TYPE, OA_VALID, OA_COUNT};
|
||||
static const XML_Char *optAttr[] = {"default", "name", "type", "valid"};
|
||||
const XML_Char *attrVal[OA_COUNT] = {NULL, NULL, NULL, NULL};
|
||||
const char *defaultVal;
|
||||
driOptionCache *cache = data->cache;
|
||||
uint32_t opt, i;
|
||||
for (i = 0; attr[i]; i += 2) {
|
||||
uint32_t attrName = bsearchStr(attr[i], optAttr, OA_COUNT);
|
||||
if (attrName >= OA_COUNT)
|
||||
XML_FATAL("illegal option attribute: %s", attr[i]);
|
||||
attrVal[attrName] = attr[i+1];
|
||||
}
|
||||
if (!attrVal[OA_NAME]) XML_FATAL1("name attribute missing in option.");
|
||||
if (!attrVal[OA_TYPE]) XML_FATAL1("type attribute missing in option.");
|
||||
if (!attrVal[OA_DEFAULT]) XML_FATAL1("default attribute missing in option.");
|
||||
|
||||
opt = findOption(cache, attrVal[OA_NAME]);
|
||||
if (cache->info[opt].name)
|
||||
XML_FATAL("option %s redefined.", attrVal[OA_NAME]);
|
||||
data->curOption = opt;
|
||||
|
||||
XSTRDUP(cache->info[opt].name, attrVal[OA_NAME]);
|
||||
|
||||
if (!strcmp(attrVal[OA_TYPE], "bool"))
|
||||
cache->info[opt].type = DRI_BOOL;
|
||||
else if (!strcmp(attrVal[OA_TYPE], "enum"))
|
||||
cache->info[opt].type = DRI_ENUM;
|
||||
else if (!strcmp(attrVal[OA_TYPE], "int"))
|
||||
cache->info[opt].type = DRI_INT;
|
||||
else if (!strcmp(attrVal[OA_TYPE], "float"))
|
||||
cache->info[opt].type = DRI_FLOAT;
|
||||
else if (!strcmp(attrVal[OA_TYPE], "string"))
|
||||
cache->info[opt].type = DRI_STRING;
|
||||
else
|
||||
XML_FATAL("illegal type in option: %s.", attrVal[OA_TYPE]);
|
||||
|
||||
defaultVal = getenv(cache->info[opt].name);
|
||||
if (defaultVal != NULL) {
|
||||
/* don't use XML_WARNING, we want the user to see this! */
|
||||
if (be_verbose()) {
|
||||
fprintf(stderr,
|
||||
"ATTENTION: default value of option %s overridden by environment.\n",
|
||||
cache->info[opt].name);
|
||||
}
|
||||
} else
|
||||
defaultVal = attrVal[OA_DEFAULT];
|
||||
if (!parseValue(&cache->values[opt], cache->info[opt].type, defaultVal))
|
||||
XML_FATAL("illegal default value for %s: %s.", cache->info[opt].name, defaultVal);
|
||||
|
||||
if (attrVal[OA_VALID]) {
|
||||
if (cache->info[opt].type == DRI_BOOL)
|
||||
XML_FATAL1("boolean option with valid attribute.");
|
||||
if (!parseRange(&cache->info[opt], attrVal[OA_VALID]))
|
||||
XML_FATAL("illegal valid attribute: %s.", attrVal[OA_VALID]);
|
||||
if (!checkValue(&cache->values[opt], &cache->info[opt]))
|
||||
XML_FATAL("default value out of valid range '%s': %s.",
|
||||
attrVal[OA_VALID], defaultVal);
|
||||
} else if (cache->info[opt].type == DRI_ENUM) {
|
||||
XML_FATAL1("valid attribute missing in option (mandatory for enums).");
|
||||
} else {
|
||||
memset(&cache->info[opt].range, 0, sizeof(cache->info[opt].range));
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Handler for start element events. */
|
||||
static void
|
||||
optInfoStartElem(void *userData, const XML_Char *name, const XML_Char **attr)
|
||||
{
|
||||
struct OptInfoData *data = (struct OptInfoData *)userData;
|
||||
enum OptInfoElem elem = bsearchStr(name, OptInfoElems, OI_COUNT);
|
||||
switch (elem) {
|
||||
case OI_DRIINFO:
|
||||
if (data->inDriInfo)
|
||||
XML_FATAL1("nested <driinfo> elements.");
|
||||
if (attr[0])
|
||||
XML_FATAL1("attributes specified on <driinfo> element.");
|
||||
data->inDriInfo = true;
|
||||
break;
|
||||
case OI_SECTION:
|
||||
if (!data->inDriInfo)
|
||||
XML_FATAL1("<section> must be inside <driinfo>.");
|
||||
if (data->inSection)
|
||||
XML_FATAL1("nested <section> elements.");
|
||||
if (attr[0])
|
||||
XML_FATAL1("attributes specified on <section> element.");
|
||||
data->inSection = true;
|
||||
break;
|
||||
case OI_DESCRIPTION:
|
||||
if (!data->inSection && !data->inOption)
|
||||
XML_FATAL1("<description> must be inside <description> or <option.");
|
||||
if (data->inDesc)
|
||||
XML_FATAL1("nested <description> elements.");
|
||||
data->inDesc = true;
|
||||
parseDescAttr(data, attr);
|
||||
break;
|
||||
case OI_OPTION:
|
||||
if (!data->inSection)
|
||||
XML_FATAL1("<option> must be inside <section>.");
|
||||
if (data->inDesc)
|
||||
XML_FATAL1("<option> nested in <description> element.");
|
||||
if (data->inOption)
|
||||
XML_FATAL1("nested <option> elements.");
|
||||
data->inOption = true;
|
||||
parseOptInfoAttr(data, attr);
|
||||
break;
|
||||
case OI_ENUM:
|
||||
if (!(data->inOption && data->inDesc))
|
||||
XML_FATAL1("<enum> must be inside <option> and <description>.");
|
||||
if (data->inEnum)
|
||||
XML_FATAL1("nested <enum> elements.");
|
||||
data->inEnum = true;
|
||||
parseEnumAttr(data, attr);
|
||||
break;
|
||||
default:
|
||||
XML_FATAL("unknown element: %s.", name);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Handler for end element events. */
|
||||
static void
|
||||
optInfoEndElem(void *userData, const XML_Char *name)
|
||||
{
|
||||
struct OptInfoData *data = (struct OptInfoData *)userData;
|
||||
enum OptInfoElem elem = bsearchStr(name, OptInfoElems, OI_COUNT);
|
||||
switch (elem) {
|
||||
case OI_DRIINFO:
|
||||
data->inDriInfo = false;
|
||||
break;
|
||||
case OI_SECTION:
|
||||
data->inSection = false;
|
||||
break;
|
||||
case OI_DESCRIPTION:
|
||||
data->inDesc = false;
|
||||
break;
|
||||
case OI_OPTION:
|
||||
data->inOption = false;
|
||||
break;
|
||||
case OI_ENUM:
|
||||
data->inEnum = false;
|
||||
break;
|
||||
default:
|
||||
assert(0); /* should have been caught by StartElem */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
driParseOptionInfo(driOptionCache *info, const char *configOptions)
|
||||
driParseOptionInfo(driOptionCache *info,
|
||||
const driOptionDescription *configOptions,
|
||||
unsigned numOptions)
|
||||
{
|
||||
XML_Parser p;
|
||||
int status;
|
||||
struct OptInfoData userData;
|
||||
struct OptInfoData *data = &userData;
|
||||
|
||||
/* Make the hash table big enough to fit more than the maximum number of
|
||||
* config options we've ever seen in a driver.
|
||||
*/
|
||||
@@ -641,25 +410,187 @@ driParseOptionInfo(driOptionCache *info, const char *configOptions)
|
||||
abort();
|
||||
}
|
||||
|
||||
p = XML_ParserCreate("UTF-8"); /* always UTF-8 */
|
||||
XML_SetElementHandler(p, optInfoStartElem, optInfoEndElem);
|
||||
XML_SetUserData(p, data);
|
||||
UNUSED bool in_section = false;
|
||||
for (int o = 0; o < numOptions; o++) {
|
||||
const driOptionDescription *opt = &configOptions[o];
|
||||
|
||||
userData.name = "__driConfigOptions";
|
||||
userData.parser = p;
|
||||
userData.cache = info;
|
||||
userData.inDriInfo = false;
|
||||
userData.inSection = false;
|
||||
userData.inDesc = false;
|
||||
userData.inOption = false;
|
||||
userData.inEnum = false;
|
||||
userData.curOption = -1;
|
||||
if (opt->info.type == DRI_SECTION) {
|
||||
in_section = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
status = XML_Parse(p, configOptions, strlen(configOptions), 1);
|
||||
if (!status)
|
||||
XML_FATAL("%s.", XML_ErrorString(XML_GetErrorCode(p)));
|
||||
/* for driconf xml generation, options must always be preceded by a
|
||||
* DRI_CONF_SECTION
|
||||
*/
|
||||
assert(in_section);
|
||||
|
||||
XML_ParserFree(p);
|
||||
const char *name = opt->info.name;
|
||||
int i = findOption(info, name);
|
||||
driOptionInfo *optinfo = &info->info[i];
|
||||
driOptionValue *optval = &info->values[i];
|
||||
|
||||
assert(!optinfo->name); /* No duplicate options in your list. */
|
||||
|
||||
optinfo->type = opt->info.type;
|
||||
XSTRDUP(optinfo->name, name);
|
||||
|
||||
switch (opt->info.type) {
|
||||
case DRI_BOOL:
|
||||
if (strcmp(opt->value._string, "true") == 0)
|
||||
optval->_bool = true;
|
||||
else {
|
||||
assert(strcmp(opt->value._string, "false") == 0);
|
||||
optval->_bool = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case DRI_INT:
|
||||
case DRI_ENUM:
|
||||
optval->_int = opt->value._int;
|
||||
break;
|
||||
|
||||
case DRI_FLOAT:
|
||||
optval->_float = opt->value._float;
|
||||
break;
|
||||
|
||||
case DRI_STRING:
|
||||
XSTRDUP(optval->_string, opt->value._string);
|
||||
break;
|
||||
|
||||
case DRI_SECTION:
|
||||
unreachable("handled above");
|
||||
}
|
||||
|
||||
assert(checkValue(optval, optinfo));
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
driGetOptionsXml(const driOptionDescription *configOptions, unsigned numOptions)
|
||||
{
|
||||
char *str = ralloc_strdup(NULL,
|
||||
"<?xml version=\"1.0\" standalone=\"yes\"?>\n" \
|
||||
"<!DOCTYPE driinfo [\n" \
|
||||
" <!ELEMENT driinfo (section*)>\n" \
|
||||
" <!ELEMENT section (description+, option+)>\n" \
|
||||
" <!ELEMENT description (enum*)>\n" \
|
||||
" <!ATTLIST description lang CDATA #FIXED \"en\"\n" \
|
||||
" text CDATA #REQUIRED>\n" \
|
||||
" <!ELEMENT option (description+)>\n" \
|
||||
" <!ATTLIST option name CDATA #REQUIRED\n" \
|
||||
" type (bool|enum|int|float) #REQUIRED\n" \
|
||||
" default CDATA #REQUIRED\n" \
|
||||
" valid CDATA #IMPLIED>\n" \
|
||||
" <!ELEMENT enum EMPTY>\n" \
|
||||
" <!ATTLIST enum value CDATA #REQUIRED\n" \
|
||||
" text CDATA #REQUIRED>\n" \
|
||||
"]>" \
|
||||
"<driinfo>\n");
|
||||
|
||||
bool in_section = false;
|
||||
for (int o = 0; o < numOptions; o++) {
|
||||
const driOptionDescription *opt = &configOptions[o];
|
||||
|
||||
const char *name = opt->info.name;
|
||||
const char *types[] = {
|
||||
[DRI_BOOL] = "bool",
|
||||
[DRI_INT] = "int",
|
||||
[DRI_FLOAT] = "float",
|
||||
[DRI_ENUM] = "enum",
|
||||
[DRI_STRING] = "string",
|
||||
};
|
||||
|
||||
if (opt->info.type == DRI_SECTION) {
|
||||
if (in_section)
|
||||
ralloc_asprintf_append(&str, " </section>\n");
|
||||
|
||||
ralloc_asprintf_append(&str,
|
||||
" <section>\n"
|
||||
" <description lang=\"en\" text=\"%s\"/>\n",
|
||||
opt->desc);
|
||||
|
||||
in_section = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
ralloc_asprintf_append(&str,
|
||||
" <option name=\"%s\" type=\"%s\" default=\"",
|
||||
name,
|
||||
types[opt->info.type]);
|
||||
|
||||
switch (opt->info.type) {
|
||||
case DRI_BOOL:
|
||||
ralloc_asprintf_append(&str, opt->value._bool ? "true" : "false");
|
||||
break;
|
||||
|
||||
case DRI_INT:
|
||||
case DRI_ENUM:
|
||||
ralloc_asprintf_append(&str, "%d", opt->value._int);
|
||||
break;
|
||||
|
||||
case DRI_FLOAT:
|
||||
ralloc_asprintf_append(&str, "%f", opt->value._float);
|
||||
break;
|
||||
|
||||
case DRI_STRING:
|
||||
ralloc_asprintf_append(&str, "%s", opt->value._string);
|
||||
break;
|
||||
|
||||
case DRI_SECTION:
|
||||
unreachable("handled above");
|
||||
break;
|
||||
}
|
||||
ralloc_asprintf_append(&str, "\"");
|
||||
|
||||
|
||||
switch (opt->info.type) {
|
||||
case DRI_INT:
|
||||
case DRI_ENUM:
|
||||
if (opt->info.range.start._int < opt->info.range.end._int) {
|
||||
ralloc_asprintf_append(&str, " valid=\"%d:%d\"",
|
||||
opt->info.range.start._int,
|
||||
opt->info.range.end._int);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRI_FLOAT:
|
||||
if (opt->info.range.start._float < opt->info.range.end._float) {
|
||||
ralloc_asprintf_append(&str, " valid=\"%f:%f\"",
|
||||
opt->info.range.start._float,
|
||||
opt->info.range.end._float);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ralloc_asprintf_append(&str, ">\n"); /* end of <option> */
|
||||
|
||||
|
||||
ralloc_asprintf_append(&str, " <description lang=\"en\" text=\"%s\"%s>\n",
|
||||
opt->desc, opt->info.type != DRI_ENUM ? "/" : "");
|
||||
|
||||
if (opt->info.type == DRI_ENUM) {
|
||||
for (int i = 0; i < ARRAY_SIZE(opt->enums) && opt->enums[i].desc; i++) {
|
||||
ralloc_asprintf_append(&str, " <enum value=\"%d\" text=\"%s\"/>\n",
|
||||
opt->enums[i].value, opt->enums[i].desc);
|
||||
}
|
||||
ralloc_asprintf_append(&str, " </description>\n");
|
||||
}
|
||||
|
||||
ralloc_asprintf_append(&str, " </option>\n");
|
||||
}
|
||||
|
||||
assert(in_section);
|
||||
ralloc_asprintf_append(&str, " </section>\n");
|
||||
|
||||
ralloc_asprintf_append(&str, "</driinfo>\n");
|
||||
|
||||
char *output = strdup(str);
|
||||
ralloc_free(str);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/** \brief Parser context for configuration files. */
|
||||
|
@@ -43,7 +43,7 @@ extern "C" {
|
||||
|
||||
/** \brief Option data types */
|
||||
typedef enum driOptionType {
|
||||
DRI_BOOL, DRI_ENUM, DRI_INT, DRI_FLOAT, DRI_STRING
|
||||
DRI_BOOL, DRI_ENUM, DRI_INT, DRI_FLOAT, DRI_STRING, DRI_SECTION
|
||||
} driOptionType;
|
||||
|
||||
/** \brief Option value */
|
||||
@@ -91,19 +91,41 @@ typedef struct driOptionCache {
|
||||
* The value is the same in the screen and all contexts. */
|
||||
} driOptionCache;
|
||||
|
||||
/** \brief Parse XML option info from configOptions
|
||||
typedef struct driEnumDescription {
|
||||
int value;
|
||||
const char *desc;
|
||||
} driEnumDescription;
|
||||
|
||||
/**
|
||||
* Struct for a driver's definition of an option, its default value, and the
|
||||
* text documenting it.
|
||||
*/
|
||||
typedef struct driOptionDescription {
|
||||
const char *desc;
|
||||
|
||||
driOptionInfo info;
|
||||
driOptionValue value;
|
||||
driEnumDescription enums[4];
|
||||
} driOptionDescription;
|
||||
|
||||
/** Returns an XML string describing the options for the driver. */
|
||||
char *
|
||||
driGetOptionsXml(const driOptionDescription *configOptions, unsigned numOptions);
|
||||
|
||||
/** \brief Parse driconf option array from configOptions
|
||||
*
|
||||
* To be called in <driver>CreateScreen
|
||||
*
|
||||
* \param info pointer to a driOptionCache that will store the option info
|
||||
* \param configOptions XML document describing available configuration opts
|
||||
* \param configOptions Array of XML document describing available configuration opts
|
||||
*
|
||||
* For the option information to be available to external configuration tools
|
||||
* it must be a public symbol __driConfigOptions. It is also passed as a
|
||||
* parameter to driParseOptionInfo in order to avoid driver-independent code
|
||||
* depending on symbols in driver-specific code. */
|
||||
void driParseOptionInfo(driOptionCache *info,
|
||||
const char *configOptions);
|
||||
const driOptionDescription *configOptions,
|
||||
unsigned numOptions);
|
||||
/** \brief Initialize option cache from info and parse configuration files
|
||||
*
|
||||
* To be called in <driver>CreateContext. screenNum, driverName,
|
||||
|
Reference in New Issue
Block a user