c/main: Add display surface counter optional vk instance ext

This commit is contained in:
Christoph Haag 2021-12-07 00:38:55 +01:00
parent ff4d492b74
commit b7d179b1b3
5 changed files with 199 additions and 60 deletions

View file

@ -219,7 +219,10 @@ def get_instance_cmds():
]
EXTENSIONS_TO_CHECK = [
INSTANCE_EXTENSIONS_TO_CHECK = [
"VK_EXT_display_surface_counter",
]
DEVICE_EXTENSIONS_TO_CHECK = [
"VK_KHR_timeline_semaphore",
"VK_EXT_global_priority",
"VK_EXT_robustness2",
@ -353,24 +356,27 @@ def make_ext_name_define(ext: str):
return "{}_EXTENSION_NAME".format(ext.upper()).replace("2", "_2")
def generate_ext_members():
for ext in EXTENSIONS_TO_CHECK:
def generate_ext_members(exts):
for ext in exts:
yield "\tbool {};".format(make_ext_member_name(ext))
def generate_ext_check():
def generate_ext_check(exts):
yield "\t// Reset before filling out."
for ext in EXTENSIONS_TO_CHECK:
for ext in exts:
yield "\tvk->{} = false;".format(make_ext_member_name(ext))
yield ""
yield "\tfor (uint32_t i = 0; i < device_extension_count; i++) {"
yield "\t\tconst char *ext = device_extensions[i];"
yield "\tconst char *const *exts = u_string_list_get_data(ext_list);"
yield "\tuint32_t ext_count = u_string_list_get_size(ext_list);"
yield ""
yield "\tfor (uint32_t i = 0; i < ext_count; i++) {"
yield "\t\tconst char *ext = exts[i];"
yield ""
conditional = ConditionalGenerator()
for ext in EXTENSIONS_TO_CHECK:
for ext in exts:
condition_line = conditional.process_condition(compute_condition((ext,)))
if condition_line:
yield condition_line
@ -401,9 +407,13 @@ INSTANCE_TEMPLATES = {
"BEGIN": BEGIN_TEMPLATE % "instance loader",
"END": END_TEMPLATE % "instance loader",
}
INSTANCE_EXT_TEMPLATES = {
"BEGIN": BEGIN_TEMPLATE % "instance extension",
"END": END_TEMPLATE % "instance extension",
}
EXT_TEMPLATES = {
"BEGIN": BEGIN_TEMPLATE % "extension",
"END": END_TEMPLATE % "extension",
"BEGIN": BEGIN_TEMPLATE % "device extension",
"END": END_TEMPLATE % "device extension",
}
@ -424,11 +434,19 @@ def process_header():
DEVICE_TEMPLATES["END"],
list(generate_structure_members(get_device_cmds())),
)
lines = replace_middle(
lines,
INSTANCE_EXT_TEMPLATES["BEGIN"],
INSTANCE_EXT_TEMPLATES["END"],
list(generate_ext_members(INSTANCE_EXTENSIONS_TO_CHECK)),
)
lines = replace_middle(
lines,
EXT_TEMPLATES["BEGIN"],
EXT_TEMPLATES["END"],
list(generate_ext_members()),
list(generate_ext_members(DEVICE_EXTENSIONS_TO_CHECK)),
)
with open(str(HEADER_FN), "w", encoding="utf-8") as fp:
@ -454,11 +472,18 @@ def process_impl():
list(generate_proc_macro("GET_DEV_PROC", get_device_cmds())),
)
lines = replace_middle(
lines,
INSTANCE_EXT_TEMPLATES["BEGIN"],
INSTANCE_EXT_TEMPLATES["END"],
list(generate_ext_check(INSTANCE_EXTENSIONS_TO_CHECK)),
)
lines = replace_middle(
lines,
EXT_TEMPLATES["BEGIN"],
EXT_TEMPLATES["END"],
list(generate_ext_check()),
list(generate_ext_check(DEVICE_EXTENSIONS_TO_CHECK)),
)
with open(str(IMPL_FN), "w", encoding="utf-8") as fp:

View file

