The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

c/main: Introduce comp_target_factory

+767 -399
+130 -355
src/xrt/compositor/main/comp_compositor.c
··· 53 53 #include "util/u_pacing.h" 54 54 #include "util/u_handles.h" 55 55 #include "util/u_trace_marker.h" 56 + #include "util/u_pretty_print.h" 56 57 #include "util/u_distortion_mesh.h" 57 58 #include "util/u_verify.h" 58 59 ··· 85 86 * Helper functions. 86 87 * 87 88 */ 88 - 89 - #define CVK_ERROR(C, FUNC, MSG, RET) COMP_ERROR(C, FUNC ": %s\n\t" MSG, vk_result_string(RET)); 90 89 91 90 static double 92 91 ns_to_ms(int64_t ns) ··· 554 553 // If any of these lists are updated, please also update the appropriate column 555 554 // in `vulkan-extensions.md` 556 555 557 - // clang-format off 558 - #define COMP_INSTANCE_EXTENSIONS_COMMON \ 559 - VK_EXT_DEBUG_REPORT_EXTENSION_NAME, \ 560 - VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \ 561 - VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \ 562 - VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, \ 563 - VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ 564 - VK_KHR_SURFACE_EXTENSION_NAME 565 - // clang-format on 566 - 567 556 static const char *instance_extensions_common[] = { 568 557 COMP_INSTANCE_EXTENSIONS_COMMON, 569 558 }; 570 - 571 - #ifdef VK_USE_PLATFORM_XCB_KHR 572 - static const char *instance_extensions_xcb[] = { 573 - VK_KHR_XCB_SURFACE_EXTENSION_NAME, 574 - }; 575 - #endif 576 - 577 - #ifdef VK_USE_PLATFORM_WAYLAND_KHR 578 - static const char *instance_extensions_wayland[] = { 579 - VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 580 - }; 581 - 582 - static const char *instance_extensions_direct_wayland[] = { 583 - VK_KHR_DISPLAY_EXTENSION_NAME, // 584 - VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, // 585 - VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, // 586 - 587 - #ifdef VK_EXT_acquire_drm_display 588 - VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME, 589 - #endif 590 - }; 591 - #endif 592 - 593 - #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 594 - static const char *instance_extensions_direct_mode[] = { 595 - VK_KHR_DISPLAY_EXTENSION_NAME, 596 - VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 597 - VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME, 598 - }; 599 - #endif 600 - 601 - #ifdef VK_USE_PLATFORM_DISPLAY_KHR 602 - static const char *instance_extensions_vk_display[] = { 603 - VK_KHR_DISPLAY_EXTENSION_NAME, 604 - }; 605 - #endif 606 - 607 - #ifdef VK_USE_PLATFORM_ANDROID_KHR 608 - static const char *instance_extensions_android[] = { 609 - VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 610 - }; 611 - #endif 612 - 613 - #ifdef VK_USE_PLATFORM_WIN32_KHR 614 - static const char *instance_extensions_windows[] = { 615 - VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 616 - }; 617 - #endif 618 559 619 560 // Note: Keep synchronized with comp_vk_glue - we should have everything they 620 561 // do, plus VK_KHR_SWAPCHAIN_EXTENSION_NAME ··· 696 637 static VkResult 697 638 select_instances_extensions(struct comp_compositor *c, struct u_string_list *required, struct u_string_list *optional) 698 639 { 699 - switch (c->settings.window_type) { 700 - case WINDOW_NONE: break; 701 - #ifdef VK_USE_PLATFORM_WAYLAND_KHR 702 - case WINDOW_DIRECT_WAYLAND: 703 - u_string_list_append_array(required, instance_extensions_direct_wayland, 704 - ARRAY_SIZE(instance_extensions_direct_wayland)); 705 - break; 640 + assert(c->target_factory != NULL); 706 641 707 - case WINDOW_WAYLAND: 708 - u_string_list_append_array(required, instance_extensions_wayland, 709 - ARRAY_SIZE(instance_extensions_wayland)); 710 - break; 711 - #endif 712 - #ifdef VK_USE_PLATFORM_XCB_KHR 713 - case WINDOW_XCB: 714 - u_string_list_append_array(required, instance_extensions_xcb, ARRAY_SIZE(instance_extensions_xcb)); 715 - break; 716 - #endif 717 - #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 718 - case WINDOW_DIRECT_RANDR: 719 - case WINDOW_DIRECT_NVIDIA: 720 - u_string_list_append_array(required, instance_extensions_direct_mode, 721 - ARRAY_SIZE(instance_extensions_direct_mode)); 722 - break; 723 - #endif 724 - #ifdef VK_USE_PLATFORM_ANDROID_KHR 725 - case WINDOW_ANDROID: 726 - u_string_list_append_array(required, instance_extensions_android, 727 - ARRAY_SIZE(instance_extensions_android)); 728 - break; 729 - #endif 730 - #ifdef VK_USE_PLATFORM_WIN32_KHR 731 - case WINDOW_MSWIN: 732 - u_string_list_append_array(required, instance_extensions_windows, 733 - ARRAY_SIZE(instance_extensions_windows)); 734 - break; 735 - #endif 736 - #ifdef VK_USE_PLATFORM_DISPLAY_KHR 737 - case WINDOW_VK_DISPLAY: 738 - u_string_list_append_array(required, instance_extensions_vk_display, 739 - ARRAY_SIZE(instance_extensions_vk_display)); 740 - break; 741 - #endif 742 - default: return VK_ERROR_INITIALIZATION_FAILED; 743 - } 642 + u_string_list_append_array( // 643 + required, // 644 + c->target_factory->required_instance_extensions, // 645 + c->target_factory->required_instance_extension_count); // 744 646 745 647 #ifdef VK_EXT_display_surface_counter 746 648 u_string_list_append(optional, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME); ··· 829 731 * 830 732 */ 831 733 734 + struct comp_target_factory *ctfs[] = { 735 + #if defined VK_USE_PLATFORM_WAYLAND_KHR && defined XRT_HAVE_WAYLAND_DIRECT 736 + &comp_target_factory_direct_wayland, 737 + #endif 738 + #ifdef VK_USE_PLATFORM_WAYLAND_KHR 739 + &comp_target_factory_wayland, 740 + #endif 832 741 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 833 - static bool 834 - _match_allowlist_entry(const char *al_entry, VkDisplayPropertiesKHR *disp) 835 - { 836 - unsigned long al_entry_length = strlen(al_entry); 837 - unsigned long disp_entry_length = strlen(disp->displayName); 838 - if (disp_entry_length < al_entry_length) 839 - return false; 742 + &comp_target_factory_direct_randr, 743 + #endif 744 + #ifdef VK_USE_PLATFORM_XCB_KHR 745 + &comp_target_factory_xcb, 746 + #endif 747 + #ifdef XRT_OS_ANDROID 748 + &comp_target_factory_android, 749 + #endif 750 + #ifdef XRT_OS_WINDOWS 751 + &comp_target_factory_mswin, 752 + #endif 753 + #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 754 + &comp_target_factory_direct_nvidia, 755 + #endif 756 + #ifdef VK_USE_PLATFORM_DISPLAY_KHR 757 + &comp_target_factory_vk_display, 758 + #endif 759 + }; 840 760 841 - // we have a match with this allowlist entry. 842 - if (strncmp(al_entry, disp->displayName, al_entry_length) == 0) 843 - return true; 761 + static void 762 + error_msg_with_list(struct comp_compositor *c, const char *msg) 763 + { 764 + struct u_pp_sink_stack_only sink; 765 + u_pp_delegate_t dg = u_pp_sink_stack_only_init(&sink); 766 + u_pp(dg, "%s, available targets:", msg); 767 + for (size_t i = 0; i < ARRAY_SIZE(ctfs); i++) { 768 + u_pp(dg, "\n\t%s: %s", ctfs[i]->identifier, ctfs[i]->name); 769 + } 844 770 845 - return false; 771 + COMP_ERROR(c, "%s", sink.buffer); 846 772 } 847 773 848 - /* 849 - * our physical device is an nvidia card, we can potentially select 850 - * nvidia-specific direct mode. 851 - * 852 - * we need to also check if we are confident that we can create a direct mode 853 - * display, if not we need to abandon the attempt here, and allow desktop-window 854 - * fallback to occur. 855 - */ 856 - 857 774 static bool 858 - _test_for_nvidia(struct comp_compositor *c, struct vk_bundle *vk) 775 + compositor_check_deferred(struct comp_compositor *c, struct comp_target_factory *ctf) 859 776 { 860 - VkResult ret; 861 - 862 - VkPhysicalDeviceProperties physical_device_properties; 863 - vk->vkGetPhysicalDeviceProperties(vk->physical_device, &physical_device_properties); 864 - 865 - if (physical_device_properties.vendorID != 0x10DE) 866 - return false; 867 - 868 - // get a list of attached displays 869 - uint32_t display_count; 870 - 871 - ret = vk->vkGetPhysicalDeviceDisplayPropertiesKHR(vk->physical_device, &display_count, NULL); 872 - if (ret != VK_SUCCESS) { 873 - CVK_ERROR(c, "vkGetPhysicalDeviceDisplayPropertiesKHR", "Failed to get vulkan display count", ret); 874 - return false; 875 - } 876 - 877 - VkDisplayPropertiesKHR *display_props = U_TYPED_ARRAY_CALLOC(VkDisplayPropertiesKHR, display_count); 878 - 879 - if (display_props && vk->vkGetPhysicalDeviceDisplayPropertiesKHR(vk->physical_device, &display_count, 880 - display_props) != VK_SUCCESS) { 881 - CVK_ERROR(c, "vkGetPhysicalDeviceDisplayPropertiesKHR", "Failed to get display properties", ret); 882 - free(display_props); 883 - return false; 884 - } 885 - 886 - for (uint32_t i = 0; i < display_count; i++) { 887 - VkDisplayPropertiesKHR *disp = display_props + i; 888 - // check this display against our allowlist 889 - for (uint32_t j = 0; j < ARRAY_SIZE(NV_DIRECT_ALLOWLIST); j++) { 890 - if (_match_allowlist_entry(NV_DIRECT_ALLOWLIST[j], disp)) { 891 - free(display_props); 892 - return true; 893 - } 894 - } 777 + struct comp_target *ct = NULL; 895 778 896 - if (c->settings.nvidia_display && _match_allowlist_entry(c->settings.nvidia_display, disp)) { 897 - free(display_props); 898 - return true; 899 - } 779 + if (!ctf->is_deferred) { 780 + return false; // It is not deferred but that's okay. 900 781 } 901 782 902 - COMP_ERROR(c, "NVIDIA: No allowlisted displays found!"); 903 - 904 - COMP_ERROR(c, "== Current Allowlist =="); 905 - for (uint32_t i = 0; i < ARRAY_SIZE(NV_DIRECT_ALLOWLIST); i++) 906 - COMP_ERROR(c, "%s", NV_DIRECT_ALLOWLIST[i]); 783 + COMP_DEBUG(c, "Deferred target backend %s selected!", ct->name); 907 784 908 - COMP_ERROR(c, "== Found Displays =="); 909 - for (uint32_t i = 0; i < display_count; i++) 910 - COMP_ERROR(c, "%s", display_props[i].displayName); 785 + c->target_factory = ctf; 786 + c->deferred_surface = true; 911 787 912 - 913 - free(display_props); 914 - 915 - return false; 788 + return true; 916 789 } 917 - #endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT 918 790 919 791 static bool 920 - compositor_check_vulkan_caps(struct comp_compositor *c) 792 + compositor_try_window(struct comp_compositor *c, struct comp_target_factory *ctf) 921 793 { 922 794 COMP_TRACE_MARKER(); 923 795 924 - #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 925 - VkResult ret; 796 + struct comp_target *ct = NULL; 926 797 927 - // this is duplicative, but seems to be the easiest way to 928 - // 'pre-check' capabilities when window creation precedes vulkan 929 - // instance creation. we also need to load the VK_KHR_DISPLAY 930 - // extension. 931 - 932 - if (c->settings.window_type != WINDOW_AUTO) { 933 - COMP_DEBUG(c, "Skipping NVIDIA detection, window type forced."); 934 - return true; 798 + if (!ctf->create_target(ctf, c, &ct)) { 799 + return false; 935 800 } 936 - COMP_DEBUG(c, "Checking for NVIDIA vulkan driver."); 937 801 938 - struct vk_bundle temp_vk_storage = {0}; 939 - struct vk_bundle *temp_vk = &temp_vk_storage; 940 - temp_vk->log_level = U_LOGGING_WARN; 941 - 942 - ret = vk_get_loader_functions(temp_vk, vkGetInstanceProcAddr); 943 - if (ret != VK_SUCCESS) { 944 - CVK_ERROR(c, "vk_get_loader_functions", "Failed to get loader functions.", ret); 802 + if (!comp_target_init_pre_vulkan(ct)) { 803 + ct->destroy(ct); 945 804 return false; 946 805 } 947 806 948 - const char *extension_names[] = {COMP_INSTANCE_EXTENSIONS_COMMON, VK_KHR_DISPLAY_EXTENSION_NAME}; 807 + COMP_DEBUG(c, "Target backend %s initialized!", ct->name); 949 808 809 + c->target_factory = ctf; 810 + c->target = ct; 950 811 951 - VkInstanceCreateInfo instance_create_info = { 952 - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 953 - .enabledExtensionCount = ARRAY_SIZE(extension_names), 954 - .ppEnabledExtensionNames = extension_names, 955 - }; 812 + return true; 813 + } 956 814 957 - ret = temp_vk->vkCreateInstance(&instance_create_info, NULL, &(temp_vk->instance)); 958 - if (ret != VK_SUCCESS) { 959 - CVK_ERROR(c, "vkCreateInstance", "Failed to create VkInstance.", ret); 960 - return false; 961 - } 815 + static bool 816 + select_target_factory_from_settings(struct comp_compositor *c, struct comp_target_factory **out_ctf) 817 + { 818 + const char *identifier = c->settings.target_identifier; 962 819 963 - ret = vk_get_instance_functions(temp_vk); 964 - if (ret != VK_SUCCESS) { 965 - CVK_ERROR(c, "vk_get_instance_functions", "Failed to get Vulkan instance functions.", ret); 966 - return false; 820 + if (identifier == NULL) { 821 + return true; // Didn't ask for a target, all ok. 967 822 } 968 823 969 - bool use_compute = c->settings.use_compute; 970 - 971 - struct u_string_list *required_device_ext_list = 972 - u_string_list_create_from_array(required_device_extensions, ARRAY_SIZE(required_device_extensions)); 973 - 974 - struct u_string_list *optional_device_ext_list = 975 - u_string_list_create_from_array(optional_device_extensions, ARRAY_SIZE(optional_device_extensions)); 976 - 977 - // follow same device selection logic as subsequent calls 978 - ret = vk_create_device( // 979 - temp_vk, // 980 - c->settings.selected_gpu_index, // 981 - use_compute, // compute_only 982 - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT, // global_priority 983 - required_device_ext_list, // 984 - optional_device_ext_list, // 985 - NULL); // optional_device_features 824 + for (size_t i = 0; i < ARRAY_SIZE(ctfs); i++) { 825 + struct comp_target_factory *ctf = ctfs[i]; 986 826 987 - u_string_list_destroy(&required_device_ext_list); 988 - u_string_list_destroy(&optional_device_ext_list); 989 - 990 - if (ret != VK_SUCCESS) { 991 - CVK_ERROR(c, "vk_create_device", "Failed to create VkDevice.", ret); 992 - return false; 827 + if (strcmp(ctf->identifier, identifier) == 0) { 828 + *out_ctf = ctf; 829 + return true; 830 + } 993 831 } 994 832 995 - if (_test_for_nvidia(c, temp_vk)) { 996 - c->settings.window_type = WINDOW_DIRECT_NVIDIA; 997 - COMP_DEBUG(c, "Selecting direct NVIDIA window type!"); 998 - } 833 + char buffer[256]; 834 + snprintf(buffer, ARRAY_SIZE(buffer), "Could not find target factory with identifier '%s'", identifier); 835 + error_msg_with_list(c, buffer); 999 836 1000 - temp_vk->vkDestroyDevice(temp_vk->device, NULL); 1001 - temp_vk->vkDestroyInstance(temp_vk->instance, NULL); 1002 - 1003 - #endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT 1004 - return true; 837 + return false; // User asked for a target that we couldn't find, error. 1005 838 } 1006 839 1007 840 static bool 1008 - compositor_try_window(struct comp_compositor *c, struct comp_target *ct) 841 + select_target_factory_by_detecting(struct comp_compositor *c, struct comp_target_factory **out_ctf) 1009 842 { 1010 - if (ct == NULL) { 1011 - return false; 1012 - } 843 + for (size_t i = 0; i < ARRAY_SIZE(ctfs); i++) { 844 + struct comp_target_factory *ctf = ctfs[i]; 1013 845 1014 - if (!comp_target_init_pre_vulkan(ct)) { 1015 - ct->destroy(ct); 1016 - return false; 846 + if (comp_target_factory_detect(ctf, c)) { 847 + *out_ctf = ctf; 848 + return true; 849 + } 1017 850 } 1018 851 1019 - COMP_DEBUG(c, "Window backend %s initialized!", ct->name); 1020 - 1021 - c->target = ct; 1022 - 1023 - return true; 852 + return true; // Didn't detect a target, but that's ok. 1024 853 } 1025 854 1026 855 static bool ··· 1028 857 { 1029 858 COMP_TRACE_MARKER(); 1030 859 1031 - // Nothing to do for nvidia and vk_display. 1032 - if (c->settings.window_type == WINDOW_DIRECT_NVIDIA || c->settings.window_type == WINDOW_VK_DISPLAY) { 1033 - return true; 860 + struct comp_target_factory *selected_ctf = NULL; 861 + 862 + if (selected_ctf == NULL && !select_target_factory_from_settings(c, &selected_ctf)) { 863 + return false; // Error! 1034 864 } 1035 865 1036 - switch (c->settings.window_type) { 1037 - case WINDOW_AUTO: 1038 - #if defined VK_USE_PLATFORM_WAYLAND_KHR && defined XRT_HAVE_WAYLAND_DIRECT 1039 - if (compositor_try_window(c, comp_window_direct_wayland_create(c))) { 1040 - c->settings.window_type = WINDOW_DIRECT_WAYLAND; 866 + if (selected_ctf == NULL && !select_target_factory_by_detecting(c, &selected_ctf)) { 867 + return false; // Error! 868 + } 869 + 870 + if (selected_ctf != NULL) { 871 + // We have selected a target factory, but it needs Vulkan. 872 + if (selected_ctf->requires_vulkan_for_create) { 873 + COMP_INFO(c, "Selected %s backend!", selected_ctf->name); 874 + c->target_factory = selected_ctf; 1041 875 return true; 1042 876 } 1043 - #endif 1044 - #ifdef VK_USE_PLATFORM_WAYLAND_KHR 1045 - if (compositor_try_window(c, comp_window_wayland_create(c))) { 1046 - c->settings.window_type = WINDOW_WAYLAND; 877 + 878 + if (compositor_check_deferred(c, selected_ctf)) { 1047 879 return true; 1048 880 } 1049 - #endif 1050 - #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 1051 - if (compositor_try_window(c, comp_window_direct_randr_create(c))) { 1052 - c->settings.window_type = WINDOW_DIRECT_RANDR; 1053 - return true; 881 + 882 + if (!compositor_try_window(c, selected_ctf)) { 883 + COMP_ERROR(c, "Failed to init %s backend!", selected_ctf->name); 884 + return false; 1054 885 } 1055 - #endif 1056 - #ifdef VK_USE_PLATFORM_XCB_KHR 1057 - if (compositor_try_window(c, comp_window_xcb_create(c))) { 1058 - c->settings.window_type = WINDOW_XCB; 1059 - COMP_DEBUG(c, "Using VK_PRESENT_MODE_IMMEDIATE_KHR for xcb window") 1060 - c->settings.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; 1061 - return true; 886 + 887 + return true; 888 + } 889 + 890 + for (size_t i = 0; i < ARRAY_SIZE(ctfs); i++) { 891 + struct comp_target_factory *ctf = ctfs[i]; 892 + 893 + // Skip targets that requires Vulkan. 894 + if (ctf->requires_vulkan_for_create) { 895 + continue; 1062 896 } 1063 - #endif 1064 - #ifdef XRT_OS_ANDROID 1065 - if (compositor_try_window(c, comp_window_android_create(c))) { 1066 - c->settings.window_type = WINDOW_ANDROID; 897 + 898 + if (compositor_check_deferred(c, ctf)) { 1067 899 return true; 1068 900 } 1069 - #endif 1070 - #ifdef XRT_OS_WINDOWS 1071 - if (compositor_try_window(c, comp_window_mswin_create(c))) { 1072 - c->settings.window_type = WINDOW_MSWIN; 901 + 902 + if (compositor_try_window(c, ctf)) { 1073 903 return true; 1074 904 } 1075 - #endif 1076 - COMP_ERROR(c, "Failed to auto detect window support!"); 1077 - break; 1078 - case WINDOW_XCB: 1079 - #ifdef VK_USE_PLATFORM_XCB_KHR 1080 - compositor_try_window(c, comp_window_xcb_create(c)); 1081 - COMP_DEBUG(c, "Using VK_PRESENT_MODE_IMMEDIATE_KHR for xcb window") 1082 - c->settings.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; 1083 - #else 1084 - COMP_ERROR(c, "XCB support not compiled in!"); 1085 - #endif 1086 - break; 1087 - case WINDOW_WAYLAND: 1088 - #ifdef VK_USE_PLATFORM_WAYLAND_KHR 1089 - compositor_try_window(c, comp_window_wayland_create(c)); 1090 - #else 1091 - COMP_ERROR(c, "Wayland support not compiled in!"); 1092 - #endif 1093 - break; 1094 - case WINDOW_DIRECT_WAYLAND: 1095 - #if defined VK_USE_PLATFORM_WAYLAND_KHR && defined XRT_HAVE_WAYLAND_DIRECT 1096 - compositor_try_window(c, comp_window_direct_wayland_create(c)); 1097 - #else 1098 - COMP_ERROR(c, "Wayland direct support not compiled in!"); 1099 - #endif 1100 - break; 1101 - case WINDOW_DIRECT_RANDR: 1102 - #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 1103 - compositor_try_window(c, comp_window_direct_randr_create(c)); 1104 - #else 1105 - COMP_ERROR(c, "Direct mode support not compiled in!"); 1106 - #endif 1107 - break; 1108 - case WINDOW_ANDROID: 1109 - #ifdef XRT_OS_ANDROID 1110 - compositor_try_window(c, comp_window_android_create(c)); 1111 - #else 1112 - COMP_ERROR(c, "Android support not compiled in!"); 1113 - #endif 1114 - break; 905 + } 1115 906 1116 - case WINDOW_MSWIN: 1117 - #ifdef XRT_OS_WINDOWS 1118 - compositor_try_window(c, comp_window_mswin_create(c)); 1119 - #else 1120 - COMP_ERROR(c, "Windows support not compiled in!"); 1121 - #endif 1122 - break; 1123 - default: COMP_ERROR(c, "Unknown window type!"); break; 1124 - } 907 + // Nothing worked, giving up. 908 + error_msg_with_list(c, "Failed to create any target"); 1125 909 1126 - // Failed to create? 1127 - return c->target != NULL; 910 + return false; 1128 911 } 1129 912 1130 913 static bool 1131 914 compositor_init_window_post_vulkan(struct comp_compositor *c) 1132 915 { 1133 - if (c->settings.window_type == WINDOW_DIRECT_NVIDIA) { 1134 - #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 1135 - return compositor_try_window(c, comp_window_direct_nvidia_create(c)); 1136 - #else 1137 - assert(false && "NVIDIA direct mode depends on the xlib/xrandr direct mode."); 1138 - return false; 1139 - #endif 1140 - } 916 + COMP_TRACE_MARKER(); 917 + 918 + assert(c->target_factory != NULL); 1141 919 1142 - if (c->settings.window_type == WINDOW_VK_DISPLAY) { 1143 - #ifdef VK_USE_PLATFORM_DISPLAY_KHR 1144 - return compositor_try_window(c, comp_window_vk_display_create(c)); 1145 - #else 1146 - assert(false && "VkDisplayKHR direct mode depends on VK_USE_PLATFORM_DISPLAY_KHR."); 1147 - return false; 1148 - #endif 920 + if (c->target != NULL) { 921 + return true; 1149 922 } 1150 923 1151 - return true; 924 + return compositor_try_window(c, c->target_factory); 1152 925 } 1153 926 1154 927 static bool 1155 928 compositor_init_swapchain(struct comp_compositor *c) 1156 929 { 1157 930 COMP_TRACE_MARKER(); 931 + 932 + assert(c->target != NULL); 933 + assert(c->target_factory != NULL); 1158 934 1159 935 if (comp_target_init_post_vulkan(c->target, // 1160 936 c->settings.preferred.width, // ··· 1260 1036 1261 1037 // clang-format off 1262 1038 if (!compositor_check_and_prepare_xdev(c, xdev) || 1263 - !compositor_check_vulkan_caps(c) || 1264 1039 !compositor_init_window_pre_vulkan(c) || 1265 1040 !compositor_init_vulkan(c) || 1266 1041 !compositor_init_render_resources(c)) {
+29
src/xrt/compositor/main/comp_compositor.h
··· 30 30 #include "main/comp_renderer.h" 31 31 32 32 struct comp_window_peek; 33 + struct comp_target_factory; 33 34 34 35 #ifdef __cplusplus 35 36 extern "C" { 36 37 #endif 37 38 39 + 40 + /* 41 + * 42 + * Defines 43 + * 44 + */ 45 + 46 + // clang-format off 47 + #define COMP_INSTANCE_EXTENSIONS_COMMON \ 48 + VK_EXT_DEBUG_REPORT_EXTENSION_NAME, \ 49 + VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \ 50 + VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \ 51 + VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, \ 52 + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \ 53 + VK_KHR_SURFACE_EXTENSION_NAME 54 + // clang-format on 55 + 56 + 38 57 /* 39 58 * 40 59 * Structs ··· 88 107 89 108 //! Vulkan resources that the compositor (renderer) uses. 90 109 struct render_resources nr; 110 + 111 + //! The selected target factory that we create our target from. 112 + struct comp_target_factory *target_factory; 91 113 92 114 //! The target we are displaying to. 93 115 struct comp_target *target; ··· 155 177 { 156 178 return (struct comp_compositor *)xc; 157 179 } 180 + 181 + /*! 182 + * Helper define for printing Vulkan errors. 183 + * 184 + * @relates comp_compositor 185 + */ 186 + #define CVK_ERROR(C, FUNC, MSG, RET) COMP_ERROR(C, FUNC ": %s\n\t" MSG, vk_result_string(RET)); 158 187 159 188 /*! 160 189 * Spew level logging.
+10 -9
src/xrt/compositor/main/comp_settings.c
··· 68 68 s->display = debug_get_num_option_xcb_display(); 69 69 s->color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; 70 70 s->present_mode = VK_PRESENT_MODE_FIFO_KHR; 71 - s->window_type = WINDOW_AUTO; 72 71 s->fullscreen = debug_get_bool_option_xcb_fullscreen(); 73 72 s->preferred.width = xdev->hmd->screens[0].w_pixels; 74 73 s->preferred.height = xdev->hmd->screens[0].h_pixels; ··· 80 79 s->desired_mode = debug_get_num_option_desired_mode(); 81 80 s->viewport_scale = debug_get_num_option_scale_percentage() / 100.0; 82 81 82 + 83 + s->nvidia_display = debug_get_option_nvidia_display(); 83 84 if (debug_get_bool_option_force_nvidia()) { 84 - s->window_type = WINDOW_DIRECT_NVIDIA; 85 + s->target_identifier = "x11_direct_nvidia"; 85 86 } 86 87 87 - s->nvidia_display = debug_get_option_nvidia_display(); 88 88 s->vk_display = debug_get_num_option_vk_display(); 89 89 if (s->vk_display >= 0) { 90 - s->window_type = WINDOW_VK_DISPLAY; 90 + s->target_identifier = "vk_display"; 91 91 } 92 92 93 93 if (debug_get_bool_option_force_randr()) { 94 - s->window_type = WINDOW_DIRECT_RANDR; 94 + s->target_identifier = "x11_direct"; 95 95 } 96 96 97 97 if (debug_get_bool_option_force_wayland_direct()) { 98 - s->window_type = WINDOW_DIRECT_WAYLAND; 98 + s->target_identifier = "wayland_direct"; 99 99 } 100 100 101 + if (debug_get_bool_option_force_xcb()) { 102 + s->target_identifier = "x11"; 101 103 102 - if (debug_get_bool_option_force_xcb()) { 103 - s->window_type = WINDOW_XCB; 104 104 // HMD screen tends to be much larger then monitors. 105 105 s->preferred.width /= 2; 106 106 s->preferred.height /= 2; 107 107 } 108 108 if (debug_get_bool_option_force_wayland()) { 109 - s->window_type = WINDOW_WAYLAND; 109 + s->target_identifier = "wayland"; 110 + 110 111 // HMD screen tends to be much larger then monitors. 111 112 s->preferred.width /= 2; 112 113 s->preferred.height /= 2;
+2 -22
src/xrt/compositor/main/comp_settings.h
··· 38 38 }; 39 39 40 40 /*! 41 - * Window type to use. 42 - * 43 - * @ingroup comp_main 44 - */ 45 - enum window_type 46 - { 47 - WINDOW_NONE = 0, 48 - WINDOW_AUTO, 49 - WINDOW_XCB, 50 - WINDOW_WAYLAND, 51 - WINDOW_DIRECT_WAYLAND, 52 - WINDOW_DIRECT_RANDR, 53 - WINDOW_DIRECT_NVIDIA, 54 - WINDOW_ANDROID, 55 - WINDOW_MSWIN, 56 - WINDOW_VK_DISPLAY, 57 - }; 58 - 59 - 60 - /*! 61 41 * Settings for the compositor. 62 42 * 63 43 * @ingroup comp_main ··· 72 52 VkColorSpaceKHR color_space; 73 53 VkPresentModeKHR present_mode; 74 54 75 - //! Window type to use. 76 - enum window_type window_type; 55 + //! Preferred window type to use, not actual used. 56 + const char *target_identifier; 77 57 78 58 //! display string forced by user or NULL 79 59 const char *nvidia_display;
+75
src/xrt/compositor/main/comp_target.h
··· 519 519 *ct_ptr = NULL; 520 520 } 521 521 522 + /*! 523 + * A factory of targets. 524 + * 525 + * @ingroup comp_main 526 + */ 527 + struct comp_target_factory 528 + { 529 + //! Pretty loggable name of target type. 530 + const char *name; 531 + 532 + //! Short all lowercaps identifier for target type. 533 + const char *identifier; 534 + 535 + //! Does this factory require Vulkan to have been initialized. 536 + bool requires_vulkan_for_create; 537 + 538 + /*! 539 + * Is this a deferred target that can have it's creation 540 + * delayed even further then after Vulkan initialization. 541 + */ 542 + bool is_deferred; 543 + 544 + //! Required instance extensions. 545 + const char **required_instance_extensions; 546 + 547 + //! Required instance extension count. 548 + size_t required_instance_extension_count; 549 + 550 + /*! 551 + * Checks if this target can be detected, is the preferred target or 552 + * some other special considiration that this target should be used over 553 + * all other targets. 554 + * 555 + * This is needed for NVIDIA direct mode which window must be created 556 + * after vulkan has initialized. 557 + */ 558 + bool (*detect)(struct comp_target_factory *ctf, struct comp_compositor *c); 559 + 560 + /*! 561 + * Create a target from this factory, some targets requires Vulkan to 562 + * have been initialised, see @ref requires_vulkan_for_create. 563 + */ 564 + bool (*create_target)(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct); 565 + }; 566 + 567 + /*! 568 + * @copydoc comp_target_factory::detect 569 + * 570 + * @public @memberof comp_target_factory 571 + * @ingroup comp_main 572 + */ 573 + static inline bool 574 + comp_target_factory_detect(struct comp_target_factory *ctf, struct comp_compositor *c) 575 + { 576 + COMP_TRACE_MARKER(); 577 + 578 + return ctf->detect(ctf, c); 579 + } 580 + 581 + /*! 582 + * @copydoc comp_target_factory::create_target 583 + * 584 + * @public @memberof comp_target_factory 585 + * @ingroup comp_main 586 + */ 587 + static inline bool 588 + comp_target_factory_create_target(struct comp_target_factory *ctf, 589 + struct comp_compositor *c, 590 + struct comp_target **out_ct) 591 + { 592 + COMP_TRACE_MARKER(); 593 + 594 + return ctf->create_target(ctf, c, out_ct); 595 + } 596 + 522 597 523 598 #ifdef __cplusplus 524 599 }
+22 -4
src/xrt/compositor/main/comp_window.h
··· 27 27 */ 28 28 29 29 #ifdef VK_USE_PLATFORM_XCB_KHR 30 + 30 31 /*! 31 32 * Create a xcb window. 32 33 * ··· 35 36 */ 36 37 struct comp_target * 37 38 comp_window_xcb_create(struct comp_compositor *c); 38 - #endif 39 + 40 + extern struct comp_target_factory comp_target_factory_xcb; 41 + 42 + #endif // VK_USE_PLATFORM_XCB_KHR 39 43 40 44 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 45 + 41 46 /*! 42 47 * Create a wayland window. 43 48 * ··· 47 52 struct comp_target * 48 53 comp_window_wayland_create(struct comp_compositor *c); 49 54 55 + extern struct comp_target_factory comp_target_factory_wayland; 56 + 50 57 /*! 51 58 * Create a direct surface to a HMD using Wayland. 52 59 * ··· 55 62 struct comp_target * 56 63 comp_window_direct_wayland_create(struct comp_compositor *c); 57 64 58 - #endif 65 + extern struct comp_target_factory comp_target_factory_direct_wayland; 66 + 67 + #endif // VK_USE_PLATFORM_WAYLAND_KHR 59 68 60 69 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 61 70 /*! ··· 67 76 struct comp_target * 68 77 comp_window_direct_randr_create(struct comp_compositor *c); 69 78 79 + extern struct comp_target_factory comp_target_factory_direct_randr; 80 + 70 81 /*! 71 82 * Create a direct surface to an HMD on NVIDIA. 72 83 * ··· 75 86 */ 76 87 struct comp_target * 77 88 comp_window_direct_nvidia_create(struct comp_compositor *c); 78 - #endif 89 + 90 + extern struct comp_target_factory comp_target_factory_direct_nvidia; 91 + #endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT 79 92 93 + #if 1 80 94 /*! 81 95 * Create a direct surface to an HMD on VkDisplay. 82 96 * ··· 86 100 struct comp_target * 87 101 comp_window_vk_display_create(struct comp_compositor *c); 88 102 89 - #ifdef XRT_OS_ANDROID 103 + extern struct comp_target_factory comp_target_factory_vk_display; 104 + #endif // 1 90 105 106 + #ifdef XRT_OS_ANDROID 91 107 /*! 92 108 * Create a surface to an HMD on Android. 93 109 * ··· 97 113 struct comp_target * 98 114 comp_window_android_create(struct comp_compositor *c); 99 115 116 + extern struct comp_target_factory comp_target_factory_android; 100 117 #endif // XRT_OS_ANDROID 101 118 102 119 #ifdef XRT_OS_WINDOWS ··· 110 127 struct comp_target * 111 128 comp_window_mswin_create(struct comp_compositor *c); 112 129 130 + extern struct comp_target_factory comp_target_factory_mswin; 113 131 #endif // XRT_OS_WINDOWS 114 132 115 133 #ifdef __cplusplus
+41
src/xrt/compositor/main/comp_window_android.c
··· 180 180 181 181 return &w->base.base; 182 182 } 183 + 184 + 185 + /* 186 + * 187 + * Factory 188 + * 189 + */ 190 + 191 + static const char *instance_extensions[] = { 192 + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 193 + }; 194 + 195 + static bool 196 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 197 + { 198 + return false; 199 + } 200 + 201 + static bool 202 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 203 + { 204 + struct comp_target *ct = comp_window_android_create(c); 205 + if (ct == NULL) { 206 + return false; 207 + } 208 + 209 + *out_ct = ct; 210 + 211 + return true; 212 + } 213 + 214 + struct comp_target_factory comp_target_factory_android = { 215 + .name = "Android", 216 + .identifier = "android", 217 + .requires_vulkan_for_create = false, 218 + .is_deferred = false, 219 + .required_instance_extensions = instance_extensions, 220 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 221 + .detect = detect, 222 + .create_target = create_target, 223 + };
+7 -9
src/xrt/compositor/main/comp_window_direct.c
··· 234 234 if (ret != VK_SUCCESS) { 235 235 COMP_ERROR(cts->base.c, "vkAcquireXlibDisplayEXT: %s (0x%016" PRIx64 ")", vk_result_string(ret), 236 236 (uint64_t)display); 237 - if (cts->base.c->settings.window_type == WINDOW_DIRECT_NVIDIA && 238 - ret == VK_ERROR_INITIALIZATION_FAILED) { 239 - COMP_ERROR(cts->base.c, 240 - "This can be caused by the AllowHMD " 241 - "xorg.conf option. Please make sure that " 242 - "AllowHMD is not set (like in '99-HMD.conf' " 243 - "from OpenHMD) and that the desktop is not " 244 - "currently extended to this display."); 245 - } 237 + } 238 + if (ret == VK_ERROR_INITIALIZATION_FAILED) { 239 + COMP_ERROR( 240 + cts->base.c, 241 + "If you are using the NVIDIA proprietary driver the above error can be caused by the AllowHMD " 242 + "xorg.conf option. Please make sure that AllowHMD is not set (like in '99-HMD.conf' from OpenHMD) " 243 + "and that the desktop is not currently extended to this display."); 246 244 } 247 245 return ret; 248 246 }
+194
src/xrt/compositor/main/comp_window_direct_nvidia.c
··· 253 253 254 254 return comp_window_direct_init_swapchain(&w_direct->base, w_direct->dpy, d->display, width, height); 255 255 } 256 + 257 + 258 + /* 259 + * 260 + * Factory 261 + * 262 + */ 263 + 264 + static const char *instance_extensions[] = { 265 + VK_KHR_DISPLAY_EXTENSION_NAME, 266 + VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 267 + VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME, 268 + }; 269 + 270 + static bool 271 + _match_allowlist_entry(const char *al_entry, VkDisplayPropertiesKHR *disp) 272 + { 273 + unsigned long al_entry_length = strlen(al_entry); 274 + unsigned long disp_entry_length = strlen(disp->displayName); 275 + if (disp_entry_length < al_entry_length) 276 + return false; 277 + 278 + // we have a match with this allowlist entry. 279 + if (strncmp(al_entry, disp->displayName, al_entry_length) == 0) 280 + return true; 281 + 282 + return false; 283 + } 284 + 285 + /* 286 + * our physical device is an nvidia card, we can potentially select 287 + * nvidia-specific direct mode. 288 + * 289 + * we need to also check if we are confident that we can create a direct mode 290 + * display, if not we need to abandon the attempt here, and allow desktop-window 291 + * fallback to occur. 292 + */ 293 + 294 + static bool 295 + _test_for_nvidia(struct comp_compositor *c, struct vk_bundle *vk) 296 + { 297 + VkResult ret; 298 + 299 + VkPhysicalDeviceProperties physical_device_properties; 300 + vk->vkGetPhysicalDeviceProperties(vk->physical_device, &physical_device_properties); 301 + 302 + if (physical_device_properties.vendorID != 0x10DE) 303 + return false; 304 + 305 + // get a list of attached displays 306 + uint32_t display_count; 307 + 308 + ret = vk->vkGetPhysicalDeviceDisplayPropertiesKHR(vk->physical_device, &display_count, NULL); 309 + if (ret != VK_SUCCESS) { 310 + CVK_ERROR(c, "vkGetPhysicalDeviceDisplayPropertiesKHR", "Failed to get vulkan display count", ret); 311 + return false; 312 + } 313 + 314 + VkDisplayPropertiesKHR *display_props = U_TYPED_ARRAY_CALLOC(VkDisplayPropertiesKHR, display_count); 315 + 316 + if (display_props && vk->vkGetPhysicalDeviceDisplayPropertiesKHR(vk->physical_device, &display_count, 317 + display_props) != VK_SUCCESS) { 318 + CVK_ERROR(c, "vkGetPhysicalDeviceDisplayPropertiesKHR", "Failed to get display properties", ret); 319 + free(display_props); 320 + return false; 321 + } 322 + 323 + for (uint32_t i = 0; i < display_count; i++) { 324 + VkDisplayPropertiesKHR *disp = display_props + i; 325 + // check this display against our allowlist 326 + for (uint32_t j = 0; j < ARRAY_SIZE(NV_DIRECT_ALLOWLIST); j++) { 327 + if (_match_allowlist_entry(NV_DIRECT_ALLOWLIST[j], disp)) { 328 + free(display_props); 329 + return true; 330 + } 331 + } 332 + 333 + if (c->settings.nvidia_display && _match_allowlist_entry(c->settings.nvidia_display, disp)) { 334 + free(display_props); 335 + return true; 336 + } 337 + } 338 + 339 + COMP_ERROR(c, "NVIDIA: No allowlisted displays found!"); 340 + 341 + COMP_ERROR(c, "== Current Allowlist =="); 342 + for (uint32_t i = 0; i < ARRAY_SIZE(NV_DIRECT_ALLOWLIST); i++) 343 + COMP_ERROR(c, "%s", NV_DIRECT_ALLOWLIST[i]); 344 + 345 + COMP_ERROR(c, "== Found Displays =="); 346 + for (uint32_t i = 0; i < display_count; i++) 347 + COMP_ERROR(c, "%s", display_props[i].displayName); 348 + 349 + 350 + free(display_props); 351 + 352 + return false; 353 + } 354 + 355 + static bool 356 + check_vulkan_caps(struct comp_compositor *c, bool *out_detected) 357 + { 358 + VkResult ret; 359 + 360 + *out_detected = false; 361 + 362 + // this is duplicative, but seems to be the easiest way to 363 + // 'pre-check' capabilities when window creation precedes vulkan 364 + // instance creation. we also need to load the VK_KHR_DISPLAY 365 + // extension. 366 + 367 + COMP_DEBUG(c, "Checking for NVIDIA vulkan driver."); 368 + 369 + struct vk_bundle temp_vk_storage = {0}; 370 + struct vk_bundle *temp_vk = &temp_vk_storage; 371 + temp_vk->log_level = U_LOGGING_WARN; 372 + 373 + ret = vk_get_loader_functions(temp_vk, vkGetInstanceProcAddr); 374 + if (ret != VK_SUCCESS) { 375 + CVK_ERROR(c, "vk_get_loader_functions", "Failed to get loader functions.", ret); 376 + return false; 377 + } 378 + 379 + const char *extension_names[] = {COMP_INSTANCE_EXTENSIONS_COMMON, VK_KHR_DISPLAY_EXTENSION_NAME}; 380 + 381 + VkInstanceCreateInfo instance_create_info = { 382 + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 383 + .enabledExtensionCount = ARRAY_SIZE(extension_names), 384 + .ppEnabledExtensionNames = extension_names, 385 + }; 386 + 387 + ret = temp_vk->vkCreateInstance(&instance_create_info, NULL, &(temp_vk->instance)); 388 + if (ret != VK_SUCCESS) { 389 + CVK_ERROR(c, "vkCreateInstance", "Failed to create VkInstance.", ret); 390 + return false; 391 + } 392 + 393 + ret = vk_get_instance_functions(temp_vk); 394 + if (ret != VK_SUCCESS) { 395 + CVK_ERROR(c, "vk_get_instance_functions", "Failed to get Vulkan instance functions.", ret); 396 + return false; 397 + } 398 + 399 + ret = vk_select_physical_device(temp_vk, c->settings.selected_gpu_index); 400 + if (ret != VK_SUCCESS) { 401 + CVK_ERROR(c, "vk_select_physical_device", "Failed to select physical device.", ret); 402 + return false; 403 + } 404 + 405 + if (_test_for_nvidia(c, temp_vk)) { 406 + *out_detected = true; 407 + COMP_DEBUG(c, "Selecting direct NVIDIA window type!"); 408 + } 409 + 410 + temp_vk->vkDestroyInstance(temp_vk->instance, NULL); 411 + 412 + return true; 413 + } 414 + 415 + static bool 416 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 417 + { 418 + bool detected = false; 419 + 420 + if (!check_vulkan_caps(c, &detected)) { 421 + return false; 422 + } 423 + 424 + return detected; 425 + } 426 + 427 + static bool 428 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 429 + { 430 + struct comp_target *ct = comp_window_direct_nvidia_create(c); 431 + if (ct == NULL) { 432 + return false; 433 + } 434 + 435 + *out_ct = ct; 436 + 437 + return true; 438 + } 439 + 440 + struct comp_target_factory comp_target_factory_direct_nvidia = { 441 + .name = "NVIDIA Direct-Mode", 442 + .identifier = "x11_direct_nvidia", 443 + .requires_vulkan_for_create = true, 444 + .is_deferred = false, 445 + .required_instance_extensions = instance_extensions, 446 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 447 + .detect = detect, 448 + .create_target = create_target, 449 + };
+43
src/xrt/compositor/main/comp_window_direct_randr.c
··· 451 451 free(non_desktop_reply); 452 452 free(resources_reply); 453 453 } 454 + 455 + 456 + /* 457 + * 458 + * Factory 459 + * 460 + */ 461 + 462 + static const char *instance_extensions[] = { 463 + VK_KHR_DISPLAY_EXTENSION_NAME, 464 + VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 465 + VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME, 466 + }; 467 + 468 + static bool 469 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 470 + { 471 + return false; 472 + } 473 + 474 + static bool 475 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 476 + { 477 + struct comp_target *ct = comp_window_direct_randr_create(c); 478 + if (ct == NULL) { 479 + return false; 480 + } 481 + 482 + *out_ct = ct; 483 + 484 + return true; 485 + } 486 + 487 + struct comp_target_factory comp_target_factory_direct_randr = { 488 + .name = "X11(RandR) Direct-Mode", 489 + .identifier = "x11_direct", 490 + .requires_vulkan_for_create = false, 491 + .is_deferred = false, 492 + .required_instance_extensions = instance_extensions, 493 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 494 + .detect = detect, 495 + .create_target = create_target, 496 + };
+47
src/xrt/compositor/main/comp_window_direct_wayland.c
··· 464 464 465 465 return &w->base.base; 466 466 } 467 + 468 + 469 + /* 470 + * 471 + * Factory 472 + * 473 + */ 474 + 475 + static const char *instance_extensions[] = { 476 + VK_KHR_DISPLAY_EXTENSION_NAME, // 477 + VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, // 478 + VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, // 479 + 480 + #ifdef VK_EXT_acquire_drm_display 481 + VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME, 482 + #endif 483 + }; 484 + 485 + static bool 486 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 487 + { 488 + return false; 489 + } 490 + 491 + static bool 492 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 493 + { 494 + struct comp_target *ct = comp_window_direct_wayland_create(c); 495 + if (ct == NULL) { 496 + return false; 497 + } 498 + 499 + *out_ct = ct; 500 + 501 + return true; 502 + } 503 + 504 + struct comp_target_factory comp_target_factory_direct_wayland = { 505 + .name = "Wayland Direct-Mode", 506 + .identifier = "direct_wayland", 507 + .requires_vulkan_for_create = false, 508 + .is_deferred = false, 509 + .required_instance_extensions = instance_extensions, 510 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 511 + .detect = detect, 512 + .create_target = create_target, 513 + };
+41
src/xrt/compositor/main/comp_window_mswin.c
··· 393 393 394 394 return &w->base.base; 395 395 } 396 + 397 + 398 + /* 399 + * 400 + * Factory 401 + * 402 + */ 403 + 404 + static const char *instance_extensions[] = { 405 + VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 406 + }; 407 + 408 + static bool 409 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 410 + { 411 + return false; 412 + } 413 + 414 + static bool 415 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 416 + { 417 + struct comp_target *ct = comp_window_mswin_create(c); 418 + if (ct == NULL) { 419 + return false; 420 + } 421 + 422 + *out_ct = ct; 423 + 424 + return true; 425 + } 426 + 427 + struct comp_target_factory comp_target_factory_mswin = { 428 + .name = "Microsoft Windows(TM)", 429 + .identifier = "mswin", 430 + .requires_vulkan_for_create = false, 431 + .is_deferred = false, 432 + .required_instance_extensions = instance_extensions, 433 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 434 + .detect = detect, 435 + .create_target = create_target, 436 + };
+41
src/xrt/compositor/main/comp_window_vk_display.c
··· 254 254 255 255 return init_swapchain(&w_direct->base, d->display, width, height); 256 256 } 257 + 258 + 259 + /* 260 + * 261 + * Factory 262 + * 263 + */ 264 + 265 + static const char *instance_extensions[] = { 266 + VK_KHR_DISPLAY_EXTENSION_NAME, 267 + }; 268 + 269 + static bool 270 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 271 + { 272 + return false; 273 + } 274 + 275 + static bool 276 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 277 + { 278 + struct comp_target *ct = comp_window_vk_display_create(c); 279 + if (ct == NULL) { 280 + return false; 281 + } 282 + 283 + *out_ct = ct; 284 + 285 + return true; 286 + } 287 + 288 + struct comp_target_factory comp_target_factory_vk_display = { 289 + .name = "Vulkan Display Direct-Mode", 290 + .identifier = "vk_display", 291 + .requires_vulkan_for_create = true, 292 + .is_deferred = false, 293 + .required_instance_extensions = instance_extensions, 294 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 295 + .detect = detect, 296 + .create_target = create_target, 297 + };
+41
src/xrt/compositor/main/comp_window_wayland.c
··· 340 340 w->fullscreen_requested = true; 341 341 } 342 342 } 343 + 344 + 345 + /* 346 + * 347 + * Factory 348 + * 349 + */ 350 + 351 + static const char *instance_extensions[] = { 352 + VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 353 + }; 354 + 355 + static bool 356 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 357 + { 358 + return false; 359 + } 360 + 361 + static bool 362 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 363 + { 364 + struct comp_target *ct = comp_window_wayland_create(c); 365 + if (ct == NULL) { 366 + return false; 367 + } 368 + 369 + *out_ct = ct; 370 + 371 + return true; 372 + } 373 + 374 + struct comp_target_factory comp_target_factory_wayland = { 375 + .name = "Wayland Windowed", 376 + .identifier = "wayland", 377 + .requires_vulkan_for_create = false, 378 + .is_deferred = false, 379 + .required_instance_extensions = instance_extensions, 380 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 381 + .detect = detect, 382 + .create_target = create_target, 383 + };
+44
src/xrt/compositor/main/comp_window_xcb.c
··· 429 429 xcb_change_property(w_xcb->connection, XCB_PROP_MODE_REPLACE, w_xcb->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 430 430 8, strlen(title), title); 431 431 } 432 + 433 + 434 + /* 435 + * 436 + * Factory 437 + * 438 + */ 439 + 440 + static const char *instance_extensions[] = { 441 + VK_KHR_XCB_SURFACE_EXTENSION_NAME, 442 + }; 443 + 444 + static bool 445 + detect(struct comp_target_factory *ctf, struct comp_compositor *c) 446 + { 447 + return false; 448 + } 449 + 450 + static bool 451 + create_target(struct comp_target_factory *ctf, struct comp_compositor *c, struct comp_target **out_ct) 452 + { 453 + struct comp_target *ct = comp_window_xcb_create(c); 454 + if (ct == NULL) { 455 + return false; 456 + } 457 + 458 + COMP_DEBUG(c, "Using VK_PRESENT_MODE_IMMEDIATE_KHR for xcb window") 459 + c->settings.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; 460 + 461 + *out_ct = ct; 462 + 463 + return true; 464 + } 465 + 466 + struct comp_target_factory comp_target_factory_xcb = { 467 + .name = "X11(XCB) Windowed", 468 + .identifier = "x11", 469 + .requires_vulkan_for_create = false, 470 + .is_deferred = false, 471 + .required_instance_extensions = instance_extensions, 472 + .required_instance_extension_count = ARRAY_SIZE(instance_extensions), 473 + .detect = detect, 474 + .create_target = create_target, 475 + };