Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
fce580a4 by Steve Lhomme at 2024-05-07T11:57:00+02:00
direct3d11: simplify the D3D11_RenderQuad call

Only the ID3D11ShaderResourceView source may change.

- - - - -
71471002 by Steve Lhomme at 2024-05-07T14:09:17+02:00
d3d11_scaler: provide a picture_sys_t

Like d3d11_tonemapper does. It provides more flexibility.

- - - - -
52be95be by Steve Lhomme at 2024-05-07T14:09:17+02:00
direct3d11: use D3D11_UpscalerGetOutput to get the final picture_sys_t

- - - - -
ae050157 by Steve Lhomme at 2024-05-07T14:14:18+02:00
d3d11_tonemap: handle output resolution changes

- - - - -
267ba645 by Steve Lhomme at 2024-05-07T15:00:43+02:00
d3d11_tonemapper: factorize the texture creation

- - - - -
0d09617a by Steve Lhomme at 2024-05-07T15:00:48+02:00
direct3d11: do the SDR->HDR conversion after upscaling

The Super Resolution filter doesn't handle RGB10A2.

- - - - -


5 changed files:

- modules/video_output/win32/d3d11_scaler.cpp
- modules/video_output/win32/d3d11_scaler.h
- modules/video_output/win32/d3d11_tonemap.cpp
- modules/video_output/win32/d3d11_tonemap.h
- modules/video_output/win32/direct3d11.c


Changes:

=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -54,6 +54,8 @@ struct d3d11_scaler
     ComPtr<ID3D11VideoProcessor>            processor;
     ComPtr<ID3D11VideoProcessorOutputView>  outputView;
     ID3D11ShaderResourceView                *SRVs[D3D11_MAX_SHADER_VIEW] = {};
+    picture_sys_t                           picsys{};
+
 #ifdef HAVE_AMF_SCALER
     vlc_amf_context                 amf = {};
     amf::AMFComponent               *amf_scaler = nullptr;
@@ -242,6 +244,11 @@ static void ReleaseSRVs(d3d11_scaler *scaleProc)
     }
 }
 
+picture_sys_t *D3D11_UpscalerGetOutput(d3d11_scaler *scaleProc)
+{
+    return &scaleProc->picsys;
+}
+
 int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, 
d3d11_device_t*d3d_dev,
                          const video_format_t *fmt, video_format_t *quad_fmt,
                          const vout_display_cfg_t *cfg)
@@ -440,6 +447,21 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler 
*scaleProc, d3d11_device
             scaleProc->amf_initialized = true;
         }
 #endif
+
+        if (scaleProc->picsys.processorInput)
+        {
+            scaleProc->picsys.processorInput->Release();
+            scaleProc->picsys.processorInput = NULL;
+        }
+        if (scaleProc->picsys.processorOutput)
+        {
+            scaleProc->picsys.processorOutput->Release();
+            scaleProc->picsys.processorOutput = NULL;
+        }
+        scaleProc->picsys.texture[0] = upscaled.Get();
+        for (size_t i=0; i<ARRAY_SIZE(scaleProc->picsys.resourceView); i++)
+            scaleProc->picsys.resourceView[i] = scaleProc->SRVs[i];
+        scaleProc->picsys.formatTexture = texDesc.Format;
     }
 
 #ifdef HAVE_AMF_SCALER


=====================================
modules/video_output/win32/d3d11_scaler.h
=====================================
@@ -27,6 +27,7 @@ int D3D11_UpscalerUpdate(vlc_object_t *, struct d3d11_scaler 
*, d3d11_device_t*,
                          const vout_display_cfg_t *);
 int D3D11_UpscalerScale(vlc_object_t *, struct d3d11_scaler *, picture_sys_t 
*);
 bool D3D11_UpscalerUsed(const struct d3d11_scaler *);
+struct picture_sys_t *D3D11_UpscalerGetOutput(struct d3d11_scaler *);
 void D3D11_UpscalerGetSRV(const struct d3d11_scaler *, 
ID3D11ShaderResourceView *SRV[D3D11_MAX_SHADER_VIEW]);
 void D3D11_UpscalerGetSize(const struct d3d11_scaler *, unsigned *i_width, 
unsigned *i_height);
 


=====================================
modules/video_output/win32/d3d11_tonemap.cpp
=====================================
@@ -28,6 +28,12 @@ struct d3d11_tonemapper
     ComPtr<ID3D11VideoProcessorOutputView>  outputView;
     ComPtr<ID3D11ShaderResourceView>        SRV;
     picture_sys_t                           picsys{};
