Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2790>
const wchar_t *codec_id;
GstD3D11Device *device;
+ GstD3D11Fence *fence;
AMFContext *context;
AMFComponent *comp;
GstBufferPool *internal_pool;
priv->context = nullptr;
}
+ gst_clear_d3d11_fence (&priv->fence);
gst_clear_object (&priv->device);
return TRUE;
GstFlowReturn ret;
ComPtr < IDXGIResource > dxgi_resource;
ComPtr < ID3D11Texture2D > shared_texture;
- ComPtr < ID3D11Query > query;
- D3D11_QUERY_DESC query_desc;
- BOOL sync_done = FALSE;
HANDLE shared_handle;
GstD3D11Device *device;
HRESULT hr;
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
if (shared) {
- query_desc.Query = D3D11_QUERY_EVENT;
- query_desc.MiscFlags = 0;
+ if (priv->fence && priv->fence->device != device)
+ gst_clear_d3d11_fence (&priv->fence);
- hr = device_handle->CreateQuery (&query_desc, &query);
- if (!gst_d3d11_result (hr, device)) {
- GST_ERROR_OBJECT (self, "Couldn't Create event query, hr: 0x%x",
- (guint) hr);
+ if (!priv->fence)
+ priv->fence = gst_d3d11_device_create_fence (device);
+
+ if (!priv->fence) {
+ GST_ERROR_OBJECT (self, "Couldn't crete fence");
goto error;
}
0, 0, 0, src_tex, subresource_idx, &src_box);
if (shared) {
- device_context->End (query.Get ());
- do {
- hr = device_context->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
- } while (!sync_done && (hr == S_OK || hr == S_FALSE));
-
- if (!gst_d3d11_result (hr, device)) {
- GST_ERROR_OBJECT (self, "Couldn't sync GPU operation, hr: 0x%x",
- (guint) hr);
+ if (!gst_d3d11_fence_signal (priv->fence) ||
+ !gst_d3d11_fence_wait (priv->fence)) {
+ GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
gst_d3d11_device_unlock (device);
+ gst_clear_d3d11_fence (&priv->fence);
goto error;
}
public:
D3D11DesktopDupObject ()
: device_(nullptr)
+ , fence_(nullptr)
, metadata_buffer_(nullptr)
, metadata_buffer_size_(0)
, vertex_buffer_(nullptr)
if (vertex_buffer_)
delete[] vertex_buffer_;
+ gst_clear_d3d11_fence (&fence_);
gst_clear_object (&device_);
}
{
ID3D11DeviceContext *context_handle = nullptr;
ComPtr <ID3D11Texture2D> tex;
- ComPtr < ID3D11Query > query;
HRESULT hr;
+ gboolean is_shared = FALSE;
context_handle = gst_d3d11_device_get_device_context_handle (device);
} else {
ID3D11Device *device_handle = nullptr;
ComPtr < IDXGIResource > dxgi_resource;
- D3D11_QUERY_DESC query_desc;
HANDLE shared_handle;
device_handle = gst_d3d11_device_get_device_handle (device);
if (!gst_d3d11_result (hr, device))
return GST_FLOW_ERROR;
- query_desc.Query = D3D11_QUERY_EVENT;
- query_desc.MiscFlags = 0;
+ if (fence_ && fence_->device != device)
+ gst_clear_d3d11_fence (&fence_);
- hr = device_handle->CreateQuery (&query_desc, &query);
- if (!gst_d3d11_result (hr, device))
+ if (!fence_)
+ fence_ = gst_d3d11_device_create_fence (device);
+
+ if (!fence_)
return GST_FLOW_ERROR;
+
+ is_shared = TRUE;
}
context_handle->CopySubresourceRegion (texture, 0, 0, 0, 0,
- tex.Get(), 0, cropBox);
+ tex.Get(), 0, cropBox);
- if (query) {
- BOOL sync_done = FALSE;
-
- do {
- hr = context_handle->GetData (query.Get (),
- &sync_done, sizeof (BOOL), 0);
- } while (!sync_done && (hr == S_OK || hr == S_FALSE));
+ if (is_shared) {
+ if (!gst_d3d11_fence_signal (fence_) || !gst_d3d11_fence_wait (fence_))
+ return GST_FLOW_ERROR;
}
return GST_FLOW_OK;
PTR_INFO ptr_info_;
DXGI_OUTDUPL_DESC output_desc_;
GstD3D11Device * device_;
+ GstD3D11Fence * fence_;
ComPtr<ID3D11Texture2D> shared_texture_;
ComPtr<ID3D11RenderTargetView> rtv_;
ID3D11Texture2D *fallback_texture;
ID3D11VideoProcessorOutputView *fallback_pov;
ID3D11RenderTargetView *fallback_rtv;
+
+ GstD3D11Fence *fence;
};
#define gst_d3d11_window_dummy_parent_class parent_class
guint width, guint height);
static gboolean gst_d3d11_window_dummy_prepare (GstD3D11Window * window,
guint display_width, guint display_height, GstCaps * caps, GError ** error);
+static void gst_d3d11_window_dummy_unprepare (GstD3D11Window * window);
static gboolean
gst_d3d11_window_dummy_open_shared_handle (GstD3D11Window * window,
GstD3D11WindowSharedHandleData * data);
window_class->on_resize =
GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_on_resize);
window_class->prepare = GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_prepare);
+ window_class->unprepare =
+ GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_unprepare);
window_class->open_shared_handle =
GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_open_shared_handle);
window_class->release_shared_handle =
}
static void
+gst_d3d11_window_dummy_unprepare (GstD3D11Window * window)
+{
+ GstD3D11WindowDummy *self = GST_D3D11_WINDOW_DUMMY (window);
+
+ gst_clear_d3d11_fence (&self->fence);
+}
+
+static void
gst_d3d11_window_dummy_on_resize (GstD3D11Window * window,
guint width, guint height)
{
GST_D3D11_CLEAR_COM (data->keyed_mutex);
} else {
- /* *INDENT-OFF* */
- ComPtr<ID3D11Query> query;
- /* *INDENT-ON* */
- D3D11_QUERY_DESC query_desc;
- ID3D11Device *device_handle = gst_d3d11_device_get_device_handle (device);
- ID3D11DeviceContext *context_handle =
- gst_d3d11_device_get_device_context_handle (device);
- BOOL sync_done = FALSE;
-
/* If keyed mutex is not used, let's handle sync manually by using
- * ID3D11Query. Issued GPU commands might not be finished yet */
- query_desc.Query = D3D11_QUERY_EVENT;
- query_desc.MiscFlags = 0;
+ * fence. Issued GPU commands might not be finished yet */
- hr = device_handle->CreateQuery (&query_desc, &query);
- if (!gst_d3d11_result (hr, device)) {
+ if (!self->fence)
+ self->fence = gst_d3d11_device_create_fence (device);
+
+ if (!self->fence) {
GST_ERROR_OBJECT (self, "Couldn't Create event query");
return FALSE;
}
- context_handle->End (query.Get ());
-
- /* Wait until all issued GPU commands are finished */
- do {
- hr = context_handle->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
- } while (!sync_done && (hr == S_OK || hr == S_FALSE));
-
- if (!gst_d3d11_result (hr, device)) {
+ if (!gst_d3d11_fence_signal (self->fence) ||
+ !gst_d3d11_fence_wait (self->fence)) {
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
return FALSE;
}
gst_clear_object (&self->other_d3d11_device);
gst_clear_object (&self->d3d11_device);
+ gst_clear_d3d11_fence (&self->fence);
#endif
return TRUE;
ComPtr < ID3D11Texture2D > mf_texture;
ComPtr < IDXGIResource > dxgi_resource;
ComPtr < ID3D11Texture2D > shared_texture;
- ComPtr < ID3D11Query > query;
- D3D11_QUERY_DESC query_desc;
- BOOL sync_done = FALSE;
HANDLE shared_handle;
GstMemory *mem;
GstD3D11Memory *dmem;
src_box.right = MIN (src_desc.Width, dst_desc.Width);
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
- /* CopySubresourceRegion() might not be able to guarantee
- * copying. To ensure it, we will make use of d3d11 query */
- query_desc.Query = D3D11_QUERY_EVENT;
- query_desc.MiscFlags = 0;
+ gst_d3d11_device_lock (dmem->device);
+ if (self->fence && self->fence->device != dmem->device)
+ gst_clear_d3d11_fence (&self->fence);
+
+ if (!self->fence)
+ self->fence = gst_d3d11_device_create_fence (dmem->device);
- hr = device_handle->CreateQuery (&query_desc, &query);
- if (!gst_d3d11_result (hr, dmem->device)) {
- GST_ERROR_OBJECT (self, "Couldn't Create event query");
+ if (!self->fence) {
+ GST_ERROR_OBJECT (self, "Couldn't create fence object");
+ gst_d3d11_device_unlock (dmem->device);
gst_memory_unmap (mem, &info);
return FALSE;
}
- gst_d3d11_device_lock (dmem->device);
context_handle->CopySubresourceRegion (shared_texture.Get (), 0, 0, 0, 0,
texture, subidx, &src_box);
- context_handle->End (query.Get ());
-
- /* Wait until all issued GPU commands are finished */
- do {
- hr = context_handle->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
- } while (!sync_done && (hr == S_OK || hr == S_FALSE));
- if (!gst_d3d11_result (hr, dmem->device)) {
+ if (!gst_d3d11_fence_signal (self->fence) ||
+ !gst_d3d11_fence_wait (self->fence)) {
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
+ gst_clear_d3d11_fence (&self->fence);
gst_d3d11_device_unlock (dmem->device);
gst_memory_unmap (mem, &info);
IMFDXGIDeviceManager *device_manager;
UINT reset_token;
IMFVideoSampleAllocatorEx *mf_allocator;
+ GstD3D11Fence *fence;
#endif
};
GstCudaContext *context;
#ifdef GST_CUDA_HAS_D3D
GstD3D11Device *device;
+ GstD3D11Fence *fence;
#endif
GstNvEncoderDeviceMode subclass_device_mode;
gst_clear_object (&priv->context);
#ifdef GST_CUDA_HAS_D3D
+ gst_clear_d3d11_fence (&priv->fence);
gst_clear_object (&priv->device);
#endif
GstFlowReturn ret;
ComPtr < IDXGIResource > dxgi_resource;
ComPtr < ID3D11Texture2D > shared_texture;
- ComPtr < ID3D11Query > query;
- D3D11_QUERY_DESC query_desc;
- BOOL sync_done = FALSE;
HANDLE shared_handle;
GstD3D11Device *device;
HRESULT hr;
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
if (shared) {
- query_desc.Query = D3D11_QUERY_EVENT;
- query_desc.MiscFlags = 0;
+ if (priv->fence && priv->fence->device != device)
+ gst_clear_d3d11_fence (&priv->fence);
- hr = device_handle->CreateQuery (&query_desc, &query);
- if (!gst_d3d11_result (hr, device)) {
- GST_ERROR_OBJECT (self, "Couldn't Create event query, hr: 0x%x",
- (guint) hr);
+ if (!priv->fence)
+ priv->fence = gst_d3d11_device_create_fence (device);
+
+ if (!priv->fence) {
+ GST_ERROR_OBJECT (self, "Couldn't crete fence");
goto error;
}
0, 0, 0, src_tex, subresource_idx, &src_box);
if (shared) {
- device_context->End (query.Get ());
- do {
- hr = device_context->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
- } while (!sync_done && (hr == S_OK || hr == S_FALSE));
-
- if (!gst_d3d11_result (hr, device)) {
- GST_ERROR_OBJECT (self, "Couldn't sync GPU operation, hr: 0x%x",
- (guint) hr);
+ if (!gst_d3d11_fence_signal (priv->fence) ||
+ !gst_d3d11_fence_wait (priv->fence)) {
+ GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
gst_d3d11_device_unlock (device);
+ gst_clear_d3d11_fence (&priv->fence);
goto error;
}