[vlc-commits] [Git][videolan/vlc][master] 6 commits: direct3d11: fix fallback output when best selection fails

Steve Lhomme (@robUx4) gitlab at videolan.org
Tue Apr 4 11:51:23 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
b1bc1224 by Steve Lhomme at 2023-04-04T11:31:52+00:00
direct3d11: fix fallback output when best selection fails

Passing false (0) would result in no format being ever selected.

- - - - -
f2480265 by Steve Lhomme at 2023-04-04T11:31:52+00:00
direct3d11: simplify decoder_format usage

No need to use the textureFormat when we know it's nullptr.

- - - - -
7334ebb8 by Steve Lhomme at 2023-04-04T11:31:52+00:00
d3d11va: lock the device when creating resources

- - - - -
e5d53949 by Steve Lhomme at 2023-04-04T11:31:52+00:00
d3d11_processor: allow usage from C++

The ID3D11VideoContext_VideoProcessorBlt define is only set with COBJMACROS.
We don't need it as the code should not be compiled if it's not available.

- - - - -
3082be67 by Steve Lhomme at 2023-04-04T11:31:52+00:00
d3d11_fmt: add a function to allocate a texture for a picture

- - - - -
d65736cd by Steve Lhomme at 2023-04-04T11:31:52+00:00
d3d11: use a specific object to handle the rendering fence

- - - - -


7 changed files:

- modules/codec/avcodec/d3d11va.c
- modules/hw/d3d11/d3d11_processor.h
- modules/video_chroma/d3d11_fmt.c
- modules/video_chroma/d3d11_fmt.h
- modules/video_output/win32/d3d11_quad.cpp
- modules/video_output/win32/d3d11_quad.h
- modules/video_output/win32/direct3d11.cpp


Changes:

=====================================
modules/codec/avcodec/d3d11va.c
=====================================
@@ -509,6 +509,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
     vlc_va_sys_t *sys = va->sys;
     HRESULT hr;
 
+    d3d11_device_lock(sys->d3d_dev);
     void *pv;
     hr = ID3D11Device_QueryInterface( sys->d3d_dev->d3ddevice, &IID_ID3D10Multithread, &pv);
     if (SUCCEEDED(hr)) {
@@ -525,6 +526,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
         isXboxHardware(sys->d3d_dev))
     {
         msg_Warn(va, "%dx%d resolution not supported by your hardware", fmt->i_width, fmt->i_height);
+        d3d11_device_unlock(sys->d3d_dev);
         return VLC_EGENERIC;
     }
 #endif
@@ -554,6 +556,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
     hr = ID3D11Device_CreateTexture2D( sys->d3d_dev->d3ddevice, &texDesc, NULL, &p_texture );
     if (FAILED(hr)) {
         msg_Err(va, "CreateTexture2D %zu failed. (hr=0x%lX)", surface_count, hr);
+        d3d11_device_unlock(sys->d3d_dev);
         return VLC_EGENERIC;
     }
 
@@ -568,6 +571,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
         if (FAILED(hr)) {
             msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%lX)", surface_idx, hr);
             ID3D11Texture2D_Release(p_texture);
+            d3d11_device_unlock(sys->d3d_dev);
             return VLC_EGENERIC;
         }
 
@@ -593,6 +597,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
     hr = ID3D11VideoDevice_GetVideoDecoderConfigCount( sys->d3ddec, &decoderDesc, &cfg_count );
     if (FAILED(hr)) {
         msg_Err(va, "GetVideoDecoderConfigCount failed. (hr=0x%lX)", hr);
+        d3d11_device_unlock(sys->d3d_dev);
         return VLC_EGENERIC;
     }
 
@@ -602,6 +607,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
         hr = ID3D11VideoDevice_GetVideoDecoderConfig( sys->d3ddec, &decoderDesc, i, &cfg_list[i] );
         if (FAILED(hr)) {
             msg_Err(va, "GetVideoDecoderConfig failed. (hr=0x%lX)", hr);
+            d3d11_device_unlock(sys->d3d_dev);
             return VLC_EGENERIC;
         }
     }
