Changeset 108229 in vbox
- Timestamp:
- Feb 14, 2025 5:47:02 PM (2 months ago)
- svn:sync-xref-src-repo-rev:
- 167549
- Location:
- trunk/src/libs/dxvk-2.3.1
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/dxvk-2.3.1/Makefile.kmk
r108118 r108229 56 56 VBOX_DXVK_CXXFLAGS_WIN += -wd5204 # class has virtual functions, but its trivial destructor is not virtual 57 57 VBOX_DXVK_CXXFLAGS_WIN += -wd5219 # implicit conversion from 'int' to 'float', possible loss of data 58 VBOX_DXVK_CXXFLAGS_WIN += -wd5246 # 'anonymous struct or union': the initialization of a subobject should be wrapped in braces 59 VBOX_DXVK_CXXFLAGS_WIN += -wd5249 # '_DXVA_ExtendedFormat::NominalRange' of type 'DXVA_NominalRange' has named enumerators with values that cannot be represented in the given bit field width of '3'. 58 60 VBOX_DXVK_CXXFLAGS_WIN += -wd5264 # 'MaxPendingSubmits': 'const' variable is not used 59 61 VBOX_DXVK_CXXFLAGS_WIN += -wd5267 # definition of implicit copy constructor for 'dxvk::DxvkSparseBindSubmission' is deprecated because it has a user-provided destructor 60 62 else 61 63 VBOX_DXVK_PLATFORM = DXVK_PLATFORM_LINUX 64 endif 65 66 VBOX_DXVK_COMMON_DEFINES = 67 ifdef VBOX_WITH_DXVK_VIDEO 68 VBOX_DXVK_COMMON_DEFINES += \ 69 VBOX_WITH_DXVK_VIDEO 62 70 endif 63 71 … … 98 106 VBox-DxVkNativeUtil_TEMPLATE = VBoxR3DllNonPedantic 99 107 VBox-DxVkNativeUtil_DEFS = \ 108 $(VBOX_DXVK_COMMON_DEFINES) \ 100 109 DXVK_NATIVE \ 101 110 NOMINMAX \ … … 191 200 VBox-DxVkNativeDxVk_TEMPLATE = VBoxR3DllNonPedantic 192 201 VBox-DxVkNativeDxVk_DEFS = \ 202 $(VBOX_DXVK_COMMON_DEFINES) \ 193 203 DXVK_NATIVE \ 194 204 NOMINMAX \ … … 266 276 src/dxvk/hud/dxvk_hud_renderer.cpp \ 267 277 src/dxvk/platform/dxvk_headless_exts.cpp 278 ifdef VBOX_WITH_DXVK_VIDEO 279 VBox-DxVkNativeDxVk_SOURCES += \ 280 src/dxvk/dxvk_video_decoder.cpp 281 endif 268 282 VBox-DxVkNativeDxVk_VBOX_SHADERS := \ 269 283 $(PATH_SUB_CURRENT)/src/dxvk/shaders/dxvk_clear_buffer_u.comp \ … … 328 342 VBox-DxVkNativeD3D11_TEMPLATE = VBoxR3DllNonPedantic 329 343 VBox-DxVkNativeD3D11_DEFS = \ 344 $(VBOX_DXVK_COMMON_DEFINES) \ 330 345 DXVK_NATIVE \ 331 346 NOMINMAX \ … … 418 433 VBoxDxVk_TEMPLATE = VBoxR3DllNonPedantic 419 434 VBoxDxVk_DEFS = \ 435 $(VBOX_DXVK_COMMON_DEFINES) \ 420 436 DXVK_NATIVE \ 421 437 NOMINMAX \ -
trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_device.cpp
r105141 r108229 1 #if defined(VBOX_WITH_DXVK_VIDEO) && defined(RT_OS_WINDOWS) 2 #define INITGUID 3 #endif 4 1 5 #include <algorithm> 2 6 #include <cstring> … … 2811 2815 : m_container(pContainer), m_device(pDevice) { 2812 2816 2817 #ifdef VBOX_WITH_DXVK_VIDEO 2818 InitDecoderProfiles(); 2819 #endif 2813 2820 } 2814 2821 … … 2840 2847 const D3D11_VIDEO_DECODER_CONFIG* pConfig, 2841 2848 ID3D11VideoDecoder** ppDecoder) { 2849 #ifdef VBOX_WITH_DXVK_VIDEO 2850 const int i = ProfileIndexFromDecoderDesc(pVideoDesc); 2851 if (i >= 0) { 2852 const DxvkVideoDecodeProfileInfo& v = m_decoderProfiles[i].second; 2853 2854 try { 2855 *ppDecoder = ref(new D3D11VideoDecoder(m_device, *pVideoDesc, *pConfig, v)); 2856 return S_OK; 2857 } catch (const DxvkError& e) { 2858 Logger::err(e.message()); 2859 return E_FAIL; 2860 } 2861 } 2862 return E_INVALIDARG; 2863 #else 2842 2864 Logger::err("D3D11VideoDevice::CreateVideoDecoder: Stub"); 2843 2865 return E_NOTIMPL; 2866 #endif 2844 2867 } 2845 2868 … … 2882 2905 const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC* pDesc, 2883 2906 ID3D11VideoDecoderOutputView** ppVDOVView) { 2907 #ifdef VBOX_WITH_DXVK_VIDEO 2908 const int i = GetDecoderProfileIndex(pDesc->DecodeProfile); 2909 if (i >= 0) { 2910 try { 2911 *ppVDOVView = ref(new D3D11VideoDecoderOutputView(m_device, pResource, *pDesc)); 2912 return S_OK; 2913 } catch (const DxvkError& e) { 2914 Logger::err(e.message()); 2915 return E_FAIL; 2916 } 2917 } 2918 return E_INVALIDARG; 2919 #else 2884 2920 Logger::err("D3D11VideoDevice::CreateVideoDecoderOutputView: Stub"); 2885 2921 return E_NOTIMPL; 2922 #endif 2886 2923 } 2887 2924 … … 2931 2968 2932 2969 UINT STDMETHODCALLTYPE D3D11VideoDevice::GetVideoDecoderProfileCount() { 2970 #ifdef VBOX_WITH_DXVK_VIDEO 2971 return m_decoderProfiles.size(); 2972 #else 2933 2973 Logger::err("D3D11VideoDevice::GetVideoDecoderProfileCount: Stub"); 2934 2974 return 0; 2975 #endif 2935 2976 } 2936 2977 … … 2939 2980 UINT Index, 2940 2981 GUID* pDecoderProfile) { 2982 #ifdef VBOX_WITH_DXVK_VIDEO 2983 if (Index < m_decoderProfiles.size()) { 2984 if (pDecoderProfile != nullptr) 2985 *pDecoderProfile = m_decoderProfiles[Index].first.guid; 2986 return S_OK; 2987 } 2988 return E_INVALIDARG; 2989 #else 2941 2990 Logger::err("D3D11VideoDevice::GetVideoDecoderProfile: Stub"); 2942 2991 return E_NOTIMPL; 2992 #endif 2943 2993 } 2944 2994 … … 2948 2998 DXGI_FORMAT Format, 2949 2999 BOOL* pSupported) { 3000 #ifdef VBOX_WITH_DXVK_VIDEO 3001 const int i = GetDecoderProfileIndex(*pDecoderProfile); 3002 if (i >= 0) { 3003 const D3D11VideoDecoderProfile &p = m_decoderProfiles[i].first; 3004 3005 const auto it = std::find_if(p.supportedFormats.begin(), p.supportedFormats.end(), 3006 [Format](DXGI_FORMAT f) -> bool { return f == Format; }); 3007 3008 if (pSupported != nullptr) 3009 *pSupported = it != p.supportedFormats.end(); 3010 return S_OK; 3011 } 3012 return E_INVALIDARG; 3013 #else 2950 3014 Logger::err("D3D11VideoDevice::CheckVideoDecoderFormat: Stub"); 2951 3015 return E_NOTIMPL; 3016 #endif 2952 3017 } 2953 3018 … … 2956 3021 const D3D11_VIDEO_DECODER_DESC* pDesc, 2957 3022 UINT* pCount) { 3023 #ifdef VBOX_WITH_DXVK_VIDEO 3024 const int i = ProfileIndexFromDecoderDesc(pDesc); 3025 if (i >= 0) { 3026 const D3D11VideoDecoderProfile& p = m_decoderProfiles[i].first; 3027 3028 if (pCount != nullptr) 3029 *pCount = p.decoderConfigs.size(); 3030 return S_OK; 3031 } 3032 return E_INVALIDARG; 3033 #else 2958 3034 Logger::err("D3D11VideoDevice::GetVideoDecoderConfigCount: Stub"); 2959 3035 return E_NOTIMPL; 3036 #endif 2960 3037 } 2961 3038 … … 2965 3042 UINT Index, 2966 3043 D3D11_VIDEO_DECODER_CONFIG* pConfig) { 3044 #ifdef VBOX_WITH_DXVK_VIDEO 3045 const int i = ProfileIndexFromDecoderDesc(pDesc); 3046 if (i >= 0) { 3047 const D3D11VideoDecoderProfile &p = m_decoderProfiles[i].first; 3048 3049 if (Index >= p.decoderConfigs.size()) 3050 return E_INVALIDARG; 3051 3052 if (pConfig != nullptr) 3053 *pConfig = p.decoderConfigs[Index]; 3054 return S_OK; 3055 } 3056 return E_INVALIDARG; 3057 #else 2967 3058 Logger::err("D3D11VideoDevice::GetVideoDecoderConfig: Stub"); 2968 3059 return E_NOTIMPL; 3060 #endif 2969 3061 } 2970 3062 … … 2974 3066 const GUID* pDecoderProfile, 2975 3067 D3D11_VIDEO_CONTENT_PROTECTION_CAPS* pCaps) { 3068 #ifdef VBOX_WITH_DXVK_VIDEO 3069 const int i = GetDecoderProfileIndex(*pDecoderProfile); 3070 if (i >= 0) { 3071 if (pCaps != nullptr) 3072 memset(pCaps, 0, sizeof(*pCaps)); 3073 return S_OK; 3074 } 3075 return E_INVALIDARG; 3076 #else 2976 3077 Logger::err("D3D11VideoDevice::GetContentProtectionCaps: Stub"); 2977 3078 return E_NOTIMPL; 3079 #endif 2978 3080 } 2979 3081 … … 3002 3104 return m_container->SetPrivateDataInterface(Name, pData); 3003 3105 } 3106 3107 3108 #ifdef VBOX_WITH_DXVK_VIDEO 3109 void D3D11VideoDevice::InitDecoderProfiles() { 3110 Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice(); 3111 3112 /* Check that video decoding is supported. */ 3113 if (!dxvkDevice->features().khrVideoDecodeQueue 3114 || dxvkDevice->queues().videoDecode.queueHandle == VK_NULL_HANDLE) 3115 return; 3116 3117 /* 3118 * Create a list of D3D11 profiles descriptions (m_decoderProfiles) with backlinks to 3119 * supported Vulkan video profiles. 3120 */ 3121 3122 /* A Vulkan video profile with a list of compatible D3D11 profiles. */ 3123 struct D3D11VideoDecodeProfileMapping { 3124 DxvkVideoDecodeProfileInfo& dxvkProfile; 3125 std::vector<D3D11VideoDecoderProfile> d3dProfiles; 3126 }; 3127 std::vector<D3D11VideoDecodeProfileMapping> mappings; 3128 3129 /* 3130 * D3D11 profiles descriptions. 3131 */ 3132 const struct D3D11VideoDecoderProfile profile_ModeH264_VLD_NoFGT = { 3133 /* .guid = */ DXVA2_ModeH264_VLD_NoFGT, /* D3D11_DECODER_PROFILE_H264_VLD_NOFGT */ 3134 /* .decoderConfigs = */ std::vector<D3D11_VIDEO_DECODER_CONFIG> { 3135 { 3136 /* .guidConfigBitstreamEncryption = */ DXVA2_NoEncrypt, 3137 /* .guidConfigMBcontrolEncryption = */ DXVA2_NoEncrypt, 3138 /* .guidConfigResidDiffEncryption = */ DXVA2_NoEncrypt, 3139 /* .ConfigBitstreamRaw = */ 1, 3140 /* .ConfigMBcontrolRasterOrder = */ 0, 3141 /* .ConfigResidDiffHost = */ 0, 3142 /* .ConfigSpatialResid8 = */ 0, 3143 /* .ConfigResid8Subtraction = */ 0, 3144 /* .ConfigSpatialHost8or9Clipping = */ 0, 3145 /* .ConfigSpatialResidInterleaved = */ 0, 3146 /* .ConfigIntraResidUnsigned = */ 0, 3147 /* .ConfigResidDiffAccelerator = */ 1, 3148 /* .ConfigHostInverseScan = */ 1, 3149 /* .ConfigSpecificIDCT = */ 2, 3150 /* .Config4GroupedCoefs = */ 0, 3151 /* .ConfigMinRenderTargetBuffCount = */ 3, 3152 /* .ConfigDecoderSpecific = */ 0 3153 }, 3154 { 3155 /* .guidConfigBitstreamEncryption = */ DXVA2_NoEncrypt, 3156 /* .guidConfigMBcontrolEncryption = */ DXVA2_NoEncrypt, 3157 /* .guidConfigResidDiffEncryption = */ DXVA2_NoEncrypt, 3158 /* .ConfigBitstreamRaw = */ 2, 3159 /* .ConfigMBcontrolRasterOrder = */ 0, 3160 /* .ConfigResidDiffHost = */ 0, 3161 /* .ConfigSpatialResid8 = */ 0, 3162 /* .ConfigResid8Subtraction = */ 0, 3163 /* .ConfigSpatialHost8or9Clipping = */ 0, 3164 /* .ConfigSpatialResidInterleaved = */ 0, 3165 /* .ConfigIntraResidUnsigned = */ 0, 3166 /* .ConfigResidDiffAccelerator = */ 1, 3167 /* .ConfigHostInverseScan = */ 1, 3168 /* .ConfigSpecificIDCT = */ 2, 3169 /* .Config4GroupedCoefs = */ 0, 3170 /* .ConfigMinRenderTargetBuffCount = */ 3, 3171 /* .ConfigDecoderSpecific = */ 0 3172 } 3173 }, 3174 /* .supportedFormats = */ std::vector<DXGI_FORMAT> { 3175 DXGI_FORMAT_NV12 3176 } 3177 }; 3178 3179 /* 3180 * Add desired Vulkan profile descriptions to the 'mappings'. 3181 */ 3182 m_vulkanDecodeProfiles[0].profileName = "H.264"; 3183 m_vulkanDecodeProfiles[0].h264ProfileInfo = 3184 { VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR, nullptr, 3185 STD_VIDEO_H264_PROFILE_IDC_HIGH, 3186 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR 3187 }; 3188 m_vulkanDecodeProfiles[0].profileInfo = 3189 { VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, &m_vulkanDecodeProfiles[0].h264ProfileInfo, 3190 VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR, 3191 VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, 3192 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, 3193 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR 3194 }; 3195 m_vulkanDecodeProfiles[0].decodeH264Capabilities = 3196 { VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR }; 3197 m_vulkanDecodeProfiles[0].decodeCapabilities = 3198 { VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR, &m_vulkanDecodeProfiles[0].decodeH264Capabilities }; 3199 m_vulkanDecodeProfiles[0].videoCapabilities = 3200 { VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR, &m_vulkanDecodeProfiles[0].decodeCapabilities }; 3201 3202 mappings.push_back({ m_vulkanDecodeProfiles[0] }); 3203 mappings.back().d3dProfiles.push_back(profile_ModeH264_VLD_NoFGT); 3204 3205 /// @todo More Vulkan profiles: H.265 and AV1 3206 3207 /* 3208 * Query caps of every Vulkan profile and add supported profiles to the m_decoderProfiles list. 3209 */ 3210 auto vki = dxvkDevice->adapter()->vki(); 3211 auto physicalDevice = dxvkDevice->adapter()->handle(); 3212 3213 for (auto& m: mappings) { 3214 VkResult vr = vki->vkGetPhysicalDeviceVideoCapabilitiesKHR(physicalDevice, 3215 &m.dxvkProfile.profileInfo, &m.dxvkProfile.videoCapabilities); 3216 if (vr != VK_SUCCESS) 3217 continue; 3218 3219 Logger::info(str::format("DXVK: Video Decode: ", m.dxvkProfile.profileName, ":" 3220 " separate reference images=", 3221 (m.dxvkProfile.videoCapabilities.flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR) ? "1" : "0", 3222 ", DPB and output distinct=", 3223 (m.dxvkProfile.decodeCapabilities.flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) ? "1" : "0", 3224 ", DPB and output coincide=", 3225 (m.dxvkProfile.decodeCapabilities.flags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) ? "1" : "0")); 3226 3227 m.dxvkProfile.videoQueueHasTransfer = 3228 (dxvkDevice->adapter()->getQueueFlags(dxvkDevice->queues().videoDecode.queueFamily) & VK_QUEUE_TRANSFER_BIT) != 0; 3229 3230 /* Query format caps of DPB images. */ 3231 VkVideoProfileListInfoKHR profileListInfo = 3232 { VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR }; 3233 profileListInfo.profileCount = 1; 3234 profileListInfo.pProfiles = &m.dxvkProfile.profileInfo; 3235 3236 VkPhysicalDeviceVideoFormatInfoKHR physicalFormatInfo = 3237 { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR, &profileListInfo }; 3238 3239 /* 42.4.2. Video Format Capabilities */ 3240 switch (m.dxvkProfile.decodeCapabilities.flags 3241 & (VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR 3242 | VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR)) 3243 { 3244 case VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR 3245 | VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR: 3246 case VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR: 3247 physicalFormatInfo.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR 3248 | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR 3249 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 3250 break; 3251 case VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR: 3252 physicalFormatInfo.imageUsage = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR; 3253 break; 3254 default: 3255 continue; /* Must not be returned by Vulkan. */ 3256 } 3257 3258 uint32_t videoFormatPropertyCount = 0; 3259 vr = vki->vkGetPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, 3260 &physicalFormatInfo, &videoFormatPropertyCount, nullptr); 3261 if (vr != VK_SUCCESS) 3262 continue; 3263 3264 std::vector<VkVideoFormatPropertiesKHR> videoFormatProperties(videoFormatPropertyCount, 3265 { VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }); 3266 vr = vki->vkGetPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, 3267 &physicalFormatInfo, &videoFormatPropertyCount, videoFormatProperties.data()); 3268 if (vr != VK_SUCCESS) 3269 continue; 3270 3271 /* Verify that DXGI_FORMAT_NV12 is supported for DPB. */ 3272 const VkVideoFormatPropertiesKHR *pFormatProperties = nullptr; 3273 for (uint32_t i = 0; i < videoFormatPropertyCount; ++i) { 3274 const VkVideoFormatPropertiesKHR &p = videoFormatProperties[i]; 3275 if (p.format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM) { 3276 pFormatProperties = &videoFormatProperties[i]; 3277 break; 3278 } 3279 } 3280 3281 if (pFormatProperties == nullptr) 3282 continue; 3283 3284 m.dxvkProfile.dpbFormatProperties = *pFormatProperties; 3285 3286 /* Add supported D3D11 profiles to the list. */ 3287 for (auto &p: m.d3dProfiles) { 3288 m_decoderProfiles.push_back({ p, m.dxvkProfile }); 3289 } 3290 } 3291 } 3292 3293 3294 int D3D11VideoDevice::GetDecoderProfileIndex(const GUID &guid) 3295 { 3296 const auto it = std::find_if(m_decoderProfiles.begin(), m_decoderProfiles.end(), 3297 [ &guid ](std::pair<D3D11VideoDecoderProfile, DxvkVideoDecodeProfileInfo&>& p) -> bool 3298 { return p.first.guid == guid; }); 3299 if (it != m_decoderProfiles.end()) 3300 return std::distance(m_decoderProfiles.begin(), it); 3301 return -1; 3302 } 3303 3304 int D3D11VideoDevice::ProfileIndexFromDecoderDesc( 3305 const D3D11_VIDEO_DECODER_DESC* pVideoDesc) 3306 { 3307 const int i = GetDecoderProfileIndex(pVideoDesc->Guid); 3308 if (i >= 0) { 3309 const D3D11VideoDecoderProfile &p = m_decoderProfiles[i].first; 3310 3311 const auto it = std::find_if(p.supportedFormats.begin(), p.supportedFormats.end(), 3312 [ OutputFormat = pVideoDesc->OutputFormat ](DXGI_FORMAT f) -> bool { return f == OutputFormat; }); 3313 if (it == p.supportedFormats.end()) 3314 return -1; 3315 3316 const DxvkVideoDecodeProfileInfo& v = m_decoderProfiles[i].second; 3317 3318 if (pVideoDesc->SampleWidth > v.videoCapabilities.maxCodedExtent.width 3319 || pVideoDesc->SampleHeight > v.videoCapabilities.maxCodedExtent.height) 3320 return -1; 3321 3322 if (pVideoDesc->SampleWidth < v.videoCapabilities.minCodedExtent.width 3323 || pVideoDesc->SampleHeight < v.videoCapabilities.minCodedExtent.height) 3324 return -1; 3325 } 3326 return i; 3327 } 3328 #endif /* VBOX_WITH_DXVK_VIDEO */ 3004 3329 3005 3330 -
trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_device.h
r105107 r108229 695 695 D3D11Device* m_device; 696 696 697 #ifdef VBOX_WITH_DXVK_VIDEO 698 struct D3D11VideoDecoderProfile { 699 GUID guid; 700 std::vector<D3D11_VIDEO_DECODER_CONFIG> decoderConfigs; 701 std::vector<DXGI_FORMAT> supportedFormats; 702 }; 703 704 /* Vulkan video profiles, supported by DxvkVideoDecoder. Not necessarily supported by hardware. */ 705 std::array<DxvkVideoDecodeProfileInfo, 1> m_vulkanDecodeProfiles; 706 707 /* Supported D3D11 profiles with a reference to the underlaying Vulkan profile (m_vulkanDecodeProfiles). 708 * This is what the D3D11 methods expose to applications. 709 */ 710 std::vector<std::pair<D3D11VideoDecoderProfile, DxvkVideoDecodeProfileInfo&> > m_decoderProfiles; 711 712 void InitDecoderProfiles(); 713 int GetDecoderProfileIndex( 714 const GUID &guid); 715 int ProfileIndexFromDecoderDesc( 716 const D3D11_VIDEO_DECODER_DESC* pVideoDesc); 717 #endif 718 697 719 }; 698 720 -
trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_include.h
r105107 r108229 4 4 5 5 #include <d3d11_4.h> 6 7 #ifdef VBOX_WITH_DXVK_VIDEO 8 // For video decoding 9 #include <d3d9.h> 10 #include <dxva.h> 11 #include <dxva2api.h> 12 #endif -
trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_texture.cpp
r105107 r108229 80 80 } 81 81 82 #ifdef VBOX_WITH_DXVK_VIDEO 83 if (m_desc.BindFlags & D3D11_BIND_DECODER) 84 formatFamily.Add(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM); 85 #endif 86 82 87 // The image must be marked as mutable if it can be reinterpreted 83 88 // by a view with a different format. Depth-stencil formats cannot -
trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_video.cpp
r105107 r108229 8 8 9 9 namespace dxvk { 10 11 #ifdef VBOX_WITH_DXVK_VIDEO 12 D3D11VideoDecoder::D3D11VideoDecoder( 13 D3D11Device* pDevice, 14 const D3D11_VIDEO_DECODER_DESC &VideoDesc, 15 const D3D11_VIDEO_DECODER_CONFIG &Config, 16 const DxvkVideoDecodeProfileInfo& profile) 17 : D3D11DeviceChild<ID3D11VideoDecoder>(pDevice), 18 m_desc(VideoDesc), m_config(Config), 19 m_device(pDevice->GetDXVKDevice()) { 20 DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat( 21 m_desc.OutputFormat, DXGI_VK_FORMAT_MODE_COLOR); 22 23 if (formatInfo.Format == VK_FORMAT_UNDEFINED) 24 throw DxvkError(str::format("D3D11VideoDecoder: Unsupported output DXGI format: ", m_desc.OutputFormat)); 25 26 m_videoDecoder = m_device->createVideoDecoder(profile, m_desc.SampleWidth, m_desc.SampleHeight, formatInfo.Format); 27 } 28 29 30 D3D11VideoDecoder::~D3D11VideoDecoder() { 31 32 } 33 34 35 HRESULT STDMETHODCALLTYPE D3D11VideoDecoder::QueryInterface( 36 REFIID riid, 37 void** ppvObject) { 38 if (riid == __uuidof(IUnknown) 39 || riid == __uuidof(ID3D11DeviceChild) 40 || riid == __uuidof(ID3D11VideoDecoder)) { 41 *ppvObject = ref(this); 42 return S_OK; 43 } 44 45 if (logQueryInterfaceError(__uuidof(ID3D11VideoDecoder), riid)) { 46 Logger::warn("D3D11VideoDecoder::QueryInterface: Unknown interface query"); 47 Logger::warn(str::format(riid)); 48 } 49 50 return E_NOINTERFACE; 51 } 52 53 54 HRESULT STDMETHODCALLTYPE D3D11VideoDecoder::GetCreationParameters( 55 D3D11_VIDEO_DECODER_DESC *pVideoDesc, 56 D3D11_VIDEO_DECODER_CONFIG *pConfig) { 57 if (pVideoDesc != nullptr) 58 *pVideoDesc = m_desc; 59 if (pConfig != nullptr) 60 *pConfig = m_config; 61 return S_OK; 62 } 63 64 65 HRESULT STDMETHODCALLTYPE D3D11VideoDecoder::GetDriverHandle( 66 HANDLE *pDriverHandle) { 67 if (pDriverHandle != nullptr) 68 *pDriverHandle = m_videoDecoder.ptr(); 69 return S_OK; 70 } 71 72 73 HRESULT D3D11VideoDecoder::GetDecoderBuffer( 74 D3D11_VIDEO_DECODER_BUFFER_TYPE Type, 75 UINT* BufferSize, 76 void** ppBuffer) 77 { 78 if (Type >= m_decoderBuffers.size()) 79 return E_INVALIDARG; 80 81 D3D11VideoDecoderBuffer& decoderBuffer = m_decoderBuffers[Type]; 82 83 if (decoderBuffer.buffer.size() == 0) { 84 size_t cbBuffer; 85 switch (Type) 86 { 87 case D3D11_VIDEO_DECODER_BUFFER_BITSTREAM: 88 /* Arbitrary. Sufficiently big for one compressed frame (usually). */ 89 cbBuffer = 1024*1024; 90 break; 91 default: 92 cbBuffer = 65536; 93 } 94 decoderBuffer.buffer.resize(cbBuffer); 95 } 96 97 if (BufferSize != nullptr) 98 *BufferSize = decoderBuffer.buffer.size(); 99 if (ppBuffer != nullptr) 100 *ppBuffer = decoderBuffer.buffer.data(); 101 return S_OK; 102 } 103 104 105 HRESULT D3D11VideoDecoder::ReleaseDecoderBuffer( 106 D3D11_VIDEO_DECODER_BUFFER_TYPE Type) 107 { 108 if (Type >= m_decoderBuffers.size()) 109 return E_INVALIDARG; 110 111 return S_OK; 112 } 113 114 115 template<typename DXVA_Slice_H264_T> 116 static bool GetSliceOffsetsAndNALType( 117 DxvkVideoDecodeInputParameters *pParms, 118 const D3D11_VIDEO_DECODER_BUFFER_DESC* pSliceDesc, 119 const void *pSlices, 120 const uint8_t *pBitStream, 121 uint32_t cbBitStream) { 122 const DXVA_Slice_H264_T *paSlices = (DXVA_Slice_H264_T *)pSlices; 123 const uint32_t cSlices = pSliceDesc->DataSize / sizeof(DXVA_Slice_H264_T); 124 125 /* D3D11VideoDecoder::GetVideoDecodeH264InputParameters checks that 'pSliceDesc->DataSize' is less than 126 * the size of D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL buffer that is assigned in 127 * D3D11VideoDecoder::GetDecoderBuffer. I.e. 'cSlices' is limuted too. 128 */ 129 pParms->sliceOffsets.resize(cSlices); 130 131 for (uint32_t i = 0; i < cSlices; ++i) { 132 const DXVA_Slice_H264_T& slice = paSlices[i]; 133 134 if (slice.SliceBytesInBuffer > cbBitStream 135 || slice.BSNALunitDataLocation > cbBitStream - slice.SliceBytesInBuffer 136 || slice.SliceBytesInBuffer < 4) { /* NALU header: 00, 00, 01, xx */ 137 Logger::warn(str::format("D3D11VideoDecoder::GetH264: Invalid slice at ", 138 slice.BSNALunitDataLocation, "/", slice.SliceBytesInBuffer, ", bitstream size ", cbBitStream)); 139 return false; 140 } 141 142 if (slice.wBadSliceChopping) { 143 /* Should not happen because we use a sufficiently big bitstream buffer (see GetDecoderBuffer). */ 144 Logger::warn(str::format("D3D11VideoDecoder::GetH264: Ignored slice with wBadSliceChopping ", 145 slice.wBadSliceChopping)); 146 return false; /// @todo not supported yet 147 } 148 149 pParms->sliceOffsets[i] = slice.BSNALunitDataLocation; 150 151 const uint8_t *pu8NALHdr = pBitStream + slice.BSNALunitDataLocation; 152 const uint8_t nal_unit_type = pu8NALHdr[3] & 0x1F; 153 154 Logger::debug(str::format("NAL[", i, "]=", (uint32_t)nal_unit_type, " at ", 155 slice.BSNALunitDataLocation, "/", slice.SliceBytesInBuffer)); 156 157 if (i == 0) 158 pParms->nal_unit_type = nal_unit_type; 159 } 160 161 return true; 162 } 163 164 165 bool D3D11VideoDecoder::GetVideoDecodeH264InputParameters( 166 UINT BufferCount, 167 const D3D11_VIDEO_DECODER_BUFFER_DESC* pBufferDescs, 168 DxvkVideoDecodeInputParameters *pParms) { 169 /* 170 * Fetch all pieces of data from available buffers. 171 */ 172 const DXVA_PicParams_H264* pPicParams = nullptr; 173 const D3D11_VIDEO_DECODER_BUFFER_DESC* pPicParamsDesc = nullptr; 174 const DXVA_Qmatrix_H264* pQmatrix = nullptr; 175 const D3D11_VIDEO_DECODER_BUFFER_DESC* pQmatrixDesc = nullptr; 176 const void* pSlices = nullptr; 177 const D3D11_VIDEO_DECODER_BUFFER_DESC* pSliceDesc = nullptr; 178 const uint8_t* pBitStream = nullptr; 179 const D3D11_VIDEO_DECODER_BUFFER_DESC* pBitStreamDesc = nullptr; 180 181 for (UINT i = 0; i < BufferCount; ++i) { 182 const auto& desc = pBufferDescs[i]; 183 if (desc.BufferType >= m_decoderBuffers.size()) { 184 Logger::warn(str::format("DXVK: Video Decode: Ignored buffer type ", desc.BufferType)); 185 continue; 186 } 187 188 D3D11VideoDecoderBuffer const &b = m_decoderBuffers[desc.BufferType]; 189 Logger::debug(str::format("D3D11VideoDecoder::GetH264: Type ", desc.BufferType, ", size ", b.buffer.size())); 190 191 if (desc.DataSize > b.buffer.size()) { 192 Logger::warn(str::format("DXVK: Video Decode: Buffer ", desc.BufferType, " invalid size: ", desc.DataSize, " > ", b.buffer.size())); 193 continue; 194 } 195 196 switch (desc.BufferType) { 197 case D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS: 198 pPicParams = (DXVA_PicParams_H264 *)b.buffer.data(); 199 pPicParamsDesc = &desc; 200 break; 201 202 case D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX: 203 pQmatrix = (DXVA_Qmatrix_H264 *)b.buffer.data(); 204 pQmatrixDesc = &desc; 205 break; 206 207 case D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL: 208 pSlices = b.buffer.data(); 209 pSliceDesc = &desc; 210 break; 211 212 case D3D11_VIDEO_DECODER_BUFFER_BITSTREAM: 213 pBitStream = (uint8_t *)b.buffer.data(); 214 pBitStreamDesc = &desc; 215 break; 216 217 default: 218 break; 219 } 220 } 221 222 if (pPicParams == nullptr || pSlices == nullptr || pBitStream == nullptr) { 223 Logger::warn(str::format("DXVK: Video Decode: Not enough data:" 224 " PicParams ", (uint32_t)(pPicParams != nullptr), 225 " Slice ", (uint32_t)(pSlices != nullptr), 226 " BitStream ", (uint32_t)(pBitStream != nullptr))); 227 return false; 228 } 229 230 if (pPicParamsDesc->DataSize < sizeof(DXVA_PicParams_H264)) { 231 Logger::warn(str::format("DXVK: Video Decode: PicParams buffer size is too small: ", pPicParamsDesc->DataSize)); 232 return false; 233 } 234 235 if (pQmatrixDesc->DataSize < sizeof(DXVA_Qmatrix_H264)) { 236 Logger::warn(str::format("DXVK: Video Decode: Qmatrix buffer size is too small: ", pQmatrixDesc->DataSize)); 237 return false; 238 } 239 240 struct DxvkVideoDecodeInputParameters &p = *pParms; 241 242 p.sps.flags.constraint_set0_flag = 0; /* not known, assume unconstrained */ 243 p.sps.flags.constraint_set1_flag = 0; /* not known, assume unconstrained */ 244 p.sps.flags.constraint_set2_flag = 0; /* not known, assume unconstrained */ 245 p.sps.flags.constraint_set3_flag = 0; /* not known, assume unconstrained */ 246 p.sps.flags.constraint_set4_flag = 0; /* not known, assume unconstrained */ 247 p.sps.flags.constraint_set5_flag = 0; /* not known, assume unconstrained */ 248 p.sps.flags.direct_8x8_inference_flag = pPicParams->ContinuationFlag 249 ? (pPicParams->direct_8x8_inference_flag ? 1 : 0) 250 : 0; 251 p.sps.flags.mb_adaptive_frame_field_flag = pPicParams->MbaffFrameFlag ? 1 : 0; /// @todo Is it? 252 p.sps.flags.frame_mbs_only_flag = pPicParams->frame_mbs_only_flag ? 1 : 0; 253 p.sps.flags.delta_pic_order_always_zero_flag = pPicParams->ContinuationFlag 254 ? (pPicParams->delta_pic_order_always_zero_flag ? 1 : 0) 255 : 0; 256 p.sps.flags.separate_colour_plane_flag = 0; /* 4:4:4 only. Apparently DXVA decoding profiles do not use this flags. */ 257 p.sps.flags.gaps_in_frame_num_value_allowed_flag = 1; /// @todo unknown 258 p.sps.flags.qpprime_y_zero_transform_bypass_flag = 0; /// @todo unknown 259 p.sps.flags.frame_cropping_flag = 0; /* not used */ 260 p.sps.flags.seq_scaling_matrix_present_flag = 0; /* not used */ 261 p.sps.flags.vui_parameters_present_flag = 0; /* not used */ 262 p.sps.profile_idc = STD_VIDEO_H264_PROFILE_IDC_HIGH; /* Unknown */ 263 p.sps.level_idc = StdVideoH264LevelIdc(0); /* Unknown, set to maxLevelIdc by Dxvk decoder. */ 264 p.sps.chroma_format_idc = StdVideoH264ChromaFormatIdc(pPicParams->chroma_format_idc); 265 p.sps.seq_parameter_set_id = 0; /* Unknown, will be inferred by the Dxvk decoder. */ 266 p.sps.bit_depth_luma_minus8 = pPicParams->bit_depth_luma_minus8; 267 p.sps.bit_depth_chroma_minus8 = pPicParams->bit_depth_chroma_minus8; 268 p.sps.log2_max_frame_num_minus4 = pPicParams->ContinuationFlag 269 ? pPicParams->log2_max_frame_num_minus4 270 : 0; 271 p.sps.pic_order_cnt_type = pPicParams->ContinuationFlag 272 ? StdVideoH264PocType(pPicParams->pic_order_cnt_type) 273 : StdVideoH264PocType(0); 274 p.sps.offset_for_non_ref_pic = 0; /// @todo unknown 275 p.sps.offset_for_top_to_bottom_field = 0; /// @todo unknown 276 p.sps.log2_max_pic_order_cnt_lsb_minus4 = pPicParams->ContinuationFlag 277 ? pPicParams->log2_max_pic_order_cnt_lsb_minus4 278 : 0; 279 p.sps.num_ref_frames_in_pic_order_cnt_cycle = 0; /* Unknown */ 280 p.sps.max_num_ref_frames = pPicParams->num_ref_frames; 281 p.sps.reserved1 = 0; 282 p.sps.pic_width_in_mbs_minus1 = pPicParams->wFrameWidthInMbsMinus1; 283 p.sps.pic_height_in_map_units_minus1 = pPicParams->wFrameHeightInMbsMinus1; /// @todo Is it? 284 p.sps.frame_crop_left_offset = 0; /* not used */ 285 p.sps.frame_crop_right_offset = 0; /* not used */ 286 p.sps.frame_crop_top_offset = 0; /* not used */ 287 p.sps.frame_crop_bottom_offset = 0; /* not used */ 288 p.sps.reserved2 = 0; 289 p.sps.pOffsetForRefFrame = nullptr; /* &p.spsOffsetForRefFrame, updated by dxvk decoder. */ 290 p.sps.pScalingLists = nullptr; /* not used */ 291 p.sps.pSequenceParameterSetVui = nullptr; /* not used */ 292 p.spsOffsetForRefFrame = 0; /// @todo Is it? 293 294 p.pps.flags.transform_8x8_mode_flag = pPicParams->transform_8x8_mode_flag; 295 p.pps.flags.redundant_pic_cnt_present_flag = pPicParams->ContinuationFlag 296 ? (pPicParams->redundant_pic_cnt_present_flag ? 1 : 0) 297 : 0; 298 p.pps.flags.constrained_intra_pred_flag = pPicParams->constrained_intra_pred_flag ? 1 : 0; 299 p.pps.flags.deblocking_filter_control_present_flag = pPicParams->deblocking_filter_control_present_flag ? 1 : 0; 300 p.pps.flags.weighted_pred_flag = pPicParams->weighted_pred_flag ? 1 : 0; 301 p.pps.flags.bottom_field_pic_order_in_frame_present_flag = pPicParams->ContinuationFlag 302 ? (pPicParams->pic_order_present_flag ? 1 : 0) 303 : 0; 304 p.pps.flags.entropy_coding_mode_flag = pPicParams->ContinuationFlag 305 ? (pPicParams->entropy_coding_mode_flag ? 1 : 0) 306 : 0; 307 p.pps.flags.pic_scaling_matrix_present_flag = pQmatrix != nullptr ? 1 : 0; 308 p.pps.seq_parameter_set_id = 0; /* Unknown, will be inferred by the Dxvk decoder. */ 309 p.pps.pic_parameter_set_id = 0; /* Unknown, will be inferred by the Dxvk decoder. */ 310 p.pps.num_ref_idx_l0_default_active_minus1 = pPicParams->ContinuationFlag 311 ? pPicParams->num_ref_idx_l0_active_minus1 312 : 0; 313 p.pps.num_ref_idx_l1_default_active_minus1 = pPicParams->ContinuationFlag 314 ? pPicParams->num_ref_idx_l1_active_minus1 315 : 0; 316 p.pps.weighted_bipred_idc = StdVideoH264WeightedBipredIdc(pPicParams->weighted_bipred_idc); 317 p.pps.pic_init_qp_minus26 = pPicParams->ContinuationFlag 318 ? pPicParams->pic_init_qp_minus26 319 : 0; 320 p.pps.pic_init_qs_minus26 = pPicParams->pic_init_qs_minus26; 321 p.pps.chroma_qp_index_offset = pPicParams->chroma_qp_index_offset; 322 p.pps.second_chroma_qp_index_offset = pPicParams->second_chroma_qp_index_offset; 323 p.pps.pScalingLists = nullptr; /* &p.ppsScalingLists, updated by dxvk decoder. */ 324 325 if (p.pps.flags.pic_scaling_matrix_present_flag) { 326 p.ppsScalingLists.scaling_list_present_mask = 0xFF; /* 6x 4x4 and 2x 8x8 = 8 bits total */ 327 p.ppsScalingLists.use_default_scaling_matrix_mask = 0; 328 memcpy(p.ppsScalingLists.ScalingList4x4, pQmatrix->bScalingLists4x4, sizeof(pQmatrix->bScalingLists4x4)); 329 memcpy(p.ppsScalingLists.ScalingList8x8, pQmatrix->bScalingLists8x8, sizeof(pQmatrix->bScalingLists8x8)); 330 } 331 332 /* Fetch slice offsets. */ 333 bool fSuccess = m_config.ConfigBitstreamRaw == 2 334 ? GetSliceOffsetsAndNALType<DXVA_Slice_H264_Short>(&p, pSliceDesc, pSlices, pBitStream, pBitStreamDesc->DataSize) 335 : GetSliceOffsetsAndNALType<DXVA_Slice_H264_Long>(&p, pSliceDesc, pSlices, pBitStream, pBitStreamDesc->DataSize); 336 if (!fSuccess) 337 return false; 338 339 /// @todo Avoid intermediate buffer. Directly copy to a DxvkBuffer? 340 p.bitstreamLength = pBitStreamDesc->DataSize; 341 p.bitstream.resize(p.bitstreamLength); 342 memcpy(p.bitstream.data(), pBitStream, p.bitstream.size()); 343 344 p.stdH264PictureInfo.flags.field_pic_flag = pPicParams->field_pic_flag; 345 p.stdH264PictureInfo.flags.is_intra = pPicParams->IntraPicFlag; 346 p.stdH264PictureInfo.flags.IdrPicFlag = p.nal_unit_type == 5 ? 1 : 0; 347 p.stdH264PictureInfo.flags.bottom_field_flag = pPicParams->CurrPic.AssociatedFlag; /* flag is bottom field flag */ 348 p.stdH264PictureInfo.flags.is_reference = pPicParams->RefPicFlag; 349 p.stdH264PictureInfo.flags.complementary_field_pair = 0; /// @todo unknown 350 p.stdH264PictureInfo.seq_parameter_set_id = 0; /* Unknown, will be inferred by the Dxvk decoder. */ 351 p.stdH264PictureInfo.pic_parameter_set_id = 0; /* Unknown, will be inferred by the Dxvk decoder. */ 352 p.stdH264PictureInfo.reserved1 = 0; 353 p.stdH264PictureInfo.reserved2 = 0; 354 p.stdH264PictureInfo.frame_num = pPicParams->frame_num; 355 p.stdH264PictureInfo.idr_pic_id = 0; /// @todo unknown 356 p.stdH264PictureInfo.PicOrderCnt[0] = pPicParams->CurrFieldOrderCnt[0]; /// @todo Is it? 357 p.stdH264PictureInfo.PicOrderCnt[1] = pPicParams->CurrFieldOrderCnt[1]; 358 359 p.stdH264ReferenceInfo.flags.top_field_flag = 360 (p.stdH264PictureInfo.flags.field_pic_flag && !p.stdH264PictureInfo.flags.bottom_field_flag) ? 1 : 0; 361 p.stdH264ReferenceInfo.flags.bottom_field_flag = 362 (p.stdH264PictureInfo.flags.field_pic_flag && p.stdH264PictureInfo.flags.bottom_field_flag) ? 1 : 0; 363 p.stdH264ReferenceInfo.flags.used_for_long_term_reference = 0; /// @todo 364 p.stdH264ReferenceInfo.flags.is_non_existing = 0; 365 p.stdH264ReferenceInfo.FrameNum = pPicParams->frame_num; 366 p.stdH264ReferenceInfo.reserved = 0; 367 p.stdH264ReferenceInfo.PicOrderCnt[0] = pPicParams->CurrFieldOrderCnt[0]; /// @todo Is it? 368 p.stdH264ReferenceInfo.PicOrderCnt[1] = pPicParams->CurrFieldOrderCnt[1]; 369 370 return true; 371 } 372 373 374 375 376 D3D11VideoDecoderOutputView::D3D11VideoDecoderOutputView( 377 D3D11Device* pDevice, 378 ID3D11Resource* pResource, 379 const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC& Desc) 380 : D3D11DeviceChild<ID3D11VideoDecoderOutputView>(pDevice), 381 m_resource(pResource), m_desc(Desc) { 382 /* Desc.DecodeProfile and resource format has been verified by the caller (Device). */ 383 D3D11_COMMON_RESOURCE_DESC resourceDesc = { }; 384 GetCommonResourceDesc(pResource, &resourceDesc); 385 386 DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat( 387 resourceDesc.Format, DXGI_VK_FORMAT_MODE_COLOR); 388 389 /* In principle it is possible to use this view as video decode output if the Vulkan implementation 390 * supports VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR capability. In this case 391 * the image must be either created with VkVideoProfileListInfoKHR it its pNext chain or with 392 * VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR flag (if VK_KHR_VIDEO_MAINTENANCE_1 is supported, 393 * which is not always the case). 394 * 395 * However the video profile is not known at D3D11_BIND_DECODER texture creation time. 396 * D3D11 provides this information only when creating a VideoDecoderOutputView. 397 * 398 * Therefore the video decoder output view image is created without the video profile and 399 * the dxvk decoder will copy decoded picture to it. 400 * 401 * If Vulkan implementation supports VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR 402 * then the decoded picture has to be copied to the output image anyway. 403 * 404 * Otherwise the dxvk video decoder will use an internal output image and will copy it to 405 * the video decoder output view. 406 * 407 * In either case the D3D11 video decoder output view is only used as a transfer destination. 408 */ 409 Rc<DxvkImage> dxvkImage = GetCommonTexture(pResource)->GetImage(); 410 411 DxvkImageViewCreateInfo viewInfo; 412 viewInfo.format = formatInfo.Format; 413 viewInfo.aspect = VK_IMAGE_ASPECT_COLOR_BIT; 414 viewInfo.swizzle = formatInfo.Swizzle; 415 viewInfo.usage = dxvkImage->info().usage & ~VK_IMAGE_USAGE_SAMPLED_BIT; 416 417 switch (m_desc.ViewDimension) { 418 case D3D11_VDOV_DIMENSION_TEXTURE2D: 419 if (m_desc.Texture2D.ArraySlice >= dxvkImage->info().numLayers) 420 throw DxvkError(str::format("Invalid video decoder output view ArraySlice ", m_desc.Texture2D.ArraySlice)); 421 422 viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; 423 viewInfo.minLevel = 0; 424 viewInfo.numLevels = 1; 425 viewInfo.minLayer = m_desc.Texture2D.ArraySlice; 426 viewInfo.numLayers = 1; 427 break; 428 429 case D3D11_VDOV_DIMENSION_UNKNOWN: 430 default: 431 throw DxvkError("Invalid view dimension"); 432 } 433 434 m_view = pDevice->GetDXVKDevice()->createImageView( 435 dxvkImage, viewInfo); 436 } 437 438 439 D3D11VideoDecoderOutputView::~D3D11VideoDecoderOutputView() { 440 441 } 442 443 444 HRESULT STDMETHODCALLTYPE D3D11VideoDecoderOutputView::QueryInterface( 445 REFIID riid, 446 void** ppvObject) { 447 if (riid == __uuidof(IUnknown) 448 || riid == __uuidof(ID3D11DeviceChild) 449 || riid == __uuidof(ID3D11View) 450 || riid == __uuidof(ID3D11VideoDecoderOutputView)) { 451 *ppvObject = ref(this); 452 return S_OK; 453 } 454 455 if (logQueryInterfaceError(__uuidof(ID3D11VideoDecoderOutputView), riid)) { 456 Logger::warn("D3D11VideoDecoderOutputView::QueryInterface: Unknown interface query"); 457 Logger::warn(str::format(riid)); 458 } 459 460 return E_NOINTERFACE; 461 } 462 463 464 void STDMETHODCALLTYPE D3D11VideoDecoderOutputView::GetResource( 465 ID3D11Resource** ppResource) { 466 *ppResource = m_resource.ref(); 467 } 468 469 470 void STDMETHODCALLTYPE D3D11VideoDecoderOutputView::GetDesc( 471 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC* pDesc) { 472 *pDesc = m_desc; 473 } 474 #endif 475 476 477 10 478 11 479 D3D11VideoProcessorEnumerator::D3D11VideoProcessorEnumerator( … … 201 669 viewInfo.minLevel = m_desc.Texture2D.MipSlice; 202 670 viewInfo.numLevels = 1; 671 #ifdef VBOX_WITH_DXVK_VIDEO 672 viewInfo.minLayer = m_desc.Texture2D.ArraySlice; 673 #else 203 674 viewInfo.minLayer = 0; 675 #endif 204 676 viewInfo.numLayers = 1; 205 677 break; … … 422 894 UINT* BufferSize, 423 895 void** ppBuffer) { 896 #ifdef VBOX_WITH_DXVK_VIDEO 897 auto videoDecoder = static_cast<D3D11VideoDecoder*>(pDecoder); 898 return videoDecoder->GetDecoderBuffer(Type, BufferSize, ppBuffer); 899 #else 424 900 Logger::err("D3D11VideoContext::GetDecoderBuffer: Stub"); 425 901 return E_NOTIMPL; 902 #endif 426 903 } 427 904 … … 430 907 ID3D11VideoDecoder* pDecoder, 431 908 D3D11_VIDEO_DECODER_BUFFER_TYPE Type) { 909 #ifdef VBOX_WITH_DXVK_VIDEO 910 auto videoDecoder = static_cast<D3D11VideoDecoder*>(pDecoder); 911 return videoDecoder->ReleaseDecoderBuffer(Type); 912 #else 432 913 Logger::err("D3D11VideoContext::ReleaseDecoderBuffer: Stub"); 433 914 return E_NOTIMPL; 915 #endif 434 916 } 435 917 … … 439 921 UINT KeySize, 440 922 const void* pKey) { 923 #ifdef VBOX_WITH_DXVK_VIDEO 924 auto videoDecoder = static_cast<D3D11VideoDecoder*>(pDecoder); 925 auto dxvkDecoder = videoDecoder->GetDecoder(); 926 auto dxvkView = static_cast<D3D11VideoDecoderOutputView*>(pView)->GetView(); 927 928 m_ctx->EmitCs([ 929 cDecoder = dxvkDecoder, 930 cView = dxvkView 931 ] (DxvkContext* ctx) { 932 cDecoder->BeginFrame(ctx, cView); 933 }); 934 return S_OK; 935 #else 441 936 Logger::err("D3D11VideoContext::DecoderBeginFrame: Stub"); 442 937 return E_NOTIMPL; 938 #endif 443 939 } 444 940 … … 446 942 HRESULT STDMETHODCALLTYPE D3D11VideoContext::DecoderEndFrame( 447 943 ID3D11VideoDecoder* pDecoder) { 944 #ifdef VBOX_WITH_DXVK_VIDEO 945 auto videoDecoder = static_cast<D3D11VideoDecoder*>(pDecoder); 946 auto dxvkDecoder = videoDecoder->GetDecoder(); 947 948 m_ctx->EmitCs([ 949 cDecoder = dxvkDecoder 950 ] (DxvkContext* ctx) { 951 cDecoder->EndFrame(ctx); 952 }); 953 return S_OK; 954 #else 448 955 Logger::err("D3D11VideoContext::DecoderEndFrame: Stub"); 449 956 return E_NOTIMPL; 957 #endif 450 958 } 451 959 … … 455 963 UINT BufferCount, 456 964 const D3D11_VIDEO_DECODER_BUFFER_DESC* pBufferDescs) { 965 #ifdef VBOX_WITH_DXVK_VIDEO 966 auto videoDecoder = static_cast<D3D11VideoDecoder*>(pDecoder); 967 auto dxvkDecoder = videoDecoder->GetDecoder(); 968 969 DxvkVideoDecodeInputParameters parms; 970 if (!videoDecoder->GetVideoDecodeH264InputParameters(BufferCount, pBufferDescs, &parms)) 971 return E_INVALIDARG; 972 973 m_ctx->EmitCs([ 974 cDecoder = dxvkDecoder, 975 cParms = parms 976 ] (DxvkContext* ctx) { 977 cDecoder->Decode(ctx, cParms); 978 }); 979 980 return S_OK; 981 #else 457 982 Logger::err("D3D11VideoContext::SubmitDecoderBuffers: Stub"); 458 983 return E_NOTIMPL; 984 #endif 459 985 } 460 986 -
trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_video.h
r105107 r108229 1 1 #pragma once 2 2 3 #include "../dxvk/dxvk_video_decoder.h" 4 3 5 #include "d3d11_device.h" 4 6 5 7 namespace dxvk { 8 9 #ifdef VBOX_WITH_DXVK_VIDEO 10 11 class D3D11VideoDecoder : public D3D11DeviceChild<ID3D11VideoDecoder> { 12 13 public: 14 15 D3D11VideoDecoder( 16 D3D11Device* pDevice, 17 const D3D11_VIDEO_DECODER_DESC &VideoDesc, 18 const D3D11_VIDEO_DECODER_CONFIG &Config, 19 const DxvkVideoDecodeProfileInfo& profile); 20 21 ~D3D11VideoDecoder(); 22 23 HRESULT STDMETHODCALLTYPE QueryInterface( 24 REFIID riid, 25 void** ppvObject); 26 27 virtual HRESULT STDMETHODCALLTYPE GetCreationParameters( 28 D3D11_VIDEO_DECODER_DESC *pVideoDesc, 29 D3D11_VIDEO_DECODER_CONFIG *pConfig); 30 31 virtual HRESULT STDMETHODCALLTYPE GetDriverHandle( 32 HANDLE *pDriverHandle); 33 34 HRESULT GetDecoderBuffer( 35 D3D11_VIDEO_DECODER_BUFFER_TYPE Type, 36 UINT* BufferSize, 37 void** ppBuffer); 38 39 HRESULT ReleaseDecoderBuffer( 40 D3D11_VIDEO_DECODER_BUFFER_TYPE Type); 41 42 Rc<DxvkVideoDecoder> GetDecoder() { 43 return m_videoDecoder; 44 } 45 46 bool GetVideoDecodeH264InputParameters( 47 UINT BufferCount, 48 const D3D11_VIDEO_DECODER_BUFFER_DESC* pBufferDescs, 49 DxvkVideoDecodeInputParameters *pParms); 50 51 private: 52 53 struct D3D11VideoDecoderBuffer { 54 std::vector<uint8_t> buffer; 55 }; 56 57 D3D11_VIDEO_DECODER_DESC m_desc; 58 D3D11_VIDEO_DECODER_CONFIG m_config; 59 60 /* All buffer types except for D3D11_VIDEO_DECODER_BUFFER_HUFFMAN_TABLE. */ 61 std::array<D3D11VideoDecoderBuffer, D3D11_VIDEO_DECODER_BUFFER_FILM_GRAIN + 1> m_decoderBuffers; 62 Rc<DxvkDevice> m_device; 63 Rc<DxvkVideoDecoder> m_videoDecoder; 64 65 }; 66 67 68 class D3D11VideoDecoderOutputView : public D3D11DeviceChild<ID3D11VideoDecoderOutputView> { 69 70 public: 71 72 D3D11VideoDecoderOutputView( 73 D3D11Device* pDevice, 74 ID3D11Resource* pResource, 75 const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC& Desc); 76 77 ~D3D11VideoDecoderOutputView(); 78 79 HRESULT STDMETHODCALLTYPE QueryInterface( 80 REFIID riid, 81 void** ppvObject); 82 83 void STDMETHODCALLTYPE GetResource( 84 ID3D11Resource** ppResource); 85 86 void STDMETHODCALLTYPE GetDesc( 87 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC* pDesc); 88 89 Rc<DxvkImageView> GetView() const { 90 return m_view; 91 } 92 93 private: 94 95 Com<ID3D11Resource> m_resource; 96 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC m_desc; 97 Rc<DxvkImageView> m_view; 98 99 }; 100 #endif /* VBOX_WITH_DXVK_VIDEO */ 6 101 7 102 static constexpr uint32_t D3D11_VK_VIDEO_STREAM_COUNT = 8; -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_adapter.cpp
r105143 r108229 159 159 } 160 160 161 #ifdef VBOX_WITH_DXVK_VIDEO 162 uint32_t videoDecodeQueue = findQueueFamily( 163 VK_QUEUE_VIDEO_DECODE_BIT_KHR, 164 VK_QUEUE_VIDEO_DECODE_BIT_KHR); 165 #endif 166 161 167 DxvkAdapterQueueIndices queues; 162 168 queues.graphics = graphicsQueue; 163 169 queues.transfer = transferQueue; 164 170 queues.sparse = sparseQueue; 171 #ifdef VBOX_WITH_DXVK_VIDEO 172 queues.videoDecode = videoDecodeQueue; 173 #endif 165 174 return queues; 166 175 } … … 470 479 queueFamiliySet.insert(queueFamilies.sparse); 471 480 481 #ifdef VBOX_WITH_DXVK_VIDEO 482 if (queueFamilies.videoDecode != VK_QUEUE_FAMILY_IGNORED) 483 queueFamiliySet.insert(queueFamilies.videoDecode); 484 #endif 485 472 486 this->logQueueFamilies(queueFamilies); 473 487 … … 520 534 queues.transfer = getDeviceQueue(vkd, queueFamilies.transfer, 0); 521 535 queues.sparse = getDeviceQueue(vkd, queueFamilies.sparse, 0); 536 #ifdef VBOX_WITH_DXVK_VIDEO 537 queues.videoDecode = getDeviceQueue(vkd, queueFamilies.videoDecode, 0); 538 #endif 522 539 523 540 return new DxvkDevice(instance, this, vkd, enabledFeatures, queues, DxvkQueueCallback()); … … 719 736 } 720 737 } 738 739 #ifdef VBOX_WITH_DXVK_VIDEO 740 for (uint32_t i = 0; i < m_queueFamilies.size(); ++i) { 741 Logger::info(str::format(" Queue[", i, "]: Flags = 0x", std::hex, m_queueFamilies[i].queueFlags, std::dec)); 742 } 743 #endif 721 744 } 722 745 … … 964 987 if (m_deviceExtensions.supports(VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME)) 965 988 m_deviceFeatures.nvxImageViewHandle = VK_TRUE; 989 990 #ifdef VBOX_WITH_DXVK_VIDEO 991 if (m_deviceExtensions.supports(VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME)) 992 m_deviceFeatures.khrVideoDecodeQueue = VK_TRUE; 993 #endif 966 994 967 995 m_vki->vkGetPhysicalDeviceFeatures2(m_handle, &m_deviceFeatures.core); … … 1029 1057 &devExtensions.nvxBinaryImport, 1030 1058 &devExtensions.nvxImageViewHandle, 1059 #ifdef VBOX_WITH_DXVK_VIDEO 1060 &devExtensions.khrVideoQueue, 1061 &devExtensions.khrVideoDecodeQueue, 1062 &devExtensions.khrVideoDecodeH264, 1063 #endif 1031 1064 }}; 1032 1065 } … … 1179 1212 if (devExtensions.khrWin32KeyedMutex) 1180 1213 enabledFeatures.khrWin32KeyedMutex = VK_TRUE; 1214 1215 #ifdef VBOX_WITH_DXVK_VIDEO 1216 if (devExtensions.khrVideoDecodeQueue) 1217 enabledFeatures.khrVideoDecodeQueue = VK_TRUE; 1218 #endif 1181 1219 } 1182 1220 … … 1331 1369 "\n", VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME, 1332 1370 "\n extension supported : ", features.khrWin32KeyedMutex ? "1" : "0")); 1371 #ifdef VBOX_WITH_DXVK_VIDEO 1372 Logger::info(str::format( 1373 "", VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME, 1374 "\n extension supported : ", features.khrVideoDecodeQueue ? "1" : "0")); 1375 #endif 1333 1376 } 1334 1377 … … 1338 1381 "\n Graphics : ", queues.graphics, 1339 1382 "\n Transfer : ", queues.transfer, 1383 #ifdef VBOX_WITH_DXVK_VIDEO 1384 "\n Sparse : ", queues.sparse != VK_QUEUE_FAMILY_IGNORED ? str::format(queues.sparse) : "n/a", 1385 "\n VideoDec : ", queues.videoDecode != VK_QUEUE_FAMILY_IGNORED ? str::format(queues.videoDecode) : "n/a")); 1386 #else 1340 1387 "\n Sparse : ", queues.sparse != VK_QUEUE_FAMILY_IGNORED ? str::format(queues.sparse) : "n/a")); 1388 #endif 1341 1389 } 1342 1390 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_adapter.h
r105107 r108229 57 57 uint32_t transfer; 58 58 uint32_t sparse; 59 #ifdef VBOX_WITH_DXVK_VIDEO 60 uint32_t videoDecode; 61 #endif 59 62 }; 60 63 … … 303 306 } 304 307 308 #ifdef VBOX_WITH_DXVK_VIDEO 309 VkQueueFlags getQueueFlags(uint32_t queueFamily) { 310 if (queueFamily < m_queueFamilies.size()) 311 return m_queueFamilies[queueFamily].queueFlags; 312 return 0; 313 } 314 #endif 315 305 316 private: 306 317 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_buffer.cpp
r105107 r108229 98 98 DxvkBufferHandle DxvkBuffer::allocBuffer(VkDeviceSize sliceCount, bool clear) const { 99 99 VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; 100 #ifdef VBOX_WITH_DXVK_VIDEO 101 info.pNext = m_info.pNext; 102 #endif 100 103 info.flags = m_info.flags; 101 104 info.size = m_physSliceStride * sliceCount; -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_buffer.h
r105107 r108229 35 35 /// Allowed access patterns 36 36 VkAccessFlags access; 37 38 #ifdef VBOX_WITH_DXVK_VIDEO 39 /// VkBufferCreateInfo::pNext 40 void* pNext = nullptr; 41 #endif 37 42 }; 38 43 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_cmdlist.cpp
r105107 r108229 174 174 const auto& graphicsQueue = m_device->queues().graphics; 175 175 const auto& transferQueue = m_device->queues().transfer; 176 #ifdef VBOX_WITH_DXVK_VIDEO 177 const auto& videoDecodeQueue = m_device->queues().videoDecode; 178 #endif 176 179 177 180 VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; … … 182 185 throw DxvkError("DxvkCommandList: Failed to create semaphore"); 183 186 187 #ifdef VBOX_WITH_DXVK_VIDEO 188 VkSemaphoreTypeCreateInfo typeInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; 189 typeInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; 190 typeInfo.initialValue = m_vdecSemaphoreValue; 191 192 semaphoreInfo.pNext = &typeInfo; 193 194 if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_vdecSemaphore)) 195 throw DxvkError("DxvkCommandList: Failed to create video decode timeline semaphore"); 196 #endif 197 184 198 VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; 185 199 … … 193 207 else 194 208 m_transferPool = m_graphicsPool; 209 210 #ifdef VBOX_WITH_DXVK_VIDEO 211 if (videoDecodeQueue.queueFamily != VK_QUEUE_FAMILY_IGNORED) 212 m_videoDecodePool = new DxvkCommandPool(device, videoDecodeQueue.queueFamily); 213 #endif 195 214 } 196 215 … … 202 221 m_vkd->vkDestroySemaphore(m_vkd->device(), m_postSemaphore, nullptr); 203 222 m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr); 223 #ifdef VBOX_WITH_DXVK_VIDEO 224 m_vkd->vkDestroySemaphore(m_vkd->device(), m_vdecSemaphore, nullptr); 225 #endif 204 226 205 227 m_vkd->vkDestroyFence(m_vkd->device(), m_fence, nullptr); … … 207 229 208 230 231 #ifdef VBOX_WITH_DXVK_VIDEO 232 void DxvkCommandList::addSubmissionFences( 233 DxvkCmdBuffer cmdBuffer, 234 const DxvkCommandSubmissionInfo& cmd) { 235 for (const auto& entry : cmd.submissionFences) { 236 if (entry.cmdBuffer == cmdBuffer) { 237 if (entry.op == DxvkFenceOp::FenceOpWait) { 238 m_commandSubmission.waitSemaphore(entry.fence.fence->handle(), 239 entry.fence.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); 240 } 241 else if (entry.op == DxvkFenceOp::FenceOpSignal) { 242 m_commandSubmission.signalSemaphore(entry.fence.fence->handle(), 243 entry.fence.value, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); 244 } 245 } 246 } 247 } 248 #endif 249 250 209 251 VkResult DxvkCommandList::submit() { 210 252 VkResult status = VK_SUCCESS; … … 213 255 const auto& transfer = m_device->queues().transfer; 214 256 const auto& sparse = m_device->queues().sparse; 257 #ifdef VBOX_WITH_DXVK_VIDEO 258 const auto& videoDecode = m_device->queues().videoDecode; 259 #endif 215 260 216 261 m_commandSubmission.reset(); … … 274 319 275 320 // Submit graphics commands 321 #ifdef VBOX_WITH_DXVK_VIDEO 322 if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) { 323 addSubmissionFences(DxvkCmdBuffer::InitBuffer, cmd); 324 m_commandSubmission.executeCommandBuffer(cmd.initBuffer); 325 } 326 #else 276 327 if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) 277 328 m_commandSubmission.executeCommandBuffer(cmd.initBuffer); 329 #endif 278 330 279 331 if (cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer)) … … 300 352 if ((status = m_commandSubmission.submit(m_device, graphics.queueHandle))) 301 353 return status; 354 355 #ifdef VBOX_WITH_DXVK_VIDEO 356 if (videoDecode.queueFamily != VK_QUEUE_FAMILY_IGNORED) { 357 // Submit video decode commands as necessary 358 359 // Always signal the vdec command buffer completion. synchronizeFence waits for it. 360 m_commandSubmission.signalSemaphore(m_vdecSemaphore, ++m_vdecSemaphoreValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); 361 362 if (cmd.usedFlags.test(DxvkCmdBuffer::VDecBuffer)) { 363 addSubmissionFences(DxvkCmdBuffer::VDecBuffer, cmd); 364 m_commandSubmission.executeCommandBuffer(cmd.vdecBuffer); 365 } 366 367 // Submit all video decode commands of the current submission 368 if ((status = m_commandSubmission.submit(m_device, videoDecode.queueHandle))) 369 return status; 370 } 371 #endif 302 372 } 303 373 … … 313 383 m_cmd.initBuffer = m_graphicsPool->getCommandBuffer(); 314 384 m_cmd.sdmaBuffer = m_transferPool->getCommandBuffer(); 385 #ifdef VBOX_WITH_DXVK_VIDEO 386 if (m_videoDecodePool.ptr() != nullptr) 387 m_cmd.vdecBuffer = m_videoDecodePool->getCommandBuffer(); 388 #endif 315 389 } 316 390 … … 325 399 this->endCommandBuffer(m_cmd.initBuffer); 326 400 this->endCommandBuffer(m_cmd.sdmaBuffer); 401 #ifdef VBOX_WITH_DXVK_VIDEO 402 if (m_videoDecodePool.ptr() != nullptr) 403 this->endCommandBuffer(m_cmd.vdecBuffer); 404 #endif 327 405 328 406 // Reset all command buffer handles … … 355 433 } 356 434 435 #ifdef VBOX_WITH_DXVK_VIDEO 436 if (m_videoDecodePool.ptr() != nullptr) { 437 if (m_cmd.usedFlags.test(DxvkCmdBuffer::VDecBuffer)) { 438 this->endCommandBuffer(m_cmd.vdecBuffer); 439 m_cmd.vdecBuffer = m_videoDecodePool->getCommandBuffer(); 440 } 441 } 442 443 m_cmd.submissionFences.clear(); 444 #endif 445 357 446 m_cmd.usedFlags = 0; 358 447 } … … 360 449 361 450 VkResult DxvkCommandList::synchronizeFence() { 451 #ifdef VBOX_WITH_DXVK_VIDEO 452 if (m_device->queues().videoDecode.queueFamily != VK_QUEUE_FAMILY_IGNORED) { 453 /* Wait for completion of vdec buffer */ 454 const uint64_t waitValue = m_vdecSemaphoreValue; 455 456 VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; 457 // waitInfo.flags = 0; 458 waitInfo.semaphoreCount = 1; 459 waitInfo.pSemaphores = &m_vdecSemaphore; 460 waitInfo.pValues = &waitValue; 461 462 m_vkd->vkWaitSemaphores(m_vkd->device(), &waitInfo, ~0ull); 463 } 464 #endif 465 362 466 return m_vkd->vkWaitForFences(m_vkd->device(), 1, &m_fence, VK_TRUE, ~0ull); 363 467 } … … 403 507 m_graphicsPool->reset(); 404 508 m_transferPool->reset(); 509 #ifdef VBOX_WITH_DXVK_VIDEO 510 if (m_videoDecodePool.ptr() != nullptr) 511 m_videoDecodePool->reset(); 512 #endif 405 513 406 514 // Reset fence -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_cmdlist.h
r105107 r108229 31 31 ExecBuffer = 1, 32 32 SdmaBuffer = 2, 33 #ifdef VBOX_WITH_DXVK_VIDEO 34 VDecBuffer = 3, 35 #endif 33 36 }; 34 37 … … 119 122 }; 120 123 124 125 #ifdef VBOX_WITH_DXVK_VIDEO 126 enum class DxvkFenceOp : uint32_t { 127 FenceOpWait = 0, 128 FenceOpSignal = 1, 129 }; 130 131 struct DxvkCommandSubmissionFence { 132 DxvkFenceOp op; /* Do this op, */ 133 DxvkFenceValuePair fence; /* for this fence (timeline semaphore in fact), */ 134 DxvkCmdBuffer cmdBuffer; /* when submitting a command buffer of this type. */ 135 }; 136 #endif 121 137 122 138 /** … … 131 147 VkCommandBuffer initBuffer = VK_NULL_HANDLE; 132 148 VkCommandBuffer sdmaBuffer = VK_NULL_HANDLE; 149 #ifdef VBOX_WITH_DXVK_VIDEO 150 VkCommandBuffer vdecBuffer = VK_NULL_HANDLE; 151 #endif 133 152 VkBool32 sparseBind = VK_FALSE; 134 153 uint32_t sparseCmd = 0; 154 #ifdef VBOX_WITH_DXVK_VIDEO 155 std::vector<DxvkCommandSubmissionFence> submissionFences; 156 #endif 135 157 }; 136 158 … … 999 1021 1000 1022 1023 #ifdef VBOX_WITH_DXVK_VIDEO 1024 void cmdBeginVideoCodingKHR( 1025 VkVideoBeginCodingInfoKHR *videoBeginCodingInfo) { 1026 m_cmd.usedFlags.set(DxvkCmdBuffer::VDecBuffer); 1027 1028 m_vkd->vkCmdBeginVideoCodingKHR(m_cmd.vdecBuffer, videoBeginCodingInfo); 1029 } 1030 1031 void cmdControlVideoCodingKHR( 1032 VkVideoCodingControlInfoKHR *videoCodingControlInfo) { 1033 m_cmd.usedFlags.set(DxvkCmdBuffer::VDecBuffer); 1034 1035 m_vkd->vkCmdControlVideoCodingKHR(m_cmd.vdecBuffer, videoCodingControlInfo); 1036 } 1037 1038 void cmdDecodeVideoKHR( 1039 VkVideoDecodeInfoKHR *videoDecodeInfo) { 1040 m_cmd.usedFlags.set(DxvkCmdBuffer::VDecBuffer); 1041 1042 m_vkd->vkCmdDecodeVideoKHR(m_cmd.vdecBuffer, videoDecodeInfo); 1043 } 1044 1045 void cmdEndVideoCodingKHR( 1046 VkVideoEndCodingInfoKHR *videoEndCodingInfo) { 1047 m_cmd.usedFlags.set(DxvkCmdBuffer::VDecBuffer); 1048 1049 m_vkd->vkCmdEndVideoCodingKHR(m_cmd.vdecBuffer, videoEndCodingInfo); 1050 } 1051 1052 void waitSubmissionFence(DxvkCmdBuffer cmdBuffer, Rc<DxvkFence> fence, uint64_t value) { 1053 m_cmd.submissionFences.emplace_back( 1054 DxvkCommandSubmissionFence {DxvkFenceOp::FenceOpWait, {std::move(fence), value}, cmdBuffer }); 1055 } 1056 1057 void signalSubmissionFence(DxvkCmdBuffer cmdBuffer, Rc<DxvkFence> fence, uint64_t value) { 1058 m_cmd.submissionFences.emplace_back( 1059 DxvkCommandSubmissionFence {DxvkFenceOp::FenceOpSignal, {std::move(fence), value}, cmdBuffer }); 1060 } 1061 #endif 1062 1063 1001 1064 void bindBufferMemory( 1002 1065 const DxvkSparseBufferBindKey& key, … … 1035 1098 Rc<DxvkCommandPool> m_graphicsPool; 1036 1099 Rc<DxvkCommandPool> m_transferPool; 1100 #ifdef VBOX_WITH_DXVK_VIDEO 1101 Rc<DxvkCommandPool> m_videoDecodePool; 1102 #endif 1037 1103 1038 1104 VkSemaphore m_bindSemaphore = VK_NULL_HANDLE; 1039 1105 VkSemaphore m_postSemaphore = VK_NULL_HANDLE; 1040 1106 VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; 1107 #ifdef VBOX_WITH_DXVK_VIDEO 1108 VkSemaphore m_vdecSemaphore = VK_NULL_HANDLE; 1109 std::atomic<uint64_t> m_vdecSemaphoreValue = 0; 1110 #endif 1041 1111 VkFence m_fence = VK_NULL_HANDLE; 1042 1112 … … 1070 1140 if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_cmd.initBuffer; 1071 1141 if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer) return m_cmd.sdmaBuffer; 1142 #ifdef VBOX_WITH_DXVK_VIDEO 1143 if (cmdBuffer == DxvkCmdBuffer::VDecBuffer) return m_cmd.vdecBuffer; 1144 #endif 1072 1145 return VK_NULL_HANDLE; 1073 1146 } … … 1085 1158 void endCommandBuffer(VkCommandBuffer cmdBuffer); 1086 1159 1160 #ifdef VBOX_WITH_DXVK_VIDEO 1161 void addSubmissionFences( 1162 DxvkCmdBuffer cmdBuffer, 1163 const DxvkCommandSubmissionInfo& cmd); 1164 #endif 1087 1165 }; 1088 1166 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_context.h
r105107 r108229 856 856 uint32_t counterBias); 857 857 858 #ifdef VBOX_WITH_DXVK_VIDEO 859 /** 860 * \brief Begin a video coding scope. 861 862 * \param [in] videoBeginCodingInfo Parameters of the video coding scope 863 */ 864 void beginVideoCodingKHR( 865 VkVideoBeginCodingInfoKHR *videoBeginCodingInfo) { 866 m_cmd->cmdBeginVideoCodingKHR( 867 videoBeginCodingInfo); 868 } 869 870 /** 871 * \brief Control video coding parameters. 872 873 * \param [in] videoDecodeInfo Control parameters 874 */ 875 void controlVideoCodingKHR( 876 VkVideoCodingControlInfoKHR *videoCodingControlInfo) { 877 m_cmd->cmdControlVideoCodingKHR( 878 videoCodingControlInfo); 879 } 880 881 /** 882 * \brief Decode video data. 883 884 * \param [in] videoDecodeInfo Video decoder input data 885 */ 886 void decodeVideoKHR( 887 VkVideoDecodeInfoKHR *videoDecodeInfo) { 888 m_cmd->cmdDecodeVideoKHR( 889 videoDecodeInfo); 890 } 891 892 /** 893 * \brief End a video coding scope. 894 895 * \param [in] videoEndCodingInfo Parameters for ending the video coding scope 896 */ 897 void endVideoCodingKHR( 898 VkVideoEndCodingInfoKHR *videoEndCodingInfo) { 899 m_cmd->cmdEndVideoCodingKHR( 900 videoEndCodingInfo); 901 } 902 903 void emitPipelineBarrier( 904 DxvkCmdBuffer cmdBuffer, 905 const VkDependencyInfo* dependencyInfo) { 906 m_cmd->cmdPipelineBarrier(cmdBuffer, dependencyInfo); 907 } 908 909 void emitCopyImage( 910 DxvkCmdBuffer cmdBuffer, 911 const VkCopyImageInfo2* copyInfo) { 912 m_cmd->cmdCopyImage(cmdBuffer, copyInfo); 913 } 914 915 void transferImageQueueOwnership( 916 DxvkCmdBuffer srcCmdBuffer, 917 const VkImageMemoryBarrier2* srcBarrier, 918 DxvkCmdBuffer dstCmdBuffer, 919 const VkImageMemoryBarrier2* dstBarrier, 920 const Rc<DxvkFence>& fence, 921 uint64_t value) { 922 // Submit 'release=src' barrier. 923 VkDependencyInfo dependencyInfo = 924 { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; 925 dependencyInfo.imageMemoryBarrierCount = 1; 926 dependencyInfo.pImageMemoryBarriers = srcBarrier; 927 928 m_cmd->cmdPipelineBarrier(srcCmdBuffer, &dependencyInfo); 929 m_cmd->signalSubmissionFence(srcCmdBuffer, fence, value); 930 931 // Split command buffers so that we submit barriers in the right order. 932 // That is the release barrier is submitted to the source queue before 933 // the acquire barrier is submitted to the destination queue. 934 splitCommands(); 935 936 // Submit 'acquire=dst' barrier. 937 dependencyInfo.pImageMemoryBarriers = dstBarrier; 938 939 m_cmd->cmdPipelineBarrier(dstCmdBuffer, &dependencyInfo); 940 m_cmd->waitSubmissionFence(dstCmdBuffer, fence, value); 941 } 942 943 void trackResource( 944 DxvkAccess access, 945 const Rc<DxvkResource>& resource) { 946 if (access == DxvkAccess::Write) 947 m_cmd->trackResource<DxvkAccess::Write>(resource); 948 else if (access == DxvkAccess::Read) 949 m_cmd->trackResource<DxvkAccess::Read>(resource); 950 else 951 m_cmd->trackResource<DxvkAccess::None>(resource); 952 } 953 #endif 954 858 955 /** 859 956 * \brief Emits graphics barrier -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_device.cpp
r105107 r108229 197 197 198 198 199 #ifdef VBOX_WITH_DXVK_VIDEO 200 Rc<DxvkVideoDecoder> DxvkDevice::createVideoDecoder( 201 const DxvkVideoDecodeProfileInfo& profile, 202 uint32_t sampleWidth, 203 uint32_t sampleHeight, 204 VkFormat outputFormat) { 205 return new DxvkVideoDecoder(this, m_objects.memoryManager(), 206 profile, sampleWidth, sampleHeight, outputFormat); 207 } 208 #endif 209 210 199 211 DxvkStatCounters DxvkDevice::getStatCounters() { 200 212 DxvkPipelineCount pipe = m_objects.pipelineManager().getPipelineCount(); -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_device.h
r105107 r108229 26 26 #include "dxvk_unbound.h" 27 27 #include "dxvk_marker.h" 28 #ifdef VBOX_WITH_DXVK_VIDEO 29 #include "dxvk_video_decoder.h" 30 #endif 28 31 29 32 namespace dxvk { … … 66 69 DxvkDeviceQueue transfer; 67 70 DxvkDeviceQueue sparse; 71 #ifdef VBOX_WITH_DXVK_VIDEO 72 DxvkDeviceQueue videoDecode; 73 #endif 68 74 }; 69 75 … … 361 367 Rc<DxvkSparsePageAllocator> createSparsePageAllocator(); 362 368 369 #ifdef VBOX_WITH_DXVK_VIDEO 370 /** 371 * \brief Creates a video decoder 372 * 373 * \param [in] profileInfo Vulkan video profile and caps 374 * \param [in] sampleWidth The video frame width 375 * \param [in] sampleHeight The video frame height 376 * \param [in] outputFormat The format of decoded frame 377 * \returns Video decoder 378 */ 379 Rc<DxvkVideoDecoder> createVideoDecoder( 380 const DxvkVideoDecodeProfileInfo& profile, 381 uint32_t sampleWidth, 382 uint32_t sampleHeight, 383 VkFormat outputFormat); 384 #endif 385 363 386 /** 364 387 * \brief Imports a buffer -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_device_info.h
r105107 r108229 73 73 VkBool32 nvxImageViewHandle; 74 74 VkBool32 khrWin32KeyedMutex; 75 #ifdef VBOX_WITH_DXVK_VIDEO 76 VkBool32 khrVideoDecodeQueue; 77 #endif 75 78 }; 76 79 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_extensions.h
r105107 r108229 329 329 DxvkExt nvxBinaryImport = { VK_NVX_BINARY_IMPORT_EXTENSION_NAME, DxvkExtMode::Disabled }; 330 330 DxvkExt nvxImageViewHandle = { VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME, DxvkExtMode::Disabled }; 331 #ifdef VBOX_WITH_DXVK_VIDEO 332 DxvkExt khrVideoQueue = { VK_KHR_VIDEO_QUEUE_EXTENSION_NAME, DxvkExtMode::Optional }; 333 DxvkExt khrVideoDecodeQueue = { VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME, DxvkExtMode::Optional }; 334 DxvkExt khrVideoDecodeH264 = { VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME, DxvkExtMode::Optional }; 335 #endif 331 336 }; 332 337 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_image.cpp
r105107 r108229 21 21 // allows some drivers to enable image compression 22 22 VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO }; 23 #ifdef VBOX_WITH_DXVK_VIDEO 24 formatList.pNext = createInfo.pNext; 25 #endif 23 26 formatList.viewFormatCount = createInfo.viewFormatCount; 24 27 formatList.pViewFormats = createInfo.viewFormats; -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_image.h
r105107 r108229 70 70 // Shared handle info 71 71 DxvkSharedHandleInfo sharing; 72 73 #ifdef VBOX_WITH_DXVK_VIDEO 74 void* pNext = nullptr; 75 #endif 72 76 }; 73 77 -
trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_instance.cpp
r107544 r108229 351 351 std::stringstream str; 352 352 353 #ifdef VBOX 354 str << "VKValidation: "; 355 #endif 356 353 357 if (pCallbackData->pMessageIdName) 354 358 str << pCallbackData->pMessageIdName << ": " << std::endl; -
trunk/src/libs/dxvk-2.3.1/src/util/com/com_include.h
r107544 r108229 6 6 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 7 7 #endif // __GNUC__ 8 9 #ifdef VBOX 10 #include <iprt/asm.h> 11 #endif 8 12 9 13 #define WIN32_LEAN_AND_MEAN -
trunk/src/libs/dxvk-2.3.1/src/vulkan/vulkan_loader.h
r105107 r108229 169 169 VULKAN_FN(vkReleaseSwapchainImagesEXT); 170 170 #endif 171 172 #ifdef VBOX_WITH_DXVK_VIDEO 173 #ifdef VK_KHR_video_queue 174 VULKAN_FN(vkGetPhysicalDeviceVideoCapabilitiesKHR); 175 VULKAN_FN(vkGetPhysicalDeviceVideoFormatPropertiesKHR); 176 #endif 177 #endif /* VBOX_WITH_DXVK_VIDEO */ 171 178 }; 172 179 … … 453 460 VULKAN_FN(wine_vkReleaseKeyedMutex); 454 461 #endif 462 463 #ifdef VBOX_WITH_DXVK_VIDEO 464 #ifdef VK_KHR_video_queue 465 VULKAN_FN(vkCreateVideoSessionKHR); 466 VULKAN_FN(vkDestroyVideoSessionKHR); 467 VULKAN_FN(vkGetVideoSessionMemoryRequirementsKHR); 468 VULKAN_FN(vkBindVideoSessionMemoryKHR); 469 VULKAN_FN(vkCreateVideoSessionParametersKHR); 470 VULKAN_FN(vkUpdateVideoSessionParametersKHR); 471 VULKAN_FN(vkDestroyVideoSessionParametersKHR); 472 VULKAN_FN(vkCmdBeginVideoCodingKHR); 473 VULKAN_FN(vkCmdEndVideoCodingKHR); 474 VULKAN_FN(vkCmdControlVideoCodingKHR); 475 #endif 476 477 #ifdef VK_KHR_video_decode_queue 478 VULKAN_FN(vkCmdDecodeVideoKHR); 479 #endif 480 #endif /* VBOX_WITH_DXVK_VIDEO */ 455 481 }; 456 482
Note:
See TracChangeset
for help on using the changeset viewer.