d3d12memory: Add support for UAV descriptor cache

Cache shader invisible UAV descriptor in memory

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7088>
This commit is contained in:
Seungha Yang 2024-06-23 01:18:54 +09:00 committed by GStreamer Marge Bot
parent ec06b0445e
commit f432e61bdc
4 changed files with 99 additions and 3 deletions

View file

@ -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);

View file

@ -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 >*/

View file

@ -346,6 +346,7 @@ struct _GstD3D12MemoryPrivate
ComPtr<ID3D12DescriptorHeap> srv_heap;
ComPtr<ID3D12DescriptorHeap> rtv_heap;
ComPtr<ID3D12DescriptorHeap> 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

View file

@ -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);