@@ -635,6 +641,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
     }
     if (cfg_score <= 0) {
         msg_Err(va, "Failed to find a supported decoder configuration");
+        d3d11_device_unlock(sys->d3d_dev);
         return VLC_EGENERIC;
     }
 
@@ -644,8 +651,10 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
     if (FAILED(hr)) {
         msg_Err(va, "ID3D11VideoDevice_CreateVideoDecoder failed. (hr=0x%lX)", hr);
         sys->hw.decoder = NULL;
+        d3d11_device_unlock(sys->d3d_dev);
         return VLC_EGENERIC;
     }
+    d3d11_device_unlock(sys->d3d_dev);
     sys->hw.decoder = decoder;
 
     msg_Dbg(va, "DxCreateDecoderSurfaces succeed");


=====================================
modules/hw/d3d11/d3d11_processor.h
=====================================
@@ -27,7 +27,10 @@
 
 #include "../../video_chroma/d3d11_fmt.h"
 
-#ifdef ID3D11VideoContext_VideoProcessorBlt
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct
 {
     ID3D11VideoDevice              *d3dviddev;
@@ -46,6 +49,9 @@ void D3D11_ReleaseProcessor(d3d11_processor_t *);
 
 HRESULT D3D11_Assert_ProcessorInput(vlc_object_t *, d3d11_processor_t *, picture_sys_d3d11_t *);
 #define D3D11_Assert_ProcessorInput(a,b,c) D3D11_Assert_ProcessorInput(VLC_OBJECT(a),b,c)
+
+#ifdef __cplusplus
+}
 #endif
 
 #endif /* VLC_D3D11_PROCESSOR_H */


=====================================
modules/video_chroma/d3d11_fmt.c
=====================================
@@ -983,32 +983,24 @@ picture_context_t *d3d11_pic_context_copy(picture_context_t *ctx)
     return &pic_ctx->s;
 }
 
-picture_t *D3D11_AllocPicture(vlc_object_t *obj,
-                              const video_format_t *fmt, vlc_video_context *vctx_out,
-                              bool shared, const d3d_format_t *cfg)
+int D3D11_PictureFill(vlc_object_t *obj, picture_t *pic,
+                      vlc_video_context *vctx_out,
+                      bool shared, const d3d_format_t *cfg)
 {
     if (unlikely(cfg == NULL))
-        return NULL;
+        return VLC_EINVAL;
 
     struct d3d11_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
     if (unlikely(pic_ctx == NULL))
-        return NULL;
+        return VLC_ENOMEM;
     pic_ctx->picsys.sharedHandle = INVALID_HANDLE_VALUE;
 
-    picture_t *pic = picture_NewFromFormat( fmt );
-    if (unlikely(pic == NULL))
-    {
-        free(pic_ctx);
-        return NULL;
-    }
-
     d3d11_decoder_device_t *dev_sys = GetD3D11OpaqueContext(vctx_out);
     if (AllocateTextures(obj, &dev_sys->d3d_dev, cfg,
-                         fmt, shared, pic_ctx->picsys.texture, NULL) != VLC_SUCCESS)
+                         &pic->format, shared, pic_ctx->picsys.texture, NULL) != VLC_SUCCESS)
     {
-        picture_Release(pic);
         free(pic_ctx);
-        return NULL;
+        return VLC_EGENERIC;
     }
 
     D3D11_AllocateResourceView(vlc_object_logger(obj), dev_sys->d3d_dev.d3ddevice, cfg, pic_ctx->picsys.texture, 0, pic_ctx->picsys.renderSrc);
@@ -1035,5 +1027,22 @@ picture_t *D3D11_AllocPicture(vlc_object_t *obj,
         vlc_video_context_Hold(vctx_out),
     };
     pic->context = &pic_ctx->s;
