d3d12memory: Check heap flag before trying to create NT handle

CreateSharedHandle() will fail eventually if the resource was created
with non-shared heap. Instead of trying to create handle blindly,
validate resource first.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7243>
This commit is contained in:
Seungha Yang 2024-07-27 03:50:19 +09:00
parent 1c8c5ed457
commit 28a7adf4dd

View file

@ -344,6 +344,7 @@ struct _GstD3D12MemoryPrivate
gpointer staging_ptr = nullptr; gpointer staging_ptr = nullptr;
D3D12_RESOURCE_DESC desc; D3D12_RESOURCE_DESC desc;
D3D12_HEAP_FLAGS heap_flags;
HANDLE nt_handle = nullptr; HANDLE nt_handle = nullptr;
std::map<gint64, std::unique_ptr<GstD3D12MemoryTokenData>> token_map; std::map<gint64, std::unique_ptr<GstD3D12MemoryTokenData>> token_map;
@ -939,6 +940,9 @@ gst_d3d12_memory_get_nt_handle_unlocked (GstD3D12Memory * mem, HANDLE * handle)
return TRUE; return TRUE;
} }
if ((priv->heap_flags & D3D12_HEAP_FLAG_SHARED) != D3D12_HEAP_FLAG_SHARED)
return FALSE;
auto device = gst_d3d12_device_get_device_handle (mem->device); auto device = gst_d3d12_device_get_device_handle (mem->device);
auto hr = device->CreateSharedHandle (priv->resource.Get (), nullptr, auto hr = device->CreateSharedHandle (priv->resource.Get (), nullptr,
GENERIC_ALL, nullptr, &priv->nt_handle); GENERIC_ALL, nullptr, &priv->nt_handle);
@ -1120,8 +1124,12 @@ gst_d3d12_memory_get_d3d11_texture (GstD3D12Memory * mem,
return (*it)->texture11.Get (); return (*it)->texture11.Get ();
HANDLE shared_handle; HANDLE shared_handle;
if (!gst_d3d12_memory_get_nt_handle_unlocked (mem, &shared_handle)) /* d3d11 interop requires rtv binding and shared heap */
if ((priv->desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) !=
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET ||
!gst_d3d12_memory_get_nt_handle_unlocked (mem, &shared_handle)) {
return nullptr; return nullptr;
}
ComPtr < ID3D11Device1 > device11_1; ComPtr < ID3D11Device1 > device11_1;
auto hr = device11->QueryInterface (IID_PPV_ARGS (&device11_1)); auto hr = device11->QueryInterface (IID_PPV_ARGS (&device11_1));
@ -1344,6 +1352,7 @@ gst_d3d12_allocator_alloc_wrapped (GstD3D12Allocator * allocator,
auto desc = GetDesc (resource); auto desc = GetDesc (resource);
guint8 num_subresources = guint8 num_subresources =
D3D12GetFormatPlaneCount (device_handle, desc.Format); D3D12GetFormatPlaneCount (device_handle, desc.Format);
D3D12_HEAP_FLAGS heap_flags;
if (num_subresources == 0) { if (num_subresources == 0) {
GST_ERROR_OBJECT (allocator, "Couldn't get format info"); GST_ERROR_OBJECT (allocator, "Couldn't get format info");
@ -1355,11 +1364,18 @@ gst_d3d12_allocator_alloc_wrapped (GstD3D12Allocator * allocator,
return nullptr; return nullptr;
} }
auto hr = resource->GetHeapProperties (nullptr, &heap_flags);
if (!gst_d3d12_result (hr, device)) {
GST_ERROR_OBJECT (allocator, "Couldn't get heap property");
return nullptr;
}
auto mem = g_new0 (GstD3D12Memory, 1); auto mem = g_new0 (GstD3D12Memory, 1);
mem->priv = new GstD3D12MemoryPrivate (); mem->priv = new GstD3D12MemoryPrivate ();
auto priv = mem->priv; auto priv = mem->priv;
priv->desc = desc; priv->desc = desc;
priv->heap_flags = heap_flags;
priv->num_subresources = num_subresources; priv->num_subresources = num_subresources;
priv->resource = resource; priv->resource = resource;
gst_d3d12_dxgi_format_get_resource_format (priv->desc.Format, gst_d3d12_dxgi_format_get_resource_format (priv->desc.Format,