@ -1230,18 +1230,44 @@ vk_check_extension(struct vk_bundle *vk, VkExtensionProperties *props, uint32_t
return false;
}
static void
fill_in_has_extensions(struct vk_bundle *vk, const char *const *device_extensions, uint32_t device_extension_count)
void
vk_fill_in_has_instance_extensions(struct vk_bundle *vk, struct u_string_list *ext_list)
{
// beginning of GENERATED extension code - do not modify - used by scripts
// beginning of GENERATED instance extension code - do not modify - used by scripts
// Reset before filling out.
vk->has_EXT_display_surface_counter = false;
const char *const *exts = u_string_list_get_data(ext_list);
uint32_t ext_count = u_string_list_get_size(ext_list);
for (uint32_t i = 0; i < ext_count; i++) {
const char *ext = exts[i];
#if defined(VK_EXT_display_surface_counter)
if (strcmp(ext, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME) == 0) {
vk->has_EXT_display_surface_counter = true;
continue;
}
#endif // defined(VK_EXT_display_surface_counter)
}
// end of GENERATED instance extension code - do not modify - used by scripts
}
static void
fill_in_has_device_extensions(struct vk_bundle *vk, struct u_string_list *ext_list)
{
// beginning of GENERATED device extension code - do not modify - used by scripts
// Reset before filling out.
vk->has_KHR_timeline_semaphore = false;
vk->has_EXT_global_priority = false;
vk->has_EXT_robustness2 = false;
vk->has_GOOGLE_display_timing = false;
for (uint32_t i = 0; i < device_extension_count; i++) {
const char *ext = device_extensions[i];
const char *const *exts = u_string_list_get_data(ext_list);
uint32_t ext_count = u_string_list_get_size(ext_list);
for (uint32_t i = 0; i < ext_count; i++) {
const char *ext = exts[i];
#if defined(VK_KHR_timeline_semaphore)
if (strcmp(ext, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME) == 0) {
@ -1271,7 +1297,82 @@ fill_in_has_extensions(struct vk_bundle *vk, const char *const *device_extension
}
#endif // defined(VK_GOOGLE_display_timing)
}
// end of GENERATED extension code - do not modify - used by scripts
// end of GENERATED device extension code - do not modify - used by scripts
}
static bool
vk_should_skip_optional_instance_ext(struct vk_bundle *vk,
struct u_string_list *required_instance_ext_list,
struct u_string_list *optional_instance_ext_listconst,
const char *ext)
{
#ifdef VK_EXT_display_surface_counter
if (strcmp(ext, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME) == 0) {
// it does not make sense to enable surface counter on anything that does not use a VkDisplayKHR
if (!u_string_list_contains(required_instance_ext_list, VK_KHR_DISPLAY_EXTENSION_NAME)) {
VK_DEBUG(vk, "Skipping optional instance extension %s because %s is not enabled", ext,
VK_KHR_DISPLAY_EXTENSION_NAME);
return true;
}
VK_DEBUG(vk, "Not skipping optional instance extension %s because %s is enabled", ext,
VK_KHR_DISPLAY_EXTENSION_NAME);
}
#endif
return false;
}
static bool
vk_is_instance_ext_supported(VkExtensionProperties *props, uint32_t prop_count, const char *ext)
{
for (uint32_t j = 0; j < prop_count; j++) {
if (strcmp(ext, props[j].extensionName) == 0) {
return true;
}
}
return false;
}
struct u_string_list *
vk_build_instance_extensions(struct vk_bundle *vk,
struct u_string_list *required_instance_ext_list,
struct u_string_list *optional_instance_ext_list)
{
VkResult res;
uint32_t prop_count = 0;
res = vk->vkEnumerateInstanceExtensionProperties(NULL, &prop_count, NULL);
vk_check_error("vkEnumerateInstanceExtensionProperties", res, NULL);
VkExtensionProperties *props = U_TYPED_ARRAY_CALLOC(VkExtensionProperties, prop_count);
res = vk->vkEnumerateInstanceExtensionProperties(NULL, &prop_count, props);
vk_check_error_with_free("vkEnumerateInstanceExtensionProperties", res, NULL, props);
struct u_string_list *ret = u_string_list_create_from_list(required_instance_ext_list);
uint32_t optional_instance_ext_count = u_string_list_get_size(optional_instance_ext_list);
const char *const *optional_instance_exts = u_string_list_get_data(optional_instance_ext_list);
for (uint32_t i = 0; i < optional_instance_ext_count; i++) {
const char *optional_ext = optional_instance_exts[i];
if (vk_should_skip_optional_instance_ext(vk, required_instance_ext_list, optional_instance_ext_list,
optional_ext)) {
continue;
}
if (!vk_is_instance_ext_supported(props, prop_count, optional_ext)) {
VK_DEBUG(vk, "Optional instance extension %s not enabled, unsupported", optional_ext);
continue;
}
int added = u_string_list_append_unique(ret, optional_ext);
if (added == 1) {
VK_DEBUG(vk, "Using optional instance ext %s", optional_ext);
} else {
VK_WARN(vk, "Duplicate instance extension %s not added twice", optional_ext);
}
break;
}
return ret;
}
static VkResult
@ -1345,8 +1446,7 @@ vk_build_device_extensions(struct vk_bundle *vk,
}
// Fill this out here.
fill_in_has_extensions(vk, u_string_list_get_data(*out_device_ext_list),
u_string_list_get_size(*out_device_ext_list));
fill_in_has_device_extensions(vk, *out_device_ext_list);
free(props);

View file

@ -57,12 +57,16 @@ struct vk_bundle
struct os_mutex queue_mutex;
// beginning of GENERATED extension code - do not modify - used by scripts
// beginning of GENERATED instance extension code - do not modify - used by scripts
bool has_EXT_display_surface_counter;
// end of GENERATED instance extension code - do not modify - used by scripts
// beginning of GENERATED device extension code - do not modify - used by scripts
bool has_KHR_timeline_semaphore;
bool has_EXT_global_priority;
bool has_EXT_robustness2;
bool has_GOOGLE_display_timing;
// end of GENERATED extension code - do not modify - used by scripts
// end of GENERATED device extension code - do not modify - used by scripts
bool is_tegra;
@ -426,6 +430,14 @@ struct vk_device_features
bool timeline_semaphore;
};
/*!
* @ingroup aux_vk
*/
struct u_string_list *
vk_build_instance_extensions(struct vk_bundle *vk,
struct u_string_list *required_instance_ext_list,
struct u_string_list *optional_instance_ext_list);
/*!
* @ingroup aux_vk
*/
@ -790,6 +802,11 @@ vk_begin_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer);
VkResult
vk_end_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer);
/*!
* Fills in has_* in vk_bundle given a string of prefiltered instance extensions
*/
void
vk_fill_in_has_instance_extensions(struct vk_bundle *vk, struct u_string_list *ext_list);
#ifdef __cplusplus
}