+    return VLC_SUCCESS;
+}
+
+picture_t *D3D11_AllocPicture(vlc_object_t *obj,
+                              const video_format_t *fmt, vlc_video_context *vctx_out,
+                              bool shared, const d3d_format_t *cfg)
+{
+    picture_t *pic = picture_NewFromFormat( fmt );
+    if (unlikely(pic == NULL))
+        return NULL;
+
+    if (D3D11_PictureFill(obj, pic, vctx_out, shared, cfg) != VLC_SUCCESS)
+    {
+        picture_Release(pic);
+        return NULL;
+    }
+
     return pic;
 }


=====================================
modules/video_chroma/d3d11_fmt.h
=====================================
@@ -206,7 +206,10 @@ picture_context_t *d3d11_pic_context_copy(picture_context_t *);
 
 picture_t *D3D11_AllocPicture(vlc_object_t *,
                               const video_format_t *, vlc_video_context *,
-                              bool, const d3d_format_t *);
+                              bool shared, const d3d_format_t *);
+int D3D11_PictureFill(vlc_object_t *,
+                      picture_t *, vlc_video_context *,
+                      bool shared, const d3d_format_t *);
 
 void D3D11_PictureAttach(picture_t *, ID3D11Texture2D *textures, const d3d_format_t *cfg);
 


=====================================
modules/video_output/win32/d3d11_quad.cpp
=====================================
@@ -370,3 +370,59 @@ void d3d11_quad_t::UpdateViewport(const RECT *rect, const d3d_format_t *display)
         vlc_assert_unreachable();
     }
 }
+
+#ifdef HAVE_D3D11_4_H
+HRESULT D3D11_InitFence(d3d11_device_t & d3d_dev, d3d11_gpu_fence & fence)
+{
+    HRESULT hr;
+    ComPtr<ID3D11Device5> d3ddev5;
+    hr = d3d_dev.d3ddevice->QueryInterface(IID_GRAPHICS_PPV_ARGS(&d3ddev5));
+    if (FAILED(hr))
+        goto error;
+    hr = d3ddev5->CreateFence(fence.renderFence, D3D11_FENCE_FLAG_NONE, IID_GRAPHICS_PPV_ARGS(&fence.d3dRenderFence));
+    if (FAILED(hr))
+        goto error;
+    hr = d3d_dev.d3dcontext->QueryInterface(IID_GRAPHICS_PPV_ARGS(&fence.d3dcontext4));
+    if (FAILED(hr))
+        goto error;
+    fence.renderFinished = CreateEvent(nullptr, TRUE, FALSE, nullptr);
+    if (unlikely(fence.renderFinished == nullptr))
+        goto error;
+    return S_OK;
+error:
+    fence.d3dRenderFence.Reset();
+    fence.d3dcontext4.Reset();
+    CloseHandle(fence.renderFinished);
+    return hr;
+}
+
+void D3D11_ReleaseFence(d3d11_gpu_fence & fence)
+{
+    if (fence.d3dcontext4.Get())
+    {
+        fence.d3dRenderFence.Reset();
+        fence.d3dcontext4.Reset();
+        CloseHandle(fence.renderFinished);
+        fence.renderFinished = nullptr;
+    }
+}
+
+int D3D11_WaitFence(d3d11_gpu_fence & fence)
+{
+    if (fence.d3dcontext4.Get())
+    {
+        if (fence.renderFence == UINT64_MAX)
+            fence.renderFence = 0;
+        else
+            fence.renderFence++;
+
+        ResetEvent(fence.renderFinished);
+        fence.d3dRenderFence->SetEventOnCompletion(fence.renderFence, fence.renderFinished);
+        fence.d3dcontext4->Signal(fence.d3dRenderFence.Get(), fence.renderFence);
+
+        WaitForSingleObject(fence.renderFinished, INFINITE);
+        return VLC_SUCCESS;
+    }
+    return VLC_ENOTSUP;
+}
+#endif // HAVE_D3D11_4_H


=====================================
modules/video_output/win32/d3d11_quad.h
=====================================
@@ -25,12 +25,30 @@
 
 #include "../../video_chroma/d3d11_fmt.h"
 #include "d3d11_shaders.h"
