VirtualBox

Changeset 108229 in vbox


Ignore:
Timestamp:
Feb 14, 2025 5:47:02 PM (2 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167549
Message:

libs/dxvk-2.3.1: D3D11 video decode API implementation (disabled)

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  
    5656 VBOX_DXVK_CXXFLAGS_WIN += -wd5204 # class has virtual functions, but its trivial destructor is not virtual
    5757 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'.
    5860 VBOX_DXVK_CXXFLAGS_WIN += -wd5264 # 'MaxPendingSubmits': 'const' variable is not used
    5961 VBOX_DXVK_CXXFLAGS_WIN += -wd5267 # definition of implicit copy constructor for 'dxvk::DxvkSparseBindSubmission' is deprecated because it has a user-provided destructor
    6062else
    6163 VBOX_DXVK_PLATFORM = DXVK_PLATFORM_LINUX
     64endif
     65
     66VBOX_DXVK_COMMON_DEFINES =
     67ifdef VBOX_WITH_DXVK_VIDEO
     68 VBOX_DXVK_COMMON_DEFINES += \
     69        VBOX_WITH_DXVK_VIDEO
    6270endif
    6371
     
    98106VBox-DxVkNativeUtil_TEMPLATE       = VBoxR3DllNonPedantic
    99107VBox-DxVkNativeUtil_DEFS           = \
     108        $(VBOX_DXVK_COMMON_DEFINES) \
    100109        DXVK_NATIVE \
    101110        NOMINMAX \
     
    191200VBox-DxVkNativeDxVk_TEMPLATE       = VBoxR3DllNonPedantic
    192201VBox-DxVkNativeDxVk_DEFS           = \
     202        $(VBOX_DXVK_COMMON_DEFINES) \
    193203        DXVK_NATIVE \
    194204        NOMINMAX \
     
    266276        src/dxvk/hud/dxvk_hud_renderer.cpp \
    267277        src/dxvk/platform/dxvk_headless_exts.cpp
     278ifdef VBOX_WITH_DXVK_VIDEO
     279VBox-DxVkNativeDxVk_SOURCES       += \
     280        src/dxvk/dxvk_video_decoder.cpp
     281endif
    268282VBox-DxVkNativeDxVk_VBOX_SHADERS := \
    269283        $(PATH_SUB_CURRENT)/src/dxvk/shaders/dxvk_clear_buffer_u.comp \
     
    328342VBox-DxVkNativeD3D11_TEMPLATE        = VBoxR3DllNonPedantic
    329343VBox-DxVkNativeD3D11_DEFS            = \
     344        $(VBOX_DXVK_COMMON_DEFINES) \
    330345        DXVK_NATIVE \
    331346        NOMINMAX \
     
    418433VBoxDxVk_TEMPLATE = VBoxR3DllNonPedantic
    419434VBoxDxVk_DEFS     = \
     435        $(VBOX_DXVK_COMMON_DEFINES) \
    420436        DXVK_NATIVE \
    421437        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
    15#include <algorithm>
    26#include <cstring>
     
    28112815  : m_container(pContainer), m_device(pDevice) {
    28122816
     2817#ifdef VBOX_WITH_DXVK_VIDEO
     2818    InitDecoderProfiles();
     2819#endif
    28132820  }
    28142821
     
    28402847    const D3D11_VIDEO_DECODER_CONFIG*                   pConfig,
    28412848          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
    28422864    Logger::err("D3D11VideoDevice::CreateVideoDecoder: Stub");
    28432865    return E_NOTIMPL;
     2866#endif
    28442867  }
    28452868
     
    28822905    const D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC*         pDesc,
    28832906          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
    28842920    Logger::err("D3D11VideoDevice::CreateVideoDecoderOutputView: Stub");
    28852921    return E_NOTIMPL;
     2922#endif
    28862923  }
    28872924
     
    29312968
    29322969  UINT STDMETHODCALLTYPE D3D11VideoDevice::GetVideoDecoderProfileCount() {
     2970#ifdef VBOX_WITH_DXVK_VIDEO
     2971    return m_decoderProfiles.size();
     2972#else
    29332973    Logger::err("D3D11VideoDevice::GetVideoDecoderProfileCount: Stub");
    29342974    return 0;
     2975#endif
    29352976  }
    29362977
     
    29392980          UINT                                          Index,
    29402981          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
    29412990    Logger::err("D3D11VideoDevice::GetVideoDecoderProfile: Stub");
    29422991    return E_NOTIMPL;
     2992#endif
    29432993  }
    29442994
     
    29482998          DXGI_FORMAT                                   Format,
    29492999          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
    29503014    Logger::err("D3D11VideoDevice::CheckVideoDecoderFormat: Stub");
    29513015    return E_NOTIMPL;
     3016#endif
    29523017  }
    29533018
     
    29563021    const D3D11_VIDEO_DECODER_DESC*                     pDesc,
    29573022          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
    29583034    Logger::err("D3D11VideoDevice::GetVideoDecoderConfigCount: Stub");
    29593035    return E_NOTIMPL;
     3036#endif
    29603037  }
    29613038
     
    29653042          UINT                                          Index,
    29663043          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
    29673058    Logger::err("D3D11VideoDevice::GetVideoDecoderConfig: Stub");
    29683059    return E_NOTIMPL;
     3060#endif
    29693061  }
    29703062
     
    29743066    const GUID*                                         pDecoderProfile,
    29753067          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
    29763077    Logger::err("D3D11VideoDevice::GetContentProtectionCaps: Stub");
    29773078    return E_NOTIMPL;
     3079#endif
    29783080  }
    29793081
     
    30023104    return m_container->SetPrivateDataInterface(Name, pData);
    30033105  }
     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 */
    30043329
    30053330
  • trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_device.h

    r105107 r108229  
    695695    D3D11Device*     m_device;
    696696
     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
    697719  };
    698720
  • trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_include.h

    r105107 r108229  
    44
    55#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  
    8080    }
    8181
     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
    8287    // The image must be marked as mutable if it can be reinterpreted
    8388    // 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  
    88
    99namespace 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
    10478
    11479  D3D11VideoProcessorEnumerator::D3D11VideoProcessorEnumerator(
     
    201669        viewInfo.minLevel   = m_desc.Texture2D.MipSlice;
    202670        viewInfo.numLevels  = 1;
     671#ifdef VBOX_WITH_DXVK_VIDEO
     672        viewInfo.minLayer   = m_desc.Texture2D.ArraySlice;
     673#else
    203674        viewInfo.minLayer   = 0;
     675#endif
    204676        viewInfo.numLayers  = 1;
    205677        break;
     
    422894          UINT*                           BufferSize,
    423895          void**                          ppBuffer) {
     896#ifdef VBOX_WITH_DXVK_VIDEO
     897    auto videoDecoder = static_cast<D3D11VideoDecoder*>(pDecoder);
     898    return videoDecoder->GetDecoderBuffer(Type, BufferSize, ppBuffer);
     899#else
    424900    Logger::err("D3D11VideoContext::GetDecoderBuffer: Stub");
    425901    return E_NOTIMPL;
     902#endif
    426903  }
    427904
     
    430907          ID3D11VideoDecoder*             pDecoder,
    431908          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
    432913    Logger::err("D3D11VideoContext::ReleaseDecoderBuffer: Stub");
    433914    return E_NOTIMPL;
     915#endif
    434916  }
    435917
     
    439921          UINT                            KeySize,
    440922    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
    441936    Logger::err("D3D11VideoContext::DecoderBeginFrame: Stub");
    442937    return E_NOTIMPL;
     938#endif
    443939  }
    444940
     
    446942  HRESULT STDMETHODCALLTYPE D3D11VideoContext::DecoderEndFrame(
    447943          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
    448955    Logger::err("D3D11VideoContext::DecoderEndFrame: Stub");
    449956    return E_NOTIMPL;
     957#endif
    450958  }
    451959
     
    455963          UINT                            BufferCount,
    456964    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
    457982    Logger::err("D3D11VideoContext::SubmitDecoderBuffers: Stub");
    458983    return E_NOTIMPL;
     984#endif
    459985  }
    460986
  • trunk/src/libs/dxvk-2.3.1/src/d3d11/d3d11_video.h

    r105107 r108229  
    11#pragma once
    22
     3#include "../dxvk/dxvk_video_decoder.h"
     4
    35#include "d3d11_device.h"
    46
    57namespace 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 */
    6101
    7102  static constexpr uint32_t D3D11_VK_VIDEO_STREAM_COUNT = 8;
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_adapter.cpp

    r105143 r108229  
    159159    }
    160160
     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
    161167    DxvkAdapterQueueIndices queues;
    162168    queues.graphics = graphicsQueue;
    163169    queues.transfer = transferQueue;
    164170    queues.sparse = sparseQueue;
     171#ifdef VBOX_WITH_DXVK_VIDEO
     172    queues.videoDecode = videoDecodeQueue;
     173#endif
    165174    return queues;
    166175  }
     
    470479      queueFamiliySet.insert(queueFamilies.sparse);
    471480
     481#ifdef VBOX_WITH_DXVK_VIDEO
     482    if (queueFamilies.videoDecode != VK_QUEUE_FAMILY_IGNORED)
     483      queueFamiliySet.insert(queueFamilies.videoDecode);
     484#endif
     485
    472486    this->logQueueFamilies(queueFamilies);
    473487   
     
    520534    queues.transfer = getDeviceQueue(vkd, queueFamilies.transfer, 0);
    521535    queues.sparse = getDeviceQueue(vkd, queueFamilies.sparse, 0);
     536#ifdef VBOX_WITH_DXVK_VIDEO
     537    queues.videoDecode = getDeviceQueue(vkd, queueFamilies.videoDecode, 0);
     538#endif
    522539
    523540    return new DxvkDevice(instance, this, vkd, enabledFeatures, queues, DxvkQueueCallback());
     
    719736      }
    720737    }
     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
    721744  }
    722745 
     
    964987    if (m_deviceExtensions.supports(VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME))
    965988      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
    966994
    967995    m_vki->vkGetPhysicalDeviceFeatures2(m_handle, &m_deviceFeatures.core);
     
    10291057      &devExtensions.nvxBinaryImport,
    10301058      &devExtensions.nvxImageViewHandle,
     1059#ifdef VBOX_WITH_DXVK_VIDEO
     1060      &devExtensions.khrVideoQueue,
     1061      &devExtensions.khrVideoDecodeQueue,
     1062      &devExtensions.khrVideoDecodeH264,
     1063#endif
    10311064    }};
    10321065  }
     
    11791212    if (devExtensions.khrWin32KeyedMutex)
    11801213      enabledFeatures.khrWin32KeyedMutex = VK_TRUE;
     1214
     1215#ifdef VBOX_WITH_DXVK_VIDEO
     1216    if (devExtensions.khrVideoDecodeQueue)
     1217      enabledFeatures.khrVideoDecodeQueue = VK_TRUE;
     1218#endif
    11811219  }
    11821220
     
    13311369      "\n", VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME,
    13321370      "\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
    13331376  }
    13341377
     
    13381381      "\n  Graphics : ", queues.graphics,
    13391382      "\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
    13401387      "\n  Sparse   : ", queues.sparse != VK_QUEUE_FAMILY_IGNORED ? str::format(queues.sparse) : "n/a"));
     1388#endif
    13411389  }
    13421390 
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_adapter.h

    r105107 r108229  
    5757    uint32_t transfer;
    5858    uint32_t sparse;
     59#ifdef VBOX_WITH_DXVK_VIDEO
     60    uint32_t videoDecode;
     61#endif
    5962  };
    6063 
     
    303306    }
    304307
     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
    305316  private:
    306317   
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_buffer.cpp

    r105107 r108229  
    9898  DxvkBufferHandle DxvkBuffer::allocBuffer(VkDeviceSize sliceCount, bool clear) const {
    9999    VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
     100#ifdef VBOX_WITH_DXVK_VIDEO
     101    info.pNext = m_info.pNext;
     102#endif
    100103    info.flags = m_info.flags;
    101104    info.size = m_physSliceStride * sliceCount;
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_buffer.h

    r105107 r108229  
    3535    /// Allowed access patterns
    3636    VkAccessFlags access;
     37
     38#ifdef VBOX_WITH_DXVK_VIDEO
     39    /// VkBufferCreateInfo::pNext
     40    void* pNext = nullptr;
     41#endif
    3742  };
    3843 
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_cmdlist.cpp

    r105107 r108229  
    174174    const auto& graphicsQueue = m_device->queues().graphics;
    175175    const auto& transferQueue = m_device->queues().transfer;
     176#ifdef VBOX_WITH_DXVK_VIDEO
     177    const auto& videoDecodeQueue = m_device->queues().videoDecode;
     178#endif
    176179
    177180    VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
     
    182185      throw DxvkError("DxvkCommandList: Failed to create semaphore");
    183186
     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
    184198    VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
    185199
     
    193207    else
    194208      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
    195214  }
    196215 
     
    202221    m_vkd->vkDestroySemaphore(m_vkd->device(), m_postSemaphore, nullptr);
    203222    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
    204226
    205227    m_vkd->vkDestroyFence(m_vkd->device(), m_fence, nullptr);
     
    207229 
    208230 
     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
    209251  VkResult DxvkCommandList::submit() {
    210252    VkResult status = VK_SUCCESS;
     
    213255    const auto& transfer = m_device->queues().transfer;
    214256    const auto& sparse = m_device->queues().sparse;
     257#ifdef VBOX_WITH_DXVK_VIDEO
     258    const auto& videoDecode = m_device->queues().videoDecode;
     259#endif
    215260
    216261    m_commandSubmission.reset();
     
    274319
    275320      // 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
    276327      if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer))
    277328        m_commandSubmission.executeCommandBuffer(cmd.initBuffer);
     329#endif
    278330
    279331      if (cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer))
     
    300352      if ((status = m_commandSubmission.submit(m_device, graphics.queueHandle)))
    301353        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
    302372    }
    303373
     
    313383    m_cmd.initBuffer = m_graphicsPool->getCommandBuffer();
    314384    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
    315389  }
    316390 
     
    325399    this->endCommandBuffer(m_cmd.initBuffer);
    326400    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
    327405
    328406    // Reset all command buffer handles
     
    355433    }
    356434
     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
    357446    m_cmd.usedFlags = 0;
    358447  }
     
    360449 
    361450  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
    362466    return m_vkd->vkWaitForFences(m_vkd->device(), 1, &m_fence, VK_TRUE, ~0ull);
    363467  }
     
    403507    m_graphicsPool->reset();
    404508    m_transferPool->reset();
     509#ifdef VBOX_WITH_DXVK_VIDEO
     510    if (m_videoDecodePool.ptr() != nullptr)
     511      m_videoDecodePool->reset();
     512#endif
    405513
    406514    // Reset fence
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_cmdlist.h

    r105107 r108229  
    3131    ExecBuffer = 1,
    3232    SdmaBuffer = 2,
     33#ifdef VBOX_WITH_DXVK_VIDEO
     34    VDecBuffer = 3,
     35#endif
    3336  };
    3437 
     
    119122  };
    120123
     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
    121137
    122138  /**
     
    131147    VkCommandBuffer     initBuffer  = VK_NULL_HANDLE;
    132148    VkCommandBuffer     sdmaBuffer  = VK_NULL_HANDLE;
     149#ifdef VBOX_WITH_DXVK_VIDEO
     150    VkCommandBuffer     vdecBuffer  = VK_NULL_HANDLE;
     151#endif
    133152    VkBool32            sparseBind  = VK_FALSE;
    134153    uint32_t            sparseCmd   = 0;
     154#ifdef VBOX_WITH_DXVK_VIDEO
     155    std::vector<DxvkCommandSubmissionFence> submissionFences;
     156#endif
    135157  };
    136158
     
    9991021
    10001022
     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
    10011064    void bindBufferMemory(
    10021065      const DxvkSparseBufferBindKey& key,
     
    10351098    Rc<DxvkCommandPool>       m_graphicsPool;
    10361099    Rc<DxvkCommandPool>       m_transferPool;
     1100#ifdef VBOX_WITH_DXVK_VIDEO
     1101    Rc<DxvkCommandPool>       m_videoDecodePool;
     1102#endif
    10371103
    10381104    VkSemaphore               m_bindSemaphore = VK_NULL_HANDLE;
    10391105    VkSemaphore               m_postSemaphore = VK_NULL_HANDLE;
    10401106    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
    10411111    VkFence                   m_fence         = VK_NULL_HANDLE;
    10421112
     
    10701140      if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_cmd.initBuffer;
    10711141      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
    10721145      return VK_NULL_HANDLE;
    10731146    }
     
    10851158    void endCommandBuffer(VkCommandBuffer cmdBuffer);
    10861159
     1160#ifdef VBOX_WITH_DXVK_VIDEO
     1161    void addSubmissionFences(
     1162      DxvkCmdBuffer cmdBuffer,
     1163      const DxvkCommandSubmissionInfo& cmd);
     1164#endif
    10871165  };
    10881166 
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_context.h

    r105107 r108229  
    856856            uint32_t          counterBias);
    857857   
     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
    858955    /**
    859956     * \brief Emits graphics barrier
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_device.cpp

    r105107 r108229  
    197197
    198198
     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
    199211  DxvkStatCounters DxvkDevice::getStatCounters() {
    200212    DxvkPipelineCount pipe = m_objects.pipelineManager().getPipelineCount();
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_device.h

    r105107 r108229  
    2626#include "dxvk_unbound.h"
    2727#include "dxvk_marker.h"
     28#ifdef VBOX_WITH_DXVK_VIDEO
     29#include "dxvk_video_decoder.h"
     30#endif
    2831
    2932namespace dxvk {
     
    6669    DxvkDeviceQueue transfer;
    6770    DxvkDeviceQueue sparse;
     71#ifdef VBOX_WITH_DXVK_VIDEO
     72    DxvkDeviceQueue videoDecode;
     73#endif
    6874  };
    6975 
     
    361367    Rc<DxvkSparsePageAllocator> createSparsePageAllocator();
    362368
     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
    363386    /**
    364387     * \brief Imports a buffer
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_device_info.h

    r105107 r108229  
    7373    VkBool32                                                  nvxImageViewHandle;
    7474    VkBool32                                                  khrWin32KeyedMutex;
     75#ifdef VBOX_WITH_DXVK_VIDEO
     76    VkBool32                                                  khrVideoDecodeQueue;
     77#endif
    7578  };
    7679
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_extensions.h

    r105107 r108229  
    329329    DxvkExt nvxBinaryImport                   = { VK_NVX_BINARY_IMPORT_EXTENSION_NAME,                      DxvkExtMode::Disabled };
    330330    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
    331336  };
    332337 
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_image.cpp

    r105107 r108229  
    2121    // allows some drivers to enable image compression
    2222    VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO };
     23#ifdef VBOX_WITH_DXVK_VIDEO
     24    formatList.pNext           = createInfo.pNext;
     25#endif
    2326    formatList.viewFormatCount = createInfo.viewFormatCount;
    2427    formatList.pViewFormats    = createInfo.viewFormats;
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_image.h

    r105107 r108229  
    7070    // Shared handle info
    7171    DxvkSharedHandleInfo sharing;
     72
     73#ifdef VBOX_WITH_DXVK_VIDEO
     74    void* pNext = nullptr;
     75#endif
    7276  };
    7377 
  • trunk/src/libs/dxvk-2.3.1/src/dxvk/dxvk_instance.cpp

    r107544 r108229  
    351351    std::stringstream str;
    352352
     353#ifdef VBOX
     354    str << "VKValidation: ";
     355#endif
     356
    353357    if (pCallbackData->pMessageIdName)
    354358      str << pCallbackData->pMessageIdName << ": " << std::endl;
  • trunk/src/libs/dxvk-2.3.1/src/util/com/com_include.h

    r107544 r108229  
    66#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
    77#endif // __GNUC__
     8
     9#ifdef VBOX
     10#include <iprt/asm.h>
     11#endif
    812
    913#define WIN32_LEAN_AND_MEAN
  • trunk/src/libs/dxvk-2.3.1/src/vulkan/vulkan_loader.h

    r105107 r108229  
    169169    VULKAN_FN(vkReleaseSwapchainImagesEXT);
    170170    #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 */
    171178  };
    172179 
     
    453460    VULKAN_FN(wine_vkReleaseKeyedMutex);
    454461    #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 */
    455481  };
    456482 
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette