From c8e417057a2736a87356b7b64dd94efa1ac53d47 Mon Sep 17 00:00:00 2001 From: VodBox Date: Fri, 12 Nov 2021 12:13:41 +1300 Subject: [PATCH] libobs, libobs-d3d11: Add support for NT Handle shared textures Adds support for using shared textures that were made with the D3D11_RESOURCE_MISC_SHARED_NTHANDLE flag. This increases the minimum required Windows version to Windows 8 or the Platform Update for Windows 7. As official support is only for Win 8+ this does not change official support. --- libobs-d3d11/d3d11-subsystem.cpp | 17 +++++++++++++++++ libobs-d3d11/d3d11-subsystem.hpp | 3 ++- libobs-d3d11/d3d11-texture2d.cpp | 17 +++++++++++++---- libobs/graphics/graphics-imports.c | 1 + libobs/graphics/graphics-internal.h | 2 ++ libobs/graphics/graphics.c | 12 ++++++++++++ libobs/graphics/graphics.h | 1 + 7 files changed, 48 insertions(+), 5 deletions(-) diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index 4ed6d4e25..e32fc9642 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -2826,6 +2826,23 @@ extern "C" EXPORT gs_texture_t *device_texture_open_shared(gs_device_t *device, return texture; } +extern "C" EXPORT gs_texture_t * +device_texture_open_nt_shared(gs_device_t *device, uint32_t handle) +{ + gs_texture *texture = nullptr; + try { + texture = new gs_texture_2d(device, handle, true); + } catch (const HRError &error) { + blog(LOG_ERROR, "gs_texture_open_nt_shared (D3D11): %s (%08lX)", + error.str, error.hr); + LogD3D11ErrorDetails(error, device); + } catch (const char *error) { + blog(LOG_ERROR, "gs_texture_open_nt_shared (D3D11): %s", error); + } + + return texture; +} + extern "C" EXPORT uint32_t device_texture_get_shared_handle(gs_texture_t *tex) { gs_texture_2d *tex2d = reinterpret_cast(tex); diff --git a/libobs-d3d11/d3d11-subsystem.hpp b/libobs-d3d11/d3d11-subsystem.hpp index dafb649f5..0c12a655a 100644 --- a/libobs-d3d11/d3d11-subsystem.hpp +++ b/libobs-d3d11/d3d11-subsystem.hpp @@ -536,7 +536,8 @@ struct gs_texture_2d : gs_texture { gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12, uint32_t flags); - gs_texture_2d(gs_device_t *device, uint32_t handle); + gs_texture_2d(gs_device_t *device, uint32_t handle, + bool ntHandle = false); gs_texture_2d(gs_device_t *device, ID3D11Texture2D *obj); }; diff --git a/libobs-d3d11/d3d11-texture2d.cpp b/libobs-d3d11/d3d11-texture2d.cpp index 58bd7dc80..566147b7e 100644 --- a/libobs-d3d11/d3d11-texture2d.cpp +++ b/libobs-d3d11/d3d11-texture2d.cpp @@ -313,15 +313,24 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12tex, InitRenderTargets(); } -gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle) +gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle, + bool ntHandle) : gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D), isShared(true), sharedHandle(handle) { HRESULT hr; - hr = device->device->OpenSharedResource((HANDLE)(uintptr_t)handle, - __uuidof(ID3D11Texture2D), - (void **)texture.Assign()); + if (ntHandle) { + ComQIPtr dev = device->device; + hr = dev->OpenSharedResource1((HANDLE)(uintptr_t)handle, + __uuidof(ID3D11Texture2D), + (void **)texture.Assign()); + } else { + hr = device->device->OpenSharedResource( + (HANDLE)(uintptr_t)handle, __uuidof(ID3D11Texture2D), + (void **)texture.Assign()); + } + if (FAILED(hr)) throw HRError("Failed to open shared 2D texture", hr); diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index 22131581b..948a854ca 100644 --- a/libobs/graphics/graphics-imports.c +++ b/libobs/graphics/graphics-imports.c @@ -215,6 +215,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT_OPTIONAL(gs_texture_get_dc); GRAPHICS_IMPORT_OPTIONAL(gs_texture_release_dc); GRAPHICS_IMPORT_OPTIONAL(device_texture_open_shared); + GRAPHICS_IMPORT_OPTIONAL(device_texture_open_nt_shared); GRAPHICS_IMPORT_OPTIONAL(device_texture_get_shared_handle); GRAPHICS_IMPORT_OPTIONAL(device_texture_wrap_obj); GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync); diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index afa356fb1..8d2812c04 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -308,6 +308,8 @@ struct gs_exports { gs_texture_t *(*device_texture_open_shared)(gs_device_t *device, uint32_t handle); + gs_texture_t *(*device_texture_open_nt_shared)(gs_device_t *device, + uint32_t handle); uint32_t (*device_texture_get_shared_handle)(gs_texture_t *tex); gs_texture_t *(*device_texture_wrap_obj)(gs_device_t *device, void *obj); diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 19a23439b..3fae4d1b0 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -2983,6 +2983,18 @@ gs_texture_t *gs_texture_open_shared(uint32_t handle) return NULL; } +gs_texture_t *gs_texture_open_nt_shared(uint32_t handle) +{ + graphics_t *graphics = thread_graphics; + if (!gs_valid("gs_texture_open_nt_shared")) + return NULL; + + if (graphics->exports.device_texture_open_nt_shared) + return graphics->exports.device_texture_open_nt_shared( + graphics->device, handle); + return NULL; +} + uint32_t gs_texture_get_shared_handle(gs_texture_t *tex) { graphics_t *graphics = thread_graphics; diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 9a532e043..c8f2c70ad 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -893,6 +893,7 @@ EXPORT void gs_texture_release_dc(gs_texture_t *gdi_tex); /** creates a windows shared texture from a texture handle */ EXPORT gs_texture_t *gs_texture_open_shared(uint32_t handle); +EXPORT gs_texture_t *gs_texture_open_nt_shared(uint32_t handle); #define GS_INVALID_HANDLE (uint32_t) - 1 EXPORT uint32_t gs_texture_get_shared_handle(gs_texture_t *tex);