diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp index ec17b86b71..21498e06b5 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp @@ -124,6 +124,18 @@ gst_d3d12_frame_map (GstD3D12Frame * frame, const GstVideoInfo * info, } } + if ((d3d12_flags & GST_D3D12_FRAME_MAP_FLAG_UAV) != 0) { + if ((desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) == 0) { + GST_WARNING ("UAV map is requested but UAV is not allowed"); + return FALSE; + } + + if (!gst_d3d12_memory_get_unordered_access_view_heap (dmem)) { + GST_ERROR ("Couldn't get UAV descriptor heap"); + return FALSE; + } + } + if ((d3d12_flags & GST_D3D12_FRAME_MAP_FLAG_RTV) != 0) { if ((desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) == 0) { GST_WARNING ("RTV map is requested but RTV is not allowed"); @@ -178,22 +190,33 @@ gst_d3d12_frame_map (GstD3D12Frame * frame, const GstVideoInfo * info, desc = GetDesc (resource); ID3D12DescriptorHeap *srv_heap = nullptr; + ID3D12DescriptorHeap *uav_heap = nullptr; ID3D12DescriptorHeap *rtv_heap = nullptr; if ((d3d12_flags & GST_D3D12_FRAME_MAP_FLAG_SRV) != 0) srv_heap = gst_d3d12_memory_get_shader_resource_view_heap (dmem); + if ((d3d12_flags & GST_D3D12_FRAME_MAP_FLAG_UAV) != 0) + uav_heap = gst_d3d12_memory_get_unordered_access_view_heap (dmem); + if ((d3d12_flags & GST_D3D12_FRAME_MAP_FLAG_RTV) != 0) rtv_heap = gst_d3d12_memory_get_render_target_view_heap (dmem); - CD3DX12_CPU_DESCRIPTOR_HANDLE srv_handle; + CD3DX12_CPU_DESCRIPTOR_HANDLE srv_handle = { }; if (srv_heap) { srv_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE (GetCPUDescriptorHandleForHeapStart (srv_heap)); } - CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle; + CD3DX12_CPU_DESCRIPTOR_HANDLE uav_handle = { }; + if (uav_heap) { + uav_handle = + CD3DX12_CPU_DESCRIPTOR_HANDLE + (GetCPUDescriptorHandleForHeapStart (uav_heap)); + } + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle = { }; if (rtv_heap) { rtv_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE @@ -223,6 +246,11 @@ gst_d3d12_frame_map (GstD3D12Frame * frame, const GstVideoInfo * info, rtv_handle.Offset (rtv_inc_size); } + if (uav_heap) { + frame->uav_desc_handle[plane_idx] = uav_handle; + uav_handle.Offset (srv_inc_size); + } + gst_d3d12_memory_get_fence (dmem, &frame->fence[plane_idx].fence, &frame->fence[plane_idx].fence_value); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.h index 2e79a2a61c..ce0c8a15ff 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.h @@ -31,6 +31,7 @@ typedef struct _GstD3D12FrameFence GstD3D12FrameFence; * GstD3D12FrameMapFlags: * @GST_D3D12_FRAME_MAP_FLAG_NONE: No flags * @GST_D3D12_FRAME_MAP_FLAG_SRV: Frame mapping requires shared resource view + * @GST_D3D12_FRAME_MAP_FLAG_UAV: Frame mapping requires unordered access view * @GST_D3D12_FRAME_MAP_FLAG_RTV: Frame mapping requires render target view * * Since: 1.26 @@ -39,7 +40,8 @@ typedef enum { GST_D3D12_FRAME_MAP_FLAG_NONE = 0, GST_D3D12_FRAME_MAP_FLAG_SRV = (1 << 0), - GST_D3D12_FRAME_MAP_FLAG_RTV = (1 << 1), + GST_D3D12_FRAME_MAP_FLAG_UAV = (1 << 1), + GST_D3D12_FRAME_MAP_FLAG_RTV = (1 << 2), } GstD3D12FrameMapFlags; DEFINE_ENUM_FLAG_OPERATORS (GstD3D12FrameMapFlags); @@ -83,6 +85,7 @@ struct _GstD3D12Frame D3D12_RECT plane_rect[GST_VIDEO_MAX_PLANES]; GstD3D12FrameFence fence[GST_VIDEO_MAX_PLANES]; D3D12_CPU_DESCRIPTOR_HANDLE srv_desc_handle[GST_VIDEO_MAX_PLANES]; + D3D12_CPU_DESCRIPTOR_HANDLE uav_desc_handle[GST_VIDEO_MAX_PLANES]; D3D12_CPU_DESCRIPTOR_HANDLE rtv_desc_handle[GST_VIDEO_MAX_PLANES]; /*< private >*/ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp index 84e955f6f2..e2ad055b4f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp @@ -346,6 +346,7 @@ struct _GstD3D12MemoryPrivate ComPtr srv_heap; ComPtr rtv_heap; + ComPtr uav_heap; gpointer staging_ptr = nullptr; @@ -812,6 +813,67 @@ gst_d3d12_memory_get_shader_resource_view_heap (GstD3D12Memory * mem) return priv->srv_heap.Get (); } +/** + * gst_d3d12_memory_get_unordered_access_view_heap: + * @mem: a #GstD3D12Memory + * + * Gets shader invisible unordered access view descriptor heap. + * Caller needs to copy returned descriptor heap to another shader visible + * descriptor heap in order for resource to be used in shader. + * + * Returns: (transfer none) (nullable): ID3D12DescriptorHeap handle or %NULL + * if the resource was allocated without unordered access view enabled + * + * Since: 1.26 + */ +ID3D12DescriptorHeap * +gst_d3d12_memory_get_unordered_access_view_heap (GstD3D12Memory * mem) +{ + auto priv = mem->priv; + auto allocator = GST_MEMORY_CAST (mem)->allocator; + if ((priv->desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) == 0) { + GST_LOG_OBJECT (allocator, + "Unordered access view is not allowed, configured flags 0x%x", + (guint) priv->desc.Flags); + return nullptr; + } + + std::lock_guard < std::mutex > lk (priv->lock); + if (!priv->uav_heap) { + D3D12_DESCRIPTOR_HEAP_DESC desc = { }; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = priv->num_subresources; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + + auto device = gst_d3d12_device_get_device_handle (mem->device); + + ComPtr < ID3D12DescriptorHeap > uav_heap; + auto hr = device->CreateDescriptorHeap (&desc, IID_PPV_ARGS (&uav_heap)); + if (!gst_d3d12_result (hr, mem->device)) { + GST_ERROR_OBJECT (allocator, "Couldn't create descriptor heap"); + return nullptr; + } + + priv->uav_heap = uav_heap; + + D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = { }; + uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + auto cpu_handle = + CD3DX12_CPU_DESCRIPTOR_HANDLE (GetCPUDescriptorHandleForHeapStart + (uav_heap)); + + for (guint i = 0; i < priv->num_subresources; i++) { + uav_desc.Format = priv->resource_formats[i]; + uav_desc.Texture2D.PlaneSlice = i; + device->CreateUnorderedAccessView (priv->resource.Get (), nullptr, + &uav_desc, cpu_handle); + cpu_handle.Offset (priv->srv_inc_size); + } + } + + return priv->uav_heap.Get (); +} + /** * gst_d3d12_memory_get_render_target_view_heap: * @mem: a #GstD3D12Memory diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.h index 69b021daad..41587d3ac6 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.h @@ -199,6 +199,9 @@ gboolean gst_d3d12_memory_get_plane_rectangle (GstD3D12Memory * mem, GST_D3D12_API ID3D12DescriptorHeap * gst_d3d12_memory_get_shader_resource_view_heap (GstD3D12Memory * mem); +GST_D3D12_API +ID3D12DescriptorHeap * gst_d3d12_memory_get_unordered_access_view_heap (GstD3D12Memory * mem); + GST_D3D12_API ID3D12DescriptorHeap * gst_d3d12_memory_get_render_target_view_heap (GstD3D12Memory * mem);