Virtualbox WDDM之DxgkDdiRecommendFunctionalVidPn

The DxgkDdiRecommendFunctionalVidPn function creates a functional VidPN that can be implemented on a specified display adapter.

https://msdn.microsoft.com/en-us/library/windows/hardware/ff559775(v=vs.85).aspx


A VidPN is functional if it satisfies the following conditions:

  • It has a topology that has at least one path. (A path is an association between a source and a target.)

  • Every source and target in the topology has a pinned mode.

The job of DxgkDdiRecommendFunctionalVidPn is to create a functional VidPN that can be implemented on the display adapter. The following list gives the steps used to create a functional VidPN.

  1. Start with a handle to an empty VidPN object. This handle was supplied in the hDesiredVidPnmember of pRecommendFunctionalVidPnArg.

  2. Add a path (source-target pair) to the topology of the VidPN.

  3. Create a new source mode set and add one source mode to the set. Assign the source mode set to the source in your path. Pin the source mode.

  4. Create a new target mode set and add one target mode to the set. Assign the target mode set to the target in your path. Pin the target mode.





NTSTATUS
APIENTRY
DxgkDdiRecommendFunctionalVidPn(
    CONST HANDLE  hAdapter,
    CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST  pRecommendFunctionalVidPnArg
    )
{
    /* The DxgkDdiRecommendFunctionalVidPn should be made pageable. */
    PAGED_CODE();


    dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));


    PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
    const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>/* 获得DXGK_VIDPN_INTERFACE,这样就能调用VidPN manger提供的接口来创建VidPN */
    NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
    if(Status == STATUS_SUCCESS)
    {
        D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
        const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;


<span style="white-space:pre">		</span>/* 获得Topology网络 */
        Status = pVidPnInterface->pfnGetTopology(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
        if(Status == STATUS_SUCCESS)
        {
            D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo;


<span style="white-space:pre">			</span>/* 创建一个path  */
            Status = pVidPnTopologyInterface->pfnCreateNewPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
            if(Status == STATUS_SUCCESS)
            {
                pNewVidPnPresentPathInfo->VidPnSourceId = 0;
                pNewVidPnPresentPathInfo->VidPnTargetId = 0;
                pNewVidPnPresentPathInfo->ImportanceOrdinal = D3DKMDT_VPPI_PRIMARY;
                pNewVidPnPresentPathInfo->ContentTransformation.Scaling = D3DKMDT_VPPS_IDENTITY;
                memset(&pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport,
                        0, sizeof(pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport));
                pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity = 1;
                pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered = 1;
                pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched = 0;
                pNewVidPnPresentPathInfo->ContentTransformation.Rotation = D3DKMDT_VPPR_IDENTITY;
                pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity = 1;
                pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180 = 0;
                pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270 = 0;
                pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90 = 0;
                pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx = 0;
                pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy = 0;
                pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx = 0;
                pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy = 0;
                pNewVidPnPresentPathInfo->VidPnTargetColorBasis = D3DKMDT_CB_SRGB; /* @todo: how does it matters? */
                pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel =  8;
                pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel =  8;
                pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel =  8;
                pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel =  0;
                pNewVidPnPresentPathInfo->Content = D3DKMDT_VPPC_GRAPHICS;
                pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_NOPROTECTION;
                pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits = 0;
                memset(&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, 0, sizeof(pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport));
                pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport.NoProtection  = 1;
                pNewVidPnPresentPathInfo->GammaRamp.Type = D3DDDI_GAMMARAMP_DEFAULT;
                pNewVidPnPresentPathInfo->GammaRamp.DataSize = 0;


<span style="white-space:pre">				</span>/* topology加入path  */
                Status = pVidPnTopologyInterface->pfnAddPath(hVidPnTopology, pNewVidPnPresentPathInfo);
                if(Status == STATUS_SUCCESS)
                {
                    D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
                    const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface;


<span style="white-space:pre">					</span>/* 创建SourceModeSet */
                    Status = pVidPnInterface->pfnCreateNewSourceModeSet(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn,
                                    0, /*__in CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID  VidPnSourceId */
                                    &hNewVidPnSourceModeSet,
                                    &pVidPnSourceModeSetInterface);
                    if(Status == STATUS_SUCCESS)
                    {
                        D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;


<span style="white-space:pre">						</span>/* 创建一个Source Mode */
                        Status = pVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
                        if(Status == STATUS_SUCCESS)
                        {
                            D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID modeId = pNewVidPnSourceModeInfo->Id;
                            pNewVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS;
                            /* @todo: should we obtain the default mode from the host? */
                            pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = 1024;
                            pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = 768;
                            pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
                            pNewVidPnSourceModeInfo->Format.Graphics.Stride = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx * 4;
                            pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat = D3DDDIFMT_X8R8G8B8;
                            pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SRGB;
                            pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT;


<span style="white-space:pre">							</span>/* Source Mode Set加入Source Mode */
                            Status = pVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
                            if(Status == STATUS_SUCCESS)
                            {
                                Status = pVidPnSourceModeSetInterface->pfnPinMode(hNewVidPnSourceModeSet, modeId);
                                if(Status == STATUS_SUCCESS)
                                {


                                }
                                else
                                {
                                    drprintf(("VBoxVideoWddm: pfnPinMode failed Status(0x%x)\n"));
                                }
                            }
                            else
                            {
                                drprintf(("VBoxVideoWddm: pfnAddMode failed Status(0x%x)\n"));
                                pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
                                pNewVidPnSourceModeInfo = NULL;
                            }
                        }
                        else
                        {
                            drprintf(("VBoxVideoWddm: pfnCreateNewModeInfo failed Status(0x%x)\n"));
                        }
                    }
                    else
                    {
                        drprintf(("VBoxVideoWddm: pfnCreateNewSourceModeSet failed Status(0x%x)\n"));
                    }
                }
                else
                {
                    drprintf(("VBoxVideoWddm: pfnAddPath failed Status(0x%x)\n"));
                    pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
                    pNewVidPnPresentPathInfo = NULL;
                }
            }
            else
            {
                drprintf(("VBoxVideoWddm: pfnCreateNewPathInfo failed Status(0x%x)\n"));
            }
        }
        else
        {
            drprintf(("VBoxVideoWddm: pfnGetTopology failed Status(0x%x)\n"));
        }
    }
    else
    {
        drprintf(("VBoxVideoWddm: DxgkCbQueryVidPnInterface failed Status(0x%x)\n"));
    }


    dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));


    return Status;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kelsel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值