[vlc-commits] [Git][videolan/vlc][3.0.x] 6 commits: direct3d11: simplify the D3D11_RenderQuad call
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Wed May 8 14:00:35 UTC 2024
Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC
Commits:
fce580a4 by Steve Lhomme at 2024-05-07T11:57:00+02:00
direct3d11: simplify the D3D11_RenderQuad call
Only the ID3D11ShaderResourceView source may change.
- - - - -
71471002 by Steve Lhomme at 2024-05-07T14:09:17+02:00
d3d11_scaler: provide a picture_sys_t
Like d3d11_tonemapper does. It provides more flexibility.
- - - - -
52be95be by Steve Lhomme at 2024-05-07T14:09:17+02:00
direct3d11: use D3D11_UpscalerGetOutput to get the final picture_sys_t
- - - - -
ae050157 by Steve Lhomme at 2024-05-07T14:14:18+02:00
d3d11_tonemap: handle output resolution changes
- - - - -
267ba645 by Steve Lhomme at 2024-05-07T15:00:43+02:00
d3d11_tonemapper: factorize the texture creation
- - - - -
0d09617a by Steve Lhomme at 2024-05-07T15:00:48+02:00
direct3d11: do the SDR->HDR conversion after upscaling
The Super Resolution filter doesn't handle RGB10A2.
- - - - -
5 changed files:
- modules/video_output/win32/d3d11_scaler.cpp
- modules/video_output/win32/d3d11_scaler.h
- modules/video_output/win32/d3d11_tonemap.cpp
- modules/video_output/win32/d3d11_tonemap.h
- modules/video_output/win32/direct3d11.c
Changes:
=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -54,6 +54,8 @@ struct d3d11_scaler
ComPtr<ID3D11VideoProcessor> processor;
ComPtr<ID3D11VideoProcessorOutputView> outputView;
ID3D11ShaderResourceView *SRVs[D3D11_MAX_SHADER_VIEW] = {};
+ picture_sys_t picsys{};
+
#ifdef HAVE_AMF_SCALER
vlc_amf_context amf = {};
amf::AMFComponent *amf_scaler = nullptr;
@@ -242,6 +244,11 @@ static void ReleaseSRVs(d3d11_scaler *scaleProc)
}
}
+picture_sys_t *D3D11_UpscalerGetOutput(d3d11_scaler *scaleProc)
+{
+ return &scaleProc->picsys;
+}
+
int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device_t*d3d_dev,
const video_format_t *fmt, video_format_t *quad_fmt,
const vout_display_cfg_t *cfg)
@@ -440,6 +447,21 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
scaleProc->amf_initialized = true;
}
#endif
+
+ if (scaleProc->picsys.processorInput)
+ {
+ scaleProc->picsys.processorInput->Release();
+ scaleProc->picsys.processorInput = NULL;
+ }
+ if (scaleProc->picsys.processorOutput)
+ {
+ scaleProc->picsys.processorOutput->Release();
+ scaleProc->picsys.processorOutput = NULL;
+ }
+ scaleProc->picsys.texture[0] = upscaled.Get();
+ for (size_t i=0; i<ARRAY_SIZE(scaleProc->picsys.resourceView); i++)
+ scaleProc->picsys.resourceView[i] = scaleProc->SRVs[i];
+ scaleProc->picsys.formatTexture = texDesc.Format;
}
#ifdef HAVE_AMF_SCALER
=====================================
modules/video_output/win32/d3d11_scaler.h
=====================================
@@ -27,6 +27,7 @@ int D3D11_UpscalerUpdate(vlc_object_t *, struct d3d11_scaler *, d3d11_device_t*,
const vout_display_cfg_t *);
int D3D11_UpscalerScale(vlc_object_t *, struct d3d11_scaler *, picture_sys_t *);
bool D3D11_UpscalerUsed(const struct d3d11_scaler *);
+struct picture_sys_t *D3D11_UpscalerGetOutput(struct d3d11_scaler *);
void D3D11_UpscalerGetSRV(const struct d3d11_scaler *, ID3D11ShaderResourceView *SRV[D3D11_MAX_SHADER_VIEW]);
void D3D11_UpscalerGetSize(const struct d3d11_scaler *, unsigned *i_width, unsigned *i_height);
=====================================
modules/video_output/win32/d3d11_tonemap.cpp
=====================================
@@ -28,6 +28,12 @@ struct d3d11_tonemapper
ComPtr<ID3D11VideoProcessorOutputView> outputView;
ComPtr<ID3D11ShaderResourceView> SRV;
picture_sys_t picsys{};
+
+ const d3d_format_t *d3d_fmt = nullptr;
+ UINT Width = 0;
+ UINT Height = 0;
+
+ HRESULT UpdateTexture(vlc_object_t *, d3d11_device_t *, UINT width, UINT height);
};
d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, d3d11_device_t *d3d_dev,
@@ -45,13 +51,9 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, d3d11_device_t *d3d_d
return nullptr; // the source is already in HDR
}
- ComPtr<ID3D11Texture2D> texture;
- ID3D11Texture2D *_texture[D3D11_MAX_SHADER_VIEW] = {};
- D3D11_TEXTURE2D_DESC texDesc { };
- D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outDesc{ };
d3d11_tonemapper *tonemapProc = new d3d11_tonemapper();
- const auto d3d_fmt = D3D11_RenderFormat(DXGI_FORMAT_R10G10B10A2_UNORM, false);
- assert(d3d_fmt != nullptr);
+ tonemapProc->d3d_fmt = D3D11_RenderFormat(DXGI_FORMAT_R10G10B10A2_UNORM, false);
+ assert(tonemapProc->d3d_fmt != nullptr);
HRESULT hr;
hr = d3d_dev->d3ddevice->QueryInterface(IID_GRAPHICS_PPV_ARGS(&tonemapProc->d3dviddev));
@@ -141,6 +143,24 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, d3d11_device_t *d3d_d
d3d11_device_unlock(d3d_dev);
}
+ hr = tonemapProc->UpdateTexture(vd, d3d_dev, in->i_width, in->i_height);
+ if (FAILED(hr))
+ goto error;
+
+ return tonemapProc;
+error:
+ delete tonemapProc;
+ return nullptr;
+}
+
+HRESULT d3d11_tonemapper::UpdateTexture(vlc_object_t *vd, d3d11_device_t *d3d_dev, UINT width, UINT height)
+{
+ ComPtr<ID3D11Texture2D> texture;
+ D3D11_TEXTURE2D_DESC texDesc { };
+ D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outDesc{ };
+ ID3D11Texture2D *_texture[D3D11_MAX_SHADER_VIEW] = {};
+ HRESULT hr;
+
// we need a texture that will receive the upscale version
texDesc.MipLevels = 1;
texDesc.SampleDesc.Count = 1;
@@ -149,37 +169,46 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, d3d11_device_t *d3d_d
texDesc.CPUAccessFlags = 0;
texDesc.ArraySize = 1;
texDesc.Format = d3d_fmt->formatTexture;
- texDesc.Width = in->i_width;
- texDesc.Height = in->i_height;
+ texDesc.Width = width;
+ texDesc.Height = height;
texDesc.MiscFlags = 0;
hr = d3d_dev->d3ddevice->CreateTexture2D(&texDesc, nullptr, texture.GetAddressOf());
if (FAILED(hr))
{
msg_Err(vd, "Failed to create the tonemap texture. (hr=0x%lX)", hr);
- goto error;
+ return hr;
}
outDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
outDesc.Texture2D.MipSlice = 0;
- hr = tonemapProc->d3dviddev->CreateVideoProcessorOutputView(
- texture.Get(),
- tonemapProc->enumerator.Get(),
- &outDesc,
- tonemapProc->outputView.ReleaseAndGetAddressOf());
+ hr = d3dviddev->CreateVideoProcessorOutputView(texture.Get(),
+ enumerator.Get(),
+ &outDesc,
+ outputView.ReleaseAndGetAddressOf());
if (FAILED(hr))
{
msg_Dbg(vd,"Failed to create processor output. (hr=0x%lX)", hr);
- goto error;
+ return hr;
}
+ if (picsys.processorInput)
+ {
+ picsys.processorInput->Release();
+ picsys.processorInput = NULL;
+ }
+ if (picsys.processorOutput)
+ {
+ picsys.processorOutput->Release();
+ picsys.processorOutput = NULL;
+ }
_texture[0] = texture.Get();
_texture[1] = texture.Get();
_texture[2] = texture.Get();
_texture[3] = texture.Get();
if ((D3D11_AllocateShaderView)(vd, d3d_dev->d3ddevice, d3d_fmt,
- _texture, 0, tonemapProc->SRV.GetAddressOf()) != VLC_SUCCESS)
- goto error;
+ _texture, 0, SRV.ReleaseAndGetAddressOf()) != VLC_SUCCESS)
+ return hr;
{
RECT srcRect;
@@ -188,26 +217,25 @@ d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *vd, d3d11_device_t *d3d_d
srcRect.right = texDesc.Width;
srcRect.bottom = texDesc.Height;
- RECT dstRect = srcRect;
-
d3d11_device_lock(d3d_dev);
- tonemapProc->d3dvidctx->VideoProcessorSetStreamSourceRect(tonemapProc->processor.Get(),
+ d3dvidctx->VideoProcessorSetStreamSourceRect(processor.Get(),
0, TRUE, &srcRect);
- tonemapProc->d3dvidctx->VideoProcessorSetStreamDestRect(tonemapProc->processor.Get(),
- 0, TRUE, &dstRect);
+ d3dvidctx->VideoProcessorSetStreamDestRect(processor.Get(),
+ 0, TRUE, &srcRect);
d3d11_device_unlock(d3d_dev);
}
- tonemapProc->picsys.texture[0] = texture.Get();
- tonemapProc->picsys.resourceView[0] = tonemapProc->SRV.Get();
- tonemapProc->picsys.formatTexture = texDesc.Format;
+ picsys.texture[0] = texture.Get();
+ picsys.resourceView[0] = SRV.Get();
+ picsys.formatTexture = texDesc.Format;
- return tonemapProc;
-error:
- delete tonemapProc;
- return nullptr;
+ Width = texDesc.Width;
+ Height = texDesc.Height;
+ msg_Dbg(vd, "tonemap resolution %ux%u", Width, Height);
+
+ return S_OK;
}
void D3D11_TonemapperDestroy(d3d11_tonemapper *tonemapProc)
@@ -265,3 +293,51 @@ HRESULT D3D11_TonemapperProcess(vlc_object_t *vd, d3d11_tonemapper *tonemapProc,
msg_Err(vd, "Failed to render the texture. (hr=0x%lX)", hr);
return hr;
}
+
+int D3D11_TonemapperUpdate(vlc_object_t *vd, d3d11_tonemapper *tonemapProc, d3d11_device_t*d3d_dev,
+ video_format_t *quad_fmt)
+{
+ HRESULT hr;
+ ID3D11Texture2D *_texture[D3D11_MAX_SHADER_VIEW];
+ ComPtr<ID3D11Texture2D> texture;
+ D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outDesc{ };
+ D3D11_VIDEO_COLOR black{};
+ black.RGBA.A = 1.f;
+
+ unsigned out_width, out_height;
+ out_width = quad_fmt->i_width;
+ out_height = quad_fmt->i_height;
+
+ quad_fmt->i_sar_num = 1;
+ quad_fmt->i_sar_den = 1;
+ quad_fmt->b_color_range_full = true;
+
+ if (tonemapProc->Width == out_width && tonemapProc->Height == out_height)
+ // do nothing
+ return VLC_SUCCESS;
+
+ hr = tonemapProc->UpdateTexture(vd, d3d_dev, out_width, out_height);
+ if (FAILED(hr))
+ goto done_super;
+
+ RECT srcRect;
+ srcRect.left = 0;
+ srcRect.top = 0;
+ srcRect.right = tonemapProc->Width;
+ srcRect.bottom = tonemapProc->Height;
+
+ d3d11_device_lock(d3d_dev);
+ tonemapProc->d3dvidctx->VideoProcessorSetStreamSourceRect(tonemapProc->processor.Get(),
+ 0, TRUE, &srcRect);
+
+ tonemapProc->d3dvidctx->VideoProcessorSetStreamDestRect(tonemapProc->processor.Get(),
+ 0, TRUE, &srcRect);
+ d3d11_device_unlock(d3d_dev);
+
+ return VLC_SUCCESS;
+done_super:
+ tonemapProc->SRV.Reset();
+ tonemapProc->processor.Reset();
+ tonemapProc->enumerator.Reset();
+ return VLC_EGENERIC;
+}
=====================================
modules/video_output/win32/d3d11_tonemap.h
=====================================
@@ -23,6 +23,8 @@ struct d3d11_tonemapper;
struct d3d11_tonemapper *D3D11_TonemapperCreate(vlc_object_t *, d3d11_device_t *,
const video_format_t * in);
void D3D11_TonemapperDestroy(struct d3d11_tonemapper *);
+int D3D11_TonemapperUpdate(vlc_object_t *, struct d3d11_tonemapper *, d3d11_device_t*,
+ video_format_t *);
HRESULT D3D11_TonemapperProcess(vlc_object_t *, struct d3d11_tonemapper *, picture_sys_t *);
struct picture_sys_t *D3D11_TonemapperGetOutput(struct d3d11_tonemapper *);
=====================================
modules/video_output/win32/direct3d11.c
=====================================
@@ -650,6 +650,10 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
cfg.display.height = window_height;
D3D11_UpscalerUpdate(VLC_OBJECT(vd), sys->scaleProc, &sys->d3d_dev,
&sys->pool_fmt, &sys->quad_fmt, &cfg);
+
+ if (sys->tonemapProc)
+ D3D11_TonemapperUpdate(VLC_OBJECT(vd), sys->tonemapProc, &sys->d3d_dev,
+ &sys->quad_fmt);
}
D3D11_TEXTURE2D_DESC dsc = { 0 };
@@ -934,6 +938,10 @@ static int Control(vout_display_t *vd, int query, va_list args)
cfg.display.height = window_height;
D3D11_UpscalerUpdate(VLC_OBJECT(vd), sys->scaleProc, &sys->d3d_dev, &vd->source,
&sys->quad_fmt, &cfg);
+
+ if (sys->tonemapProc)
+ D3D11_TonemapperUpdate(VLC_OBJECT(vd), sys->tonemapProc, &sys->d3d_dev,
+ &sys->quad_fmt);
}
break;
}
@@ -1046,28 +1054,25 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
{
picture_sys_t *p_sys = ActivePictureSys(picture);
- D3D11_TEXTURE2D_DESC srcDesc;
- ID3D11Texture2D_GetDesc(p_sys->texture[KNOWN_DXGI_INDEX], &srcDesc);
-
if (is_d3d11_opaque(picture->format.i_chroma))
d3d11_device_lock( &sys->d3d_dev );
- if (sys->tonemapProc)
+ if (sys->scaleProc && D3D11_UpscalerUsed(sys->scaleProc))
{
- if (FAILED(D3D11_TonemapperProcess(VLC_OBJECT(vd), sys->tonemapProc, p_sys)))
+ if (D3D11_UpscalerScale(VLC_OBJECT(vd), sys->scaleProc, p_sys) != VLC_SUCCESS)
return;
- p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
+ p_sys = D3D11_UpscalerGetOutput(sys->scaleProc);
}
- if (sys->scaleProc && D3D11_UpscalerUsed(sys->scaleProc))
+ if (sys->tonemapProc)
{
- if (D3D11_UpscalerScale(VLC_OBJECT(vd), sys->scaleProc, p_sys) != VLC_SUCCESS)
+ if (FAILED(D3D11_TonemapperProcess(VLC_OBJECT(vd), sys->tonemapProc, p_sys)))
return;
- uint32_t witdh, height;
- D3D11_UpscalerGetSize(sys->scaleProc, &witdh, &height);
- srcDesc.Width = witdh;
- srcDesc.Height = height;
+ p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
}
+ D3D11_TEXTURE2D_DESC srcDesc;
+ ID3D11Texture2D_GetDesc(p_sys->texture[KNOWN_DXGI_INDEX], &srcDesc);
+
if (!is_d3d11_opaque(picture->format.i_chroma) || sys->legacy_shader) {
D3D11_TEXTURE2D_DESC texDesc;
if (!is_d3d11_opaque(picture->format.i_chroma))
@@ -1153,24 +1158,28 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
ID3D11DeviceContext_ClearDepthStencilView(sys->d3d_dev.d3dcontext, sys->d3ddepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
- /* Render the quad */
+ ID3D11ShaderResourceView *SRV[D3D11_MAX_SHADER_VIEW];
+ /* Render the quad using the last stage of processing */
if (!is_d3d11_opaque(picture->format.i_chroma) || sys->legacy_shader)
- D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, sys->stagingSys.resourceView, sys->d3drenderTargetView);
+ {
+ memcpy(SRV, sys->stagingSys.resourceView, sizeof(SRV));
+ }
+ else if (sys->tonemapProc)
+ {
+ picture_sys_t *p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
+ memcpy(SRV, p_sys->resourceView, sizeof(SRV));
+ }
else if (sys->scaleProc && D3D11_UpscalerUsed(sys->scaleProc))
{
- ID3D11ShaderResourceView *SRV[D3D11_MAX_SHADER_VIEW];
D3D11_UpscalerGetSRV(sys->scaleProc, SRV);
- D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, SRV, sys->d3drenderTargetView);
}
else
{
picture_sys_t *p_sys;
- if (sys->tonemapProc)
- p_sys = D3D11_TonemapperGetOutput(sys->tonemapProc);
- else
- p_sys = ActivePictureSys(picture);
- D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, p_sys->resourceView, sys->d3drenderTargetView);
+ p_sys = ActivePictureSys(picture);
+ memcpy(SRV, p_sys->resourceView, sizeof(SRV));
}
+ D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad, SRV, sys->d3drenderTargetView);
if (subpicture) {
// draw the additional vertices
@@ -1588,8 +1597,6 @@ static int Direct3D11Open(vout_display_t *vd, bool external_device)
return VLC_EGENERIC;
}
- InitTonemapProcessor(vd, &vd->source);
-
hr = IDXGIAdapter_GetParent(dxgiadapter, &IID_IDXGIFactory2, (void **)&dxgifactory);
IDXGIAdapter_Release(dxgiadapter);
if (FAILED(hr)) {
@@ -1773,21 +1780,6 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, video_form
// look for the requested pixel format first
const d3d_format_t *decoder_format = NULL;
- if (sys->hdrMode == hdr_Fake)
- {
- quad_fmt->i_chroma = VLC_CODEC_RGBA10;
- quad_fmt->primaries = sys->display.colorspace->primaries;
- quad_fmt->transfer = sys->display.colorspace->transfer;
- quad_fmt->space = sys->display.colorspace->color;
- quad_fmt->b_color_range_full = sys->display.colorspace->b_full_range;
-
- // request an input format that can be input of a VideoProcessor
- UINT supportFlags = D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT;
- if (is_d3d11_opaque(fmt->i_chroma))
- supportFlags |= D3D11_FORMAT_SUPPORT_DECODER_OUTPUT;
- decoder_format = FindD3D11Format( vd, &sys->d3d_dev, fmt->i_chroma, false, 0, 0, 0,
- is_d3d11_opaque(fmt->i_chroma), supportFlags );
- }
sys->picQuad.formatInfo = SelectOutputFormat(vd, quad_fmt, &decoder_format);
if ( !sys->picQuad.formatInfo )
@@ -1797,18 +1789,30 @@ static int SetupOutputFormat(vout_display_t *vd, video_format_t *fmt, video_form
}
sys->pool_d3dfmt = decoder_format ? decoder_format : sys->picQuad.formatInfo;
+ InitScaleProcessor(vd);
+
msg_Dbg( vd, "Using pixel format %s for chroma %4.4s", sys->pool_d3dfmt->name,
(char *)&fmt->i_chroma );
fmt->i_chroma = sys->pool_d3dfmt->fourcc;
DxgiFormatMask( sys->picQuad.formatInfo->formatTexture, fmt );
+ InitTonemapProcessor(vd, quad_fmt);
+
+ if (sys->hdrMode == hdr_Fake)
+ {
+ quad_fmt->i_chroma = VLC_CODEC_RGBA10;
+ quad_fmt->primaries = sys->display.colorspace->primaries;
+ quad_fmt->transfer = sys->display.colorspace->transfer;
+ quad_fmt->space = sys->display.colorspace->color;
+ quad_fmt->b_color_range_full = sys->display.colorspace->b_full_range;
+ sys->picQuad.formatInfo = SelectOutputFormat(vd, quad_fmt, &decoder_format);
+ }
+
/* check the region pixel format */
sys->d3dregion_format = GetBlendableFormat(vd, VLC_CODEC_RGBA);
if (!sys->d3dregion_format)
sys->d3dregion_format = GetBlendableFormat(vd, VLC_CODEC_BGRA);
- InitScaleProcessor(vd);
-
sys->legacy_shader = sys->d3d_dev.feature_level < D3D_FEATURE_LEVEL_10_0 ||
(sys->scaleProc == NULL && !CanUseTextureArray(vd)) ||
BogusZeroCopy(vd);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6f813f37e989d43da625fcdf8e63a28b06ca5bdb...0d09617ac88e492a6ced8971f3a6b3d6d5af3c02
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6f813f37e989d43da625fcdf8e63a28b06ca5bdb...0d09617ac88e492a6ced8971f3a6b3d6d5af3c02
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list