View file

@ -629,10 +629,10 @@ static const char *optional_device_extensions[] = {
};
static bool
append_all(struct comp_compositor *c, struct u_string_list *list, const char *const *arr, uint32_t size)
append_all(struct comp_compositor *c, struct u_string_list *required, const char *const *arr, uint32_t size)
{
for (uint32_t i = 0; i < size; i++) {
int ret = u_string_list_append(list, arr[i]);
int ret = u_string_list_append(required, arr[i]);
if (ret < 0) {
COMP_ERROR(c, "Failed to add %s to instance extension list: %d", arr[i], ret);
return false;
@ -642,46 +642,53 @@ append_all(struct comp_compositor *c, struct u_string_list *list, const char *co
}
static VkResult
select_instances_extensions(struct comp_compositor *c, struct u_string_list *list)
select_instances_extensions(struct comp_compositor *c, struct u_string_list *required, struct u_string_list *optional)
{
switch (c->settings.window_type) {
case WINDOW_NONE: append_all(c, list, instance_extensions_none, ARRAY_SIZE(instance_extensions_none)); break;
case WINDOW_NONE:
append_all(c, required, instance_extensions_none, ARRAY_SIZE(instance_extensions_none));
break;
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
case WINDOW_DIRECT_WAYLAND:
append_all(c, list, instance_extensions_direct_wayland, ARRAY_SIZE(instance_extensions_direct_wayland));
append_all(c, required, instance_extensions_direct_wayland,
ARRAY_SIZE(instance_extensions_direct_wayland));
break;
case WINDOW_WAYLAND:
append_all(c, list, instance_extensions_wayland, ARRAY_SIZE(instance_extensions_wayland));
append_all(c, required, instance_extensions_wayland, ARRAY_SIZE(instance_extensions_wayland));
break;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
case WINDOW_XCB: append_all(c, list, instance_extensions_xcb, ARRAY_SIZE(instance_extensions_xcb)); break;
case WINDOW_XCB: append_all(c, required, instance_extensions_xcb, ARRAY_SIZE(instance_extensions_xcb)); break;
#endif
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
case WINDOW_DIRECT_RANDR:
case WINDOW_DIRECT_NVIDIA:
append_all(c, list, instance_extensions_direct_mode, ARRAY_SIZE(instance_extensions_direct_mode));
append_all(c, required, instance_extensions_direct_mode, ARRAY_SIZE(instance_extensions_direct_mode));
break;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
case WINDOW_ANDROID:
append_all(c, list, instance_extensions_android, ARRAY_SIZE(instance_extensions_android));
append_all(c, required, instance_extensions_android, ARRAY_SIZE(instance_extensions_android));
break;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
case WINDOW_MSWIN:
append_all(c, list, instance_extensions_windows, ARRAY_SIZE(instance_extensions_windows));
append_all(c, required, instance_extensions_windows, ARRAY_SIZE(instance_extensions_windows));
break;
#endif
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
case WINDOW_VK_DISPLAY:
append_all(c, list, instance_extensions_vk_display, ARRAY_SIZE(instance_extensions_vk_display));
append_all(c, required, instance_extensions_vk_display, ARRAY_SIZE(instance_extensions_vk_display));
break;
#endif
default: return VK_ERROR_INITIALIZATION_FAILED;
}
#ifdef VK_EXT_display_surface_counter
u_string_list_append(optional, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
#endif
return VK_SUCCESS;
}
@ -692,13 +699,16 @@ compositor_init_vulkan(struct comp_compositor *c)
VkResult ret;
// every backend needs at least as many extensions as the none window
struct u_string_list *instance_extension_list =
struct u_string_list *required_instance_ext_list =
u_string_list_create_with_capacity(ARRAY_SIZE(instance_extensions_none));
ret = select_instances_extensions(c, instance_extension_list);
struct u_string_list *optional_instance_ext_list = u_string_list_create();
ret = select_instances_extensions(c, required_instance_ext_list, optional_instance_ext_list);
if (ret != VK_SUCCESS) {
CVK_ERROR(c, "select_instances_extensions", "Failed to select instance extensions.", ret);
u_string_list_destroy(&instance_extension_list);
u_string_list_destroy(&required_instance_ext_list);
u_string_list_destroy(&optional_instance_ext_list);
return ret;
}
@ -714,7 +724,8 @@ compositor_init_vulkan(struct comp_compositor *c)
struct comp_vulkan_arguments vk_args = {
.get_instance_proc_address = vkGetInstanceProcAddr,
.required_instance_extensions = instance_extension_list,
.required_instance_extensions = required_instance_ext_list,
.optional_instance_extensions = optional_instance_ext_list,
.required_device_extensions = required_device_extension_list,
.optional_device_extensions = optional_device_extension_list,
.log_level = c->settings.log_level,
@ -726,7 +737,8 @@ compositor_init_vulkan(struct comp_compositor *c)
struct comp_vulkan_results vk_res = {0};
bool bundle_ret = comp_vulkan_init_bundle(vk, &vk_args, &vk_res);
u_string_list_destroy(&instance_extension_list);
u_string_list_destroy(&required_instance_ext_list);
u_string_list_destroy(&optional_instance_ext_list);
u_string_list_destroy(&required_device_extension_list);
u_string_list_destroy(&optional_device_extension_list);

View file

@ -98,7 +98,6 @@ fill_in_results(struct vk_bundle *vk, const struct comp_vulkan_arguments *vk_arg
return VK_SUCCESS;
}
/*
*
* Creation functions.
@ -110,30 +109,16 @@ create_instance(struct vk_bundle *vk, const struct comp_vulkan_arguments *vk_arg
{
VkResult ret;
uint32_t prop_count = 0;
vk->vkEnumerateInstanceExtensionProperties(NULL, &prop_count, NULL);
struct u_string_list *instance_ext_list = vk_build_instance_extensions(
vk, vk_args->required_instance_extensions, vk_args->optional_instance_extensions);
VkExtensionProperties *props = U_TYPED_ARRAY_CALLOC(VkExtensionProperties, prop_count);
vk->vkEnumerateInstanceExtensionProperties(NULL, &prop_count, props);
struct u_string_list *instance_ext_list = u_string_list_create_from_list(vk_args->required_instance_extensions);
uint32_t optional_instance_ext_count = u_string_list_get_size(vk_args->optional_instance_extensions);
const char *const *optional_instance_exts = u_string_list_get_data(vk_args->optional_instance_extensions);
for (uint32_t i = 0; i < optional_instance_ext_count; i++) {
const char *optional_ext = optional_instance_exts[i];
for (uint32_t j = 0; j < prop_count; j++) {
if (strcmp(optional_ext, props[j].extensionName) == 0) {
int added = u_string_list_append_unique(instance_ext_list, optional_ext);
if (added == 0) {
VK_ERROR(vk, "Duplicate device extension %s not added twice", optional_ext);
}
break;
}
}
if (!instance_ext_list) {
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
// Fill this out here.
vk_fill_in_has_instance_extensions(vk, instance_ext_list);
VkApplicationInfo app_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pApplicationName = "Monado Compositor",