Commit b21fef06 authored by Steve Lhomme's avatar Steve Lhomme

direct3d11: separate the fields to initialize the swapchain

In external rendering these fields should never be used.
parent 5609c1b4
...@@ -87,6 +87,16 @@ vlc_module_begin () ...@@ -87,6 +87,16 @@ vlc_module_begin ()
set_callbacks(Open, Close) set_callbacks(Open, Close)
vlc_module_end () vlc_module_end ()
struct d3d11_local_swapchain
{
vlc_object_t *obj;
IDXGISwapChain1 *dxgiswapChain; /* DXGI 1.2 swap chain */
IDXGISwapChain4 *dxgiswapChain4; /* DXGI 1.5 for HDR metadata */
ID3D11RenderTargetView *swapchainTargetView[D3D11_MAX_RENDER_TARGET];
};
struct vout_display_sys_t struct vout_display_sys_t
{ {
vout_display_sys_win32_t sys; /* only use if sys.event is not NULL */ vout_display_sys_win32_t sys; /* only use if sys.event is not NULL */
...@@ -98,8 +108,6 @@ struct vout_display_sys_t ...@@ -98,8 +108,6 @@ struct vout_display_sys_t
display_info_t display; display_info_t display;
d3d11_handle_t hd3d; d3d11_handle_t hd3d;
IDXGISwapChain1 *dxgiswapChain; /* DXGI 1.2 swap chain */
IDXGISwapChain4 *dxgiswapChain4; /* DXGI 1.5 for HDR */
d3d11_device_t d3d_dev; d3d11_device_t d3d_dev;
d3d_quad_t picQuad; d3d_quad_t picQuad;
...@@ -108,7 +116,7 @@ struct vout_display_sys_t ...@@ -108,7 +116,7 @@ struct vout_display_sys_t
picture_sys_t stagingSys; picture_sys_t stagingSys;
picture_pool_t *pool; /* hardware decoding pool */ picture_pool_t *pool; /* hardware decoding pool */
ID3D11RenderTargetView *swapchainTargetView[D3D11_MAX_RENDER_TARGET]; struct d3d11_local_swapchain internal_swapchain; /* TODO do not access fields directly */
d3d_vshader_t projectionVShader; d3d_vshader_t projectionVShader;
d3d_vshader_t flatVShader; d3d_vshader_t flatVShader;
...@@ -203,9 +211,9 @@ static bool Resize(void *opaque, unsigned i_width, unsigned i_height) ...@@ -203,9 +211,9 @@ static bool Resize(void *opaque, unsigned i_width, unsigned i_height)
D3D11_TEXTURE2D_DESC dsc = { 0 }; D3D11_TEXTURE2D_DESC dsc = { 0 };
if (sys->swapchainTargetView[0]) { if (sys->internal_swapchain.swapchainTargetView[0]) {
ID3D11Resource *res = NULL; ID3D11Resource *res = NULL;
ID3D11RenderTargetView_GetResource(sys->swapchainTargetView[0], &res); ID3D11RenderTargetView_GetResource(sys->internal_swapchain.swapchainTargetView[0], &res);
if (res) if (res)
{ {
ID3D11Texture2D_GetDesc((ID3D11Texture2D*) res, &dsc); ID3D11Texture2D_GetDesc((ID3D11Texture2D*) res, &dsc);
...@@ -216,37 +224,37 @@ static bool Resize(void *opaque, unsigned i_width, unsigned i_height) ...@@ -216,37 +224,37 @@ static bool Resize(void *opaque, unsigned i_width, unsigned i_height)
if (dsc.Width == i_width && dsc.Height == i_height) if (dsc.Width == i_width && dsc.Height == i_height)
return true; /* nothing changed */ return true; /* nothing changed */
for (size_t i=0; i < ARRAY_SIZE(sys->swapchainTargetView); i++) for (size_t i=0; i < ARRAY_SIZE(sys->internal_swapchain.swapchainTargetView); i++)
{ {
if (sys->swapchainTargetView[i]) { if (sys->internal_swapchain.swapchainTargetView[i]) {
ID3D11RenderTargetView_Release(sys->swapchainTargetView[i]); ID3D11RenderTargetView_Release(sys->internal_swapchain.swapchainTargetView[i]);
sys->swapchainTargetView[i] = NULL; sys->internal_swapchain.swapchainTargetView[i] = NULL;
} }
} }
/* TODO detect is the size is the same as the output and switch to fullscreen mode */ /* 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, hr = IDXGISwapChain_ResizeBuffers(sys->internal_swapchain.dxgiswapChain, 0, i_width, i_height,
DXGI_FORMAT_UNKNOWN, 0); DXGI_FORMAT_UNKNOWN, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
msg_Err(vd, "Failed to resize the backbuffer. (hr=0x%lX)", hr); msg_Err(vd, "Failed to resize the backbuffer. (hr=0x%lX)", hr);
return false; return false;
} }
hr = IDXGISwapChain_GetBuffer(sys->dxgiswapChain, 0, &IID_ID3D11Texture2D, (LPVOID *)&pBackBuffer); hr = IDXGISwapChain_GetBuffer(sys->internal_swapchain.dxgiswapChain, 0, &IID_ID3D11Texture2D, (LPVOID *)&pBackBuffer);
if (FAILED(hr)) { if (FAILED(hr)) {
msg_Err(vd, "Could not get the backbuffer for the Swapchain. (hr=0x%lX)", hr); msg_Err(vd, "Could not get the backbuffer for the Swapchain. (hr=0x%lX)", hr);
return false; return false;
} }
hr = D3D11_CreateRenderTargets( &sys->d3d_dev, (ID3D11Resource *)pBackBuffer, hr = D3D11_CreateRenderTargets( &sys->d3d_dev, (ID3D11Resource *)pBackBuffer,
sys->display.pixelFormat, sys->swapchainTargetView ); sys->display.pixelFormat, sys->internal_swapchain.swapchainTargetView );
ID3D11Texture2D_Release(pBackBuffer); ID3D11Texture2D_Release(pBackBuffer);
if (FAILED(hr)) { if (FAILED(hr)) {
msg_Err(vd, "Failed to create the target view. (hr=0x%lX)", hr); msg_Err(vd, "Failed to create the target view. (hr=0x%lX)", hr);
return false; return false;
} }
D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->swapchainTargetView ); D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->internal_swapchain.swapchainTargetView );
return true; return true;
} }
...@@ -256,7 +264,7 @@ static bool StartRendering(void *opaque) ...@@ -256,7 +264,7 @@ static bool StartRendering(void *opaque)
vout_display_t *vd = opaque; vout_display_t *vd = opaque;
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->swapchainTargetView ); D3D11_ClearRenderTargets( &sys->d3d_dev, sys->display.pixelFormat, sys->internal_swapchain.swapchainTargetView );
return true; return true;
} }
...@@ -267,7 +275,7 @@ static void Swap(void *opaque) ...@@ -267,7 +275,7 @@ static void Swap(void *opaque)
DXGI_PRESENT_PARAMETERS presentParams = { 0 }; DXGI_PRESENT_PARAMETERS presentParams = { 0 };
HRESULT hr = IDXGISwapChain1_Present1(sys->dxgiswapChain, 0, 0, &presentParams); HRESULT hr = IDXGISwapChain1_Present1(sys->internal_swapchain.dxgiswapChain, 0, 0, &presentParams);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{ {
/* TODO device lost */ /* TODO device lost */
...@@ -349,13 +357,13 @@ static int SetupWindowedOutput(vout_display_t *vd) ...@@ -349,13 +357,13 @@ static int SetupWindowedOutput(vout_display_t *vd)
} }
hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice, hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain); sys->sys.hvideownd, &scd, NULL, NULL, &sys->internal_swapchain.dxgiswapChain);
if (hr == DXGI_ERROR_INVALID_CALL && scd.Format == DXGI_FORMAT_R10G10B10A2_UNORM) if (hr == DXGI_ERROR_INVALID_CALL && scd.Format == DXGI_FORMAT_R10G10B10A2_UNORM)
{ {
msg_Warn(vd, "10 bits swapchain failed, try 8 bits"); msg_Warn(vd, "10 bits swapchain failed, try 8 bits");
scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice, hr = IDXGIFactory2_CreateSwapChainForHwnd(dxgifactory, (IUnknown *)sys->d3d_dev.d3ddevice,
sys->sys.hvideownd, &scd, NULL, NULL, &sys->dxgiswapChain); sys->sys.hvideownd, &scd, NULL, NULL, &sys->internal_swapchain.dxgiswapChain);
} }
IDXGIFactory2_Release(dxgifactory); IDXGIFactory2_Release(dxgifactory);
if (FAILED(hr)) { if (FAILED(hr)) {
...@@ -363,7 +371,7 @@ static int SetupWindowedOutput(vout_display_t *vd) ...@@ -363,7 +371,7 @@ static int SetupWindowedOutput(vout_display_t *vd)
return VLC_EGENERIC; return VLC_EGENERIC;
} }
IDXGISwapChain_QueryInterface( sys->dxgiswapChain, &IID_IDXGISwapChain4, (void **)&sys->dxgiswapChain4); IDXGISwapChain_QueryInterface( sys->internal_swapchain.dxgiswapChain, &IID_IDXGISwapChain4, (void **)&sys->internal_swapchain.dxgiswapChain4);
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#endif /* !VLC_WINSTORE_APP */ #endif /* !VLC_WINSTORE_APP */
...@@ -379,8 +387,8 @@ static int SetupWindowLessOutput(vout_display_t *vd) ...@@ -379,8 +387,8 @@ static int SetupWindowLessOutput(vout_display_t *vd)
if (!dxgiswapChain) if (!dxgiswapChain)
return VLC_EGENERIC; return VLC_EGENERIC;
sys->dxgiswapChain = dxgiswapChain; sys->internal_swapchain.dxgiswapChain = dxgiswapChain;
IDXGISwapChain_AddRef(sys->dxgiswapChain); IDXGISwapChain_AddRef(sys->internal_swapchain.dxgiswapChain);
if (FAILED(IDXGISwapChain1_GetDesc(dxgiswapChain, &scd))) if (FAILED(IDXGISwapChain1_GetDesc(dxgiswapChain, &scd)))
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -431,6 +439,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg, ...@@ -431,6 +439,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
bool uses_external_callbacks = true; bool uses_external_callbacks = true;
if (!sys->swapCb || !sys->starRenderCb || !sys->endRenderCb || !sys->resizeCb) if (!sys->swapCb || !sys->starRenderCb || !sys->endRenderCb || !sys->resizeCb)
{ {
sys->internal_swapchain.obj = VLC_OBJECT(vd);
sys->outside_opaque = vd; sys->outside_opaque = vd;
sys->swapCb = Swap; sys->swapCb = Swap;
sys->starRenderCb = StartRendering; sys->starRenderCb = StartRendering;
...@@ -818,7 +827,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t ...@@ -818,7 +827,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
{ {
D3D11_UpdateQuadLuminanceScale(vd, &sys->d3d_dev, &sys->picQuad, GetFormatLuminance(VLC_OBJECT(vd), &picture->format) / (float)sys->display.luminance_peak); D3D11_UpdateQuadLuminanceScale(vd, &sys->d3d_dev, &sys->picQuad, GetFormatLuminance(VLC_OBJECT(vd), &picture->format) / (float)sys->display.luminance_peak);
if (sys->dxgiswapChain4) if (sys->internal_swapchain.dxgiswapChain4)
{ {
DXGI_HDR_METADATA_HDR10 hdr10 = {0}; DXGI_HDR_METADATA_HDR10 hdr10 = {0};
hdr10.GreenPrimary[0] = picture->format.mastering.primaries[0]; hdr10.GreenPrimary[0] = picture->format.mastering.primaries[0];
...@@ -833,7 +842,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t ...@@ -833,7 +842,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
hdr10.MaxMasteringLuminance = picture->format.mastering.max_luminance; hdr10.MaxMasteringLuminance = picture->format.mastering.max_luminance;
hdr10.MaxContentLightLevel = picture->format.lighting.MaxCLL; hdr10.MaxContentLightLevel = picture->format.lighting.MaxCLL;
hdr10.MaxFrameAverageLightLevel = picture->format.lighting.MaxFALL; hdr10.MaxFrameAverageLightLevel = picture->format.lighting.MaxFALL;
IDXGISwapChain4_SetHDRMetaData(sys->dxgiswapChain4, DXGI_HDR_METADATA_TYPE_HDR10, sizeof(hdr10), &hdr10); IDXGISwapChain4_SetHDRMetaData(sys->internal_swapchain.dxgiswapChain4, DXGI_HDR_METADATA_TYPE_HDR10, sizeof(hdr10), &hdr10);
} }
} }
...@@ -847,7 +856,8 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t ...@@ -847,7 +856,8 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
} }
D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad,
vd->source.projection_mode == PROJECTION_MODE_RECTANGULAR ? &sys->flatVShader : &sys->projectionVShader, vd->source.projection_mode == PROJECTION_MODE_RECTANGULAR ? &sys->flatVShader : &sys->projectionVShader,
renderSrc, sys->swapchainTargetView); renderSrc,
sys->internal_swapchain.swapchainTargetView); /* NULL with external rendering */
if (subpicture) { if (subpicture) {
// draw the additional vertices // draw the additional vertices
...@@ -856,7 +866,8 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t ...@@ -856,7 +866,8 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
{ {
d3d_quad_t *quad = (d3d_quad_t *) sys->d3dregions[i]->p_sys; d3d_quad_t *quad = (d3d_quad_t *) sys->d3dregions[i]->p_sys;
D3D11_RenderQuad(&sys->d3d_dev, quad, &sys->flatVShader, D3D11_RenderQuad(&sys->d3d_dev, quad, &sys->flatVShader,
quad->picSys.renderSrc, sys->swapchainTargetView); quad->picSys.renderSrc,
sys->internal_swapchain.swapchainTargetView); /* NULL with external rendering */
} }
} }
} }
...@@ -887,10 +898,10 @@ static void Prepare(vout_display_t *vd, picture_t *picture, ...@@ -887,10 +898,10 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
uint32_t i_width; uint32_t i_width;
uint32_t i_height; uint32_t i_height;
UINT dataSize = sizeof(i_width); UINT dataSize = sizeof(i_width);
HRESULT hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width); HRESULT hr = IDXGISwapChain_GetPrivateData(sys->internal_swapchain.dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
dataSize = sizeof(i_height); dataSize = sizeof(i_height);
hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height); hr = IDXGISwapChain_GetPrivateData(sys->internal_swapchain.dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
if (i_width != sys->area.vdcfg.display.width || i_height != sys->area.vdcfg.display.height) if (i_width != sys->area.vdcfg.display.width || i_height != sys->area.vdcfg.display.height)
{ {
...@@ -988,7 +999,7 @@ static void D3D11SetColorSpace(vout_display_t *vd) ...@@ -988,7 +999,7 @@ static void D3D11SetColorSpace(vout_display_t *vd)
if (sys->sys.event == NULL) /* TODO support external colourspace handling */ if (sys->sys.event == NULL) /* TODO support external colourspace handling */
goto done; goto done;
hr = IDXGISwapChain_QueryInterface( sys->dxgiswapChain, &IID_IDXGISwapChain3, (void **)&dxgiswapChain3); hr = IDXGISwapChain_QueryInterface( sys->internal_swapchain.dxgiswapChain, &IID_IDXGISwapChain3, (void **)&dxgiswapChain3);
if (FAILED(hr)) { if (FAILED(hr)) {
msg_Warn(vd, "could not get a IDXGISwapChain3"); msg_Warn(vd, "could not get a IDXGISwapChain3");
goto done; goto done;
...@@ -1033,7 +1044,7 @@ static void D3D11SetColorSpace(vout_display_t *vd) ...@@ -1033,7 +1044,7 @@ static void D3D11SetColorSpace(vout_display_t *vd)
#ifdef HAVE_DXGI1_6_H #ifdef HAVE_DXGI1_6_H
IDXGIOutput *dxgiOutput = NULL; IDXGIOutput *dxgiOutput = NULL;
if (SUCCEEDED(IDXGISwapChain_GetContainingOutput( sys->dxgiswapChain, &dxgiOutput ))) if (SUCCEEDED(IDXGISwapChain_GetContainingOutput( sys->internal_swapchain.dxgiswapChain, &dxgiOutput )))
{ {
IDXGIOutput6 *dxgiOutput6 = NULL; IDXGIOutput6 *dxgiOutput6 = NULL;
if (SUCCEEDED(IDXGIOutput_QueryInterface( dxgiOutput, &IID_IDXGIOutput6, (void **)&dxgiOutput6 ))) if (SUCCEEDED(IDXGIOutput_QueryInterface( dxgiOutput, &IID_IDXGIOutput6, (void **)&dxgiOutput6 )))
...@@ -1312,15 +1323,16 @@ static void Direct3D11Close(vout_display_t *vd) ...@@ -1312,15 +1323,16 @@ static void Direct3D11Close(vout_display_t *vd)
vout_display_sys_t *sys = vd->sys; vout_display_sys_t *sys = vd->sys;
Direct3D11DestroyResources(vd); Direct3D11DestroyResources(vd);
if (sys->dxgiswapChain4)
if (sys->internal_swapchain.dxgiswapChain4)
{ {
IDXGISwapChain_Release(sys->dxgiswapChain4); IDXGISwapChain4_Release(sys->internal_swapchain.dxgiswapChain4);
sys->dxgiswapChain4 = NULL; sys->internal_swapchain.dxgiswapChain4 = NULL;
} }
if (sys->dxgiswapChain) if (sys->internal_swapchain.dxgiswapChain)
{ {
IDXGISwapChain_Release(sys->dxgiswapChain); IDXGISwapChain_Release(sys->internal_swapchain.dxgiswapChain);
sys->dxgiswapChain = NULL; sys->internal_swapchain.dxgiswapChain = NULL;
} }
D3D11_ReleaseDevice( &sys->d3d_dev ); D3D11_ReleaseDevice( &sys->d3d_dev );
...@@ -1607,11 +1619,11 @@ static void Direct3D11DestroyResources(vout_display_t *vd) ...@@ -1607,11 +1619,11 @@ static void Direct3D11DestroyResources(vout_display_t *vd)
D3D11_ReleaseVertexShader(&sys->projectionVShader); D3D11_ReleaseVertexShader(&sys->projectionVShader);
D3D11_ReleasePixelShader(&sys->regionQuad); D3D11_ReleasePixelShader(&sys->regionQuad);
for (size_t i=0; i < ARRAY_SIZE(sys->swapchainTargetView); i++) for (size_t i=0; i < ARRAY_SIZE(sys->internal_swapchain.swapchainTargetView); i++)
{ {
if (sys->swapchainTargetView[i]) { if (sys->internal_swapchain.swapchainTargetView[i]) {
ID3D11RenderTargetView_Release(sys->swapchainTargetView[i]); ID3D11RenderTargetView_Release(sys->internal_swapchain.swapchainTargetView[i]);
sys->swapchainTargetView[i] = NULL; sys->internal_swapchain.swapchainTargetView[i] = NULL;
} }
} }
if (sys->prepareWait) if (sys->prepareWait)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment