[vlc-devel] [PATCH] direct3d11: allow custom shader per pixel format

Steve Lhomme robux4 at videolabs.io
Wed Mar 25 17:51:42 CET 2015


---
 modules/video_output/msw/common.h     |   1 +
 modules/video_output/msw/direct3d11.c | 157 ++++++++++++++++++----------------
 2 files changed, 82 insertions(+), 76 deletions(-)

diff --git a/modules/video_output/msw/common.h b/modules/video_output/msw/common.h
index 2aeeba7..20ca328 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -177,6 +177,7 @@ struct vout_display_sys_t
     DXGI_FORMAT              d3dFormatY;
     DXGI_FORMAT              d3dFormatUV;
     vlc_fourcc_t             vlcFormat;
+    const char               *d3dPxShader;
 #endif
 
 #ifdef MODULE_NAME_IS_direct3d9
diff --git a/modules/video_output/msw/direct3d11.c b/modules/video_output/msw/direct3d11.c
index 09334fb..333fa60 100644
--- a/modules/video_output/msw/direct3d11.c
+++ b/modules/video_output/msw/direct3d11.c
@@ -63,35 +63,6 @@ vlc_module_begin ()
     set_callbacks(Open, Close)
 vlc_module_end ()
 
-typedef struct
-{
-    const char   *name;
-    DXGI_FORMAT  formatTexture;
-    vlc_fourcc_t fourcc;
-    DXGI_FORMAT  formatY;
-    DXGI_FORMAT  formatUV;
-} d3d_format_t;
-
-static const d3d_format_t d3d_formats[] = {
-    { "NV12",     DXGI_FORMAT_NV12,           VLC_CODEC_NV12,     DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8G8_UNORM },
-#ifdef BROKEN_PIXEL
-    { "YUY2",     DXGI_FORMAT_YUY2,           VLC_CODEC_I422,     DXGI_FORMAT_R8G8B8A8_UNORM,     0 },
-    { "AYUV",     DXGI_FORMAT_AYUV,           VLC_CODEC_YUVA,     DXGI_FORMAT_R8G8B8A8_UNORM,     0 },
-    { "Y416",     DXGI_FORMAT_Y416,           VLC_CODEC_I444_16L, DXGI_FORMAT_R16G16B16A16_UINT,  0 },
-#endif
-#ifdef UNTESTED
-    { "P010",     DXGI_FORMAT_P010,           VLC_CODEC_I420_10L, DXGI_FORMAT_R16_UNORM,          DXGI_FORMAT_R16_UNORM },
-    { "Y210",     DXGI_FORMAT_Y210,           VLC_CODEC_I422_10L, DXGI_FORMAT_R16G16B16A16_UNORM, 0 },
-    { "Y410",     DXGI_FORMAT_Y410,           VLC_CODEC_I444_10L, DXGI_FORMAT_R10G10B10A2_UNORM,  0 },
-    { "NV11",     DXGI_FORMAT_NV11,           VLC_CODEC_I411,     DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8G8_UNORM },
-#endif
-    { "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_RGB32,    DXGI_FORMAT_B8G8R8X8_UNORM,     0 },
-    { "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA,     DXGI_FORMAT_B8G8R8A8_UNORM,     0 },
-    { "B5G6R5",   DXGI_FORMAT_B5G6R5_UNORM,   VLC_CODEC_RGB16,    DXGI_FORMAT_B5G6R5_UNORM,       0 },
-
-    { NULL, 0, 0, 0, 0}
-};
-
 static const vlc_fourcc_t d3d_subpicture_chromas[] = {
     VLC_CODEC_RGBA,
     0
@@ -152,7 +123,7 @@ static const char* globVertexShaderDefault = "\
   }\
 ";
 
-static const char* globPixelShaderDefault = "\
+#define globPixelShaderDefault "\
   Texture2D shaderTexture;\
   SamplerState SampleType;\
   \
@@ -166,9 +137,9 @@ static const char* globPixelShaderDefault = "\
   {\
     return shaderTexture.Sample(SampleType, In.Texture);\
   }\
-";
+"
 
-static const char* globPixelShaderBiplanarYUV2RGB = "\
+#define globPixelShaderBiplanarYUV2RGB "\
   Texture2D shaderTextureY;\
   Texture2D shaderTextureUV;\
   SamplerState SampleType;\
@@ -194,8 +165,37 @@ static const char* globPixelShaderBiplanarYUV2RGB = "\
     rgba.w = 1.0;\
     return rgba;\
   }\
-";
+"
+
+typedef struct
+{
+    const char   *name;
+    DXGI_FORMAT  formatTexture;
+    vlc_fourcc_t fourcc;
+    DXGI_FORMAT  formatY;
+    DXGI_FORMAT  formatUV;
+    const char   *px_shader;
+} d3d_format_t;
+
+static const d3d_format_t d3d_formats[] = {
+    { "NV12",     DXGI_FORMAT_NV12,           VLC_CODEC_NV12,     DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8G8_UNORM, globPixelShaderBiplanarYUV2RGB },
+#ifdef BROKEN_PIXEL
+    { "YUY2",     DXGI_FORMAT_YUY2,           VLC_CODEC_I422,     DXGI_FORMAT_R8G8B8A8_UNORM,     0, globPixelShaderDefault },
+    { "AYUV",     DXGI_FORMAT_AYUV,           VLC_CODEC_YUVA,     DXGI_FORMAT_R8G8B8A8_UNORM,     0, globPixelShaderDefault },
+    { "Y416",     DXGI_FORMAT_Y416,           VLC_CODEC_I444_16L, DXGI_FORMAT_R16G16B16A16_UINT,  0, globPixelShaderDefault },
+#endif
+#ifdef UNTESTED
+    { "P010",     DXGI_FORMAT_P010,           VLC_CODEC_I420_10L, DXGI_FORMAT_R16_UNORM,          DXGI_FORMAT_R16_UNORM, globPixelShaderBiplanarYUV2RGB },
+    { "Y210",     DXGI_FORMAT_Y210,           VLC_CODEC_I422_10L, DXGI_FORMAT_R16G16B16A16_UNORM, 0, globPixelShaderDefault },
+    { "Y410",     DXGI_FORMAT_Y410,           VLC_CODEC_I444_10L, DXGI_FORMAT_R10G10B10A2_UNORM,  0, globPixelShaderDefault },
+    { "NV11",     DXGI_FORMAT_NV11,           VLC_CODEC_I411,     DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8G8_UNORM, globPixelShaderBiplanarYUV2RGB },
+#endif
+    { "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_RGB32,    DXGI_FORMAT_B8G8R8X8_UNORM,     0, globPixelShaderDefault },
+    { "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA,     DXGI_FORMAT_B8G8R8A8_UNORM,     0, globPixelShaderDefault },
+    { "B5G6R5",   DXGI_FORMAT_B5G6R5_UNORM,   VLC_CODEC_RGB16,    DXGI_FORMAT_B5G6R5_UNORM,       0, globPixelShaderDefault },
 
+    { NULL, 0, 0, 0, 0, NULL}
+};
 
 static int Open(vlc_object_t *object)
 {
@@ -356,11 +356,14 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
 
     /* Render the quad */
     ID3D11DeviceContext_VSSetShader(sys->d3dcontext, sys->d3dvertexShader, NULL, 0);
-    ID3D11DeviceContext_PSSetShader(sys->d3dcontext, sys->d3dpixelShader, NULL, 0);
-    ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 0, 1, &sys->d3dresViewY);
+    if( sys->d3dPxShader )
+    {
+        ID3D11DeviceContext_PSSetShader(sys->d3dcontext, sys->d3dpixelShader, NULL, 0);
+        ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 0, 1, &sys->d3dresViewY);
 
-    if( sys->d3dFormatUV )
-        ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 1, 1, &sys->d3dresViewUV);
+        if( sys->d3dFormatUV )
+            ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 1, 1, &sys->d3dresViewUV);
+    }
 
     ID3D11DeviceContext_PSSetSamplers(sys->d3dcontext, 0, 1, &sys->d3dsampState);
     ID3D11DeviceContext_DrawIndexed(sys->d3dcontext, 6, 0, 0);
@@ -593,10 +596,11 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
                 ( i_formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D ))
         {
             msg_Dbg(vd, "Using pixel format %s", d3d_formats[i].name );
-            sys->d3dFormatTex = d3d_formats[i].formatTexture;
-            sys->vlcFormat    = d3d_formats[i].fourcc;
-            sys->d3dFormatY   = d3d_formats[i].formatY;
-            sys->d3dFormatUV  = d3d_formats[i].formatUV;
+            sys->d3dFormatTex   = d3d_formats[i].formatTexture;
+            sys->vlcFormat      = d3d_formats[i].fourcc;
+            sys->d3dFormatY     = d3d_formats[i].formatY;
+            sys->d3dFormatUV    = d3d_formats[i].formatUV;
+            sys->d3dPxShader    = d3d_formats[i].px_shader;
             break;
         }
     }
@@ -744,30 +748,28 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
 
     ID3D11DeviceContext_IASetInputLayout(sys->d3dcontext, pVertexLayout);
 
-    ID3DBlob* pPSBlob = NULL;
+    if( sys->d3dPxShader )
+    {
+        ID3DBlob* pPSBlob = NULL;
 
-    /* TODO : Match the version to the D3D_FEATURE_LEVEL */
-    if( sys->d3dFormatUV )
-        hr = D3DCompile(globPixelShaderBiplanarYUV2RGB, strlen(globPixelShaderBiplanarYUV2RGB),
+        /* TODO : Match the version to the D3D_FEATURE_LEVEL */
+        hr = D3DCompile(sys->d3dPxShader, strlen(sys->d3dPxShader),
                         NULL, NULL, NULL, "PS", "ps_4_0_level_9_1", 0, 0, &pPSBlob, NULL);
-    else
-        hr = D3DCompile(globPixelShaderDefault, strlen(globPixelShaderDefault),
-                        NULL, NULL, NULL, "PS", "ps_4_0_level_9_1", 0, 0, &pPSBlob, NULL);
-
 
-    if( FAILED(hr)) {
-      msg_Err(vd, "The Pixel Shader is invalid.");
-      return VLC_EGENERIC;
-    }
+        if( FAILED(hr)) {
+          msg_Err(vd, "The Pixel Shader is invalid. (hr=0x%lX)", hr );
+          return VLC_EGENERIC;
+        }
 
-    hr = ID3D11Device_CreatePixelShader(sys->d3ddevice, (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
-                                        ID3D10Blob_GetBufferSize(pPSBlob), NULL, &sys->d3dpixelShader);
+        hr = ID3D11Device_CreatePixelShader(sys->d3ddevice, (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
+                                            ID3D10Blob_GetBufferSize(pPSBlob), NULL, &sys->d3dpixelShader);
 
-    ID3D10Blob_Release(pPSBlob);
+        ID3D10Blob_Release(pPSBlob);
 
-    if(FAILED(hr)) {
-      msg_Err(vd, "Failed to create the pixel shader.");
-      return VLC_EGENERIC;
+        if(FAILED(hr)) {
+          msg_Err(vd, "Failed to create the pixel shader.");
+          return VLC_EGENERIC;
+        }
     }
 
     float vertices[] = {
@@ -844,28 +846,31 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
         return VLC_EGENERIC;
     }
 
-    D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
-    memset(&resviewDesc, 0, sizeof(resviewDesc));
-    resviewDesc.Format = sys->d3dFormatY;
-    resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
-    resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
-
-    hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewY);
-    if (FAILED(hr)) {
-        if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
-        msg_Err(vd, "Could not Create the Y D3d11 Texture ResourceView. (hr=0x%lX)", hr);
-        return VLC_EGENERIC;
-    }
-
-    if( sys->d3dFormatUV )
+    if( sys->d3dPxShader )
     {
-        resviewDesc.Format = sys->d3dFormatUV;
-        hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewUV);
+        D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
+        memset(&resviewDesc, 0, sizeof(resviewDesc));
+        resviewDesc.Format = sys->d3dFormatY;
+        resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+        resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
+
+        hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewY);
         if (FAILED(hr)) {
             if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
-            msg_Err(vd, "Could not Create the UV D3d11 Texture ResourceView. (hr=0x%lX)", hr);
+            msg_Err(vd, "Could not Create the Y D3d11 Texture ResourceView. (hr=0x%lX)", hr);
             return VLC_EGENERIC;
         }
+
+        if( sys->d3dFormatUV )
+        {
+            resviewDesc.Format = sys->d3dFormatUV;
+            hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewUV);
+            if (FAILED(hr)) {
+                if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
+                msg_Err(vd, "Could not Create the UV D3d11 Texture ResourceView. (hr=0x%lX)", hr);
+                return VLC_EGENERIC;
+            }
+        }
     }
 
     D3D11_SAMPLER_DESC sampDesc;
-- 
2.3.0




More information about the vlc-devel mailing list