[vlc-devel] [PATCH 5/7] direct3d11: group quad data and configuration in structures

Steve Lhomme robUx4 at videolabs.io
Mon May 25 13:49:49 CEST 2015


---
the same structures will be used for the SPU
---
 modules/video_output/msw/common.h     |  27 ++--
 modules/video_output/msw/direct3d11.c | 230 +++++++++++++++++++++-------------
 2 files changed, 161 insertions(+), 96 deletions(-)

diff --git a/modules/video_output/msw/common.h b/modules/video_output/msw/common.h
index 73f0925..2091124 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -51,6 +51,24 @@
  *****************************************************************************/
 #include "events.h"
 
+#ifdef MODULE_NAME_IS_direct3d11
+typedef struct
+{
+    DXGI_FORMAT   textureFormat;
+    DXGI_FORMAT   resourceFormatYRGB;
+    DXGI_FORMAT   resourceFormatUV;
+} d3d_quad_cfg_t;
+
+typedef struct
+{
+    ID3D11Buffer              *pVertexBuffer;
+    ID3D11Texture2D           *pTexture;
+    ID3D11ShaderResourceView  *d3dresViewY;
+    ID3D11ShaderResourceView  *d3dresViewUV;
+    ID3D11PixelShader         *d3dpixelShader;
+} d3d_quad_t;
+#endif
+
 /*****************************************************************************
  * vout_sys_t: video output method descriptor
  *****************************************************************************
@@ -161,16 +179,11 @@ struct vout_display_sys_t
 #endif
     ID3D11Device             *d3ddevice;       /* D3D device */
     ID3D11DeviceContext      *d3dcontext;      /* D3D context */
-    ID3D11Texture2D          *d3dtexture;
-    ID3D11ShaderResourceView *d3dresViewY;
-    ID3D11ShaderResourceView *d3dresViewUV;
+    d3d_quad_t               picQuad;
+    d3d_quad_cfg_t           picQuadConfig;
     ID3D11RenderTargetView   *d3drenderTargetView;
     ID3D11DepthStencilView   *d3ddepthStencilView;
-    ID3D11PixelShader        *d3dpixelShader;
     picture_sys_t            *picsys;
-    DXGI_FORMAT              d3dFormatTex;
-    DXGI_FORMAT              d3dFormatY;
-    DXGI_FORMAT              d3dFormatUV;
     vlc_fourcc_t             vlcFormat;
     const char               *d3dPxShader;
 #endif
diff --git a/modules/video_output/msw/direct3d11.c b/modules/video_output/msw/direct3d11.c
index d105a98..be7060e 100644
--- a/modules/video_output/msw/direct3d11.c
+++ b/modules/video_output/msw/direct3d11.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2014-2015 VLC authors and VideoLAN
  *
  * Authors: Martell Malone <martellmalone at gmail.com>
+ *          Steve Lhomme <robux4 at gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -31,6 +32,7 @@
 #define COBJMACROS
 #define INITGUID
 #include <d3d11.h>
+#include <d3dx9math.h>
 
 /* avoided until we can pass ISwapchainPanel without c++/cx mode
 # include <windows.ui.xaml.media.dxinterop.h> */
@@ -107,6 +109,12 @@ struct picture_sys_t
     vout_display_t      *vd;
 };
 
+/* matches the D3D11_INPUT_ELEMENT_DESC we setup */
+typedef struct d3d_vertex_t {
+    D3DXVECTOR3 position;
+    D3DXVECTOR2 texture;
+} d3d_vertex_t;
+
 static int  Open(vlc_object_t *);
 static void Close(vlc_object_t *object);
 
@@ -124,6 +132,11 @@ static void Direct3D11DestroyResources(vout_display_t *);
 
 static int  Direct3D11MapTexture(picture_t *);
 
+static int AllocQuad(vout_display_t *, const video_format_t *, d3d_quad_t *,
+                     d3d_quad_cfg_t *, ID3D11PixelShader *,
+                     const float vertices[4 * sizeof(d3d_vertex_t)]);
+static void ReleaseQuad(d3d_quad_t *);
+
 /* All the #if USE_DXGI contain an alternative method to setup dx11
    They both need to be benchmarked to see which performs better */
 #if USE_DXGI
