[vlc-commits] d3d11_surface: allocate the CPU to GPU staging texture in a function

Steve Lhomme git at videolan.org
Tue Dec 10 16:24:32 CET 2019


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Dec 10 08:26:13 2019 +0100| [12148ff53cdddb6acecd1df87e25a490cfa34308] | committer: Steve Lhomme

d3d11_surface: allocate the CPU to GPU staging texture in a function

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=12148ff53cdddb6acecd1df87e25a490cfa34308
---

 modules/hw/d3d11/d3d11_surface.c | 152 ++++++++++++++++++++++-----------------
 1 file changed, 86 insertions(+), 66 deletions(-)

diff --git a/modules/hw/d3d11/d3d11_surface.c b/modules/hw/d3d11/d3d11_surface.c
index 28c77dccd5..2c88bf0bc8 100644
--- a/modules/hw/d3d11/d3d11_surface.c
+++ b/modules/hw/d3d11/d3d11_surface.c
@@ -475,13 +475,6 @@ static void D3D11_RGBA(filter_t *p_filter, picture_t *src, picture_t *dst)
     vlc_mutex_unlock(&sys->staging_lock);
 }
 
-static void DestroyPicture(picture_t *picture)
-{
-    picture_sys_d3d11_t *p_sys = picture->p_sys;
-    ReleaseD3D11PictureSys( p_sys );
-    free(p_sys);
-}
-
 static void DeleteFilter( filter_t * p_filter )
 {
     if( p_filter->p_module )
@@ -547,7 +540,7 @@ static void NV12_D3D11(filter_t *p_filter, picture_t *src, picture_t *dst)
         return;
     }
 
-    picture_sys_d3d11_t *p_staging_sys = sys->staging_pic->p_sys;
+    picture_sys_d3d11_t *p_staging_sys = p_sys;
 
     D3D11_TEXTURE2D_DESC texDesc;
     ID3D11Texture2D_GetDesc( p_staging_sys->texture[KNOWN_DXGI_INDEX], &texDesc);
@@ -576,6 +569,8 @@ static void NV12_D3D11(filter_t *p_filter, picture_t *src, picture_t *dst)
                                               0, 0, 0,
                                               p_staging_sys->resource[KNOWN_DXGI_INDEX], 0,
                                               &copyBox);
+    dst->i_planes = 0;
+
     if (dst->context == NULL)
     {
         struct d3d11_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
@@ -586,7 +581,6 @@ static void NV12_D3D11(filter_t *p_filter, picture_t *src, picture_t *dst)
                 vlc_video_context_Hold(p_filter->vctx_out),
             };
             pic_ctx->picsys = *p_sys;
-            AcquireD3D11PictureSys(&pic_ctx->picsys);
             dst->context = &pic_ctx->s;
         }
     }
@@ -597,6 +591,86 @@ VIDEO_FILTER_WRAPPER (D3D11_YUY2)
 VIDEO_FILTER_WRAPPER (D3D11_RGBA)
 VIDEO_FILTER_WRAPPER (NV12_D3D11)
 
+static picture_t *AllocateCPUtoGPUTexture(filter_t *p_filter)
+{
+    video_format_t fmt_staging;
+    ID3D11Texture2D *texture = NULL;
+    HRESULT hr;
+
+    d3d11_video_context_t *vctx_sys = GetD3D11ContextPrivate( p_filter->vctx_out );
+
+    const d3d_format_t *cfg = NULL;
+    for (const d3d_format_t *output_format = GetRenderFormatList();
+            output_format->name != NULL; ++output_format)
+    {
+        if (output_format->formatTexture == vctx_sys->format &&
+            !is_d3d11_opaque(output_format->fourcc))
+        {
+            cfg = output_format;
+            break;
+        }
+    }
+    if (unlikely(cfg == NULL))
+        return NULL;
+
+    struct d3d11_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
+    if (unlikely(pic_ctx == NULL))
+        goto done;
+
+    picture_resource_t res = {};
+    picture_sys_d3d11_t *res_sys = &pic_ctx->picsys;
+    res.p_sys = res_sys;
+    res_sys->context = vctx_sys->device;
+    res_sys->formatTexture = vctx_sys->format;
+
+    video_format_Copy(&fmt_staging, &p_filter->fmt_out.video);
+    fmt_staging.i_chroma = cfg->fourcc;
+
+    picture_t *p_dst = picture_NewFromResource(&fmt_staging, &res);
+    if (p_dst == NULL) {
+        msg_Err(p_filter, "Failed to map create the temporary picture.");
+        goto done;
+    }
+    picture_Setup(p_dst, &p_dst->format);
+
+    D3D11_TEXTURE2D_DESC texDesc;
+    texDesc.Format = vctx_sys->format;
+    texDesc.MipLevels = 1;
+    texDesc.SampleDesc.Count = 1;
+    texDesc.SampleDesc.Quality = 0;
+    texDesc.MiscFlags = 0;
+    texDesc.ArraySize = 1;
+    texDesc.Usage = D3D11_USAGE_STAGING;
+    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    texDesc.BindFlags = 0;
+    texDesc.Width  = p_dst->format.i_width;
+    texDesc.Height = p_dst->format.i_height; /* make sure we match picture_Setup() */
+
+    filter_sys_t *p_sys = p_filter->p_sys;
+
+    hr = ID3D11Device_CreateTexture2D( p_sys->d3d_dev.d3ddevice, &texDesc, NULL, &texture);
+    if (FAILED(hr)) {
+        msg_Err(p_filter, "Failed to create a %s staging texture to extract surface pixels (hr=0x%lX)", DxgiFormatToStr(texDesc.Format), hr );
+        goto done;
+    }
+
+    res_sys->texture[KNOWN_DXGI_INDEX] = texture;
+
+    pic_ctx->s = (picture_context_t) {
+        d3d11_pic_context_destroy, d3d11_pic_context_copy,
+        vlc_video_context_Hold(p_filter->vctx_out),
+    };
+    AcquireD3D11PictureSys(res_sys);
+    ID3D11Texture2D_Release(res_sys->texture[KNOWN_DXGI_INDEX]);
+
+    p_dst->context = &pic_ctx->s;
+
+    return p_dst;
+done:
+    free(pic_ctx);
+    return NULL;
+}
+
 int D3D11OpenConverter( vlc_object_t *obj )
 {
     filter_t *p_filter = (filter_t *)obj;
@@ -665,9 +739,7 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
 {
     filter_t *p_filter = (filter_t *)obj;
     int err = VLC_EGENERIC;
-    ID3D11Texture2D *texture = NULL;
     filter_t *p_cpu_filter = NULL;
-    video_format_t fmt_staging;
     filter_sys_t *p_sys = NULL;
 
     if ( p_filter->fmt_out.video.i_chroma != VLC_CODEC_D3D11_OPAQUE
@@ -718,8 +790,6 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
         return VLC_EGENERIC;
     }
 
-    video_format_Init(&fmt_staging, 0);
-
     p_filter->vctx_out = vlc_video_context_Create(dec_device, VLC_VIDEO_CONTEXT_D3D11VA,
                                           sizeof(d3d11_video_context_t), &d3d11_vctx_ops);
     vlc_decoder_device_Release(dec_device);
@@ -745,57 +815,11 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
         vlc_assert_unreachable();
     }
     vctx_sys->device = p_sys->d3d_dev.d3dcontext;
+    p_filter->p_sys = p_sys;
 
-    vlc_fourcc_t d3d_fourcc = DxgiFormatFourcc(vctx_sys->format);
-    if (d3d_fourcc == 0)
-        goto done;
-
-    picture_resource_t res = {
-        .pf_destroy = DestroyPicture,
-    };
-    picture_sys_d3d11_t *res_sys = calloc(1, sizeof(picture_sys_d3d11_t));
-    if (res_sys == NULL) {
-        err = VLC_ENOMEM;
-        goto done;
-    }
-    res.p_sys = res_sys;
-    res_sys->context = p_sys->d3d_dev.d3dcontext;
-    res_sys->formatTexture = vctx_sys->format;
-
-    video_format_Copy(&fmt_staging, &p_filter->fmt_out.video);
-    fmt_staging.i_chroma = d3d_fourcc;
-
-    picture_t *p_dst = picture_NewFromResource(&fmt_staging, &res);
-    if (p_dst == NULL) {
-        msg_Err(p_filter, "Failed to map create the temporary picture.");
-        goto done;
-    }
-    picture_sys_d3d11_t *p_dst_sys = p_dst->p_sys;
-    picture_Setup(p_dst, &p_dst->format);
-
-    D3D11_TEXTURE2D_DESC texDesc;
-    texDesc.Format = vctx_sys->format;
-    texDesc.MipLevels = 1;
-    texDesc.SampleDesc.Count = 1;
-    texDesc.SampleDesc.Quality = 0;
-    texDesc.MiscFlags = 0;
-    texDesc.ArraySize = 1;
-    texDesc.Usage = D3D11_USAGE_STAGING;
-    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-    texDesc.BindFlags = 0;
-    texDesc.Width  = p_dst->format.i_width;
-    texDesc.Height = p_dst->format.i_height; /* make sure we match picture_Setup() */
-
-    hr = ID3D11Device_CreateTexture2D( p_sys->d3d_dev.d3ddevice, &texDesc, NULL, &texture);
-    if (FAILED(hr)) {
-        msg_Err(p_filter, "Failed to create a %s staging texture to extract surface pixels (hr=0x%lX)", DxgiFormatToStr(texDesc.Format), hr );
-        goto done;
-    }
-
-    res_sys->texture[KNOWN_DXGI_INDEX] = texture;
-    ID3D11DeviceContext_AddRef(p_dst_sys->context);
+    picture_t *p_dst = AllocateCPUtoGPUTexture(p_filter);
 
-    if ( p_filter->fmt_in.video.i_chroma != d3d_fourcc )
+    if ( p_filter->fmt_in.video.i_chroma != p_dst->format.i_chroma )
     {
         p_cpu_filter = CreateCPUtoGPUFilter(p_filter, &p_filter->fmt_in, p_dst->format.i_chroma);
         if (!p_cpu_filter)
@@ -804,17 +828,13 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
 
     p_sys->filter = p_cpu_filter;
     p_sys->staging_pic = p_dst;
-    p_filter->p_sys = p_sys;
     err = VLC_SUCCESS;
 
 done:
-    video_format_Clean(&fmt_staging);
     if (err != VLC_SUCCESS)
     {
         if (p_cpu_filter)
             DeleteFilter( p_cpu_filter );
-        if (texture)
-            ID3D11Texture2D_Release(texture);
         vlc_video_context_Release(p_filter->vctx_out);
         D3D11_ReleaseDevice(&p_sys->d3d_dev);
     }



More information about the vlc-commits mailing list