[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