1
0
Эх сурвалжийг харах

libobs: Allow wrapping D3D11 object with gs_texture_t

This can be useful for reading from textures provided by middleware.
jpark37 4 жил өмнө
parent
commit
2d547cf669

+ 17 - 0
libobs-d3d11/d3d11-subsystem.cpp

@@ -2670,6 +2670,23 @@ extern "C" EXPORT uint32_t device_texture_get_shared_handle(gs_texture_t *tex)
 	return tex2d->isShared ? tex2d->sharedHandle : GS_INVALID_HANDLE;
 }
 
+extern "C" EXPORT gs_texture_t *device_texture_wrap_obj(gs_device_t *device,
+							void *obj)
+{
+	gs_texture *texture = nullptr;
+	try {
+		texture = new gs_texture_2d(device, (ID3D11Texture2D *)obj);
+	} catch (const HRError &error) {
+		blog(LOG_ERROR, "gs_texture_wrap_obj (D3D11): %s (%08lX)",
+		     error.str, error.hr);
+		LogD3D11ErrorDetails(error, device);
+	} catch (const char *error) {
+		blog(LOG_ERROR, "gs_texture_wrap_obj (D3D11): %s", error);
+	}
+
+	return texture;
+}
+
 int device_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms)
 {
 	gs_texture_2d *tex2d = reinterpret_cast<gs_texture_2d *>(tex);

+ 1 - 0
libobs-d3d11/d3d11-subsystem.hpp

@@ -490,6 +490,7 @@ 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, ID3D11Texture2D *obj);
 };
 
 struct gs_texture_3d : gs_texture {

+ 27 - 0
libobs-d3d11/d3d11-texture2d.cpp

@@ -311,3 +311,30 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle)
 	if (FAILED(hr))
 		throw HRError("Failed to create shader resource view", hr);
 }
+
+gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *obj)
+	: gs_texture(device, gs_type::gs_texture_2d, GS_TEXTURE_2D)
+{
+	texture = obj;
+
+	texture->GetDesc(&td);
+
+	this->type = GS_TEXTURE_2D;
+	this->format = ConvertDXGITextureFormat(td.Format);
+	this->levels = 1;
+	this->device = device;
+
+	this->width = td.Width;
+	this->height = td.Height;
+	this->dxgiFormat = td.Format;
+
+	memset(&resourceDesc, 0, sizeof(resourceDesc));
+	resourceDesc.Format = td.Format;
+	resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+	resourceDesc.Texture2D.MipLevels = 1;
+
+	HRESULT hr = device->device->CreateShaderResourceView(
+		texture, &resourceDesc, shaderRes.Assign());
+	if (FAILED(hr))
+		throw HRError("Failed to create shader resource view", hr);
+}

+ 1 - 0
libobs/graphics/graphics-imports.c

@@ -210,6 +210,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
 	GRAPHICS_IMPORT_OPTIONAL(gs_texture_release_dc);
 	GRAPHICS_IMPORT_OPTIONAL(device_texture_open_shared);
 	GRAPHICS_IMPORT_OPTIONAL(device_texture_get_shared_handle);
+	GRAPHICS_IMPORT_OPTIONAL(device_texture_wrap_obj);
 	GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync);
 	GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
 	GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);

+ 2 - 0
libobs/graphics/graphics-internal.h

@@ -299,6 +299,8 @@ struct gs_exports {
 	gs_texture_t *(*device_texture_open_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);
 	int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key,
 					   uint32_t ms);
 	int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key);

+ 12 - 0
libobs/graphics/graphics.c

@@ -2885,6 +2885,18 @@ uint32_t gs_texture_get_shared_handle(gs_texture_t *tex)
 	return GS_INVALID_HANDLE;
 }
 
+gs_texture_t *gs_texture_wrap_obj(void *obj)
+{
+	graphics_t *graphics = thread_graphics;
+	if (!gs_valid("gs_texture_wrap_obj"))
+		return NULL;
+
+	if (graphics->exports.device_texture_wrap_obj)
+		return graphics->exports.device_texture_wrap_obj(
+			graphics->device, obj);
+	return NULL;
+}
+
 int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms)
 {
 	graphics_t *graphics = thread_graphics;

+ 2 - 0
libobs/graphics/graphics.h

@@ -867,6 +867,8 @@ EXPORT gs_texture_t *gs_texture_open_shared(uint32_t handle);
 #define GS_INVALID_HANDLE (uint32_t) - 1
 EXPORT uint32_t gs_texture_get_shared_handle(gs_texture_t *tex);
 
+EXPORT gs_texture_t *gs_texture_wrap_obj(void *obj);
+
 #define GS_WAIT_INFINITE (uint32_t) - 1
 
 /**