diff mbox series

[FFmpeg-devel] d3d11va: let user can create SRV from output

Message ID ME3PR01MB562442911EA9A24F5402E084DA0A9@ME3PR01MB5624.ausprd01.prod.outlook.com
State New
Headers show
Series [FFmpeg-devel] d3d11va: let user can create SRV from output | expand

Checks

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

Commit Message

Wang Chuan March 9, 2022, 6:56 a.m. UTC
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;

Comments

Hendrik Leppkes March 9, 2022, 7:20 a.m. UTC | #1
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 mbox series

Patch

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);
+    }