mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Updated NVIDIALibrary and WinLibrary to latest version
This commit is contained in:
parent
4661ffb72f
commit
7d0c8e1ca4
@ -2146,6 +2146,7 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
public const UInt32 NV_MOSAIC_TOPO_MAX = (UInt32)NV_MOSAIC_TOPO.TOPO_MAX;
|
||||
public const UInt32 NVAPI_MAX_MOSAIC_DISPLAY_ROWS = 8;
|
||||
public const UInt32 NVAPI_MAX_MOSAIC_DISPLAY_COLUMNS = 8;
|
||||
public const UInt32 NVAPI_MAX_MOSAIC_TOPOS = 16;
|
||||
public const UInt32 NVAPI_GENERIC_STRING_MAX = 4096;
|
||||
public const UInt32 NVAPI_LONG_STRING_MAX = 256;
|
||||
public const UInt32 NVAPI_SHORT_STRING_MAX = 64;
|
||||
@ -2343,6 +2344,8 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
GetDelegate(NvId_Mosaic_GetCurrentTopo, out Mosaic_GetCurrentTopoInternal);
|
||||
GetDelegate(NvId_Mosaic_GetTopoGroup, out Mosaic_GetTopoGroupInternal);
|
||||
GetDelegate(NvId_Mosaic_GetSupportedTopoInfo, out Mosaic_GetSupportedTopoInfoInternal);
|
||||
GetDelegate(NvId_Mosaic_EnumDisplayModes, out Mosaic_EnumDisplayModesInternal);
|
||||
GetDelegate(NvId_Mosaic_EnumDisplayModes, out Mosaic_EnumDisplayModesInternalNull); // The null version of the submission
|
||||
GetDelegate(NvId_Mosaic_EnumDisplayGrids, out Mosaic_EnumDisplayGridsInternal);
|
||||
GetDelegate(NvId_Mosaic_EnumDisplayGrids, out Mosaic_EnumDisplayGridsInternalNull); // The null version of the submission
|
||||
GetDelegate(NvId_Mosaic_SetDisplayGrids, out Mosaic_SetDisplayGridsInternal);
|
||||
@ -3629,6 +3632,113 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
return status;
|
||||
}
|
||||
|
||||
// NVAPI_INTERFACE NvAPI_Mosaic_EnumDisplayModes ( __in NV_MOSAIC_GRID_TOPO * pGridTopology, __inout_ecount_part_opt*,*pDisplayCount NV_MOSAIC_DISPLAY_SETTING * pDisplaySettings,
|
||||
// __inout NvU32 * pDisplayCount )
|
||||
// NvAPIMosaic_EnumDisplayModes
|
||||
private delegate NVAPI_STATUS Mosaic_EnumDisplayModesDelegate(
|
||||
[In] NV_MOSAIC_GRID_TOPO_V2 gridTopology,
|
||||
[In][Out] IntPtr displaySettingsBuffer,
|
||||
[In][Out] ref UInt32 displayCount);
|
||||
private static readonly Mosaic_EnumDisplayModesDelegate Mosaic_EnumDisplayModesInternal;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the set of available display modes for a given grid topology.
|
||||
/// If displaySettings is NULL, then displayCount will receive the total number of modes that are available.
|
||||
/// If displaySettings is not NULL, then displayCount should point to the number of elements in the pDisplaySettings array. On return, it will contain the number of modes that were actually returned
|
||||
/// </summary>
|
||||
/// <param name="gridTopology"></param>
|
||||
/// <param name="displaySettingsBuffer"></param>
|
||||
/// <param name="displayCount"></param>
|
||||
/// <returns></returns>
|
||||
public static NVAPI_STATUS NvAPI_Mosaic_EnumDisplayModes(NV_MOSAIC_GRID_TOPO_V2 gridTopology, ref NV_MOSAIC_DISPLAY_SETTING_V2[] displaySettings, ref UInt32 displayCount)
|
||||
{
|
||||
NVAPI_STATUS status;
|
||||
|
||||
// Build a managed structure for us to use as a data source for another object that the unmanaged NVAPI C library can use
|
||||
displaySettings = new NV_MOSAIC_DISPLAY_SETTING_V2[displayCount];
|
||||
// Initialize unmanged memory to hold the unmanaged array of structs
|
||||
IntPtr displaySettingsBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(NV_MOSAIC_DISPLAY_SETTING_V2)) * (int)displayCount);
|
||||
// Also set another memory pointer to the same place so that we can do the memory copying item by item
|
||||
// as we have to do it ourselves (there isn't an easy to use Marshal equivalent)
|
||||
IntPtr currentDisplaySettingsBuffer = displaySettingsBuffer;
|
||||
// Go through the array and copy things from managed code to unmanaged code
|
||||
for (Int32 x = 0; x < (Int32)displayCount; x++)
|
||||
{
|
||||
// Set up the basic structure
|
||||
displaySettings[x].Version = NVImport.NV_MOSAIC_DISPLAY_SETTING_V2_VER;
|
||||
|
||||
// Marshal a single gridtopology into unmanaged code ready for sending to the unmanaged NVAPI function
|
||||
Marshal.StructureToPtr(displaySettings[x], currentDisplaySettingsBuffer, false);
|
||||
// advance the buffer forwards to the next object
|
||||
currentDisplaySettingsBuffer = (IntPtr)((long)currentDisplaySettingsBuffer + Marshal.SizeOf(displaySettings[x]));
|
||||
}
|
||||
|
||||
|
||||
if (Mosaic_EnumDisplayModesInternal != null)
|
||||
{
|
||||
// Use the unmanaged buffer in the unmanaged C call
|
||||
status = Mosaic_EnumDisplayModesInternal(gridTopology, displaySettingsBuffer, ref displayCount);
|
||||
|
||||
if (status == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
// If everything worked, then copy the data back from the unmanaged array into the managed array
|
||||
// So that we can use it in C# land
|
||||
// Reset the memory pointer we're using for tracking where we are back to the start of the unmanaged memory buffer
|
||||
currentDisplaySettingsBuffer = displaySettingsBuffer;
|
||||
// Create a managed array to store the received information within
|
||||
displaySettings = new NV_MOSAIC_DISPLAY_SETTING_V2[displayCount];
|
||||
// Go through the memory buffer item by item and copy the items into the managed array
|
||||
for (int i = 0; i < displayCount; i++)
|
||||
{
|
||||
// build a structure in the array slot
|
||||
displaySettings[i] = new NV_MOSAIC_DISPLAY_SETTING_V2();
|
||||
// fill the array slot structure NV_MOSAIC_DISPLAY_SETTING_V2 the data from the buffer
|
||||
displaySettings[i] = (NV_MOSAIC_DISPLAY_SETTING_V2)Marshal.PtrToStructure(currentDisplaySettingsBuffer, typeof(NV_MOSAIC_DISPLAY_SETTING_V2));
|
||||
// destroy the bit of memory we no longer need
|
||||
Marshal.DestroyStructure(currentDisplaySettingsBuffer, typeof(NV_MOSAIC_DISPLAY_SETTING_V2));
|
||||
// advance the buffer forwards to the next object
|
||||
currentDisplaySettingsBuffer = (IntPtr)((long)currentDisplaySettingsBuffer + Marshal.SizeOf(displaySettings[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NVAPI_STATUS.NVAPI_FUNCTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
Marshal.FreeCoTaskMem(displaySettingsBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// NVAPI_INTERFACE NvAPI_Mosaic_EnumDisplayModes(__inout_ecount_part_opt*,* pGridCount NV_MOSAIC_GRID_TOPO* pGridTopologies,__inout NvU32 * pGridCount)
|
||||
// NvAPIMosaic_EnumDisplayModes
|
||||
private delegate NVAPI_STATUS Mosaic_EnumDisplayModesDelegateNull(
|
||||
[In] NV_MOSAIC_GRID_TOPO_V2 gridTopology,
|
||||
[In][Out] IntPtr displaySettingsBuffer,
|
||||
[In][Out] ref UInt32 displayCount);
|
||||
private static readonly Mosaic_EnumDisplayModesDelegateNull Mosaic_EnumDisplayModesInternalNull;
|
||||
|
||||
/// <summary>
|
||||
/// Determines the set of available display modes for a given grid topology.
|
||||
/// If displaySettings is NULL, then displayCount will receive the total number of modes that are available.
|
||||
/// If displaySettings is not NULL, then displayCount should point to the number of elements in the pDisplaySettings array. On return, it will contain the number of modes that were actually returned
|
||||
/// </summary>
|
||||
/// <param name="gridTopologiesBuffer"></param>
|
||||
/// <param name="displaySettingsBuffer"></param>
|
||||
/// <param name="displayCount"></param>
|
||||
/// <returns></returns>
|
||||
public static NVAPI_STATUS NvAPI_Mosaic_EnumDisplayModes(NV_MOSAIC_GRID_TOPO_V2 gridTopology, ref UInt32 displayCount)
|
||||
{
|
||||
NVAPI_STATUS status;
|
||||
IntPtr displaySettings = IntPtr.Zero;
|
||||
|
||||
if (Mosaic_EnumDisplayModesInternalNull != null) { status = Mosaic_EnumDisplayModesInternalNull(gridTopology, displaySettings, ref displayCount); }
|
||||
else { status = NVAPI_STATUS.NVAPI_FUNCTION_NOT_FOUND; }
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// NVAPI_INTERFACE NvAPI_Mosaic_EnumDisplayGrids(__inout_ecount_part_opt*,* pGridCount NV_MOSAIC_GRID_TOPO* pGridTopologies,__inout NvU32 * pGridCount)
|
||||
// NvAPIMosaic_EnumDisplayGrids
|
||||
private delegate NVAPI_STATUS Mosaic_EnumDisplayGridsDelegate(
|
||||
@ -3752,8 +3862,9 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
/// <param name="topoStatuses"></param>
|
||||
/// <param name="gridCount"></param>
|
||||
/// <returns></returns>
|
||||
public static NVAPI_STATUS NvAPI_Mosaic_ValidateDisplayGrids(NV_MOSAIC_SETDISPLAYTOPO_FLAGS setTopoFlags, ref NV_MOSAIC_GRID_TOPO_V2[] gridTopologies, ref NV_MOSAIC_DISPLAY_TOPO_STATUS_V1[] topoStatuses, UInt32 gridCount)
|
||||
public static NVAPI_STATUS NvAPI_Mosaic_ValidateDisplayGrids(NV_MOSAIC_SETDISPLAYTOPO_FLAGS setTopoFlags, NV_MOSAIC_GRID_TOPO_V2[] gridTopologies, ref NV_MOSAIC_DISPLAY_TOPO_STATUS_V1[] topoStatuses, UInt32 gridCount)
|
||||
{
|
||||
// Warning! - This function still has some errors with it. It errors with an NVAPI_INCOMPATIBLE_STRUCT_VERSION error. Still needs troubleshooting.
|
||||
NVAPI_STATUS status;
|
||||
// Initialize unmanged memory to hold the unmanaged array of structs
|
||||
IntPtr gridTopologiesBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(NV_MOSAIC_GRID_TOPO_V2)) * (int)gridCount);
|
||||
@ -3763,13 +3874,6 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
// Go through the array and copy things from managed code to unmanaged code
|
||||
for (Int32 x = 0; x < (Int32)gridCount; x++)
|
||||
{
|
||||
for (Int32 y = 0; y < gridTopologies[x].DisplayCount; y++)
|
||||
{
|
||||
gridTopologies[x].Displays[y].Version = NVImport.NV_MOSAIC_GRID_TOPO_DISPLAY_V2_VER;
|
||||
}
|
||||
gridTopologies[x].DisplaySettings.Version = NVImport.NV_MOSAIC_DISPLAY_SETTING_V1_VER;
|
||||
gridTopologies[x].Version = NVImport.NV_MOSAIC_GRID_TOPO_V2_VER;
|
||||
|
||||
// Marshal a single gridtopology into unmanaged code ready for sending to the unmanaged NVAPI function
|
||||
Marshal.StructureToPtr(gridTopologies[x], currentGridTopologiesBuffer, false);
|
||||
// advance the buffer forwards to the next object
|
||||
@ -4008,8 +4112,8 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
// NVAPI_INTERFACE NvAPI_Mosaic_SetCurrentTopo ( NV_MOSAIC_TOPO_BRIEF * pTopoBrief, NV_MOSAIC_DISPLAY_SETTING* pDisplaySetting, NvS32 overlapX, NvS32 overlapY, NvU32 enable)
|
||||
// NvAPI_Mosaic_SetCurrentTopo
|
||||
private delegate NVAPI_STATUS Mosaic_SetCurrentTopoDelegate(
|
||||
[In] ref NV_MOSAIC_TOPO_BRIEF topoBrief,
|
||||
[In] ref NV_MOSAIC_DISPLAY_SETTING_V2 displaySetting,
|
||||
[In] NV_MOSAIC_TOPO_BRIEF topoBrief,
|
||||
[In] NV_MOSAIC_DISPLAY_SETTING_V2 displaySetting,
|
||||
[In] Int32 overlapX,
|
||||
[In] Int32 overlapY,
|
||||
[In] UInt32 enable);
|
||||
@ -4025,15 +4129,15 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
/// <param name="overlapY"></param>
|
||||
/// <param name="enable"></param>
|
||||
/// <returns></returns>
|
||||
public static NVAPI_STATUS NvAPI_Mosaic_SetCurrentTopo(ref NV_MOSAIC_TOPO_BRIEF topoBrief, ref NV_MOSAIC_DISPLAY_SETTING_V2 displaySetting, Int32 overlapX, Int32 overlapY, UInt32 enable)
|
||||
public static NVAPI_STATUS NvAPI_Mosaic_SetCurrentTopo(NV_MOSAIC_TOPO_BRIEF topoBrief, NV_MOSAIC_DISPLAY_SETTING_V2 displaySetting, Int32 overlapX, Int32 overlapY, UInt32 enable)
|
||||
{
|
||||
NVAPI_STATUS status;
|
||||
topoBrief.Version = NVImport.NV_MOSAIC_TOPO_BRIEF_VER;
|
||||
displaySetting.Version = NVImport.NV_MOSAIC_DISPLAY_SETTING_V2_VER;
|
||||
//topoBrief.Version = NVImport.NV_MOSAIC_TOPO_BRIEF_VER;
|
||||
//displaySetting.Version = NVImport.NV_MOSAIC_DISPLAY_SETTING_V2_VER;
|
||||
// Set enable to false within the version as we want to enable it now
|
||||
// This is needed as the saved display topology object was made when the topology was enabled :)
|
||||
//topoBrief.Enabled = 0;
|
||||
if (Mosaic_SetCurrentTopoInternal != null) { status = Mosaic_SetCurrentTopoInternal(ref topoBrief, ref displaySetting, overlapX, overlapY, enable); }
|
||||
if (Mosaic_SetCurrentTopoInternal != null) { status = Mosaic_SetCurrentTopoInternal(topoBrief, displaySetting, overlapX, overlapY, enable); }
|
||||
else { status = NVAPI_STATUS.NVAPI_FUNCTION_NOT_FOUND; }
|
||||
|
||||
return status;
|
||||
|
@ -354,12 +354,59 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
}
|
||||
}
|
||||
|
||||
// Get current Supported Mosaic Topology info (check whether Mosaic is on)
|
||||
NV_MOSAIC_SUPPORTED_TOPO_INFO_V2 mosaicSupportedTopoInfo = new NV_MOSAIC_SUPPORTED_TOPO_INFO_V2();
|
||||
NVStatus = NVImport.NvAPI_Mosaic_GetSupportedTopoInfo(ref mosaicSupportedTopoInfo, NV_MOSAIC_TOPO_TYPE.ALL);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetSupportedTopoInfo returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The version of the structure passed in is not supported by this driver. NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_GetSupportedTopoInfo() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
if (mosaicSupportedTopoInfo != null && mosaicSupportedTopoInfo.TopoBriefsCount > 0)
|
||||
{
|
||||
int numValidTopos = mosaicSupportedTopoInfo.TopoBriefs.Count(tb => tb.IsPossible == 1);
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: There are {numValidTopos} valid Mosaic Topologies available with this display layout.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: There are no valid Mosaic Topologies available with this display layout.");
|
||||
}
|
||||
|
||||
|
||||
// Get current Mosaic Topology settings in brief (check whether Mosaic is on)
|
||||
NV_MOSAIC_TOPO_BRIEF mosaicTopoBrief = new NV_MOSAIC_TOPO_BRIEF();
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2 mosaicDisplaySettings = new NV_MOSAIC_DISPLAY_SETTING_V2();
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2 mosaicDisplaySetting = new NV_MOSAIC_DISPLAY_SETTING_V2();
|
||||
int mosaicOverlapX = 0;
|
||||
int mosaicOverlapY = 0;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_GetCurrentTopo(ref mosaicTopoBrief, ref mosaicDisplaySettings, out mosaicOverlapX, out mosaicOverlapY);
|
||||
NVStatus = NVImport.NvAPI_Mosaic_GetCurrentTopo(ref mosaicTopoBrief, ref mosaicDisplaySetting, out mosaicOverlapX, out mosaicOverlapY);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetCurrentTopo returned OK.");
|
||||
@ -389,52 +436,93 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Get more Mosaic Topology detailed settings
|
||||
NV_MOSAIC_TOPO_GROUP mosaicTopoGroup = new NV_MOSAIC_TOPO_GROUP();
|
||||
NVStatus = NVImport.NvAPI_Mosaic_GetTopoGroup(ref mosaicTopoBrief, ref mosaicTopoGroup);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetTopoGroup returned OK.");
|
||||
if (mosaicTopoBrief.IsPossible == 1)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: The current Mosaic Topology of {mosaicTopoBrief.Topo} is possible to use");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: The current Mosaic Topology of {mosaicTopoBrief.Topo} is NOT possible to use");
|
||||
}
|
||||
if (mosaicTopoGroup.Count > 0)
|
||||
{
|
||||
int m = 1;
|
||||
foreach (var mosaicTopoDetail in mosaicTopoGroup.Topos)
|
||||
{
|
||||
|
||||
if (mosaicTopoDetail.TopologyValid)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: The returned Mosaic Topology Group #{m} is VALID.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: The returned Mosaic Topology Group #{m} is NOT VALID and cannot be used.");
|
||||
}
|
||||
if (mosaicTopoDetail.TopologyMissingGPU)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: The returned Mosaic Topology Group #{m} is MISSING THE GPU it was created with.");
|
||||
}
|
||||
if (mosaicTopoDetail.TopologyMissingDisplay)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: The returned Mosaic Topology Group #{m} is MISSING ONE OR MORE DISPLAYS it was created with.");
|
||||
}
|
||||
if (mosaicTopoDetail.TopologyMixedDisplayTypes)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/GetNVIDIADisplayConfig: The returned Mosaic Topology Group #{m} is USING MIXED DISPLAY TYPES and NVIDIA don't support that at present.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The returned Mosaic Topology Group doesn't have any returned Topo Groups. We expect there should be at least one if the Mosaic display layout is configured correctly.");
|
||||
}
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more arguments passed in are invalid. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The version of the structure passed in is not supported by this driver. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Check if there is a topology and that Mosaic is enabled
|
||||
if (mosaicTopoBrief.Topo != NV_MOSAIC_TOPO.TOPO_NONE && mosaicTopoBrief.Enabled == 1)
|
||||
{
|
||||
// Mosaic is enabled!
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NVIDIA Mosaic is enabled.");
|
||||
myDisplayConfig.MosaicConfig.MosaicTopologyBrief = mosaicTopoBrief;
|
||||
myDisplayConfig.MosaicConfig.MosaicDisplaySettings = mosaicDisplaySettings;
|
||||
myDisplayConfig.MosaicConfig.MosaicDisplaySettings = mosaicDisplaySetting;
|
||||
myDisplayConfig.MosaicConfig.OverlapX = mosaicOverlapX;
|
||||
myDisplayConfig.MosaicConfig.OverlapY = mosaicOverlapY;
|
||||
myDisplayConfig.MosaicConfig.IsMosaicEnabled = true;
|
||||
|
||||
// Get more Mosaic Topology detailed settings
|
||||
NV_MOSAIC_TOPO_GROUP mosaicTopoGroup = new NV_MOSAIC_TOPO_GROUP();
|
||||
NVStatus = NVImport.NvAPI_Mosaic_GetTopoGroup(ref mosaicTopoBrief, ref mosaicTopoGroup);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetTopoGroup returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The version of the structure passed in is not supported by this driver. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_GetTopoGroup() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Figure out how many Mosaic Grid topoligies there are
|
||||
uint mosaicGridCount = 0;
|
||||
@ -521,6 +609,47 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
// Save the viewports to the List
|
||||
allViewports.Add(viewports);
|
||||
|
||||
// Figure out how many Mosaic Display topologies there are
|
||||
UInt32 mosaicDisplayModesCount = 0;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnumDisplayModes(gridTopo, ref mosaicDisplayModesCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_EnumDisplayModes returned OK.");
|
||||
}
|
||||
|
||||
// Get Current Mosaic Display Topology settings using the Grid topologies numbers we got before
|
||||
//NV_MOSAIC_TOPO myGridTopo = gridTopo;
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2[] mosaicDisplaySettings = new NV_MOSAIC_DISPLAY_SETTING_V2[mosaicDisplayModesCount];
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnumDisplayModes(gridTopo, ref mosaicDisplaySettings, ref mosaicDisplayModesCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_EnumDisplayModes returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology Display Settings! NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
myDisplayConfig.MosaicConfig.MosaicViewports = allViewports;
|
||||
@ -1477,8 +1606,105 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to change to a Mosaic profile, so we need to apply the new Mosaic Topology
|
||||
NV_MOSAIC_SETDISPLAYTOPO_FLAGS setTopoFlags = NV_MOSAIC_SETDISPLAYTOPO_FLAGS.NONE;
|
||||
/*// We need to change to a Mosaic profile, so we need to apply the new Mosaic Topology
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Mosaic current config is different as the one we want, so applying the Mosaic config now");
|
||||
// If we get here then the display is valid, so now we actually apply the new Mosaic Topology
|
||||
NVStatus = NVImport.NvAPI_Mosaic_SetCurrentTopo(displayConfig.MosaicConfig.MosaicTopologyBrief, displayConfig.MosaicConfig.MosaicDisplaySettings, displayConfig.MosaicConfig.OverlapX, displayConfig.MosaicConfig.OverlapY, 0);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: NvAPI_Mosaic_SetCurrentTopo returned OK.");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Waiting 0.5 second to let the Mosaic display change take place before continuing");
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_ACTIVE_SLI_TOPOLOGY)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: No matching GPU topologies could be found. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_TOPO_NOT_POSSIBLE)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The topology passed in is not currently possible. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The version of the structure passed in is not compatible with this entrypoint. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_MODE_CHANGE_FAILED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: There was an error changing the display mode. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: A miscellaneous error occurred. NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Some non standard error occurred while getting Mosaic Display Grids! NvAPI_Mosaic_SetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Turn on the selected Mosaic
|
||||
uint enable = 1;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnableCurrentTopo(enable);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: NvAPI_Mosaic_EnableCurrentTopo returned OK. Previously set Mosiac config re-enabled.");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Waiting 0.5 second to let the Mosaic display change take place before continuing");
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_TOPO_NOT_POSSIBLE)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The topology passed in is not currently possible. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The version of the structure passed in is not compatible with this entrypoint. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_MODE_CHANGE_FAILED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: There was an error disabling the display mode. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: A miscellaneous error occurred. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
}*/
|
||||
|
||||
NV_MOSAIC_SETDISPLAYTOPO_FLAGS setTopoFlags = NV_MOSAIC_SETDISPLAYTOPO_FLAGS.MAXIMIZE_PERFORMANCE;
|
||||
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Mosaic current config is different as the one we want, so applying the Mosaic config now");
|
||||
// If we get here then the display is valid, so now we actually apply the new Mosaic Topology
|
||||
@ -1536,52 +1762,199 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
// We are on a Mosaic profile now, and we need to change to a non-Mosaic profile
|
||||
// We need to disable the Mosaic Topology
|
||||
|
||||
// Turn off Mosaic
|
||||
uint enable = 0;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnableCurrentTopo(enable);
|
||||
NV_MOSAIC_SETDISPLAYTOPO_FLAGS setTopoFlags = NV_MOSAIC_SETDISPLAYTOPO_FLAGS.ALLOW_INVALID;
|
||||
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Mosaic config that is currently set is no longer needed. Removing Mosaic config.");
|
||||
NV_MOSAIC_GRID_TOPO_V2[] individualScreensTopology = CreateSingleScreenMosaicTopology();
|
||||
|
||||
// WARNING - Validation is disabled at present. This is mostly because there are errors in my NvAPI_Mosaic_ValidateDisplayGrids,
|
||||
// but also because the config is coming from the NVIDIA Control Panel which will already do it's own validation checks.
|
||||
/*// Firstly try to see if the oneScreenTopology is a valid config
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Checking if the 1x1 DisplayGrid we chose is valid for the NvAPI_Mosaic_SetDisplayGrids mosaic layout.");
|
||||
NV_MOSAIC_DISPLAY_TOPO_STATUS_V1[] individualScreensStatuses = new NV_MOSAIC_DISPLAY_TOPO_STATUS_V1[(UInt32)individualScreensTopology.Length];
|
||||
NVStatus = NVImport.NvAPI_Mosaic_ValidateDisplayGrids(setTopoFlags, individualScreensTopology, ref individualScreensStatuses, (UInt32)individualScreensTopology.Length);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: NvAPI_Mosaic_EnableCurrentTopo returned OK. Previously set Mosiac config re-enabled.");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: NvAPI_Mosaic_ValidateDisplayGrids returned OK.");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Waiting 0.5 second to let the Mosaic display change take place before continuing");
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_ACTIVE_SLI_TOPOLOGY)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: No matching GPU topologies could be found. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_TOPO_NOT_POSSIBLE)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The topology passed in is not currently possible. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The topology passed in is not currently possible. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_DISPLAY_ID)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/SetActiveConfig: The Display ID of the first display is not currently possible to use. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}. Trying again with the next display.");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: One or more arguments passed in are invalid. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The version of the structure passed in is not compatible with this entrypoint. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The version of the structure passed in is not compatible with this entrypoint. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_MODE_CHANGE_FAILED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: There was an error disabling the display mode. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: There was an error changing the display mode. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: A miscellaneous error occurred. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: A miscellaneous error occurred. NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Some non standard error occurred while getting Mosaic Display Grids! NvAPI_Mosaic_ValidateDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}*/
|
||||
|
||||
|
||||
// If we get here then the display is valid, so now we actually apply the new Mosaic Topology
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Trying to set a 1x1 DisplayGrid for the NvAPI_Mosaic_SetDisplayGrids mosaic layout.");
|
||||
NVStatus = NVImport.NvAPI_Mosaic_SetDisplayGrids(individualScreensTopology, (UInt32)individualScreensTopology.Length, setTopoFlags);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: NvAPI_Mosaic_SetDisplayGrids returned OK.");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Waiting 0.5 second to let the Mosaic display change take place before continuing");
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_ACTIVE_SLI_TOPOLOGY)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: No matching GPU topologies could be found. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_TOPO_NOT_POSSIBLE)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The topology passed in is not currently possible. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_DISPLAY_ID)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/SetActiveConfig: The Display ID of the first display is not currently possible to use. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}. Trying again with the next display.");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: One or more arguments passed in are invalid. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The version of the structure passed in is not compatible with this entrypoint. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_MODE_CHANGE_FAILED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: There was an error changing the display mode. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: A miscellaneous error occurred. NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we get here, we may have an error, or it may have worked successfully! So we need to check again :(
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Some non standard error occurred while getting Mosaic Display Grids! NvAPI_Mosaic_SetDisplayGrids() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we get here, it may or it may not have worked successfully! So we need to check again :(
|
||||
// We don't want to do a full ceck, so we do a quick check instead.
|
||||
if (MosaicIsOn())
|
||||
{
|
||||
// If the Mosaic is still on, then the last mosaic disable failed, so we need to then try turning it off this using NvAPI_Mosaic_EnableCurrentTopo(0)
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Previous attempt to turn off Mosaic. Now trying to use NvAPI_Mosaic_EnableCurrentTopo to disable Mosaic instead.");
|
||||
uint enable = 0;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnableCurrentTopo(enable);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: NvAPI_Mosaic_EnableCurrentTopo returned OK. Previously set Mosiac config now disabled");
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Waiting 0.5 second to let the Mosaic display change take place before continuing");
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_TOPO_NOT_POSSIBLE)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The topology passed in is not currently possible. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INCOMPATIBLE_STRUCT_VERSION)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: The version of the structure passed in is not compatible with this entrypoint. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_MODE_CHANGE_FAILED)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: There was an error disabling the display mode. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Error($"NVIDIALibrary/SetActiveConfig: A miscellaneous error occurred. NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_EnableCurrentTopo() returned error code {NVStatus}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/SetActiveConfig: Mosaic successfully disabled using NvAPI_Mosaic_SetDisplayGrids method.");
|
||||
}
|
||||
}
|
||||
else if (!displayConfig.MosaicConfig.IsMosaicEnabled && !ActiveDisplayConfig.MosaicConfig.IsMosaicEnabled)
|
||||
@ -2066,6 +2439,68 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
}
|
||||
}*/
|
||||
|
||||
public static bool MosaicIsOn()
|
||||
{
|
||||
PhysicalGpuHandle[] physicalGpus = new PhysicalGpuHandle[NVImport.NVAPI_MAX_PHYSICAL_GPUS];
|
||||
uint physicalGpuCount = 0;
|
||||
NVAPI_STATUS NVStatus = NVImport.NvAPI_EnumPhysicalGPUs(ref physicalGpus, out physicalGpuCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_EnumPhysicalGPUs returned {physicalGpuCount} Physical GPUs");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Error getting physical GPU count. NvAPI_EnumPhysicalGPUs() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Go through the Physical GPUs one by one
|
||||
for (uint physicalGpuIndex = 0; physicalGpuIndex < physicalGpuCount; physicalGpuIndex++)
|
||||
{
|
||||
// Get current Mosaic Topology settings in brief (check whether Mosaic is on)
|
||||
NV_MOSAIC_TOPO_BRIEF mosaicTopoBrief = new NV_MOSAIC_TOPO_BRIEF();
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2 mosaicDisplaySetting = new NV_MOSAIC_DISPLAY_SETTING_V2();
|
||||
int mosaicOverlapX = 0;
|
||||
int mosaicOverlapY = 0;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_GetCurrentTopo(ref mosaicTopoBrief, ref mosaicDisplaySetting, out mosaicOverlapX, out mosaicOverlapY);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetCurrentTopo returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Check if there is a topology and that Mosaic is enabled
|
||||
if (mosaicTopoBrief.Topo != NV_MOSAIC_TOPO.TOPO_NONE && mosaicTopoBrief.Enabled == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<string> GetCurrentDisplayIdentifiers()
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetCurrentDisplayIdentifiers: Getting the current display identifiers for the displays in use now");
|
||||
@ -2453,6 +2888,171 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
return displayIdentifiers;
|
||||
}
|
||||
|
||||
|
||||
public static NV_MOSAIC_GRID_TOPO_V2[] CreateSingleScreenMosaicTopology()
|
||||
{
|
||||
/*// Get current Mosaic Topology settings in brief (check whether Mosaic is on)
|
||||
NV_MOSAIC_TOPO_BRIEF mosaicTopoBrief = new NV_MOSAIC_TOPO_BRIEF();
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2 mosaicDisplaySetting = new NV_MOSAIC_DISPLAY_SETTING_V2();
|
||||
int mosaicOverlapX = 0;
|
||||
int mosaicOverlapY = 0;
|
||||
NVAPI_STATUS NVStatus = NVImport.NvAPI_Mosaic_GetCurrentTopo(ref mosaicTopoBrief, ref mosaicDisplaySetting, out mosaicOverlapX, out mosaicOverlapY);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetCurrentTopo returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_GetCurrentTopo() returned error code {NVStatus}");
|
||||
}*/
|
||||
|
||||
// Figure out how many Mosaic Grid topoligies there are
|
||||
uint mosaicGridCount = 0;
|
||||
NVAPI_STATUS NVStatus = NVImport.NvAPI_Mosaic_EnumDisplayGrids(ref mosaicGridCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_GetCurrentTopo returned OK.");
|
||||
}
|
||||
|
||||
// Get Current Mosaic Grid settings using the Grid topologies fnumbers we got before
|
||||
NV_MOSAIC_GRID_TOPO_V2[] mosaicGridTopos = new NV_MOSAIC_GRID_TOPO_V2[mosaicGridCount];
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnumDisplayGrids(ref mosaicGridTopos, ref mosaicGridCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_EnumDisplayGrids returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_EnumDisplayGrids() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_EnumDisplayGrids() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_EnumDisplayGrids() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_EnumDisplayGrids() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_EnumDisplayGrids() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology! NvAPI_Mosaic_EnumDisplayGrids() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
// Sum up all the screens we have
|
||||
//int totalScreenCount = mosaicGridTopos.Select(tp => tp.Displays).Sum(d => d.Count());
|
||||
List<NV_MOSAIC_GRID_TOPO_V2> screensToReturn = new List<NV_MOSAIC_GRID_TOPO_V2>();
|
||||
|
||||
foreach (NV_MOSAIC_GRID_TOPO_V2 gridTopo in mosaicGridTopos)
|
||||
{
|
||||
// Figure out how many Mosaic Display topologies there are
|
||||
UInt32 mosaicDisplayModesCount = 0;
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnumDisplayModes(gridTopo, ref mosaicDisplayModesCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_EnumDisplayModes returned OK.");
|
||||
}
|
||||
|
||||
// Get Current Mosaic Display Topology settings using the Grid topologies numbers we got before
|
||||
//NV_MOSAIC_TOPO myGridTopo = gridTopo;
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2[] mosaicDisplaySettings = new NV_MOSAIC_DISPLAY_SETTING_V2[mosaicDisplayModesCount];
|
||||
NVStatus = NVImport.NvAPI_Mosaic_EnumDisplayModes(gridTopo, ref mosaicDisplaySettings, ref mosaicDisplayModesCount);
|
||||
if (NVStatus == NVAPI_STATUS.NVAPI_OK)
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: NvAPI_Mosaic_EnumDisplayModes returned OK.");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NOT_SUPPORTED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: Mosaic is not supported with the existing hardware. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_INVALID_ARGUMENT)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: One or more argumentss passed in are invalid. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_API_NOT_INITIALIZED)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: The NvAPI API needs to be initialized first. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_NO_IMPLEMENTATION)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: This entry point not available in this NVIDIA Driver. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else if (NVStatus == NVAPI_STATUS.NVAPI_ERROR)
|
||||
{
|
||||
SharedLogger.logger.Warn($"NVIDIALibrary/GetNVIDIADisplayConfig: A miscellaneous error occurred. NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Trace($"NVIDIALibrary/GetNVIDIADisplayConfig: Some non standard error occurred while getting Mosaic Topology Display Settings! NvAPI_Mosaic_EnumDisplayModes() returned error code {NVStatus}");
|
||||
}
|
||||
|
||||
for (int displayIndexToUse = 0; displayIndexToUse < gridTopo.DisplayCount; displayIndexToUse++)
|
||||
{
|
||||
NV_MOSAIC_GRID_TOPO_V2 thisScreen = new NV_MOSAIC_GRID_TOPO_V2();
|
||||
thisScreen.Version = NVImport.NV_MOSAIC_GRID_TOPO_V2_VER;
|
||||
thisScreen.Rows = 1;
|
||||
thisScreen.Columns = 1;
|
||||
thisScreen.DisplayCount = 1;
|
||||
thisScreen.Flags = 0;
|
||||
thisScreen.Displays = new NV_MOSAIC_GRID_TOPO_DISPLAY_V2[NVImport.NV_MOSAIC_MAX_DISPLAYS];
|
||||
thisScreen.Displays[0].Version = NVImport.NV_MOSAIC_GRID_TOPO_DISPLAY_V2_VER;
|
||||
thisScreen.Displays[0].DisplayId = gridTopo.Displays[displayIndexToUse].DisplayId;
|
||||
thisScreen.Displays[0].CloneGroup = gridTopo.Displays[displayIndexToUse].CloneGroup;
|
||||
thisScreen.Displays[0].OverlapX = gridTopo.Displays[displayIndexToUse].OverlapX;
|
||||
thisScreen.Displays[0].OverlapY = gridTopo.Displays[displayIndexToUse].OverlapY;
|
||||
thisScreen.Displays[0].PixelShiftType = gridTopo.Displays[displayIndexToUse].PixelShiftType;
|
||||
thisScreen.Displays[0].Rotation = gridTopo.Displays[displayIndexToUse].Rotation;
|
||||
thisScreen.DisplaySettings = new NV_MOSAIC_DISPLAY_SETTING_V1();
|
||||
thisScreen.DisplaySettings.Version = gridTopo.DisplaySettings.Version;
|
||||
thisScreen.DisplaySettings.Bpp = gridTopo.DisplaySettings.Bpp;
|
||||
thisScreen.DisplaySettings.Freq = gridTopo.DisplaySettings.Freq;
|
||||
thisScreen.DisplaySettings.Height = gridTopo.DisplaySettings.Height;
|
||||
thisScreen.DisplaySettings.Width = gridTopo.DisplaySettings.Width;
|
||||
screensToReturn.Add(thisScreen);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
// Selected the best display settings to use
|
||||
NV_MOSAIC_DISPLAY_SETTING_V2 bestSetting = mosaicDisplaySettings.OrderByDescending(
|
||||
settings => (long)settings.Width *
|
||||
settings.Height *
|
||||
settings.Bpp *
|
||||
settings.Freq).First();
|
||||
*/
|
||||
|
||||
return screensToReturn.ToArray();
|
||||
}
|
||||
|
||||
public static bool ListOfArraysEqual(List<NV_RECT[]> a1, List<NV_RECT[]> a2)
|
||||
{
|
||||
if (a1.Count == a2.Count)
|
||||
|
@ -11,7 +11,7 @@ using Microsoft.Win32;
|
||||
namespace DisplayMagicianShared.Windows
|
||||
{
|
||||
public class TaskBarSettings
|
||||
{
|
||||
{
|
||||
private const string AdvancedSettingsAddress =
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
|
||||
|
||||
@ -68,7 +68,7 @@ namespace DisplayMagicianShared.Windows
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
var value = key.GetValue(valueName, null,
|
||||
RegistryValueOptions.DoNotExpandEnvironmentNames);
|
||||
|
||||
@ -134,4 +134,4 @@ namespace DisplayMagicianShared.Windows
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -89,7 +89,7 @@ namespace DisplayMagicianShared.Windows
|
||||
|
||||
public string DevicePath { get; set; }
|
||||
|
||||
public bool MainScreen{ get; set; }
|
||||
public bool MainScreen { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public UInt32 DPI
|
||||
@ -262,7 +262,7 @@ namespace DisplayMagicianShared.Windows
|
||||
=> Version == other.Version &&
|
||||
MainScreen == other.MainScreen &&
|
||||
DevicePath == other.DevicePath &&
|
||||
Xor(Binary,other.Binary);
|
||||
Xor(Binary, other.Binary);
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
@ -334,8 +334,8 @@ namespace DisplayMagicianShared.Windows
|
||||
version = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 2)
|
||||
|
||||
if (version >= 2)
|
||||
{
|
||||
// Grab the main screen taskbar placement
|
||||
try
|
||||
@ -383,7 +383,6 @@ namespace DisplayMagicianShared.Windows
|
||||
{
|
||||
foreach (string displayId in displayIdentifiers)
|
||||
{
|
||||
TaskBarStuckRectangle tbStuckRect;
|
||||
// e.g. "WINAPI|\\\\?\\PCI#VEN_10DE&DEV_2482&SUBSYS_408E1458&REV_A1#4&2283f625&0&0019#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}|DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI|54074|4318|\\\\?\\DISPLAY#NVS10DE#5&2b46c695&0&UID185344#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}|NV Surround"
|
||||
string[] winapiLine = displayId.Split('|');
|
||||
string pattern = @"DISPLAY\#(.*)\#\{";
|
||||
@ -485,4 +484,4 @@ namespace DisplayMagicianShared.Windows
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -167,7 +167,7 @@ namespace DisplayMagicianShared.Windows
|
||||
myDefaultConfig.DisplayConfigPaths = new DISPLAYCONFIG_PATH_INFO[0];
|
||||
myDefaultConfig.DisplayHDRStates = new List<ADVANCED_HDR_INFO_PER_PATH>();
|
||||
myDefaultConfig.DisplayIdentifiers = new List<string>();
|
||||
myDefaultConfig.DisplaySources = new Dictionary<string, List<uint>>();
|
||||
myDefaultConfig.DisplaySources = new Dictionary<string, List<uint>>();
|
||||
myDefaultConfig.GdiDisplaySettings = new Dictionary<string, GDI_DISPLAY_SETTING>();
|
||||
myDefaultConfig.TaskBarLayout = new List<TaskBarStuckRectangle>();
|
||||
myDefaultConfig.TaskBarSettings = new TaskBarSettings();
|
||||
@ -387,8 +387,8 @@ namespace DisplayMagicianShared.Windows
|
||||
bool isClonedProfile = false;
|
||||
for (int i = 0; i < paths.Length; i++)
|
||||
{
|
||||
bool gotSourceDeviceName = false;
|
||||
bool gotAdapterName = false;
|
||||
//bool gotSourceDeviceName = false;
|
||||
//bool gotAdapterName = false;
|
||||
bool gotAdvancedColorInfo = false;
|
||||
bool gotSdrWhiteLevel = false;
|
||||
|
||||
@ -414,7 +414,7 @@ namespace DisplayMagicianShared.Windows
|
||||
err = CCDImport.DisplayConfigGetDeviceInfo(ref sourceInfo);
|
||||
if (err == WIN32STATUS.ERROR_SUCCESS)
|
||||
{
|
||||
gotSourceDeviceName = true;
|
||||
//gotSourceDeviceName = true;
|
||||
// Store it for later
|
||||
if (windowsDisplayConfig.DisplaySources.ContainsKey(sourceInfo.ViewGdiDeviceName))
|
||||
{
|
||||
@ -462,7 +462,7 @@ namespace DisplayMagicianShared.Windows
|
||||
err = CCDImport.DisplayConfigGetDeviceInfo(ref adapterInfo);
|
||||
if (err == WIN32STATUS.ERROR_SUCCESS)
|
||||
{
|
||||
gotAdapterName = true;
|
||||
//gotAdapterName = true;
|
||||
// Store it for later
|
||||
windowsDisplayConfig.DisplayAdapters.Add(paths[i].TargetInfo.AdapterId.Value, adapterInfo.AdapterDevicePath);
|
||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Found adapter name {adapterInfo.AdapterDevicePath} for adapter {paths[i].TargetInfo.AdapterId.Value}.");
|
||||
@ -476,7 +476,7 @@ namespace DisplayMagicianShared.Windows
|
||||
{
|
||||
// We already have the adapter name
|
||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: We already have the adapter name {windowsDisplayConfig.DisplayAdapters[paths[i].TargetInfo.AdapterId.Value]} for adapter {paths[i].TargetInfo.AdapterId.Value} so skipping storing it.");
|
||||
gotAdapterName = true;
|
||||
//gotAdapterName = true;
|
||||
}
|
||||
|
||||
// Get advanced color info
|
||||
@ -603,7 +603,7 @@ namespace DisplayMagicianShared.Windows
|
||||
// We use the information we already got from the display identifiers
|
||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get the Windows Taskbar layout.");
|
||||
List<TaskBarStuckRectangle> taskBarStuckRectangles = TaskBarStuckRectangle.GetCurrent(windowsDisplayConfig.DisplayIdentifiers);
|
||||
|
||||
|
||||
// Now we try to get the taskbar settings too
|
||||
SharedLogger.logger.Trace($"WinLibrary/GetWindowsDisplayConfig: Attempting to get the Windows Taskbar settings.");
|
||||
TaskBarSettings taskBarSettings = TaskBarSettings.GetCurrent();
|
||||
@ -1075,7 +1075,7 @@ namespace DisplayMagicianShared.Windows
|
||||
|
||||
public bool SetActiveConfig(WINDOWS_DISPLAY_CONFIG displayConfig)
|
||||
{
|
||||
bool needToRestartExplorer = false;
|
||||
//bool needToRestartExplorer = false;
|
||||
|
||||
// Get the all possible windows display configs
|
||||
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Generating a list of all the current display configs");
|
||||
@ -1333,10 +1333,10 @@ namespace DisplayMagicianShared.Windows
|
||||
{
|
||||
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Display {displayDeviceKey} is not currently in use, so cannot set it!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Now set the taskbar position for each screen
|
||||
if (displayConfig.TaskBarLayout.Count > 0)
|
||||
{
|
||||
@ -1367,7 +1367,7 @@ namespace DisplayMagicianShared.Windows
|
||||
if (displayConfig.TaskBarSettings.Apply())
|
||||
{
|
||||
SharedLogger.logger.Trace($"WinLibrary/SetActiveConfig: Set the taskbar settings successfully!");
|
||||
needToRestartExplorer = true;
|
||||
//needToRestartExplorer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1908,66 +1908,6 @@ namespace DisplayMagicianShared.Windows
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RestartExplorer()
|
||||
{
|
||||
try
|
||||
{
|
||||
RestartManagerSession restartManager = new RestartManagerSession();
|
||||
FileInfo explorerFileInfo = new FileInfo(@"C:\Windows\explorer.exe");
|
||||
restartManager.RegisterProcessFile(explorerFileInfo);
|
||||
restartManager.Shutdown(RestartManagerSession.ShutdownType.ForceShutdown);
|
||||
restartManager.Restart();
|
||||
restartManager.Dispose();
|
||||
return true;
|
||||
}
|
||||
catch (Win32Exception ex)
|
||||
{
|
||||
if (ex.ErrorCode == 776)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_REQUEST_OUT_OF_SEQUENCE (779): This error value is returned if the RmRestart function is called with a valid session handle before calling the RmShutdown function.");
|
||||
}
|
||||
else if (ex.ErrorCode == 352)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_FAIL_RESTART (352): One or more applications could not be restarted.");
|
||||
}
|
||||
else if (ex.ErrorCode == 121)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_SEM_TIMEOUT (121): A Restart Manager function could not obtain a registry write mutex in the allotted time. A system restart is recommended because further use of the Restart Manager is likely to fail.");
|
||||
}
|
||||
else if (ex.ErrorCode == 1223)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_CANCELLED (1223): This error value is returned by the RmRestart function when the request to cancel an operation is successful.");
|
||||
}
|
||||
else if (ex.ErrorCode == 160)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_BAD_ARGUMENTS (160): One or more arguments are not correct. This error value is returned by the Restart Manager function if a NULL pointer or 0 is passed in a parameter that requires a non-null and non-zero value.");
|
||||
}
|
||||
else if (ex.ErrorCode == 29)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_WRITE_FAULT (29): An operation was unable to read or write to the registry.");
|
||||
}
|
||||
else if (ex.ErrorCode == 14)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_OUTOFMEMORY (14): A Restart Manager operation could not complete because not enough memory was available.");
|
||||
}
|
||||
else if (ex.ErrorCode == 6)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ERROR_INVALID_HANDLE (6): No Restart Manager session exists for the handle supplied.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: RestartManager was unable to restart Windows Explorer. ErrorCode = {ex.ErrorCode}.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SharedLogger.logger.Error(ex, $"WinLibrary/RestartExplorer: General exception when trying to restart Windows Explorer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[global::System.Serializable]
|
||||
|
Loading…
Reference in New Issue
Block a user