+
+    const d3d_format_t              *d3d_fmt = nullptr;
+    UINT                            Width  = 0;
+    UINT                            Height = 0;
+
+    HRESULT UpdateTexture(vlc_object_t *, d3d11_device_t *, UINT width, UINT 
height);
 };
 
 d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, d3d11_device_t 
*d3d_dev,
@@ -45,13 +51,9 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, 
d3d11_device_t *d3d_d
         return nullptr; // the source is already in HDR
     }
 
-    ComPtr<ID3D11Texture2D> texture;
-    ID3D11Texture2D *_texture[D3D11_MAX_SHADER_VIEW] = {};
-    D3D11_TEXTURE2D_DESC texDesc { };
-    D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outDesc{ };
     d3d11_tonemapper *tonemapProc = new d3d11_tonemapper();
-    const auto d3d_fmt = D3D11_RenderFormat(DXGI_FORMAT_R10G10B10A2_UNORM, 
false);
-    assert(d3d_fmt != nullptr);
+    tonemapProc->d3d_fmt = D3D11_RenderFormat(DXGI_FORMAT_R10G10B10A2_UNORM, 
false);
+    assert(tonemapProc->d3d_fmt != nullptr);
 
     HRESULT hr;
     hr = 
d3d_dev->d3ddevice->QueryInterface(IID_GRAPHICS_PPV_ARGS(&tonemapProc->d3dviddev));
@@ -141,6 +143,24 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, 
d3d11_device_t *d3d_d
         d3d11_device_unlock(d3d_dev);
     }
 
+    hr = tonemapProc->UpdateTexture(vd, d3d_dev, in->i_width, in->i_height);
+    if (FAILED(hr))
+        goto error;
+
+    return tonemapProc;
+error:
+    delete tonemapProc;
+    return nullptr;
+}
+
+HRESULT d3d11_tonemapper::UpdateTexture(vlc_object_t *vd, d3d11_device_t 
*d3d_dev, UINT width, UINT height)
+{
+    ComPtr<ID3D11Texture2D> texture;
+    D3D11_TEXTURE2D_DESC texDesc { };
+    D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outDesc{ };
+    ID3D11Texture2D *_texture[D3D11_MAX_SHADER_VIEW] = {};
+    HRESULT hr;
+
     // we need a texture that will receive the upscale version
     texDesc.MipLevels = 1;
     texDesc.SampleDesc.Count = 1;
@@ -149,37 +169,46 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t 
*vd, d3d11_device_t *d3d_d
     texDesc.CPUAccessFlags = 0;
     texDesc.ArraySize = 1;
     texDesc.Format = d3d_fmt->formatTexture;
-    texDesc.Width = in->i_width;
-    texDesc.Height = in->i_height;
+    texDesc.Width = width;
+    texDesc.Height = height;
     texDesc.MiscFlags = 0;
     hr = d3d_dev->d3ddevice->CreateTexture2D(&texDesc, nullptr, 
texture.GetAddressOf());
     if (FAILED(hr))
     {
         msg_Err(vd, "Failed to create the tonemap texture. (hr=0x%lX)", hr);
-        goto error;
+        return hr;
     }
 
     outDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
     outDesc.Texture2D.MipSlice = 0;
 
-    hr = tonemapProc->d3dviddev->CreateVideoProcessorOutputView(
-                                                            texture.Get(),
-                                                            
tonemapProc->enumerator.Get(),
-                                                            &outDesc,
-                                                            
tonemapProc->outputView.ReleaseAndGetAddressOf());
+    hr = d3dviddev->CreateVideoProcessorOutputView(texture.Get(),
+                                                   enumerator.Get(),
+                                                   &outDesc,
+                                                   
outputView.ReleaseAndGetAddressOf());
     if (FAILED(hr))
     {
         msg_Dbg(vd,"Failed to create processor output. (hr=0x%lX)", hr);
-        goto error;
+        return hr;
     }
 
+    if (picsys.processorInput)
+    {
+        picsys.processorInput->Release();
+        picsys.processorInput = NULL;
+    }
+    if (picsys.processorOutput)
+    {
+        picsys.processorOutput->Release();
+        picsys.processorOutput = NULL;
+    }
     _texture[0] = texture.Get();
     _texture[1] = texture.Get();
     _texture[2] = texture.Get();
     _texture[3] = texture.Get();
     if ((D3D11_AllocateShaderView)(vd, d3d_dev->d3ddevice, d3d_fmt,
-                                   _texture, 0, 
tonemapProc->SRV.GetAddressOf()) != VLC_SUCCESS)
-        goto error;
+                                   _texture, 0, SRV.ReleaseAndGetAddressOf()) 
!= VLC_SUCCESS)
+        return hr;
 
     {
         RECT srcRect;
@@ -188,26 +217,25 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t 
*vd, d3d11_device_t *d3d_d
         srcRect.right  = texDesc.Width;
         srcRect.bottom = texDesc.Height;
 
-        RECT dstRect = srcRect;
-
         d3d11_device_lock(d3d_dev);
-        
tonemapProc->d3dvidctx->VideoProcessorSetStreamSourceRect(tonemapProc->processor.Get(),
+        d3dvidctx->VideoProcessorSetStreamSourceRect(processor.Get(),
                                                                   0, TRUE, 
&srcRect);
 
-        
tonemapProc->d3dvidctx->VideoProcessorSetStreamDestRect(tonemapProc->processor.Get(),
-                                                                0, TRUE, 
&dstRect);
+        d3dvidctx->VideoProcessorSetStreamDestRect(processor.Get(),
+                                                                0, TRUE, 
&srcRect);
 
         d3d11_device_unlock(d3d_dev);
     }
 
-    tonemapProc->picsys.texture[0] = texture.Get();
-    tonemapProc->picsys.resourceView[0] = tonemapProc->SRV.Get();
-    tonemapProc->picsys.formatTexture = texDesc.Format;
+    picsys.texture[0] = texture.Get();
+    picsys.resourceView[0] = SRV.Get();
+    picsys.formatTexture = texDesc.Format;
 
-    return tonemapProc;
-error:
-    delete tonemapProc;
-    return nullptr;
+    Width  = texDesc.Width;
+    Height = texDesc.Height;
+    msg_Dbg(vd, "tonemap resolution %ux%u", Width, Height);
+
+    return S_OK;
 }
 
 void D3D11_TonemapperDestroy(d3d11_tonemapper *tonemapProc)
