[vlc-devel] [PATCH 7/7] direct3d11: add 3d playback
Steve Lhomme
robux4 at ycbcr.xyz
Thu Aug 16 11:00:49 CEST 2018
From: "Mohammed (Shaan) Huzaifa Danish" <shaan3 at gmail.com>
This adds code for core stereo 3d files playback
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
---
modules/video_output/win32/d3d11_quad.c | 216 ++++++++++++-----
modules/video_output/win32/d3d11_quad.h | 12 +-
modules/video_output/win32/d3d11_shaders.c | 84 ++++---
modules/video_output/win32/d3d11_shaders.h | 16 +-
modules/video_output/win32/direct3d11.c | 267 +++++++++++++++++++--
5 files changed, 474 insertions(+), 121 deletions(-)
diff --git a/modules/video_output/win32/d3d11_quad.c b/modules/video_output/win32/d3d11_quad.c
index 3bb60d3e35..fd3a25f495 100644
--- a/modules/video_output/win32/d3d11_quad.c
+++ b/modules/video_output/win32/d3d11_quad.c
@@ -43,7 +43,8 @@
void D3D11_RenderQuad(d3d11_device_t *d3d_dev, d3d_quad_t *quad, d3d_vshader_t *vsshader,
ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW],
- ID3D11RenderTargetView *d3drenderTargetView[D3D11_MAX_SHADER_VIEW])
+ ID3D11RenderTargetView *d3drenderTargetView[D3D11_MAX_SHADER_VIEW][2],
+ size_t eyeIndex, size_t targetEye)
{
UINT offset = 0;
@@ -74,9 +75,9 @@ void D3D11_RenderQuad(d3d11_device_t *d3d_dev, d3d_quad_t *quad, d3d_vshader_t *
ID3D11DeviceContext_PSSetShader(d3d_dev->d3dcontext, quad->d3dpixelShader[i], NULL, 0);
- ID3D11DeviceContext_RSSetViewports(d3d_dev->d3dcontext, 1, &quad->cropViewport[i]);
+ ID3D11DeviceContext_RSSetViewports(d3d_dev->d3dcontext, 1, &quad->cropViewport[i][eyeIndex]);
- ID3D11DeviceContext_OMSetRenderTargets(d3d_dev->d3dcontext, 1, &d3drenderTargetView[i], NULL);
+ ID3D11DeviceContext_OMSetRenderTargets(d3d_dev->d3dcontext, 1, &d3drenderTargetView[i][targetEye], NULL);
ID3D11DeviceContext_DrawIndexed(d3d_dev->d3dcontext, quad->indexCount, 0, 0);
}
@@ -114,6 +115,9 @@ static bool AllocQuadVertices(vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ quad->pVertexBuffer = NULL;
+ quad->pIndexBuffer = NULL;
+
hr = ID3D11Device_CreateBuffer(d3d_dev->d3ddevice, &bd, NULL, &quad->pVertexBuffer);
if(FAILED(hr)) {
msg_Err(o, "Failed to create vertex buffer. (hr=%lX)", hr);
@@ -133,7 +137,6 @@ static bool AllocQuadVertices(vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad
msg_Err(o, "Could not create the quad indices. (hr=0x%lX)", hr);
goto fail;
}
-
return true;
fail:
if (quad->pVertexBuffer)
@@ -166,7 +169,7 @@ void D3D11_ReleaseQuad(d3d_quad_t *quad)
ID3D11Buffer_Release(quad->pVertexBuffer);
quad->pVertexBuffer = NULL;
}
- if (quad->pIndexBuffer)
+ if (quad->pVertexBuffer)
{
ID3D11Buffer_Release(quad->pIndexBuffer);
quad->pIndexBuffer = NULL;
@@ -590,12 +593,12 @@ bool D3D11_UpdateQuadPosition( vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_qua
break;
default:
msg_Warn(o, "Projection mode %d not handled", quad->projection);
+ ID3D11DeviceContext_Unmap(d3d_dev->d3dcontext, (ID3D11Resource *)quad->pIndexBuffer, 0);
+ ID3D11DeviceContext_Unmap(d3d_dev->d3dcontext, (ID3D11Resource *)quad->pVertexBuffer, 0);
result = false;
}
-
ID3D11DeviceContext_Unmap(d3d_dev->d3dcontext, (ID3D11Resource *)quad->pIndexBuffer, 0);
ID3D11DeviceContext_Unmap(d3d_dev->d3dcontext, (ID3D11Resource *)quad->pVertexBuffer, 0);
-
return result;
}
@@ -692,7 +695,7 @@ error:
#undef D3D11_SetupQuad
int D3D11_SetupQuad(vlc_object_t *o, d3d11_device_t *d3d_dev, const video_format_t *fmt, d3d_quad_t *quad,
const display_info_t *displayFormat, const RECT *output,
- video_orientation_t orientation)
+ video_orientation_t orientation, video_multiview_mode_t src_mode)
{
const bool RGB_shader = IsRGBShader(quad->textureFormat);
@@ -829,6 +832,7 @@ int D3D11_SetupQuad(vlc_object_t *o, d3d11_device_t *d3d_dev, const video_format
ShaderUpdateConstants(o, d3d_dev, quad, PS_CONST_COLORSPACE, &colorspace);
+ quad->src_stereo = src_mode;
quad->picSys.formatTexture = quad->textureFormat->formatTexture;
quad->picSys.context = d3d_dev->d3dcontext;
@@ -839,78 +843,172 @@ int D3D11_SetupQuad(vlc_object_t *o, d3d11_device_t *d3d_dev, const video_format
for (size_t i=0; i<D3D11_MAX_SHADER_VIEW; i++)
{
- quad->cropViewport[i].MinDepth = 0.0f;
- quad->cropViewport[i].MaxDepth = 1.0f;
+ for (size_t eye=0; eye < 2;eye++)
+ {
+ quad->cropViewport[i][eye].MinDepth = 0.0f;
+ quad->cropViewport[i][eye].MaxDepth = 1.0f;
+ }
}
quad->resourceCount = DxgiResourceCount(quad->textureFormat);
return VLC_SUCCESS;
}
-void D3D11_UpdateViewport(d3d_quad_t *quad, const RECT *rect, const d3d_format_t *display)
+void D3D11_UpdateViewport(d3d_quad_t *quad, const RECT *rect,
+ const d3d_format_t *display, vlc_stereoscopic_mode_t display_mode)
{
#define RECTWidth(r) (LONG)((r)->right - (r)->left)
#define RECTHeight(r) (LONG)((r)->bottom - (r)->top)
LONG srcAreaWidth, srcAreaHeight;
+ LONG rightEyeTop;
+
+ switch (quad->src_stereo)
+ {
+ case MULTIVIEW_STEREO_SBS:
+ srcAreaWidth = RECTWidth(rect) * 2;
+ srcAreaHeight = RECTHeight(rect);
+ rightEyeTop = rect->top;
+ break;
- srcAreaWidth = RECTWidth(rect);
- srcAreaHeight = RECTHeight(rect);
+ case MULTIVIEW_STEREO_TB:
+ srcAreaWidth = RECTWidth(rect);
+ srcAreaHeight = RECTHeight(rect) * 2;
+ rightEyeTop = rect->top - RECTHeight(rect);
+ break;
+
+ default:
+ srcAreaWidth = RECTWidth(rect);
+ srcAreaHeight = RECTHeight(rect);
+ rightEyeTop = rect->top;
+ break;
+ }
#undef RECTWidth
#undef RECTHeight
- quad->cropViewport[0].TopLeftX = rect->left;
- quad->cropViewport[0].TopLeftY = rect->top;
- quad->cropViewport[0].Width = srcAreaWidth;
- quad->cropViewport[0].Height = srcAreaHeight;
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX = rect->left;
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY = rect->top;
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].Width = srcAreaWidth;
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].Height = srcAreaHeight;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftY = rightEyeTop;
- switch ( quad->textureFormat->formatTexture )
+ //Default 2D mode selection
+ if (display_mode != VIDEO_STEREO_OUTPUT_STEREO)
{
- case DXGI_FORMAT_NV12:
- case DXGI_FORMAT_P010:
- quad->cropViewport[1].TopLeftX = rect->left / 2;
- quad->cropViewport[1].TopLeftY = rect->top / 2;
- quad->cropViewport[1].Width = srcAreaWidth / 2;
- quad->cropViewport[1].Height = srcAreaHeight / 2;
- break;
- case DXGI_FORMAT_R8G8B8A8_UNORM:
- case DXGI_FORMAT_B8G8R8A8_UNORM:
- case DXGI_FORMAT_B8G8R8X8_UNORM:
- case DXGI_FORMAT_B5G6R5_UNORM:
- case DXGI_FORMAT_R10G10B10A2_UNORM:
- case DXGI_FORMAT_R16G16B16A16_UNORM:
- case DXGI_FORMAT_YUY2:
- case DXGI_FORMAT_AYUV:
- if ( display->formatTexture == DXGI_FORMAT_NV12 ||
- display->formatTexture == DXGI_FORMAT_P010 )
+ switch ( quad->textureFormat->formatTexture )
{
- quad->cropViewport[1].TopLeftX = rect->left / 2;
- quad->cropViewport[1].TopLeftY = rect->top / 2;
- quad->cropViewport[1].Width = srcAreaWidth / 2;
- quad->cropViewport[1].Height = srcAreaHeight / 2;
- }
- break;
- case DXGI_FORMAT_UNKNOWN:
- switch ( quad->textureFormat->fourcc )
- {
- case VLC_CODEC_YUVA:
- if ( display->formatTexture != DXGI_FORMAT_NV12 &&
- display->formatTexture != DXGI_FORMAT_P010 )
+ case DXGI_FORMAT_NV12:
+ case DXGI_FORMAT_P010:
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].TopLeftX = rect->left / 2;
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].TopLeftY = rect->top / 2;
+ break;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_YUY2:
+ case DXGI_FORMAT_AYUV:
+ if ( display->formatTexture == DXGI_FORMAT_NV12 ||
+ display->formatTexture == DXGI_FORMAT_P010 )
{
- quad->cropViewport[1] = quad->cropViewport[2] =
- quad->cropViewport[3] = quad->cropViewport[0];
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].TopLeftX = rect->left / 2;
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].TopLeftY = rect->top / 2;
+ }
+ break;
+ case DXGI_FORMAT_UNKNOWN:
+ switch ( quad->textureFormat->fourcc )
+ {
+ case VLC_CODEC_YUVA:
+ if ( display->formatTexture != DXGI_FORMAT_NV12 &&
+ display->formatTexture != DXGI_FORMAT_P010 )
+ {
+ quad->cropViewport[1][MONO_OR_LEFT_EYE] = quad->cropViewport[2][MONO_OR_LEFT_EYE] =
+ quad->cropViewport[3][MONO_OR_LEFT_EYE] = quad->cropViewport[0][MONO_OR_LEFT_EYE];
+ break;
+ }
+ /* fallthrough */
+ case VLC_CODEC_I420:
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].TopLeftX = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX / 2;
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].TopLeftY = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY / 2;
+ quad->cropViewport[2][MONO_OR_LEFT_EYE] = quad->cropViewport[1][MONO_OR_LEFT_EYE];
break;
}
- /* fallthrough */
- case VLC_CODEC_I420:
- quad->cropViewport[1].TopLeftX = quad->cropViewport[0].TopLeftX / 2;
- quad->cropViewport[1].TopLeftY = quad->cropViewport[0].TopLeftY / 2;
- quad->cropViewport[1].Width = quad->cropViewport[0].Width / 2;
- quad->cropViewport[1].Height = quad->cropViewport[0].Height / 2;
- quad->cropViewport[2] = quad->cropViewport[1];
break;
+ default:
+ vlc_assert_unreachable();
+ }
+
+ if (display_mode == VIDEO_STEREO_OUTPUT_RIGHT_ONLY)
+ {
+ /* the right eye will be shown on the "left"(mono) eye */
+ if (quad->src_stereo != MULTIVIEW_2D)
+ {
+ if (quad->src_stereo == MULTIVIEW_STEREO_TB)
+ {
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY -= srcAreaHeight / 2;
+ }
+ else if (quad->src_stereo == MULTIVIEW_STEREO_SBS)
+ {
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX -= srcAreaWidth / 2;
+ }
+ }
+ }
+ else if (display_mode == VIDEO_STEREO_OUTPUT_SIDE_BY_SIDE)
+ {
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX /= 2;
+ quad->cropViewport[0][MONO_OR_LEFT_EYE].Width /= 2;
+ quad->cropViewport[0][RIGHT_EYE].Height = quad->cropViewport[0][MONO_OR_LEFT_EYE].Height;
+
+ if (quad->src_stereo == MULTIVIEW_2D)
+ {
+ quad->cropViewport[0][RIGHT_EYE].Width = quad->cropViewport[0][MONO_OR_LEFT_EYE].Width;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftY = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX + srcAreaWidth / 2;
+ }
+ else if (quad->src_stereo == MULTIVIEW_STEREO_SBS)
+ {
+ quad->cropViewport[0][RIGHT_EYE].Width = quad->cropViewport[0][MONO_OR_LEFT_EYE].Width / 2;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftY = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX + srcAreaWidth / 2;
+ }
+ else if (quad->src_stereo == MULTIVIEW_STEREO_TB)
+ {
+ quad->cropViewport[0][RIGHT_EYE].Width = quad->cropViewport[0][MONO_OR_LEFT_EYE].Width;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = srcAreaWidth / 2;
+ }
+ else if (quad->src_stereo == MULTIVIEW_STEREO_FRAME)
+ {
+ quad->cropViewport[0][RIGHT_EYE].Width = quad->cropViewport[0][MONO_OR_LEFT_EYE].Width;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftY = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX + srcAreaWidth / 2;
+ }
+ }
+
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].Width = quad->cropViewport[0][MONO_OR_LEFT_EYE].Width / 2;
+ quad->cropViewport[1][MONO_OR_LEFT_EYE].Height = quad->cropViewport[0][MONO_OR_LEFT_EYE].Height / 2;
+ }
+ else { /* VIDEO_STEREO_OUTPUT_STEREO */
+ quad->cropViewport[0][RIGHT_EYE].Width = srcAreaWidth;
+ quad->cropViewport[0][RIGHT_EYE].Height = srcAreaHeight;
+
+ //For stereoscopic side by side left-right format
+ if (quad->src_stereo == MULTIVIEW_2D)
+ {
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX;
+ quad->cropViewport[0][RIGHT_EYE].TopLeftY = quad->cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY;
+ }
+ else if (quad->src_stereo == MULTIVIEW_STEREO_SBS)
+ {
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = quad->projection == PROJECTION_MODE_EQUIRECTANGULAR ?
+ rect->left : rect->left - srcAreaWidth / 2;
+ }
+ //For stereoscopic side by side top-bottom format
+ else if (quad->src_stereo == MULTIVIEW_STEREO_TB)
+ {
+ quad->cropViewport[0][RIGHT_EYE].TopLeftX = rect->left;
+ if (quad->projection == PROJECTION_MODE_EQUIRECTANGULAR)
+ quad->cropViewport[0][RIGHT_EYE].TopLeftY = rect->top;
}
- break;
- default:
- vlc_assert_unreachable();
}
}
diff --git a/modules/video_output/win32/d3d11_quad.h b/modules/video_output/win32/d3d11_quad.h
index c39eb58307..5855a48868 100644
--- a/modules/video_output/win32/d3d11_quad.h
+++ b/modules/video_output/win32/d3d11_quad.h
@@ -23,6 +23,8 @@
#ifndef VLC_D3D11_QUAD_H
#define VLC_D3D11_QUAD_H
+#include <vlc_vout.h>
+
#include "../../video_chroma/d3d11_fmt.h"
#include "d3d11_shaders.h"
@@ -47,7 +49,8 @@ typedef struct d3d_vertex_t {
void D3D11_RenderQuad(d3d11_device_t *, d3d_quad_t *, d3d_vshader_t *,
ID3D11ShaderResourceView *resourceViews[D3D11_MAX_SHADER_VIEW],
- ID3D11RenderTargetView *renderTarget[D3D11_MAX_SHADER_VIEW]);
+ ID3D11RenderTargetView *renderTarget[D3D11_MAX_SHADER_VIEW][2],
+ size_t eyeIndex, size_t targetEye);
int D3D11_AllocateQuad(vlc_object_t *, d3d11_device_t *, video_projection_mode_t, d3d_quad_t *);
#define D3D11_AllocateQuad(a,b,c,d) D3D11_AllocateQuad(VLC_OBJECT(a),b,c,d)
@@ -56,14 +59,15 @@ void D3D11_ReleaseQuad(d3d_quad_t *);
int D3D11_SetupQuad(vlc_object_t *, d3d11_device_t *, const video_format_t *, d3d_quad_t *,
const display_info_t *, const RECT *,
- video_orientation_t);
-#define D3D11_SetupQuad(a,b,c,d,e,f,g) D3D11_SetupQuad(VLC_OBJECT(a),b,c,d,e,f,g)
+ video_orientation_t, video_multiview_mode_t);
+#define D3D11_SetupQuad(a,b,c,d,e,f,g,h) D3D11_SetupQuad(VLC_OBJECT(a),b,c,d,e,f,g,h)
bool D3D11_UpdateQuadPosition( vlc_object_t *, d3d11_device_t *, d3d_quad_t *,
const RECT *output, video_orientation_t );
#define D3D11_UpdateQuadPosition(a,b,c,d,e) D3D11_UpdateQuadPosition(VLC_OBJECT(a),b,c,d,e)
-void D3D11_UpdateViewport(d3d_quad_t *, const RECT *, const d3d_format_t *display);
+void D3D11_UpdateViewport(d3d_quad_t *, const RECT *src, const d3d_format_t *display,
+ vlc_stereoscopic_mode_t display_mode);
void D3D11_UpdateQuadOpacity(vlc_object_t *, d3d11_device_t *, d3d_quad_t *, float opacity);
#define D3D11_UpdateQuadOpacity(a,b,c,d) D3D11_UpdateQuadOpacity(VLC_OBJECT(a),b,c,d)
diff --git a/modules/video_output/win32/d3d11_shaders.c b/modules/video_output/win32/d3d11_shaders.c
index e54dcfca9e..c39c360d42 100644
--- a/modules/video_output/win32/d3d11_shaders.c
+++ b/modules/video_output/win32/d3d11_shaders.c
@@ -658,22 +658,32 @@ float GetFormatLuminance(vlc_object_t *o, const video_format_t *fmt)
}
HRESULT D3D11_CreateRenderTargets( d3d11_device_t *d3d_dev, ID3D11Resource *texture,
- const d3d_format_t *cfg, ID3D11RenderTargetView *output[D3D11_MAX_SHADER_VIEW] )
+ const d3d_format_t *cfg, bool both_eyes,
+ ID3D11RenderTargetView *output[D3D11_MAX_SHADER_VIEW][2] )
{
- D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
- renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- renderTargetViewDesc.Texture2D.MipSlice = 0;
+ D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc = { 0 };
+ if (both_eyes)
+ {
+ renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ renderTargetViewDesc.Texture2DArray.ArraySize = 1;
+ }
+ else
+ renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
for (size_t i=0; i<D3D11_MAX_SHADER_VIEW; i++)
{
if (cfg->resourceFormat[i])
{
renderTargetViewDesc.Format = cfg->resourceFormat[i];
- HRESULT hr = ID3D11Device_CreateRenderTargetView(d3d_dev->d3ddevice, texture,
- &renderTargetViewDesc, &output[i]);
- if (FAILED(hr))
+ for (size_t eye=0; eye < (both_eyes ? 2 : 1); eye++)
{
- return hr;
+ renderTargetViewDesc.Texture2DArray.FirstArraySlice = eye;
+ HRESULT hr = ID3D11Device_CreateRenderTargetView(d3d_dev->d3ddevice, texture,
+ &renderTargetViewDesc, &output[i][eye]);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
}
}
}
@@ -681,7 +691,8 @@ HRESULT D3D11_CreateRenderTargets( d3d11_device_t *d3d_dev, ID3D11Resource *text
}
void D3D11_ClearRenderTargets(d3d11_device_t *d3d_dev, const d3d_format_t *cfg,
- ID3D11RenderTargetView *targets[D3D11_MAX_SHADER_VIEW])
+ ID3D11RenderTargetView *targets[D3D11_MAX_SHADER_VIEW][2],
+ int clear_eye)
{
static const FLOAT blackY[1] = {0.0f};
static const FLOAT blackUV[2] = {0.5f, 0.5f};
@@ -689,28 +700,41 @@ void D3D11_ClearRenderTargets(d3d11_device_t *d3d_dev, const d3d_format_t *cfg,
static const FLOAT blackYUY2[4] = {0.0f, 0.5f, 0.0f, 0.5f};
static const FLOAT blackVUYA[4] = {0.5f, 0.5f, 0.0f, 1.0f};
- switch (cfg->formatTexture)
+ for (size_t eye=0; eye < 2;eye++)
{
- case DXGI_FORMAT_NV12:
- case DXGI_FORMAT_P010:
- ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0], blackY);
- ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[1], blackUV);
- break;
- case DXGI_FORMAT_R8G8B8A8_UNORM:
- case DXGI_FORMAT_B8G8R8A8_UNORM:
- case DXGI_FORMAT_B8G8R8X8_UNORM:
- case DXGI_FORMAT_R10G10B10A2_UNORM:
- case DXGI_FORMAT_B5G6R5_UNORM:
- ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0], blackRGBA);
- break;
- case DXGI_FORMAT_YUY2:
- ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0], blackYUY2);
- break;
- case DXGI_FORMAT_AYUV:
- ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0], blackVUYA);
- break;
- default:
- vlc_assert_unreachable();
+ if (!(clear_eye & D3D11_SHOW_EYE_LEFT) && eye == MONO_OR_LEFT_EYE)
+ continue;
+ if (!(clear_eye & D3D11_SHOW_EYE_RIGHT) && eye == RIGHT_EYE)
+ continue;
+
+ switch (cfg->formatTexture)
+ {
+ case DXGI_FORMAT_NV12:
+ case DXGI_FORMAT_P010:
+ if (targets[0][eye])
+ ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0][eye], blackY);
+ if (targets[1][eye])
+ ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[1][eye], blackUV);
+ break;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ if (targets[0][eye])
+ ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0][eye], blackRGBA);
+ break;
+ case DXGI_FORMAT_YUY2:
+ if (targets[0][eye])
+ ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0][eye], blackYUY2);
+ break;
+ case DXGI_FORMAT_AYUV:
+ if (targets[0][eye])
+ ID3D11DeviceContext_ClearRenderTargetView( d3d_dev->d3dcontext, targets[0][eye], blackVUYA);
+ break;
+ default:
+ vlc_assert_unreachable();
+ }
}
}
diff --git a/modules/video_output/win32/d3d11_shaders.h b/modules/video_output/win32/d3d11_shaders.h
index 2f87bafd4a..e014f06171 100644
--- a/modules/video_output/win32/d3d11_shaders.h
+++ b/modules/video_output/win32/d3d11_shaders.h
@@ -26,6 +26,9 @@
#include "../../video_chroma/d3d11_fmt.h"
#include <dxgi1_4.h>
+#define MONO_OR_LEFT_EYE 0
+#define RIGHT_EYE 1
+
#define DEFAULT_BRIGHTNESS 100
#define DEFAULT_SRGB_BRIGHTNESS 100
#define MAX_PQ_BRIGHTNESS 10000
@@ -97,10 +100,11 @@ typedef struct
UINT PSConstantsCount;
ID3D11PixelShader *d3dpixelShader[D3D11_MAX_SHADER_VIEW];
ID3D11SamplerState *d3dsampState[2];
- D3D11_VIEWPORT cropViewport[D3D11_MAX_SHADER_VIEW];
+ D3D11_VIEWPORT cropViewport[D3D11_MAX_SHADER_VIEW][2];
unsigned int i_width;
unsigned int i_height;
video_projection_mode_t projection;
+ video_multiview_mode_t src_stereo;
PS_CONSTANT_BUFFER shaderConstants;
} d3d_quad_t;
@@ -129,10 +133,16 @@ float GetFormatLuminance(vlc_object_t *, const video_format_t *);
#define GetFormatLuminance(a,b) GetFormatLuminance(VLC_OBJECT(a),b)
HRESULT D3D11_CreateRenderTargets(d3d11_device_t *, ID3D11Resource *, const d3d_format_t *,
- ID3D11RenderTargetView *output[D3D11_MAX_SHADER_VIEW]);
+ bool both_eyes,
+ ID3D11RenderTargetView *output[D3D11_MAX_SHADER_VIEW][2]);
+
+#define D3D11_SHOW_EYE_LEFT 1
+#define D3D11_SHOW_EYE_RIGHT 2
+#define D3D11_SHOW_EYE_BOTH (D3D11_SHOW_EYE_LEFT|D3D11_SHOW_EYE_RIGHT)
void D3D11_ClearRenderTargets(d3d11_device_t *, const d3d_format_t *,
- ID3D11RenderTargetView *targets[D3D11_MAX_SHADER_VIEW]);
+ ID3D11RenderTargetView *targets[D3D11_MAX_SHADER_VIEW][2],
+ int eyes);
void D3D11_SetVertexShader(d3d_vshader_t *dst, d3d_vshader_t *src);
void D3D11_ReleaseVertexShader(d3d_vshader_t *);
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index ae8f4449a9..4ded9279d1 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -102,7 +102,7 @@ struct vout_display_sys_t
picture_sys_t stagingSys;
- ID3D11RenderTargetView *swapchainTargetView[D3D11_MAX_SHADER_VIEW];
+ ID3D11RenderTargetView *swapchainTargetView[D3D11_MAX_SHADER_VIEW][2];
d3d_vshader_t projectionVShader;
d3d_vshader_t flatVShader;
@@ -111,6 +111,11 @@ struct vout_display_sys_t
* Uses a Texture2D with slices rather than a Texture2DArray for the decoder */
bool legacy_shader;
+ /* Stereo info */
+ bool device_3d_capable;
+ vlc_stereoscopic_mode_t stereo_mode; /* actual mode, not auto */
+ picture_t *stereo_pic;
+
// SPU
vlc_fourcc_t pSubpictureChromas[2];
d3d_quad_t regionQuad;
@@ -298,6 +303,8 @@ static int Open(vlc_object_t *object)
vd->info.has_double_click = true;
vd->info.has_pictures_invalid = vd->info.is_slow;
+ vd->info.stereo_modes = (1 << MULTIVIEW_2D) | (1 << MULTIVIEW_STEREO_FRAME) |
+ (1 << MULTIVIEW_STEREO_SBS) | (1 << MULTIVIEW_STEREO_TB);
if (var_InheritBool(vd, "direct3d11-hw-blending") &&
vd->sys->regionQuad.textureFormat != NULL)
@@ -360,7 +367,7 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size)
}
if (D3D11_SetupQuad( vd, &sys->d3d_dev, &surface_fmt, &sys->picQuad, &sys->display, &sys->sys.rect_src_clipped,
- vd->fmt.orientation ) != VLC_SUCCESS) {
+ vd->fmt.orientation, vd->fmt.multiview_mode ) != VLC_SUCCESS) {
msg_Err(vd, "Could not Create the main quad picture.");
return NULL;
}
@@ -485,7 +492,8 @@ static void DestroyDisplayPoolPicture(picture_t *picture)
static void FillSwapChainDesc(vout_display_t *vd, DXGI_SWAP_CHAIN_DESC1 *out)
{
ZeroMemory(out, sizeof(*out));
- out->BufferCount = 3;
+ out->Stereo = vd->sys->stereo_mode == VIDEO_STEREO_OUTPUT_STEREO;
+ out->BufferCount = out->Stereo ? 2 : 3;
out->BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
out->SampleDesc.Count = 1;
out->SampleDesc.Quality = 0;
@@ -495,6 +503,63 @@ static void FillSwapChainDesc(vout_display_t *vd, DXGI_SWAP_CHAIN_DESC1 *out)
//out->Flags = 512; // DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO;
out->SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
}
+
+static int UpdateSwapChain(vout_display_t *vd)
+{
+ vout_display_sys_t *sys = vd->sys;
+ DXGI_SWAP_CHAIN_DESC1 scd;
+ IDXGIFactory2 *dxgifactory;
+ HRESULT hr = S_OK;
+
+ IDXGIAdapter *dxgiadapter = D3D11DeviceAdapter(sys->d3d_dev.d3ddevice);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Could not get the DXGI Adapter");
+ return VLC_EGENERIC;
+ }
+
+ hr = IDXGIAdapter_GetParent(dxgiadapter, &IID_IDXGIFactory2, (void **)&dxgifactory);
+ IDXGIAdapter_Release(dxgiadapter);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Could not get the DXGI Factory. (hr=0x%lX)", hr);
+ return VLC_EGENERIC;
+ }
+
+ //Release references to recreate the swapchain
+ if (sys->d3d_dev.d3dcontext)
+ {
+ ID3D11DeviceContext_Flush(sys->d3d_dev.d3dcontext);
+ }
+ if (sys->dxgiswapChain4)
+ {
+ IDXGISwapChain4_Release(sys->dxgiswapChain4);
+ sys->dxgiswapChain4 = NULL;
+ }
+ if (sys->dxgiswapChain)
+ {
+ IDXGISwapChain_Release(sys->dxgiswapChain);
+ sys->dxgiswapChain = NULL;
+ }
+ if (sys->swapchainTargetView[0][MONO_OR_LEFT_EYE])
+ {
+ ID3D11RenderTargetView_Release(sys->swapchainTargetView[0][MONO_OR_LEFT_EYE]);
+ sys->swapchainTargetView[0][MONO_OR_LEFT_EYE] = NULL;
+ }
+ if (sys->swapchainTargetView[0][RIGHT_EYE])
+ {
+ ID3D11RenderTargetView_Release(sys->swapchainTargetView[0][RIGHT_EYE]);
+ sys->swapchainTargetView[0][RIGHT_EYE] = NULL;
+ }
+
+ FillSwapChainDesc(vd, &scd);
+ hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
+ sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain);
+ IDXGIFactory2_Release(dxgifactory);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Could not recreate the %s SwapChain. (hr=0x%lX)", sys->stereo_mode == VIDEO_STEREO_OUTPUT_STEREO ? "stereo ":"", hr);
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
#endif
static HRESULT UpdateBackBuffer(vout_display_t *vd)
@@ -511,9 +576,9 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
uint32_t i_height = RECTHeight(rect);
D3D11_TEXTURE2D_DESC dsc = { 0 };
- if (sys->swapchainTargetView[0]) {
+ if (sys->swapchainTargetView[0][MONO_OR_LEFT_EYE]) {
ID3D11Resource *res = NULL;
- ID3D11RenderTargetView_GetResource(sys->swapchainTargetView[0], &res);
+ ID3D11RenderTargetView_GetResource(sys->swapchainTargetView[0][MONO_OR_LEFT_EYE], &res);
if (res)
{
ID3D11Texture2D_GetDesc((ID3D11Texture2D*) res, &dsc);
@@ -526,15 +591,18 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
for (size_t i=0; i < D3D11_MAX_SHADER_VIEW; i++)
{
- if (sys->swapchainTargetView[i]) {
- ID3D11RenderTargetView_Release(sys->swapchainTargetView[i]);
- sys->swapchainTargetView[i] = NULL;
+ for (size_t eye=0; eye<2; eye++)
+ {
+ if (sys->swapchainTargetView[i][eye]) {
+ ID3D11RenderTargetView_Release(sys->swapchainTargetView[i][eye]);
+ sys->swapchainTargetView[i][eye] = NULL;
+ }
}
}
/* TODO detect is the size is the same as the output and switch to fullscreen mode */
- hr = IDXGISwapChain_ResizeBuffers(sys->dxgiswapChain, 0, i_width, i_height,
- DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_ResizeBuffers(sys->dxgiswapChain, sys->stereo_mode == VIDEO_STEREO_OUTPUT_STEREO ? 4 : 0,
+ i_width, i_height, DXGI_FORMAT_UNKNOWN, 0);
if (FAILED(hr)) {
msg_Err(vd, "Failed to resize the backbuffer. (hr=0x%lX)", hr);
return hr;
@@ -547,18 +615,53 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
}
hr = D3D11_CreateRenderTargets( &sys->d3d_dev, (ID3D11Resource *)pBackBuffer,
- sys->display.pixelFormat, sys->swapchainTargetView );
+ sys->display.pixelFormat, sys->stereo_mode == VIDEO_STEREO_OUTPUT_STEREO,
+ sys->swapchainTargetView );
ID3D11Texture2D_Release(pBackBuffer);
if (FAILED(hr)) {
msg_Err(vd, "Failed to create the target view. (hr=0x%lX)", hr);
return hr;
}
- D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->swapchainTargetView );
+ D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->swapchainTargetView, D3D11_SHOW_EYE_BOTH );
return S_OK;
}
+#if !VLC_WINSTORE_APP
+static int ChangeStereoSwapChain(vout_display_t *vd, vlc_stereoscopic_mode_t new_mode)
+{
+ vout_display_sys_t *sys = vd->sys;
+ if (sys->stereo_mode == new_mode)
+ return VLC_SUCCESS;
+
+ if (new_mode == VIDEO_STEREO_OUTPUT_STEREO && !sys->device_3d_capable)
+ {
+ sys->stereo_mode = VIDEO_STEREO_OUTPUT_LEFT_ONLY;
+ UpdatePicQuadPosition(vd);
+ return VLC_EGENERIC;
+ }
+
+ vlc_stereoscopic_mode_t old_mode = sys->stereo_mode;
+ sys->stereo_mode = new_mode;
+ int res = UpdateSwapChain(vd);
+ if (res == VLC_SUCCESS)
+ {
+ UpdateBackBuffer(vd);
+ }
+
+ if (res != VLC_SUCCESS)
+ {
+ if (new_mode == VIDEO_STEREO_OUTPUT_STEREO)
+ sys->device_3d_capable = false;
+ sys->stereo_mode = new_mode = old_mode;
+ UpdateSwapChain(vd);
+ }
+ UpdatePicQuadPosition(vd);
+ return res;
+}
+#endif /* VLC_WINSTORE_APP */
+
/* rotation around the Z axis */
static void getZRotMatrix(float theta, FLOAT matrix[static 16])
{
@@ -726,6 +829,20 @@ static void UpdateSize(vout_display_t *vd)
d3d11_device_unlock( &sys->d3d_dev );
}
+static vlc_stereoscopic_mode_t GetStereoMode(vout_display_t *vd, vlc_stereoscopic_mode_t stereo_output, video_multiview_mode_t src_mode)
+{
+ vout_display_sys_t *sys = vd->sys;
+ if (stereo_output == VIDEO_STEREO_OUTPUT_AUTO)
+ {
+ /* decide which mode we're going with */
+ if (sys->device_3d_capable && src_mode != MULTIVIEW_2D)
+ stereo_output = VIDEO_STEREO_OUTPUT_STEREO;
+ else
+ stereo_output = VIDEO_STEREO_OUTPUT_LEFT_ONLY;
+ }
+ return stereo_output;
+}
+
static inline bool RectEquals(const RECT *r1, const RECT *r2)
{
return r1->bottom == r2->bottom && r1->top == r2->top &&
@@ -750,6 +867,15 @@ static int Control(vout_display_t *vd, int query, va_list args)
res = VLC_SUCCESS;
}
}
+#if !VLC_WINSTORE_APP
+ else if (query == VOUT_DISPLAY_CHANGE_STEREO_MODE)
+ {
+ const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t*);
+ vlc_stereoscopic_mode_t new_mode = GetStereoMode(vd, cfg->stereo_mode, vd->source.multiview_mode);
+ /* reset the swapchain to 2D/3D accordingly */
+ res = ChangeStereoSwapChain(vd, new_mode);
+ }
+#endif
if (!RectEquals(&before_src_clipped, &sys->sys.rect_src_clipped) ||
!RectEquals(&before_dest_clipped, &sys->sys.rect_dest_clipped) ||
@@ -779,15 +905,36 @@ static void Manage(vout_display_t *vd)
}
static void DisplayPicture(vout_display_sys_t *sys, d3d_quad_t *quad, d3d_vshader_t *vs_shader,
- ID3D11ShaderResourceView *renderSrc[D3D11_MAX_SHADER_VIEW])
+ ID3D11ShaderResourceView *renderSrc[D3D11_MAX_SHADER_VIEW],
+ int showEyes)
{
- D3D11_RenderQuad(&sys->d3d_dev, quad, vs_shader, renderSrc, sys->swapchainTargetView);
+ if (showEyes & D3D11_SHOW_EYE_LEFT)
+ D3D11_RenderQuad(&sys->d3d_dev, quad, vs_shader, renderSrc, sys->swapchainTargetView, MONO_OR_LEFT_EYE, MONO_OR_LEFT_EYE);
+ if (showEyes & D3D11_SHOW_EYE_RIGHT)
+ D3D11_RenderQuad(&sys->d3d_dev, quad, vs_shader, renderSrc, sys->swapchainTargetView, RIGHT_EYE,
+ sys->stereo_mode == VIDEO_STEREO_OUTPUT_STEREO ? RIGHT_EYE : MONO_OR_LEFT_EYE);
}
static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
+ if (sys->picQuad.src_stereo != picture->format.multiview_mode)
+ {
+ D3D11_SetupQuad( vd, &sys->d3d_dev, &picture->format, &sys->picQuad, &sys->display,
+ &sys->sys.rect_src_clipped, vd->fmt.orientation, picture->format.multiview_mode );
+#if !VLC_WINSTORE_APP
+ vlc_stereoscopic_mode_t new_mode = GetStereoMode(vd, vd->cfg->stereo_mode, picture->format.multiview_mode);
+ if (sys->stereo_mode != new_mode)
+ {
+ /* stereo mode changed */
+ ChangeStereoSwapChain(vd, new_mode);
+ }
+ else
+#endif
+ UpdatePicQuadPosition(vd);
+ }
+
if (sys->picQuad.textureFormat->formatTexture == DXGI_FORMAT_UNKNOWN)
{
D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -884,6 +1031,19 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
sys->d3dregions = subpicture_regions;
}
+ int showEyes;
+ if (sys->stereo_mode == VIDEO_STEREO_OUTPUT_LEFT_ONLY || sys->stereo_mode == VIDEO_STEREO_OUTPUT_RIGHT_ONLY)
+ showEyes = D3D11_SHOW_EYE_LEFT;
+ else if (sys->picQuad.src_stereo == MULTIVIEW_STEREO_FRAME)
+ {
+ if (picture->format.b_multiview_left_eye)
+ showEyes = D3D11_SHOW_EYE_LEFT;
+ else
+ showEyes = D3D11_SHOW_EYE_RIGHT;
+ }
+ else
+ showEyes = D3D11_SHOW_EYE_BOTH;
+
if (picture->format.mastering.max_luminance)
{
D3D11_UpdateQuadLuminanceScale(vd, &sys->d3d_dev, &sys->picQuad, GetFormatLuminance(VLC_OBJECT(vd), &picture->format) / (float)sys->display.luminance_peak);
@@ -917,7 +1077,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
}
DisplayPicture(sys, &sys->picQuad,
vd->fmt.projection_mode == PROJECTION_MODE_RECTANGULAR ? &sys->flatVShader : &sys->projectionVShader,
- renderSrc);
+ renderSrc, showEyes);
if (subpicture) {
// draw the additional vertices
@@ -925,7 +1085,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
if (sys->d3dregions[i])
{
d3d_quad_t *quad = (d3d_quad_t *) sys->d3dregions[i]->p_sys;
- DisplayPicture(sys, quad, &sys->flatVShader, quad->picSys.renderSrc);
+ DisplayPicture(sys, quad, &sys->flatVShader, quad->picSys.renderSrc, showEyes);
}
}
}
@@ -941,11 +1101,33 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
{
vout_display_sys_t *sys = vd->sys;
+ /* keep the first of a stereo sequence for later */
+ /* TODO move this to the core so it's kept during a pause */
+ if (sys->picQuad.src_stereo == MULTIVIEW_STEREO_FRAME)
+ {
+ if (picture->format.b_multiview_right_eye_first == !picture->format.b_multiview_left_eye)
+ {
+ /* first picture in the sequence, wait for the next one */
+ if (sys->stereo_pic)
+ picture_Release(sys->stereo_pic);
+ sys->stereo_pic = picture;
+ return;
+ }
+ }
+
Manage(vd);
VLC_UNUSED(date);
- D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->swapchainTargetView );
+ int cleanEyes;
+ if (sys->stereo_mode == VIDEO_STEREO_OUTPUT_STEREO)
+ cleanEyes = D3D11_SHOW_EYE_BOTH;
+ else
+ cleanEyes = D3D11_SHOW_EYE_LEFT;
+ D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->swapchainTargetView, cleanEyes );
+
+ if (sys->stereo_pic)
+ PreparePicture(vd, sys->stereo_pic, subpicture);
PreparePicture(vd, picture, subpicture);
}
@@ -953,6 +1135,17 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
{
vout_display_sys_t *sys = vd->sys;
+ if (sys->picQuad.src_stereo == MULTIVIEW_STEREO_FRAME)
+ {
+ if (picture->format.b_multiview_right_eye_first == !picture->format.b_multiview_left_eye)
+ {
+ if (subpicture)
+ subpicture_Delete(subpicture);
+ /* wait for the next picture to display anything */
+ return;
+ }
+ }
+
DXGI_PRESENT_PARAMETERS presentParams;
memset(&presentParams, 0, sizeof(presentParams));
d3d11_device_lock( &sys->d3d_dev );
@@ -1217,6 +1410,16 @@ static int Direct3D11Open(vout_display_t *vd)
return VLC_EGENERIC;
}
+ //Disable 3D if not supported by the system
+ sys->device_3d_capable = sys->d3d_dev.feature_level >= D3D_FEATURE_LEVEL_10_0 /*&&
+ IDXGIFactory2_IsWindowedStereoEnabled(dxgifactory)*/;
+
+ if (vd->source.multiview_mode != MULTIVIEW_2D && !sys->device_3d_capable)
+ {
+ msg_Dbg(vd, "Could not create the D3D11 device for Stereoscopic 3D. 3D won't work.");
+ }
+ sys->stereo_mode = GetStereoMode(vd, vd->cfg->stereo_mode, vd->source.multiview_mode);
+
FillSwapChainDesc(vd, &scd);
hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
@@ -1233,6 +1436,9 @@ static int Direct3D11Open(vout_display_t *vd)
msg_Err(vd, "Could not create the SwapChain. (hr=0x%lX)", hr);
return VLC_EGENERIC;
}
+#else
+ // We can't switch to 3D on UWP
+ sys->device_3d_capable = false;
#endif
IDXGISwapChain_QueryInterface( sys->dxgiswapChain, &IID_IDXGISwapChain4, (void **)&sys->dxgiswapChain4);
@@ -1354,6 +1560,12 @@ static void Direct3D11Close(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
+ if (sys->stereo_pic)
+ {
+ picture_Release(sys->stereo_pic);
+ sys->stereo_pic = NULL;
+ }
+
Direct3D11DestroyResources(vd);
if (sys->dxgiswapChain4)
{
@@ -1375,14 +1587,15 @@ static void UpdatePicQuadPosition(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
- D3D11_UpdateViewport( &sys->picQuad, &sys->sys.rect_dest_clipped, sys->display.pixelFormat );
+ D3D11_UpdateViewport( &sys->picQuad, &sys->sys.rect_dest_clipped, sys->display.pixelFormat,
+ sys->stereo_mode );
SetQuadVSProjection(vd, &sys->picQuad, &vd->cfg->viewpoint);
#ifndef NDEBUG
msg_Dbg( vd, "picQuad position (%.02f,%.02f) %.02fx%.02f",
- sys->picQuad.cropViewport[0].TopLeftX, sys->picQuad.cropViewport[0].TopLeftY,
- sys->picQuad.cropViewport[0].Width, sys->picQuad.cropViewport[0].Height );
+ sys->picQuad.cropViewport[0][MONO_OR_LEFT_EYE].TopLeftX, sys->picQuad.cropViewport[0][MONO_OR_LEFT_EYE].TopLeftY,
+ sys->picQuad.cropViewport[0][MONO_OR_LEFT_EYE].Width, sys->picQuad.cropViewport[0][MONO_OR_LEFT_EYE].Height );
#endif
}
@@ -1578,9 +1791,12 @@ static void Direct3D11DestroyResources(vout_display_t *vd)
D3D11_ReleasePixelShader(&sys->regionQuad);
for (size_t i=0; i < D3D11_MAX_SHADER_VIEW; i++)
{
- if (sys->swapchainTargetView[i]) {
- ID3D11RenderTargetView_Release(sys->swapchainTargetView[i]);
- sys->swapchainTargetView[i] = NULL;
+ for (size_t eye=0; eye<2; eye++)
+ {
+ if (sys->swapchainTargetView[i][eye]) {
+ ID3D11RenderTargetView_Release(sys->swapchainTargetView[i][eye]);
+ sys->swapchainTargetView[i][eye] = NULL;
+ }
}
}
@@ -1687,7 +1903,7 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
}
err = D3D11_SetupQuad( vd, &sys->d3d_dev, &r->fmt, d3dquad, &sys->display, &output,
- ORIENT_NORMAL );
+ ORIENT_NORMAL, MULTIVIEW_2D );
if (err != VLC_SUCCESS) {
msg_Err(vd, "Failed to setup %dx%d quad for OSD",
r->fmt.i_visible_width, r->fmt.i_visible_height);
@@ -1750,7 +1966,8 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
spuViewport.right = sys->sys.rect_dest.left + (FLOAT) (r->i_x + r->fmt.i_visible_width) * RECTWidth(sys->sys.rect_dest) / subpicture->i_original_picture_width;
spuViewport.bottom = sys->sys.rect_dest.top + (FLOAT) (r->i_y + r->fmt.i_visible_height) * RECTHeight(sys->sys.rect_dest) / subpicture->i_original_picture_height;
- D3D11_UpdateViewport( quad, &spuViewport, sys->display.pixelFormat );
+ D3D11_UpdateViewport( quad, &spuViewport, sys->display.pixelFormat,
+ sys->stereo_mode );
D3D11_UpdateQuadOpacity(vd, &sys->d3d_dev, quad, r->i_alpha / 255.0f );
}
--
2.17.0
More information about the vlc-devel
mailing list