+#ifdef HAVE_D3D11_4_H
+# include <d3d11_4.h>
+#endif
 
 #define PS_CONST_LUMI_BOUNDS 0
 #define VS_CONST_VIEWPOINT   1
 
 typedef bool (*d3d11_select_plane_t)(void *opaque, size_t plane_index, ID3D11RenderTargetView **);
 
+#ifdef HAVE_D3D11_4_H
+struct d3d11_gpu_fence
+{
+    Microsoft::WRL::ComPtr<ID3D11Fence>          d3dRenderFence;
+    Microsoft::WRL::ComPtr<ID3D11DeviceContext4> d3dcontext4;
+    UINT64                                       renderFence = 0;
+    HANDLE                                       renderFinished = nullptr;
+};
+
+HRESULT D3D11_InitFence(d3d11_device_t &, d3d11_gpu_fence &);
+int D3D11_WaitFence(d3d11_gpu_fence &);
+void D3D11_ReleaseFence(d3d11_gpu_fence &);
+#endif
+
+
 void D3D11_RenderQuad(d3d11_device_t *, d3d11_quad_t *, d3d11_vertex_shader_t *,
                       ID3D11ShaderResourceView *resourceViews[DXGI_MAX_SHADER_VIEW],
                       d3d11_select_plane_t selectPlane, void *selectOpaque);


=====================================
modules/video_output/win32/direct3d11.cpp
=====================================
@@ -40,9 +40,6 @@
 #include <new>
 
 #include "../../video_chroma/d3d11_fmt.h"
-#ifdef HAVE_D3D11_4_H
-#include <d3d11_4.h>
-#endif
 
 #include "d3d11_quad.h"
 #include "d3d11_shaders.h"
@@ -92,10 +89,7 @@ typedef struct vout_display_sys_t
     d3d11_quad_t             picQuad;
 
 #ifdef HAVE_D3D11_4_H
-    ComPtr<ID3D11Fence>      d3dRenderFence;
-    ComPtr<ID3D11DeviceContext4> d3dcontext4;
-    UINT64                   renderFence = 0;
-    HANDLE                   renderFinished = NULL;
+    d3d11_gpu_fence          fence;
 #endif
 
     picture_sys_d3d11_t      stagingSys;
@@ -628,23 +622,15 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
     }
 
 #ifdef HAVE_D3D11_4_H
-    if (sys->d3dcontext4.Get())
+    if (sys->log_level >= 4)
     {
-        vlc_tick_t render_start;
-        if (sys->log_level >= 4)
-            render_start = vlc_tick_now();
-        if (sys->renderFence == UINT64_MAX)
-            sys->renderFence = 0;
-        else
-            sys->renderFence++;
-
-        ResetEvent(sys->renderFinished);
-        sys->d3dRenderFence->SetEventOnCompletion(sys->renderFence, sys->renderFinished);
-        sys->d3dcontext4->Signal(sys->d3dRenderFence.Get(), sys->renderFence);
-
-        WaitForSingleObject(sys->renderFinished, INFINITE);
-        if (sys->log_level >= 4)
-            msg_Dbg(vd, "waited %" PRId64 " ms for the render fence", MS_FROM_VLC_TICK(vlc_tick_now() - render_start));
+        vlc_tick_t render_start = vlc_tick_now();
+        D3D11_WaitFence(sys->fence);
+        msg_Dbg(vd, "waited %" PRId64 " ms for the render fence", MS_FROM_VLC_TICK(vlc_tick_now() - render_start));
+    }
+    else
+    {
+        D3D11_WaitFence(sys->fence);
     }
 #endif
 }
@@ -829,7 +815,7 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, vlc_video_
         sys->picQuad.generic.textureFormat = GetDirectRenderingFormat(vd, fmt->i_chroma);
 
     // look for any pixel format that we can handle with enough pixels per channel
