Message ID | ME3PR01MB562442911EA9A24F5402E084DA0A9@ME3PR01MB5624.ausprd01.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] d3d11va: let user can create SRV from output | expand |
Context | Check | Description |
---|---|---|
andriy/configure_armv7_RPi4 | warning | Failed to apply patch |
yinshiyou/configure_loongarch64 | warning | Failed to apply patch |
andriy/configure_aarch64_jetson | warning | Failed to apply patch |
On Wed, Mar 9, 2022 at 7:56 AM Wang Chuan <ouchuanm@outlook.com> wrote: > > Starting from Windows 8, users can create SRV from video resource > and bind it to shaders directly. This can avoid unnecessary memcpy > (ID3D11DeviceContext::CopyResource, etc), so create texture with > [D3D11_BIND_SHADER_RESOURCE] as decoder's output if possible. > > Signed-off-by: Wang Chuan <ouchuanm@outlook.com> > --- > libavcodec/dxva2.c | 2 +- > libavutil/hwcontext_d3d11va.c | 10 ++++++++++ > 2 files changed, 11 insertions(+), 1 deletion(-) > > diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c > index 568d686f39..15b25d793c 100644 > --- a/libavcodec/dxva2.c > +++ b/libavcodec/dxva2.c > @@ -645,7 +645,7 @@ int ff_dxva2_common_frame_params(AVCodecContext *avctx, > if (frames_ctx->format == AV_PIX_FMT_D3D11) { > AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx; > - frames_hwctx->BindFlags |= D3D11_BIND_DECODER; > + frames_hwctx->BindFlags |= (D3D11_BIND_DECODER | > D3D11_BIND_SHADER_RESOURCE); > } > #endif > diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c > index 8ab96bad25..97ffd745bd 100644 > --- a/libavutil/hwcontext_d3d11va.c > +++ b/libavutil/hwcontext_d3d11va.c > @@ -203,6 +203,11 @@ static AVBufferRef > *d3d11va_alloc_single(AVHWFramesContext *ctx) > }; > hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, > NULL, &tex); > + if (FAILED(hr) && (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) { > + av_log(ctx, AV_LOG_ERROR, "Could not create the texture with > [D3D11_BIND_SHADER_RESOURCE] flag"); > + texDesc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE; > + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, > &texDesc, NULL, &tex); > + } > if (FAILED(hr)) { > av_log(ctx, AV_LOG_ERROR, "Could not create the texture > (%lx)\n", (long)hr); > return NULL; > @@ -278,6 +283,11 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx) > } > } else if (!(texDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && > texDesc.ArraySize > 0) { > hr = ID3D11Device_CreateTexture2D(device_hwctx->device, > &texDesc, NULL, &hwctx->texture); > + if (FAILED(hr) && (texDesc.BindFlags & > D3D11_BIND_SHADER_RESOURCE)) { > + av_log(ctx, AV_LOG_ERROR, "Could not create the texture > with [D3D11_BIND_SHADER_RESOURCE] flag"); > + texDesc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE; > + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, > &texDesc, NULL, &hwctx->texture); > + } I really don't like these fallbacks. If a caller requests a certain set of flags, it should fullfill these, or fail, and not change them. Especially special-casing this one flag just makes it extra iffy, and I know why you added it, but that doesn't help. IMHO, its also not entirely unreasonable that if you require anything but the default flags, to let the user just manage their own frames context, the effort required is not that high and there is never a set of flags you can set that'll cover every use case (for example, I use surface sharing, thats not set by default either). - Hendrik
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 568d686f39..15b25d793c 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -645,7 +645,7 @@ int ff_dxva2_common_frame_params(AVCodecContext *avctx, if (frames_ctx->format == AV_PIX_FMT_D3D11) { AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx; - frames_hwctx->BindFlags |= D3D11_BIND_DECODER; + frames_hwctx->BindFlags |= (D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE); } #endif diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index 8ab96bad25..97ffd745bd 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -203,6 +203,11 @@ static AVBufferRef *d3d11va_alloc_single(AVHWFramesContext *ctx) }; hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex); + if (FAILED(hr) && (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the texture with [D3D11_BIND_SHADER_RESOURCE] flag"); + texDesc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE; + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex); + }
Starting from Windows 8, users can create SRV from video resource and bind it to shaders directly. This can avoid unnecessary memcpy (ID3D11DeviceContext::CopyResource, etc), so create texture with [D3D11_BIND_SHADER_RESOURCE] as decoder's output if possible. Signed-off-by: Wang Chuan <ouchuanm@outlook.com> --- libavcodec/dxva2.c | 2 +- libavutil/hwcontext_d3d11va.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) if (FAILED(hr)) { av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr); return NULL; @@ -278,6 +283,11 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx) } } else if (!(texDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && texDesc.ArraySize > 0) { hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture); + if (FAILED(hr) && (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the texture with [D3D11_BIND_SHADER_RESOURCE] flag"); + texDesc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE; + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture); + } if (FAILED(hr)) { av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr); return AVERROR_UNKNOWN;