@@ -465,14 +478,21 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
     /* float ClearColor[4] = { 1.0f, 0.125f, 0.3f, 1.0f }; */
     /* ID3D11DeviceContext_ClearRenderTargetView(sys->d3dcontext,sys->d3drenderTargetView, ClearColor); */
     ID3D11DeviceContext_ClearDepthStencilView(sys->d3dcontext,sys->d3ddepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
+}
+
+static void DisplayD3DPicture(vout_display_sys_t *sys, d3d_quad_t *quad)
+{
+    UINT stride = sizeof(d3d_vertex_t);
+    UINT offset = 0;
 
     /* Render the quad */
-    ID3D11DeviceContext_PSSetShader(sys->d3dcontext, sys->d3dpixelShader, NULL, 0);
-    ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 0, 1, &sys->d3dresViewY);
+    ID3D11DeviceContext_PSSetShader(sys->d3dcontext, quad->d3dpixelShader, NULL, 0);
+    ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 0, 1, &quad->d3dresViewY);
 
-    if( sys->d3dFormatUV )
-        ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 1, 1, &sys->d3dresViewUV);
+    if( quad->d3dresViewUV )
+        ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 1, 1, &quad->d3dresViewUV);
 
+    ID3D11DeviceContext_IASetVertexBuffers(sys->d3dcontext, 0, 1, &quad->pVertexBuffer, &stride, &offset);
     ID3D11DeviceContext_DrawIndexed(sys->d3dcontext, 6, 0, 0);
 }
 
@@ -480,6 +500,11 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
 {
     vout_display_sys_t *sys = vd->sys;
 
+    /* no ID3D11Device operations should come here */
+
+    /* Render the quad */
+    DisplayD3DPicture(sys, &sys->picQuad);
+
     IDXGISwapChain_Present(sys->dxgiswapChain, 0, 0);
 
     picture_Release(picture);
@@ -706,21 +731,22 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
         i_src_chroma = fmt->i_chroma;
 
     // look for the request pixel format first
+    UINT i_quadSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_LOAD;
+    UINT i_formatSupport;
     for (unsigned i = 0; d3d_formats[i].name != 0; i++)
     {
         if( i_src_chroma == d3d_formats[i].fourcc)
         {
-            UINT i_formatSupport;
             if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
                                                            d3d_formats[i].formatTexture,
                                                            &i_formatSupport)) &&
-                    ( i_formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D ))
+                    ( i_formatSupport & i_quadSupportFlags ))
             {
                 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->vlcFormat = d3d_formats[i].fourcc;
+                sys->picQuadConfig.textureFormat      = d3d_formats[i].formatTexture;
+                sys->picQuadConfig.resourceFormatYRGB = d3d_formats[i].formatY;
+                sys->picQuadConfig.resourceFormatUV   = d3d_formats[i].formatUV;
                 break;
             }
         }
@@ -731,17 +757,16 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
     {
         for (unsigned i = 0; d3d_formats[i].name != 0; i++)
         {
-            UINT i_formatSupport;
             if( SUCCEEDED( ID3D11Device_CheckFormatSupport(sys->d3ddevice,
                                                            d3d_formats[i].formatTexture,
                                                            &i_formatSupport)) &&
-                    ( i_formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D ))
+                    ( i_formatSupport & i_quadSupportFlags ))
             {
                 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->vlcFormat = d3d_formats[i].fourcc;
+                sys->picQuadConfig.textureFormat      = d3d_formats[i].formatTexture;
+                sys->picQuadConfig.resourceFormatYRGB = d3d_formats[i].formatY;
+                sys->picQuadConfig.resourceFormatUV   = d3d_formats[i].formatUV;
                 break;
             }
         }
@@ -960,8 +985,9 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
       return VLC_EGENERIC;
     }
 
+    ID3D11PixelShader *pPicQuadShader;
     hr = ID3D11Device_CreatePixelShader(sys->d3ddevice, (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
-                                        ID3D10Blob_GetBufferSize(pPSBlob), NULL, &sys->d3dpixelShader);
+                                        ID3D10Blob_GetBufferSize(pPSBlob), NULL, &pPicQuadShader);
 
     ID3D10Blob_Release(pPSBlob);
 
@@ -970,81 +996,19 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
       return VLC_EGENERIC;
     }
 
