Sample Code
Windows Driver Samples/ Kernel mode display-only miniport driver (KMDOD) sample/ C++/ bdd_dmm.cxx/
/******************************Module*Header*******************************\ * Module Name: bdd_dmm.hxx * * Basic Display Driver display-mode management (DMM) function implementations * * * Copyright (c) 2010 Microsoft Corporation \**************************************************************************/ #include "BDD.hxx" #pragma code_seg("PAGE") // Display-Only Devices can only return display modes of D3DDDIFMT_A8R8G8B8. // Color conversion takes place if the app's fullscreen backbuffer has different format. // Full display drivers can add more if the hardware supports them. D3DDDIFORMAT gBddPixelFormats[] = { D3DDDIFMT_A8R8G8B8 }; // TODO: Need to also check pinned modes and the path parameters, not just topology NTSTATUS BASIC_DISPLAY_DRIVER::IsSupportedVidPn(_Inout_ DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPn) { PAGED_CODE(); BDD_ASSERT(pIsSupportedVidPn != NULL); if (pIsSupportedVidPn->hDesiredVidPn == 0) { // A null desired VidPn is supported pIsSupportedVidPn->IsVidPnSupported = TRUE; return STATUS_SUCCESS; } // Default to not supported, until shown it is supported pIsSupportedVidPn->IsVidPnSupported = FALSE; CONST DXGK_VIDPN_INTERFACE* pVidPnInterface; NTSTATUS Status = m_DxgkInterface.DxgkCbQueryVidPnInterface(pIsSupportedVidPn->hDesiredVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("DxgkCbQueryVidPnInterface failed with Status = 0x%I64x, hDesiredVidPn = 0x%I64x", Status, pIsSupportedVidPn->hDesiredVidPn); return Status; } D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology; CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface; Status = pVidPnInterface->pfnGetTopology(pIsSupportedVidPn->hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnGetTopology failed with Status = 0x%I64x, hDesiredVidPn = 0x%I64x", Status, pIsSupportedVidPn->hDesiredVidPn); return Status; } // For every source in this topology, make sure they don't have more paths than there are targets for (D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId = 0; SourceId < MAX_VIEWS; ++SourceId) { SIZE_T NumPathsFromSource = 0; Status = pVidPnTopologyInterface->pfnGetNumPathsFromSource(hVidPnTopology, SourceId, &NumPathsFromSource); if (Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY) { continue; } else if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnGetNumPathsFromSource failed with Status = 0x%I64x. hVidPnTopology = 0x%I64x, SourceId = 0x%I64x", Status, hVidPnTopology, SourceId); return Status; } else if (NumPathsFromSource > MAX_CHILDREN) { // This VidPn is not supported, which has already been set as the default return STATUS_SUCCESS; } } // All sources succeeded so this VidPn is supported pIsSupportedVidPn->IsVidPnSupported = TRUE; return STATUS_SUCCESS; } NTSTATUS BASIC_DISPLAY_DRIVER::RecommendFunctionalVidPn(_In_ CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPn) { PAGED_CODE(); BDD_ASSERT(pRecommendFunctionalVidPn == NULL); return STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN; } NTSTATUS BASIC_DISPLAY_DRIVER::RecommendVidPnTopology(_In_ CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopology) { PAGED_CODE(); BDD_ASSERT(pRecommendVidPnTopology == NULL); return STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN; } NTSTATUS BASIC_DISPLAY_DRIVER::RecommendMonitorModes(_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes) { PAGED_CODE(); // This is always called to recommend modes for the monitor. The sample driver doesn't provide EDID for a monitor, so // the OS prefills the list with default monitor modes. Since the required mode might not be in the list, it should // be provided as a recommended mode. return AddSingleMonitorMode(pRecommendMonitorModes); } // Tell DMM about all the modes, etc. that are supported NTSTATUS BASIC_DISPLAY_DRIVER::EnumVidPnCofuncModality(_In_ CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModality) { PAGED_CODE(); BDD_ASSERT(pEnumCofuncModality != NULL); D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology = 0; D3DKMDT_HVIDPNSOURCEMODESET hVidPnSourceModeSet = 0; D3DKMDT_HVIDPNTARGETMODESET hVidPnTargetModeSet = 0; CONST DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL; CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface = NULL; CONST DXGK_VIDPNSOURCEMODESET_INTERFACE* pVidPnSourceModeSetInterface = NULL; CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface = NULL; CONST D3DKMDT_VIDPN_PRESENT_PATH* pVidPnPresentPath = NULL; CONST D3DKMDT_VIDPN_PRESENT_PATH* pVidPnPresentPathTemp = NULL; // Used for AcquireNextPathInfo CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnPinnedSourceModeInfo = NULL; CONST D3DKMDT_VIDPN_TARGET_MODE* pVidPnPinnedTargetModeInfo = NULL; // Get the VidPn Interface so we can get the 'Source Mode Set', 'Target Mode Set' and 'VidPn Topology' interfaces NTSTATUS Status = m_DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModality->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("DxgkCbQueryVidPnInterface failed with Status = 0x%I64x, hFunctionalVidPn = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn); return Status; } // Get the VidPn Topology interface so we can enumerate all paths Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModality->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnGetTopology failed with Status = 0x%I64x, hFunctionalVidPn = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn); return Status; } // Get the first path before we start looping through them Status = pVidPnTopologyInterface->pfnAcquireFirstPathInfo(hVidPnTopology, &pVidPnPresentPath); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnAcquireFirstPathInfo failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x", Status, hVidPnTopology); return Status; } // Loop through all available paths. while (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET) { // Get the Source Mode Set interface so the pinned mode can be retrieved Status = pVidPnInterface->pfnAcquireSourceModeSet(pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnSourceId, &hVidPnSourceModeSet, &pVidPnSourceModeSetInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnAcquireSourceModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, SourceId = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnSourceId); break; } // Get the pinned mode, needed when VidPnSource isn't pivot, and when VidPnTarget isn't pivot Status = pVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hVidPnSourceModeSet, &pVidPnPinnedSourceModeInfo); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnAcquirePinnedModeInfo failed with Status = 0x%I64x, hVidPnSourceModeSet = 0x%I64x", Status, hVidPnSourceModeSet); break; } // SOURCE MODES: If this source mode isn't the pivot point, do work on the source mode set if (!((pEnumCofuncModality->EnumPivotType == D3DKMDT_EPT_VIDPNSOURCE) && (pEnumCofuncModality->EnumPivot.VidPnSourceId == pVidPnPresentPath->VidPnSourceId))) { // If there's no pinned source add possible modes (otherwise they've already been added) if (pVidPnPinnedSourceModeInfo == NULL) { // Release the acquired source mode set, since going to create a new one to put all modes in Status = pVidPnInterface->pfnReleaseSourceModeSet(pEnumCofuncModality->hConstrainingVidPn, hVidPnSourceModeSet); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnReleaseSourceModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, hVidPnSourceModeSet = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, hVidPnSourceModeSet); break; } hVidPnSourceModeSet = 0; // Successfully released it // Create a new source mode set which will be added to the constraining VidPn with all the possible modes Status = pVidPnInterface->pfnCreateNewSourceModeSet(pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnSourceId, &hVidPnSourceModeSet, &pVidPnSourceModeSetInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnCreateNewSourceModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, SourceId = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnSourceId); break; } // Add the appropriate modes to the source mode set { Status = AddSingleSourceMode(pVidPnSourceModeSetInterface, hVidPnSourceModeSet, pVidPnPresentPath->VidPnSourceId); } if (!NT_SUCCESS(Status)) { break; } // Give DMM back the source modes just populated Status = pVidPnInterface->pfnAssignSourceModeSet(pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnSourceId, hVidPnSourceModeSet); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR4("pfnAssignSourceModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, SourceId = 0x%I64x, hVidPnSourceModeSet = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnSourceId, hVidPnSourceModeSet); break; } hVidPnSourceModeSet = 0; // Successfully assigned it (equivalent to releasing it) } }// End: SOURCE MODES // TARGET MODES: If this target mode isn't the pivot point, do work on the target mode set if (!((pEnumCofuncModality->EnumPivotType == D3DKMDT_EPT_VIDPNTARGET) && (pEnumCofuncModality->EnumPivot.VidPnTargetId == pVidPnPresentPath->VidPnTargetId))) { // Get the Target Mode Set interface so modes can be added if necessary Status = pVidPnInterface->pfnAcquireTargetModeSet(pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnTargetId, &hVidPnTargetModeSet, &pVidPnTargetModeSetInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnAcquireTargetModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, TargetId = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnTargetId); break; } Status = pVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hVidPnTargetModeSet, &pVidPnPinnedTargetModeInfo); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnAcquirePinnedModeInfo failed with Status = 0x%I64x, hVidPnTargetModeSet = 0x%I64x", Status, hVidPnTargetModeSet); break; } // If there's no pinned target add possible modes (otherwise they've already been added) if (pVidPnPinnedTargetModeInfo == NULL) { // Release the acquired target mode set, since going to create a new one to put all modes in Status = pVidPnInterface->pfnReleaseTargetModeSet(pEnumCofuncModality->hConstrainingVidPn, hVidPnTargetModeSet); if (!NT_SUCCESS(Status)) { BDD_LOG_ASSERTION3("pfnReleaseTargetModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, hVidPnTargetModeSet = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, hVidPnTargetModeSet); break; } hVidPnTargetModeSet = 0; // Successfully released it // Create a new target mode set which will be added to the constraining VidPn with all the possible modes Status = pVidPnInterface->pfnCreateNewTargetModeSet(pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnTargetId, &hVidPnTargetModeSet, &pVidPnTargetModeSetInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnCreateNewTargetModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, TargetId = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnTargetId); break; } Status = AddSingleTargetMode(pVidPnTargetModeSetInterface, hVidPnTargetModeSet, pVidPnPinnedSourceModeInfo, pVidPnPresentPath->VidPnSourceId); if (!NT_SUCCESS(Status)) { break; } // Give DMM back the source modes just populated Status = pVidPnInterface->pfnAssignTargetModeSet(pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnTargetId, hVidPnTargetModeSet); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR4("pfnAssignTargetModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, TargetId = 0x%I64x, hVidPnTargetModeSet = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, pVidPnPresentPath->VidPnTargetId, hVidPnTargetModeSet); break; } hVidPnTargetModeSet = 0; // Successfully assigned it (equivalent to releasing it) } else { // Release the pinned target as there's no other work to do Status = pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pVidPnPinnedTargetModeInfo); if (!NT_SUCCESS(Status)) { BDD_LOG_ASSERTION3("pfnReleaseModeInfo failed with Status = 0x%I64x, hVidPnTargetModeSet = 0x%I64x, pVidPnPinnedTargetModeInfo = 0x%I64x", Status, hVidPnTargetModeSet, pVidPnPinnedTargetModeInfo); break; } pVidPnPinnedTargetModeInfo = NULL; // Successfully released it // Release the acquired target mode set, since it is no longer needed Status = pVidPnInterface->pfnReleaseTargetModeSet(pEnumCofuncModality->hConstrainingVidPn, hVidPnTargetModeSet); if (!NT_SUCCESS(Status)) { BDD_LOG_ASSERTION3("pfnReleaseTargetModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, hVidPnTargetModeSet = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, hVidPnTargetModeSet); break; } hVidPnTargetModeSet = 0; // Successfully released it } }// End: TARGET MODES // Nothing else needs the pinned source mode so release it if (pVidPnPinnedSourceModeInfo != NULL) { Status = pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hVidPnSourceModeSet, pVidPnPinnedSourceModeInfo); if (!NT_SUCCESS(Status)) { BDD_LOG_ASSERTION3("pfnReleaseModeInfo failed with Status = 0x%I64x, hVidPnSourceModeSet = 0x%I64x, pVidPnPinnedSourceModeInfo = 0x%I64x", Status, hVidPnSourceModeSet, pVidPnPinnedSourceModeInfo); break; } pVidPnPinnedSourceModeInfo = NULL; // Successfully released it } // With the pinned source mode now released, if the source mode set hasn't been released, release that as well if (hVidPnSourceModeSet != 0) { Status = pVidPnInterface->pfnReleaseSourceModeSet(pEnumCofuncModality->hConstrainingVidPn, hVidPnSourceModeSet); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnReleaseSourceModeSet failed with Status = 0x%I64x, hConstrainingVidPn = 0x%I64x, hVidPnSourceModeSet = 0x%I64x", Status, pEnumCofuncModality->hConstrainingVidPn, hVidPnSourceModeSet); break; } hVidPnSourceModeSet = 0; // Successfully released it } // If modifying support fields, need to modify a local version of a path structure since the retrieved one is const D3DKMDT_VIDPN_PRESENT_PATH LocalVidPnPresentPath = *pVidPnPresentPath; BOOLEAN SupportFieldsModified = FALSE; // SCALING: If this path's scaling isn't the pivot point, do work on the scaling support if (!((pEnumCofuncModality->EnumPivotType == D3DKMDT_EPT_SCALING) && (pEnumCofuncModality->EnumPivot.VidPnSourceId == pVidPnPresentPath->VidPnSourceId) && (pEnumCofuncModality->EnumPivot.VidPnTargetId == pVidPnPresentPath->VidPnTargetId))) { // If the scaling is unpinned, then modify the scaling support field if (pVidPnPresentPath->ContentTransformation.Scaling == D3DKMDT_VPPS_UNPINNED) { // Identity and centered scaling are supported, but not any stretch modes RtlZeroMemory(&(LocalVidPnPresentPath.ContentTransformation.ScalingSupport), sizeof(D3DKMDT_VIDPN_PRESENT_PATH_SCALING_SUPPORT)); LocalVidPnPresentPath.ContentTransformation.ScalingSupport.Identity = 1; LocalVidPnPresentPath.ContentTransformation.ScalingSupport.Centered = 1; SupportFieldsModified = TRUE; } } // End: SCALING // ROTATION: If this path's rotation isn't the pivot point, do work on the rotation support if (!((pEnumCofuncModality->EnumPivotType != D3DKMDT_EPT_ROTATION) && (pEnumCofuncModality->EnumPivot.VidPnSourceId == pVidPnPresentPath->VidPnSourceId) && (pEnumCofuncModality->EnumPivot.VidPnTargetId == pVidPnPresentPath->VidPnTargetId))) { // If the rotation is unpinned, then modify the rotation support field if (pVidPnPresentPath->ContentTransformation.Rotation == D3DKMDT_VPPR_UNPINNED) { LocalVidPnPresentPath.ContentTransformation.RotationSupport.Identity = 1; // Sample supports only Rotate90 LocalVidPnPresentPath.ContentTransformation.RotationSupport.Rotate90 = 1; LocalVidPnPresentPath.ContentTransformation.RotationSupport.Rotate180 = 0; LocalVidPnPresentPath.ContentTransformation.RotationSupport.Rotate270 = 0; SupportFieldsModified = TRUE; } } // End: ROTATION if (SupportFieldsModified) { // The correct path will be found by this function and the appropriate fields updated Status = pVidPnTopologyInterface->pfnUpdatePathSupportInfo(hVidPnTopology, &LocalVidPnPresentPath); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnUpdatePathSupportInfo failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x", Status, hVidPnTopology); break; } } // Get the next path... // (NOTE: This is the value of Status that will return STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET when it's time to quit the loop) pVidPnPresentPathTemp = pVidPnPresentPath; Status = pVidPnTopologyInterface->pfnAcquireNextPathInfo(hVidPnTopology, pVidPnPresentPathTemp, &pVidPnPresentPath); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnAcquireNextPathInfo failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x, pVidPnPresentPathTemp = 0x%I64x", Status, hVidPnTopology, pVidPnPresentPathTemp); break; } // ...and release the last path NTSTATUS TempStatus = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathTemp); if (!NT_SUCCESS(TempStatus)) { BDD_LOG_ERROR3("pfnReleasePathInfo failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x, pVidPnPresentPathTemp = 0x%I64x", TempStatus, hVidPnTopology, pVidPnPresentPathTemp); Status = TempStatus; break; } pVidPnPresentPathTemp = NULL; // Successfully released it }// End: while loop for paths in topology // If quit the while loop normally, set the return value to success if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET) { Status = STATUS_SUCCESS; } // Release any resources hanging around because the loop was quit early. // Since in normal execution everything should be released by this point, TempStatus is initialized to a bogus error to be used as an // assertion that if anything had to be released now (TempStatus changing) Status isn't successful. NTSTATUS TempStatus = STATUS_NOT_FOUND; if ((pVidPnSourceModeSetInterface != NULL) && (pVidPnPinnedSourceModeInfo != NULL)) { TempStatus = pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hVidPnSourceModeSet, pVidPnPinnedSourceModeInfo); BDD_ASSERT_CHK(NT_SUCCESS(TempStatus)); } if ((pVidPnTargetModeSetInterface != NULL) && (pVidPnPinnedTargetModeInfo != NULL)) { TempStatus = pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pVidPnPinnedTargetModeInfo); BDD_ASSERT_CHK(NT_SUCCESS(TempStatus)); } if (pVidPnPresentPath != NULL) { TempStatus = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPath); BDD_ASSERT_CHK(NT_SUCCESS(TempStatus)); } if (pVidPnPresentPathTemp != NULL) { TempStatus = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathTemp); BDD_ASSERT_CHK(NT_SUCCESS(TempStatus)); } if (hVidPnSourceModeSet != 0) { TempStatus = pVidPnInterface->pfnReleaseSourceModeSet(pEnumCofuncModality->hConstrainingVidPn, hVidPnSourceModeSet); BDD_ASSERT_CHK(NT_SUCCESS(TempStatus)); } if (hVidPnTargetModeSet != 0) { TempStatus = pVidPnInterface->pfnReleaseTargetModeSet(pEnumCofuncModality->hConstrainingVidPn, hVidPnTargetModeSet); BDD_ASSERT_CHK(NT_SUCCESS(TempStatus)); } BDD_ASSERT_CHK(TempStatus == STATUS_NOT_FOUND || Status != STATUS_SUCCESS); return Status; } NTSTATUS BASIC_DISPLAY_DRIVER::SetVidPnSourceVisibility(_In_ CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility) { PAGED_CODE(); BDD_ASSERT(pSetVidPnSourceVisibility != NULL); BDD_ASSERT((pSetVidPnSourceVisibility->VidPnSourceId < MAX_VIEWS) || (pSetVidPnSourceVisibility->VidPnSourceId == D3DDDI_ID_ALL)); UINT StartVidPnSourceId = (pSetVidPnSourceVisibility->VidPnSourceId == D3DDDI_ID_ALL) ? 0 : pSetVidPnSourceVisibility->VidPnSourceId; UINT MaxVidPnSourceId = (pSetVidPnSourceVisibility->VidPnSourceId == D3DDDI_ID_ALL) ? MAX_VIEWS : pSetVidPnSourceVisibility->VidPnSourceId + 1; for (UINT SourceId = StartVidPnSourceId; SourceId < MaxVidPnSourceId; ++SourceId) { if (pSetVidPnSourceVisibility->Visible) { m_CurrentModes[SourceId].Flags.FullscreenPresent = TRUE; } else { BlackOutScreen(SourceId); } // Store current visibility so it can be dealt with during Present call m_CurrentModes[SourceId].Flags.SourceNotVisible = !(pSetVidPnSourceVisibility->Visible); } return STATUS_SUCCESS; } // NOTE: The value of pCommitVidPn->MonitorConnectivityChecks is ignored, since BDD is unable to recognize whether a monitor is connected or not // The value of pCommitVidPn->hPrimaryAllocation is also ignored, since BDD is a display only driver and does not deal with allocations NTSTATUS BASIC_DISPLAY_DRIVER::CommitVidPn(_In_ CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPn) { PAGED_CODE(); BDD_ASSERT(pCommitVidPn != NULL); BDD_ASSERT(pCommitVidPn->AffectedVidPnSourceId < MAX_VIEWS); NTSTATUS Status; SIZE_T NumPaths = 0; D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology = 0; D3DKMDT_HVIDPNSOURCEMODESET hVidPnSourceModeSet = 0; CONST DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL; CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface = NULL; CONST DXGK_VIDPNSOURCEMODESET_INTERFACE* pVidPnSourceModeSetInterface = NULL; CONST D3DKMDT_VIDPN_PRESENT_PATH* pVidPnPresentPath = NULL; CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo = NULL; // Check this CommitVidPn is for the mode change notification when monitor is in power off state. if (pCommitVidPn->Flags.PathPoweredOff) { // Ignore the commitVidPn call for the mode change notification when monitor is in power off state. Status = STATUS_SUCCESS; goto CommitVidPnExit; } // Get the VidPn Interface so we can get the 'Source Mode Set' and 'VidPn Topology' interfaces Status = m_DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPn->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("DxgkCbQueryVidPnInterface failed with Status = 0x%I64x, hFunctionalVidPn = 0x%I64x", Status, pCommitVidPn->hFunctionalVidPn); goto CommitVidPnExit; } // Get the VidPn Topology interface so can enumerate paths from source Status = pVidPnInterface->pfnGetTopology(pCommitVidPn->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnGetTopology failed with Status = 0x%I64x, hFunctionalVidPn = 0x%I64x", Status, pCommitVidPn->hFunctionalVidPn); goto CommitVidPnExit; } // Find out the number of paths now, if it's 0 don't bother with source mode set and pinned mode, just clear current and then quit Status = pVidPnTopologyInterface->pfnGetNumPaths(hVidPnTopology, &NumPaths); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnGetNumPaths failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x", Status, hVidPnTopology); goto CommitVidPnExit; } if (NumPaths != 0) { // Get the Source Mode Set interface so we can get the pinned mode Status = pVidPnInterface->pfnAcquireSourceModeSet(pCommitVidPn->hFunctionalVidPn, pCommitVidPn->AffectedVidPnSourceId, &hVidPnSourceModeSet, &pVidPnSourceModeSetInterface); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnAcquireSourceModeSet failed with Status = 0x%I64x, hFunctionalVidPn = 0x%I64x, SourceId = 0x%I64x", Status, pCommitVidPn->hFunctionalVidPn, pCommitVidPn->AffectedVidPnSourceId); goto CommitVidPnExit; } // Get the mode that is being pinned Status = pVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnAcquirePinnedModeInfo failed with Status = 0x%I64x, hFunctionalVidPn = 0x%I64x", Status, pCommitVidPn->hFunctionalVidPn); goto CommitVidPnExit; } } else { // This will cause the successful quit below pPinnedVidPnSourceModeInfo = NULL; } if (m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].FrameBuffer.Ptr && !m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].Flags.DoNotMapOrUnmap) { Status = UnmapFrameBuffer(m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].FrameBuffer.Ptr, m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].DispInfo.Pitch * m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].DispInfo.Height); m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].FrameBuffer.Ptr = NULL; m_CurrentModes[pCommitVidPn->AffectedVidPnSourceId].Flags.FrameBufferIsActive = FALSE; if (!NT_SUCCESS(Status)) { goto CommitVidPnExit; } } if (pPinnedVidPnSourceModeInfo == NULL) { // There is no mode to pin on this source, any old paths here have already been cleared Status = STATUS_SUCCESS; goto CommitVidPnExit; } Status = IsVidPnSourceModeFieldsValid(pPinnedVidPnSourceModeInfo); if (!NT_SUCCESS(Status)) { goto CommitVidPnExit; } // Get the number of paths from this source so we can loop through all paths SIZE_T NumPathsFromSource = 0; Status = pVidPnTopologyInterface->pfnGetNumPathsFromSource(hVidPnTopology, pCommitVidPn->AffectedVidPnSourceId, &NumPathsFromSource); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR2("pfnGetNumPathsFromSource failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x", Status, hVidPnTopology); goto CommitVidPnExit; } // Loop through all paths to set this mode for (SIZE_T PathIndex = 0; PathIndex < NumPathsFromSource; ++PathIndex) { // Get the target id for this path D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId = D3DDDI_ID_UNINITIALIZED; Status = pVidPnTopologyInterface->pfnEnumPathTargetsFromSource(hVidPnTopology, pCommitVidPn->AffectedVidPnSourceId, PathIndex, &TargetId); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR4("pfnEnumPathTargetsFromSource failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x, SourceId = 0x%I64x, PathIndex = 0x%I64x", Status, hVidPnTopology, pCommitVidPn->AffectedVidPnSourceId, PathIndex); goto CommitVidPnExit; } // Get the actual path info Status = pVidPnTopologyInterface->pfnAcquirePathInfo(hVidPnTopology, pCommitVidPn->AffectedVidPnSourceId, TargetId, &pVidPnPresentPath); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR4("pfnAcquirePathInfo failed with Status = 0x%I64x, hVidPnTopology = 0x%I64x, SourceId = 0x%I64x, TargetId = 0x%I64x", Status, hVidPnTopology, pCommitVidPn->AffectedVidPnSourceId, TargetId); goto CommitVidPnExit; } Status = IsVidPnPathFieldsValid(pVidPnPresentPath); if (!NT_SUCCESS(Status)) { goto CommitVidPnExit; } Status = SetSourceModeAndPath(pPinnedVidPnSourceModeInfo, pVidPnPresentPath); if (!NT_SUCCESS(Status)) { goto CommitVidPnExit; } Status = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPath); if (!NT_SUCCESS(Status)) { BDD_LOG_ERROR3("pfnReleasePathInfo failed with Status = 0x%I64x, hVidPnTopoogy = 0x%I64x, pVidPnPresentPath = 0x%I64x", Status, hVidPnTopology, pVidPnPresentPath); goto CommitVidPnExit; } pVidPnPresentPath = NULL; // Successfully released it } CommitVidPnExit: NTSTATUS TempStatus; UNREFERENCED_PARAMETER(TempStatus); if ((pVidPnSourceModeSetInterface != NULL) && (hVidPnSourceModeSet != 0) && (pPinnedVidPnSourceModeInfo != NULL)) { TempStatus = pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hVidPnSourceModeSet, pPinnedVidPnSourceModeInfo); NT_ASSERT(NT_SUCCESS(TempStatus)); } if ((pVidPnInterface != NULL) && (pCommitVidPn->hFunctionalVidPn != 0) && (hVidPnSourceModeSet != 0)) { TempStatus = pVidPnInterface->pfnReleaseSourceModeSet(pCommitVidPn->hFunctionalVidPn, hVidPnSourceModeSet); NT_ASSERT(NT_SUCCESS(TempStatus)); } if ((pVidPnTopologyInterface != NULL) && (hVidPnTopology != 0) && (pVidPnPresentPath != NULL)) { TempStatus = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPath); NT_ASSERT(NT_SUCCESS(TempStatus)); } return Status; } NTSTATUS BASIC_DISPLAY_DRIVER::UpdateActiveVidPnPresentPath(_In_ CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPath) { PAGED_CODE(); BDD_ASSERT(pUpdateActiveVidPnPresentPath != NULL); NTSTATUS Status = IsVidPnPathFieldsValid(&(pUpdateActiveVidPnPresentPath->VidPnPresentPathInfo)); if (!NT_SUCCESS(Status)) { return Status; } // Mark the next present as fullscreen to make sure the full rotation comes through m_CurrentModes[pUpdateActiveVidPnPresentPath->VidPnPresentPathInfo.VidPnSourceId].Flags.FullscreenPresent = TRUE; m_CurrentModes[pUpdateActiveVidPnPresentPath->VidPnPresentPathInfo.VidPnSourceId].Rotation = pUpdateActiveVidPnPresentPath->VidPnPresentPathInfo.ContentTransformation.Rotation; return STATUS_SUCCESS; } // // Private BDD DMM functions // NTSTATUS BASIC_DISPLAY_DRIVER::SetSourceModeAndPath(CONST D3DKMDT_VIDPN_SOURCE_MODE* pSourceMode, CONST D3DKMDT_VIDPN_PRESENT_PATH* pPath) { PAGED_CODE(); CURRENT_BDD_MODE* pCurrentBddMode = &m_CurrentModes[pPath->VidPnSourceId]; NTSTATUS Status = STATUS_SUCCESS; pCurrentBddMode->Scaling = pPath->ContentTransformation.Scaling; pCurrentBddMode->SrcModeWidth = pSourceMode->Format.Graphics.PrimSurfSize.cx; pCurrentBddMode->SrcModeHeight = pSourceMode->Format.Graphics.PrimSurfSize.cy; pCurrentBddMode->Rotation = pPath->ContentTransformation.Rotation; if (!pCurrentBddMode->Flags.DoNotMapOrUnmap) { // Map the new frame buffer BDD_ASSERT(pCurrentBddMode->FrameBuffer.Ptr == NULL); Status = MapFrameBuffer(pCurrentBddMode->DispInfo.PhysicAddress, pCurrentBddMode->DispInfo.Pitch * pCurrentBddMode->DispInfo.Height, &(pCurrentBddMode->FrameBuffer.Ptr)); } if (NT_SUCCESS(Status)) { pCurrentBddMode->Flags.FrameBufferIsActive = TRUE; BlackOutScreen(pPath->VidPnSourceId); // Mark that the next present should be fullscreen so the screen doesn't go from black to actual pixels one dirty rect at a time. pCurrentBddMode->Flags.FullscreenPresent = TRUE; } return Status; } NTSTATUS BASIC_DISPLAY_DRIVER::IsVidPnPathFieldsValid(CONST D3DKMDT_VIDPN_PRESENT_PATH* pPath) const { PAGED_CODE(); if (pPath->VidPnSourceId >= MAX_VIEWS) { BDD_LOG_ERROR2("VidPnSourceId is 0x%I64x is too high (MAX_VIEWS is 0x%I64x)", pPath->VidPnSourceId, MAX_VIEWS); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE; } else if (pPath->VidPnTargetId >= MAX_CHILDREN) { BDD_LOG_ERROR2("VidPnTargetId is 0x%I64x is too high (MAX_CHILDREN is 0x%I64x)", pPath->VidPnTargetId, MAX_CHILDREN); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET; } else if (pPath->GammaRamp.Type != D3DDDI_GAMMARAMP_DEFAULT) { BDD_LOG_ERROR1("pPath contains a gamma ramp (0x%I64x)", pPath->GammaRamp.Type); return STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED; } else if ((pPath->ContentTransformation.Scaling != D3DKMDT_VPPS_IDENTITY) && (pPath->ContentTransformation.Scaling != D3DKMDT_VPPS_CENTERED) && (pPath->ContentTransformation.Scaling != D3DKMDT_VPPS_NOTSPECIFIED) && (pPath->ContentTransformation.Scaling != D3DKMDT_VPPS_UNINITIALIZED)) { BDD_LOG_ERROR1("pPath contains a non-identity scaling (0x%I64x)", pPath->ContentTransformation.Scaling); return STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED; } else if ((pPath->ContentTransformation.Rotation != D3DKMDT_VPPR_IDENTITY) && (pPath->ContentTransformation.Rotation != D3DKMDT_VPPR_ROTATE90) && (pPath->ContentTransformation.Rotation != D3DKMDT_VPPR_NOTSPECIFIED) && (pPath->ContentTransformation.Rotation != D3DKMDT_VPPR_UNINITIALIZED)) { BDD_LOG_ERROR1("pPath contains a not-supported rotation (0x%I64x)", pPath->ContentTransformation.Rotation); return STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED; } else if ((pPath->VidPnTargetColorBasis != D3DKMDT_CB_SCRGB) && (pPath->VidPnTargetColorBasis != D3DKMDT_CB_UNINITIALIZED)) { BDD_LOG_ERROR1("pPath has a non-linear RGB color basis (0x%I64x)", pPath->VidPnTargetColorBasis); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE; } else { return STATUS_SUCCESS; } } NTSTATUS BASIC_DISPLAY_DRIVER::IsVidPnSourceModeFieldsValid(CONST D3DKMDT_VIDPN_SOURCE_MODE* pSourceMode) const { PAGED_CODE(); if (pSourceMode->Type != D3DKMDT_RMT_GRAPHICS) { BDD_LOG_ERROR1("pSourceMode is a non-graphics mode (0x%I64x)", pSourceMode->Type); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE; } else if ((pSourceMode->Format.Graphics.ColorBasis != D3DKMDT_CB_SCRGB) && (pSourceMode->Format.Graphics.ColorBasis != D3DKMDT_CB_UNINITIALIZED)) { BDD_LOG_ERROR1("pSourceMode has a non-linear RGB color basis (0x%I64x)", pSourceMode->Format.Graphics.ColorBasis); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE; } else if (pSourceMode->Format.Graphics.PixelValueAccessMode != D3DKMDT_PVAM_DIRECT) { BDD_LOG_ERROR1("pSourceMode has a palettized access mode (0x%I64x)", pSourceMode->Format.Graphics.PixelValueAccessMode); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE; } else { for (UINT PelFmtIdx = 0; PelFmtIdx < ARRAYSIZE(gBddPixelFormats); ++PelFmtIdx) { if (pSourceMode->Format.Graphics.PixelFormat == gBddPixelFormats[PelFmtIdx]) { return STATUS_SUCCESS; } } BDD_LOG_ERROR1("pSourceMode has an unknown pixel format (0x%I64x)", pSourceMode->Format.Graphics.PixelFormat); return STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE; } } // Add more mode from the table. struct SampleSourceMode { UINT ModeWidth; UINT ModeHeight; }; // The driver will advertise all modes that fit within the actual required mode (see AddSingleSourceMode below) const static SampleSourceMode C_SampleSourceMode[] = {{800,600},{1024,768},{1152,864},{1280,800},{1280,1024},{1400,1050},{1600,1200},{1680,1050},{1920,1200}}; const static UINT C_SampleSourceModeMax = sizeof(C_SampleSourceMode)/sizeof(C_SampleSourceMode[0]); NTSTATUS BASIC_DISPLAY_DRIVER::AddSingleSourceMode(_In_ CONST DXGK_VIDPNSOURCEMODESET_INTERFACE* pVidPnSourceModeSetInterface, D3DKMDT_HVIDPNSOURCEMODESET hVidPnSourceModeSet, D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId) { PAGED_CODE(); // There is only one source format supported by display-only drivers, but more can be added in a // full WDDM driver if the hardware supports them for (UINT PelFmtIdx = 0; PelFmtIdx < ARRAYSIZE(gBddPixelFormats); ++PelFmtIdx) { // Create new mode info that will be populated D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo = NULL; NTSTATUS Status = pVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hVidPnSourceModeSet, &pVidPnSourceModeInfo); if (!NT_SUCCESS(Status)) { // If failed to create a new mode info, mode doesn't need to be released since it was never created BDD_LOG_ERROR2("pfnCreateNewModeInfo failed with Status = 0x%I64x, hVidPnSourceModeSet = 0x%I64x", Status, hVidPnSourceModeSet); return Status; } // Populate mode info with values from current mode and hard-coded values // Always report 32 bpp format, this will be color converted during the present if the mode is < 32bpp pVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS; pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = m_CurrentModes[SourceId].DispInfo.Width; pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = m_CurrentModes[SourceId].DispInfo.Height; pVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize; pVidPnSourceModeInfo->Format.Graphics.Stride = m_CurrentModes[SourceId].DispInfo.Pitch; pVidPnSourceModeInfo->Format.Graphics.PixelFormat = gBddPixelFormats[PelFmtIdx]; pVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SCRGB; pVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT; // Add the mode to the source mode set Status = pVidPnSourceModeSetInterface->pfnAddMode(hVidPnSourceModeSet, pVidPnSourceModeInfo); if (!NT_SUCCESS(Status)) { // If adding the mode failed, release the mode, if this doesn't work there is nothing that can be done, some memory will get leaked NTSTATUS TempStatus = pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hVidPnSourceModeSet, pVidPnSourceModeInfo); UNREFERENCED_PARAMETER(TempStatus); NT_ASSERT(NT_SUCCESS(TempStatus)); if (Status != STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET) { BDD_LOG_ERROR3("pfnAddMode failed with Status = 0x%I64x, hVidPnSourceModeSet = 0x%I64x, pVidPnSourceModeInfo = 0x%I64x", Status, hVidPnSourceModeSet, pVidPnSourceModeInfo); return Status; } } } UINT WidthMax = m_CurrentModes[SourceId].DispInfo.Width; UINT HeightMax = m_CurrentModes[SourceId].DispInfo.Height; // Add all predefined modes that fit within the bounds of the required (POST) mode for (UINT ModeIndex = 0; ModeIndex < C_SampleSourceModeMax; ++ModeIndex) { if (C_SampleSourceMode[ModeIndex].ModeWidth > WidthMax) { break; } else if (C_SampleSourceMode[ModeIndex].ModeWidth == WidthMax) { if(C_SampleSourceMode[ModeIndex].ModeHeight >= HeightMax) { break; } } else { if(C_SampleSourceMode[ModeIndex].ModeHeight > HeightMax) { continue; } } // There is only one source format supported by display-only drivers, but more can be added in a // full WDDM driver if the hardware supports them for (UINT PelFmtIdx = 0; PelFmtIdx < ARRAYSIZE(gBddPixelFormats); ++PelFmtIdx) { // Create new mode info that will be populated D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo = NULL; NTSTATUS Status = pVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hVidPnSourceModeSet, &pVidPnSourceModeInfo); if (!NT_SUCCESS(Status)) { // If failed to create a new mode info, continuing to the next mode and trying again isn't going to be at all helpful, so return // Also, mode doesn't need to be released since it was never created BDD_LOG_ERROR2("pfnCreateNewModeInfo failed with Status = 0x%I64x, hVidPnSourceModeSet = 0x%I64x", Status, hVidPnSourceModeSet); return Status; } // Populate mode info with values from mode at ModeIndex and hard-coded values // Always report 32 bpp format, this will be color converted during the present if the mode at ModeIndex was < 32bpp pVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS; pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = C_SampleSourceMode[ModeIndex].ModeWidth; pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = C_SampleSourceMode[ModeIndex].ModeHeight; pVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize; pVidPnSourceModeInfo->Format.Graphics.Stride = 4*C_SampleSourceMode[ModeIndex].ModeWidth; pVidPnSourceModeInfo->Format.Graphics.PixelFormat = gBddPixelFormats[PelFmtIdx]; pVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SCRGB; pVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT; // Add the mode to the source mode set Status = pVidPnSourceModeSetInterface->pfnAddMode(hVidPnSourceModeSet, pVidPnSourceModeInfo); if (!NT_SUCCESS(Status)) { if (Status != STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET) { BDD_LOG_ERROR3("pfnAddMode failed with Status = 0x%I64x, hVidPnSourceModeSet = 0x%I64x, pVidPnSourceModeInfo = 0x%I64x", Status, hVidPnSourceModeSet, pVidPnSourceModeInfo); } // If adding the mode failed, release the mode, if this doesn't work there is nothing that can be done, some memory will get leaked, continue to next mode anyway Status = pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hVidPnSourceModeSet, pVidPnSourceModeInfo); BDD_ASSERT_CHK(NT_SUCCESS(Status)); } } } return STATUS_SUCCESS; } // Add the current mode information (acquired from the POST frame buffer) as the target mode. NTSTATUS BASIC_DISPLAY_DRIVER::AddSingleTargetMode(_In_ CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface, D3DKMDT_HVIDPNTARGETMODESET hVidPnTargetModeSet, _In_opt_ CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnPinnedSourceModeInfo, D3DDDI_VIDEO_PRESENT_SOURCE_ID SourceId) { PAGED_CODE(); D3DKMDT_VIDPN_TARGET_MODE* pVidPnTargetModeInfo = NULL; NTSTATUS Status = pVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hVidPnTargetModeSet, &pVidPnTargetModeInfo); if (!NT_SUCCESS(Status)) { // If failed to create a new mode info, mode doesn't need to be released since it was never created BDD_LOG_ERROR2("pfnCreateNewModeInfo failed with Status = 0x%I64x, hVidPnTargetModeSet = 0x%I64x", Status, hVidPnTargetModeSet); return Status; } pVidPnTargetModeInfo->VideoSignalInfo.VideoStandard = D3DKMDT_VSS_OTHER; UNREFERENCED_PARAMETER(pVidPnPinnedSourceModeInfo); pVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cx = m_CurrentModes[SourceId].DispInfo.Width; pVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy = m_CurrentModes[SourceId].DispInfo.Height; pVidPnTargetModeInfo->VideoSignalInfo.ActiveSize = pVidPnTargetModeInfo->VideoSignalInfo.TotalSize; pVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Numerator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Denominator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Numerator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Denominator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pVidPnTargetModeInfo->VideoSignalInfo.PixelRate = D3DKMDT_FREQUENCY_NOTSPECIFIED; pVidPnTargetModeInfo->VideoSignalInfo.ScanLineOrdering = D3DDDI_VSSLO_PROGRESSIVE; // We add this as PREFERRED since it is the only supported target pVidPnTargetModeInfo->Preference = D3DKMDT_MP_PREFERRED; Status = pVidPnTargetModeSetInterface->pfnAddMode(hVidPnTargetModeSet, pVidPnTargetModeInfo); if (!NT_SUCCESS(Status)) { if (Status != STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET) { BDD_LOG_ERROR3("pfnAddMode failed with Status = 0x%I64x, hVidPnTargetModeSet = 0x%I64x, pVidPnTargetModeInfo = 0x%I64x", Status, hVidPnTargetModeSet, pVidPnTargetModeInfo); } else { Status = STATUS_SUCCESS; } // If adding the mode failed, release the mode, if this doesn't work there is nothing that can be done, some memory will get leaked NTSTATUS TempStatus = pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pVidPnTargetModeInfo); UNREFERENCED_PARAMETER(TempStatus); NT_ASSERT(NT_SUCCESS(TempStatus)); return Status; } else { // If AddMode succeeded with something other than STATUS_SUCCESS treat it as such anyway when propagating up return STATUS_SUCCESS; } } NTSTATUS BASIC_DISPLAY_DRIVER::AddSingleMonitorMode(_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes) { PAGED_CODE(); D3DKMDT_MONITOR_SOURCE_MODE* pMonitorSourceMode = NULL; NTSTATUS Status = pRecommendMonitorModes->pMonitorSourceModeSetInterface->pfnCreateNewModeInfo(pRecommendMonitorModes->hMonitorSourceModeSet, &pMonitorSourceMode); if (!NT_SUCCESS(Status)) { // If failed to create a new mode info, mode doesn't need to be released since it was never created BDD_LOG_ERROR2("pfnCreateNewModeInfo failed with Status = 0x%I64x, hMonitorSourceModeSet = 0x%I64x", Status, pRecommendMonitorModes->hMonitorSourceModeSet); return Status; } D3DDDI_VIDEO_PRESENT_SOURCE_ID CorrespondingSourceId = FindSourceForTarget(pRecommendMonitorModes->VideoPresentTargetId, TRUE); // Since we don't know the real monitor timing information, just use the current display mode (from the POST device) with unknown frequencies pMonitorSourceMode->VideoSignalInfo.VideoStandard = D3DKMDT_VSS_OTHER; pMonitorSourceMode->VideoSignalInfo.TotalSize.cx = m_CurrentModes[CorrespondingSourceId].DispInfo.Width; pMonitorSourceMode->VideoSignalInfo.TotalSize.cy = m_CurrentModes[CorrespondingSourceId].DispInfo.Height; pMonitorSourceMode->VideoSignalInfo.ActiveSize = pMonitorSourceMode->VideoSignalInfo.TotalSize; pMonitorSourceMode->VideoSignalInfo.VSyncFreq.Numerator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pMonitorSourceMode->VideoSignalInfo.VSyncFreq.Denominator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pMonitorSourceMode->VideoSignalInfo.HSyncFreq.Numerator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pMonitorSourceMode->VideoSignalInfo.HSyncFreq.Denominator = D3DKMDT_FREQUENCY_NOTSPECIFIED; pMonitorSourceMode->VideoSignalInfo.PixelRate = D3DKMDT_FREQUENCY_NOTSPECIFIED; pMonitorSourceMode->VideoSignalInfo.ScanLineOrdering = D3DDDI_VSSLO_PROGRESSIVE; // We set the preference to PREFERRED since this is the only supported mode pMonitorSourceMode->Origin = D3DKMDT_MCO_DRIVER; pMonitorSourceMode->Preference = D3DKMDT_MP_PREFERRED; pMonitorSourceMode->ColorBasis = D3DKMDT_CB_SRGB; pMonitorSourceMode->ColorCoeffDynamicRanges.FirstChannel = 8; pMonitorSourceMode->ColorCoeffDynamicRanges.SecondChannel = 8; pMonitorSourceMode->ColorCoeffDynamicRanges.ThirdChannel = 8; pMonitorSourceMode->ColorCoeffDynamicRanges.FourthChannel = 8; Status = pRecommendMonitorModes->pMonitorSourceModeSetInterface->pfnAddMode(pRecommendMonitorModes->hMonitorSourceModeSet, pMonitorSourceMode); if (!NT_SUCCESS(Status)) { if (Status != STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET) { BDD_LOG_ERROR3("pfnAddMode failed with Status = 0x%I64x, hMonitorSourceModeSet = 0x%I64x, pMonitorSourceMode = 0x%I64x", Status, pRecommendMonitorModes->hMonitorSourceModeSet, pMonitorSourceMode); } else { Status = STATUS_SUCCESS; } // If adding the mode failed, release the mode, if this doesn't work there is nothing that can be done, some memory will get leaked NTSTATUS TempStatus = pRecommendMonitorModes->pMonitorSourceModeSetInterface->pfnReleaseModeInfo(pRecommendMonitorModes->hMonitorSourceModeSet, pMonitorSourceMode); UNREFERENCED_PARAMETER(TempStatus); NT_ASSERT(NT_SUCCESS(TempStatus)); return Status; } else { // If AddMode succeeded with something other than STATUS_SUCCESS treat it as such anyway when propagating up return STATUS_SUCCESS; } }
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials