vlc | branch: master | Steve Lhomme <[email protected]> | Mon Oct 16 13:25:33 2017 +0200| [f4b05693ddb0f0c006b6275c26dc338dff6488cc] | committer: Jean-Baptiste Kempf
direct3d11: simplify the I420 handling Rather than use buffers in the GPU and then copy in the staging texture, use CPU buffers and copy in the staging texture from there. Fixes #18766 Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f4b05693ddb0f0c006b6275c26dc338dff6488cc --- modules/video_chroma/d3d11_fmt.h | 1 - modules/video_output/win32/direct3d11.c | 324 +++++++++++++------------------- 2 files changed, 131 insertions(+), 194 deletions(-) diff --git a/modules/video_chroma/d3d11_fmt.h b/modules/video_chroma/d3d11_fmt.h index db462111ba..d88c3d2419 100644 --- a/modules/video_chroma/d3d11_fmt.h +++ b/modules/video_chroma/d3d11_fmt.h @@ -46,7 +46,6 @@ struct picture_sys_t ID3D11VideoProcessorOutputView *processorOutput; /* when used as processor output */ ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW]; DXGI_FORMAT formatTexture; - bool mapped; }; #include "../codec/avcodec/va_surface.h" diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c index b8241f3df4..5914d65487 100644 --- a/modules/video_output/win32/direct3d11.c +++ b/modules/video_output/win32/direct3d11.c @@ -412,47 +412,6 @@ static void Direct3D11UnmapPoolTexture(picture_t *picture) ID3D11DeviceContext_Unmap(p_sys->context, p_sys->resource[KNOWN_DXGI_INDEX], 0); } -static int Direct3D11LockDirectTexture(picture_t *picture) -{ - picture_sys_t *p_sys = picture->p_sys; - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT hr; - D3D11_TEXTURE2D_DESC texDesc; - int i; - - for (i = 0; i < picture->i_planes; i++) { - hr = ID3D11DeviceContext_Map(p_sys->context, p_sys->resource[i], 0, D3D11_MAP_WRITE, 0, &mappedResource); - if( FAILED(hr) ) - break; - ID3D11Texture2D_GetDesc(p_sys->texture[i], &texDesc); - picture->p[i].p_pixels = mappedResource.pData; - picture->p[i].i_pitch = mappedResource.RowPitch; - picture->p[i].i_lines = texDesc.Height; - assert(picture->p[i].i_visible_pitch <= picture->p[i].i_pitch); - assert(picture->p[i].i_visible_lines <= picture->p[i].i_lines); - } - - if( FAILED(hr) ) - { - while (i-- > 0) - ID3D11DeviceContext_Unmap(p_sys->context, p_sys->resource[i+1], 0); - return VLC_EGENERIC; - } - - p_sys->mapped = true; - return VLC_SUCCESS; -} - -static void Direct3D11UnlockDirectTexture(picture_t *picture) -{ - picture_sys_t *p_sys = ActivePictureSys(picture); - if (p_sys->mapped) { - for (int i = 0; i < picture->i_planes; i++) - ID3D11DeviceContext_Unmap(p_sys->context, p_sys->resource[i], 0); - p_sys->mapped = false; - } -} - #if !VLC_WINSTORE_APP static int OpenHwnd(vout_display_t *vd) { @@ -623,9 +582,8 @@ static void Close(vlc_object_t *object) } static int AllocateTextures(vout_display_t *vd, const d3d_format_t *cfg, - video_format_t *fmt, unsigned pool_size, - ID3D11Texture2D *textures[], - bool pool_type_display) + const video_format_t *fmt, unsigned pool_size, + ID3D11Texture2D *textures[]) { vout_display_sys_t *sys = vd->sys; plane_t planes[PICTURE_PLANE_MAX]; @@ -637,13 +595,22 @@ 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.BindFlags = D3D11_BIND_SHADER_RESOURCE; + 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; + const vlc_chroma_description_t *p_chroma_desc = vlc_fourcc_GetChromaDescription( fmt->i_chroma ); if( !p_chroma_desc ) return VLC_EGENERIC; if (cfg->formatTexture == DXGI_FORMAT_UNKNOWN) { - int i_width_aligned = fmt->i_width; - int i_height_aligned = fmt->i_height; if (p_chroma_desc->plane_count == 0) { msg_Dbg(vd, "failed to get the pixel format planes for %4.4s", (char *)&fmt->i_chroma); @@ -656,47 +623,19 @@ static int AllocateTextures(vout_display_t *vd, const d3d_format_t *cfg, assert(cfg->resourceFormat[1] == cfg->resourceFormat[0]); assert(cfg->resourceFormat[2] == cfg->resourceFormat[0]); - if (pool_type_display) { - texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - texDesc.Usage = D3D11_USAGE_DEFAULT; - } else { - texDesc.Usage = D3D11_USAGE_STAGING; - texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - - /* align on 16 pixel boundaries */ - i_width_aligned = ( i_width_aligned + 15 ) & ~15; - i_height_aligned = ( i_height_aligned + 15 ) & ~15; - } - for( int i = 0; i < plane_count; i++ ) { plane_t *p = &planes[i]; - p->i_lines = i_height_aligned * p_chroma_desc->p[i].h.num / p_chroma_desc->p[i].h.den; + p->i_lines = fmt->i_height * p_chroma_desc->p[i].h.num / p_chroma_desc->p[i].h.den; p->i_visible_lines = fmt->i_visible_height * p_chroma_desc->p[i].h.num / p_chroma_desc->p[i].h.den; - p->i_pitch = i_width_aligned * p_chroma_desc->p[i].w.num / p_chroma_desc->p[i].w.den * p_chroma_desc->pixel_size; + p->i_pitch = fmt->i_width * p_chroma_desc->p[i].w.num / p_chroma_desc->p[i].w.den * p_chroma_desc->pixel_size; p->i_visible_pitch = fmt->i_visible_width * p_chroma_desc->p[i].w.num / p_chroma_desc->p[i].w.den * p_chroma_desc->pixel_size; p->i_pixel_pitch = p_chroma_desc->pixel_size; } - - if (!pool_type_display) { - assert( (planes[0].i_pitch % 16) == 0 ); - } - - texDesc.ArraySize = 1; } else { plane_count = 1; texDesc.Format = cfg->formatTexture; - texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - 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; @@ -767,9 +706,7 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size) ID3D11Texture2D *textures[pool_size * D3D11_MAX_SHADER_VIEW]; picture_t **pictures = NULL; picture_t *picture; - unsigned plane; unsigned picture_count = 0; - picture_pool_configuration_t pool_cfg = {}; if (sys->sys.pool) return sys->sys.pool; @@ -781,10 +718,6 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size) surface_fmt.i_width = sys->picQuad.i_width; surface_fmt.i_height = sys->picQuad.i_height; - if (AllocateTextures(vd, sys->picQuadConfig, &surface_fmt, pool_size, textures, - sys->picQuadConfig->formatTexture != DXGI_FORMAT_UNKNOWN)) - goto error; - if (!vd->info.is_slow) { HRESULT hr; ID3D10Multithread *pMultithread; @@ -795,44 +728,50 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size) } } - pictures = calloc(pool_size, sizeof(*pictures)); - if (!pictures) - goto error; + if (sys->picQuadConfig->formatTexture != DXGI_FORMAT_UNKNOWN) + { + if (AllocateTextures(vd, sys->picQuadConfig, &surface_fmt, pool_size, textures)) + goto error; - for (picture_count = 0; picture_count < pool_size; picture_count++) { - picture_sys_t *picsys = calloc(1, sizeof(*picsys)); - if (unlikely(picsys == NULL)) + pictures = calloc(pool_size, sizeof(*pictures)); + if (!pictures) goto error; - for (plane = 0; plane < D3D11_MAX_SHADER_VIEW; plane++) - picsys->texture[plane] = textures[picture_count * D3D11_MAX_SHADER_VIEW + plane]; + for (picture_count = 0; picture_count < pool_size; picture_count++) { + picture_sys_t *picsys = calloc(1, sizeof(*picsys)); + if (unlikely(picsys == NULL)) + goto error; - picsys->slice_index = picture_count; - picsys->formatTexture = sys->picQuadConfig->formatTexture; - picsys->context = sys->d3dcontext; + for (unsigned plane = 0; plane < D3D11_MAX_SHADER_VIEW; plane++) + picsys->texture[plane] = textures[picture_count * D3D11_MAX_SHADER_VIEW + plane]; - picture_resource_t resource = { - .p_sys = picsys, - .pf_destroy = DestroyDisplayPoolPicture, - }; + picsys->slice_index = picture_count; + picsys->formatTexture = sys->picQuadConfig->formatTexture; + picsys->context = sys->d3dcontext; - picture = picture_NewFromResource(&surface_fmt, &resource); - if (unlikely(picture == NULL)) { - free(picsys); - msg_Err( vd, "Failed to create picture %d in the pool.", picture_count ); - goto error; - } + picture_resource_t resource = { + .p_sys = picsys, + .pf_destroy = DestroyDisplayPoolPicture, + }; - pictures[picture_count] = picture; - /* each picture_t holds a ref to the context and release it on Destroy */ - ID3D11DeviceContext_AddRef(picsys->context); + picture = picture_NewFromResource(&surface_fmt, &resource); + if (unlikely(picture == NULL)) { + free(picsys); + msg_Err( vd, "Failed to create picture %d in the pool.", picture_count ); + goto error; + } + + pictures[picture_count] = picture; + /* each picture_t holds a ref to the context and release it on Destroy */ + ID3D11DeviceContext_AddRef(picsys->context); + } } #ifdef HAVE_ID3D11VIDEODECODER if (!is_d3d11_opaque(surface_fmt.i_chroma) || sys->legacy_shader) { /* we need a staging texture */ - if (AllocateTextures(vd, sys->picQuadConfig, &surface_fmt, 1, textures, true)) + if (AllocateTextures(vd, sys->picQuadConfig, &surface_fmt, 1, textures)) goto error; sys->picQuad.p_chroma_sampling = vlc_fourcc_GetChromaDescription( surface_fmt.i_chroma ); @@ -862,20 +801,25 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned pool_size) } if (sys->picQuadConfig->formatTexture == DXGI_FORMAT_UNKNOWN) + sys->sys.pool = picture_pool_NewFromFormat( &surface_fmt, pool_size ); + else { - pool_cfg.lock = Direct3D11LockDirectTexture; - pool_cfg.unlock = Direct3D11UnlockDirectTexture; - } - else if (vd->info.is_slow) { - pool_cfg.lock = Direct3D11MapPoolTexture; - //pool_cfg.unlock = Direct3D11UnmapPoolTexture; + picture_pool_configuration_t pool_cfg = { + .picture = pictures, + .picture_count = pool_size, + }; + if (vd->info.is_slow) { + pool_cfg.lock = Direct3D11MapPoolTexture; + //pool_cfg.unlock = Direct3D11UnmapPoolTexture; + } + sys->sys.pool = picture_pool_NewExtended( &pool_cfg ); } - pool_cfg.picture = pictures; - pool_cfg.picture_count = pool_size; - sys->sys.pool = picture_pool_NewExtended( &pool_cfg ); error: if (sys->sys.pool == NULL) { + picture_pool_configuration_t pool_cfg = { + .picture_count = 0, + }; if (pictures) { msg_Dbg(vd, "Failed to create the picture d3d11 pool"); for (unsigned i=0;i<picture_count; ++i) @@ -884,7 +828,6 @@ error: } /* create an empty pool to avoid crashing */ - pool_cfg.picture_count = 0; sys->sys.pool = picture_pool_NewExtended( &pool_cfg ); } else { msg_Dbg(vd, "D3D11 pool succeed with %d surfaces (%dx%d) context 0x%p", @@ -1254,92 +1197,87 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic { vout_display_sys_t *sys = vd->sys; - picture_sys_t *p_sys = ActivePictureSys(picture); - -#if defined(HAVE_ID3D11VIDEODECODER) - if (sys->context_lock != INVALID_HANDLE_VALUE && is_d3d11_opaque(picture->format.i_chroma)) - WaitForSingleObjectEx( sys->context_lock, INFINITE, FALSE ); -#endif - if (p_sys->formatTexture == DXGI_FORMAT_UNKNOWN) + if (sys->picQuadConfig->formatTexture == DXGI_FORMAT_UNKNOWN) { - Direct3D11UnlockDirectTexture(picture); - for (int plane = 0; plane < D3D11_MAX_SHADER_VIEW; plane++) - { - if (!p_sys->resource[plane]) - continue; + D3D11_MAPPED_SUBRESOURCE mappedResource; + D3D11_TEXTURE2D_DESC texDesc; + int i; + HRESULT hr; - unsigned int width = sys->picQuad.i_width; - unsigned int height = sys->picQuad.i_height; - unsigned int x_offset = picture->format.i_x_offset; - unsigned int y_offset = picture->format.i_y_offset; - x_offset = x_offset * sys->picQuad.p_chroma_sampling->p[plane].h.num / sys->picQuad.p_chroma_sampling->p[plane].h.den; - y_offset = y_offset * sys->picQuad.p_chroma_sampling->p[plane].w.num / sys->picQuad.p_chroma_sampling->p[plane].w.den; - width = width * sys->picQuad.p_chroma_sampling->p[plane].h.num / sys->picQuad.p_chroma_sampling->p[plane].h.den; - height = height * sys->picQuad.p_chroma_sampling->p[plane].w.num / sys->picQuad.p_chroma_sampling->p[plane].w.den; + for (i = 0; i < picture->i_planes; i++) { + hr = ID3D11DeviceContext_Map(sys->d3dcontext, sys->stagingSys.resource[i], + 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if( FAILED(hr) ) + break; + ID3D11Texture2D_GetDesc(sys->stagingSys.texture[i], &texDesc); + plane_t texture_plane; + texture_plane.i_lines = texDesc.Height; + texture_plane.i_pitch = mappedResource.RowPitch; + texture_plane.p_pixels = mappedResource.pData; + texture_plane.i_visible_lines = picture->p[i].i_visible_lines; + texture_plane.i_visible_pitch = picture->p[i].i_visible_pitch; + plane_CopyPixels(&texture_plane, &picture->p[i]); + ID3D11DeviceContext_Unmap(sys->d3dcontext, sys->stagingSys.resource[i], 0); + } + } + else + { + picture_sys_t *p_sys = ActivePictureSys(picture); +#if defined(HAVE_ID3D11VIDEODECODER) + if (sys->context_lock != INVALID_HANDLE_VALUE && is_d3d11_opaque(picture->format.i_chroma)) + WaitForSingleObjectEx( sys->context_lock, INFINITE, FALSE ); +#endif + if (!is_d3d11_opaque(picture->format.i_chroma) || sys->legacy_shader) { + D3D11_TEXTURE2D_DESC texDesc; + if (!is_d3d11_opaque(picture->format.i_chroma)) + Direct3D11UnmapPoolTexture(picture); + ID3D11Texture2D_GetDesc(sys->stagingSys.texture[0], &texDesc); D3D11_BOX box = { - .top = y_offset, - .bottom = y_offset + height, - .left = x_offset, - .right = x_offset + width, + .top = 0, + .bottom = picture->format.i_y_offset + picture->format.i_visible_height, + .left = 0, + .right = picture->format.i_x_offset + picture->format.i_visible_width, .back = 1, }; + if ( sys->picQuadConfig->formatTexture != DXGI_FORMAT_R8G8B8A8_UNORM && + sys->picQuadConfig->formatTexture != DXGI_FORMAT_B5G6R5_UNORM ) + { + box.bottom = (box.bottom + 0x01) & ~0x01; + box.right = (box.right + 0x01) & ~0x01; + } + assert(box.right <= texDesc.Width); + assert(box.bottom <= texDesc.Height); ID3D11DeviceContext_CopySubresourceRegion(sys->d3dcontext, - sys->stagingSys.resource[plane], + sys->stagingSys.resource[KNOWN_DXGI_INDEX], 0, 0, 0, 0, - p_sys->resource[plane], - 0, &box); - } - } - else if (!is_d3d11_opaque(picture->format.i_chroma) || sys->legacy_shader) { - D3D11_TEXTURE2D_DESC texDesc; - if (!is_d3d11_opaque(picture->format.i_chroma)) - Direct3D11UnmapPoolTexture(picture); - ID3D11Texture2D_GetDesc(sys->stagingSys.texture[0], &texDesc); - D3D11_BOX box = { - .top = 0, - .bottom = picture->format.i_y_offset + picture->format.i_visible_height, - .left = 0, - .right = picture->format.i_x_offset + picture->format.i_visible_width, - .back = 1, - }; - if ( sys->picQuadConfig->formatTexture != DXGI_FORMAT_R8G8B8A8_UNORM && - sys->picQuadConfig->formatTexture != DXGI_FORMAT_B5G6R5_UNORM ) - { - box.bottom = (box.bottom + 0x01) & ~0x01; - box.right = (box.right + 0x01) & ~0x01; + p_sys->resource[KNOWN_DXGI_INDEX], + p_sys->slice_index, &box); } - assert(box.right <= texDesc.Width); - assert(box.bottom <= texDesc.Height); - ID3D11DeviceContext_CopySubresourceRegion(sys->d3dcontext, - sys->stagingSys.resource[KNOWN_DXGI_INDEX], - 0, 0, 0, 0, - p_sys->resource[KNOWN_DXGI_INDEX], - p_sys->slice_index, &box); - } - else - { - D3D11_TEXTURE2D_DESC texDesc; - ID3D11Texture2D_GetDesc(p_sys->texture[0], &texDesc); - if (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + else { - /* for performance reason we don't want to allocate this during - * display, do it preferrably when creating the texture */ - assert(p_sys->resourceView[0]!=NULL); - } + D3D11_TEXTURE2D_DESC texDesc; + ID3D11Texture2D_GetDesc(p_sys->texture[0], &texDesc); + if (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + { + /* for performance reason we don't want to allocate this during + * display, do it preferrably when creating the texture */ + assert(p_sys->resourceView[0]!=NULL); + } - if ( sys->picQuad.i_height != texDesc.Height || - sys->picQuad.i_width != texDesc.Width ) - { - /* the decoder produced different sizes than the vout, we need to - * adjust the vertex */ - sys->picQuad.i_height = texDesc.Height; - sys->picQuad.i_width = texDesc.Width; - - BEFORE_UPDATE_RECTS; - UpdateRects(vd, NULL, true); - AFTER_UPDATE_RECTS; - UpdateSize(vd); + if ( sys->picQuad.i_height != texDesc.Height || + sys->picQuad.i_width != texDesc.Width ) + { + /* the decoder produced different sizes than the vout, we need to + * adjust the vertex */ + sys->picQuad.i_height = texDesc.Height; + sys->picQuad.i_width = texDesc.Width; + + BEFORE_UPDATE_RECTS; + UpdateRects(vd, NULL, true); + AFTER_UPDATE_RECTS; + UpdateSize(vd); + } } } @@ -3051,7 +2989,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, true)) { + if (AllocateTextures(vd, sys->d3dregion_format, &r->fmt, 1, textures)) { 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++) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