-    float vertices[] = {
+    float vertices[4 * sizeof(d3d_vertex_t)] = {
     -1.0f, -1.0f, -1.0f, 0.0f, 1.0f,
      1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
      1.0f,  1.0f, -1.0f, 1.0f, 0.0f,
     -1.0f,  1.0f, -1.0f, 0.0f, 0.0f,
     };
 
-    D3D11_BUFFER_DESC bd;
-    memset(&bd, 0, sizeof(bd));
-    bd.Usage = D3D11_USAGE_DEFAULT;
-    bd.ByteWidth = sizeof(float) * 5 * 4;
-    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
-    bd.CPUAccessFlags = 0;
-
-    D3D11_SUBRESOURCE_DATA InitData;
-    memset(&InitData, 0, sizeof(InitData));
-    InitData.pSysMem = vertices;
-
-    ID3D11Buffer* pVertexBuffer = NULL;
-    hr = ID3D11Device_CreateBuffer(sys->d3ddevice, &bd, &InitData, &pVertexBuffer);
-
-    if(FAILED(hr)) {
-      msg_Err(vd, "Failed to create vertex buffer.");
-      return VLC_EGENERIC;
-    }
-
-    UINT stride = sizeof(float) * 5;
-    UINT offset = 0;
-    ID3D11DeviceContext_IASetVertexBuffers(sys->d3dcontext, 0, 1, &pVertexBuffer, &stride, &offset);
-
-    ID3D11Buffer_Release(pVertexBuffer);
-
-    ID3D11Buffer_Release(pVertexBuffer);
-
-    D3D11_TEXTURE2D_DESC texDesc;
-    memset(&texDesc, 0, sizeof(texDesc));
-    texDesc.Width = fmt->i_visible_width;
-    texDesc.Height = fmt->i_visible_height;
-    texDesc.MipLevels = texDesc.ArraySize = 1;
-    texDesc.Format = sys->d3dFormatTex;
-    texDesc.SampleDesc.Count = 1;
-    texDesc.Usage = D3D11_USAGE_DYNAMIC;
-    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
-    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-    texDesc.MiscFlags = 0;
-
-    hr = ID3D11Device_CreateTexture2D(sys->d3ddevice, &texDesc, NULL, &sys->d3dtexture);
-    if (FAILED(hr)) {
-        msg_Err(vd, "Could not Create the D3d11 Texture. (hr=0x%lX)", hr);
+    if (AllocQuad( vd, fmt, &sys->picQuad, &sys->picQuadConfig, pPicQuadShader, vertices )!=VLC_SUCCESS) {
+        ID3D11PixelShader_Release(pPicQuadShader);
+        msg_Err(vd, "Could not Create the main quad picture. (hr=0x%lX)", hr);
         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 )
-    {
-        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;
-        }
-    }
+    ID3D11PixelShader_Release(pPicQuadShader);
 
     D3D11_SAMPLER_DESC sampDesc;
     memset(&sampDesc, 0, sizeof(sampDesc));
@@ -1060,7 +1024,6 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
     hr = ID3D11Device_CreateSamplerState(sys->d3ddevice, &sampDesc, &d3dsampState);
 
     if (FAILED(hr)) {
-      if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
       msg_Err(vd, "Could not Create the D3d11 Sampler State. (hr=0x%lX)", hr);
       return VLC_EGENERIC;
     }
@@ -1069,11 +1032,10 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
 
     picture_sys_t *picsys = malloc(sizeof(*picsys));
     if (unlikely(picsys == NULL)) {
-        if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
         return VLC_ENOMEM;
     }
 
-    picsys->texture  = sys->d3dtexture;
+    picsys->texture  = sys->picQuad.pTexture;
     picsys->context  = sys->d3dcontext;
     picsys->vd       = vd;
 
@@ -1083,10 +1045,10 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
 
     picture_t *picture = picture_NewFromResource(fmt, &resource);
     if (!picture) {
-        if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
         free(picsys);
         return VLC_ENOMEM;
     }
+    ID3D11Texture2D_AddRef(picsys->texture);
     ID3D11DeviceContext_AddRef(picsys->context);
     sys->picsys = picsys;
 
@@ -1099,7 +1061,6 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
     sys->pool = picture_pool_NewExtended(&pool_cfg);
     if (!sys->pool) {
         picture_Release(picture);
-        if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
         return VLC_ENOMEM;
     }
 
@@ -1107,6 +1068,94 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
     return VLC_SUCCESS;
 }
 
