/***************************************************************************** * d3d11_fmt.h : D3D11 helper calls ***************************************************************************** * Copyright © 2017 VLC authors, VideoLAN and VideoLabs * * Authors: Steve Lhomme * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifndef VLC_VIDEOCHROMA_D3D11_FMT_H_ #define VLC_VIDEOCHROMA_D3D11_FMT_H_ #include #include #include "dxgi_fmt.h" #ifdef __cplusplus extern "C" { #ifndef IID_GRAPHICS_PPV_ARGS #define IID_GRAPHICS_PPV_ARGS(ppType) IID_PPV_ARGS(ppType) #endif #endif DEFINE_GUID(GUID_CONTEXT_MUTEX, 0x472e8835, 0x3f8e, 0x4f93, 0xa0, 0xcb, 0x25, 0x79, 0x77, 0x6c, 0xed, 0x86); /* see https://msdn.microsoft.com/windows/hardware/commercialize/design/compatibility/device-graphics */ struct wddm_version { int wddm, d3d_features, revision, build; }; typedef struct { ID3D11Device *d3ddevice; /* D3D device */ ID3D11DeviceContext *d3dcontext; /* D3D context */ bool owner; HANDLE context_mutex; struct wddm_version WDDM; D3D_FEATURE_LEVEL feature_level; DXGI_ADAPTER_DESC adapterDesc; } d3d11_device_t; typedef struct { #if !VLC_WINSTORE_APP HINSTANCE hdll; /* handle of the opened d3d11 dll */ HINSTANCE compiler_dll; /* handle of the opened d3dcompiler dll */ pD3DCompile OurD3DCompile; #if !defined(NDEBUG) && defined(HAVE_DXGIDEBUG_H) HINSTANCE dxgidebug_dll; HRESULT (WINAPI * pf_DXGIGetDebugInterface)(const GUID *riid, void **ppDebug); #endif #endif } d3d11_handle_t; /* owned by the vout for VLC_CODEC_D3D11_OPAQUE */ struct picture_sys_t { ID3D11VideoDecoderOutputView *decoder; /* may be NULL for pictures from the pool */ union { ID3D11Texture2D *texture[D3D11_MAX_SHADER_VIEW]; ID3D11Resource *resource[D3D11_MAX_SHADER_VIEW]; }; ID3D11DeviceContext *context; unsigned slice_index; ID3D11VideoProcessorInputView *processorInput; /* when used as processor input */ ID3D11VideoProcessorOutputView *processorOutput; /* when used as processor output */ ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW]; DXGI_FORMAT formatTexture; }; #include "../codec/avcodec/va_surface.h" picture_sys_t *ActivePictureSys(picture_t *p_pic); /* index to use for texture/resource that use a known DXGI format * (ie not DXGI_FORMAT_UNKNWON) */ #define KNOWN_DXGI_INDEX 0 static inline bool is_d3d11_opaque(vlc_fourcc_t chroma) { return chroma == VLC_CODEC_D3D11_OPAQUE || chroma == VLC_CODEC_D3D11_OPAQUE_10B; } void AcquirePictureSys(picture_sys_t *p_sys); void ReleasePictureSys(picture_sys_t *p_sys); /* map texture planes to resource views */ int D3D11_AllocateShaderView(vlc_object_t *obj, ID3D11Device *d3ddevice, const d3d_format_t *format, ID3D11Texture2D *p_texture[D3D11_MAX_SHADER_VIEW], UINT slice_index, ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW]); #define D3D11_AllocateShaderView(a,b,c,d,e,f) D3D11_AllocateShaderView(VLC_OBJECT(a),b,c,d,e,f) HRESULT D3D11_CreateDevice(vlc_object_t *obj, d3d11_handle_t *, bool hw_decoding, d3d11_device_t *out); #define D3D11_CreateDevice(a,b,c,d) D3D11_CreateDevice( VLC_OBJECT(a), b, c, d ) void D3D11_ReleaseDevice(d3d11_device_t *); int D3D11_Create(vlc_object_t *, d3d11_handle_t *, bool with_shaders); #define D3D11_Create(a,b,c) D3D11_Create( VLC_OBJECT(a), b, c ) void D3D11_Destroy(d3d11_handle_t *); void D3D11_LogResources(d3d11_handle_t *); bool isXboxHardware(const d3d11_device_t *); bool CanUseVoutPool(d3d11_device_t *, UINT slices); IDXGIAdapter *D3D11DeviceAdapter(ID3D11Device *d3ddev); int D3D11CheckDriverVersion(const d3d11_device_t *, UINT vendorId, const struct wddm_version *min_ver); void D3D11_GetDriverVersion(vlc_object_t *, d3d11_device_t *); #define D3D11_GetDriverVersion(a,b) D3D11_GetDriverVersion(VLC_OBJECT(a),b) bool DeviceSupportsFormat(ID3D11Device *d3ddevice, DXGI_FORMAT format, UINT supportFlags); const d3d_format_t *FindD3D11Format(vlc_object_t *, d3d11_device_t*, vlc_fourcc_t i_src_chroma, bool rgb_only, uint8_t bits_per_channel, uint8_t widthDenominator, uint8_t heightDenominator, bool allow_opaque, UINT supportFlags); #define FindD3D11Format(a,b,c,d,e,f,g,h,i) \ FindD3D11Format(VLC_OBJECT(a),b,c,d,e,f,g,h,i) static inline const d3d_format_t *D3D11_RenderFormat(DXGI_FORMAT opaque, bool gpu_based) { for (const d3d_format_t *output_format = GetRenderFormatList(); output_format->name != NULL; ++output_format) { if (output_format->formatTexture == opaque && is_d3d11_opaque(output_format->fourcc) == gpu_based) { return output_format; } } return NULL; } int AllocateTextures(vlc_object_t *, d3d11_device_t *, const d3d_format_t *, const video_format_t *, unsigned pool_size, ID3D11Texture2D *textures[]); #define AllocateTextures(a,b,c,d,e,f) AllocateTextures(VLC_OBJECT(a),b,c,d,e,f) #ifndef NDEBUG void D3D11_LogProcessorSupport(vlc_object_t*, ID3D11VideoProcessorEnumerator*); #define D3D11_LogProcessorSupport(a,b) D3D11_LogProcessorSupport( VLC_OBJECT(a), b ) #endif static inline void d3d11_device_lock(d3d11_device_t *d3d_dev) { if( d3d_dev->context_mutex != INVALID_HANDLE_VALUE ) WaitForSingleObjectEx( d3d_dev->context_mutex, INFINITE, FALSE ); } static inline void d3d11_device_unlock(d3d11_device_t *d3d_dev) { if( d3d_dev->context_mutex != INVALID_HANDLE_VALUE ) ReleaseMutex( d3d_dev->context_mutex ); } #ifdef __cplusplus } #endif #endif /* include-guard */