[vlc-devel] [PATCH 3/3] direct3d11: use P010 output when rendering 10 bits content

Steve Lhomme robux4 at videolabs.io
Tue Jul 12 16:59:48 CEST 2016


---
 modules/video_chroma/dxgi_fmt.c         |  3 ++-
 modules/video_output/win32/direct3d11.c | 46 ++++++++++++++++++++++++++++-----
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/modules/video_chroma/dxgi_fmt.c b/modules/video_chroma/dxgi_fmt.c
index f24d20d..0e576b3 100644
--- a/modules/video_chroma/dxgi_fmt.c
+++ b/modules/video_chroma/dxgi_fmt.c
@@ -60,13 +60,14 @@ static const dxgi_format_t dxgi_formats[] = {
 static const d3d_format_t d3d_formats[] = {
     { "NV12",     DXGI_FORMAT_NV12,           VLC_CODEC_NV12,          8, DXGI_FORMAT_R8_UNORM,       DXGI_FORMAT_R8G8_UNORM },
     { "VA_NV12",  DXGI_FORMAT_NV12,           VLC_CODEC_D3D11_OPAQUE,  8, DXGI_FORMAT_R8_UNORM,       DXGI_FORMAT_R8G8_UNORM },
+    { "P010",     DXGI_FORMAT_P010,           VLC_CODEC_P010,         10, DXGI_FORMAT_R16_UNORM,      DXGI_FORMAT_R16G16_UNORM },
+    { "VA_P010",  DXGI_FORMAT_P010,           VLC_CODEC_D3D11_OPAQUE, 10, DXGI_FORMAT_R16_UNORM,      DXGI_FORMAT_R16G16_UNORM },
 #ifdef BROKEN_PIXEL
     { "YUY2",     DXGI_FORMAT_YUY2,           VLC_CODEC_I422,          8, DXGI_FORMAT_R8G8B8A8_UNORM,     0 },
     { "AYUV",     DXGI_FORMAT_AYUV,           VLC_CODEC_YUVA,          8, DXGI_FORMAT_R8G8B8A8_UNORM,     0 },
     { "Y416",     DXGI_FORMAT_Y416,           VLC_CODEC_I444_16L,     16, DXGI_FORMAT_R16G16B16A16_UINT,  0 },
 #endif
 #ifdef UNTESTED
-    { "P010",     DXGI_FORMAT_P010,           VLC_CODEC_P010,         10, DXGI_FORMAT_R16_UNORM,      DXGI_FORMAT_R16G16_UNORM },
     { "Y210",     DXGI_FORMAT_Y210,           VLC_CODEC_I422_10L,     10, DXGI_FORMAT_R16G16B16A16_UNORM, 0 },
     { "Y410",     DXGI_FORMAT_Y410,           VLC_CODEC_I444_10L,     10, DXGI_FORMAT_R10G10B10A2_UNORM,  0 },
     { "NV11",     DXGI_FORMAT_NV11,           VLC_CODEC_I411,          8, DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8G8_UNORM },
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index ed5b97d..67e579a 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -896,6 +896,14 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
     creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
 # endif
 
+    vlc_fourcc_t i_src_chroma = fmt->i_chroma;
+    fmt->i_chroma = 0;
+
+    const vlc_chroma_description_t *p_chroma_desc = vlc_fourcc_GetChromaDescription( i_src_chroma );
+    if ( p_chroma_desc == NULL ||
+         ( p_chroma_desc->pixel_bits == 0 && fmt->i_original_chroma != 0 ))
+        p_chroma_desc = vlc_fourcc_GetChromaDescription( fmt->i_original_chroma );
+
     DXGI_SWAP_CHAIN_DESC1 scd;
     memset(&scd, 0, sizeof(scd));
     scd.BufferCount = 2;
@@ -904,7 +912,7 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
     scd.SampleDesc.Quality = 0;
     scd.Width = fmt->i_visible_width;
     scd.Height = fmt->i_visible_height;
-    scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; /* TODO: use DXGI_FORMAT_NV12 */
+    scd.Format = p_chroma_desc && p_chroma_desc->pixel_bits > 8 ? DXGI_FORMAT_R10G10B10A2_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM; /* TODO: use DXGI_FORMAT_NV12 */
     //scd.Flags = 512; // DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO;
     scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
 
@@ -1029,16 +1037,14 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
 # endif
 #endif
 
-    vlc_fourcc_t i_src_chroma = fmt->i_chroma;
-    fmt->i_chroma = 0;
-
     // look for the request pixel format first
     UINT i_quadSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_LOAD;
     UINT i_formatSupport;
     for (const d3d_format_t *output_format = GetRenderFormatList();
          output_format->name != NULL; ++output_format)
     {
-        if( i_src_chroma == output_format->fourcc)
+        if( i_src_chroma == output_format->fourcc &&
+            ( p_chroma_desc== NULL || p_chroma_desc->pixel_bits <= output_format->bitsPerChannel ))
         {
             if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
                                                            output_format->formatTexture,
@@ -1057,6 +1063,33 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
         }
     }
 
+    // look for any pixel format that we can handle with enough pixels per channel
+    if ( !fmt->i_chroma )
+    {
+        for (const d3d_format_t *output_format = GetRenderFormatList();
+             output_format->name != NULL; ++output_format)
+        {
+            if( i_src_chroma == output_format->fourcc &&
+                ( p_chroma_desc== NULL || p_chroma_desc->pixel_bits <= output_format->bitsPerChannel ))
+            {
+                if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
+                                                               output_format->formatTexture,
+                                                               &i_formatSupport)) &&
+                        ( i_formatSupport & i_quadSupportFlags ) == i_quadSupportFlags )
+                {
+                    msg_Dbg( vd, "Using pixel format %s for chroma %4.4s", output_format->name,
+                                 (char *)&i_src_chroma );
+                    fmt->i_chroma = output_format->fourcc;
+                    DxgiFormatMask( output_format->formatTexture, fmt );
+                    sys->picQuadConfig.textureFormat      = output_format->formatTexture;
+                    sys->picQuadConfig.resourceFormatYRGB = output_format->formatY;
+                    sys->picQuadConfig.resourceFormatUV   = output_format->formatUV;
+                    break;
+                }
+            }
+        }
+    }
+
     // look for any pixel format that we can handle
     if ( !fmt->i_chroma )
     {
@@ -1105,7 +1138,8 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
         sys->d3dregion_format = DXGI_FORMAT_UNKNOWN;
     }
 
-    if (sys->picQuadConfig.resourceFormatYRGB == DXGI_FORMAT_R8_UNORM)
+    if (sys->picQuadConfig.resourceFormatYRGB == DXGI_FORMAT_R8_UNORM ||
+        sys->picQuadConfig.resourceFormatYRGB == DXGI_FORMAT_R16_UNORM)
     {
         if( fmt->i_height > 576 )
             sys->d3dPxShader = globPixelShaderBiplanarYUV_BT709_2RGB;
-- 
2.8.2



More information about the vlc-devel mailing list