[vlc-devel] [PATCH 6/7] direct3d11: fix picture quality when resizing

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


---
every time the window is resized we need to update the backbuffer to match
the window area so that the GPU (samler) resizing is triggered
---
 modules/video_output/msw/direct3d11.c | 170 ++++++++++++++++++++++------------
 1 file changed, 113 insertions(+), 57 deletions(-)

diff --git a/modules/video_output/msw/direct3d11.c b/modules/video_output/msw/direct3d11.c
index be7060e..9562d8d 100644
--- a/modules/video_output/msw/direct3d11.c
+++ b/modules/video_output/msw/direct3d11.c
@@ -115,6 +115,9 @@ typedef struct d3d_vertex_t {
     D3DXVECTOR2 texture;
 } d3d_vertex_t;
 
+#define RECTWidth(r)   (int)(r.right - r.left)
+#define RECTHeight(r)  (int)(r.bottom - r.top)
+
 static int  Open(vlc_object_t *);
 static void Close(vlc_object_t *object);
 
@@ -137,6 +140,8 @@ static int AllocQuad(vout_display_t *, const video_format_t *, d3d_quad_t *,
                      const float vertices[4 * sizeof(d3d_vertex_t)]);
 static void ReleaseQuad(d3d_quad_t *);
 
+static void Manage(vout_display_t *vd);
+
 /* 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
@@ -446,7 +451,7 @@ static int Open(vlc_object_t *object)
     vd->prepare = Prepare;
     vd->display = Display;
     vd->control = CommonControl;
-    vd->manage  = CommonManage;
+    vd->manage  = Manage;
 
     msg_Dbg(vd, "Direct3D11 Open Succeeded");
 
@@ -469,6 +474,106 @@ static void Close(vlc_object_t *object)
     free(vd->sys);
 }
 
+static HRESULT UpdateBackBuffer(vout_display_t *vd)
+{
+    vout_display_sys_t *sys = vd->sys;
+    HRESULT hr;
+    ID3D11Texture2D* pDepthStencil;
+    ID3D11Texture2D* pBackBuffer;
+
+    if (sys->d3drenderTargetView) {
+        ID3D11RenderTargetView_Release(sys->d3drenderTargetView);
+        sys->d3drenderTargetView = NULL;
+    }
+    if (sys->d3ddepthStencilView) {
+        ID3D11DepthStencilView_Release(sys->d3ddepthStencilView);
+        sys->d3ddepthStencilView = NULL;
+    }
+
+    hr = IDXGISwapChain_ResizeBuffers(sys->dxgiswapChain, 1, RECTWidth(sys->rect_dest_clipped),
+                                 RECTHeight(sys->rect_dest_clipped),
+                                 DXGI_FORMAT_R8G8B8A8_UNORM, 0);
+    if (FAILED(hr)) {
+       msg_Err(vd, "Failed to resize the backbuffer. (hr=0x%lX)", hr);
+       return hr;
+    }
+
+    hr = IDXGISwapChain_GetBuffer(sys->dxgiswapChain, 0, &IID_ID3D11Texture2D, (LPVOID *)&pBackBuffer);
+    if (FAILED(hr)) {
+       msg_Err(vd, "Could not get the backbuffer for the Swapchain. (hr=0x%lX)", hr);
+       return hr;
+    }
+
+    hr = ID3D11Device_CreateRenderTargetView(sys->d3ddevice, (ID3D11Resource *)pBackBuffer, NULL, &sys->d3drenderTargetView);
+    ID3D11Texture2D_Release(pBackBuffer);
+
+    D3D11_TEXTURE2D_DESC deptTexDesc;
+    memset(&deptTexDesc, 0,sizeof(deptTexDesc));
+    deptTexDesc.ArraySize = 1;
+    deptTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+    deptTexDesc.CPUAccessFlags = 0;
+    deptTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+    deptTexDesc.Width = RECTWidth(sys->rect_dest_clipped);
+    deptTexDesc.Height = RECTHeight(sys->rect_dest_clipped);
+    deptTexDesc.MipLevels = 1;
+    deptTexDesc.MiscFlags = 0;
+    deptTexDesc.SampleDesc.Count = 1;
+    deptTexDesc.SampleDesc.Quality = 0;
+    deptTexDesc.Usage = D3D11_USAGE_DEFAULT;
+
+    hr = ID3D11Device_CreateTexture2D(sys->d3ddevice, &deptTexDesc, NULL, &pDepthStencil);
+    if (FAILED(hr)) {
+       msg_Err(vd, "Could not create the depth stencil texture. (hr=0x%lX)", hr);
+       return hr;
+    }
+
+    D3D11_DEPTH_STENCIL_VIEW_DESC depthViewDesc;
+    memset(&depthViewDesc, 0, sizeof(depthViewDesc));
+
+    depthViewDesc.Format = deptTexDesc.Format;
+    depthViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+    depthViewDesc.Texture2D.MipSlice = 0;
+
+    hr = ID3D11Device_CreateDepthStencilView(sys->d3ddevice, (ID3D11Resource *)pDepthStencil, &depthViewDesc, &sys->d3ddepthStencilView);
+    ID3D11Texture2D_Release(pDepthStencil);
+
+    if (FAILED(hr)) {
+       msg_Err(vd, "Could not create the depth stencil view. (hr=0x%lX)", hr);
+       return hr;
+    }
+
+    ID3D11DeviceContext_OMSetRenderTargets(sys->d3dcontext, 1, &sys->d3drenderTargetView, sys->d3ddepthStencilView);
+
+    D3D11_VIEWPORT vp;
+    vp.Width = (FLOAT)RECTWidth(sys->rect_dest_clipped);
+    vp.Height = (FLOAT)RECTHeight(sys->rect_dest_clipped);
+    vp.MinDepth = 0.0f;
+    vp.MaxDepth = 1.0f;
+    vp.TopLeftX = 0;
+    vp.TopLeftY = 0;
+
+    ID3D11DeviceContext_RSSetViewports(sys->d3dcontext, 1, &vp);
+
+    return S_OK;
+}
+
+static void Manage(vout_display_t *vd)
+{
+    vout_display_sys_t *sys = vd->sys;
+    RECT size_before = sys->rect_dest_clipped;
+
+    CommonManage(vd);
+
+    if (RECTWidth(size_before)  != RECTWidth(sys->rect_dest_clipped) ||
+        RECTHeight(size_before) != RECTHeight(sys->rect_dest_clipped))
+    {
+        msg_Dbg(vd, "Manage detected size change %dx%d", RECTWidth(sys->rect_dest_clipped),
+                RECTHeight(sys->rect_dest_clipped));
+
+        UpdateBackBuffer(vd);
+    }
+}
+
 static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
 {
     vout_display_sys_t *sys = vd->sys;
@@ -833,65 +938,16 @@ static void Direct3D11Close(vout_display_t *vd)
 static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
 {
     vout_display_sys_t *sys = vd->sys;
-    ID3D11Texture2D* pBackBuffer = NULL;
-    ID3D11Texture2D* pDepthStencil= NULL;
     HRESULT hr;
 
     fmt->i_chroma = sys->vlcFormat;
 
-    hr = IDXGISwapChain_GetBuffer(sys->dxgiswapChain, 0, &IID_ID3D11Texture2D, (LPVOID *)&pBackBuffer);
-    if (FAILED(hr)) {
-       msg_Err(vd, "Could not get the backbuffer from the Swapchain. (hr=0x%lX)", hr);
-       return VLC_EGENERIC;
-    }
-
-    hr = ID3D11Device_CreateRenderTargetView(sys->d3ddevice, (ID3D11Resource *)pBackBuffer, NULL, &sys->d3drenderTargetView);
-
-    ID3D11Texture2D_Release(pBackBuffer);
-
+    hr = UpdateBackBuffer(vd);
     if (FAILED(hr)) {
-       msg_Err(vd, "Could not create the render view target. (hr=0x%lX)", hr);
+       msg_Err(vd, "Could not update the backbuffer. (hr=0x%lX)", hr);
        return VLC_EGENERIC;
     }
 
-    D3D11_TEXTURE2D_DESC deptTexDesc;
-    memset(&deptTexDesc, 0,sizeof(deptTexDesc));
-    deptTexDesc.ArraySize = 1;
-    deptTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
-    deptTexDesc.CPUAccessFlags = 0;
-    deptTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
-    deptTexDesc.Width = fmt->i_visible_width;
-    deptTexDesc.Height = fmt->i_visible_height;
-    deptTexDesc.MipLevels = 1;
-    deptTexDesc.MiscFlags = 0;
-    deptTexDesc.SampleDesc.Count = 1;
-    deptTexDesc.SampleDesc.Quality = 0;
-    deptTexDesc.Usage = D3D11_USAGE_DEFAULT;
-
-    hr = ID3D11Device_CreateTexture2D(sys->d3ddevice, &deptTexDesc, NULL, &pDepthStencil);
-
-    if (FAILED(hr)) {
-       msg_Err(vd, "Could not create the depth stencil texture. (hr=0x%lX)", hr);
-       return VLC_EGENERIC;
-    }
-
-    D3D11_DEPTH_STENCIL_VIEW_DESC depthViewDesc;
-    memset(&depthViewDesc, 0, sizeof(depthViewDesc));
-
-    depthViewDesc.Format = deptTexDesc.Format;
-    depthViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
-    depthViewDesc.Texture2D.MipSlice = 0;
-
-    hr = ID3D11Device_CreateDepthStencilView(sys->d3ddevice, (ID3D11Resource *)pDepthStencil, &depthViewDesc, &sys->d3ddepthStencilView);
-
-    ID3D11Texture2D_Release(pDepthStencil);
-
-    if (FAILED(hr)) {
-       msg_Err(vd, "Could not create the depth stencil view. (hr=0x%lX)", hr);
-       return VLC_EGENERIC;
-    }
-
-    ID3D11DeviceContext_OMSetRenderTargets(sys->d3dcontext, 1, &sys->d3drenderTargetView, sys->d3ddepthStencilView);
 
     D3D11_VIEWPORT vp;
     vp.Width = (FLOAT)fmt->i_visible_width;
@@ -1012,11 +1068,11 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
 
     D3D11_SAMPLER_DESC sampDesc;
     memset(&sampDesc, 0, sizeof(sampDesc));
-    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
-    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
-    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
-    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
-    sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+    sampDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
+    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
+    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
+    sampDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
     sampDesc.MinLOD = 0;
     sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
 
-- 
2.4.0




More information about the vlc-devel mailing list