@@ -265,3 +293,51 @@ HRESULT D3D11_TonemapperProcess(vlc_object_t *vd, 
d3d11_tonemapper *tonemapProc,
         msg_Err(vd, "Failed to render the texture. (hr=0x%lX)", hr);
     return hr;
 }
+
+int D3D11_TonemapperUpdate(vlc_object_t *vd, d3d11_tonemapper *tonemapProc, 
d3d11_device_t*d3d_dev,
+                           video_format_t *quad_fmt)
+{
+    HRESULT hr;
+    ID3D11Texture2D *_texture[D3D11_MAX_SHADER_VIEW];
+    ComPtr<ID3D11Texture2D> texture;
+    D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outDesc{ };
+    D3D11_VIDEO_COLOR black{};
+    black.RGBA.A = 1.f;
+
+    unsigned out_width, out_height;
+    out_width  = quad_fmt->i_width;
+    out_height = quad_fmt->i_height;
+
+    quad_fmt->i_sar_num = 1;
+    quad_fmt->i_sar_den = 1;
+    quad_fmt->b_color_range_full = true;
+
+    if (tonemapProc->Width == out_width && tonemapProc->Height == out_height)
+        // do nothing
+        return VLC_SUCCESS;
+
+    hr = tonemapProc->UpdateTexture(vd, d3d_dev, out_width, out_height);
+    if (FAILED(hr))
+        goto done_super;
+
+    RECT srcRect;
+    srcRect.left   = 0;
+    srcRect.top    = 0;
+    srcRect.right  = tonemapProc->Width;
+    srcRect.bottom = tonemapProc->Height;
+
+    d3d11_device_lock(d3d_dev);
+    
tonemapProc->d3dvidctx->VideoProcessorSetStreamSourceRect(tonemapProc->processor.Get(),
+                                                            0, TRUE, &srcRect);
+
+    
tonemapProc->d3dvidctx->VideoProcessorSetStreamDestRect(tonemapProc->processor.Get(),
+                                                          0, TRUE, &srcRect);
+    d3d11_device_unlock(d3d_dev);
+
+    return VLC_SUCCESS;
+done_super:
+    tonemapProc->SRV.Reset();
+    tonemapProc->processor.Reset();
+    tonemapProc->enumerator.Reset();
+    return VLC_EGENERIC;
+}


=====================================
modules/video_output/win32/d3d11_tonemap.h
=====================================
@@ -23,6 +23,8 @@ struct d3d11_tonemapper;
 struct d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *, d3d11_device_t 
*,
                                                 const video_format_t * in);
 void D3D11_TonemapperDestroy(struct d3d11_tonemapper *);
+int D3D11_TonemapperUpdate(vlc_object_t *, struct d3d11_tonemapper *, 
d3d11_device_t*,
+                         video_format_t *);
 HRESULT D3D11_TonemapperProcess(vlc_object_t *, struct d3d11_tonemapper *, 
picture_sys_t *);
 struct picture_sys_t *D3D11_TonemapperGetOutput(struct d3d11_tonemapper *);
 


=====================================
modules/video_output/win32/direct3d11.c
=====================================
@@ -650,6 +650,10 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
         cfg.display.height = window_height;
         D3D11_UpscalerUpdate(VLC_OBJECT(vd), sys->scaleProc, &sys->d3d_dev,
                              &sys->pool_fmt, &sys->quad_fmt, &cfg);
+
+        if (sys->tonemapProc)
+            D3D11_TonemapperUpdate(VLC_OBJECT(vd), sys->tonemapProc, 
&sys->d3d_dev,
+                                   &sys->quad_fmt);
     }
 
     D3D11_TEXTURE2D_DESC dsc = { 0 };
@@ -934,6 +938,10 @@ static int Control(vout_display_t *vd, int query, va_list 
args)
                 cfg.display.height = window_height;
                 D3D11_UpscalerUpdate(VLC_OBJECT(vd), sys->scaleProc, 
&sys->d3d_dev, &vd->source,
                                      &sys->quad_fmt, &cfg);
+
+                if (sys->tonemapProc)
+                    D3D11_TonemapperUpdate(VLC_OBJECT(vd), sys->tonemapProc, 
&sys->d3d_dev,
+                                           &sys->quad_fmt);
             }
             break;
         }
