[vlc-devel] [PATCH 3/5] direct3d11: handle separate pools for decoder/display/filters
Steve Lhomme
robux4 at videolabs.io
Tue Mar 28 16:23:58 CEST 2017
---
modules/video_output/win32/direct3d11.c | 164 ++++++++++++++++++++------------
1 file changed, 102 insertions(+), 62 deletions(-)
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 0cac84e6ac..6b9b17ddc4 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -125,6 +125,8 @@ struct vout_display_sys_t
{
vout_display_sys_win32_t sys;
+ picture_pool_t *pools[VOUT_POOL_COUNT];
+
struct { /* TODO may go in vout_display_info_t without DXGI */
const dxgi_color_space *colorspace;
unsigned luminance_peak;
@@ -535,6 +537,8 @@ static int Open(vlc_object_t *object)
video_format_Clean(&vd->fmt);
video_format_Copy(&vd->fmt, &fmt);
+ vd->info.typed_pools = true;
+ vd->info.can_display_decoder = true;
vd->info.has_double_click = true;
vd->info.has_hide_mouse = false;
vd->info.has_pictures_invalid = vd->info.is_slow;
@@ -658,7 +662,8 @@ static int AllocateShaderView(vout_display_t *vd, const d3d_format_t *format,
static int AllocateTextures(vout_display_t *vd, const d3d_format_t *cfg,
video_format_t *fmt, unsigned pool_size,
- ID3D11Texture2D *textures[])
+ ID3D11Texture2D *textures[],
+ vout_display_pool_t pool_type)
{
vout_display_sys_t *sys = vd->sys;
int plane;
@@ -669,33 +674,55 @@ static int AllocateTextures(vout_display_t *vd, const d3d_format_t *cfg,
texDesc.MipLevels = 1;
texDesc.SampleDesc.Count = 1;
texDesc.MiscFlags = 0; //D3D11_RESOURCE_MISC_SHARED;
- texDesc.Usage = D3D11_USAGE_DEFAULT;
- texDesc.CPUAccessFlags = 0;
texDesc.Format = cfg->formatTexture;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ if (pool_type == VOUT_POOL_DECODER) {
+ if (is_d3d11_opaque(fmt->i_chroma)) {
+ texDesc.BindFlags |= D3D11_BIND_DECODER;
+ }
+ } else if (is_d3d11_opaque(fmt->i_chroma)) {
+ texDesc.BindFlags |= D3D11_BIND_RENDER_TARGET;
+ }
if (is_d3d11_opaque(fmt->i_chroma)) {
- texDesc.BindFlags |= D3D11_BIND_DECODER;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.CPUAccessFlags = 0;
} else {
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
}
- texDesc.ArraySize = pool_size;
texDesc.Height = fmt->i_height;
texDesc.Width = fmt->i_width;
- hr = ID3D11Device_CreateTexture2D( sys->d3ddevice, &texDesc, NULL, &slicedTexture );
- if (FAILED(hr)) {
- msg_Err(vd, "CreateTexture2D failed for the %d pool. (hr=0x%0lx)", pool_size, hr);
- goto error;
+ /* use only a sliced texture for the decoder pool, otherwise a texture
+ * per picture */
+ if (pool_type != VOUT_POOL_DECODER)
+ texDesc.ArraySize = 1;
+ else
+ {
+ texDesc.ArraySize = pool_size;
+ hr = ID3D11Device_CreateTexture2D( sys->d3ddevice, &texDesc, NULL, &slicedTexture );
+ if (FAILED(hr)) {
+ msg_Err(vd, "CreateTexture2D failed for the %d pool of %d textures. (hr=0x%0lx)", pool_type, pool_size, hr);
+ goto error;
+ }
}
for (unsigned picture_count = 0; picture_count < pool_size; picture_count++) {
- textures[picture_count * D3D11_MAX_SHADER_VIEW] = slicedTexture;
- ID3D11Texture2D_AddRef(slicedTexture);
-
- for (plane = 1; plane < D3D11_MAX_SHADER_VIEW; plane++) {
+ for (plane = 0; plane < 1; plane++) {
+ if (!cfg->resourceFormat[plane])
+ textures[picture_count * D3D11_MAX_SHADER_VIEW + plane] = NULL;
+ else if (slicedTexture) {
+ textures[picture_count * D3D11_MAX_SHADER_VIEW + plane] = slicedTexture;
+ ID3D11Texture2D_AddRef(slicedTexture);
+ } else {
+ hr = ID3D11Device_CreateTexture2D( sys->d3ddevice, &texDesc, NULL, &textures[picture_count * D3D11_MAX_SHADER_VIEW + plane] );
+ if (FAILED(hr)) {
+ msg_Err(vd, "CreateTexture2D failed for the %d pool of %d textures, plane %d. (hr=0x%0lx)", pool_type, pool_size, plane, hr);
+ goto error;
+ }
+ }
+ }
+ for (; plane < D3D11_MAX_SHADER_VIEW; plane++) {
if (!cfg->resourceFormat[plane])
textures[picture_count * D3D11_MAX_SHADER_VIEW + plane] = NULL;
else
@@ -745,10 +772,14 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size, vout_display
if (sys->sys.pool)
return sys->sys.pool;
+ if (sys->pools[type] != NULL)
+ return sys->pools[type];
+
if (vd->info.is_slow)
pool_size = 1;
- if (AllocateTextures(vd, sys->picQuadConfig, &vd->fmt, pool_size, textures))
+ if (AllocateTextures(vd, sys->picQuadConfig, &vd->fmt, pool_size, textures,
+ type))
goto error;
if (vd->info.is_slow) {
@@ -785,7 +816,10 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size, vout_display
for (plane = 0; plane < D3D11_MAX_SHADER_VIEW; plane++)
picsys->texture[plane] = textures[picture_count * D3D11_MAX_SHADER_VIEW + plane];
- picsys->slice_index = picture_count;
+ if (type == VOUT_POOL_DECODER)
+ picsys->slice_index = picture_count;
+ else
+ picsys->slice_index = 0;
picsys->formatTexture = sys->picQuadConfig->formatTexture;
picsys->context = sys->d3dcontext;
@@ -807,51 +841,55 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size, vout_display
}
#ifdef HAVE_ID3D11VIDEODECODER
- if (!is_d3d11_opaque(vd->fmt.i_chroma) || sys->legacy_shader)
+ if (type == VOUT_POOL_DISPLAY)
{
- /* we need a staging texture */
- video_format_t staging_fmt;
- video_format_Copy(&staging_fmt, &vd->fmt);
- staging_fmt.i_width = staging_fmt.i_visible_width;
- staging_fmt.i_height = staging_fmt.i_visible_height;
- if ( sys->picQuadConfig->formatTexture == DXGI_FORMAT_NV12 ||
- sys->picQuadConfig->formatTexture == DXGI_FORMAT_P010 )
+ if (!is_d3d11_opaque(vd->fmt.i_chroma) || sys->legacy_shader)
{
- staging_fmt.i_width = (staging_fmt.i_width + 1) & ~1;
- staging_fmt.i_height = (staging_fmt.i_height + 1) & ~1;
- }
- if (AllocateTextures(vd, sys->picQuadConfig, &staging_fmt, 1, textures))
- goto error;
-
- sys->picQuad.i_x_offset = 0;
- sys->picQuad.i_y_offset = 0;
- sys->picQuad.i_width = staging_fmt.i_width;
- sys->picQuad.i_height = staging_fmt.i_height;
+ /* we need a staging texture */
+ video_format_t staging_fmt;
+ video_format_Copy(&staging_fmt, &vd->fmt);
+ staging_fmt.i_width = staging_fmt.i_visible_width;
+ staging_fmt.i_height = staging_fmt.i_visible_height;
+ if ( sys->picQuadConfig->formatTexture == DXGI_FORMAT_NV12 ||
+ sys->picQuadConfig->formatTexture == DXGI_FORMAT_P010 )
+ {
+ staging_fmt.i_width = (staging_fmt.i_width + 1) & ~1;
+ staging_fmt.i_height = (staging_fmt.i_height + 1) & ~1;
+ }
+ if (AllocateTextures(vd, sys->picQuadConfig, &staging_fmt, 1, textures, type))
+ goto error;
- for (unsigned plane = 0; plane < D3D11_MAX_SHADER_VIEW; plane++)
- sys->stagingSys.texture[plane] = textures[plane];
+ sys->picQuad.i_x_offset = 0;
+ sys->picQuad.i_y_offset = 0;
+ sys->picQuad.i_width = staging_fmt.i_width;
+ sys->picQuad.i_height = staging_fmt.i_height;
- if (AllocateShaderView(vd, sys->picQuadConfig, 0, &sys->stagingSys))
- goto error;
- } else
-#endif
- {
- sys->picQuad.i_x_offset = vd->fmt.i_x_offset;
- sys->picQuad.i_y_offset = vd->fmt.i_y_offset;
- sys->picQuad.i_width = vd->fmt.i_width;
- sys->picQuad.i_height = vd->fmt.i_height;
+ for (unsigned plane = 0; plane < D3D11_MAX_SHADER_VIEW; plane++)
+ sys->stagingSys.texture[plane] = textures[plane];
- for (picture_count = 0; picture_count < pool_size; picture_count++) {
- if (AllocateShaderView(vd, sys->picQuadConfig, picture_count, pictures[picture_count]->p_sys))
+ if (AllocateShaderView(vd, sys->picQuadConfig, 0, &sys->stagingSys))
goto error;
}
- }
+ else
+ {
+ sys->picQuad.i_x_offset = vd->fmt.i_x_offset;
+ sys->picQuad.i_y_offset = vd->fmt.i_y_offset;
+ sys->picQuad.i_width = vd->fmt.i_width;
+ sys->picQuad.i_height = vd->fmt.i_height;
+
+ for (picture_count = 0; picture_count < pool_size; picture_count++) {
+ if (AllocateShaderView(vd, sys->picQuadConfig, picture_count, pictures[picture_count]->p_sys))
+ goto error;
+ }
+ }
- if (SetupQuad( vd, &vd->fmt, &sys->picQuad, sys->picQuadConfig, sys->picQuadPixelShader,
- vd->fmt.projection_mode) != VLC_SUCCESS) {
- msg_Err(vd, "Could not Create the main quad picture.");
- return NULL;
+ if (SetupQuad( vd, &vd->fmt, &sys->picQuad, sys->picQuadConfig, sys->picQuadPixelShader,
+ vd->fmt.projection_mode) != VLC_SUCCESS) {
+ msg_Err(vd, "Could not Create the main quad picture.");
+ return NULL;
+ }
}
+#endif
if (vd->info.is_slow) {
pool_cfg.lock = Direct3D11MapPoolTexture;
@@ -859,25 +897,21 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size, vout_display
}
pool_cfg.picture = pictures;
pool_cfg.picture_count = pool_size;
- sys->sys.pool = picture_pool_NewExtended( &pool_cfg );
+ sys->pools[type] = picture_pool_NewExtended( &pool_cfg );
error:
- if (sys->sys.pool == NULL) {
+ if (sys->pools[type] == NULL) {
if (pictures) {
msg_Dbg(vd, "Failed to create the picture d3d11 pool");
for (unsigned i=0;i<picture_count; ++i)
picture_Release(pictures[i]);
free(pictures);
}
-
- /* create an empty pool to avoid crashing */
- pool_cfg.picture_count = 0;
- sys->sys.pool = picture_pool_NewExtended( &pool_cfg );
} else {
- msg_Dbg(vd, "ID3D11VideoDecoderOutputView succeed with %d surfaces (%dx%d) context 0x%p",
- picture_count, vd->fmt.i_width, vd->fmt.i_height, sys->d3dcontext);
+ msg_Dbg(vd, "pool[%d] succeed with %d surfaces (%dx%d) context 0x%p",
+ type, picture_count, vd->fmt.i_width, vd->fmt.i_height, sys->d3dcontext);
}
- return sys->sys.pool;
+ return sys->pools[type];
}
static void ReleasePictureResources(picture_sys_t *p_sys)
@@ -2249,9 +2283,15 @@ static void Direct3D11DestroyPool(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
+ if (sys->pools[VOUT_POOL_DISPLAY])
+ picture_pool_Release(sys->pools[VOUT_POOL_DISPLAY]);
+ for (int i=0;i<VOUT_POOL_COUNT; ++i)
+ sys->pools[i] = NULL;
if (sys->sys.pool)
+ {
picture_pool_Release(sys->sys.pool);
- sys->sys.pool = NULL;
+ sys->sys.pool = NULL;
+ }
}
static void SetupQuadFlat(d3d_vertex_t *dst_data, const video_format_t *fmt, d3d_quad_t *quad, WORD *triangle_pos)
@@ -2767,7 +2807,7 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
if (unlikely(d3dquad==NULL)) {
continue;
}
- if (AllocateTextures(vd, sys->d3dregion_format, &r->fmt, 1, textures)) {
+ if (AllocateTextures(vd, sys->d3dregion_format, &r->fmt, 1, textures, VOUT_POOL_DISPLAY)) {
msg_Err(vd, "Failed to allocate %dx%d texture for OSD",
r->fmt.i_visible_width, r->fmt.i_visible_height);
for (int i=0; i<D3D11_MAX_SHADER_VIEW; i++)
--
2.11.1
More information about the vlc-devel
mailing list