-    const d3d_format_t *decoder_format = NULL;
+    const d3d_format_t *decoder_format = nullptr;
     if ( !sys->picQuad.generic.textureFormat )
     {
         uint8_t bits_per_channel;
@@ -891,24 +877,22 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, vlc_video_
         /* look for a decoder format that can be decoded but not used in shaders */
         if ( is_d3d11_opaque(fmt->i_chroma) )
             decoder_format = GetDirectDecoderFormat(vd, fmt->i_chroma);
-        else
-            decoder_format = sys->picQuad.generic.textureFormat;
 
         bool is_rgb = !vlc_fourcc_IsYUV(fmt->i_chroma);
         sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, bits_per_channel,
                                                              widthDenominator, heightDenominator,
-                                                             decoder_format!=NULL,
+                                                             decoder_format!=nullptr,
                                                              is_rgb ? DXGI_RGB_FORMAT : DXGI_YUV_FORMAT);
         if (!sys->picQuad.generic.textureFormat)
             sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, bits_per_channel,
                                                                  widthDenominator, heightDenominator,
-                                                                 decoder_format!=NULL,
+                                                                 decoder_format!=nullptr,
                                                                  is_rgb ? DXGI_YUV_FORMAT : DXGI_RGB_FORMAT);
     }
 
     // look for any pixel format that we can handle
     if ( !sys->picQuad.generic.textureFormat )
-        sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, 0, 0, 0, false, false);
+        sys->picQuad.generic.textureFormat = GetDisplayFormatByDepth(vd, 0, 0, 0, false, DXGI_YUV_FORMAT|DXGI_RGB_FORMAT);
 
     if ( !sys->picQuad.generic.textureFormat )
     {
@@ -1075,39 +1059,13 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
     return UpdateStaging(vd, fmt);
 }
 
-#ifdef HAVE_D3D11_4_H
-static HRESULT InitRenderFence(vout_display_sys_t *sys)
-{
-    HRESULT hr;
-    ComPtr<ID3D11Device5> d3ddev5;
-    hr = sys->d3d_dev->d3ddevice->QueryInterface(IID_GRAPHICS_PPV_ARGS(&d3ddev5));
-    if (FAILED(hr))
-        goto error;
-    hr = d3ddev5->CreateFence(sys->renderFence, D3D11_FENCE_FLAG_NONE, IID_GRAPHICS_PPV_ARGS(&sys->d3dRenderFence));
-    if (FAILED(hr))
-        goto error;
-    hr = sys->d3d_dev->d3dcontext->QueryInterface(IID_GRAPHICS_PPV_ARGS(&sys->d3dcontext4));
-    if (FAILED(hr))
-        goto error;
-    sys->renderFinished = CreateEvent(NULL, TRUE, FALSE, NULL);
-    if (unlikely(sys->renderFinished == NULL))
-        goto error;
-    return S_OK;
-error:
-    sys->d3dRenderFence.Reset();
-    sys->d3dcontext4.Reset();
-    CloseHandle(sys->renderFinished);
-    return hr;
-}
-#endif // HAVE_D3D11_4_H
-
 static int Direct3D11CreateGenericResources(vout_display_t *vd)
 {
     vout_display_sys_t *sys = static_cast<vout_display_sys_t *>(vd->sys);
     HRESULT hr;
 
 #ifdef HAVE_D3D11_4_H
-    hr = InitRenderFence(sys);
+    hr = D3D11_InitFence(*sys->d3d_dev, sys->fence);
     if (SUCCEEDED(hr))
     {
         msg_Dbg(vd, "using GPU render fence");
@@ -1225,13 +1183,7 @@ static void Direct3D11DestroyResources(vout_display_t *vd)
     D3D11_ReleaseVertexShader(&sys->projectionVShader);
 
 #ifdef HAVE_D3D11_4_H
-    if (sys->d3dcontext4.Get())
-    {
-        sys->d3dRenderFence.Reset();
-        sys->d3dcontext4.Reset();
-        CloseHandle(sys->renderFinished);
-        sys->renderFinished = NULL;
-    }
+    D3D11_ReleaseFence(sys->fence);
 #endif
 
     msg_Dbg(vd, "Direct3D11 resources destroyed");



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/bc056eb4803b31b3e701c604560bc7384cde471f...d65736cd202d620a6832a1f06d7144037de6b95f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/bc056eb4803b31b3e701c604560bc7384cde471f...d65736cd202d620a6832a1f06d7144037de6b95f
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list