+static int AllocQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *quad,
+                     d3d_quad_cfg_t *cfg, ID3D11PixelShader *d3dpixelShader,
+                     const float vertices[4 * sizeof(d3d_vertex_t)])
+{
+    vout_display_sys_t *sys = vd->sys;
+    HRESULT hr;
+
+    D3D11_BUFFER_DESC bd;
+    memset(&bd, 0, sizeof(bd));
+    bd.Usage = vertices==NULL ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
+    bd.ByteWidth = sizeof(d3d_vertex_t) * 4;
+    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+    bd.CPUAccessFlags = vertices==NULL ? D3D11_CPU_ACCESS_WRITE : 0;
+
+    D3D11_SUBRESOURCE_DATA InitData = {
+        .pSysMem = vertices,
+    };
+
+    hr = ID3D11Device_CreateBuffer(sys->d3ddevice, &bd, vertices==NULL ? NULL : &InitData, &quad->pVertexBuffer);
+    if(FAILED(hr)) {
+      msg_Err(vd, "Failed to create vertex buffer.");
+      goto error;
+    }
+
+    D3D11_TEXTURE2D_DESC texDesc;
+    memset(&texDesc, 0, sizeof(texDesc));
+    texDesc.Width = fmt->i_visible_width;
+    texDesc.Height = fmt->i_visible_height;
+    texDesc.MipLevels = texDesc.ArraySize = 1;
+    texDesc.Format = cfg->textureFormat;
+    texDesc.SampleDesc.Count = 1;
+    texDesc.Usage = D3D11_USAGE_DYNAMIC;
+    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+    texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    texDesc.MiscFlags = 0;
+
+    hr = ID3D11Device_CreateTexture2D(sys->d3ddevice, &texDesc, NULL, &quad->pTexture);
+    if (FAILED(hr)) {
+        msg_Err(vd, "Could not Create the D3d11 Texture. (hr=0x%lX)", hr);
+        goto error;
+    }
+
+    D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
+    memset(&resviewDesc, 0, sizeof(resviewDesc));
+    resviewDesc.Format = cfg->resourceFormatYRGB;
+    resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+    resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
+
+    hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)quad->pTexture, &resviewDesc, &quad->d3dresViewY);
+    if (FAILED(hr)) {
+        msg_Err(vd, "Could not Create the Y/RGB D3d11 Texture ResourceView. (hr=0x%lX)", hr);
+        goto error;
+    }
+
+    if( cfg->resourceFormatUV )
+    {
+        resviewDesc.Format = cfg->resourceFormatUV;
+        hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)quad->pTexture, &resviewDesc, &quad->d3dresViewUV);
+        if (FAILED(hr)) {
+            msg_Err(vd, "Could not Create the UV D3d11 Texture ResourceView. (hr=0x%lX)", hr);
+            goto error;
+        }
+    }
+
+    quad->d3dpixelShader = d3dpixelShader;
+    ID3D11PixelShader_AddRef(quad->d3dpixelShader);
+
+    return VLC_SUCCESS;
+
+error:
+    ReleaseQuad(quad);
+    return VLC_EGENERIC;
+}
+
+static void ReleaseQuad(d3d_quad_t *quad)
+{
+    if (quad->pVertexBuffer)
+        ID3D11Buffer_Release(quad->pVertexBuffer);
+    if (quad->pTexture)
+        ID3D11Texture2D_Release(quad->pTexture);
+    if (quad->d3dresViewY)
+        ID3D11ShaderResourceView_Release(quad->d3dresViewY);
+    if (quad->d3dresViewUV)
+        ID3D11ShaderResourceView_Release(quad->d3dresViewUV);
+    if (quad->d3dpixelShader)
+        ID3D11VertexShader_Release(quad->d3dpixelShader);
+}
+
 static void Direct3D11DestroyResources(vout_display_t *vd)
 {
     vout_display_sys_t *sys = vd->sys;
@@ -1119,6 +1168,9 @@ static void Direct3D11DestroyResources(vout_display_t *vd)
         picture_pool_Release(sys->pool);
     }
     sys->pool = NULL;
+
+    ReleaseQuad(&sys->picQuad);
+
     if (sys->d3drenderTargetView)
         ID3D11RenderTargetView_Release(sys->d3drenderTargetView);
     if (sys->d3ddepthStencilView)
-- 
2.4.0




More information about the vlc-devel mailing list