diff --git a/plugins/win-capture/graphics-hook/CMakeLists.txt b/plugins/win-capture/graphics-hook/CMakeLists.txt index f78f1c610..fbe3c1e6b 100644 --- a/plugins/win-capture/graphics-hook/CMakeLists.txt +++ b/plugins/win-capture/graphics-hook/CMakeLists.txt @@ -53,7 +53,9 @@ target_include_directories(graphics-hook PUBLIC "${CMAKE_BINARY_DIR}/plugins/win-capture/graphics-hook/config") target_link_libraries(graphics-hook - ipc-util psapi) + dxguid + ipc-util + psapi) if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(_output_suffix "64") diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.c b/plugins/win-capture/graphics-hook/vulkan-capture.c index e791e001a..517551d77 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.c +++ b/plugins/win-capture/graphics-hook/vulkan-capture.c @@ -35,13 +35,6 @@ /* use the loader's dispatch table pointer as a key for internal data maps */ #define GET_LDT(x) (*(void **)x) -/* clang-format off */ -static const GUID dxgi_factory1_guid = -{0x770aae78, 0xf26f, 0x4dba, {0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87}}; -static const GUID dxgi_resource_guid = -{0x035f3ab4, 0x482e, 0x4e50, {0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b}}; -/* clang-format on */ - static bool vulkan_seen = false; static SRWLOCK mutex = SRWLOCK_INIT; // Faster CRITICAL_SECTION @@ -231,7 +224,7 @@ static void vk_shtex_free(struct vk_data *data) NULL); if (swap->d3d11_tex) { - ID3D11Resource_Release(swap->d3d11_tex); + ID3D11Texture2D_Release(swap->d3d11_tex); } swap->handle = INVALID_HANDLE_VALUE; @@ -405,7 +398,7 @@ static inline bool vk_shtex_init_d3d11(struct vk_data *data) { D3D_FEATURE_LEVEL level_used; IDXGIFactory1 *factory; - IDXGIAdapter *adapter; + IDXGIAdapter1 *adapter; HRESULT hr; HMODULE d3d11 = load_system_library("d3d11.dll"); @@ -436,14 +429,13 @@ static inline bool vk_shtex_init_d3d11(struct vk_data *data) return false; } - hr = create_factory(&dxgi_factory1_guid, (void **)&factory); + hr = create_factory(&IID_IDXGIFactory1, &factory); if (FAILED(hr)) { flog_hr("failed to create factory", hr); return false; } - hr = IDXGIFactory1_EnumAdapters1(factory, 0, - (IDXGIAdapter1 **)&adapter); + hr = IDXGIFactory1_EnumAdapters1(factory, 0, &adapter); IDXGIFactory1_Release(factory); if (FAILED(hr)) { @@ -458,11 +450,12 @@ static inline bool vk_shtex_init_d3d11(struct vk_data *data) D3D_FEATURE_LEVEL_9_3, }; - hr = create(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, feature_levels, + hr = create((IDXGIAdapter *)adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, + feature_levels, sizeof(feature_levels) / sizeof(D3D_FEATURE_LEVEL), D3D11_SDK_VERSION, &data->d3d11_device, &level_used, &data->d3d11_context); - IDXGIAdapter_Release(adapter); + IDXGIAdapter1_Release(adapter); if (FAILED(hr)) { flog_hr("failed to create device", hr); @@ -501,8 +494,8 @@ static inline bool vk_shtex_init_d3d11_tex(struct vk_data *data, return false; } - hr = ID3D11Device_QueryInterface(swap->d3d11_tex, &dxgi_resource_guid, - (void **)&dxgi_res); + hr = ID3D11Texture2D_QueryInterface(swap->d3d11_tex, &IID_IDXGIResource, + &dxgi_res); if (FAILED(hr)) { flog_hr("failed to get IDXGIResource", hr); return false; @@ -1139,6 +1132,7 @@ static VkResult VKAPI OBS_CreateInstance(const VkInstanceCreateInfo *cinfo, GETADDR(DestroySurfaceKHR); GETADDR(GetPhysicalDeviceMemoryProperties); GETADDR(GetPhysicalDeviceImageFormatProperties2); + GETADDR(EnumerateDeviceExtensionProperties); #undef GETADDR data->valid = !funcs_not_found; @@ -1319,6 +1313,46 @@ static VkResult VKAPI OBS_CreateDevice(VkPhysicalDevice phy_device, goto fail; } + const char *required_device_extensions[] = { + VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME}; + + uint32_t device_extension_count = 0; + ret = ifuncs->EnumerateDeviceExtensionProperties( + phy_device, NULL, &device_extension_count, NULL); + if (ret != VK_SUCCESS) + goto fail; + + VkExtensionProperties *device_extensions = _malloca( + sizeof(VkExtensionProperties) * device_extension_count); + ret = ifuncs->EnumerateDeviceExtensionProperties( + phy_device, NULL, &device_extension_count, device_extensions); + if (ret != VK_SUCCESS) + goto fail; + + bool extensions_found = true; + for (uint32_t i = 0; i < _countof(required_device_extensions); i++) { + const char *const required_extension = + required_device_extensions[i]; + + bool found = false; + for (uint32_t j = 0; j < device_extension_count; j++) { + if (!strcmp(required_extension, + device_extensions[j].extensionName)) { + found = true; + break; + } + } + + if (!found) { + flog("missing device extension: %s", + required_extension); + extensions_found = false; + } + } + + if (!extensions_found) + goto fail; + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; @@ -1405,6 +1439,7 @@ OBS_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *cinfo, swap->format = cinfo->imageFormat; swap->hwnd = find_surf_hwnd(data->inst_data, cinfo->surface); swap->image_count = count; + swap->d3d11_tex = NULL; return VK_SUCCESS; } diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.h b/plugins/win-capture/graphics-hook/vulkan-capture.h index 15651153f..b52ccac60 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.h +++ b/plugins/win-capture/graphics-hook/vulkan-capture.h @@ -9,6 +9,7 @@ struct vk_inst_funcs { DEF_FUNC(DestroySurfaceKHR); DEF_FUNC(GetPhysicalDeviceMemoryProperties); DEF_FUNC(GetPhysicalDeviceImageFormatProperties2); + DEF_FUNC(EnumerateDeviceExtensionProperties); }; struct vk_device_funcs {