@@ -1046,28 +1054,25 @@ static void Prepare(vout_display_t *vd, picture_t 
*picture, subpicture_t *subpic
     {
         picture_sys_t *p_sys = ActivePictureSys(picture);
 
-        D3D11_TEXTURE2D_DESC srcDesc;
-        ID3D11Texture2D_GetDesc(p_sys->texture[KNOWN_DXGI_INDEX], &srcDesc);
-
         if (is_d3d11_opaque(picture->format.i_chroma))
             d3d11_device_lock( &sys->d3d_dev );
 
-        if (sys->tonemapProc)
+        if (sys->scaleProc && D3D11_UpscalerUsed(sys->scaleProc))
         {
-            if (FAILED(D3D11_TonemapperProcess(VLC_OBJECT(vd), 
sys->tonemapProc, p_sys)))
+            if (D3D11_UpscalerScale(VLC_OBJECT(vd), sys->scaleProc, p_sys) != 
VLC_SUCCESS)
                 return;
-            p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
+            p_sys = D3D11_UpscalerGetOutput(sys->scaleProc);
         }
-        if (sys->scaleProc && D3D11_UpscalerUsed(sys->scaleProc))
+        if (sys->tonemapProc)
         {
-            if (D3D11_UpscalerScale(VLC_OBJECT(vd), sys->scaleProc, p_sys) != 
VLC_SUCCESS)
+            if (FAILED(D3D11_TonemapperProcess(VLC_OBJECT(vd), 
sys->tonemapProc, p_sys)))
                 return;
-            uint32_t witdh, height;
-            D3D11_UpscalerGetSize(sys->scaleProc, &witdh, &height);
-            srcDesc.Width  = witdh;
-            srcDesc.Height = height;
+            p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
         }
 
+        D3D11_TEXTURE2D_DESC srcDesc;
+        ID3D11Texture2D_GetDesc(p_sys->texture[KNOWN_DXGI_INDEX], &srcDesc);
+
         if (!is_d3d11_opaque(picture->format.i_chroma) || sys->legacy_shader) {
             D3D11_TEXTURE2D_DESC texDesc;
             if (!is_d3d11_opaque(picture->format.i_chroma))
@@ -1153,24 +1158,28 @@ static void Prepare(vout_display_t *vd, picture_t 
*picture, subpicture_t *subpic
 
     ID3D11DeviceContext_ClearDepthStencilView(sys->d3d_dev.d3dcontext, 
sys->d3ddepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
 
-    /* Render the quad */
+    ID3D11ShaderResourceView *SRV[D3D11_MAX_SHADER_VIEW];
+    /* Render the quad using the last stage of processing */
     if (!is_d3d11_opaque(picture->format.i_chroma) || sys->legacy_shader)
-        D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, 
sys->stagingSys.resourceView, sys->d3drenderTargetView);
+    {
+        memcpy(SRV, sys->stagingSys.resourceView, sizeof(SRV));
+    }
+    else if (sys->tonemapProc)
+    {
+        picture_sys_t *p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
+        memcpy(SRV, p_sys->resourceView, sizeof(SRV));
+    }
     else if (sys->scaleProc && D3D11_UpscalerUsed(sys->scaleProc))
     {
-        ID3D11ShaderResourceView *SRV[D3D11_MAX_SHADER_VIEW];
         D3D11_UpscalerGetSRV(sys->scaleProc, SRV);
-        D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, SRV, 
sys->d3drenderTargetView);
     }
     else
     {
         picture_sys_t *p_sys;
-        if (sys->tonemapProc)
-            p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
-        else
-            p_sys = ActivePictureSys(picture);
-        D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, p_sys->resourceView, 
sys->d3drenderTargetView);
+        p_sys = ActivePictureSys(picture);
+        memcpy(SRV, p_sys->resourceView, sizeof(SRV));
     }
+    D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, SRV, 
sys->d3drenderTargetView);
 
     if (subpicture) {
         // draw the additional vertices
@@ -1588,8 +1597,6 @@ static int Direct3D11Open(vout_display_t *vd, bool 
external_device)
         return VLC_EGENERIC;
         }
 
-        InitTonemapProcessor(vd, &vd->source);
-
         hr = IDXGIAdapter_GetParent(dxgiadapter, &IID_IDXGIFactory2, (void 
**)&dxgifactory);
         IDXGIAdapter_Release(dxgiadapter);
         if (FAILED(hr)) {
@@ -1773,21 +1780,6 @@ static int SetupOutputFormat(vout_display_t *vd, 
video_format_t *fmt, video_form
 
     // look for the requested pixel format first
     const d3d_format_t *decoder_format = NULL;
-    if (sys->hdrMode == hdr_Fake)
-    {
-        quad_fmt->i_chroma           = VLC_CODEC_RGBA10;
-        quad_fmt->primaries          = sys->display.colorspace->primaries;
-        quad_fmt->transfer           = sys->display.colorspace->transfer;
-        quad_fmt->space              = sys->display.colorspace->color;
-        quad_fmt->b_color_range_full = sys->display.colorspace->b_full_range;
-
-        // request an input format that can be input of a VideoProcessor
-        UINT supportFlags = D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT;
-        if (is_d3d11_opaque(fmt->i_chroma))
-            supportFlags |= D3D11_FORMAT_SUPPORT_DECODER_OUTPUT;
-        decoder_format = FindD3D11Format( vd, &sys->d3d_dev, fmt->i_chroma, 
false, 0, 0, 0,
-                                          is_d3d11_opaque(fmt->i_chroma), 
supportFlags );
-    }
     sys->picQuad.formatInfo = SelectOutputFormat(vd, quad_fmt, 
&decoder_format);
 
     if ( !sys->picQuad.formatInfo )
@@ -1797,18 +1789,30 @@ static int SetupOutputFormat(vout_display_t *vd, 
video_format_t *fmt, video_form
     }
     sys->pool_d3dfmt = decoder_format ? decoder_format : 
sys->picQuad.formatInfo;
 
+    InitScaleProcessor(vd);
+
     msg_Dbg( vd, "Using pixel format %s for chroma %4.4s", 
sys->pool_d3dfmt->name,
                  (char *)&fmt->i_chroma );
     fmt->i_chroma = sys->pool_d3dfmt->fourcc;
     DxgiFormatMask( sys->picQuad.formatInfo->formatTexture, fmt );
 
+    InitTonemapProcessor(vd, quad_fmt);
+
+    if (sys->hdrMode == hdr_Fake)
+    {
+        quad_fmt->i_chroma           = VLC_CODEC_RGBA10;
+        quad_fmt->primaries          = sys->display.colorspace->primaries;
+        quad_fmt->transfer           = sys->display.colorspace->transfer;
+        quad_fmt->space              = sys->display.colorspace->color;
+        quad_fmt->b_color_range_full = sys->display.colorspace->b_full_range;
+        sys->picQuad.formatInfo = SelectOutputFormat(vd, quad_fmt, 
&decoder_format);
+    }
+
     /* check the region pixel format */
     sys->d3dregion_format = GetBlendableFormat(vd, VLC_CODEC_RGBA);
     if (!sys->d3dregion_format)
         sys->d3dregion_format = GetBlendableFormat(vd, VLC_CODEC_BGRA);
 
-    InitScaleProcessor(vd);
-
     sys->legacy_shader = sys->d3d_dev.feature_level < D3D_FEATURE_LEVEL_10_0 ||
             (sys->scaleProc == NULL && !CanUseTextureArray(vd)) ||
             BogusZeroCopy(vd);



View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/6f813f37e989d43da625fcdf8e63a28b06ca5bdb...0d09617ac88e492a6ced8971f3a6b3d6d5af3c02

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


VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to