diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..373608b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy +Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. + +## Reporting a Vulnerability +Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). diff --git a/Samples/3D_Feature_Samples/3D_Feature_Sample_App.cpp b/Samples/3D_Feature_Samples/3D_Feature_Sample_App.cpp index 7cc0262..a780e70 100644 --- a/Samples/3D_Feature_Samples/3D_Feature_Sample_App.cpp +++ b/Samples/3D_Feature_Samples/3D_Feature_Sample_App.cpp @@ -47,7 +47,7 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) { ctl_result_t Result = CTL_RESULT_SUCCESS; - printf("======================Endurance Gaming test -> Per Application settings======================\n"); + PRINT_LOGS("======================Endurance Gaming test -> Per Application settings======================"); char *pAppName = "GTA5.exe"; ctl_3d_feature_getset_t Get3DProperty = { 0 }; @@ -72,18 +72,18 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) if (NULL != hDevices) { Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" Set3DProperty.ApplicationName = %s\n", Set3DProperty.ApplicationName); - printf(" SetEnduranceGaming.EGControl = %d\n", SetEnduranceGaming.EGControl); - printf(" SetEnduranceGaming.EGMode = %d\n", SetEnduranceGaming.EGMode); + APP_LOG_INFO(" Set3DProperty.ApplicationName = %s", Set3DProperty.ApplicationName); + APP_LOG_INFO(" SetEnduranceGaming.EGControl = %d", SetEnduranceGaming.EGControl); + APP_LOG_INFO(" SetEnduranceGaming.EGMode = %d", SetEnduranceGaming.EGMode); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Set EnduranceGaming) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Set EnduranceGaming) returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success(Set EnduranceGaming)\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Set EnduranceGaming)"); } } @@ -103,7 +103,7 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Get EnduranceGaming) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Get EnduranceGaming) returned failure code: 0x%X", Result); if (nullptr != Get3DProperty.pCustomValue) { @@ -116,11 +116,11 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) else { ctl_endurance_gaming_t *pGetEnduranceGaming = (ctl_endurance_gaming_t *)Get3DProperty.pCustomValue; - printf("ctlGetSet3DFeature returned success(Get EnduranceGaming)\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Get EnduranceGaming)"); - printf(" Get3DProperty.ApplicationName = %s\n", Get3DProperty.ApplicationName); - printf(" pGetEnduranceGaming->EGControl = %d\n", pGetEnduranceGaming->EGControl); - printf(" pGetEnduranceGaming->EGMode = %d\n", pGetEnduranceGaming->EGMode); + APP_LOG_INFO(" Get3DProperty.ApplicationName = %s", Get3DProperty.ApplicationName); + APP_LOG_INFO(" pGetEnduranceGaming->EGControl = %d", pGetEnduranceGaming->EGControl); + APP_LOG_INFO(" pGetEnduranceGaming->EGMode = %d", pGetEnduranceGaming->EGMode); } } @@ -130,7 +130,7 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) Get3DProperty.pCustomValue = NULL; } - printf("======================Endurance Gaming test -> Global settings======================\n"); + PRINT_LOGS("======================Endurance Gaming test -> Global settings======================"); Get3DProperty = { 0 }; Set3DProperty = { 0 }; @@ -151,17 +151,17 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) if (NULL != hDevices) { Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" SetEnduranceGaming.EGControl = %d\n", SetEnduranceGaming.EGControl); - printf(" SetEnduranceGaming.EGMode = %d\n", SetEnduranceGaming.EGMode); + APP_LOG_INFO(" SetEnduranceGaming.EGControl = %d", SetEnduranceGaming.EGControl); + APP_LOG_INFO(" SetEnduranceGaming.EGMode = %d", SetEnduranceGaming.EGMode); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Set EnduranceGaming) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Set EnduranceGaming) returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success(Set EnduranceGaming)\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Set EnduranceGaming)"); } } @@ -179,7 +179,7 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Get EnduranceGaming) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Get EnduranceGaming) returned failure code: 0x%X", Result); if (nullptr != Get3DProperty.pCustomValue) { @@ -192,10 +192,10 @@ ctl_result_t CtlEnduranceGamingTest(ctl_device_adapter_handle_t hDevices) else { ctl_endurance_gaming_t *pGetEnduranceGamingGlobal = (ctl_endurance_gaming_t *)Get3DProperty.pCustomValue; - printf("ctlGetSet3DFeature returned success(Get EnduranceGaming)\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Get EnduranceGaming)"); - printf(" pGetEnduranceGamingGlobal->EGControl = %d\n", pGetEnduranceGamingGlobal->EGControl); - printf(" pGetEnduranceGamingGlobal->EGMode = %d\n", pGetEnduranceGamingGlobal->EGMode); + APP_LOG_INFO(" pGetEnduranceGamingGlobal->EGControl = %d", pGetEnduranceGamingGlobal->EGControl); + APP_LOG_INFO(" pGetEnduranceGamingGlobal->EGMode = %d", pGetEnduranceGamingGlobal->EGMode); } } @@ -219,7 +219,7 @@ ctl_result_t CtlGamingFlipTest(ctl_device_adapter_handle_t hDevices) // Gaming flips Per APP GET/SET ctl_result_t Result = CTL_RESULT_SUCCESS; - printf("======================Gaming flips test -> Per Application settings =====================\n"); + PRINT_LOGS("======================Gaming flips test -> Per Application settings ====================="); char *pAppName = "GTA5.exe"; ctl_3d_feature_getset_t Get3DProperty = { 0 }; ctl_3d_feature_getset_t Set3DProperty = { 0 }; @@ -241,17 +241,17 @@ ctl_result_t CtlGamingFlipTest(ctl_device_adapter_handle_t hDevices) if (NULL != hDevices) { Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" Set3DProperty.Value.EnumType.EnableType = %d\n", Set3DProperty.Value.EnumType.EnableType); - printf(" Set3DProperty.ApplicationName = %s\n", Set3DProperty.ApplicationName); + APP_LOG_INFO(" Set3DProperty.Value.EnumType.EnableType = %d", Set3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Set3DProperty.ApplicationName = %s", Set3DProperty.ApplicationName); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); } // Get Gaming flips modes only @@ -269,22 +269,22 @@ ctl_result_t CtlGamingFlipTest(ctl_device_adapter_handle_t hDevices) Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); - printf(" Get3DProperty.Value.EnumType.EnableType = %d\n", Get3DProperty.Value.EnumType.EnableType); - printf(" Get3DProperty.ApplicationName = %s\n", Get3DProperty.ApplicationName); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); + APP_LOG_INFO(" Get3DProperty.Value.EnumType.EnableType = %d", Get3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Get3DProperty.ApplicationName = %s", Get3DProperty.ApplicationName); } } } // Gaming flips Global GET/SET - printf("======================Gaming flips test -> Global settings======================\n"); + PRINT_LOGS("======================Gaming flips test -> Global settings======================"); Get3DProperty = { 0 }; Set3DProperty = { 0 }; @@ -303,16 +303,16 @@ ctl_result_t CtlGamingFlipTest(ctl_device_adapter_handle_t hDevices) if (NULL != hDevices) { Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" Set3DProperty.Value.EnumType.EnableType = %d\n", Set3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Set3DProperty.Value.EnumType.EnableType = %d", Set3DProperty.Value.EnumType.EnableType); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); } // Get Gaming flips modes only @@ -328,14 +328,14 @@ ctl_result_t CtlGamingFlipTest(ctl_device_adapter_handle_t hDevices) Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); - printf(" Get3DProperty.Value.EnumType.EnableType = %d\n", Get3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); + APP_LOG_INFO(" Get3DProperty.Value.EnumType.EnableType = %d", Get3DProperty.Value.EnumType.EnableType); } } } @@ -360,13 +360,18 @@ ctl_result_t CtlGet3DFeatureCaps(ctl_device_adapter_handle_t hDevices) Result = ctlGetSupported3DCapabilities(hDevices, &FeatureCaps3D); if (Result != CTL_RESULT_SUCCESS) { - printf("ctlGetSupported3DCapabilities returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSupported3DCapabilities returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSupported3DCapabilities returned success\n"); + APP_LOG_INFO("ctlGetSupported3DCapabilities returned success"); FeatureCaps3D.pFeatureDetails = (ctl_3d_feature_details_t *)malloc(sizeof(ctl_3d_feature_details_t) * FeatureCaps3D.NumSupportedFeatures); + if (FeatureCaps3D.pFeatureDetails == NULL) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + memset(FeatureCaps3D.pFeatureDetails, 0x0, sizeof(ctl_3d_feature_details_t) * FeatureCaps3D.NumSupportedFeatures); Result = ctlGetSupported3DCapabilities(hDevices, &FeatureCaps3D); if (Result == CTL_RESULT_SUCCESS) @@ -399,7 +404,7 @@ ctl_result_t CtlGet3DFeatureCaps(ctl_device_adapter_handle_t hDevices) } else { - printf("ctlGetSupported3DCapabilities returned failure code when called with NumSupportedFeatures set: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSupported3DCapabilities returned failure code when called with NumSupportedFeatures set: 0x%X", Result); if (nullptr != FeatureCaps3D.pFeatureDetails) { free(FeatureCaps3D.pFeatureDetails); @@ -407,11 +412,9 @@ ctl_result_t CtlGet3DFeatureCaps(ctl_device_adapter_handle_t hDevices) } return Result; } - if (nullptr != FeatureCaps3D.pFeatureDetails) - { - free(FeatureCaps3D.pFeatureDetails); - FeatureCaps3D.pFeatureDetails = nullptr; - } + + free(FeatureCaps3D.pFeatureDetails); + FeatureCaps3D.pFeatureDetails = nullptr; } } @@ -425,13 +428,13 @@ DWORD WINAPI CtlEventThread(LPVOID ThreadParameterPtr) ctl_wait_property_change_args_t Args = { 0 }; - printf("CtlEventThread: Entering thread\n"); + APP_LOG_INFO("CtlEventThread: Entering thread"); Args.PropertyType = CTL_PROPERTY_TYPE_FLAG_MEDIA | CTL_PROPERTY_TYPE_FLAG_DISPLAY | CTL_PROPERTY_TYPE_FLAG_3D; Args.Size = sizeof(Args); Args.TimeOutMilliSec = 500; // 0.5sec - printf("CtlEventThread: Calling ctlWaitForPropertyChange() and getting to blocked state...\n"); + APP_LOG_INFO("CtlEventThread: Calling ctlWaitForPropertyChange() and getting to blocked state..."); do { @@ -440,8 +443,8 @@ DWORD WINAPI CtlEventThread(LPVOID ThreadParameterPtr) continue; } while (false == QuiteEventThread); - printf("CtlEventThread: ctlWaitForPropertyChange() unblocked return value = %d\n", Result); - printf("CtlEventThread: Exiting thread\n"); + APP_LOG_INFO("CtlEventThread: ctlWaitForPropertyChange() unblocked return value = %d", Result); + APP_LOG_INFO("CtlEventThread: Exiting thread"); return Result; } @@ -460,9 +463,8 @@ ctl_result_t CtlTestEvents(ctl_device_adapter_handle_t hAdapter) DWORD ThreadID = 0; HANDLE ThreadHandle = NULL; - printf("Do you want to listen for events (L), listen via a thread (T), quit (Q) or do series of set calls (any other key)? "); + PRINT_LOGS("Do you want to listen for events (L), listen via a thread (T), quit (Q) or do series of set calls (any other key)? "); int Key = _getch(); - printf("\n"); if ((Key == 'L') || (Key == 'l')) { Listener = true; @@ -485,13 +487,13 @@ ctl_result_t CtlTestEvents(ctl_device_adapter_handle_t hAdapter) if (NULL == ThreadHandle) { - printf("CreateThread failed!\n"); + APP_LOG_ERROR("CreateThread failed!"); Result = CTL_RESULT_ERROR_OS_CALL; break; } else { - printf("Created thread ID = 0x%X\n", ThreadID); + APP_LOG_INFO("Created thread ID = 0x%X", ThreadID); } } else @@ -502,16 +504,16 @@ ctl_result_t CtlTestEvents(ctl_device_adapter_handle_t hAdapter) Args.Size = sizeof(Args); Args.TimeOutMilliSec = 0xFFFFFFFF; // INFINITE; - printf("Calling ctlWaitForPropertyChange() and getting to blocked state...\n"); + APP_LOG_INFO("Calling ctlWaitForPropertyChange() and getting to blocked state..."); Result = ctlWaitForPropertyChange(hAdapter, &Args); // blocking call - printf("ctlWaitForPropertyChange() unblocked return value = %d\n", Result); + APP_LOG_INFO("ctlWaitForPropertyChange() unblocked return value = %d", Result); } } else { - printf("Trying a 3D set call & restoring it (overrall 2 set calls)...\n"); + APP_LOG_INFO("Trying a 3D set call & restoring it (overrall 2 set calls)..."); // try setting various parameters, or just the app once more ctl_3d_feature_getset_t Feature3D = { 0 }; @@ -546,17 +548,15 @@ ctl_result_t CtlTestEvents(ctl_device_adapter_handle_t hAdapter) if (SpawnThread) { - printf("Press any key to signal thread to exit..."); - int Key = _getch(); - printf("\n"); + PRINT_LOGS("Press any key to signal thread to exit..."); + int Key = _getch(); QuiteEventThread = true; break; // exit from loop } else { - printf("Quit(q) or continue (any other key)? "); + PRINT_LOGS("Quit(q) or continue (any other key)? "); int Key = _getch(); - printf("\n"); if ((Key == 'Q') || (Key == 'q')) { QuiteEventThread = true; @@ -599,28 +599,28 @@ ctl_result_t CtlGetGamingAppProfile(ctl_device_adapter_handle_t hDevices, ctl_3d if (NULL != hDevices) { - printf("\nDoing a GetAILProfile(%s, %s)\n", ApplicationName ? ApplicationName : "Global", AppProfileGet.TierType == CTL_3D_TIER_TYPE_FLAG_COMPATIBILITY ? "Compatibility" : "Performance"); + APP_LOG_INFO("Doing a GetAILProfile(%s, %s)", ApplicationName ? ApplicationName : "Global", AppProfileGet.TierType == CTL_3D_TIER_TYPE_FLAG_COMPATIBILITY ? "Compatibility" : "Performance"); Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Get AppProfile) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Get AppProfile) returned failure code: 0x%X", Result); if (Result == CTL_RESULT_ERROR_DATA_NOT_FOUND) { - printf(" Reason: Value not found\n"); - printf(" Use DefaultEnabledTierProfiles (=%s) for UI default selection if required\n", GetProfileTierName(AppProfileGet.DefaultEnabledTierProfiles, TierName, 100)); + APP_LOG_ERROR(" Reason: Value not found"); + APP_LOG_INFO(" Use DefaultEnabledTierProfiles (=%s) for UI default selection if required", GetProfileTierName(AppProfileGet.DefaultEnabledTierProfiles, TierName, 100)); } } else if (Get3DProperty.CustomValueSize > 0) { - printf("ctlGetSet3DFeature returned success(Get AppProfile)\n"); - printf(" App name = %s\n", ApplicationName == NULL ? "Global" : ApplicationName); - printf(" AppProfileGet.TierType = %s\n", GetProfileTypeName(AppProfileGet.TierType)); - printf(" AppProfileGet.EnabledTierProfiles = %s\n", GetProfileTierName(AppProfileGet.EnabledTierProfiles, TierName, 100)); - printf(" AppProfileGet.DefaultEnabledTierProfiles = %s\n", GetProfileTierName(AppProfileGet.DefaultEnabledTierProfiles, TierName, 100)); - printf(" AppProfileGet.CustomizationSupportedTierProfiles = %s\n", GetProfileTierName(AppProfileGet.CustomizationSupportedTierProfiles, TierName, 100)); - printf(" AppProfileGet.CustomizationEnabledTierProfiles = %s\n", GetProfileTierName(AppProfileGet.CustomizationEnabledTierProfiles, TierName, 100)); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Get AppProfile)"); + APP_LOG_INFO(" App name = %s", ApplicationName == NULL ? "Global" : ApplicationName); + APP_LOG_INFO(" AppProfileGet.TierType = %s", GetProfileTypeName(AppProfileGet.TierType)); + APP_LOG_INFO(" AppProfileGet.EnabledTierProfiles = %s", GetProfileTierName(AppProfileGet.EnabledTierProfiles, TierName, 100)); + APP_LOG_INFO(" AppProfileGet.DefaultEnabledTierProfiles = %s", GetProfileTierName(AppProfileGet.DefaultEnabledTierProfiles, TierName, 100)); + APP_LOG_INFO(" AppProfileGet.CustomizationSupportedTierProfiles = %s", GetProfileTierName(AppProfileGet.CustomizationSupportedTierProfiles, TierName, 100)); + APP_LOG_INFO(" AppProfileGet.CustomizationEnabledTierProfiles = %s", GetProfileTierName(AppProfileGet.CustomizationEnabledTierProfiles, TierName, 100)); } } @@ -651,24 +651,24 @@ ctl_result_t CtlSetGamingAppProfile(ctl_device_adapter_handle_t hDevices, ctl_3d if (NULL != hDevices) { - printf("\nDoing a SetAILProfile(%s, %s)\n", ApplicationName ? ApplicationName : "Global", AppProfileSet.TierType == CTL_3D_TIER_TYPE_FLAG_COMPATIBILITY ? "Compatibility" : "Performance"); + APP_LOG_INFO("Doing a SetAILProfile(%s, %s)", ApplicationName ? ApplicationName : "Global", AppProfileSet.TierType == CTL_3D_TIER_TYPE_FLAG_COMPATIBILITY ? "Compatibility" : "Performance"); Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Set AppProfile) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Set AppProfile) returned failure code: 0x%X", Result); if (CTL_RESULT_ERROR_DATA_NOT_FOUND == Result) - printf("Reason: Value not found\n"); + APP_LOG_ERROR("Reason: Value not found"); return Result; } else if (Set3DProperty.CustomValueSize > 0) { - printf("ctlGetSet3DFeature returned success(Set AppProfile)\n"); - printf(" App name = %s\n", ApplicationName == NULL ? "Global" : ApplicationName); - printf(" AppProfileSet.TierType = %s\n", GetProfileTypeName(AppProfileSet.TierType)); - printf(" AppProfileSet.EnabledTierProfiles = %s\n", GetProfileTierName(AppProfileSet.EnabledTierProfiles, TierName, 100)); - printf(" AppProfileSet.CustomizationSupportedTierProfiles = %s\n", GetProfileTierName(AppProfileSet.CustomizationSupportedTierProfiles, TierName, 100)); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Set AppProfile)"); + APP_LOG_INFO(" App name = %s", ApplicationName == NULL ? "Global" : ApplicationName); + APP_LOG_INFO(" AppProfileSet.TierType = %s", GetProfileTypeName(AppProfileSet.TierType)); + APP_LOG_INFO(" AppProfileSet.EnabledTierProfiles = %s", GetProfileTierName(AppProfileSet.EnabledTierProfiles, TierName, 100)); + APP_LOG_INFO(" AppProfileSet.CustomizationSupportedTierProfiles = %s", GetProfileTierName(AppProfileSet.CustomizationSupportedTierProfiles, TierName, 100)); } } @@ -685,7 +685,7 @@ ctl_result_t CtlGamingAppProfile(ctl_device_adapter_handle_t hDevices) { ctl_result_t Result = CTL_RESULT_SUCCESS; - printf("======================Gaming App Profile test======================\n"); + PRINT_LOGS("======================Gaming App Profile test======================"); ctl_3d_app_profiles_t AppProfile = { 0 }; @@ -722,7 +722,7 @@ ctl_result_t CtlCMAAGamingFeatureTest(ctl_device_adapter_handle_t hDevices) if (NULL == hDevices) return CTL_RESULT_ERROR_INVALID_NULL_HANDLE; - printf("======================CtlCMAAGamingFeatureTest======================\n"); + PRINT_LOGS("======================CtlCMAAGamingFeatureTest======================"); ctl_3d_feature_getset_t Get3DProperty = { 0 }; ctl_3d_feature_getset_t Set3DProperty = { 0 }; @@ -737,16 +737,16 @@ ctl_result_t CtlCMAAGamingFeatureTest(ctl_device_adapter_handle_t hDevices) Get3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; Get3DProperty.Version = 0; Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); - printf(" Get3DProperty.Value.EnumType.EnableType = %d\n", Get3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Get3DProperty.Value.EnumType.EnableType = %d", Get3DProperty.Value.EnumType.EnableType); if (CTL_RESULT_SUCCESS != Result) { - printf("Returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("Returned failure code: 0x%X", Result); if (CTL_RESULT_ERROR_DATA_NOT_FOUND != Result) // if value not present, it's expected, so continue with set/get verification return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); InitialValue = Get3DProperty.Value.EnumType.EnableType; } @@ -757,15 +757,15 @@ ctl_result_t CtlCMAAGamingFeatureTest(ctl_device_adapter_handle_t hDevices) Set3DProperty.Version = 0; Set3DProperty.Value.EnumType.EnableType = CTL_3D_CMAA_TYPES_OVERRIDE_MSAA; Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" Set3DProperty.Value.EnumType.EnableType = CTL_3D_CMAA_TYPES_OVERRIDE_MSAA\n"); + APP_LOG_INFO(" Set3DProperty.Value.EnumType.EnableType = CTL_3D_CMAA_TYPES_OVERRIDE_MSAA"); if (CTL_RESULT_SUCCESS != Result) { - printf("Returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("Returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); } // Get feature back & check - global @@ -774,18 +774,18 @@ ctl_result_t CtlCMAAGamingFeatureTest(ctl_device_adapter_handle_t hDevices) Get3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; Get3DProperty.Version = 0; Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); - printf(" Get3DProperty.Value.EnumType.EnableType = %d\n", Get3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Get3DProperty.Value.EnumType.EnableType = %d", Get3DProperty.Value.EnumType.EnableType); if (CTL_RESULT_SUCCESS != Result) { - printf("Returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("Returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); if (Get3DProperty.Value.EnumType.EnableType != Set3DProperty.Value.EnumType.EnableType) { - printf("ERROR: Value didn't get set!\n"); + APP_LOG_ERROR("ERROR: Value didn't get set!"); return CTL_RESULT_ERROR_UNKNOWN; } } @@ -797,15 +797,15 @@ ctl_result_t CtlCMAAGamingFeatureTest(ctl_device_adapter_handle_t hDevices) Set3DProperty.Version = 0; Set3DProperty.Value.EnumType.EnableType = InitialValue; Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" Set3DProperty.Value.EnumType.EnableType = %d\n", Set3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Set3DProperty.Value.EnumType.EnableType = %d", Set3DProperty.Value.EnumType.EnableType); if (CTL_RESULT_SUCCESS != Result) { - printf("Returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("Returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success"); } return Result; @@ -822,7 +822,7 @@ ctl_result_t CtlGlobalOrPerAppTest(ctl_device_adapter_handle_t hDevices) ctl_result_t Result = CTL_RESULT_SUCCESS; char *pAppName = "GTA5.exe"; - printf("======================Global Or Per App test======================\n"); + PRINT_LOGS("======================Global Or Per App test======================"); ctl_3d_feature_getset_t Get3DProperty = { 0 }; ctl_3d_feature_getset_t Set3DProperty = { 0 }; @@ -844,18 +844,18 @@ ctl_result_t CtlGlobalOrPerAppTest(ctl_device_adapter_handle_t hDevices) if (NULL != hDevices) { Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); - printf(" Set3DProperty.ApplicationName = %s\n", Set3DProperty.ApplicationName); - printf(" Set3DProperty.Value.EnumType.EnableType = %d\n", Set3DProperty.Value.EnumType.EnableType); + APP_LOG_INFO(" Set3DProperty.ApplicationName = %s", Set3DProperty.ApplicationName); + APP_LOG_INFO(" Set3DProperty.Value.EnumType.EnableType = %d", Set3DProperty.Value.EnumType.EnableType); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Set Global Over Per App Setting (Set call)) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Set Global Over Per App Setting (Set call)) returned failure code: 0x%X", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success(Set Global Over Per App Setting (Set call))\n"); + APP_LOG_INFO("ctlGetSet3DFeature returned success(Set Global Over Per App Setting (Set call))"); } } @@ -875,15 +875,293 @@ ctl_result_t CtlGlobalOrPerAppTest(ctl_device_adapter_handle_t hDevices) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSet3DFeature(Set Global Over Per App Setting (Get call)) returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlGetSet3DFeature(Set Global Over Per App Setting (Get call)) returned failure code: 0x%X", Result); + + return Result; + } + else + { + APP_LOG_INFO("ctlGetSet3DFeature returned success(Set Global Over Per App Setting (Get call))"); + APP_LOG_INFO(" Get3DProperty.ApplicationName = %s", Get3DProperty.ApplicationName); + APP_LOG_INFO(" Get3DProperty.Value.EnumType.EnableTypee = %d", Get3DProperty.Value.EnumType.EnableType); + } + } + + return Result; +} + +/*************************************************************** + * @brief + * Method to test Frame Limit + * @param hDevices + * @return ctl_result_t + ***************************************************************/ +ctl_result_t CtlTestFrameLimit(ctl_device_adapter_handle_t hDevices) +{ + // Frame Limit Per APP GET/SET + ctl_result_t Result = CTL_RESULT_SUCCESS; + + printf("======================Frame Limit test -> Per Application settings =====================\n"); + char *pAppName = "GTA5.exe"; + ctl_3d_feature_getset_t Get3DProperty = { 0 }; + ctl_3d_feature_getset_t Set3DProperty = { 0 }; + + Set3DProperty.Size = sizeof(Set3DProperty); + Get3DProperty.Size = sizeof(Get3DProperty); + + // Set Frame Limit + Set3DProperty.FeatureType = CTL_3D_FEATURE_FRAME_LIMIT; + Set3DProperty.bSet = TRUE; + Set3DProperty.CustomValueSize = 0; + Set3DProperty.pCustomValue = NULL; + Set3DProperty.ApplicationName = pAppName; + Set3DProperty.ApplicationNameLength = (int8_t)strlen(pAppName); + Set3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_INT32; + Set3DProperty.Value.IntType.Enable = true; + Set3DProperty.Value.IntType.Value = 30; + Set3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); + printf(" Set3DProperty.Value.IntType.Enable = %d\n", Set3DProperty.Value.IntType.Enable); + printf(" Set3DProperty.Value.IntType.Value = %d\n", Set3DProperty.Value.IntType.Value); + printf(" Set3DProperty.ApplicationName = %s\n", Set3DProperty.ApplicationName); + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + } + + // Get Frame Limit + Get3DProperty.FeatureType = CTL_3D_FEATURE_FRAME_LIMIT; + Get3DProperty.bSet = FALSE; + Get3DProperty.CustomValueSize = 0; + Get3DProperty.pCustomValue = NULL; + Get3DProperty.ApplicationName = pAppName; + Get3DProperty.ApplicationNameLength = (int8_t)strlen(pAppName); + Get3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_INT32; + Get3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); + + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + printf(" Get3DProperty.Value.IntType.Enable = %d\n", Get3DProperty.Value.IntType.Enable); + printf(" Get3DProperty.Value.IntType.Value = %d\n", Get3DProperty.Value.IntType.Value); + printf(" Get3DProperty.ApplicationName = %s\n", Get3DProperty.ApplicationName); + } + } + } + + // Frame Limit Global GET/SET + + printf("======================Frame Limit test -> Global settings======================\n"); + Get3DProperty = { 0 }; + Set3DProperty = { 0 }; + + Set3DProperty.Size = sizeof(Set3DProperty); + Get3DProperty.Size = sizeof(Get3DProperty); + + // Set Frame Limit + Set3DProperty.FeatureType = CTL_3D_FEATURE_FRAME_LIMIT; + Set3DProperty.bSet = TRUE; + Set3DProperty.CustomValueSize = 0; + Set3DProperty.pCustomValue = NULL; + Set3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_INT32; + Set3DProperty.Value.IntType.Enable = true; + Set3DProperty.Value.IntType.Value = 60; + Set3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); + printf(" Set3DProperty.Value.IntType.Enable = %d\n", Set3DProperty.Value.IntType.Enable); + printf(" Set3DProperty.Value.IntType.Value = %d\n", Set3DProperty.Value.IntType.Value); + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); return Result; } else { - printf("ctlGetSet3DFeature returned success(Set Global Over Per App Setting (Get call))\n"); - printf(" Get3DProperty.ApplicationName = %s\n", Get3DProperty.ApplicationName); - printf(" Get3DProperty.Value.EnumType.EnableTypee = %d\n", Get3DProperty.Value.EnumType.EnableType); + printf("ctlGetSet3DFeature returned success\n"); + } + + // Get Frame Limit + Get3DProperty.FeatureType = CTL_3D_FEATURE_FRAME_LIMIT; + Get3DProperty.bSet = FALSE; + Get3DProperty.CustomValueSize = 0; + Get3DProperty.pCustomValue = NULL; + Get3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_INT32; + Get3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + printf(" Get3DProperty.Value.IntType.Enable = %d\n", Get3DProperty.Value.IntType.Enable); + printf(" Get3DProperty.Value.IntType.Value = %d\n", Get3DProperty.Value.IntType.Value); + } + } + } + + return Result; +} + +/*************************************************************** + * @brief + * Method to test Low Latency + * @param hDevices + * @return ctl_result_t + ***************************************************************/ +ctl_result_t CtlTestLowLatency(ctl_device_adapter_handle_t hDevices) +{ + // Low Latency Per APP GET/SET + ctl_result_t Result = CTL_RESULT_SUCCESS; + + printf("======================Low Latency test -> Per Application settings =====================\n"); + char *pAppName = "GTA5.exe"; + ctl_3d_feature_getset_t Get3DProperty = { 0 }; + ctl_3d_feature_getset_t Set3DProperty = { 0 }; + + Set3DProperty.Size = sizeof(Set3DProperty); + Get3DProperty.Size = sizeof(Get3DProperty); + + // Set Low Latency mode + Set3DProperty.FeatureType = CTL_3D_FEATURE_LOW_LATENCY; + Set3DProperty.bSet = TRUE; + Set3DProperty.CustomValueSize = 0; + Set3DProperty.pCustomValue = NULL; + Set3DProperty.ApplicationName = pAppName; + Set3DProperty.ApplicationNameLength = (int8_t)strlen(pAppName); + Set3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Set3DProperty.Value.EnumType.EnableType = CTL_3D_LOW_LATENCY_TYPES_TURN_ON_BOOST_MODE_ON; + Set3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); + printf(" Set3DProperty.Value.EnumType.EnableType = %d\n", Set3DProperty.Value.EnumType.EnableType); + printf(" Set3DProperty.ApplicationName = %s\n", Set3DProperty.ApplicationName); + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + } + + // Get Low Latency mode + Get3DProperty.FeatureType = CTL_3D_FEATURE_LOW_LATENCY; + Get3DProperty.bSet = FALSE; + Get3DProperty.CustomValueSize = 0; + Get3DProperty.pCustomValue = NULL; + Get3DProperty.ApplicationName = pAppName; + Get3DProperty.ApplicationNameLength = (int8_t)strlen(pAppName); + Get3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Get3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); + + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + printf(" Get3DProperty.Value.EnumType.EnableType = %d\n", Get3DProperty.Value.EnumType.EnableType); + printf(" Get3DProperty.ApplicationName = %s\n", Get3DProperty.ApplicationName); + } + } + } + + // Low Latency Global GET/SET + + printf("======================Low Latency test -> Global settings======================\n"); + Get3DProperty = { 0 }; + Set3DProperty = { 0 }; + + Set3DProperty.Size = sizeof(Set3DProperty); + Get3DProperty.Size = sizeof(Get3DProperty); + + // Set Low Latency mode + Set3DProperty.FeatureType = CTL_3D_FEATURE_LOW_LATENCY; + Set3DProperty.bSet = TRUE; + Set3DProperty.CustomValueSize = 0; + Set3DProperty.pCustomValue = NULL; + Set3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Set3DProperty.Value.EnumType.EnableType = CTL_3D_LOW_LATENCY_TYPES_TURN_ON; + Set3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Set3DProperty); + printf(" Set3DProperty.Value.EnumType.EnableType = %d\n", Set3DProperty.Value.EnumType.EnableType); + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + } + + // Get Low Latency mode + Get3DProperty.FeatureType = CTL_3D_FEATURE_LOW_LATENCY; + Get3DProperty.bSet = FALSE; + Get3DProperty.CustomValueSize = 0; + Get3DProperty.pCustomValue = NULL; + Get3DProperty.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Get3DProperty.Version = 0; + + if (NULL != hDevices) + { + Result = ctlGetSet3DFeature(hDevices, &Get3DProperty); + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlGetSet3DFeature returned failure code: 0x%X\n", Result); + + return Result; + } + else + { + printf("ctlGetSet3DFeature returned success\n"); + printf(" Get3DProperty.Value.EnumType.EnableType = %d\n", Get3DProperty.Value.EnumType.EnableType); + } } } @@ -908,13 +1186,29 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { @@ -924,12 +1218,20 @@ int main() return CTL_RESULT_ERROR_INVALID_NULL_POINTER; } - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } } if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDevices returned failure code: 0x%X\n", Result); - goto free_exit; + APP_LOG_ERROR("ctlEnumerateDevices returned failure code: 0x%X", Result); + goto Exit; } for (Index = 0; Index < AdapterCount; Index++) @@ -937,11 +1239,18 @@ int main() if (CTL_RESULT_SUCCESS == Result) { - Result = CtlGet3DFeatureCaps(hDevices[Index]); + try + { + Result = CtlGet3DFeatureCaps(hDevices[Index]); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } if (CTL_RESULT_SUCCESS != Result) { - printf("CtlGet3DCaps returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("CtlGet3DCaps returned failure code: 0x%X", Result); } STORE_RESET_ERROR(Result); @@ -949,7 +1258,7 @@ int main() if (CTL_RESULT_SUCCESS != Result) { - printf("CtlEnduranceGamingTest failure code: 0x%X\n", Result); + APP_LOG_ERROR("CtlEnduranceGamingTest failure code: 0x%X", Result); } STORE_RESET_ERROR(Result); @@ -957,28 +1266,42 @@ int main() if (CTL_RESULT_SUCCESS != Result) { - printf("CtlGamingFlipTest failure code: 0x%X\n", Result); + APP_LOG_ERROR("CtlGamingFlipTest failure code: 0x%X", Result); } STORE_RESET_ERROR(Result); Result = CtlGamingAppProfile(hDevices[Index]); if (CTL_RESULT_SUCCESS != Result) { - printf("CtlGamingAppProfile failure code: 0x%X\n", Result); + APP_LOG_ERROR("CtlGamingAppProfile failure code: 0x%X", Result); } STORE_RESET_ERROR(Result); Result = CtlCMAAGamingFeatureTest(hDevices[Index]); if (CTL_RESULT_SUCCESS != Result) { - printf("CtlCMAAGamingFeatureTest failure code: 0x%X\n", Result); + APP_LOG_ERROR("CtlCMAAGamingFeatureTest failure code: 0x%X", Result); } STORE_RESET_ERROR(Result); Result = CtlGlobalOrPerAppTest(hDevices[Index]); if (CTL_RESULT_SUCCESS != Result) { - printf("CtlGlobalOrPerAppTest failure code: 0x%X\n", Result); + APP_LOG_ERROR("CtlGlobalOrPerAppTest failure code: 0x%X", Result); + } + STORE_RESET_ERROR(Result); + + Result = CtlTestFrameLimit(hDevices[Index]); + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("CtlTestFrameLimit failure code: 0x%X", Result); + } + STORE_RESET_ERROR(Result); + + Result = CtlTestLowLatency(hDevices[Index]); + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("CtlTestLowLatency failure code: 0x%X", Result); } STORE_RESET_ERROR(Result); @@ -991,7 +1314,7 @@ int main() { STORE_RESET_ERROR(Result); } -free_exit: +Exit: ctlClose(hAPIHandle); @@ -1001,7 +1324,7 @@ int main() hDevices = nullptr; } - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/3D_Feature_Samples/CMakeLists.txt b/Samples/3D_Feature_Samples/CMakeLists.txt index 4e0e9f6..d76dbe4 100644 --- a/Samples/3D_Feature_Samples/CMakeLists.txt +++ b/Samples/3D_Feature_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME 3D_Feature_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(3D_Feature_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/3D_Feature_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Color_Samples/CMakeLists.txt b/Samples/Color_Samples/CMakeLists.txt index 90223f6..a39564b 100644 --- a/Samples/Color_Samples/CMakeLists.txt +++ b/Samples/Color_Samples/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Color_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Color_Samples VERSION 1.0) @@ -6,7 +6,7 @@ add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/ColorAlgorithms_App.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Color_Sample_App.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ColorAlgorithms_App.h - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -20,5 +20,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Color_Samples/Color_Sample_App.cpp b/Samples/Color_Samples/Color_Sample_App.cpp index 2544ee2..ab095a9 100644 --- a/Samples/Color_Samples/Color_Sample_App.cpp +++ b/Samples/Color_Samples/Color_Sample_App.cpp @@ -783,7 +783,7 @@ ctl_result_t GetPixTxCapability(ctl_display_output_handle_t hDisplayOutput, ctl_ LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig for query type capability"); // Number of blocks - printf("GetPixTxCapsArgs.NumBlocks = %d\n", pPixTxCaps->NumBlocks); + APP_LOG_INFO("GetPixTxCapsArgs.NumBlocks = %d", pPixTxCaps->NumBlocks); if (NULL == pPixTxCaps->pBlockConfigs) { @@ -795,26 +795,26 @@ ctl_result_t GetPixTxCapability(ctl_display_output_handle_t hDisplayOutput, ctl_ ctl_pixtx_1dlut_config_t *pOneDLutConfig = &pPixTxCaps->pBlockConfigs[i].Config.OneDLutConfig; // Block specific information - printf("pPixTxCaps->pBlockConfigs[%d].BlockId = %d\n", i, pPixTxCaps->pBlockConfigs[i].BlockId); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].BlockId = %d", i, pPixTxCaps->pBlockConfigs[i].BlockId); if (CTL_PIXTX_BLOCK_TYPE_1D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) { - printf("Block type is CTL_PIXTX_BLOCK_TYPE_1D_LUT\n"); - printf("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.NumChannels = %d\n", i, pOneDLutConfig->NumChannels); - printf("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.NumSamplesPerChannel = %d\n", i, pOneDLutConfig->NumSamplesPerChannel); - printf("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.SamplingType = %d\n", i, pOneDLutConfig->SamplingType); + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_1D_LUT"); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.NumChannels = %d", i, pOneDLutConfig->NumChannels); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.NumSamplesPerChannel = %d", i, pOneDLutConfig->NumSamplesPerChannel); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.SamplingType = %d", i, pOneDLutConfig->SamplingType); } else if (CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX == pPixTxCaps->pBlockConfigs[i].BlockType) { - printf("Block type is CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX\n"); + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX"); } else if (CTL_PIXTX_BLOCK_TYPE_3D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) { - printf("Block type is CTL_PIXTX_BLOCK_TYPE_3D_LUT\n"); - printf("pPixTxCaps->pBlockConfigs[%d].Config.ThreeDLutConfig.NumSamplesPerChannel = %d\n", i, pPixTxCaps->pBlockConfigs[i].Config.ThreeDLutConfig.NumSamplesPerChannel); + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_3D_LUT"); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.ThreeDLutConfig.NumSamplesPerChannel = %d", i, pPixTxCaps->pBlockConfigs[i].Config.ThreeDLutConfig.NumSamplesPerChannel); } else if (CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS == pPixTxCaps->pBlockConfigs[i].BlockType) { - printf("Block type is CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS\n"); + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS"); } } @@ -867,7 +867,7 @@ ctl_result_t ApplyLinearCSC(ctl_display_output_handle_t hDisplayOutput, ctl_pixt if (DGLUTIndex < 0 || CscIndex < 0 || GLUTIndex < 0) { - printf("Invalid Index for DGLUT/CSC/GLUT\n"); + APP_LOG_ERROR("Invalid Index for DGLUT/CSC/GLUT"); return CTL_RESULT_ERROR_INVALID_ARGUMENT; } @@ -1052,7 +1052,7 @@ ctl_result_t RotateAndScalePanelColorSpaceToContentColorSpace(ctl_display_output if (DGLUTIndex < 0 || CscIndex < 0 || GLUTIndex < 0) { - printf("Invalid Index for DGLUT/CSC/GLUT\n"); + APP_LOG_ERROR("Invalid Index for DGLUT/CSC/GLUT"); return CTL_RESULT_ERROR_INVALID_ARGUMENT; } @@ -1247,16 +1247,16 @@ ctl_result_t GetDeGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx Result = ctlPixelTransformationGetConfig(hDisplayOutput, &GetPixTxCurrentArgs); LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig"); - printf("DEGamma values : LutConfig.Config.OneDLutConfig.pSampleValues\n"); + APP_LOG_INFO("DEGamma values : LutConfig.Config.OneDLutConfig.pSampleValues"); uint32_t LutDataSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; - printf("LutDataSize = %d\n ", LutDataSize); + APP_LOG_INFO("LutDataSize = %d ", LutDataSize); - printf("DeGamma values : LutConfig.Config.OneDLutConfig.pSampleValues\n"); + APP_LOG_INFO("DeGamma values : LutConfig.Config.OneDLutConfig.pSampleValues"); for (uint32_t i = 0; i < LutDataSize; i++) { - printf("[%d] = %f\n", i, LutConfig.Config.OneDLutConfig.pSampleValues[i]); + APP_LOG_INFO("[%d] = %f", i, LutConfig.Config.OneDLutConfig.pSampleValues[i]); } Exit: @@ -1287,6 +1287,7 @@ ctl_result_t SetGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_p SetPixTxArgs.pBlockConfigs = &LutConfig; // for 1DLUT block double *pRedLut, *pGreenLut, *pBlueLut; + double LutMultiplier; // Create a valid 1D LUT. const uint32_t LutSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; @@ -1298,10 +1299,30 @@ ctl_result_t SetGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_p pGreenLut = pRedLut + LutConfig.Config.OneDLutConfig.NumSamplesPerChannel; pBlueLut = pGreenLut + LutConfig.Config.OneDLutConfig.NumSamplesPerChannel; - for (uint32_t i = 0; i < (LutSize / LutConfig.Config.OneDLutConfig.NumChannels); i++) + // Applying a LUT which reduces the Red channel values by 30%.in linear format + // Based on the Pixel Encoding type , encode the multiplier 0.7 with the same function + // For example if Encoding is ST2084 then OETF2084(0.7) -> 0.962416136 + // if Encoding is SRGB then sRGB(0.7) -> 0.854305832 + + if (CTL_PIXTX_GAMMA_ENCODING_TYPE_ST2084 == pPixTxCaps->OutputPixelFormat.EncodingType) { - double Input = (double)i / (double)(LutSize / LutConfig.Config.OneDLutConfig.NumChannels - 1); - pRedLut[i] = pGreenLut[i] = pBlueLut[i] = GetSRGBEncodingValue(Input); + LutMultiplier = 0.962416136; + } + else if (CTL_PIXTX_GAMMA_ENCODING_TYPE_SRGB == pPixTxCaps->OutputPixelFormat.EncodingType) + { + LutMultiplier = 0.854305832; + } + else + { + LutMultiplier = 1.0; + } + + // When calling Set for just OneDLUT the LUT is expected to be a Relative Correction LUT + for (uint32_t i = 0; i < LutConfig.Config.OneDLutConfig.NumSamplesPerChannel; i++) + { + double Input = (double)i / (double)(LutConfig.Config.OneDLutConfig.NumSamplesPerChannel - 1); + pRedLut[i] = pGreenLut[i] = pBlueLut[i] = Input; + pRedLut[i] *= LutMultiplier; } Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); @@ -1338,13 +1359,13 @@ ctl_result_t GetGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_p LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig"); uint32_t LutDataSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; - printf("LutDataSize = %d\n ", LutDataSize); + APP_LOG_INFO("LutDataSize = %d ", LutDataSize); - printf("Gamma values : LutConfig.Config.OneDLutConfig.pSampleValues\n"); + APP_LOG_INFO("Gamma values : LutConfig.Config.OneDLutConfig.pSampleValues"); for (uint32_t i = 0; i < LutDataSize; i++) { - printf("[%d] = %f\n", i, LutConfig.Config.OneDLutConfig.pSampleValues[i]); + APP_LOG_INFO("[%d] = %f", i, LutConfig.Config.OneDLutConfig.pSampleValues[i]); } Exit: @@ -1582,7 +1603,7 @@ void GetSetDeGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_ge if (DGLUTIndex < 0) { - printf("Invalid DGLut Index\n"); + APP_LOG_ERROR("Invalid DGLut Index"); goto Exit; } @@ -1590,7 +1611,7 @@ void GetSetDeGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_ge Result = SetDeGammaLut(hDisplayOutput, pPixTxCaps, DGLUTIndex); if (CTL_RESULT_SUCCESS != Result) { - printf("SetDeGammaLut call failed\n"); + APP_LOG_ERROR("SetDeGammaLut call failed"); STORE_AND_RESET_ERROR(Result); } else @@ -1599,7 +1620,7 @@ void GetSetDeGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_ge Result = GetDeGammaLut(hDisplayOutput, pPixTxCaps, DGLUTIndex); if (CTL_RESULT_SUCCESS != Result) { - printf("GetDeGamma call failed\n"); + APP_LOG_ERROR("GetDeGamma call failed"); LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "GetDeGammaLut"); } } @@ -1635,7 +1656,7 @@ void GetSetGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_ if (OneDLUTIndex < 0) { - printf("Invalid OneDLut Index\n"); + APP_LOG_ERROR("Invalid OneDLut Index"); goto Exit; } @@ -1644,7 +1665,7 @@ void GetSetGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_ if (CTL_RESULT_SUCCESS != Result) { - printf("SetGammaLut call failed\n"); + APP_LOG_ERROR("SetGammaLut call failed"); STORE_AND_RESET_ERROR(Result); } else @@ -1682,7 +1703,7 @@ void GetSet3DLUT(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_ if (ThreeDLutBlockIndex < 0) { - printf("Invalid ThreeDLut Index\n"); + APP_LOG_ERROR("Invalid ThreeDLut Index"); goto Exit; } @@ -1690,7 +1711,7 @@ void GetSet3DLUT(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_ if (CTL_RESULT_SUCCESS != Result) { - printf("Set3DLut call failed\n"); + APP_LOG_ERROR("Set3DLut call failed"); STORE_AND_RESET_ERROR(Result); } else @@ -1729,7 +1750,7 @@ ctl_result_t TestBrightnessContrastGamma(ctl_display_output_handle_t hDisplayOut if (DesktopGammaBlockIndex < 0) { - printf("ctlPixelTransformationGetConfig did not report 1DLUT capability\n"); + APP_LOG_ERROR("ctlPixelTransformationGetConfig did not report 1DLUT capability"); STORE_AND_RESET_ERROR(Result); } else @@ -1785,7 +1806,7 @@ ctl_result_t TestPartialSaturation(ctl_display_output_handle_t hDisplayOutput, c if (PartialSatBlockIndex < 0) { - printf("ctlPixelTransformationGetConfig did not report 3DLUT capability for partial saturation\n"); + APP_LOG_ERROR("ctlPixelTransformationGetConfig did not report 3DLUT capability for partial saturation"); STORE_AND_RESET_ERROR(Result); } @@ -1833,10 +1854,10 @@ ctl_result_t TestPixTxGetSetConfig(ctl_display_output_handle_t hDisplayOutput) } // Logical Pipeline details in current mode - printf("Logical Pipeline Input Color Model : %d , Color Space %d, Encoding Type: %d \n", PixTxCaps.InputPixelFormat.ColorModel, PixTxCaps.InputPixelFormat.ColorSpace, - PixTxCaps.InputPixelFormat.EncodingType); - printf("Logical Pipeline Output Color Model : %d , Color Space %d, Encoding Type: %d , BPC: %d \n", PixTxCaps.InputPixelFormat.ColorModel, PixTxCaps.InputPixelFormat.ColorSpace, - PixTxCaps.InputPixelFormat.EncodingType, PixTxCaps.OutputPixelFormat.BitsPerColor); + APP_LOG_INFO("Logical Pipeline Input Color Model : %d , Color Space %d, Encoding Type: %d ", PixTxCaps.InputPixelFormat.ColorModel, PixTxCaps.InputPixelFormat.ColorSpace, + PixTxCaps.InputPixelFormat.EncodingType); + APP_LOG_INFO("Logical Pipeline Output Color Model : %d , Color Space %d, Encoding Type: %d , BPC: %d ", PixTxCaps.InputPixelFormat.ColorModel, PixTxCaps.InputPixelFormat.ColorSpace, + PixTxCaps.InputPixelFormat.EncodingType, PixTxCaps.OutputPixelFormat.BitsPerColor); const uint8_t NumBlocksToQuery = PixTxCaps.NumBlocks; // Query about the blocks in the pipeline @@ -1877,7 +1898,7 @@ ctl_result_t TestPixTxGetSetConfig(ctl_display_output_handle_t hDisplayOutput) if (CscBlockIndex < 0) { - printf("ctlPixelTransformationGetConfig did not report CSC capability\n"); + APP_LOG_ERROR("ctlPixelTransformationGetConfig did not report CSC capability"); STORE_AND_RESET_ERROR(Result); } else @@ -1930,18 +1951,19 @@ ctl_result_t TestLaceGetSetConfigForFixedAgressiveness(ctl_display_output_handle ctl_lace_config_t NewLaceConfigSettings = { 0 }; ctl_power_optimization_caps_t PowerCaps = { 0 }; - PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); - Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerCaps); + PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; + Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerCaps); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationCaps (LACE)"); if (CTL_POWER_OPTIMIZATION_FLAG_LACE != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_LACE)) { - printf("LACE is not supported\n"); + APP_LOG_WARN("LACE is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } - NewLaceConfigSettings.Version = 0; + NewLaceConfigSettings.Version = 1; NewLaceConfigSettings.Size = sizeof(ctl_lace_config_t); NewLaceConfigSettings.Enabled = TRUE; NewLaceConfigSettings.OpTypeSet = CTL_SET_OPERATION_CUSTOM; @@ -1953,7 +1975,7 @@ ctl_result_t TestLaceGetSetConfigForFixedAgressiveness(ctl_display_output_handle // Get Lace Config Call for current flag AppliedLaceConfigSettings = { 0 }; - AppliedLaceConfigSettings.Version = 0; + AppliedLaceConfigSettings.Version = 1; AppliedLaceConfigSettings.Size = sizeof(ctl_lace_config_t); AppliedLaceConfigSettings.OpTypeGet = CTL_GET_OPERATION_FLAG_CURRENT; @@ -1976,18 +1998,19 @@ ctl_result_t TestLaceGetSetConfigForALS(ctl_display_output_handle_t hDisplayOutp ctl_lace_config_t AppliedLaceConfigSettings = { 0 }; ctl_lace_config_t NewLaceConfigSettings = { 0 }; ctl_power_optimization_caps_t PowerCaps = { 0 }; - AppliedLaceConfigSettings.Version = 0; + AppliedLaceConfigSettings.Version = 1; AppliedLaceConfigSettings.Size = sizeof(ctl_lace_config_t); AppliedLaceConfigSettings.OpTypeGet = CTL_GET_OPERATION_FLAG_CAPABILITY; uint32_t MaxNumEntries = 0; - PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); - Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerCaps); + PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; + Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerCaps); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationCaps (LACE)"); if (CTL_POWER_OPTIMIZATION_FLAG_LACE != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_LACE)) { - printf("LACE is not supported\n"); + APP_LOG_WARN("LACE is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } @@ -1998,7 +2021,7 @@ ctl_result_t TestLaceGetSetConfigForALS(ctl_display_output_handle_t hDisplayOutp MaxNumEntries = AppliedLaceConfigSettings.LaceConfig.AggrLevelMap.MaxNumEntries; - NewLaceConfigSettings.Version = 0; + NewLaceConfigSettings.Version = 1; NewLaceConfigSettings.Size = sizeof(ctl_lace_config_t); NewLaceConfigSettings.Enabled = TRUE; NewLaceConfigSettings.OpTypeSet = CTL_SET_OPERATION_CUSTOM; @@ -2020,7 +2043,7 @@ ctl_result_t TestLaceGetSetConfigForALS(ctl_display_output_handle_t hDisplayOutp // Get Lace Config Call for current flag AppliedLaceConfigSettings = { 0 }; - AppliedLaceConfigSettings.Version = 0; + AppliedLaceConfigSettings.Version = 1; AppliedLaceConfigSettings.Size = sizeof(ctl_lace_config_t); AppliedLaceConfigSettings.OpTypeGet = CTL_GET_OPERATION_FLAG_CURRENT; AppliedLaceConfigSettings.LaceConfig.AggrLevelMap.NumEntries = MaxNumEntries; @@ -2037,6 +2060,52 @@ ctl_result_t TestLaceGetSetConfigForALS(ctl_display_output_handle_t hDisplayOutp return Result; } +/*************************************************************** + * @brief + * Sample Test To Override Color Model And Color Depth + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToOverrideColorModelAndColorDepth(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_get_set_wire_format_config_t CurrentWireFormatSetting = { 0 }; + ctl_get_set_wire_format_config_t NewWireFormatSetting = { 0 }; + + // GET call + CurrentWireFormatSetting.Size = sizeof(ctl_get_set_wire_format_config_t); + CurrentWireFormatSetting.Operation = CTL_WIRE_FORMAT_OPERATION_TYPE_GET; + Result = ctlGetSetWireFormat(hDisplayOutput, &CurrentWireFormatSetting); + LOG_AND_EXIT_ON_ERROR(Result, "GET Call using ctlGetSetWireFormat"); + + APP_LOG_INFO("Current ColorModel %d", CurrentWireFormatSetting.WireFormat.ColorModel); + APP_LOG_INFO("Current ColorDepth %d", CurrentWireFormatSetting.WireFormat.ColorDepth); + + for (uint32_t Index = 0; Index < CTL_MAX_WIREFORMAT_COLOR_MODELS_SUPPORTED; Index++) + { + APP_LOG_INFO("Supported ColorModel %d", CurrentWireFormatSetting.SupportedWireFormat[Index].ColorModel); + APP_LOG_INFO("Supported ColorDepth %d", CurrentWireFormatSetting.SupportedWireFormat[Index].ColorDepth); + } + + // SET call + NewWireFormatSetting.Size = sizeof(ctl_get_set_wire_format_config_t); + NewWireFormatSetting.Operation = CTL_WIRE_FORMAT_OPERATION_TYPE_SET; + NewWireFormatSetting.WireFormat.ColorModel = CTL_WIRE_FORMAT_COLOR_MODEL_RGB; + NewWireFormatSetting.WireFormat.ColorDepth = CTL_OUTPUT_BPC_FLAG_8BPC; + + Result = ctlGetSetWireFormat(hDisplayOutput, &NewWireFormatSetting); + LOG_AND_EXIT_ON_ERROR(Result, "SET Call using ctlGetSetWireFormat"); + + // Restore to default + NewWireFormatSetting.Size = sizeof(ctl_get_set_wire_format_config_t); + NewWireFormatSetting.Operation = CTL_WIRE_FORMAT_OPERATION_TYPE_RESTORE_DEFAULT; + Result = ctlGetSetWireFormat(hDisplayOutput, &NewWireFormatSetting); + LOG_AND_EXIT_ON_ERROR(Result, "RESTORE DEFAULT Call using ctlGetSetWireFormat"); + +Exit: + return Result; +} + /*************************************************************** * @brief TestColorForEnumDisplayHandles * Only for demonstration purpose, API is called for each of the display output handle in below snippet. @@ -2061,7 +2130,7 @@ ctl_result_t TestColorForEnumDisplayHandles(ctl_display_output_handle_t *hDispla if (FALSE == IsDisplayActive || FALSE == IsDisplayAttached) { - printf("Display %d is not attached/Active, skipping the call for this display\n", DisplayIndex); + APP_LOG_WARN("Display %d is not attached/Active, skipping the call for this display", DisplayIndex); continue; } @@ -2073,6 +2142,9 @@ ctl_result_t TestColorForEnumDisplayHandles(ctl_display_output_handle_t *hDispla Result = TestLaceGetSetConfigForALS(hDisplayOutput[DisplayIndex]); STORE_AND_RESET_ERROR(Result); + + Result = TestToOverrideColorModelAndColorDepth(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); } Exit: @@ -2101,13 +2173,13 @@ ctl_result_t TestDisplays(uint32_t AdapterCount, ctl_device_adapter_handle_t *hD if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); continue; } @@ -2123,7 +2195,7 @@ ctl_result_t TestDisplays(uint32_t AdapterCount, ctl_device_adapter_handle_t *hD if (CTL_RESULT_SUCCESS != Result) { - printf("TestColorForEnumDisplayHandles returned failure code: 0x%X\n", Result); + APP_LOG_WARN("TestColorForEnumDisplayHandles returned failure code: 0x%X", Result); } CTL_FREE_MEM(hDisplayOutput); @@ -2158,19 +2230,40 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = TestDisplays(AdapterCount, hDevices); LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "TestDisplays"); @@ -2179,6 +2272,6 @@ int main() ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/CombinedDisplay/CMakeLists.txt b/Samples/CombinedDisplay/CMakeLists.txt index 0619f00..d07c21c 100644 --- a/Samples/CombinedDisplay/CMakeLists.txt +++ b/Samples/CombinedDisplay/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME CombinedDisplay) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(CombinedDisplay VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/CombinedDisplay_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/CombinedDisplay/CombinedDisplay_Sample_App.cpp b/Samples/CombinedDisplay/CombinedDisplay_Sample_App.cpp index 370679a..5b5ae61 100644 --- a/Samples/CombinedDisplay/CombinedDisplay_Sample_App.cpp +++ b/Samples/CombinedDisplay/CombinedDisplay_Sample_App.cpp @@ -56,14 +56,14 @@ enum ChildInfoIndex ***************************************************************/ void PrintUsage(char *pArgv[]) { - printf("Combined Display Sample Test Application.\n"); - printf("\nUsage: %s [Combined Display Port] \n", pArgv[0]); - printf("\nCombined Display Port - 0 | 1\n"); - printf("\tCombined Display port number you want to disable or query. Default is 0.\n"); - printf("Config File - sample config file\n"); - printf("\tEnable.cfg - Enabling 1x2 mode of Combined Display with 1080p displays\n"); - printf("\tDisable.cfg - Disabling Combined Display\n"); - printf("\tQuery.cfg - Querying current Combined Display topology\n"); + APP_LOG_INFO("Combined Display Sample Test Application."); + APP_LOG_INFO("Usage: %s [Combined Display Port] ", pArgv[0]); + APP_LOG_INFO("Combined Display Port - 0 | 1"); + APP_LOG_INFO("Combined Display port number you want to disable or query. Default is 0."); + APP_LOG_INFO("Config File - sample config file"); + APP_LOG_INFO("Enable.cfg - Enabling 1x2 mode of Combined Display with 1080p displays"); + APP_LOG_INFO("Disable.cfg - Disabling Combined Display"); + APP_LOG_INFO("Query.cfg - Querying current Combined Display topology"); } /*************************************************************** @@ -82,7 +82,7 @@ ctl_result_t ParseArguments(const char *pCDArgFile, ctl_combined_display_args_t if (false == ConfigFile.is_open()) { - printf("Cannot open a config file.\n"); + APP_LOG_ERROR("Cannot open a config file."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -107,7 +107,7 @@ ctl_result_t ParseArguments(const char *pCDArgFile, ctl_combined_display_args_t } // Print lines - printf("%s = %s\n", Name.c_str(), Value.c_str()); + APP_LOG_INFO("%s = %s", Name.c_str(), Value.c_str()); // Fill out combined display config arguments pCombinedDisplayArgs->Size = sizeof(ctl_combined_display_args_t); @@ -163,7 +163,7 @@ ctl_result_t ParseChildInfoArguments(const char *pCDArgFile, ctl_combined_displa if (false == ConfigFile.is_open()) { - printf("Cannot open a config file.\n"); + APP_LOG_ERROR("Cannot open a config file."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -296,7 +296,7 @@ ctl_result_t ParseDisplayOrderArguments(uint8_t NumOutputs, const char *pCDArgFi if (false == ConfigFile.is_open()) { - printf("Cannot open a config file.\n"); + APP_LOG_ERROR("Cannot open a config file."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -338,7 +338,7 @@ ctl_result_t ParseDisplayOrderArguments(uint8_t NumOutputs, const char *pCDArgFi break; } } - Order = Value; + Order = move(Value); SelectedDisplays[Index] = stoi(Order); break; } @@ -362,23 +362,23 @@ void PrintCombinedConfig(const ctl_combined_display_args_t CombinedDisplayArgs) ctl_rect_t FbSrc, FbPos; ctl_child_display_target_mode_t TargetMode; - printf("========= Combined Display Configuration =========\n"); - printf("Number of Display Outputs: %u\n", CombinedDisplayArgs.NumOutputs); - printf("Combined Display Width: %u\n", CombinedDisplayArgs.CombinedDesktopWidth); - printf("Combined Display Height: %u\n", CombinedDisplayArgs.CombinedDesktopHeight); + PRINT_LOGS("========= Combined Display Configuration ========="); + APP_LOG_INFO("Number of Display Outputs: %u", CombinedDisplayArgs.NumOutputs); + APP_LOG_INFO("Combined Display Width: %u", CombinedDisplayArgs.CombinedDesktopWidth); + APP_LOG_INFO("Combined Display Height: %u", CombinedDisplayArgs.CombinedDesktopHeight); for (uint8_t i = 0; i < CombinedDisplayArgs.NumOutputs; i++) { FbSrc = CombinedDisplayArgs.pChildInfo[i].FbSrc; FbPos = CombinedDisplayArgs.pChildInfo[i].FbPos; TargetMode = CombinedDisplayArgs.pChildInfo[i].TargetMode; - printf("Display[%u]: ", i); - printf("{%u,%u,%u,%u},", FbSrc.Left, FbSrc.Top, FbSrc.Right, FbSrc.Bottom); - printf("{%u,%u,%u,%u},", FbPos.Left, FbPos.Top, FbPos.Right, FbPos.Bottom); - printf("%u,", CombinedDisplayArgs.pChildInfo[i].DisplayOrientation); - printf("{%u,%u,%.1f}\n", TargetMode.Width, TargetMode.Height, TargetMode.RefreshRate); + APP_LOG_INFO("Display[%u]: ", i); + APP_LOG_INFO("{%u,%u,%u,%u},", FbSrc.Left, FbSrc.Top, FbSrc.Right, FbSrc.Bottom); + APP_LOG_INFO("{%u,%u,%u,%u},", FbPos.Left, FbPos.Top, FbPos.Right, FbPos.Bottom); + APP_LOG_INFO("%u,", CombinedDisplayArgs.pChildInfo[i].DisplayOrientation); + APP_LOG_INFO("{%u,%u,%.1f}", TargetMode.Width, TargetMode.Height, TargetMode.RefreshRate); } - printf("==========================================================\n"); + PRINT_LOGS("=========================================================="); } /*************************************************************** @@ -491,7 +491,7 @@ ctl_result_t TestCombinedDisplay(uint32_t AdapterCount, ctl_device_adapter_handl } else if (DisplayCount <= 0) { - printf("Invalid Display Count. Skipping display enumeration for adapter: %d\n", Index); + APP_LOG_WARN("Invalid Display Count. Skipping display enumeration for adapter: %d", Index); CTL_FREE_MEM(pSelectedDisplays); continue; } @@ -519,7 +519,7 @@ ctl_result_t TestCombinedDisplay(uint32_t AdapterCount, ctl_device_adapter_handl if (NULL == pHDisplayOutput[i]) { - printf("pHDisplayOutput[%d] is NULL.\n", i); + APP_LOG_ERROR("pHDisplayOutput[%d] is NULL.", i); Result = CTL_RESULT_ERROR_INVALID_NULL_HANDLE; EXIT_ON_ERROR(Result); } @@ -539,8 +539,9 @@ ctl_result_t TestCombinedDisplay(uint32_t AdapterCount, ctl_device_adapter_handl pHCombinedDisplayOutputs[CombinedDisplayCount++] = pHDisplayOutput[i]; } - uint32_t CombinedAllowedEncoderTypes = CTL_ENCODER_CONFIG_FLAG_TYPEC_CAPABLE | CTL_ENCODER_CONFIG_FLAG_TBT_CAPABLE | CTL_ENCODER_CONFIG_FLAG_DITHERING_SUPPORTED; - bool IsCombinedAvailable = false; + uint32_t CombinedAllowedEncoderTypes = + CTL_ENCODER_CONFIG_FLAG_TYPEC_CAPABLE | CTL_ENCODER_CONFIG_FLAG_TBT_CAPABLE | CTL_ENCODER_CONFIG_FLAG_DITHERING_SUPPORTED | CTL_ENCODER_CONFIG_FLAG_INTERNAL_DISPLAY; + bool IsCombinedAvailable = false; IsCombinedAvailable = (0 == stDisplayEncoderProperties.EncoderConfigFlags) || (stDisplayEncoderProperties.EncoderConfigFlags & CombinedAllowedEncoderTypes); IsDisplayActive = stDisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ACTIVE; @@ -558,7 +559,7 @@ ctl_result_t TestCombinedDisplay(uint32_t AdapterCount, ctl_device_adapter_handl { if (CombinedDisplayArgs.NumOutputs > NumActiveOutputs) { - printf("The input NumOutputs of %u is greater than the system's NumActiveOutputs of %u.\n", CombinedDisplayArgs.NumOutputs, NumActiveOutputs); + APP_LOG_ERROR("The input NumOutputs of %u is greater than the system's NumActiveOutputs of %u.", CombinedDisplayArgs.NumOutputs, NumActiveOutputs); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -568,7 +569,7 @@ ctl_result_t TestCombinedDisplay(uint32_t AdapterCount, ctl_device_adapter_handl { if ((CTL_DISPLAY_ORIENTATION_0 != CombinedDisplayArgs.pChildInfo[i].DisplayOrientation) && (CTL_DISPLAY_ORIENTATION_180 != CombinedDisplayArgs.pChildInfo[i].DisplayOrientation)) { - printf("Only 0/180 degree rotation is supported.\n"); + APP_LOG_ERROR("Only 0/180 degree rotation is supported."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -583,7 +584,7 @@ ctl_result_t TestCombinedDisplay(uint32_t AdapterCount, ctl_device_adapter_handl Result = ctlGetSetCombinedDisplay(hDevices[Index], &CombinedDisplayArgs); if (CTL_RESULT_SUCCESS == Result && CombinedDisplayArgs.IsSupported == false) { - printf("The following Combined Display configuration is not supported\n"); + APP_LOG_WARN("The following Combined Display configuration is not supported"); PrintCombinedConfig(CombinedDisplayArgs); } } @@ -680,28 +681,64 @@ int main(int argc, char *pArgv[]) CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } - Result = TestCombinedDisplay(AdapterCount, hDevices, pCDArgFile, CombinedPort); - LOG_AND_EXIT_ON_ERROR(Result, "TestCombinedDisplay"); + try + { + Result = TestCombinedDisplay(AdapterCount, hDevices, pCDArgFile, CombinedPort); + LOG_AND_EXIT_ON_ERROR(Result, "TestCombinedDisplay"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } + catch (const std::ios_base::failure &e) + { + APP_LOG_ERROR("%s ", e.what()); + } + catch (const std::bad_cast &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Exit: ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overall test result is 0x%X", GResult); return GResult; } \ No newline at end of file diff --git a/Samples/CombinedDisplay/Disable.cfg b/Samples/CombinedDisplay/Disable.cfg new file mode 100644 index 0000000..93d359b --- /dev/null +++ b/Samples/CombinedDisplay/Disable.cfg @@ -0,0 +1,17 @@ +## syntax - OpType and NumOutputs must be placed at first. Configuration item label is case sensitive. + +OpType = 3 # Operation type: 1 -- Is_Supported_Config, 2 -- Enable, 3 -- Disable, 4 -- Query_Config +NumOutputs = 4 # Number of (display) outputs: has to be 2 or greater, maximum is 4. +DisplayOrder = 0,1,2,3 # which displays are involved: 0 indicates the first, 1 indicates the 2nd, and so on. order matters, "1 0" means display 1 will be viewed as first elected and display 0 is will be viewed as 2nd selected. +CombinedDesktopWidth = 3840 # combined display width +CombinedDesktopHeight = 2160 # combined display height + +# ChildInfo = Display Number,{FbSrc},{FbPos},Orientation,{Target Mode} where +# FbSrc = {left,top,right,bottom} +# FbPos = {left,top,right,bottom} +# Display Orientation = 0 (0 rotation), 2 (180 rotation) +# Target Mode = {width, height, refresh} : If 0, this means using native target mode instead of custom mode +ChildInfo = 0,{0,0,1920,1080},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 1,{1920,0,3840,1080},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 2,{0,1080,1920,2160},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 3,{1920,1080,3840,2160},{0,0,1920,1080}, 0, {0,0,0} \ No newline at end of file diff --git a/Samples/CombinedDisplay/Enable.cfg b/Samples/CombinedDisplay/Enable.cfg new file mode 100644 index 0000000..fbf1b88 --- /dev/null +++ b/Samples/CombinedDisplay/Enable.cfg @@ -0,0 +1,17 @@ +## syntax - OpType and NumOutputs must be placed at first. Configuration item label is case sensitive. + +OpType = 2 # Operation type: 1 -- Is_Supported_Config, 2 -- Enable, 3 -- Disable, 4 -- Query_Config +NumOutputs = 2 # Number of (display) outputs: has to be 2 or greater, maximum is 4. +DisplayOrder = 0,1,2,3 # which displays are involved: 0 indicates the first, 1 indicates the 2nd, and so on. order matters, "1 0" means display 1 will be viewed as first elected and display 0 is will be viewed as 2nd selected. +CombinedDesktopWidth = 3840 # combined display width +CombinedDesktopHeight = 1080 # combined display height + +# ChildInfo = Display Number,{FbSrc},{FbPos},Orientation,{Target Mode} where +# FbSrc = {left,top,right,bottom} +# FbPos = {left,top,right,bottom} +# Display Orientation = 0 (0 rotation), 2 (180 rotation) +# Target Mode = {width, height, refresh} : If 0, this means using native target mode instead of custom mode +ChildInfo = 0,{0,0,1920,1080},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 1,{1920,0,3840,1080},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 2,{0,1080,1920,2160},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 3,{1920,1080,3840,2160},{0,0,1920,1080}, 0, {0,0,0} \ No newline at end of file diff --git a/Samples/CombinedDisplay/Query.cfg b/Samples/CombinedDisplay/Query.cfg new file mode 100644 index 0000000..d3633c4 --- /dev/null +++ b/Samples/CombinedDisplay/Query.cfg @@ -0,0 +1,17 @@ +## syntax - OpType and NumOutputs must be placed at first. Configuration item label is case sensitive. + +OpType = 4 # Operation type: 1 -- Is_Supported_Config, 2 -- Enable, 3 -- Disable, 4 -- Query_Config +NumOutputs = 4 # Number of (display) outputs: has to be 2 or greater, maximum is 4. +DisplayOrder = 0,1,2,3 # which displays are involved: 0 indicates the first, 1 indicates the 2nd, and so on. order matters, "1 0" means display 1 will be viewed as first elected and display 0 is will be viewed as 2nd selected. +CombinedDesktopWidth = 3840 # combined display width +CombinedDesktopHeight = 2160 # combined display height + +# ChildInfo = Display Number,{FbSrc},{FbPos},Orientation,{Target Mode} where +# FbSrc = {left,top,right,bottom} +# FbPos = {left,top,right,bottom} +# Display Orientation = 0 (0 rotation), 2 (180 rotation) +# Target Mode = {width, height, refresh} : If 0, this means using native target mode instead of custom mode +ChildInfo = 0,{0,0,1920,1080},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 1,{1920,0,3840,1080},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 2,{0,1080,1920,2160},{0,0,1920,1080}, 0, {0,0,0} +ChildInfo = 3,{1920,1080,3840,2160},{0,0,1920,1080}, 0, {0,0,0} \ No newline at end of file diff --git a/Samples/Custom_Mode_Samples/CMakeLists.txt b/Samples/Custom_Mode_Samples/CMakeLists.txt index 7b6731d..af0e346 100644 --- a/Samples/Custom_Mode_Samples/CMakeLists.txt +++ b/Samples/Custom_Mode_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Custom_Mode_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Custom_Mode_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/CustomMode_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Custom_Mode_Samples/CustomMode_Sample_App.cpp b/Samples/Custom_Mode_Samples/CustomMode_Sample_App.cpp index 80d5ccd..187f79c 100644 --- a/Samples/Custom_Mode_Samples/CustomMode_Sample_App.cpp +++ b/Samples/Custom_Mode_Samples/CustomMode_Sample_App.cpp @@ -66,12 +66,12 @@ ctl_result_t GetCustomModes(ctl_display_output_handle_t hDisplayOutput) if (0 == NumOfCustomModes) { - printf("\n No Custom modes added.\n"); + APP_LOG_WARN("No Custom modes added."); goto Exit; } else { - printf("\n Number of custom modes:%d", NumOfCustomModes); + APP_LOG_INFO("Number of custom modes:%d", NumOfCustomModes); } pCustomModeSourceSize = NumOfCustomModes * sizeof(ctl_custom_src_mode_t); @@ -80,7 +80,7 @@ ctl_result_t GetCustomModes(ctl_display_output_handle_t hDisplayOutput) EXIT_ON_MEM_ALLOC_FAILURE(pCustomSourceModes, "pCustomSourceModes"); - memset(pCustomSourceModes, 0, sizeof(pCustomSourceModes)); + memset(pCustomSourceModes, 0, pCustomModeSourceSize); GetCustomModes.NumOfModes = NumOfCustomModes; GetCustomModes.CustomModeOpType = CTL_CUSTOM_MODE_OPERATION_TYPES_GET_CUSTOM_SOURCE_MODES; @@ -94,15 +94,13 @@ ctl_result_t GetCustomModes(ctl_display_output_handle_t hDisplayOutput) pCustomSourceModesList = pCustomSourceModes; - printf("\n No.\tSourceX\tSourceY\n"); + APP_LOG_INFO("No.\tSourceX\tSourceY"); for (uint8_t i = 0; i < NumOfCustomModes; i++) { - printf(" %d\t%d\t%d\n", i, pCustomSourceModesList->SourceX, pCustomSourceModesList->SourceY); + APP_LOG_INFO(" %d\t%d\t%d", i, pCustomSourceModesList->SourceX, pCustomSourceModesList->SourceY); pCustomSourceModesList++; } - printf("\n"); - Exit: CTL_FREE_MEM(pCustomSourceModes); return Result; @@ -124,7 +122,7 @@ ctl_result_t AddCustomModes(ctl_display_output_handle_t hDisplayOutput, uint32_t EXIT_ON_MEM_ALLOC_FAILURE(pCustomSourceMode, "pCustomSourceMode"); - memset(pCustomSourceMode, 0, sizeof(pCustomSourceMode)); + memset(pCustomSourceMode, 0, sizeof(ctl_custom_src_mode_t)); AddCustomMode.NumOfModes = 1; AddCustomMode.CustomModeOpType = CTL_CUSTOM_MODE_OPERATION_TYPES_ADD_CUSTOM_SOURCE_MODE; @@ -135,7 +133,7 @@ ctl_result_t AddCustomModes(ctl_display_output_handle_t hDisplayOutput, uint32_t pCustomSourceMode->SourceX = SourceX; pCustomSourceMode->SourceY = SourceY; - printf("\nAdding Custom mode X:%d Y:%d\n", SourceX, SourceY); + APP_LOG_INFO("Adding Custom mode X:%d Y:%d", SourceX, SourceY); // Add Custom mode. Result = ctlGetSetCustomMode(hDisplayOutput, &AddCustomMode); @@ -172,7 +170,7 @@ ctl_result_t RemoveCustomModes(ctl_display_output_handle_t hDisplayOutput) EXIT_ON_MEM_ALLOC_FAILURE(pCustomSourceModes, "pCustomSourceModes"); - memset(pCustomSourceModes, 0, sizeof(pCustomSourceModes)); + memset(pCustomSourceModes, 0, pCustomModeSourceSize); RemoveCustomModes.NumOfModes = NumOfModesToRemove; RemoveCustomModes.CustomModeOpType = CTL_CUSTOM_MODE_OPERATION_TYPES_REMOVE_CUSTOM_SOURCE_MODES; @@ -187,7 +185,7 @@ ctl_result_t RemoveCustomModes(ctl_display_output_handle_t hDisplayOutput) pCustomSourceModesList->SourceX = Modes[i].X; pCustomSourceModesList->SourceY = Modes[i].Y; pCustomSourceModesList++; - printf("Removing Custom mode X:%d Y:%d\n", Modes[i].X, Modes[i].Y); + APP_LOG_INFO("Removing Custom mode X:%d Y:%d", Modes[i].X, Modes[i].Y); } // Add Custom mode. @@ -225,12 +223,12 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput if (FALSE == IsDisplayAttached) { - printf("Display %d is not attached, skipping the call for this display\n", DisplayIndex); + APP_LOG_WARN("Display %d is not attached, skipping the call for this display", DisplayIndex); continue; } else { - printf("Attached Display Count: %d\n", DisplayIndex); + APP_LOG_INFO("Attached Display Count: %d", DisplayIndex); } // At a time only one custom mode add operation is supported @@ -287,13 +285,13 @@ ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); continue; } @@ -305,7 +303,7 @@ ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -315,7 +313,7 @@ ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateDisplayHandles returned failure code: 0x%X\n", Result); + APP_LOG_WARN("EnumerateDisplayHandles returned failure code: 0x%X", Result); } CTL_FREE_MEM(hDisplayOutput); @@ -351,25 +349,46 @@ int main() CtlInitArgs.Version = 0; ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = EnumerateTargetDisplays(hDisplayOutput, AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateTargetDisplays returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -378,6 +397,6 @@ int main() ctlClose(hAPIHandle); CTL_FREE_MEM(hDisplayOutput); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/DisplayGenlock/CMakeLists.txt b/Samples/DisplayGenlock/CMakeLists.txt index 656670f..545b930 100644 --- a/Samples/DisplayGenlock/CMakeLists.txt +++ b/Samples/DisplayGenlock/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME DisplayGenlock) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(DisplayGenlock VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/DisplayGenlock_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/DisplayGenlock/DisplayGenlock_Sample_App.cpp b/Samples/DisplayGenlock/DisplayGenlock_Sample_App.cpp index 52cfe6a..56f602d 100644 --- a/Samples/DisplayGenlock/DisplayGenlock_Sample_App.cpp +++ b/Samples/DisplayGenlock/DisplayGenlock_Sample_App.cpp @@ -23,6 +23,7 @@ #include #include #include +#include using namespace std; #define CTL_APIEXPORT // caller of control API DLL shall define this before including igcl_api.h @@ -30,12 +31,14 @@ using namespace std; #include "igcl_api.h" #include "GenericIGCLApp.h" +#define NUMBER_OF_PRIMARY_ADAPTERS 1 + typedef struct _genlock_sample_args { bool IsGenlockPrimary; ctl_genlock_operation_t Operation; ctl_display_output_types_t PortType; - uint32_t NumberOfPrimaryAdapters; + uint32_t PrimaryBusId; } genlock_sample_args; static bool IsGetVBlankTs = false; @@ -50,25 +53,25 @@ ctl_result_t GResult = CTL_RESULT_SUCCESS; ***************************************************************/ void PrintTopology(ctl_genlock_args_t *pGenlockArgs, uint32_t AdapterCount) { - printf("========= Genlock Topology =========\n"); + PRINT_LOGS("========= Genlock Topology ========="); for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) { - printf("Adapter %u:\n", AdapterIndex); - printf("\tIsGenlockEnabled : %s\n", pGenlockArgs[AdapterIndex].IsGenlockEnabled ? "true" : "false"); - printf("\tIsGenlockPossible : %s\n", pGenlockArgs[AdapterIndex].IsGenlockPossible ? "true" : "false"); + APP_LOG_INFO("Adapter %u:", AdapterIndex); + APP_LOG_INFO("\tIsGenlockEnabled : %s", pGenlockArgs[AdapterIndex].IsGenlockEnabled ? "true" : "false"); + APP_LOG_INFO("\tIsGenlockPossible : %s", pGenlockArgs[AdapterIndex].IsGenlockPossible ? "true" : "false"); if (true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) { - printf("\tIsPrimaryGenlockSystem : %s\n", pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem ? "true" : "false"); - printf("\tNumber of Genlock displays : %d\n", pGenlockArgs[AdapterIndex].GenlockTopology.NumGenlockDisplays); + APP_LOG_INFO("\tIsPrimaryGenlockSystem : %s", pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem ? "true" : "false"); + APP_LOG_INFO("\tNumber of Genlock displays : %d", pGenlockArgs[AdapterIndex].GenlockTopology.NumGenlockDisplays); for (int8_t DisplayIndex = 0; DisplayIndex < pGenlockArgs[AdapterIndex].GenlockTopology.NumGenlockDisplays; DisplayIndex++) { - printf("\tDisplay %u:\n", DisplayIndex); - printf("\t\tDisplay output handle : %p\n", pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo[DisplayIndex].hDisplayOutput); - printf("\t\tPrimary pipe : %s\n", pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo[DisplayIndex].IsPrimary ? "true" : "false"); + APP_LOG_INFO("\tDisplay %u:", DisplayIndex); + APP_LOG_INFO("\t\tDisplay output handle : %p", pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo[DisplayIndex].hDisplayOutput); + APP_LOG_INFO("\t\tPrimary pipe : %s", pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo[DisplayIndex].IsPrimary ? "true" : "false"); } } } - printf("====================================\n"); + PRINT_LOGS("===================================="); } /*************************************************************** @@ -79,24 +82,24 @@ void PrintTopology(ctl_genlock_args_t *pGenlockArgs, uint32_t AdapterCount) ***************************************************************/ void PrintUsage(char *pArgv[]) { - printf("Genlock Sample Test Application.\n"); - printf("\nUsage: %s [Operation] <-g Genlock_Mode> <-d Display_Type> <-n Number_Of_Primary_Adapters>\n", pArgv[0]); - printf("Operation\n"); - printf("\t-timing : Get target mode timing details supported by each display\n"); - printf("\t-validate : Validate Genlock configuration\n"); - printf("\t-enable : Enable Genlock\n"); - printf("\t-topology : Get current Genlock topology\n"); - printf("\t-disable : Disable Genlock\n"); - printf("\t-vblankts : Get VBlank Timestamp\n"); - printf("\t-help : Display usage\n"); - printf("-g [Genlock mode]\n"); - printf("\tprimary : primary system providing ref clock and ref sync (default)\n"); - printf("\tsecondary : secondary system referring ref clock and ref sync from primary\n"); - printf("-d [Display type]\n"); - printf("\tdp : Display Port (default)\n"); - printf("\thdmi : HDMI\n"); - printf("-n [Number of Primary Adapters]\n"); - printf("\tSpecify how many adapters you want to enable as a primary (default : 1)\n"); + APP_LOG_INFO("Genlock Sample Test Application."); + APP_LOG_INFO("Usage: %s [Operation] <-g Genlock_Mode> <-d Display_Type> <-n Number_Of_Primary_Adapters>", pArgv[0]); + APP_LOG_INFO("Operation"); + APP_LOG_INFO("\t-timing : Get target mode timing details supported by each display"); + APP_LOG_INFO("\t-validate : Validate Genlock configuration"); + APP_LOG_INFO("\t-enable : Enable Genlock"); + APP_LOG_INFO("\t-topology : Get current Genlock topology"); + APP_LOG_INFO("\t-disable : Disable Genlock"); + APP_LOG_INFO("\t-vblankts : Get VBlank Timestamp"); + APP_LOG_INFO("\t-help : Display usage"); + APP_LOG_INFO("-g [Genlock mode]"); + APP_LOG_INFO("\tprimary : primary system providing ref clock and ref sync (default)"); + APP_LOG_INFO("\tsecondary : secondary system referring ref clock and ref sync from primary"); + APP_LOG_INFO("-d [Display type]"); + APP_LOG_INFO("\tdp : Display Port (default)"); + APP_LOG_INFO("\thdmi : HDMI"); + APP_LOG_INFO("-p [PCIe BUS ID of Primary Adapter]"); + APP_LOG_INFO("\tDesignate PCIe BUS ID of adapter you want to set as a primary (default : 0)"); } /*************************************************************** @@ -139,9 +142,9 @@ ctl_result_t GetCmdlineArgs(int Argc, char *pArgv[], genlock_sample_args *pGenlo string OptionArg; // initialize Genlock Sample Args - pGenlockSampleArgs->PortType = CTL_DISPLAY_OUTPUT_TYPES_DISPLAYPORT; - pGenlockSampleArgs->NumberOfPrimaryAdapters = 1; - pGenlockSampleArgs->IsGenlockPrimary = true; + pGenlockSampleArgs->PortType = CTL_DISPLAY_OUTPUT_TYPES_DISPLAYPORT; + pGenlockSampleArgs->IsGenlockPrimary = true; + pGenlockSampleArgs->PrimaryBusId = 0; if (CTL_RESULT_SUCCESS == FindOptionArg(Argc, pArgv, "-timing", OptionArg)) { @@ -182,7 +185,7 @@ ctl_result_t GetCmdlineArgs(int Argc, char *pArgv[], genlock_sample_args *pGenlo pGenlockSampleArgs->IsGenlockPrimary = false; } } - printf("[in] Genlock Mode: %s\n", pGenlockSampleArgs->IsGenlockPrimary == true ? "primary" : "secondary"); + APP_LOG_INFO("[in] Genlock Mode: %s", pGenlockSampleArgs->IsGenlockPrimary == true ? "primary" : "secondary"); // Display Type option if (CTL_RESULT_SUCCESS == FindOptionArg(Argc, pArgv, "-d", OptionArg)) { @@ -191,9 +194,9 @@ ctl_result_t GetCmdlineArgs(int Argc, char *pArgv[], genlock_sample_args *pGenlo pGenlockSampleArgs->PortType = CTL_DISPLAY_OUTPUT_TYPES_HDMI; } } - printf("[in] Display Type: %s\n", pGenlockSampleArgs->PortType == CTL_DISPLAY_OUTPUT_TYPES_HDMI ? "hdmi" : "dp"); - // Number of Primary Adapters option - if (CTL_RESULT_SUCCESS == FindOptionArg(Argc, pArgv, "-n", OptionArg)) + APP_LOG_INFO("[in] Display Type: %s", pGenlockSampleArgs->PortType == CTL_DISPLAY_OUTPUT_TYPES_HDMI ? "hdmi" : "dp"); + // Primary BUS ID option + if (CTL_RESULT_SUCCESS == FindOptionArg(Argc, pArgv, "-p", OptionArg)) { if (("" != OptionArg)) { @@ -201,20 +204,116 @@ ctl_result_t GetCmdlineArgs(int Argc, char *pArgv[], genlock_sample_args *pGenlo { if (!isdigit(OptionArg[Index])) { - printf("Invalid Number of primary adapters.\n"); + APP_LOG_ERROR("Invalid PCIe BUS ID."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } } - pGenlockSampleArgs->NumberOfPrimaryAdapters = stoul(OptionArg, 0, 16); + pGenlockSampleArgs->PrimaryBusId = stoul(OptionArg, 0, 10); } } - printf("[in] Number of primary adapters: %u\n", pGenlockSampleArgs->NumberOfPrimaryAdapters); + APP_LOG_INFO("[in] BUS ID of primary adapter: %u", pGenlockSampleArgs->PrimaryBusId); Exit: return Result; } +/*************************************************************** + * @brief GetVblankTimestamp + * get vblank time stamp + * @param hDevices, AdapterCount + * @return ctl_result_t + ***************************************************************/ +ctl_result_t GetVblankTimestamp(ctl_device_adapter_handle_t *hDevices, uint32_t AdapterCount) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_device_adapter_handle_t hFailureDeviceAdapter = NULL; + ctl_display_output_handle_t *hDisplayOutput = NULL; + ctl_display_output_handle_t *hActiveDisplayOutputs = NULL; + uint32_t DisplayCount = 0; + uint8_t ActiveDisplayCount = 0; + uint8_t MaxNumDisplayOutputs = 0; + bool IsDisplayActive = false; + bool IsDisplayAttached = false; + ctl_vblank_ts_args_t VblankTsArgs; + + for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + { + ActiveDisplayCount = 0; + + // Enumerate all the possible target displays for the adapters + // First step is to get the count + DisplayCount = 0; + + Result = ctlEnumerateDisplayOutputs(hDevices[AdapterIndex], &DisplayCount, NULL); + + if (CTL_RESULT_SUCCESS != Result) + { + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + } + else if (DisplayCount <= 0) + { + APP_LOG_WARN("Invalid Display Count. Skipping display enumeration for adapter: %d", AdapterIndex); + continue; + } + + hDisplayOutput = (ctl_display_output_handle_t *)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevices[AdapterIndex], &DisplayCount, hDisplayOutput); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + APP_LOG_INFO("Adapter %u:", AdapterIndex); + for (uint8_t DisplayIndex = 0; DisplayIndex < DisplayCount; DisplayIndex++) + { + ctl_display_properties_t stDisplayProperties = {}; + stDisplayProperties.Size = sizeof(ctl_display_properties_t); + + if (NULL == hDisplayOutput[DisplayIndex]) + { + APP_LOG_ERROR("\thDisplayOutput[%d] is NULL.", DisplayIndex); + Result = CTL_RESULT_ERROR_INVALID_NULL_HANDLE; + EXIT_ON_ERROR(Result); + } + + Result = ctlGetDisplayProperties(hDisplayOutput[DisplayIndex], &stDisplayProperties); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetDisplayProperties"); + + ctl_adapter_display_encoder_properties_t stDisplayEncoderProperties = {}; + stDisplayEncoderProperties.Size = sizeof(ctl_adapter_display_encoder_properties_t); + + Result = ctlGetAdaperDisplayEncoderProperties(hDisplayOutput[DisplayIndex], &stDisplayEncoderProperties); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetAdaperDisplayEncoderProperties"); + + IsDisplayActive = stDisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ACTIVE; + IsDisplayAttached = stDisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ATTACHED; + + memset(&VblankTsArgs, 0, sizeof(ctl_vblank_ts_args_t)); + + // Filter active display outputs + if (IsDisplayActive && IsDisplayAttached) + { + // get genlock status (vblank time stamp) + Result = ctlGetVblankTimestamp(hDisplayOutput[DisplayIndex], &VblankTsArgs); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetVblankTimestamp"); + } + + for (uint8_t i = 0; i < VblankTsArgs.NumOfTargets; i++) + { + APP_LOG_INFO("\tTarget ID: %d Child[%d] vblank timestamp: %I64d", stDisplayProperties.Os_display_encoder_handle.WindowsDisplayEncoderID, i, VblankTsArgs.VblankTS[i]); + } + } + + // Free dynamically allocated memories + CTL_FREE_MEM(hDisplayOutput); + } + +Exit: + CTL_FREE_MEM(hDisplayOutput); + + return Result; +} + /*************************************************************** * @brief FindBestCommonTiming * Find best common target mode timing and fill it to CommonTargetMode @@ -386,10 +485,10 @@ ctl_result_t TestGenlockValidate(ctl_device_adapter_handle_t *hDevices, ctl_genl Result = ctlGetSetDisplayGenlock(hDevices, pGenlockArgs, AdapterCount, &hFailureDeviceAdapter); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplayGenlock"); - printf("========= Genlock Validate =========\n"); + PRINT_LOGS("========= Genlock Validate ========="); for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) { - printf("Adapter[%u]: IsGenlockPossible : %s\n", AdapterIndex, pGenlockArgs[AdapterIndex].IsGenlockPossible ? "true" : "false"); + APP_LOG_INFO("Adapter[%u]: IsGenlockPossible : %s", AdapterIndex, pGenlockArgs[AdapterIndex].IsGenlockPossible ? "true" : "false"); } Exit: @@ -527,7 +626,7 @@ ctl_result_t InitGenlockArgs(ctl_device_adapter_handle_t *hDevices, uint32_t Ada } else if (DisplayCount <= 0) { - printf("Invalid display count for adapter: %d\n", AdapterIndex); + APP_LOG_ERROR("Invalid display count for adapter: %d", AdapterIndex); LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); } @@ -548,7 +647,7 @@ ctl_result_t InitGenlockArgs(ctl_device_adapter_handle_t *hDevices, uint32_t Ada if (NULL == hDisplayOutput[DisplayIndex]) { - printf("hDisplayOutput[%d] is NULL.\n", DisplayIndex); + APP_LOG_ERROR("hDisplayOutput[%d] is NULL.", DisplayIndex); Result = CTL_RESULT_ERROR_INVALID_NULL_HANDLE; EXIT_ON_ERROR(Result); } @@ -574,7 +673,7 @@ ctl_result_t InitGenlockArgs(ctl_device_adapter_handle_t *hDevices, uint32_t Ada if ((CTL_GENLOCK_OPERATION_GET_TOPOLOGY != GenlockSampleArgs.Operation) && (0 == ActiveDisplayCount)) { - printf("Adatper[%d] does not have any active displays for the selected display type. ActiveDisplayCount is %d.\n", AdapterIndex, ActiveDisplayCount); + APP_LOG_ERROR("Adatper[%d] does not have any active displays for the selected display type. ActiveDisplayCount is %d.", AdapterIndex, ActiveDisplayCount); Result = CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED; EXIT_ON_ERROR(Result); } @@ -591,11 +690,13 @@ ctl_result_t InitGenlockArgs(ctl_device_adapter_handle_t *hDevices, uint32_t Ada pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem = GenlockSampleArgs.IsGenlockPrimary; // Allocate dynamic memories + CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo); pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo = (ctl_genlock_display_info_t *)malloc(sizeof(ctl_genlock_display_info_t) * pGenlockArgs[AdapterIndex].GenlockTopology.NumGenlockDisplays); EXIT_ON_MEM_ALLOC_FAILURE(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo, "pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo"); memset(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo, 0, sizeof(ctl_genlock_display_info_t) * pGenlockArgs[AdapterIndex].GenlockTopology.NumGenlockDisplays); + CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList); pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList = (ctl_genlock_target_mode_list_t *)malloc(sizeof(ctl_genlock_target_mode_list_t) * pGenlockArgs[AdapterIndex].GenlockTopology.NumGenlockDisplays); EXIT_ON_MEM_ALLOC_FAILURE(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList, "pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList"); @@ -621,97 +722,194 @@ ctl_result_t InitGenlockArgs(ctl_device_adapter_handle_t *hDevices, uint32_t Ada } /*************************************************************** - * @brief GetVblankTimestamp - * get vblank time stamp - * @param hDevices, AdapterCount + * @brief GenlockEnable + * Enable Display Genlock + * @param hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs * @return ctl_result_t ***************************************************************/ -ctl_result_t GetVblankTimestamp(ctl_device_adapter_handle_t *hDevices, uint32_t AdapterCount) +ctl_result_t GenlockEnable(ctl_device_adapter_handle_t *hDevices, uint32_t AdapterCount, genlock_sample_args GenlockSampleArgs, ctl_genlock_args_t *pGenlockArgs) { - ctl_result_t Result = CTL_RESULT_SUCCESS; - ctl_device_adapter_handle_t hFailureDeviceAdapter = NULL; - ctl_display_output_handle_t *hDisplayOutput = NULL; - ctl_display_output_handle_t *hActiveDisplayOutputs = NULL; - uint32_t DisplayCount = 0; - uint8_t ActiveDisplayCount = 0; - uint8_t MaxNumDisplayOutputs = 0; - bool IsDisplayActive = false; - bool IsDisplayAttached = false; - ctl_vblank_ts_args_t VblankTsArgs; + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_device_adapter_handle_t PrimaryAdapter = NULL; + ctl_device_adapter_handle_t *hSecondaryAdapters = NULL; + uint8_t PrimaryAdapterCount = 0; + uint8_t SecondaryAdapterCount = 0; + uint8_t SecondaryAdapterIndex = 0; - for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + // The primary adapter must be enabled before enabling other secondary adapters + // Number of primary adapters should be one. Other adapters are configured as a secondary + if (true == GenlockSampleArgs.IsGenlockPrimary) { - ActiveDisplayCount = 0; + PrimaryAdapterCount = NUMBER_OF_PRIMARY_ADAPTERS; + SecondaryAdapterCount = AdapterCount - PrimaryAdapterCount; + hSecondaryAdapters = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * SecondaryAdapterCount); + for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + { + LUID deviceID; + ctl_device_adapter_properties_t stdeviceAdapterProperties = { 0 }; - // Enumerate all the possible target displays for the adapters - // First step is to get the count - DisplayCount = 0; + stdeviceAdapterProperties.Size = sizeof(ctl_device_adapter_properties_t); + stdeviceAdapterProperties.pDeviceID = &deviceID; + stdeviceAdapterProperties.device_id_size = sizeof(LUID); + stdeviceAdapterProperties.Version = 2; - Result = ctlEnumerateDisplayOutputs(hDevices[AdapterIndex], &DisplayCount, NULL); + // Fetch device adapter properties into stdeviceAdapterProperties + Result = ctlGetDeviceProperties(hDevices[AdapterIndex], &stdeviceAdapterProperties); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetDeviceProperties"); - if (CTL_RESULT_SUCCESS != Result) - { - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); - } - else if (DisplayCount <= 0) - { - printf("Invalid Display Count. Skipping display enumeration for adapter: %d\n", AdapterIndex); - continue; + if (((GenlockSampleArgs.PrimaryBusId != 0) && (stdeviceAdapterProperties.adapter_bdf.bus == GenlockSampleArgs.PrimaryBusId)) || + ((GenlockSampleArgs.PrimaryBusId == 0) && (AdapterIndex == 0))) + { + PrimaryAdapter = hDevices[AdapterIndex]; + } + else + { + hSecondaryAdapters[SecondaryAdapterIndex] = hDevices[AdapterIndex]; + SecondaryAdapterIndex++; + } } - hDisplayOutput = (ctl_display_output_handle_t *)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); - EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + // Enabling a primary adapter + Result = InitGenlockArgs(&PrimaryAdapter, PrimaryAdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs for a primary adapter"); - Result = ctlEnumerateDisplayOutputs(hDevices[AdapterIndex], &DisplayCount, hDisplayOutput); - LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + Result = TestGenlockEnable(&PrimaryAdapter, pGenlockArgs, PrimaryAdapterCount); + LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockEnable - Primary"); - printf("Adapter %u:\n", AdapterIndex); - for (uint8_t DisplayIndex = 0; DisplayIndex < DisplayCount; DisplayIndex++) + // Enabling secondary adapters + if (SecondaryAdapterCount > 0) { - ctl_display_properties_t stDisplayProperties = {}; - stDisplayProperties.Size = sizeof(ctl_display_properties_t); + GenlockSampleArgs.IsGenlockPrimary = false; + Result = InitGenlockArgs(hSecondaryAdapters, SecondaryAdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs for secondary adapters"); - if (NULL == hDisplayOutput[DisplayIndex]) - { - printf("\thDisplayOutput[%d] is NULL.\n", DisplayIndex); - Result = CTL_RESULT_ERROR_INVALID_NULL_HANDLE; - EXIT_ON_ERROR(Result); - } + Result = TestGenlockEnable(hSecondaryAdapters, pGenlockArgs, SecondaryAdapterCount); + LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockEnable - Secondary"); + } + } + else + { + // Configuring all adapters as a secondary + Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); + Result = TestGenlockEnable(hDevices, pGenlockArgs, AdapterCount); + LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockEnable - Secondary Adapters"); + } - Result = ctlGetDisplayProperties(hDisplayOutput[DisplayIndex], &stDisplayProperties); - LOG_AND_EXIT_ON_ERROR(Result, "ctlGetDisplayProperties"); +Exit: + CTL_FREE_MEM(hSecondaryAdapters); - ctl_adapter_display_encoder_properties_t stDisplayEncoderProperties = {}; - stDisplayEncoderProperties.Size = sizeof(ctl_adapter_display_encoder_properties_t); + return Result; +} - Result = ctlGetAdaperDisplayEncoderProperties(hDisplayOutput[DisplayIndex], &stDisplayEncoderProperties); - LOG_AND_EXIT_ON_ERROR(Result, "ctlGetAdaperDisplayEncoderProperties"); +/*************************************************************** + * @brief GenlockDisable + * Disable Display Genlock + * @param hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs + * @return ctl_result_t + ***************************************************************/ +ctl_result_t GenlockDisable(ctl_device_adapter_handle_t *hDevices, uint32_t AdapterCount, genlock_sample_args GenlockSampleArgs, ctl_genlock_args_t *pGenlockArgs) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_device_adapter_handle_t *hPrimaryAdapters = NULL; + ctl_device_adapter_handle_t *hSecondaryAdapters = NULL; + uint8_t GenlockedAdapterCount = 0; + uint8_t PrimaryAdapterCount = 0; + uint8_t SecondaryAdapterCount = 0; - IsDisplayActive = stDisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ACTIVE; - IsDisplayAttached = stDisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ATTACHED; + // The primary adapter must be disabled last after secondary adapters are disabled + if (true == GenlockSampleArgs.IsGenlockPrimary) + { + // Secondary adapters should be disabled firstly + // Get topology to check which adapter is a primary + GenlockSampleArgs.Operation = CTL_GENLOCK_OPERATION_GET_TOPOLOGY; + Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); + Result = TestGenlockGetTopology(hDevices, pGenlockArgs, AdapterCount); + LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockGetTopology"); + + // Count primary and secondary adapters + GenlockedAdapterCount = 0; + PrimaryAdapterCount = 0; + SecondaryAdapterCount = 0; + for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + { + if (true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) + { + GenlockedAdapterCount++; + if (false == pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem) + { + SecondaryAdapterCount++; + } + } + } - memset(&VblankTsArgs, 0, sizeof(ctl_vblank_ts_args_t)); + if (0 == GenlockedAdapterCount) + { + APP_LOG_ERROR("There is no Genlocked adapter."); + Result = CTL_RESULT_ERROR_NOT_INITIALIZED; + EXIT_ON_ERROR(Result); + } - // Filter active display outputs - if (IsDisplayActive && IsDisplayAttached) + PrimaryAdapterCount = GenlockedAdapterCount - SecondaryAdapterCount; + if (0 != PrimaryAdapterCount) + { + hPrimaryAdapters = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * PrimaryAdapterCount); + EXIT_ON_MEM_ALLOC_FAILURE(hPrimaryAdapters, "hPrimaryAdapters"); + } + if (0 != SecondaryAdapterCount) + { + hSecondaryAdapters = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * SecondaryAdapterCount); + EXIT_ON_MEM_ALLOC_FAILURE(hSecondaryAdapters, "hSecondaryAdapters"); + } + + PrimaryAdapterCount = 0; + SecondaryAdapterCount = 0; + for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + { + if ((true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) && (true == pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem) && (NULL != hPrimaryAdapters)) { - // get genlock status (vblank time stamp) - Result = ctlGetVblankTimestamp(hDisplayOutput[DisplayIndex], &VblankTsArgs); - LOG_AND_EXIT_ON_ERROR(Result, "ctlGetVblankTimestamp"); + hPrimaryAdapters[PrimaryAdapterCount++] = hDevices[AdapterIndex]; } - - for (uint8_t i = 0; i < VblankTsArgs.NumOfTargets; i++) + else if ((true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) && (false == pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem) && (NULL != hSecondaryAdapters)) { - printf("\tTarget ID: %d Child[%d] vblank timestamp: %I64d\n", stDisplayProperties.Os_display_encoder_handle.WindowsDisplayEncoderID, i, VblankTsArgs.VblankTS[i]); + hSecondaryAdapters[SecondaryAdapterCount++] = hDevices[AdapterIndex]; } } - // Free dynamically allocated memories - CTL_FREE_MEM(hDisplayOutput); + GenlockSampleArgs.Operation = CTL_GENLOCK_OPERATION_DISABLE; + // Disable secondary adapters + GenlockSampleArgs.IsGenlockPrimary = false; + if (0 < SecondaryAdapterCount) + { + Result = InitGenlockArgs(hSecondaryAdapters, SecondaryAdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); + Result = TestGenlockDisable(hSecondaryAdapters, pGenlockArgs, SecondaryAdapterCount); + LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockDisable"); + } + CTL_FREE_MEM(hSecondaryAdapters); + + // Disable primary adapter + GenlockSampleArgs.IsGenlockPrimary = true; + if (0 < PrimaryAdapterCount) + { + Result = InitGenlockArgs(hPrimaryAdapters, PrimaryAdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); + Result = TestGenlockDisable(hPrimaryAdapters, pGenlockArgs, PrimaryAdapterCount); + } + + CTL_FREE_MEM(hPrimaryAdapters); + } + else + { + Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); + LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); + Result = TestGenlockDisable(hDevices, pGenlockArgs, AdapterCount); } Exit: - CTL_FREE_MEM(hDisplayOutput); + CTL_FREE_MEM(hPrimaryAdapters); + CTL_FREE_MEM(hSecondaryAdapters); return Result; } @@ -724,13 +922,8 @@ ctl_result_t GetVblankTimestamp(ctl_device_adapter_handle_t *hDevices, uint32_t ***************************************************************/ ctl_result_t TestDisplayGenlock(ctl_device_adapter_handle_t *hDevices, uint32_t AdapterCount, genlock_sample_args GenlockSampleArgs) { - ctl_result_t Result = CTL_RESULT_SUCCESS; - ctl_genlock_args_t *pGenlockArgs = NULL; - ctl_device_adapter_handle_t *hPrimaryAdapters = NULL; - ctl_device_adapter_handle_t *hSecondaryAdapters = NULL; - uint8_t GenlockedAdapterCount = 0; - uint8_t PrimaryAdapterCount = 0; - uint8_t SecondaryAdapterCount = 0; + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_genlock_args_t *pGenlockArgs = NULL; pGenlockArgs = (ctl_genlock_args_t *)malloc(sizeof(ctl_genlock_args_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(pGenlockArgs, "pGenlockArgs"); @@ -748,131 +941,10 @@ ctl_result_t TestDisplayGenlock(ctl_device_adapter_handle_t *hDevices, uint32_t Result = TestGenlockValidate(hDevices, pGenlockArgs, AdapterCount); break; case CTL_GENLOCK_OPERATION_ENABLE: - // The primary adapter must be enabled first before other secondary adapters are enabled - if (true == GenlockSampleArgs.IsGenlockPrimary) - { - // Number of primary adapters cannot be zero or bigger than plugged-in adapters count - if ((0 == GenlockSampleArgs.NumberOfPrimaryAdapters) || (AdapterCount < GenlockSampleArgs.NumberOfPrimaryAdapters)) - { - printf("Number of primary adapters cannot be zero or bigger than plugged-in adapters count.\n"); - Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; - CTL_FREE_MEM(pGenlockArgs); - return Result; - } - // Enable primary target on the primary adapter#0 - Result = InitGenlockArgs(hDevices, GenlockSampleArgs.NumberOfPrimaryAdapters, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - - Result = TestGenlockEnable(hDevices, pGenlockArgs, GenlockSampleArgs.NumberOfPrimaryAdapters); - LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockEnable - Primary"); - - SecondaryAdapterCount = AdapterCount - GenlockSampleArgs.NumberOfPrimaryAdapters; - if (SecondaryAdapterCount > 0) - { - // Other adapters are secondary systems for Genlock - GenlockSampleArgs.IsGenlockPrimary = false; - Result = InitGenlockArgs(&hDevices[GenlockSampleArgs.NumberOfPrimaryAdapters], SecondaryAdapterCount, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - Result = TestGenlockEnable(&hDevices[GenlockSampleArgs.NumberOfPrimaryAdapters], pGenlockArgs, SecondaryAdapterCount); - LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockEnable - Secondary"); - } - } - else - { - Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - Result = TestGenlockEnable(hDevices, pGenlockArgs, AdapterCount); - LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockEnable - Primary"); - } + Result = GenlockEnable(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); break; case CTL_GENLOCK_OPERATION_DISABLE: - // The primary adapter must be disabled last after secondary adapters are disabled - if (true == GenlockSampleArgs.IsGenlockPrimary) - { - // Secondary adapters should be disabled first - // Get topology to check which adapter is a primary - GenlockSampleArgs.Operation = CTL_GENLOCK_OPERATION_GET_TOPOLOGY; - Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - Result = TestGenlockGetTopology(hDevices, pGenlockArgs, AdapterCount); - LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockGetTopology"); - - // Count primary and secondary adapters - GenlockedAdapterCount = 0; - PrimaryAdapterCount = 0; - SecondaryAdapterCount = 0; - for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) - { - if (true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) - { - GenlockedAdapterCount++; - if (false == pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem) - { - SecondaryAdapterCount++; - } - } - } - - if (0 == GenlockedAdapterCount) - { - printf("There is no Genlocked adapter.\n"); - Result = CTL_RESULT_ERROR_NOT_INITIALIZED; - EXIT_ON_ERROR(Result); - } - - PrimaryAdapterCount = GenlockedAdapterCount - SecondaryAdapterCount; - if (0 != PrimaryAdapterCount) - { - hPrimaryAdapters = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * PrimaryAdapterCount); - EXIT_ON_MEM_ALLOC_FAILURE(hPrimaryAdapters, "hPrimaryAdapters"); - } - if (0 != SecondaryAdapterCount) - { - hSecondaryAdapters = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * SecondaryAdapterCount); - EXIT_ON_MEM_ALLOC_FAILURE(hSecondaryAdapters, "hSecondaryAdapters"); - } - - PrimaryAdapterCount = 0; - SecondaryAdapterCount = 0; - for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) - { - if ((true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) && (true == pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem) && (NULL != hPrimaryAdapters)) - { - hPrimaryAdapters[PrimaryAdapterCount++] = hDevices[AdapterIndex]; - } - else if ((true == pGenlockArgs[AdapterIndex].IsGenlockEnabled) && (false == pGenlockArgs[AdapterIndex].GenlockTopology.IsPrimaryGenlockSystem) && (NULL != hSecondaryAdapters)) - { - hSecondaryAdapters[SecondaryAdapterCount++] = hDevices[AdapterIndex]; - } - } - - GenlockSampleArgs.Operation = CTL_GENLOCK_OPERATION_DISABLE; - // Disable secondary adapters - GenlockSampleArgs.IsGenlockPrimary = false; - if (0 < SecondaryAdapterCount) - { - Result = InitGenlockArgs(hSecondaryAdapters, SecondaryAdapterCount, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - Result = TestGenlockDisable(hSecondaryAdapters, pGenlockArgs, SecondaryAdapterCount); - LOG_AND_EXIT_ON_ERROR(Result, "TestGenlockDisable"); - } - CTL_FREE_MEM(hSecondaryAdapters); - - // Disable primary adapter - GenlockSampleArgs.IsGenlockPrimary = true; - if (0 < PrimaryAdapterCount) - { - Result = InitGenlockArgs(hPrimaryAdapters, PrimaryAdapterCount, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - Result = TestGenlockDisable(hPrimaryAdapters, pGenlockArgs, PrimaryAdapterCount); - } - } - else - { - Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); - LOG_AND_EXIT_ON_ERROR(Result, "InitGenlockArgs"); - Result = TestGenlockDisable(hDevices, pGenlockArgs, AdapterCount); - } + Result = GenlockDisable(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); break; case CTL_GENLOCK_OPERATION_GET_TOPOLOGY: Result = InitGenlockArgs(hDevices, AdapterCount, GenlockSampleArgs, pGenlockArgs); @@ -899,8 +971,12 @@ ctl_result_t TestDisplayGenlock(ctl_device_adapter_handle_t *hDevices, uint32_t CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList[ModeListIndex].pTargetModes); } } - CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo); - CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList); + + for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + { + CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockDisplayInfo); + CTL_FREE_MEM(pGenlockArgs[AdapterIndex].GenlockTopology.pGenlockModeList); + } } } @@ -934,19 +1010,40 @@ int main(int Argc, char *pArgv[]) CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } if (true == IsGetVBlankTs) { @@ -963,6 +1060,6 @@ int main(int Argc, char *pArgv[]) ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/DisplaySettings/CMakeLists.txt b/Samples/DisplaySettings/CMakeLists.txt new file mode 100644 index 0000000..d1900f1 --- /dev/null +++ b/Samples/DisplaySettings/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) +set(TARGET_NAME DisplaySettings) +get_filename_component(ROOT_DIR ../../ ABSOLUTE) +project(DisplaySettings VERSION 1.0) +add_executable(${TARGET_NAME} + ${CMAKE_CURRENT_SOURCE_DIR}/DisplaySettings_Sample_App.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp +) + +if(MSVC) + set_target_properties(${TARGET_NAME} + PROPERTIES + VS_DEBUGGER_COMMAND_ARGUMENTS "" + VS_DEBUGGER_WORKING_DIRECTORY "$(OutDir)" + ) + + ADD_DEFINITIONS(-DUNICODE) + ADD_DEFINITIONS(-D_UNICODE) +endif() + +include_directories(${ROOT_DIR}/include) +include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/DisplaySettings/DisplaySettings_Sample_App.cpp b/Samples/DisplaySettings/DisplaySettings_Sample_App.cpp new file mode 100644 index 0000000..f2f10c3 --- /dev/null +++ b/Samples/DisplaySettings/DisplaySettings_Sample_App.cpp @@ -0,0 +1,706 @@ +//=========================================================================== +// Copyright (C) 2022 Intel Corporation +// +// +// +// SPDX-License-Identifier: MIT +//-------------------------------------------------------------------------- + +/** + * + * @file DisplaySettings_Sample_App.cpp + * @brief : This file contains the 'main' function and the DisplaySettings Sample APP. Program execution begins and ends there. + * + */ + +#define _CRTDBG_MAP_ALLOC +#include +#include +#include +#include +#include +#include + +#define CTL_APIEXPORT // caller of control API DLL shall define this before + // including igcl_api.h +#include "igcl_api.h" +#include "GenericIGCLApp.h" + +#define API_VERSION 0; + +ctl_result_t GResult = CTL_RESULT_SUCCESS; + +/*************************************************************** + * @brief + * Sample test for Get/Set Quantization Range + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToGetSetQuantizationRange(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Quantization Range GET CALL)"); + + IsControllable = (CTL_DISPLAY_SETTING_FLAG_QUANTIZATION_RANGE & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_QUANTIZATION_RANGE & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set Quantization Range is not supported"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + APP_LOG_INFO(" Current Applied Quantization Range is %d ", AppliedDisplaySettings.QuantizationRange); + + // SET CALL + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_QUANTIZATION_RANGE; + NewDisplaySettings.QuantizationRange = CTL_DISPLAY_SETTING_QUANTIZATION_RANGE_FULL_RANGE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Quantization Range SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Quantization Range GET CALL)"); + APP_LOG_INFO(" Current Quantization Range is %d ", AppliedDisplaySettings.QuantizationRange); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Sample test for Get/Set PictureAspectRatio + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToGetSetPictureAspectRatio(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Picture Aspect Ratio GET CALL)"); + + IsControllable = (CTL_DISPLAY_SETTING_FLAG_PICTURE_AR & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_PICTURE_AR & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set PictureAspectRatio is not supported"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + APP_LOG_INFO(" Supported Picture Aspect Ratio is %d ", AppliedDisplaySettings.SupportedPictureAR); + APP_LOG_INFO(" Current Applied Picture Aspect Ratio is %d ", AppliedDisplaySettings.PictureAR); + + // CALL TO SET 16_9 + if (CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_AR_16_9 & AppliedDisplaySettings.SupportedPictureAR) + { + + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_PICTURE_AR; + NewDisplaySettings.PictureAR = CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_AR_16_9; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Picture Aspect Ratio SET CALL)"); + } + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Picture Aspect Ratio GET CALL)"); + APP_LOG_INFO(" Current Picture Aspect Ratio is %d ", AppliedDisplaySettings.PictureAR); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Sample test for Get/Set ContentType + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToGetSetContentType(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (ContentType GET CALL)"); + + IsControllable = (CTL_DISPLAY_SETTING_FLAG_CONTENT_TYPE & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_CONTENT_TYPE & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set ContentType is not supported"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + APP_LOG_INFO(" Current Applied ContentType is %d ", AppliedDisplaySettings.ContentType); + + // CALL TO SET GAMING CONTENT TYPE + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_CONTENT_TYPE; + NewDisplaySettings.ContentType = CTL_DISPLAY_SETTING_CONTENT_TYPE_GAMING; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (ContentType SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (ContentType GET CALL)"); + APP_LOG_INFO(" Current ContentType is %d ", AppliedDisplaySettings.ContentType); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Sample test for Get/Set LowLatency + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToGetSetLowLatency(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (LowLatency GET CALL)"); + + IsControllable = (CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set LowLatency is not supported"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + APP_LOG_INFO(" Current Applied LowLatency is %d ", AppliedDisplaySettings.LowLatency); + + // CALL TO ENABLE HDR10+ LOW_LATENCY + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY; + NewDisplaySettings.LowLatency = CTL_DISPLAY_SETTING_LOW_LATENCY_ENABLED; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (LowLatency SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (LowLatency GET CALL)"); + APP_LOG_INFO(" Current LowLatency is %d ", AppliedDisplaySettings.LowLatency); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Sample test for Get/Set SourceTonemapping + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToGetSetSourceTonemapping(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (SourceTM GET CALL)"); + + IsControllable = (CTL_DISPLAY_SETTING_FLAG_SOURCE_TM & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_SOURCE_TM & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set SourceTM is not supported"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + APP_LOG_INFO(" Current Applied SourceTM is %d ", AppliedDisplaySettings.SourceTM); + + // CALL TO ENABLE HDR10+ SOURCETM + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_SOURCE_TM; + NewDisplaySettings.SourceTM = CTL_DISPLAY_SETTING_SOURCETM_ENABLED; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (SourceTM SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (SourceTM GET CALL)"); + APP_LOG_INFO(" Current SourceTM is %d ", AppliedDisplaySettings.SourceTM); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Sample test for HDR10+ + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestHDR10Plus(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + AppliedDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY | CTL_DISPLAY_SETTING_FLAG_SOURCE_TM; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (LowLatency GET CALL)"); + + // LowLatency + IsControllable = (CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set LowLatency is not supported/controllable = %d/%d", IsSupported, IsControllable); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + APP_LOG_INFO(" Current Applied LowLatency is %d ", AppliedDisplaySettings.LowLatency); + + // SourceTM + IsControllable = (CTL_DISPLAY_SETTING_FLAG_SOURCE_TM & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_SOURCE_TM & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if ((FALSE == IsControllable) || (FALSE == IsSupported)) + { + APP_LOG_WARN("Get/Set SourceTM is not supported/controllable = %d/%d. Ensure HDR mode is enabled in OS settings.", IsSupported, IsControllable); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + APP_LOG_INFO(" Current Applied SourceTM is %d ", AppliedDisplaySettings.SourceTM); + + // CALL TO ENABLE HDR10+ LOW_LATENCY + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY | CTL_DISPLAY_SETTING_FLAG_SOURCE_TM; + NewDisplaySettings.LowLatency = CTL_DISPLAY_SETTING_LOW_LATENCY_ENABLED; + NewDisplaySettings.SourceTM = CTL_DISPLAY_SETTING_SOURCETM_ENABLED; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (LowLatency_SourceTM SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + AppliedDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY | CTL_DISPLAY_SETTING_FLAG_SOURCE_TM; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (LowLatency_SourceTM GET CALL)"); + APP_LOG_INFO(" Current LowLatency is %d ", AppliedDisplaySettings.LowLatency); + APP_LOG_INFO(" Current SourceTM is %d ", AppliedDisplaySettings.SourceTM); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Sample test for Get/Set Audio settings + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestToGetSetAudioEndpoint(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_settings_t AppliedDisplaySettings = { 0 }; + ctl_display_settings_t NewDisplaySettings = { 0 }; + bool IsControllable, IsSupported = FALSE; + + // GET CALL + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Audio settings GET CALL)"); + + IsControllable = (CTL_DISPLAY_SETTING_FLAG_AUDIO & AppliedDisplaySettings.ControllableFlags) ? TRUE : FALSE; + IsSupported = (CTL_DISPLAY_SETTING_FLAG_AUDIO & AppliedDisplaySettings.SupportedFlags) ? TRUE : FALSE; + + if (FALSE == IsControllable) + { + printf("Get/Set Audio settings are not controllable \n"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + if (FALSE == IsSupported) + { + printf("Get/Set Audio is not supported \n"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + printf("\n Current Audio settings are %d \n", AppliedDisplaySettings.AudioSettings); + + // SET CALL To disable audio endpoint + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_AUDIO; + NewDisplaySettings.AudioSettings = CTL_DISPLAY_SETTING_AUDIO_DISABLED; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Audio settings SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Audio settings GET CALL)"); + printf("\n Current Audio settings post SET call %d \n", AppliedDisplaySettings.AudioSettings); + + if (AppliedDisplaySettings.AudioSettings != NewDisplaySettings.AudioSettings) + { + APP_LOG_ERROR("Current and Applied AudioSettings mismatched: %d, %d", AppliedDisplaySettings.AudioSettings, NewDisplaySettings.AudioSettings); + } + + // SET CALL To enable back audio endpoint + NewDisplaySettings = { 0 }; + NewDisplaySettings.Version = API_VERSION; + NewDisplaySettings.Size = sizeof(ctl_display_settings_t); + NewDisplaySettings.Set = TRUE; + + NewDisplaySettings.ValidFlags = CTL_DISPLAY_SETTING_FLAG_AUDIO; + NewDisplaySettings.AudioSettings = CTL_DISPLAY_SETTING_AUDIO_DEFAULT; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &NewDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Audio settings SET CALL)"); + + // GET CALL + AppliedDisplaySettings = { 0 }; + AppliedDisplaySettings.Version = API_VERSION; + AppliedDisplaySettings.Size = sizeof(ctl_display_settings_t); + AppliedDisplaySettings.Set = FALSE; + + Result = ctlGetSetDisplaySettings(hDisplayOutput, &AppliedDisplaySettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetDisplaySettings (Audio settings GET CALL)"); + printf("\n Current Audio settings post SET call %d \n", AppliedDisplaySettings.AudioSettings); + + if (AppliedDisplaySettings.AudioSettings != NewDisplaySettings.AudioSettings) + { + APP_LOG_ERROR("Current and Applied AudioSettings mismatched: %d, %d", AppliedDisplaySettings.AudioSettings, NewDisplaySettings.AudioSettings); + } + +Exit: + return Result; +} + +/*************************************************************** + * @brief EnumerateDisplayHandles + * Only for demonstration purpose, API is called for each of the display output handle in below snippet. + * User has to filter through the available display output handle and has to call the API with particular display output handle. + * @param hDisplayOutput, DisplayCount + * @return ctl_result_t + ***************************************************************/ +ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput, uint32_t DisplayCount) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + for (uint32_t DisplayIndex = 0; DisplayIndex < DisplayCount; DisplayIndex++) + { + ctl_display_properties_t DisplayProperties = {}; + DisplayProperties.Size = sizeof(ctl_display_properties_t); + + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput[DisplayIndex], "hDisplayOutput"); + + Result = ctlGetDisplayProperties(hDisplayOutput[DisplayIndex], &DisplayProperties); + + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetDisplayProperties"); + + bool IsDisplayAttached = DisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ATTACHED; + + if (FALSE == IsDisplayAttached) + { + continue; + } + + APP_LOG_INFO("Attached Display Count: %d", DisplayIndex); + + // Get/Set Quantization Range + Result = TestToGetSetQuantizationRange(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + + // Get/Set Picture Aspect Ratio + Result = TestToGetSetPictureAspectRatio(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + + // Get/Set Content type + Result = TestToGetSetContentType(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + + if (DisplayProperties.FeatureSupportedFlags & CTL_STD_DISPLAY_FEATURE_FLAG_HDR10_PLUS_CERTIFIED) + { + APP_LOG_INFO("HDR10+ Certified Display is detected"); + + // Get/Set HDR10+ Low Latency & SourceTM Flag + Result = TestHDR10Plus(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + } + else + { + APP_LOG_INFO("HDR10+ Certified Display not detected"); + + // Get/Set HDR10+ Low Latency Flag + Result = TestToGetSetLowLatency(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + + // Get/Set HDR10+ Source Tonemapping Flag + Result = TestToGetSetSourceTonemapping(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + } + + // Get/Set Audio Endpoint + Result = TestToGetSetAudioEndpoint(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + } + +Exit: + return Result; +} + +/*************************************************************** + * @brief EnumerateTargetDisplays + * Enumerates all the possible target display's for the adapters + * @param hDisplayOutput, AdapterCount, hDevices + * @return ctl_result_t + ***************************************************************/ +ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput, uint32_t AdapterCount, ctl_device_adapter_handle_t *hDevices) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + uint32_t DisplayCount = 0; + + for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) + { + // enumerate all the possible target display's for the adapters + // first step is to get the count + DisplayCount = 0; + + Result = ctlEnumerateDisplayOutputs(hDevices[AdapterIndex], &DisplayCount, hDisplayOutput); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + continue; + } + else if (DisplayCount <= 0) + { + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); + continue; + } + + hDisplayOutput = (ctl_display_output_handle_t *)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevices[AdapterIndex], &DisplayCount, hDisplayOutput); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + } + + // Only for demonstration purpose, API is called for each of the display output handle in below snippet. + // User has to filter through the available display output handle and has to call the API with particular display output handle. + Result = EnumerateDisplayHandles(hDisplayOutput, DisplayCount); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_WARN("EnumerateDisplayHandles returned failure code: 0x%X", Result); + } + + CTL_FREE_MEM(hDisplayOutput); + } + +Exit: + + CTL_FREE_MEM(hDisplayOutput); + return Result; +} + +/*************************************************************** + * @brief Main Function which calls the Sample Display Settings API + * @param + * @return int + ***************************************************************/ +int main() +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_device_adapter_handle_t *hDevices = NULL; + ctl_display_output_handle_t *hDisplayOutput = NULL; + ctl_device_adapter_properties_t DeviceAdapterProperties = { 0 }; + // Get a handle to the DLL module. + uint32_t AdapterCount = 0; + uint32_t DisplayCount = 0; + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + + ctl_init_args_t CtlInitArgs; + ctl_api_handle_t hAPIHandle; + CtlInitArgs.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION); + CtlInitArgs.flags = 0; + CtlInitArgs.Size = sizeof(CtlInitArgs); + CtlInitArgs.Version = 0; + ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); + + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } + + // Initialization successful + // Get the list of Intel Adapters + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } + + hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); + + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } + + Result = EnumerateTargetDisplays(hDisplayOutput, AdapterCount, hDevices); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + } + +Exit: + + ctlClose(hAPIHandle); + CTL_FREE_MEM(hDisplayOutput); + CTL_FREE_MEM(hDevices); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); + return GResult; +} diff --git a/Samples/DisplaySettings/README.md b/Samples/DisplaySettings/README.md new file mode 100644 index 0000000..02ef053 --- /dev/null +++ b/Samples/DisplaySettings/README.md @@ -0,0 +1 @@ +Sample Application for Display Settings interfaces \ No newline at end of file diff --git a/Samples/DynamicContrastEnhancement_Sample/CMakeLists.txt b/Samples/DynamicContrastEnhancement_Sample/CMakeLists.txt index 6de84c2..858c16a 100644 --- a/Samples/DynamicContrastEnhancement_Sample/CMakeLists.txt +++ b/Samples/DynamicContrastEnhancement_Sample/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME DynamicContrastEnhancement_Sample) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(DynamicContrastEnhancement_Sample VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/DynamicContrastEnhancement_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/DynamicContrastEnhancement_Sample/DynamicContrastEnhancement_Sample_App.cpp b/Samples/DynamicContrastEnhancement_Sample/DynamicContrastEnhancement_Sample_App.cpp index 4ef5ad2..93fe746 100644 --- a/Samples/DynamicContrastEnhancement_Sample/DynamicContrastEnhancement_Sample_App.cpp +++ b/Samples/DynamicContrastEnhancement_Sample/DynamicContrastEnhancement_Sample_App.cpp @@ -266,7 +266,10 @@ double CalculateAverageLuminance(const ctl_dce_args_t DceArgs) TotalLuminance += (double)DceArgs.pHistogram[Index] * DeGammaLUT; } - AverageLuminance = (TotalLuminance / TotalNumPixels) * BLC_PWM_LOW_PRECISION_FACTOR; + if (0 != TotalNumPixels) + { + AverageLuminance = (TotalLuminance / TotalNumPixels) * BLC_PWM_LOW_PRECISION_FACTOR; + } return AverageLuminance; } @@ -432,19 +435,40 @@ int main(int argc, char *pArgv[]) CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } Result = TestDynamicContrastEnhancement(hDevices, AdapterCount); LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "TestDynamicContrastEnhancement"); diff --git a/Samples/Edid_Management_Sample/CMakeLists.txt b/Samples/Edid_Management_Sample/CMakeLists.txt index ea9c555..878ea6f 100644 --- a/Samples/Edid_Management_Sample/CMakeLists.txt +++ b/Samples/Edid_Management_Sample/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Edid_Management_Sample) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Edid_Management_Sample VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Edid_Mgmt_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Edid_Management_Sample/Edid_Mgmt_Sample_App.cpp b/Samples/Edid_Management_Sample/Edid_Mgmt_Sample_App.cpp index d8ed5e7..f4b0a8a 100644 --- a/Samples/Edid_Management_Sample/Edid_Mgmt_Sample_App.cpp +++ b/Samples/Edid_Management_Sample/Edid_Mgmt_Sample_App.cpp @@ -43,16 +43,17 @@ static bool WriteBinaryFile = false; static bool DisableAudioInEdid = false; static char EdidBinFileName[MAX_PATH] = { 0 }; -static uint8_t EdidOverrideBuf[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0xAC, 0x16, 0xF0, 0x4C, 0x4E, 0x37, 0x30, 0x17, 0x15, 0x01, 0x03, 0x80, 0x34, 0x20, 0x78, 0xEA, 0x1E, - 0xC5, 0xAE, 0x4F, 0x34, 0xB1, 0x26, 0x0E, 0x50, 0x54, 0xA5, 0x4B, 0x00, 0x81, 0x80, 0xA9, 0x40, 0xD1, 0x00, 0x71, 0x4F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x28, 0x3C, 0x80, 0xA0, 0x70, 0xB0, 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x4A, - 0x32, 0x35, 0x37, 0x4D, 0x31, 0x36, 0x31, 0x30, 0x37, 0x4E, 0x4C, 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x49, 0x47, 0x43, 0x4C, 0x20, 0x44, 0x45, 0x4C, 0x55, - 0x32, 0x34, 0x31, 0x30, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x38, 0x4C, 0x1E, 0x51, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xEC, 0x02, 0x03, - 0x29, 0xF1, 0x50, 0x90, 0x05, 0x04, 0x03, 0x02, 0x07, 0x16, 0x01, 0x1F, 0x12, 0x13, 0x14, 0x20, 0x15, 0x11, 0x06, 0x23, 0x09, 0x07, 0x07, 0x67, 0x03, 0x0C, - 0x00, 0x10, 0x00, 0x38, 0x2D, 0x83, 0x01, 0x00, 0x00, 0xE3, 0x05, 0x03, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x06, - 0x44, 0x21, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x80, 0x18, 0x71, 0x1C, 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x9E, 0x01, 0x1D, 0x00, - 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28, 0x55, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1E, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, - 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E }; +// declare a size variable vector instead of fixed size array, such that, we can recieve variant blocks of EDID +static std::vector EdidOverrideBuf = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0xAC, 0x16, 0xF0, 0x4C, 0x4E, 0x37, 0x30, 0x17, 0x15, 0x01, 0x03, 0x80, 0x34, 0x20, 0x78, 0xEA, 0x1E, 0xC5, 0xAE, 0x4F, 0x34, 0xB1, 0x26, + 0x0E, 0x50, 0x54, 0xA5, 0x4B, 0x00, 0x81, 0x80, 0xA9, 0x40, 0xD1, 0x00, 0x71, 0x4F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3C, 0x80, 0xA0, 0x70, 0xB0, 0x23, 0x40, 0x30, 0x20, + 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x4A, 0x32, 0x35, 0x37, 0x4D, 0x31, 0x36, 0x31, 0x30, 0x37, 0x4E, 0x4C, 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x49, + 0x47, 0x43, 0x4C, 0x20, 0x44, 0x45, 0x4C, 0x55, 0x32, 0x34, 0x31, 0x30, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x38, 0x4C, 0x1E, 0x51, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xEC, + 0x02, 0x03, 0x29, 0xF1, 0x50, 0x90, 0x05, 0x04, 0x03, 0x02, 0x07, 0x16, 0x01, 0x1F, 0x12, 0x13, 0x14, 0x20, 0x15, 0x11, 0x06, 0x23, 0x09, 0x07, 0x07, 0x67, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x38, + 0x2D, 0x83, 0x01, 0x00, 0x00, 0xE3, 0x05, 0x03, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x80, 0x18, 0x71, + 0x1C, 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x9E, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28, 0x55, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1E, 0x8C, + 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E +}; /*************************************************************** * @brief PrintUsage @@ -62,29 +63,29 @@ static uint8_t EdidOverrideBuf[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0 ***************************************************************/ void PrintUsage(char *pArgv[]) { - printf("EDID Management Sample Test Application.\n"); - printf("\nUsage: %s [Operation] <-a Adapter#> <-t Target_ID> <-e Bin_Filename>\n", pArgv[0]); - printf("\nOperation\n"); - printf("\t'-lock' : Locks Monitor EDID\n"); - printf("\t'-unlock' : Unlock Previous Operation\n"); - printf("\t'-over' : Override EDID\n"); - printf("\t'-rem' : Remove EDID\n"); - printf("\t'-read' : Read Current Active EDID\n"); - printf("\t'-noaud' : Disable Display Audio. NOTE: You Must Specify an EDID binary\n"); - printf("\t'-help' : Display usage\n"); - printf("-a [Adapter #] : Optional Arg\n"); - printf("\tSpecify adapter number [min:0, max:4]\n"); - printf("\t0 (default) - applies to all adapters\n"); - printf("\t1 - applies to the first enumerated adapter\n"); - printf("\t2 - applies to the second enumerated adapter\n"); - printf("\t3 - applies to the third enumerated adapter\n"); - printf("\t4 - applies to the fourth enumerated adapter\n"); - printf("-t [Target ID] : Optional Arg\n"); - printf("\tSpecify Target ID in Hex. e.g '1040'\n"); - printf("-e [path\\to\\EDID binary file(read)] : Optional Arg\n"); - printf("\tSpecify EDID binary\n"); - printf("-we [path\\to\\EDID binary file(write)] : Optional Arg\n"); - printf("\tSpecify EDID binary\n"); + APP_LOG_INFO("EDID Management Sample Test Application."); + APP_LOG_INFO("Usage: %s [Operation] <-a Adapter#> <-t Target_ID> <-e Bin_Filename>", pArgv[0]); + APP_LOG_INFO("Operation"); + APP_LOG_INFO("\t'-lock' : Locks Monitor EDID"); + APP_LOG_INFO("\t'-unlock' : Unlock Previous Operation"); + APP_LOG_INFO("\t'-over' : Override EDID"); + APP_LOG_INFO("\t'-rem' : Remove EDID"); + APP_LOG_INFO("\t'-read' : Read Current Active EDID"); + APP_LOG_INFO("\t'-noaud' : Disable Display Audio. NOTE: You Must Specify an EDID binary"); + APP_LOG_INFO("\t'-help' : Display usage"); + APP_LOG_INFO("-a [Adapter #] : Optional Arg"); + APP_LOG_INFO("\tSpecify adapter number [min:0, max:4]"); + APP_LOG_INFO("\t0 (default) - applies to all adapters"); + APP_LOG_INFO("\t1 - applies to the first enumerated adapter"); + APP_LOG_INFO("\t2 - applies to the second enumerated adapter"); + APP_LOG_INFO("\t3 - applies to the third enumerated adapter"); + APP_LOG_INFO("\t4 - applies to the fourth enumerated adapter"); + APP_LOG_INFO("-t [Target ID] : Optional Arg"); + APP_LOG_INFO("\tSpecify Target ID in Hex. e.g '1040'"); + APP_LOG_INFO("-e [path\\to\\EDID binary file(read)] : Optional Arg"); + APP_LOG_INFO("\tSpecify EDID binary"); + APP_LOG_INFO("-we [path\\to\\EDID binary file(write)] : Optional Arg"); + APP_LOG_INFO("\tSpecify EDID binary"); } /*************************************************************** @@ -106,13 +107,13 @@ bool WriteEdidToFile(uint8_t *const pEdidBuf, uint32_t EdidSize) fclose(pFile); if (BytesWritten != (1 * EdidSize)) { - printf("Number of bytes differ when writing Edid binary file.\n"); + APP_LOG_ERROR("Number of bytes differ when writing Edid binary file."); return false; } } else { - printf("Failure opening Edid binary file for writing.\n"); + APP_LOG_ERROR("Failure opening Edid binary file for writing."); return false; } @@ -227,8 +228,8 @@ uint32_t RemoveAudioCapsFromEdid(uint8_t *pEdidBuf, uint32_t EdidSize) } } - printf("Number of Audio blocks removed from Edid = %d.\n", NumAudioBlocksRemoved); - printf("Number of Basic Audio flags disabled in Edid = %d.\n", NumCeaV3ExtensionsFound); + APP_LOG_INFO("Number of Audio blocks removed from Edid = %d.", NumAudioBlocksRemoved); + APP_LOG_INFO("Number of Basic Audio flags disabled in Edid = %d.", NumCeaV3ExtensionsFound); return NumAudioBlocksRemoved; } @@ -262,7 +263,7 @@ ctl_result_t EdidMgmtApi(ctl_display_output_handle_t hDisplayOutput, const ctl_e if ((EdidMgmtArgs.OutFlags & CTL_EDID_MANAGEMENT_OUT_FLAG_DISPLAY_CONNECTED) != 0) { - printf("info: Out flags : Physical Display is connected.\n"); + APP_LOG_INFO("Out flags : Physical Display is connected."); } if (CTL_EDID_MANAGEMENT_OPTYPE_READ_EDID == OpType) @@ -271,33 +272,33 @@ ctl_result_t EdidMgmtApi(ctl_display_output_handle_t hDisplayOutput, const ctl_e if (pEdidSz) { *pEdidSz = EdidMgmtArgs.EdidSize; - printf("EDID Size %d.\n", EdidMgmtArgs.EdidSize); + APP_LOG_INFO("EDID Size %d.", EdidMgmtArgs.EdidSize); } if (pEdidBuf) { if (DisableAudioInEdid) { - printf("Attempting to remove audio from Edid...\n"); + APP_LOG_INFO("Attempting to remove audio from Edid..."); if (0 == RemoveAudioCapsFromEdid(pEdidBuf, EdidMgmtArgs.EdidSize)) { if (NumCeaV3ExtensionsFound) { - printf("Audio descriptor blocks not found and only Basic Audio was removed from Edid,\n"); - printf("so override operations may fail to disable monitor audio.\n"); + APP_LOG_WARN("Audio descriptor blocks not found and only Basic Audio was removed from Edid,"); + APP_LOG_WARN("so override operations may fail to disable monitor audio."); } else { - printf("No CEA Extensions found in Edid, binary file will fail to disable monitor audio\n"); + APP_LOG_ERROR("No CEA Extensions found in Edid, binary file will fail to disable monitor audio"); } } } if (WriteBinaryFile) { - printf("Writing binary file: %s\n", EdidBinFileName); + APP_LOG_INFO("Writing binary file: %s", EdidBinFileName); if (false == WriteEdidToFile(pEdidBuf, EdidMgmtArgs.EdidSize)) { - printf("Failure writing Edid binary file.\n"); + APP_LOG_ERROR("Failure writing Edid binary file."); } } @@ -306,26 +307,26 @@ ctl_result_t EdidMgmtApi(ctl_display_output_handle_t hDisplayOutput, const ctl_e { if (0 == (j % 16)) // Format EDID to make it easier to analyze { - printf("\n"); + PRINT_LOGS(" "); } - printf("0x%02X ", pEdidBuf[j]); + APP_LOG_INFO("0x%02X ", pEdidBuf[j]); } - printf("\n"); + PRINT_LOGS(" "); } if ((EdidMgmtArgs.OutFlags & CTL_EDID_MANAGEMENT_OUT_FLAG_SUPPLIED_EDID) != 0) { - printf("info: Out flags : Current EDID is IGCL Supplied.\n"); + APP_LOG_INFO("Out flags : Current EDID is IGCL Supplied."); } else if ((EdidMgmtArgs.OutFlags & CTL_EDID_MANAGEMENT_OUT_FLAG_MONITOR_EDID) != 0) { - printf("info: Out flags : Current EDID is Monitor Data.\n"); + APP_LOG_INFO("Out flags : Current EDID is Monitor Data."); } } // wait based on out flag, to allow time for Config Switches by OS if ((EdidMgmtArgs.OutFlags & CTL_EDID_MANAGEMENT_OUT_FLAG_OS_CONN_NOTIFICATION) != 0) { - printf("info: Waiting for 5 secs to allow any OS Config Switch.\n"); + APP_LOG_INFO("Waiting for 5 secs to allow any OS Config Switch."); Sleep(5000); } return Result; @@ -345,8 +346,8 @@ ctl_result_t TestEDIDManagement(ctl_display_output_handle_t hDisplayOutput, ctl_ uint8_t *pEdidBuf = nullptr; bool IsDisplayAttached = (0 != (DisplayProperties.DisplayConfigFlags & CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ATTACHED)); - printf("Info: Start EDID Management Tests for TargetID: %x, Type %d, Config 0x%x, DisplayMuxType %d, PConOutType %d.\n", DisplayProperties.Os_display_encoder_handle.WindowsDisplayEncoderID, - DisplayProperties.Type, DisplayProperties.DisplayConfigFlags, DisplayProperties.AttachedDisplayMuxType, DisplayProperties.ProtocolConverterOutput); + APP_LOG_INFO("Start EDID Management Tests for TargetID: %x, Type %d, Config 0x%x, DisplayMuxType %d, PConOutType %d.", DisplayProperties.Os_display_encoder_handle.WindowsDisplayEncoderID, + DisplayProperties.Type, DisplayProperties.DisplayConfigFlags, DisplayProperties.AttachedDisplayMuxType, DisplayProperties.ProtocolConverterOutput); if (TgtId > 0) // individual display control { // Below operations possible on detached target @@ -360,27 +361,27 @@ ctl_result_t TestEDIDManagement(ctl_display_output_handle_t hDisplayOutput, ctl_ } else { - EdidSize = sizeof(EdidOverrideBuf); - Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, EdidOverrideBuf); + EdidSize = static_cast(EdidOverrideBuf.size()); + Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, &EdidOverrideBuf[0]); } LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:LOCK supplied EDID"); - printf("Info: Passed Test Lock supplied EDID.\n"); + APP_LOG_INFO("Passed Test Lock supplied EDID."); break; case CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID: Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:UNLOCK EDID"); - printf("Info: Passed Test Unlock EDID.\n"); + APP_LOG_INFO("Passed Test Unlock EDID."); break; case CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID: - EdidSize = sizeof(EdidOverrideBuf); - Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, EdidOverrideBuf); + EdidSize = static_cast(EdidOverrideBuf.size()); + Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, &EdidOverrideBuf[0]); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:override EDID"); - printf("Info: Passed Test override EDID.\n"); + APP_LOG_INFO("Passed Test override EDID."); break; case CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID: Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:remove EDID"); - printf("Info: Passed Test remove overridden EDID.\n"); + APP_LOG_INFO("Passed Test remove overridden EDID."); break; case CTL_EDID_MANAGEMENT_OPTYPE_READ_EDID: // Pass 1: read EDID size @@ -392,7 +393,7 @@ ctl_result_t TestEDIDManagement(ctl_display_output_handle_t hDisplayOutput, ctl_ EXIT_ON_MEM_ALLOC_FAILURE(pEdidBuf, "pEdidBuf"); Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_READ_EDID, CTL_EDID_TYPE_CURRENT, &EdidSize, pEdidBuf); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:READ EDID 2"); - printf("\nInfo: Passed Test read EDID.\n"); + APP_LOG_INFO("Passed Test read EDID."); break; default: break; @@ -404,30 +405,30 @@ ctl_result_t TestEDIDManagement(ctl_display_output_handle_t hDisplayOutput, ctl_ { if (true == IsCustomEdid) { - EdidSize = sizeof(EdidOverrideBuf); - Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, EdidOverrideBuf); + EdidSize = static_cast(EdidOverrideBuf.size()); + Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, &EdidOverrideBuf[0]); } else { Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_MONITOR); } LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:LOCK Monitor EDID"); - printf("Info: Passed Test Lock Monitor EDID.\n"); + APP_LOG_INFO("Passed Test Lock Monitor EDID."); } if (CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID == EdidMgmtOpType || CTL_EDID_MANAGEMENT_OPTYPE_MAX == EdidMgmtOpType) { Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:UNLOCK EDID"); - printf("Info: Passed Test Unlock EDID.\n"); + APP_LOG_INFO("Passed Test Unlock EDID."); } if (CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID == EdidMgmtOpType || CTL_EDID_MANAGEMENT_OPTYPE_MAX == EdidMgmtOpType) { - EdidSize = sizeof(EdidOverrideBuf); - Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, EdidOverrideBuf); + EdidSize = static_cast(EdidOverrideBuf.size()); + Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, &EdidOverrideBuf[0]); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:override EDID"); - printf("Info: Passed Test override EDID.\n"); + APP_LOG_INFO("Passed Test override EDID."); } if (CTL_EDID_MANAGEMENT_OPTYPE_READ_EDID == EdidMgmtOpType || CTL_EDID_MANAGEMENT_OPTYPE_MAX == EdidMgmtOpType) @@ -443,7 +444,7 @@ ctl_result_t TestEDIDManagement(ctl_display_output_handle_t hDisplayOutput, ctl_ LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:READ EDID 2"); CTL_FREE_MEM(pEdidBuf); - printf("\nInfo: Passed Test read EDID.\n"); + APP_LOG_INFO("Passed Test read EDID."); } if (CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID == EdidMgmtOpType || CTL_EDID_MANAGEMENT_OPTYPE_MAX == EdidMgmtOpType) @@ -463,26 +464,26 @@ ctl_result_t TestEDIDManagement(ctl_display_output_handle_t hDisplayOutput, ctl_ LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:READ EDID 2"); CTL_FREE_MEM(pEdidBuf); - printf("\nInfo: Passed Test remove overridden EDID.\n"); + APP_LOG_INFO("Passed Test remove overridden EDID."); } // When ran the app w/o any commandline args, // test EDID lock with Supplied EDID. For demo purpose. if (CTL_EDID_MANAGEMENT_OPTYPE_MAX == EdidMgmtOpType) { - EdidSize = sizeof(EdidOverrideBuf); - Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, EdidOverrideBuf); + EdidSize = static_cast(EdidOverrideBuf.size()); + Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID, CTL_EDID_TYPE_OVERRIDE, &EdidSize, &EdidOverrideBuf[0]); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:LOCK supplied EDID"); - printf("Info: Passed Test Lock supplied EDID.\n"); + APP_LOG_INFO("Passed Test Lock supplied EDID."); // unlock display Result = EdidMgmtApi(hDisplayOutput, CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID); LOG_AND_EXIT_ON_ERROR(Result, "ctlEdidManagement:UNLOCK EDID"); - printf("Info: Passed Test Unlock EDID.\n"); + APP_LOG_INFO("Passed Test Unlock EDID."); } } Exit: - printf("Info: Exit EDID Management Tests for TargetID: %x.\n\n", DisplayProperties.Os_display_encoder_handle.WindowsDisplayEncoderID); + APP_LOG_INFO("Exit EDID Management Tests for TargetID: %x.", DisplayProperties.Os_display_encoder_handle.WindowsDisplayEncoderID); CTL_FREE_MEM(pEdidBuf); return Result; } @@ -549,13 +550,13 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); continue; } @@ -566,7 +567,7 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } @@ -577,7 +578,7 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateDisplayHandles returned failure code: 0x%X\n", Result); + APP_LOG_WARN("EnumerateDisplayHandles returned failure code: 0x%X", Result); } CTL_FREE_MEM(hDisplayOutput); @@ -638,8 +639,15 @@ int main(int32_t Argc, char *pArgv[]) CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Get a handle to the DLL module. uint32_t AdapterCount = 0; @@ -687,13 +695,13 @@ int main(int32_t Argc, char *pArgv[]) { if (!isdigit(OptionArg[Index])) { - printf("Invalid Adapter Number.\n"); + APP_LOG_ERROR("Invalid Adapter Number."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } } AdapterNumber = stoul(OptionArg, 0, 16); - printf("Adapter Number: %d\n", AdapterNumber); + APP_LOG_INFO("Adapter Number: %d", AdapterNumber); } } // Target ID option @@ -705,13 +713,13 @@ int main(int32_t Argc, char *pArgv[]) { if (!isxdigit(OptionArg[Index])) { - printf("Invalid Target ID.\n"); + APP_LOG_ERROR("Invalid Target ID."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } } TgtId = stoul(OptionArg, 0, 16); - printf("Test or Target ID: 0x%X\n", TgtId); + APP_LOG_INFO("Test or Target ID: 0x%X", TgtId); } } @@ -725,10 +733,10 @@ int main(int32_t Argc, char *pArgv[]) switch (EdidMgmtOpType) { case CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID: - printf("Info: Ignoring write of binary file for Undo Override operation.\n"); + APP_LOG_WARN("Ignoring write of binary file for Undo Override operation."); break; case CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID: - printf("Info: Ignoring write of binary file for Unlock operation.\n"); + APP_LOG_WARN("Ignoring write of binary file for Unlock operation."); break; default: ZeroMemory(&EdidBinFileName, sizeof(EdidBinFileName)); @@ -739,7 +747,7 @@ int main(int32_t Argc, char *pArgv[]) } else { - printf("Failed to write the EDID binary file - NULL filename.\n"); + APP_LOG_ERROR("Failed to write the EDID binary file - NULL filename."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -751,36 +759,45 @@ int main(int32_t Argc, char *pArgv[]) switch (EdidMgmtOpType) { case CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID: - printf("Info: Ignoring read of binary file for Undo Override operation.\n"); + APP_LOG_WARN("Ignoring read of binary file for Undo Override operation."); break; case CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID: - printf("Info: Ignoring read of binary file for Unlock operation.\n"); + APP_LOG_WARN("Ignoring read of binary file for Unlock operation."); break; default: - ifstream EdidFile; - streampos FileSize; - - EdidFile.open(OptionArg, ios::in | ios::binary | ios::ate); - - if (false == EdidFile.is_open()) + try { - printf("Cannot open a EDID file.\n"); - Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; - EXIT_ON_ERROR(Result); + ifstream EdidFile; + streampos FileSize; + + EdidFile.open(OptionArg, ios::in | ios::binary | ios::ate); + + if (false == EdidFile.is_open()) + { + APP_LOG_ERROR("Cannot open a EDID file."); + Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; + EXIT_ON_ERROR(Result); + } + + FileSize = EdidFile.tellg(); + // resize the buffer to recive data read from file + EdidOverrideBuf.clear(); + EdidOverrideBuf.resize(static_cast(FileSize)); + EdidFile.seekg(0, ios::beg); + EdidFile.read((char *)&EdidOverrideBuf[0], FileSize); + EdidFile.close(); + IsCustomEdid = true; + } + catch (const std::ios_base::failure &e) + { + APP_LOG_ERROR("%s ", e.what()); } - - FileSize = EdidFile.tellg(); - ZeroMemory(&EdidOverrideBuf, sizeof(EdidOverrideBuf)); - EdidFile.seekg(0, ios::beg); - EdidFile.read((char *)&EdidOverrideBuf, FileSize); - EdidFile.close(); - IsCustomEdid = true; break; } } else { - printf("Failed to find the EDID binary file.\n"); + APP_LOG_ERROR("Failed to find the EDID binary file."); Result = CTL_RESULT_ERROR_INVALID_ARGUMENT; EXIT_ON_ERROR(Result); } @@ -788,27 +805,41 @@ int main(int32_t Argc, char *pArgv[]) // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = EnumerateTargetDisplays(AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateTargetDisplays returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } Exit: ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/FirmwareApi/CMakeLists.txt b/Samples/FirmwareApi/CMakeLists.txt new file mode 100644 index 0000000..68b3d74 --- /dev/null +++ b/Samples/FirmwareApi/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) +set(TARGET_NAME FirmwareApi) +get_filename_component(ROOT_DIR ../../ ABSOLUTE) +project(FirmwareApi VERSION 1.0) +add_executable(${TARGET_NAME} + ${CMAKE_CURRENT_SOURCE_DIR}/FirmwareApiApp.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp +) + +if(MSVC) + set_target_properties(${TARGET_NAME} + PROPERTIES + VS_DEBUGGER_COMMAND_ARGUMENTS "" + VS_DEBUGGER_WORKING_DIRECTORY "$(OutDir)" + ) + + ADD_DEFINITIONS(-DUNICODE) + ADD_DEFINITIONS(-D_UNICODE) +endif() + +include_directories(${ROOT_DIR}/include) +include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/FirmwareApi/FirmwareApiApp.cpp b/Samples/FirmwareApi/FirmwareApiApp.cpp new file mode 100644 index 0000000..693c30e --- /dev/null +++ b/Samples/FirmwareApi/FirmwareApiApp.cpp @@ -0,0 +1,262 @@ +//=========================================================================== +// Copyright (C) 2022 Intel Corporation +// +// +// +// SPDX-License-Identifier: MIT +//-------------------------------------------------------------------------- + +/** + * + * @file FirmwareApiApp.cpp + * @brief This file contains the I2C AUX Sample App & the 'main' function. Program execution begins and ends there. + * + */ + +#define _CRTDBG_MAP_ALLOC +#include +#include +#include +#include +#include +#include + +#define CTL_APIEXPORT // caller of control API DLL shall define this before + // including igcl_api.h +#include "igcl_api.h" +#include "GenericIGCLApp.h" + +ctl_result_t IsDiscreteGfxAdapter(ctl_device_adapter_properties_t *pDeviceAdapterProperties) +{ + if (CTL_DEVICE_TYPE_GRAPHICS != pDeviceAdapterProperties->device_type) + { + printf("This is not a Graphics device \n"); + return CTL_RESULT_ERROR_NOT_INITIALIZED; + } + if (0 != pDeviceAdapterProperties->graphics_adapter_properties) + { + printf("This is not a Discrete Graphics adapter, its either integrated/LDA adapter \n"); + return CTL_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + return CTL_RESULT_SUCCESS; +} + +int main() +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + uint32_t AdapterCount = 0; + ctl_device_adapter_handle_t *hDevices = nullptr; + ctl_device_adapter_properties_t DeviceAdapterProperties[4] = { 0 }; + LUID DeviceID[4] = { 0 }; + + // Get a handle to the DLL module. + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + + ctl_init_args_t CtlInitArgs; + ctl_api_handle_t hAPIHandle; + CtlInitArgs.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION); + CtlInitArgs.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO | CTL_INIT_FLAG_IGSC_FUL; + CtlInitArgs.Size = sizeof(CtlInitArgs); + CtlInitArgs.Version = 0; + + ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); + + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } + + if (CTL_RESULT_SUCCESS != Result) + { + goto Exit; + } + + AdapterCount = 0; + + // Initialization successful + // Get the list of Intel Adapters + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, NULL); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } + + if (CTL_RESULT_SUCCESS == Result) + { + hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); + if (nullptr == hDevices) + { + Result = CTL_RESULT_ERROR_INVALID_NULL_POINTER; + goto Exit; + } + + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } + } + if (CTL_RESULT_SUCCESS != Result) + { + printf("ctlEnumerateDevices returned failure code: 0x%X\n", Result); + goto Exit; + } + + try + { + for (uint32_t i = 0; i < AdapterCount; i++) + { + DeviceAdapterProperties[i].Size = sizeof(ctl_device_adapter_properties_t); + DeviceAdapterProperties[i].pDeviceID = &(DeviceID[i]); + DeviceAdapterProperties[i].device_id_size = sizeof(LUID); + if (NULL == DeviceAdapterProperties[i].pDeviceID) + { + Result = CTL_RESULT_ERROR_INVALID_NULL_POINTER; + goto Exit; + } + + Result = ctlGetDeviceProperties(hDevices[i], &DeviceAdapterProperties[i]); + if (Result != CTL_RESULT_SUCCESS) + { + printf("ctlGetDeviceProperties returned failure code: 0x%X\n", Result); + continue; + } + + Result = IsDiscreteGfxAdapter(&DeviceAdapterProperties[i]); + if (Result != CTL_RESULT_SUCCESS) + { + continue; + } + + // Get PCI paramters to check link speed + ctl_pci_properties_t PciProperties = { 0 }; + PciProperties.Size = sizeof(PciProperties); + ctl_result_t res = ctlPciGetProperties(hDevices[i], &PciProperties); + if (res != CTL_RESULT_SUCCESS) + { + printf("Error: %d from PCI get properties.", res); + continue; + } + + // Get PCI paramters to check current link speed + ctl_pci_state_t PciState = { 0 }; + PciState.Size = sizeof(PciState); + + res = ctlPciGetState(hDevices[i], &PciState); + if (res != CTL_RESULT_SUCCESS) + { + printf("Error: %d from PCI get properties.", res); + continue; + } + + printf("PCI Max link speed: %d :: PCI Current link speed: %d \n", PciProperties.maxSpeed.gen, PciState.speed.gen); + + if (PciState.speed.gen == 5) + { + printf("Current PCI link speed is already Gen5, so nothing to do\n"); + continue; + } + + // Check if current FW supports Gen5 to Gen4 downgrade capability + ctl_firmware_properties_t BaseFwProperties = { 0 }; + BaseFwProperties.Size = sizeof(BaseFwProperties); + + res = ctlGetFirmwareProperties(hDevices[i], &BaseFwProperties); + if (res == CTL_RESULT_SUCCESS) + { + if (BaseFwProperties.FirmwareConfig & CTL_FIRMWARE_CONFIG_FLAG_IS_DEVICE_LINK_SPEED_DOWNGRADE_CAPABLE) + { + printf("FW supports Gen5 to Gen4 downgrade capability\n"); + } + else + { + printf("FW does not support Gen5 to Gen4 downgrade capability\n"); + continue; + } + + if (BaseFwProperties.FirmwareConfig & CTL_FIRMWARE_CONFIG_FLAG_IS_DEVICE_LINK_SPEED_DOWNGRADE_ACTIVE) + { + printf("We downgraded from Gen5 to Gen4 successfully or we already attempted to go from Gen4 to Gen5 and it probably failed\n"); + continue; + } + } + else + { + printf("Error: %d from getfirmwareproperties.", res); + } + + // Enumerate firmware components + uint32_t Count = 0; + ctl_firmware_component_handle_t *phFirmwareComponents = nullptr; + + res = ctlEnumerateFirmwareComponents(hDevices[i], &Count, nullptr); + if (res != CTL_RESULT_SUCCESS) + { + printf("Error: %d from enumeratefirmwarecomponents.", res); + continue; + } + + phFirmwareComponents = (ctl_firmware_component_handle_t *)malloc(sizeof(ctl_firmware_component_handle_t) * Count); + if (phFirmwareComponents == nullptr) + { + printf("Error: %d from malloc.", res); + continue; + } + res = ctlEnumerateFirmwareComponents(hDevices[i], &Count, phFirmwareComponents); + if (res != CTL_RESULT_SUCCESS) + { + if (phFirmwareComponents != nullptr) + free(phFirmwareComponents); + + printf("Error: %d from enumeratefirmwarecomponents.", res); + continue; + } + + for (uint32_t j = 0; j < Count; j++) + { + ctl_firmware_component_properties_t FwComponentProperties = { 0 }; + FwComponentProperties.Size = sizeof(FwComponentProperties); + + res = ctlGetFirmwareComponentProperties(phFirmwareComponents[j], &FwComponentProperties); + if (res != CTL_RESULT_SUCCESS) + { + printf("Error: %d from getfirmwarecomponentproperties.", res); + continue; + } + + printf("Fw componenent (%d) : Name: %s and Version : %s \n", j, FwComponentProperties.name, FwComponentProperties.version); + } + + if (phFirmwareComponents != nullptr) + free(phFirmwareComponents); + } + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } +Exit: + + if (hDevices != nullptr) + free(hDevices); + + ctlClose(hAPIHandle); + + printf("Overrall test result is 0x%X\n", CTL_RESULT_SUCCESS); + + return CTL_RESULT_SUCCESS; +} diff --git a/Samples/FirmwareApi/README.md b/Samples/FirmwareApi/README.md new file mode 100644 index 0000000..1942577 --- /dev/null +++ b/Samples/FirmwareApi/README.md @@ -0,0 +1 @@ +Sample Application for Firmware API interfaces diff --git a/Samples/Generic_Sample/CMakeLists.txt b/Samples/Generic_Sample/CMakeLists.txt index e6d7644..4647c49 100644 --- a/Samples/Generic_Sample/CMakeLists.txt +++ b/Samples/Generic_Sample/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Generic_Sample) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Generic_Sample VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Sample_ControlAPP.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Generic_Sample/Sample_ControlAPP.cpp b/Samples/Generic_Sample/Sample_ControlAPP.cpp index 55cdf2c..b4ac3fd 100644 --- a/Samples/Generic_Sample/Sample_ControlAPP.cpp +++ b/Samples/Generic_Sample/Sample_ControlAPP.cpp @@ -179,12 +179,28 @@ ctl_result_t CtlSharpnessTest(ctl_display_output_handle_t hDisplayOutput) } } } - if (Result == CTL_RESULT_SUCCESS && SharpnessCaps.SupportedFilterFlags == CTL_SHARPNESS_FILTER_TYPE_FLAG_NON_ADAPTIVE) // This Check is to be revisited when we have Adaptive Support + if ((Result == CTL_RESULT_SUCCESS) && + ((SharpnessCaps.SupportedFilterFlags == CTL_SHARPNESS_FILTER_TYPE_FLAG_NON_ADAPTIVE) || (SharpnessCaps.SupportedFilterFlags == CTL_SHARPNESS_FILTER_TYPE_FLAG_ADAPTIVE))) { // SetSharpness if (NULL != hDisplayOutput) { - Result = ctlSetCurrentSharpness(hDisplayOutput, &SetSharpness); + if (SharpnessCaps.SupportedFilterFlags == CTL_SHARPNESS_FILTER_TYPE_FLAG_NON_ADAPTIVE) + { + SetSharpness.FilterType = CTL_SHARPNESS_FILTER_TYPE_FLAG_NON_ADAPTIVE; + } + else if (SharpnessCaps.SupportedFilterFlags == CTL_SHARPNESS_FILTER_TYPE_FLAG_ADAPTIVE) + { + SetSharpness.FilterType = CTL_SHARPNESS_FILTER_TYPE_FLAG_ADAPTIVE; + } + else + { + Result = CTL_RESULT_ERROR_INVALID_SHARPNESS_FILTER_FLAG; + printf("Result: 0x%X FilterType %d", Result, SharpnessCaps.SupportedFilterFlags); + return Result; + } + SetSharpness.FilterType = SharpnessCaps.SupportedFilterFlags; + Result = ctlSetCurrentSharpness(hDisplayOutput, &SetSharpness); if (Result != CTL_RESULT_SUCCESS) { @@ -303,6 +319,11 @@ ctl_result_t CtlGet3DGlobalTest(ctl_device_adapter_handle_t hDevices) { printf("ctlGetSupported3DCapabilities returned success. No of gaming features = %d\n", FeatureCaps3D.NumSupportedFeatures); FeatureCaps3D.pFeatureDetails = (ctl_3d_feature_details_t *)malloc(sizeof(ctl_3d_feature_details_t) * FeatureCaps3D.NumSupportedFeatures); + if (FeatureCaps3D.pFeatureDetails == NULL) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + memset(FeatureCaps3D.pFeatureDetails, 0x0, sizeof(ctl_3d_feature_details_t) * FeatureCaps3D.NumSupportedFeatures); Result = ctlGetSupported3DCapabilities(hDevices, &FeatureCaps3D); if (Result == CTL_RESULT_SUCCESS) @@ -338,7 +359,7 @@ ctl_result_t CtlGet3DGlobalTest(ctl_device_adapter_handle_t hDevices) { if (false == Get3DCustomStruct(&Feature3D)) { - assert(0); + printf("A new custom feature was added which is not known to the driver\n"); continue; // some error, continue with next value } } @@ -402,6 +423,13 @@ ctl_result_t CtlGetDisplayPropertiesTest(ctl_device_adapter_handle_t hAdapter, c std::cout << "DisplayConfigFlags is " << pStdisplayproperties->DisplayConfigFlags << "\n"; std::cout << "Is Display Active : " << Isdisplay_active << "\n"; std::cout << "Is Display Attached : " << Isdisplay_attached << "\n"; + + std::cout << "Supported features\n"; + PrintStdDisplayFeatureFlags(pStdisplayproperties->FeatureSupportedFlags); + PrintIntelDisplayFeatureFlags(pStdisplayproperties->AdvancedFeatureSupportedFlags); + std::cout << "Enabled features\n "; + PrintStdDisplayFeatureFlags(pStdisplayproperties->FeatureEnabledFlags); + PrintIntelDisplayFeatureFlags(pStdisplayproperties->AdvancedFeatureEnabledFlags); } pStdisplayproperties->DisplayConfigFlags = 0; pStdisplayproperties->Os_display_encoder_handle.WindowsDisplayEncoderID = 0; @@ -640,39 +668,40 @@ ctl_result_t CtlTestEvents(ctl_device_adapter_handle_t hAdapter) * @param * @return ***************************************************************/ -void PrintAdapterProperties(ctl_device_adapter_properties_t StDeviceAdapterProperties) +void PrintAdapterProperties(ctl_device_adapter_properties_t *pStDeviceAdapterProperties) { char DriverVersion[25] = ""; LARGE_INTEGER LIDriverVersion; - LIDriverVersion.QuadPart = StDeviceAdapterProperties.driver_version; + LIDriverVersion.QuadPart = pStDeviceAdapterProperties->driver_version; sprintf(DriverVersion, "%d.%d.%d.%d", HIWORD(LIDriverVersion.HighPart), LOWORD(LIDriverVersion.HighPart), HIWORD(LIDriverVersion.LowPart), LOWORD(LIDriverVersion.LowPart)); printf("Intel Graphics Driver Version : %s\n", DriverVersion); - printf("GOP Version : %lld.%lld.%lld\n", StDeviceAdapterProperties.firmware_version.major_version, StDeviceAdapterProperties.firmware_version.minor_version, - StDeviceAdapterProperties.firmware_version.build_number); - - printf("Intel Adapter Name: %s\n", StDeviceAdapterProperties.name); - printf("Vendor ID: 0x%X\n", StDeviceAdapterProperties.pci_vendor_id); - printf("Device ID: 0x%X\n", StDeviceAdapterProperties.pci_device_id); - printf("SubSys id 0x%X\n", StDeviceAdapterProperties.pci_subsys_id); - printf("SubSys Vendor id 0x%X\n", StDeviceAdapterProperties.pci_subsys_vendor_id); - printf("Rev ID: 0x%X\n", StDeviceAdapterProperties.rev_id); - printf("Graphics Frequency: %dMHz\n", StDeviceAdapterProperties.Frequency); - printf("num_eus_per_sub_slice: %d\n", StDeviceAdapterProperties.num_eus_per_sub_slice); - printf("num_slices: %d\n", StDeviceAdapterProperties.num_slices); - printf("num_sub_slices_per_slice: %d\n", StDeviceAdapterProperties.num_sub_slices_per_slice); - printf("Graphics HW type: %s\n", StDeviceAdapterProperties.graphics_adapter_properties & CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED ? "Integrated" : "External GFX"); - - if ((INVALID_ADAPTER_BDF == StDeviceAdapterProperties.adapter_bdf.bus) && (INVALID_ADAPTER_BDF == StDeviceAdapterProperties.adapter_bdf.device) && - (INVALID_ADAPTER_BDF == StDeviceAdapterProperties.adapter_bdf.function)) + printf("GOP Version : %lld.%lld.%lld\n", pStDeviceAdapterProperties->firmware_version.major_version, pStDeviceAdapterProperties->firmware_version.minor_version, + pStDeviceAdapterProperties->firmware_version.build_number); + + printf("Intel Adapter Name: %s\n", pStDeviceAdapterProperties->name); + printf("Vendor ID: 0x%X\n", pStDeviceAdapterProperties->pci_vendor_id); + printf("Device ID: 0x%X\n", pStDeviceAdapterProperties->pci_device_id); + printf("SubSys id 0x%X\n", pStDeviceAdapterProperties->pci_subsys_id); + printf("SubSys Vendor id 0x%X\n", pStDeviceAdapterProperties->pci_subsys_vendor_id); + printf("Rev ID: 0x%X\n", pStDeviceAdapterProperties->rev_id); + printf("Graphics Frequency: %dMHz\n", pStDeviceAdapterProperties->Frequency); + printf("num_eus_per_sub_slice: %d\n", pStDeviceAdapterProperties->num_eus_per_sub_slice); + printf("num_slices: %d\n", pStDeviceAdapterProperties->num_slices); + printf("num_sub_slices_per_slice: %d\n", pStDeviceAdapterProperties->num_sub_slices_per_slice); + printf("num_xe_cores: %d\n", pStDeviceAdapterProperties->num_xe_cores); + printf("Graphics HW type: %s\n", pStDeviceAdapterProperties->graphics_adapter_properties & CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED ? "Integrated" : "External GFX"); + + if ((INVALID_ADAPTER_BDF == pStDeviceAdapterProperties->adapter_bdf.bus) && (INVALID_ADAPTER_BDF == pStDeviceAdapterProperties->adapter_bdf.device) && + (INVALID_ADAPTER_BDF == pStDeviceAdapterProperties->adapter_bdf.function)) { printf("ctlGetDeviceProperties returned invalid adapter BDF.\n"); } else { - printf("adapter_bdf.bus:%d\n", StDeviceAdapterProperties.adapter_bdf.bus); - printf("adapter_bdf.device:%d\n", StDeviceAdapterProperties.adapter_bdf.device); - printf("adapter_bdf.function:%d\n", StDeviceAdapterProperties.adapter_bdf.function); + printf("adapter_bdf.bus:%d\n", pStDeviceAdapterProperties->adapter_bdf.bus); + printf("adapter_bdf.device:%d\n", pStDeviceAdapterProperties->adapter_bdf.device); + printf("adapter_bdf.function:%d\n", pStDeviceAdapterProperties->adapter_bdf.function); } } @@ -769,6 +798,148 @@ void PrintDetailsFromSysman(ctl_device_adapter_handle_t hDevice) return; } +ctl_result_t CtlAdapterTesting(ctl_device_adapter_handle_t *hDevices, uint32_t Adapter_count) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_output_handle_t *hDisplayOutput = nullptr; + ctl_device_adapter_properties_t StDeviceAdapterProperties = { 0 }; + + uint32_t Display_count = 0; + uint32_t Index = 0; + uint32_t Display_index = 0; + + LUID AdapterID; + StDeviceAdapterProperties.Size = sizeof(ctl_device_adapter_properties_t); + StDeviceAdapterProperties.pDeviceID = malloc(sizeof(LUID)); + StDeviceAdapterProperties.device_id_size = sizeof(LUID); + StDeviceAdapterProperties.Version = 3; + + for (Index = 0; Index < Adapter_count; Index++) + { + if (NULL != hDevices[Index]) + { + printf("\n\n*** Testing adapter #%d ***\n", Index); + + Result = ctlGetDeviceProperties(hDevices[Index], &StDeviceAdapterProperties); + + if (CTL_RESULT_ERROR_UNSUPPORTED_VERSION == Result) // reduce version if required & recheck + { + printf("ctlGetDeviceProperties() version mismatch - Reducing version to 0 and retrying\n"); + StDeviceAdapterProperties.Version = 0; + Result = ctlGetDeviceProperties(hDevices[Index], &StDeviceAdapterProperties); + } + + if (Result != CTL_RESULT_SUCCESS) + { + printf("ctlGetDeviceProperties returned failure code: 0x%X\n", Result); + continue; + } + + if (CTL_DEVICE_TYPE_GRAPHICS != StDeviceAdapterProperties.device_type) + { + printf("This is not a Graphics device \n"); + continue; + } + + if (NULL != StDeviceAdapterProperties.pDeviceID) + { + AdapterID = *(reinterpret_cast(StDeviceAdapterProperties.pDeviceID)); + std::cout << "Adapter ID " << AdapterID.LowPart << "\n"; + } + + if (0x8086 != StDeviceAdapterProperties.pci_vendor_id) + continue; + + PrintAdapterProperties(&StDeviceAdapterProperties); + + // get max/P0 from L0 & print the same here + try + { + PrintDetailsFromSysman(hDevices[Index]); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } + + // enumerate all the possible target display's for the adapters + // first step is to get the count + Display_count = 0; + Result = ctlEnumerateDisplayOutputs(hDevices[Index], &Display_count, hDisplayOutput); + + printf("ctlEnumerateDisplayOutputs returned %d encoders\n", Display_count); + + if (CTL_RESULT_SUCCESS == Result && (Display_count > 0)) + { + hDisplayOutput = (ctl_display_output_handle_t *)malloc(sizeof(ctl_display_output_handle_t) * Display_count); + if (NULL == hDisplayOutput) + { + return CTL_RESULT_ERROR_UNKNOWN; + } + Result = ctlEnumerateDisplayOutputs(hDevices[Index], &Display_count, hDisplayOutput); + } + + if (Result != CTL_RESULT_SUCCESS) + { + printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + STORE_RESET_ERROR(Result); + } + + // get display encoder properties + if (CTL_RESULT_SUCCESS == Result && hDisplayOutput) + { + GetDisplayEncoderPropertiesTest(hDisplayOutput, &Result, Display_count); + } + + // get display properties + if (CTL_RESULT_SUCCESS == Result && hDisplayOutput) + { + GetDisplayPropertiesTest(hDevices, hDisplayOutput, &Result, Index, Display_count); + } + + // Sharpness Test + if (CTL_RESULT_SUCCESS == Result) + { + if (nullptr == hDisplayOutput) + return CTL_RESULT_ERROR_UNKNOWN; + + for (Display_index = 0; Display_index < Display_count; Display_index++) + { + Result = CtlSharpnessTest(hDisplayOutput[Display_index]); + STORE_RESET_ERROR(Result); + } + } + + // get 3D global properties + if (CTL_RESULT_SUCCESS == Result) + { + try + { + Result = CtlGet3DGlobalTest(hDevices[Index]); + STORE_RESET_ERROR(Result); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } + } + } + if (hDisplayOutput != nullptr) + { + free(hDisplayOutput); + hDisplayOutput = nullptr; + } + } + + if (StDeviceAdapterProperties.pDeviceID != nullptr) + { + free(StDeviceAdapterProperties.pDeviceID); + StDeviceAdapterProperties.pDeviceID = nullptr; + } + + return Result; +} + /*************************************************************** * @brief Main Function * @@ -799,7 +970,15 @@ int main() // Init App UID appropriately ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { @@ -808,7 +987,15 @@ int main() // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { @@ -817,16 +1004,23 @@ int main() { return ERROR; } - Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } if (CTL_RESULT_SUCCESS != Result) { printf("ctlEnumerateDevices returned failure code: 0x%X\n", Result); - goto free_exit; + goto Exit; } printf("ctlEnumerateDevices returned %d adapters\n", Adapter_count); - LUID AdapterID; StDeviceAdapterProperties.Size = sizeof(ctl_device_adapter_properties_t); StDeviceAdapterProperties.pDeviceID = malloc(sizeof(LUID)); StDeviceAdapterProperties.device_id_size = sizeof(LUID); @@ -838,108 +1032,24 @@ int main() } // test an additional caller from same process - CtlTestAdditionalCaller(); - - for (Index = 0; Index < Adapter_count; Index++) + try { - if (NULL != hDevices[Index]) - { - printf("\n\n*** Testing adapter #%d ***\n", Index); - - Result = ctlGetDeviceProperties(hDevices[Index], &StDeviceAdapterProperties); - - if (CTL_RESULT_ERROR_UNSUPPORTED_VERSION == Result) // reduce version if required & recheck - { - printf("ctlGetDeviceProperties() version mismatch - Reducing version to 0 and retrying\n"); - StDeviceAdapterProperties.Version = 0; - Result = ctlGetDeviceProperties(hDevices[Index], &StDeviceAdapterProperties); - } - - if (Result != CTL_RESULT_SUCCESS) - { - printf("ctlGetDeviceProperties returned failure code: 0x%X\n", Result); - continue; - } - - if (CTL_DEVICE_TYPE_GRAPHICS != StDeviceAdapterProperties.device_type) - { - printf("This is not a Graphics device \n"); - continue; - } - - if (NULL != StDeviceAdapterProperties.pDeviceID) - { - AdapterID = *(reinterpret_cast(StDeviceAdapterProperties.pDeviceID)); - std::cout << "Adapter ID " << AdapterID.LowPart << "\n"; - } - - if (0x8086 != StDeviceAdapterProperties.pci_vendor_id) - continue; - - PrintAdapterProperties(StDeviceAdapterProperties); - - // get max/P0 from L0 & print the same here - PrintDetailsFromSysman(hDevices[Index]); - - // enumerate all the possible target display's for the adapters - // first step is to get the count - Display_count = 0; - Result = ctlEnumerateDisplayOutputs(hDevices[Index], &Display_count, hDisplayOutput); - - printf("ctlEnumerateDisplayOutputs returned %d encoders\n", Display_count); - - if (CTL_RESULT_SUCCESS == Result && (Display_count > 0)) - { - hDisplayOutput = (ctl_display_output_handle_t *)malloc(sizeof(ctl_display_output_handle_t) * Display_count); - Result = ctlEnumerateDisplayOutputs(hDevices[Index], &Display_count, hDisplayOutput); - } - - if (Result != CTL_RESULT_SUCCESS) - { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); - STORE_RESET_ERROR(Result); - } - - // get display encoder properties - if (CTL_RESULT_SUCCESS == Result && hDisplayOutput) - { - GetDisplayEncoderPropertiesTest(hDisplayOutput, &Result, Display_count); - } - - // get display properties - if (CTL_RESULT_SUCCESS == Result && hDisplayOutput) - { - GetDisplayPropertiesTest(hDevices, hDisplayOutput, &Result, Index, Display_count); - } - -#ifdef TEST_ENABLE_SETCALLS - // Sharpness Test - if (CTL_RESULT_SUCCESS == Result) - { - if (nullptr == hDisplayOutput) - return ERROR; - - for (Display_index = 0; Display_index < Display_count; Display_index++) - { - Result = CtlSharpnessTest(hDisplayOutput[Display_index]); - STORE_RESET_ERROR(Result); - } - } -#endif + CtlTestAdditionalCaller(); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } - // get 3D global properties - if (CTL_RESULT_SUCCESS == Result) - { - Result = CtlGet3DGlobalTest(hDevices[Index]); - STORE_RESET_ERROR(Result); - } - } - if (hDisplayOutput != nullptr) - { - free(hDisplayOutput); - hDisplayOutput = nullptr; - } + try + { + CtlAdapterTesting(hDevices, Adapter_count); + } + catch (const std::ios_base::failure &e) + { + printf("%s \n", e.what()); } + #ifdef _ZE_DDI_H // test level0 handle if ((CTL_RESULT_SUCCESS == Result) && (Adapter_count > 0)) @@ -965,7 +1075,7 @@ int main() { STORE_RESET_ERROR(Result); } -free_exit: +Exit: if (NULL != StDeviceAdapterProperties.pDeviceID) { @@ -975,17 +1085,8 @@ int main() ctlClose(hAPIHandle); - if (hDisplayOutput != nullptr) - { - free(hDisplayOutput); - hDisplayOutput = nullptr; - } - - if (hDevices != nullptr) - { - free(hDevices); - hDevices = nullptr; - } + CTL_FREE_MEM(hDisplayOutput); + CTL_FREE_MEM(hDevices); printf("Overrall test result is 0x%X\n", GResult); return GResult; diff --git a/Samples/I2C_AUX_Samples/CMakeLists.txt b/Samples/I2C_AUX_Samples/CMakeLists.txt index efce49d..c21b579 100644 --- a/Samples/I2C_AUX_Samples/CMakeLists.txt +++ b/Samples/I2C_AUX_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME I2C_AUX_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(I2C_AUX_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/I2C_AUX_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/I2C_AUX_Samples/I2C_AUX_Sample_App.cpp b/Samples/I2C_AUX_Samples/I2C_AUX_Sample_App.cpp index 98763f5..5a382c4 100644 --- a/Samples/I2C_AUX_Samples/I2C_AUX_Sample_App.cpp +++ b/Samples/I2C_AUX_Samples/I2C_AUX_Sample_App.cpp @@ -39,7 +39,7 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) ctl_aux_access_args_t AUXArgs = { 0 }; // AUX Access WRITE ctl_i2c_access_args_t I2CArgs = { 0 }; // I2C Access - printf("Aux Read Test.\n"); + APP_LOG_INFO("Aux Read Test."); AUXArgs.Size = sizeof(ctl_aux_access_args_t); AUXArgs.OpType = CTL_OPERATION_TYPE_WRITE; @@ -52,7 +52,7 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlAUXAccess for Native Aux DPCD WRITE returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlAUXAccess for Native Aux DPCD WRITE returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -69,7 +69,7 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlAUXAccess for Native Aux DPCD Read returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlAUXAccess for Native Aux DPCD Read returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } else @@ -77,11 +77,11 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) // Print the data for (uint32_t j = 0; j < AUXArgs.DataSize; j++) { - printf("Read data[%d] = : 0x%X\n", j, AUXArgs.Data[j]); + APP_LOG_INFO("Read data[%d] = : 0x%X", j, AUXArgs.Data[j]); } } - printf("I2C Write Test.\n"); + APP_LOG_INFO("I2C Write Test."); // I2C WRITE : 82 01 10 AC at adddress 6E and subaddress 51 // If we write these BYTEs ( 82 01 10 AC) to adddress 6E and @@ -112,10 +112,10 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlI2CAccess for I2C write returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlI2CAccess for I2C write returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } - printf("I2C Read Test.\n"); + APP_LOG_INFO("I2C Read Test."); // I2C READ : 82 01 10 AC at adddress 6E and subaddress 51 I2CArgs.Size = sizeof(ctl_i2c_access_args_t); I2CArgs.OpType = CTL_OPERATION_TYPE_READ; @@ -130,7 +130,7 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) // Print the data for (uint32_t j = 0; j < I2CArgs.DataSize; j++) { - printf("Read data[%d] = : 0x%X\n", j, I2CArgs.Data[j]); + APP_LOG_INFO("Read data[%d] = : 0x%X", j, I2CArgs.Data[j]); } Exit: @@ -138,6 +138,211 @@ ctl_result_t TestI2CAUXAccess(ctl_display_output_handle_t hDisplayOutput) return Result; } +/*************************************************************** + * @brief TestI2CAccessWithDriverOverrideFlagsForMultipleReadTransactions + * Reference code to show how to use the I2C driver flags for multiple read transactions for HDMI displays + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestI2CAccessWithDriverOverrideFlagsForMultipleReadTransactions(ctl_display_output_handle_t hDisplayOutput) +{ +#define READ_DATA_SIZE 11 // the total read data size to +#define READ_SIZE_LIMIT 2 // the read data size limit for each I2C read transaction + + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_i2c_access_args_t I2CArgs = { 0 }; // I2C Access + uint32_t ReadDataLeft = 0; + uint32_t ReadDataSent = 0; + uint32_t ReadDataSizeLimit = 0; + bool IsFirstReadTransaction = TRUE; + + // I2C WRITE : 82 01 10 AC at address 6E and subaddress 51 + // If we write these BYTEs ( 82 01 10 AC) to address 6E and + // subaddress 51, it should update the current brightness to the 10th + // byte at address 6E and subaddress 51. One can verify by changing + // panel brightness from panel buttons, writing to address 6E + // and subaddress 51 ( 82 01 10 AC), and then reading 10th byte at + // address 6E and subaddress 51. Here is an example of an 11 byte output: + // 6E 88 02 00 10 00 00 64 00 19 D9. The 10th byte value is the current brightness value of the + // panel. To confirm whether this value is correct or not, convert the Hex + // value to Decimal. In this example, the 10th byte is 0x19, which represents 25% panel brightness. + I2CArgs.Size = sizeof(ctl_i2c_access_args_t); + I2CArgs.OpType = CTL_OPERATION_TYPE_WRITE; + I2CArgs.Address = 0x6E; // Address used for demonstration purpose + I2CArgs.Offset = 0x51; // Offset used for demonstration purpose + I2CArgs.DataSize = 4; + I2CArgs.Data[0] = 0x82; + I2CArgs.Data[1] = 0x01; + I2CArgs.Data[2] = 0x10; + I2CArgs.Data[3] = 0xAC; + + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + APP_LOG_INFO("I2C Write Test using I2C driver override flags for multiple read transactions"); + + Result = ctlI2CAccess(hDisplayOutput, &I2CArgs); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("ctlI2CAccess for I2C write returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + } + + // I2C READ : 82 01 10 AC at address 6E and subaddress 51 + APP_LOG_INFO("I2C Read Transaction Test using I2C driver override flags for multiple read transactions"); + + ZeroMemory(&I2CArgs, sizeof(I2CArgs)); + I2CArgs.Size = sizeof(ctl_i2c_access_args_t); + I2CArgs.OpType = CTL_OPERATION_TYPE_READ; + I2CArgs.Address = 0x6E; // Address used for demonstration purpose + I2CArgs.Offset = 0x51; // Offset used for demonstration purpose + I2CArgs.DataSize = READ_SIZE_LIMIT; + + I2CArgs.Flags |= CTL_I2C_FLAG_DRIVER_OVERRIDE; // must be enabled to use the driver override I2C flags + I2CArgs.Flags |= CTL_I2C_FLAG_SPEED_BIT_BASH; // bit bash flag is required for driver override feature + + ReadDataLeft = READ_DATA_SIZE; + ReadDataSizeLimit = READ_SIZE_LIMIT; + ReadDataSent = 0; + IsFirstReadTransaction = TRUE; + + for (uint32_t i = 0; ReadDataLeft > 0; i++) + { + I2CArgs.Offset = ReadDataSent; + + if (TRUE == IsFirstReadTransaction) + { + if (ReadDataLeft <= ReadDataSizeLimit) // single read transaction: enable start and stop + { + APP_LOG_INFO("Single Transaction"); + I2CArgs.DataSize = ReadDataLeft; + I2CArgs.Flags |= CTL_I2C_FLAG_START; + I2CArgs.Flags |= CTL_I2C_FLAG_STOP; + } + else // first read transaction: enable start, disable stop + { + APP_LOG_INFO("First Transaction: %i", i + 1); + I2CArgs.DataSize = ReadDataSizeLimit; + I2CArgs.Flags |= CTL_I2C_FLAG_START; + I2CArgs.Flags &= ~CTL_I2C_FLAG_STOP; + } + + IsFirstReadTransaction = FALSE; + } + else + { + if (ReadDataLeft <= ReadDataSizeLimit) // last read transaction: disable start, enable stop + { + APP_LOG_INFO("Last Transaction: %i", i + 1); + I2CArgs.DataSize = ReadDataLeft; + I2CArgs.Flags &= ~CTL_I2C_FLAG_START; + I2CArgs.Flags |= CTL_I2C_FLAG_STOP; + } + else // middle range read transaction: disable start and stop + { + APP_LOG_INFO("Middle Range Transaction: %i", i + 1); + I2CArgs.Flags &= ~CTL_I2C_FLAG_START; + I2CArgs.Flags &= ~CTL_I2C_FLAG_STOP; + } + } + + memset(I2CArgs.Data, 0xFF, I2CArgs.DataSize); // Clear the data buffer before reading + + Result = ctlI2CAccess(hDisplayOutput, &I2CArgs); + LOG_AND_EXIT_ON_ERROR(Result, "ctlI2CAccess for I2C Read Transaction Test using I2C driver override flags"); + + // Print the data + for (uint32_t j = 0; j < I2CArgs.DataSize; j++) + { + APP_LOG_INFO("Read data[%d] = : 0x%X", j, I2CArgs.Data[j]); + } + + ReadDataSent += I2CArgs.DataSize; + ReadDataLeft -= I2CArgs.DataSize; + } + +Exit: + return Result; +} + +/*************************************************************** + * @brief TestI2CAccessWithRestartDriverOverrideFlag + * Reference code to show how to use the I2C Restart driver override flag for HDMI displays + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestI2CAccessWithRestartDriverOverrideFlag(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_i2c_access_args_t I2CArgs = { 0 }; // I2C Access + + // I2C WRITE : 82 01 10 AC at address 6E and subaddress 51 + // If we write these BYTEs ( 82 01 10 AC) to address 6E and + // subaddress 51, it should update the current brightness to the 10th + // byte at address 6E and subaddress 51. One can verify by changing + // panel brightness from panel buttons, writing to address 6E + // and subaddress 51 ( 82 01 10 AC), and then reading 10th byte at + // address 6E and subaddress 51. Here is an example of an 11 byte output: + // 6E 88 02 00 10 00 00 64 00 19 D9. The 10th byte value is the current brightness value of the + // panel. To confirm whether this value is correct or not, convert the Hex + // value to Decimal. In this example, the 10th byte is 0x19, which represents 25% panel brightness. + I2CArgs.Size = sizeof(ctl_i2c_access_args_t); + I2CArgs.OpType = CTL_OPERATION_TYPE_WRITE; + I2CArgs.Address = 0x6E; // Address used for demonstration purpose + I2CArgs.Offset = 0x51; // Offset used for demonstration purpose + I2CArgs.DataSize = 4; + I2CArgs.Data[0] = 0x82; + I2CArgs.Data[1] = 0x01; + I2CArgs.Data[2] = 0x10; + I2CArgs.Data[3] = 0xAC; + + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + APP_LOG_INFO("I2C Write Test using I2C Restart driver override flag for read"); + + I2CArgs.Flags |= CTL_I2C_FLAG_DRIVER_OVERRIDE; // must be enabled to use the driver override I2C flags + I2CArgs.Flags |= CTL_I2C_FLAG_SPEED_BIT_BASH; // bit bash flag is required for driver override feature + I2CArgs.Flags |= CTL_I2C_FLAG_START; // enable start flag for the write operation + + Result = ctlI2CAccess(hDisplayOutput, &I2CArgs); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("ctlI2CAccess for I2C write returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + } + + // I2C READ : 82 01 10 AC at address 6E and subaddress 51 + APP_LOG_INFO("I2C Read Transaction Test using I2C Restart driver override flag for read"); + + ZeroMemory(&I2CArgs, sizeof(I2CArgs)); + I2CArgs.Size = sizeof(ctl_i2c_access_args_t); + I2CArgs.OpType = CTL_OPERATION_TYPE_READ; + I2CArgs.Address = 0x6E; // Address used for demonstration purpose + I2CArgs.Offset = 0x51; // Offset used for demonstration purpose + I2CArgs.DataSize = 11; + + // Perform I2C repeated start transaction for read by enabling Restart flag + I2CArgs.Flags |= CTL_I2C_FLAG_DRIVER_OVERRIDE; // must be enabled to use the driver override I2C flags + I2CArgs.Flags |= CTL_I2C_FLAG_SPEED_BIT_BASH; // bit bash flag is required for driver override feature + I2CArgs.Flags |= CTL_I2C_FLAG_RESTART; // enable restart flag for the read operation + I2CArgs.Flags |= CTL_I2C_FLAG_STOP; // issue a stop after the read operation is completed + + memset(I2CArgs.Data, 0xFF, I2CArgs.DataSize); // Clear the data buffer before reading + + Result = ctlI2CAccess(hDisplayOutput, &I2CArgs); + LOG_AND_EXIT_ON_ERROR(Result, "ctlI2CAccess for I2C read with Restart flag"); + + // Print the data + for (uint32_t j = 0; j < I2CArgs.DataSize; j++) + { + APP_LOG_INFO("Read data[%d] = : 0x%X", j, I2CArgs.Data[j]); + } + +Exit: + return Result; +} + /*************************************************************** * @brief Tests I2C Access on enumerated Pin Pairs. * Reference code to use ctlI2CAccessOnPinPair API @@ -172,16 +377,16 @@ ctl_result_t TestI2CAUXAccessOnPinPair(ctl_i2c_pin_pair_handle_t hI2cPinPair) I2CArgs.Data[2] = 0x10; I2CArgs.Data[3] = 0xAC; - printf("I2C Write Test: Address %#x, Offset %#x, size %d.\n", I2CArgs.Address, I2CArgs.Offset, I2CArgs.DataSize); + APP_LOG_INFO("I2C Write Test: Address %#x, Offset %#x, size %d.", I2CArgs.Address, I2CArgs.Offset, I2CArgs.DataSize); Result = ctlI2CAccessOnPinPair(hI2cPinPair, &I2CArgs); if (CTL_RESULT_SUCCESS != Result) { - printf("I2C write returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("I2C write returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } else { - printf("I2C Write Test Success.\n"); + APP_LOG_INFO("I2C Write Test Success."); } ZeroMemory(&I2CArgs, sizeof(I2CArgs)); @@ -196,18 +401,18 @@ ctl_result_t TestI2CAUXAccessOnPinPair(ctl_i2c_pin_pair_handle_t hI2cPinPair) // I2CArgs.Flags |= CTL_I2C_FLAG_SPEED_BIT_BASH; // I2CArgs.Flags = CTL_I2C_FLAG_ATOMICI2C; // Need to set this to do Atomic I2C call - printf("I2C Read Test: Address %#X, Offset %#X, size %d, Flags %#X.\n", I2CArgs.Address, I2CArgs.Offset, I2CArgs.DataSize, I2CArgs.Flags); + APP_LOG_INFO("I2C Read Test: Address %#X, Offset %#X, size %d, Flags %#X.", I2CArgs.Address, I2CArgs.Offset, I2CArgs.DataSize, I2CArgs.Flags); Result = ctlI2CAccessOnPinPair(hI2cPinPair, &I2CArgs); LOG_AND_EXIT_ON_ERROR(Result, "ctlI2CAccessOnPinPair for I2C read"); // Print the data for (uint32_t j = 0; j < I2CArgs.DataSize; j++) { - printf("Read data[%d] = : 0x%X\n", j, I2CArgs.Data[j]); + APP_LOG_INFO("Read data[%d] = : 0x%X", j, I2CArgs.Data[j]); } Exit: - printf("\n-------------------------\n"); + PRINT_LOGS("-------------------------"); return Result; } @@ -226,7 +431,8 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput { ctl_display_properties_t DisplayProperties = { 0 }; DisplayProperties.Size = sizeof(ctl_display_properties_t); - printf("Display Handle: %p\n-------------------------\n", hDisplayOutput[DisplayIndex]); + APP_LOG_INFO("Display Handle: %p", hDisplayOutput[DisplayIndex]); + PRINT_LOGS("-------------------------"); Result = ctlGetDisplayProperties(hDisplayOutput[DisplayIndex], &DisplayProperties); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetDisplayProperties"); @@ -234,12 +440,28 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput if (FALSE == IsDisplayAttached) { - printf("Display %d is not attached, skipping the call for this display\n", DisplayIndex); + APP_LOG_WARN("Display %d is not attached, skipping the call for this display", DisplayIndex); continue; } Result = TestI2CAUXAccess(hDisplayOutput[DisplayIndex]); STORE_AND_RESET_ERROR(Result); + + ctl_adapter_display_encoder_properties_t stDisplayEncoderProperties = {}; + stDisplayEncoderProperties.Size = sizeof(ctl_adapter_display_encoder_properties_t); + + Result = ctlGetAdaperDisplayEncoderProperties(hDisplayOutput[DisplayIndex], &stDisplayEncoderProperties); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetAdaperDisplayEncoderProperties"); + + // Currently the driver override flags are limited to HDMI only + if (CTL_DISPLAY_OUTPUT_TYPES_HDMI == stDisplayEncoderProperties.Type) + { + Result = TestI2CAccessWithDriverOverrideFlagsForMultipleReadTransactions(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + + Result = TestI2CAccessWithRestartDriverOverrideFlag(hDisplayOutput[DisplayIndex]); + STORE_AND_RESET_ERROR(Result); + } } Exit: @@ -257,7 +479,8 @@ ctl_result_t TestI2cAccessOnEmumeratedPinPairs(ctl_i2c_pin_pair_handle_t *hI2cPi ctl_result_t Result = CTL_RESULT_SUCCESS; for (uint32_t Index = 0; Index < PinPairCount; Index++) { - printf("I2CAccessOnPinPair Test for Pin Pair[%d] handle: %p\n-------------------------\n", Index, hI2cPinPair[Index]); + APP_LOG_INFO("I2CAccessOnPinPair Test for Pin Pair[%d] handle: %p", Index, hI2cPinPair[Index]); + PRINT_LOGS("-------------------------"); Result = TestI2CAUXAccessOnPinPair(hI2cPinPair[Index]); STORE_AND_RESET_ERROR(Result); } @@ -279,7 +502,8 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) { - printf("Adapter Handle: %p\n===============================\n", hDevices[AdapterIndex]); + APP_LOG_INFO("Adapter Handle: %p", hDevices[AdapterIndex]); + PRINT_LOGS("==============================="); // enumerate all the possible target display's for the adapters // first step is to get the count @@ -289,13 +513,13 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); continue; } @@ -306,7 +530,7 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -316,7 +540,7 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateDisplayHandles returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateDisplayHandles returned failure code: 0x%X", Result); } CTL_FREE_MEM(hDisplayOutput); @@ -342,7 +566,8 @@ ctl_result_t EnumerateI2CDevices(uint32_t AdapterCount, ctl_device_adapter_handl for (uint32_t AdapterIndex = 0; AdapterIndex < AdapterCount; AdapterIndex++) { - printf("\nI2C Access Test For Adapter[%d] handle: %p\n===========================\n", AdapterIndex, hDevices[AdapterIndex]); + APP_LOG_INFO("I2C Access Test For Adapter[%d] handle: %p", AdapterIndex, hDevices[AdapterIndex]); + PRINT_LOGS("==========================="); // enumerate all the possible target display's for the adapters // first step is to get the count PinCount = 0; @@ -351,13 +576,13 @@ ctl_result_t EnumerateI2CDevices(uint32_t AdapterCount, ctl_device_adapter_handl if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateI2CPinPairs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlEnumerateI2CPinPairs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (PinCount <= 0) { - printf("Invalid Display Count. skipping pin pair enumration for adapter:%d\n", AdapterIndex); + APP_LOG_ERROR("Invalid Display Count. skipping pin pair enumration for adapter:%d", AdapterIndex); continue; } @@ -368,7 +593,7 @@ ctl_result_t EnumerateI2CDevices(uint32_t AdapterCount, ctl_device_adapter_handl if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateI2CPinPairs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlEnumerateI2CPinPairs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -378,7 +603,7 @@ ctl_result_t EnumerateI2CDevices(uint32_t AdapterCount, ctl_device_adapter_handl if (CTL_RESULT_SUCCESS != Result) { - printf("TestI2cAccessOnEmumeratedPinPairs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("TestI2cAccessOnEmumeratedPinPairs returned failure code: 0x%X", Result); } CTL_FREE_MEM(hI2cPinPair); @@ -413,32 +638,53 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = EnumerateTargetDisplays(AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateTargetDisplays returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } #if 0 // Keeping the call disabled as not needed for regular Display use cases. Mainly intended for non-display devices. Result = EnumerateI2CDevices(AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateI2CDevices returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateI2CDevices returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } #endif @@ -446,7 +692,7 @@ int main() ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/IntelArcSync/CMakeLists.txt b/Samples/IntelArcSync/CMakeLists.txt index cfdaf48..e6339bb 100644 --- a/Samples/IntelArcSync/CMakeLists.txt +++ b/Samples/IntelArcSync/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME IntelArcSync) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(IntelArcSync VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/IntelArcSync_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/IntelArcSync/IntelArcSync_App.cpp b/Samples/IntelArcSync/IntelArcSync_App.cpp index 89b46dc..6318a1f 100644 --- a/Samples/IntelArcSync/IntelArcSync_App.cpp +++ b/Samples/IntelArcSync/IntelArcSync_App.cpp @@ -591,11 +591,25 @@ int main(int argc, char *pArgv[]) if ("caps" == SubOption) { - GetIntelArcSyncCaps(); + try + { + GetIntelArcSyncCaps(); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } else if ("profile" == SubOption) { - GetIntelArcSyncProfileDetails(); + try + { + GetIntelArcSyncProfileDetails(); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } else if ("profile-names" == SubOption) { @@ -639,11 +653,25 @@ int main(int argc, char *pArgv[]) sscanf_s(pArgv[5], "%f", &MaxRr); sscanf_s(pArgv[6], "%d", &SfditValue); sscanf_s(pArgv[7], "%d", &SfddtValue); - SetIntelArcSyncProfile(pArgv[3], MinRr, MaxRr, SfditValue, SfddtValue); + try + { + SetIntelArcSyncProfile(pArgv[3], MinRr, MaxRr, SfditValue, SfddtValue); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } else { - SetIntelArcSyncProfile(pArgv[3], 0, 0, 0, 0); + try + { + SetIntelArcSyncProfile(pArgv[3], 0, 0, 0, 0); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } } else diff --git a/Samples/Media_Samples/CMakeLists.txt b/Samples/Media_Samples/CMakeLists.txt index 0ecfa82..eec053c 100644 --- a/Samples/Media_Samples/CMakeLists.txt +++ b/Samples/Media_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Media_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Media_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Media_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Media_Samples/Media_Sample_App.cpp b/Samples/Media_Samples/Media_Sample_App.cpp index 77d21a1..8d1cec4 100644 --- a/Samples/Media_Samples/Media_Sample_App.cpp +++ b/Samples/Media_Samples/Media_Sample_App.cpp @@ -23,6 +23,7 @@ #define CTL_APIEXPORT // caller of control API DLL shall define this before // including igcl_api.h #include "igcl_api.h" +#include "GenericIGCLApp.h" ctl_result_t GResult = CTL_RESULT_SUCCESS; #define STORE_RESET_ERROR(Result) \ @@ -966,14 +967,30 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { @@ -981,14 +998,22 @@ int main() if (hDevices == NULL) { GResult = CTL_RESULT_ERROR_INVALID_NULL_POINTER; - goto free_exit; + goto Exit; + } + try + { + Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); } - Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); } if (CTL_RESULT_SUCCESS != Result) { printf("ctlEnumerateDevices returned failure code: 0x%X\n", Result); - goto free_exit; + goto Exit; } for (Index = 0; Index < Adapter_count; Index++) @@ -1028,17 +1053,17 @@ int main() if (NULL != StDeviceAdapterProperties.pDeviceID) { AdapterID = *(reinterpret_cast(StDeviceAdapterProperties.pDeviceID)); - std::cout << "Adapter ID " << AdapterID.LowPart << "\n"; + printf(" Adapter ID %lu\n", AdapterID.LowPart); } if (0x8086 == StDeviceAdapterProperties.pci_vendor_id) { - std::cout << "Intel Adapter Name " << StDeviceAdapterProperties.name << "\n"; - std::cout << "Vendor id " << StDeviceAdapterProperties.pci_vendor_id << "\n"; - std::cout << "Device id " << StDeviceAdapterProperties.pci_device_id << "\n"; - std::cout << "SubSys id " << StDeviceAdapterProperties.pci_subsys_id << "\n"; - std::cout << "SubSys Vendor id " << StDeviceAdapterProperties.pci_subsys_vendor_id << "\n"; - std::cout << "Rev id " << StDeviceAdapterProperties.rev_id << "\n"; + printf(" Intel Adapter Name %s\n", StDeviceAdapterProperties.name); + printf("Vendor id 0x%X\n", StDeviceAdapterProperties.pci_vendor_id); + printf("Device id: 0x%X\n", StDeviceAdapterProperties.pci_device_id); + printf("SubSys id 0x%X\n", StDeviceAdapterProperties.pci_subsys_id); + printf("SubSys Vendor id 0x%X\n", StDeviceAdapterProperties.pci_subsys_vendor_id); + printf("Rev id: 0x%X\n", StDeviceAdapterProperties.rev_id); } // get media properties @@ -1059,7 +1084,6 @@ int main() if (NULL != StDeviceAdapterProperties.pDeviceID) { free(StDeviceAdapterProperties.pDeviceID); - StDeviceAdapterProperties.pDeviceID = NULL; } } } @@ -1069,7 +1093,7 @@ int main() STORE_RESET_ERROR(Result); } -free_exit: +Exit: ctlClose(hAPIHandle); diff --git a/Samples/Overclocking_Sample/CMakeLists.txt b/Samples/Overclocking_Sample/CMakeLists.txt index 7603ccf..331fa10 100644 --- a/Samples/Overclocking_Sample/CMakeLists.txt +++ b/Samples/Overclocking_Sample/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Overclocking_Sample) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Overclocking_Sample VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Sample_OverclockAPP.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Overclocking_Sample/README.md b/Samples/Overclocking_Sample/README.md index b3c7097..9e05a42 100644 --- a/Samples/Overclocking_Sample/README.md +++ b/Samples/Overclocking_Sample/README.md @@ -1 +1 @@ -Sample Application for the Overclocking interface \ No newline at end of file +Sample Application for the Overclocking interface with Overclocking V2 APIs \ No newline at end of file diff --git a/Samples/Overclocking_Sample/Sample_OverclockAPP.cpp b/Samples/Overclocking_Sample/Sample_OverclockAPP.cpp index f83a841..39918ec 100644 --- a/Samples/Overclocking_Sample/Sample_OverclockAPP.cpp +++ b/Samples/Overclocking_Sample/Sample_OverclockAPP.cpp @@ -22,16 +22,10 @@ #include #include #include - -#include #include - -#include -#include #include "igcl_api.h" #include "GenericIGCLApp.h" - -std::string DecodeRetCode(ctl_result_t Res); +#include void OverclockProperties(ctl_device_adapter_handle_t hDAhandle); void OverclockFrequencyOffset(ctl_device_adapter_handle_t hDAhandle); @@ -39,163 +33,124 @@ void OverclockVoltageOffset(ctl_device_adapter_handle_t hDAhandle); void OverclockLockFrequency(ctl_device_adapter_handle_t hDAhandle); void OverclockPowerLimit(ctl_device_adapter_handle_t hDAhandle); void OverclockTemperatureLimit(ctl_device_adapter_handle_t hDAhandle); +void OverclockVramMemSpeedLimit(ctl_device_adapter_handle_t hDAhandle); +void OverclockVFCurveReadWrite(ctl_device_adapter_handle_t hDAhandle); void OverclockPowerTelemetry(ctl_device_adapter_handle_t hDAhandle); -const char *printType(ctl_data_type_t Type) +std::string DecodeCtlDataType(ctl_data_type_t Type) { - switch (Type) + static const std::map dataTypeStringMap = { { CTL_DATA_TYPE_INT8, "INT8" }, + { CTL_DATA_TYPE_UINT8, "UINT8" }, + { CTL_DATA_TYPE_INT16, "INT16" }, + { CTL_DATA_TYPE_UINT16, "UINT16" }, + { CTL_DATA_TYPE_INT32, "INT32" }, + { CTL_DATA_TYPE_UINT32, "UINT32" }, + { CTL_DATA_TYPE_INT64, "INT64" }, + { CTL_DATA_TYPE_UINT64, "UINT64" }, + { CTL_DATA_TYPE_FLOAT, "FLOAT" }, + { CTL_DATA_TYPE_DOUBLE, "DOUBLE" }, + { CTL_DATA_TYPE_STRING_ASCII, "STRING_ASCII" }, + { CTL_DATA_TYPE_STRING_UTF16, "STRING_UTF16" }, + { CTL_DATA_TYPE_STRING_UTF132, "STRING_UTF132" } }; + + auto it = dataTypeStringMap.find(Type); + if (it != dataTypeStringMap.end()) { - case ctl_data_type_t::CTL_DATA_TYPE_INT8: - { - return "CTL_DATA_TYPE_INT8"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT8: - { - return "CTL_DATA_TYPE_UINT8"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_INT16: - { - return "CTL_DATA_TYPE_INT16"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT16: - { - return "CTL_DATA_TYPE_UINT16"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_INT32: - { - return "CTL_DATA_TYPE_INT32"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT32: - { - return "CTL_DATA_TYPE_UINT32"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_INT64: - { - return "CTL_DATA_TYPE_INT64"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT64: - { - return "CTL_DATA_TYPE_UINT64"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_FLOAT: - { - return "CTL_DATA_TYPE_FLOAT"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_DOUBLE: - { - return "CTL_DATA_TYPE_DOUBLE"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_STRING_ASCII: - { - return "CTL_DATA_TYPE_STRING_ASCII"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_STRING_UTF16: - { - return "CTL_DATA_TYPE_STRING_UTF16"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_STRING_UTF132: - { - return "CTL_DATA_TYPE_STRING_UTF132"; - } - break; - default: - return "Unknown units"; + return it->second; } + return "Unknown datatype"; } -const char *printUnits(ctl_units_t Units) +std::string DecodeCtlUnits(ctl_units_t Units) { - switch (Units) + static const std::map unitsStringMap = { { CTL_UNITS_FREQUENCY_MHZ, "Frequency in MHz" }, + { CTL_UNITS_OPERATIONS_GTS, "GigaOperations per Second" }, + { CTL_UNITS_OPERATIONS_MTS, "MegaOperations per Second" }, + { CTL_UNITS_VOLTAGE_VOLTS, "Voltage in Volts" }, + { CTL_UNITS_POWER_WATTS, "Power in Watts" }, + { CTL_UNITS_TEMPERATURE_CELSIUS, "Temperature in Celsius" }, + { CTL_UNITS_ENERGY_JOULES, "Energy in Joules" }, + { CTL_UNITS_TIME_SECONDS, "Time in Seconds" }, + { CTL_UNITS_MEMORY_BYTES, "Memory in Bytes" }, + { CTL_UNITS_ANGULAR_SPEED_RPM, "Angular Speed in RPM" }, + { CTL_UNITS_POWER_MILLIWATTS, "Power in Milli Watts" }, + { CTL_UNITS_PERCENT, "Units in Percentage" }, + { CTL_UNITS_MEM_SPEED_GBPS, "Units in Gigabyte Per Second" }, + { CTL_UNITS_VOLTAGE_MILLIVOLTS, "Voltage in MilliVolts" }, + { CTL_UNITS_BANDWIDTH_MBPS, "Bandwidth in MegaBytes Per Second" } }; + + auto it = unitsStringMap.find(Units); + if (it != unitsStringMap.end()) { - case ctl_units_t::CTL_UNITS_FREQUENCY_MHZ: - { - return "Frequency in MHz"; - } - break; - case ctl_units_t::CTL_UNITS_OPERATIONS_GTS: - { - return "GigaOperations per Second"; - } - break; - case ctl_units_t::CTL_UNITS_OPERATIONS_MTS: - { - return "MegaOperations per Second"; - } - break; - case ctl_units_t::CTL_UNITS_VOLTAGE_VOLTS: - { - return "Voltage in Volts"; - } - break; - case ctl_units_t::CTL_UNITS_POWER_WATTS: - { - return "Power in Watts"; - } - break; - case ctl_units_t::CTL_UNITS_TEMPERATURE_CELSIUS: - { - return "Temperature in Celsius"; - } - break; - case ctl_units_t::CTL_UNITS_ENERGY_JOULES: - { - return "Energy in Joules"; - } - break; - case ctl_units_t::CTL_UNITS_TIME_SECONDS: - { - return "Time in Seconds"; - } - break; - case ctl_units_t::CTL_UNITS_MEMORY_BYTES: - { - return "Memory in Bytes"; - } - break; - case ctl_units_t::CTL_UNITS_ANGULAR_SPEED_RPM: - { - return "Angular Speed in RPM"; - } - break; - case ctl_units_t::CTL_UNITS_POWER_MILLIWATTS: - { - return "Power in Milli Watts"; - } - break; - case ctl_units_t::CTL_UNITS_PERCENT: - { - return "Units in Percentage"; - } - break; - case ctl_units_t::CTL_UNITS_MEM_SPEED_GBPS: - { - return "Units in Gigabyte Per Second"; - } - break; - case ctl_units_t::CTL_UNITS_VOLTAGE_MILLIVOLTS: - { - return "Voltage in MilliVolts"; - } - break; - default: - return "Unknown units"; + return it->second; + } + return "Unknown unit"; +} + +std::string DecodeVFCurveDetails(ctl_vf_curve_details_t VFCurveDetails) +{ + static const std::map vfCurveDetailsMap = { { CTL_VF_CURVE_DETAILS_SIMPLIFIED, "[CTL_VF_CURVE_DETAILS_SIMPLIFIED]" }, + { CTL_VF_CURVE_DETAILS_MEDIUM, "[CTL_VF_CURVE_DETAILS_MEDIUM]" }, + { CTL_VF_CURVE_DETAILS_ELABORATE, "[CTL_VF_CURVE_DETAILS_ELABORATE]" } }; + + auto it = vfCurveDetailsMap.find(VFCurveDetails); + if (it != vfCurveDetailsMap.end()) + { + return it->second; } + return "Unknown vfcurvedetails"; +} + +std::string DecodeBoolean(bool Value) +{ + return Value ? "true" : "false"; +} + +// Decoding the return code for the most common error codes. +std::string DecodeRetCode(ctl_result_t Res) +{ + static const std::map retCodeMap = { { CTL_RESULT_SUCCESS, "[CTL_RESULT_SUCCESS]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_GENERIC_START, "[CTL_RESULT_ERROR_GENERIC_START]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET]" }, + { CTL_RESULT_ERROR_NOT_INITIALIZED, "[CTL_RESULT_ERROR_NOT_INITIALIZED]" }, + { CTL_RESULT_ERROR_ALREADY_INITIALIZED, "[CTL_RESULT_ERROR_ALREADY_INITIALIZED]" }, + { CTL_RESULT_ERROR_DEVICE_LOST, "[CTL_RESULT_ERROR_DEVICE_LOST]" }, + { CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, "[CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS]" }, + { CTL_RESULT_ERROR_NOT_AVAILABLE, "[CTL_RESULT_ERROR_NOT_AVAILABLE]" }, + { CTL_RESULT_ERROR_UNINITIALIZED, "[CTL_RESULT_ERROR_UNINITIALIZED]" }, + { CTL_RESULT_ERROR_UNSUPPORTED_VERSION, "[CTL_RESULT_ERROR_UNSUPPORTED_VERSION]" }, + { CTL_RESULT_ERROR_UNSUPPORTED_FEATURE, "[CTL_RESULT_ERROR_UNSUPPORTED_FEATURE]" }, + { CTL_RESULT_ERROR_INVALID_ARGUMENT, "[CTL_RESULT_ERROR_INVALID_ARGUMENT]" }, + { CTL_RESULT_ERROR_INVALID_NULL_HANDLE, "[CTL_RESULT_ERROR_INVALID_NULL_HANDLE]" }, + { CTL_RESULT_ERROR_INVALID_NULL_POINTER, "[CTL_RESULT_ERROR_INVALID_NULL_POINTER]" }, + { CTL_RESULT_ERROR_INVALID_SIZE, "[CTL_RESULT_ERROR_INVALID_SIZE]" }, + { CTL_RESULT_ERROR_UNSUPPORTED_SIZE, "[CTL_RESULT_ERROR_UNSUPPORTED_SIZE]" }, + { CTL_RESULT_ERROR_NOT_IMPLEMENTED, "[CTL_RESULT_ERROR_NOT_IMPLEMENTED]" }, + { CTL_RESULT_ERROR_ZE_LOADER, "[CTL_RESULT_ERROR_ZE_LOADER]" }, + { CTL_RESULT_ERROR_INVALID_OPERATION_TYPE, "[CTL_RESULT_ERROR_INVALID_OPERATION_TYPE]" }, + { CTL_RESULT_ERROR_DATA_READ, "[CTL_RESULT_ERROR_DATA_READ]" }, + { CTL_RESULT_ERROR_DATA_WRITE, "[CTL_RESULT_ERROR_DATA_WRITE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_INVALID_CUSTOM_VF_CURVE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_INVALID_CUSTOM_VF_CURVE]" }, + { CTL_RESULT_ERROR_UNKNOWN, "[CTL_RESULT_ERROR_UNKNOWN]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_DEPRECATED_API, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_DEPRECATED_API]" } }; + + auto it = retCodeMap.find(Res); + if (it != retCodeMap.end()) + { + return it->second; + } + return "[Unknown Error]"; } /*************************************************************** - * @brief + * @brief OverclockProperties * Overclock Properties: The function ctlOverclockGetProperties * retrieves all the necessary information to populate a GUI. For * each property the following is provided: @@ -214,215 +169,237 @@ void OverclockProperties(ctl_device_adapter_handle_t hDAhandle) { ctl_oc_properties_t OcProperties = {}; OcProperties.Size = sizeof(ctl_oc_properties_t); + OcProperties.Version = 1; ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nError: %s", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockProperties => ctlOverclockGetProperties Error: %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); return; } // Is Overclocking supported by this adapter? - PRINT_LOGS("\nOc Supported? %s", OcProperties.bSupported ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Max: %f\n", OcProperties.gpuFrequencyOffset.max); + PRINT_LOGS("\nOc Supported? %s", DecodeBoolean(OcProperties.bSupported).c_str()); // Slider for frequency offset - PRINT_LOGS("\nGpu Frequency Offset Supported? %s ", OcProperties.gpuFrequencyOffset.bSupported ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Supported? %s", OcProperties.gpuFrequencyOffset.bSupported ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Is Relative? %s", OcProperties.gpuFrequencyOffset.bRelative ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Default: %f", OcProperties.gpuFrequencyOffset.Default); - PRINT_LOGS("\nGpu Frequency Offset Min: %f", OcProperties.gpuFrequencyOffset.min); - PRINT_LOGS("\nGpu Frequency Offset Max: %f", OcProperties.gpuFrequencyOffset.max); - PRINT_LOGS("\nGpu Frequency Offset Reference: %f", OcProperties.gpuFrequencyOffset.reference); - PRINT_LOGS("\nGpu Frequency Offset Step: %f", OcProperties.gpuFrequencyOffset.step); - PRINT_LOGS("\nGpu Frequency Offset Units:: %s\n", printUnits(OcProperties.gpuFrequencyOffset.units)); + PRINT_LOGS("\nGpu Frequency Offset Supported? %s ", DecodeBoolean(OcProperties.gpuFrequencyOffset.bSupported).c_str()); + PRINT_LOGS("\nGpu Frequency Offset Is Relative? %s", DecodeBoolean(OcProperties.gpuFrequencyOffset.bRelative).c_str()); + PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", DecodeBoolean(OcProperties.gpuFrequencyOffset.bReference).c_str()); + PRINT_LOGS("\nGpu Frequency Offset Default: %lf", OcProperties.gpuFrequencyOffset.Default); + PRINT_LOGS("\nGpu Frequency Offset Min: %lf", OcProperties.gpuFrequencyOffset.min); + PRINT_LOGS("\nGpu Frequency Offset Max: %lf", OcProperties.gpuFrequencyOffset.max); + PRINT_LOGS("\nGpu Frequency Offset Reference: %lf", OcProperties.gpuFrequencyOffset.reference); + PRINT_LOGS("\nGpu Frequency Offset Step: %lf", OcProperties.gpuFrequencyOffset.step); + PRINT_LOGS("\nGpu Frequency Offset Units:: %s\n", DecodeCtlUnits(OcProperties.gpuFrequencyOffset.units).c_str()); // Slider for voltage offset - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Voltage Offset Default: %f", OcProperties.gpuVoltageOffset.Default); - PRINT_LOGS("\n Gpu Voltage Offset Min : %f", OcProperties.gpuVoltageOffset.min); - PRINT_LOGS("\nGpu Voltage Offset Max: %f", OcProperties.gpuVoltageOffset.max); - PRINT_LOGS("\nGpu Voltage Offset Reference: %f", OcProperties.gpuVoltageOffset.reference); - PRINT_LOGS("\nGpu Voltage Offset Step: %f", OcProperties.gpuVoltageOffset.step); - PRINT_LOGS("\nGpu Voltage Offset Units: %s\n", printUnits(OcProperties.gpuVoltageOffset.units)); - - // Slider for VRAM frequency offset - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nVRAM Frequency Offset Default: %f", OcProperties.vramFrequencyOffset.Default); - PRINT_LOGS("\nVRAM Frequency Offset Min : %f", OcProperties.vramFrequencyOffset.min); - PRINT_LOGS("\nVRAM Frequency Offset Max: %f", OcProperties.vramFrequencyOffset.max); - PRINT_LOGS("\nVRAM Frequency Offset Reference: %f", OcProperties.vramFrequencyOffset.reference); - PRINT_LOGS("\nVRAM Frequency Offset Step: %f", OcProperties.vramFrequencyOffset.step); - PRINT_LOGS("\nVRAM Frequency Offset Units: %s\n", printUnits(OcProperties.vramFrequencyOffset.units)); - - // Slider for VRAM voltage offset - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nVRAM Voltage Offset Default: %f", OcProperties.vramVoltageOffset.Default); - PRINT_LOGS("\nVRAM Voltage Offset Min: %f", OcProperties.vramVoltageOffset.min); - PRINT_LOGS("\nVRAM Voltage Offset Max: %f", OcProperties.vramVoltageOffset.max); - PRINT_LOGS("\nVRAM Voltage Offset Reference : %f", OcProperties.vramVoltageOffset.reference); - PRINT_LOGS("\nVRAM Voltage Offset Step: %f", OcProperties.vramVoltageOffset.step); - PRINT_LOGS("\nVRAM Voltage Offset Units: %s\n", printUnits(OcProperties.vramVoltageOffset.units)); + PRINT_LOGS("\nGpu Voltage Offset Supported? %s ", DecodeBoolean(OcProperties.gpuVoltageOffset.bSupported).c_str()); + PRINT_LOGS("\nGpu Voltage Offset Is Relative? %s", DecodeBoolean(OcProperties.gpuVoltageOffset.bRelative).c_str()); + PRINT_LOGS("\nGpu Voltage Offset Have Reference? %s", DecodeBoolean(OcProperties.gpuVoltageOffset.bReference).c_str()); + PRINT_LOGS("\nGpu Voltage Offset Default: %lf", OcProperties.gpuVoltageOffset.Default); + PRINT_LOGS("\nGpu Voltage Offset Min : %lf", OcProperties.gpuVoltageOffset.min); + PRINT_LOGS("\nGpu Voltage Offset Max: %lf", OcProperties.gpuVoltageOffset.max); + PRINT_LOGS("\nGpu Voltage Offset Reference: %lf", OcProperties.gpuVoltageOffset.reference); + PRINT_LOGS("\nGpu Voltage Offset Step: %lf", OcProperties.gpuVoltageOffset.step); + PRINT_LOGS("\nGpu Voltage Offset Units: %s\n", DecodeCtlUnits(OcProperties.gpuVoltageOffset.units).c_str()); + + // Slider for VRAM Mem Speed Limit + PRINT_LOGS("\nVram Memory Speed Limit Supported? %s ", DecodeBoolean(OcProperties.vramMemSpeedLimit.bSupported).c_str()); + PRINT_LOGS("\nVram Memory Speed Limit Is Relative? %s", DecodeBoolean(OcProperties.vramMemSpeedLimit.bRelative).c_str()); + PRINT_LOGS("\nVram Memory Speed Limit Have Reference? %s", DecodeBoolean(OcProperties.vramMemSpeedLimit.bReference).c_str()); + PRINT_LOGS("\nVram Memory Speed Limit Default: %lf", OcProperties.vramMemSpeedLimit.Default); + PRINT_LOGS("\nVram Memory Speed Limit Min : %lf", OcProperties.vramMemSpeedLimit.min); + PRINT_LOGS("\nVram Memory Speed Limit Max: %lf", OcProperties.vramMemSpeedLimit.max); + PRINT_LOGS("\nVram Memory Speed Limit Reference: %lf", OcProperties.vramMemSpeedLimit.reference); + PRINT_LOGS("\nVram Memory Speed Limit Step: %lf", OcProperties.vramMemSpeedLimit.step); + PRINT_LOGS("\nVram Memory Speed Limit Units: %s\n", DecodeCtlUnits(OcProperties.vramMemSpeedLimit.units).c_str()); // Slider for Power Limit - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("G\npu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nPower Limit Default: %f", OcProperties.powerLimit.Default); - PRINT_LOGS("\nPower Limit Min: %f", OcProperties.powerLimit.min); - PRINT_LOGS("\nPower Limit Max: %f", OcProperties.powerLimit.max); - PRINT_LOGS("\nPower Limit Reference: %f", OcProperties.powerLimit.reference); - PRINT_LOGS("\nPower Limit Step: %f", OcProperties.powerLimit.step); - PRINT_LOGS("\nPower Limit Units: %s\n", printUnits(OcProperties.powerLimit.units)); + PRINT_LOGS("\nPower Limit Supported? %s ", DecodeBoolean(OcProperties.powerLimit.bSupported).c_str()); + PRINT_LOGS("\nPower Limit Is Relative? %s", DecodeBoolean(OcProperties.powerLimit.bRelative).c_str()); + PRINT_LOGS("\nPower Limit Have Reference? %s", DecodeBoolean(OcProperties.powerLimit.bReference).c_str()); + PRINT_LOGS("\nPower Limit Default: %lf", OcProperties.powerLimit.Default); + PRINT_LOGS("\nPower Limit Min: %lf", OcProperties.powerLimit.min); + PRINT_LOGS("\nPower Limit Max: %lf", OcProperties.powerLimit.max); + PRINT_LOGS("\nPower Limit Reference: %lf", OcProperties.powerLimit.reference); + PRINT_LOGS("\nPower Limit Step: %lf", OcProperties.powerLimit.step); + PRINT_LOGS("\nPower Limit Units: %s\n", DecodeCtlUnits(OcProperties.powerLimit.units).c_str()); // Slider for Temperature Limit - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", OcProperties.gpuFrequencyOffset.bReference ? "true" : "false"); - PRINT_LOGS("\nTemperature Limit Default: %f", OcProperties.temperatureLimit.Default); - PRINT_LOGS("\nTemperature Limit Min: %f", OcProperties.temperatureLimit.min); - PRINT_LOGS("\nTemperature Limit Max: %f", OcProperties.temperatureLimit.max); - PRINT_LOGS("\nTemperature Limit Reference: %f", OcProperties.temperatureLimit.reference); - PRINT_LOGS("\nTemperature Limit Step: %f", OcProperties.temperatureLimit.step); - PRINT_LOGS("\nTemperature Limit Units: %s\n \n", printUnits(OcProperties.temperatureLimit.units)); + PRINT_LOGS("\nTemperature Limit Supported? %s ", DecodeBoolean(OcProperties.temperatureLimit.bSupported).c_str()); + PRINT_LOGS("\nTemperature Limit Is Relative? %s", DecodeBoolean(OcProperties.temperatureLimit.bRelative).c_str()); + PRINT_LOGS("\nTemperature Limit Have Reference? %s", DecodeBoolean(OcProperties.temperatureLimit.bReference).c_str()); + PRINT_LOGS("\nTemperature Limit Default: %lf", OcProperties.temperatureLimit.Default); + PRINT_LOGS("\nTemperature Limit Min: %lf", OcProperties.temperatureLimit.min); + PRINT_LOGS("\nTemperature Limit Max: %lf", OcProperties.temperatureLimit.max); + PRINT_LOGS("\nTemperature Limit Reference: %lf", OcProperties.temperatureLimit.reference); + PRINT_LOGS("\nTemperature Limit Step: %lf", OcProperties.temperatureLimit.step); + PRINT_LOGS("\nTemperature Limit Units: %s\n", DecodeCtlUnits(OcProperties.temperatureLimit.units).c_str()); + + // Voltage Frequency Curve Property + PRINT_LOGS("\nVF Curve R/W Supported? %s ", DecodeBoolean(OcProperties.gpuVFCurveVoltageLimit.bSupported).c_str()); + PRINT_LOGS("\nVF Curve Voltage Axis Min: %lf", OcProperties.gpuVFCurveVoltageLimit.min); + PRINT_LOGS("\nVF Curve Voltage Axis Max: %lf", OcProperties.gpuVFCurveVoltageLimit.max); + PRINT_LOGS("\nVF Curve Voltage Axis Step: %lf", OcProperties.gpuVFCurveVoltageLimit.step); + PRINT_LOGS("\nVF Curve Voltage Axis Units: %s\n", DecodeCtlUnits(OcProperties.gpuVFCurveVoltageLimit.units).c_str()); + + PRINT_LOGS("\nVF Curve R/W Supported? %s ", DecodeBoolean(OcProperties.gpuVFCurveFrequencyLimit.bSupported).c_str()); + PRINT_LOGS("\nVF Curve Freq Axis Min: %lf", OcProperties.gpuVFCurveFrequencyLimit.min); + PRINT_LOGS("\nVF Curve Freq Axis Max: %lf", OcProperties.gpuVFCurveFrequencyLimit.max); + PRINT_LOGS("\nVF Curve Freq Axis Step: %lf", OcProperties.gpuVFCurveFrequencyLimit.step); + PRINT_LOGS("\nVF Curve Freq Axis Units: %s", DecodeCtlUnits(OcProperties.gpuVFCurveFrequencyLimit.units).c_str()); } /*************************************************************** - * @brief - * Overclock Frequency Offset: The function ctlOverclockGpuFrequencyOffsetSet + * @brief OverclockFrequencyOffset + * + * Overclock Frequency Offset: The function ctlOverclockGpuFrequencyOffsetSetV2 * allows to set a positive frequency offset. * @param * @return ***************************************************************/ void OverclockFrequencyOffset(ctl_device_adapter_handle_t hDAhandle) { - double GPUFrequencyOffset = 0.0; - - ctl_result_t Status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); + ctl_oc_properties_t OcProperties = {}; + OcProperties.Size = sizeof(ctl_oc_properties_t); + OcProperties.Version = 1; + // Step 1: Reading Overclock Properties + ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockFrequencyOffset => ctlOverclockGetProperties Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - PRINT_LOGS("\nCurrent Frequency Offset: %f MHz", GPUFrequencyOffset); - - // Setting 50 MHz Offset - GPUFrequencyOffset = 50.0; - - // Calling the waiver first - Status = ctlOverclockWaiverSet(hDAhandle); - + // Step 2: Reading Current Frequency Offset + // Output Frequency Offset units are returned in ctl_oc_properties_t::gpuFrequencyOffset::units returned from ctlOverclockGetProperties() + double GPUFrequencyOffset = 0.0; + Status = ctlOverclockGpuFrequencyOffsetGetV2(hDAhandle, &GPUFrequencyOffset); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockFrequencyOffset => ctlOverclockGpuFrequencyOffsetGetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\n\nCurrent Frequency Offset: %lf, %s", GPUFrequencyOffset, DecodeCtlUnits(OcProperties.gpuFrequencyOffset.units).c_str()); - // Setting the Offset - Status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); + // Step 3: Writing New Frequency Offset by increasing it by (Step * 5.0) MHz from min value + // Input Frequency Offset units are given in ctl_oc_properties_t::gpuFrequencyOffset::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::gpuFrequencyOffset::units for both Alchemist and Battlemage are CTL_UNITS_FREQUENCY_MHZ units + GPUFrequencyOffset = OcProperties.gpuFrequencyOffset.min + (OcProperties.gpuFrequencyOffset.step * 5.0); + Status = ctlOverclockGpuFrequencyOffsetSetV2(hDAhandle, GPUFrequencyOffset); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockFrequencyOffset => ctlOverclockGpuFrequencyOffsetSetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nSetting New Frequency Offset: %lf, %s", GPUFrequencyOffset, DecodeCtlUnits(OcProperties.gpuFrequencyOffset.units).c_str()); - // Reseting local var + // Step 4: Reading back New Frequency Offset + // Output Frequency Offset units are returned in ctl_oc_properties_t::gpuFrequencyOffset::units returned from ctlOverclockGetProperties() GPUFrequencyOffset = 0.0; - - // Read back to confirm the new value - Status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - + Status = ctlOverclockGpuFrequencyOffsetGetV2(hDAhandle, &GPUFrequencyOffset); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockFrequencyOffset => ctlOverclockGpuFrequencyOffsetGetV2 after setting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nReading New Frequency Offset: %lf, %s", GPUFrequencyOffset, DecodeCtlUnits(OcProperties.gpuFrequencyOffset.units).c_str()); - PRINT_LOGS("\nCurrent New Frequency Offset: %f MHz\n \n", GPUFrequencyOffset); - - // Setting the Offset to 0 - GPUFrequencyOffset = 0.0; - ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - -Exit: - return; + // Step 5: Resetting Frequency Offset + // Input Frequency Offset units are given in ctl_oc_properties_t::gpuFrequencyOffset::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::gpuFrequencyOffset::units for both Alchemist and Battlemage are CTL_UNITS_FREQUENCY_MHZ units + GPUFrequencyOffset = OcProperties.gpuFrequencyOffset.Default; + Status = ctlOverclockGpuFrequencyOffsetSetV2(hDAhandle, GPUFrequencyOffset); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockFrequencyOffset => ctlOverclockGpuFrequencyOffsetSetV2 after resetting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nResetting Frequency Offset to Default Value: %lf, %s", GPUFrequencyOffset, DecodeCtlUnits(OcProperties.gpuFrequencyOffset.units).c_str()); } /*************************************************************** - * @brief - * Overclock Voltage Offset: The function ctlOverclockGpuVoltageOffsetSet + * @brief OverclockVoltageOffset + * + * Overclock Voltage Offset: The function ctlOverclockGpuMaxVoltageOffsetSetV2 * allows to set a positive voltage offset. * @param * @return ***************************************************************/ void OverclockVoltageOffset(ctl_device_adapter_handle_t hDAhandle) { - double VoltageOffset = 0.0; - ctl_result_t Status = ctlOverclockGpuVoltageOffsetGet(hDAhandle, &VoltageOffset); + ctl_oc_properties_t OcProperties = {}; + OcProperties.Size = sizeof(ctl_oc_properties_t); + OcProperties.Version = 1; + // Step 1: Reading Overclock Properties + ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockVoltageOffset => ctlOverclockGetProperties Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - PRINT_LOGS("\n Current Voltage Offset: %f V", VoltageOffset); - - // Setting 25 mV Voltage Offset - VoltageOffset = 25; + // Step 2: Reading Current Voltage Offset + // Output Voltage Offset units are returned in ctl_oc_properties_t::gpuVoltageOffset::units returned from ctlOverclockGetProperties() + double VoltageOffset = 0.0; + Status = ctlOverclockGpuMaxVoltageOffsetGetV2(hDAhandle, &VoltageOffset); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVoltageOffset => ctlOverclockGpuMaxVoltageOffsetGetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\n\nCurrent Voltage Offset: %lf, %s", VoltageOffset, DecodeCtlUnits(OcProperties.gpuVoltageOffset.units).c_str()); - // Calling the waiver first + // Step 3: Calling Waiver Set first before writing the Voltage Offset Status = ctlOverclockWaiverSet(hDAhandle); - if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockVoltageOffset => ctlOverclockWaiverSet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nOverclock Waiver Set Succesfully for ctlOverclockGpuMaxVoltageOffsetSetV2 API !!"); - // Setting the Offset - Status = ctlOverclockGpuVoltageOffsetSet(hDAhandle, VoltageOffset); - + // Step 4: Writing New Voltage Offset by increasing it by (Step * 5.0) from min value + // Input Voltage Offset units are given in ctl_oc_properties_t::gpuVoltageOffset::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::gpuVoltageOffset::units for Alchemist are CTL_UNITS_VOLTAGE_VOLTS units, for Battlemage are CTL_UNITS_PERCENT units + VoltageOffset = OcProperties.gpuVoltageOffset.min + (OcProperties.gpuVoltageOffset.step * 5.0); + Status = ctlOverclockGpuMaxVoltageOffsetSetV2(hDAhandle, VoltageOffset); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockVoltageOffset => ctlOverclockGpuMaxVoltageOffsetSetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nSetting New Voltage Offset: %lf, %s", VoltageOffset, DecodeCtlUnits(OcProperties.gpuVoltageOffset.units).c_str()); - // Reseting local var + // Step 5: Reading back New Voltage Offset + // Output Voltage Offset units are returned in ctl_oc_properties_t::gpuVoltageOffset::units returned from ctlOverclockGetProperties() VoltageOffset = 0.0; - - // Read back to confirm the new value - Status = ctlOverclockGpuVoltageOffsetGet(hDAhandle, &VoltageOffset); - + Status = ctlOverclockGpuMaxVoltageOffsetGetV2(hDAhandle, &VoltageOffset); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockVoltageOffset => ctlOverclockGpuMaxVoltageOffsetGetV2 after setting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nReading New Voltage Offset: %lf %s", VoltageOffset, DecodeCtlUnits(OcProperties.gpuVoltageOffset.units).c_str()); - PRINT_LOGS("\nCurrent New Voltage Offset: %f\n \n", VoltageOffset); - - // Setting the Offset to 0 - VoltageOffset = 0.0; - ctlOverclockGpuVoltageOffsetSet(hDAhandle, VoltageOffset); - -Exit: - return; + // Step 6: Resetting Voltage Offset + // Input Voltage Offset units are given in ctl_oc_properties_t::gpuVoltageOffset::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::gpuVoltageOffset::units for Alchemist are CTL_UNITS_VOLTAGE_VOLTS units, for Battlemage are CTL_UNITS_PERCENT units + VoltageOffset = OcProperties.gpuVoltageOffset.Default; + Status = ctlOverclockGpuMaxVoltageOffsetSetV2(hDAhandle, VoltageOffset); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVoltageOffset => ctlOverclockGpuMaxVoltageOffsetSetV2 after resetting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nResetting Voltage Offset to Default Value: %lf, %s", VoltageOffset, DecodeCtlUnits(OcProperties.gpuVoltageOffset.units).c_str()); } /*************************************************************** - * @brief + * @brief OverclockLockFrequency * Overclock Lock Frequency: The function ctlOverclockGpuLockSet * allows to fix the frequency and voltage, useful for OC scanners * or performance testing. @@ -433,142 +410,145 @@ void OverclockLockFrequency(ctl_device_adapter_handle_t hDAhandle) { ctl_oc_properties_t OcProperties = {}; OcProperties.Size = sizeof(ctl_oc_properties_t); - ctl_oc_vf_pair_t VfPair = {}; + OcProperties.Version = 1; + // Step 1: Reading Overclock Properties ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); - if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockLockFrequency => ctlOverclockGetProperties Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - Status = ctlOverclockGpuLockGet(hDAhandle, &VfPair); - + // ctlOverclockGpuLockGet, ctlOverclockGpuLockSet APIs are only supported for Alchemist, not supported for Battlemage + // Step 2: Reading Current Locked OC VF Pair + ctl_oc_vf_pair_t VfPair = {}; + Status = ctlOverclockGpuLockGet(hDAhandle, &VfPair); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockLockFrequency => ctlOverclockGpuLockGet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nCurrent Locked OC VF Pair - Locked Frequency: %lf MHz, Locked Voltage: %lf mV", VfPair.Frequency, VfPair.Voltage); - PRINT_LOGS("\nCurrent Locked Frequency: %f MHz", VfPair.Frequency); - PRINT_LOGS("\nCurrent Locked Voltage: %f mV", VfPair.Voltage); + // Step 3: Calling Waiver Set first before writing the Locked OC VF Pair + Status = ctlOverclockWaiverSet(hDAhandle); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockLockFrequency => ctlOverclockWaiverSet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } - VfPair = {}; + // Step 3: Setting New Locked OC VF Pair // Set slighly more frequency and voltage // 50 MHz over reference frequency + VfPair = {}; VfPair.Frequency = OcProperties.gpuFrequencyOffset.reference + 50.0; // 50 mV over reference voltage. Convert to mV first. VfPair.Voltage = OcProperties.gpuVoltageOffset.reference * 1000.0 + 50.0; - - Status = ctlOverclockGpuLockSet(hDAhandle, VfPair); - + Status = ctlOverclockGpuLockSet(hDAhandle, VfPair); if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockLockFrequency => ctlOverclockGpuLockSet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nSetting New Locked OC VF Pair - Locked Frequency: %lf MHz, Locked Voltage: %lf mV", VfPair.Frequency, VfPair.Voltage); - // Reseting local var + // Step 4: Reading back New Locked OC VF Pair VfPair = {}; Status = ctlOverclockGpuLockGet(hDAhandle, &VfPair); - if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); - goto Exit; + PRINT_LOGS("\nOverclockLockFrequency => ctlOverclockGpuLockGet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nReading New Locked OC VF Pair - Locked Frequency: %lf MHz, Locked Voltage: %lf mV", VfPair.Frequency, VfPair.Voltage); - // Verifying the new locked frequency and voltage - PRINT_LOGS("\nNew Current Locked Frequency: %f MHz", VfPair.Frequency); - PRINT_LOGS("\nNew Current Locked Voltage: %f mV \n \n", VfPair.Voltage); - - // Reset to default + // Step 5: Resetting Locked OC VF Pair VfPair = {}; - ctlOverclockGpuLockSet(hDAhandle, VfPair); - -Exit: - return; + Status = ctlOverclockGpuLockSet(hDAhandle, VfPair); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockLockFrequency => ctlOverclockGpuLockSet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nResetting Locked OC VF Pair - Locked Frequency: %lf MHz, Locked Voltage: %lf mV", VfPair.Frequency, VfPair.Voltage); } -/*************************************************************** - * @brief Main Function +/***************************************************************** + * @brief OverclockPowerLimit * - * Overclock Power Limit: The function ctlOverclockPowerLimitSet - * allows to increase or decrease the power (TPD) budget for the + * Overclock Power Limit: The function ctlOverclockPowerLimitSetV2 + * allows to increase or decrease the power (TDP) budget for the * adapter. * @param * @return - ***************************************************************/ + *****************************************************************/ void OverclockPowerLimit(ctl_device_adapter_handle_t hDAhandle) { ctl_oc_properties_t OcProperties = {}; OcProperties.Size = sizeof(ctl_oc_properties_t); + OcProperties.Version = 1; + // Step 1: Reading Overclock Properties ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); - if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockPowerLimit => ctlOverclockGetProperties Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); return; } - PRINT_LOGS("\nGetting current Power Limit\n \n"); - + // Step 2: Reading Current Sustained Power Limit + // Output Sustained Power Limit units are returned in ctl_oc_properties_t::powerLimit::units returned from ctlOverclockGetProperties() double CurrentPowerLimit = 0.0; - - Status = ctlOverclockPowerLimitGet(hDAhandle, &CurrentPowerLimit); - - if (Status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nCurrent Sustained Power Limit: %f", CurrentPowerLimit); - } - else + Status = ctlOverclockPowerLimitGetV2(hDAhandle, &CurrentPowerLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockPowerLimit => ctlOverclockPowerLimitGetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\n\nCurrent Sustained Power Limit: %lf, %s", CurrentPowerLimit, DecodeCtlUnits(OcProperties.powerLimit.units).c_str()); - PRINT_LOGS("\nSetting current Power Limit inside limits: \n \n"); - - // Convert to mW and get min + 15 W. - CurrentPowerLimit = OcProperties.powerLimit.Default * 1000.0 + 15000.0; - - Status = ctlOverclockPowerLimitSet(hDAhandle, CurrentPowerLimit); - - if (Status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nPower Limit set correctly.\n \n"); - } - else + // Step 3: Writing New Sustained Power Limit by increasing it by (Step * 5.0) from min value + // Input Sustained Power Limit units are given in ctl_oc_properties_t::powerLimit::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::powerLimit::units for Alchemist are CTL_UNITS_POWER_WATTS units, for Battlemage are CTL_UNITS_PERCENT units + CurrentPowerLimit = OcProperties.powerLimit.min + (OcProperties.powerLimit.step * 5.0); + Status = ctlOverclockPowerLimitSetV2(hDAhandle, CurrentPowerLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockPowerLimit => ctlOverclockPowerLimitSetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nSetting New Sustained Power Limit: %lf, %s", CurrentPowerLimit, DecodeCtlUnits(OcProperties.powerLimit.units).c_str()); - PRINT_LOGS("\nGetting the now current Power Limit:\n \n"); - - double NewCurrentPowerLimit = 0.0; - - Status = ctlOverclockPowerLimitGet(hDAhandle, &NewCurrentPowerLimit); - - if (Status == ctl_result_t::CTL_RESULT_SUCCESS) + // Step 4: Reading back New Sustained Power Limit + // Output Sustained Power Limit units are returned in ctl_oc_properties_t::powerLimit::units returned from ctlOverclockGetProperties() + CurrentPowerLimit = 0.0; + Status = ctlOverclockPowerLimitGetV2(hDAhandle, &CurrentPowerLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nCurrent Sustained Power Limit: %f", NewCurrentPowerLimit); - PRINT_LOGS("\nRequested Sustained Power Limit: %f", CurrentPowerLimit); + PRINT_LOGS("\nOverclockPowerLimit => ctlOverclockPowerLimitGetV2 after setting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - else + PRINT_LOGS("\nReading New Sustained Power Limit: %lf, %s", CurrentPowerLimit, DecodeCtlUnits(OcProperties.powerLimit.units).c_str()); + + // Step 5: Resetting Sustained Power Limit + // Input Sustained Power Limit units are given in ctl_oc_properties_t::powerLimit::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::powerLimit::units for Alchemist are CTL_UNITS_POWER_WATTS units, for Battlemage are CTL_UNITS_PERCENT units + CurrentPowerLimit = OcProperties.powerLimit.Default; + Status = ctlOverclockPowerLimitSetV2(hDAhandle, CurrentPowerLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n \n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockPowerLimit => ctlOverclockPowerLimitSetV2 after resetting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - - // Reset to default - CurrentPowerLimit = OcProperties.powerLimit.Default * 1000.0; - ctlOverclockPowerLimitSet(hDAhandle, CurrentPowerLimit); + PRINT_LOGS("\nResetting Sustained Power Limit to Default Value: %lf %s", CurrentPowerLimit, DecodeCtlUnits(OcProperties.powerLimit.units).c_str()); } /*************************************************************** - * @brief Main Function + * @brief OverclockTemperatureLimit * - * Overclock Temperature Limit: The function ctlOverclockTemperatureLimitSet + * Overclock Temperature Limit: The function ctlOverclockTemperatureLimitSetV2 * allows to increase or decrease the temperature limit. If the temperature reaches * the limit, frequency will be throttled to be within the temperature limit. * adapter. @@ -579,68 +559,316 @@ void OverclockTemperatureLimit(ctl_device_adapter_handle_t hDAhandle) { ctl_oc_properties_t OcProperties = {}; OcProperties.Size = sizeof(ctl_oc_properties_t); - ctl_result_t Result = CTL_RESULT_SUCCESS; + OcProperties.Version = 1; + // Step 1: Reading Overclock Properties ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); - if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockTemperatureLimit => ctlOverclockGetProperties Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); return; } - PRINT_LOGS("\nGetting current Temperature Limit\n"); + // Step 2: Reading Current Temperature Limit + // Output Temperature Limit units are returned in ctl_oc_properties_t::temperatureLimit::units returned from ctlOverclockGetProperties() double CurrentTemperatureLimit = 0.0; + Status = ctlOverclockTemperatureLimitGetV2(hDAhandle, &CurrentTemperatureLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockTemperatureLimit => ctlOverclockTemperatureLimitGetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\n\nCurrent Temperature Limit: %lf, %s", CurrentTemperatureLimit, DecodeCtlUnits(OcProperties.temperatureLimit.units).c_str()); - Status = ctlOverclockTemperatureLimitGet(hDAhandle, &CurrentTemperatureLimit); + // Step 3: Writing New Temperature Limit by increasing it by (Step * 5.0) from min value + // Input Temperature Limit units are given in ctl_oc_properties_t::temperatureLimit::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::temperatureLimit::units for Alchemist and BMG G31 are CTL_UNITS_TEMPERATURE_CELSIUS units, for Battlemage (excluding G31) are CTL_UNITS_PERCENT units + CurrentTemperatureLimit = OcProperties.temperatureLimit.min + (OcProperties.temperatureLimit.step * 5.0); + Status = ctlOverclockTemperatureLimitSetV2(hDAhandle, CurrentTemperatureLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockTemperatureLimit => ctlOverclockTemperatureLimitSetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nSetting New Temperature Limit: %lf, %s", CurrentTemperatureLimit, DecodeCtlUnits(OcProperties.temperatureLimit.units).c_str()); - if (Status == ctl_result_t::CTL_RESULT_SUCCESS) + // Step 4: Reading back New Temperature Limit + // Output Temperature Limit units are returned in ctl_oc_properties_t::temperatureLimit::units returned from ctlOverclockGetProperties() + CurrentTemperatureLimit = 0.0; + Status = ctlOverclockTemperatureLimitGetV2(hDAhandle, &CurrentTemperatureLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nCurrent Temperature Limit: %f\n", CurrentTemperatureLimit); + PRINT_LOGS("\nOverclockTemperatureLimit => ctlOverclockTemperatureLimitGetV2 after setting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - else + PRINT_LOGS("\nReading New Temperature Limit: %lf, %s", CurrentTemperatureLimit, DecodeCtlUnits(OcProperties.temperatureLimit.units).c_str()); + + // Step 5: Resetting Temperature Limit + // Input Temperature Limit units are given in ctl_oc_properties_t::temperatureLimit::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::temperatureLimit::units for Alchemist are CTL_UNITS_TEMPERATURE_CELSIUS units, for Battlemage are CTL_UNITS_PERCENT units + CurrentTemperatureLimit = OcProperties.temperatureLimit.Default; + Status = ctlOverclockTemperatureLimitSetV2(hDAhandle, CurrentTemperatureLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockTemperatureLimit => ctlOverclockTemperatureLimitSetV2 after resetting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nResetting Temperature Limit to Default Value: %lf, %s", CurrentTemperatureLimit, DecodeCtlUnits(OcProperties.temperatureLimit.units).c_str()); +} - PRINT_LOGS("\nSetting current Temperature Limit \n \n"); +/*************************************************************** + * @brief OverclockVramMemSpeedLimit + * VramMemSpeedLimit Overclocking V2 APIs are only supported for Battlemage, not supported for Alchemist + * adapter. + * @param + * @return + ***************************************************************/ +void OverclockVramMemSpeedLimit(ctl_device_adapter_handle_t hDAhandle) +{ + ctl_oc_properties_t OcProperties = {}; + OcProperties.Size = sizeof(ctl_oc_properties_t); + OcProperties.Version = 1; - CurrentTemperatureLimit = OcProperties.temperatureLimit.Default + 5.0; + // Step 1: Reading Overclock Properties + ctl_result_t Status = ctlOverclockGetProperties(hDAhandle, &OcProperties); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVramMemSpeedLimit => ctlOverclockGetProperties Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } - Status = ctlOverclockTemperatureLimitSet(hDAhandle, CurrentTemperatureLimit); + // Below set of VramMemSpeedLimit Overclocking V2 APIs are only supported for Battlemage, not supported for Alchemist + // + // Step 2: Reading Current VramMemSpeed Limit + // Output VramMemSpeed Limit units are returned in ctl_oc_properties_t::vramMemSpeedLimit::units returned from ctlOverclockGetProperties() + double CurrentVramMemSpeedLimit = 0.0; + Status = ctlOverclockVramMemSpeedLimitGetV2(hDAhandle, &CurrentVramMemSpeedLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVramMemSpeedLimit => ctlOverclockVramMemSpeedLimitGetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\n\nCurrent VramMemSpeed Limit: %lf, %s", CurrentVramMemSpeedLimit, DecodeCtlUnits(OcProperties.vramMemSpeedLimit.units).c_str()); - if (Status == ctl_result_t::CTL_RESULT_SUCCESS) + // Step 3: Writing New VramMemSpeed Limit by increasing it by (Step * 5.0) Gbps from min value + // Input VramMemSpeed Limit units are given in ctl_oc_properties_t::vramMemSpeedLimit::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::vramMemSpeedLimit::units for Battlemage are CTL_UNITS_MEM_SPEED_GBPS units + CurrentVramMemSpeedLimit = OcProperties.vramMemSpeedLimit.min + (OcProperties.vramMemSpeedLimit.step * 5.0); + Status = ctlOverclockVramMemSpeedLimitSetV2(hDAhandle, CurrentVramMemSpeedLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nTemperature Limit set correctly.\n"); + PRINT_LOGS("\nOverclockVramMemSpeedLimit => ctlOverclockVramMemSpeedLimitSetV2 Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } - else + PRINT_LOGS("\nSetting New VramMemSpeed Limit: %lf, %s", CurrentVramMemSpeedLimit, DecodeCtlUnits(OcProperties.vramMemSpeedLimit.units).c_str()); + + // Step 4: Reading back New VramMemSpeed Limit + // Output VramMemSpeed Limit units are returned in ctl_oc_properties_t::vramMemSpeedLimit::units returned from ctlOverclockGetProperties() + CurrentVramMemSpeedLimit = 0.0; + Status = ctlOverclockVramMemSpeedLimitGetV2(hDAhandle, &CurrentVramMemSpeedLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s\n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockVramMemSpeedLimit => ctlOverclockVramMemSpeedLimitGetV2 after setting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; } + PRINT_LOGS("\nReading New VramMemSpeed Limit: %lf, %s", CurrentVramMemSpeedLimit, DecodeCtlUnits(OcProperties.vramMemSpeedLimit.units).c_str()); - PRINT_LOGS("\nGetting the now current Temperature Limit:\n \n"); + // Step 5: Resetting VramMemSpeed Limit + // Input VramMemSpeed Limit units are given in ctl_oc_properties_t::vramMemSpeedLimit::units returned from ctlOverclockGetProperties() + // Currently ctl_oc_properties_t::vramMemSpeedLimit::units for Battlemage are CTL_UNITS_MEM_SPEED_GBPS units + CurrentVramMemSpeedLimit = OcProperties.vramMemSpeedLimit.Default; + Status = ctlOverclockVramMemSpeedLimitSetV2(hDAhandle, CurrentVramMemSpeedLimit); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVramMemSpeedLimit => ctlOverclockVramMemSpeedLimitSetV2 after resetting, Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nResetting VramMemSpeed Limit to Default Value: %lf, %s", CurrentVramMemSpeedLimit, DecodeCtlUnits(OcProperties.vramMemSpeedLimit.units).c_str()); +} - double NewCurrentTemperatureLimit = 0.0; +/*************************************************************** + * @brief OverclockVFCurveReadWrite + * VFCurve Read/Write Overclocking V2 APIs are only supported for Battlemage, not supported for Alchemist + * adapter. + * @param + * @return + ***************************************************************/ +void OverclockVFCurveReadWrite(ctl_device_adapter_handle_t hDAhandle) +{ + ctl_vf_curve_type_t VFCurveType = CTL_VF_CURVE_TYPE_STOCK; + ctl_vf_curve_details_t VFCurveDetails = CTL_VF_CURVE_DETAILS_SIMPLIFIED; + uint32_t NumVFPoints = 0; + ctl_voltage_frequency_point_t *pVFCurveTable = NULL; + ctl_result_t Status = CTL_RESULT_SUCCESS; + + // Below set of VFCurve Read/Write Overclocking V2 APIs are only supported for Battlemage, not supported for Alchemist + + PRINT_LOGS("\n\n======================== OverclockVFCurveReadWrite ==============================="); + PRINT_LOGS("\n================================== STEP 1 ========================================"); + // Step 1: Read Stock VF Curve Points with VFCurveDetails as Simplified, Medium, Elaborate + VFCurveType = CTL_VF_CURVE_TYPE_STOCK; + for (uint32_t VFCurveDetailsIndex = CTL_VF_CURVE_DETAILS_SIMPLIFIED; VFCurveDetailsIndex < CTL_VF_CURVE_DETAILS_MAX; VFCurveDetailsIndex++) + { + NumVFPoints = 0; + VFCurveDetails = (ctl_vf_curve_details_t)VFCurveDetailsIndex; + Status = ctlOverclockReadVFCurve(hDAhandle, VFCurveType, VFCurveDetails, &NumVFPoints, nullptr); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 1, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + return; + } + else + { + PRINT_LOGS("\n\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 1, NumVFPoints: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), NumVFPoints); + pVFCurveTable = (ctl_voltage_frequency_point_t *)malloc(sizeof(ctl_voltage_frequency_point_t) * NumVFPoints); - Status = ctlOverclockTemperatureLimitGet(hDAhandle, &NewCurrentTemperatureLimit); + if (pVFCurveTable == NULL) + { + free(pVFCurveTable); + goto Exit; + } - if (Status == ctl_result_t::CTL_RESULT_SUCCESS) + Status = ctlOverclockReadVFCurve(hDAhandle, VFCurveType, VFCurveDetails, &NumVFPoints, pVFCurveTable); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + free(pVFCurveTable); + goto Exit; + } + for (uint32_t i = 0; i < NumVFPoints; i++) + { + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, VFPoint: %lu, Frequency: %lu, Voltage: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), i, + pVFCurveTable[i].Frequency, pVFCurveTable[i].Voltage); + } + free(pVFCurveTable); + } + } + + PRINT_LOGS("\n================================== STEP 2 ========================================"); + // Step 2.1: Calling Waiver Set first before calling ctlOverclockWriteCustomVFCurve + Status = ctlOverclockWaiverSet(hDAhandle); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => ctlOverclockWaiverSet Result: Error %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nOverclock Waiver Set Succesfully for ctlOverclockWriteCustomVFCurve API !!"); + + // Step 2.2: Modify few points in Stock Simplified VFCurveTable and perform VFCurveWrite + NumVFPoints = 0; + VFCurveType = CTL_VF_CURVE_TYPE_STOCK; + VFCurveDetails = CTL_VF_CURVE_DETAILS_SIMPLIFIED; + Status = ctlOverclockReadVFCurve(hDAhandle, VFCurveType, VFCurveDetails, &NumVFPoints, nullptr); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nCurrent Temperature Limit: %f", NewCurrentTemperatureLimit); - PRINT_LOGS("\nRequested Temperature Limit: %f", CurrentTemperatureLimit); + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 1, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + return; } else { - PRINT_LOGS("\nResult: Error %s\n \n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 1, NumVFPoints: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), NumVFPoints); + pVFCurveTable = (ctl_voltage_frequency_point_t *)malloc(sizeof(ctl_voltage_frequency_point_t) * NumVFPoints); + + if (pVFCurveTable == NULL) + { + free(pVFCurveTable); + goto Exit; + } + + Status = ctlOverclockReadVFCurve(hDAhandle, VFCurveType, VFCurveDetails, &NumVFPoints, pVFCurveTable); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + free(pVFCurveTable); + goto Exit; + } + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, Before modifying VFPoint 5, VFPoint 6", DecodeVFCurveDetails(VFCurveDetails).c_str()); + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, VFPoint: %lu, Frequency: %lu, Voltage: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), 5, + pVFCurveTable[5].Frequency, pVFCurveTable[5].Voltage); + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, VFPoint: %lu, Frequency: %lu, Voltage: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), 6, + pVFCurveTable[6].Frequency, pVFCurveTable[6].Voltage); + + pVFCurveTable[5].Frequency += 50; + pVFCurveTable[6].Frequency += 100; + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, After modifying VFPoint 5, VFPoint 6", DecodeVFCurveDetails(VFCurveDetails).c_str()); + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, VFPoint: %lu, Frequency: %lu, Voltage: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), 5, + pVFCurveTable[5].Frequency, pVFCurveTable[5].Voltage); + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockReadVFCurve Pass 2, VFPoint: %lu, Frequency: %lu, Voltage: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), 6, + pVFCurveTable[6].Frequency, pVFCurveTable[6].Voltage); + + Status = ctlOverclockWriteCustomVFCurve(hDAhandle, NumVFPoints, pVFCurveTable); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_STOCK, %s, ctlOverclockWriteCustomVFCurve, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + free(pVFCurveTable); + goto Exit; + } + free(pVFCurveTable); } - // Resetting to default - CurrentTemperatureLimit = OcProperties.temperatureLimit.Default; - ctlOverclockTemperatureLimitSet(hDAhandle, CurrentTemperatureLimit); + PRINT_LOGS("\n================================== STEP 3 ========================================"); + // Step 3: Read Live VF Curve Points with VFCurveDetails as Simplified, Medium, Elaborate + VFCurveType = CTL_VF_CURVE_TYPE_LIVE; + for (uint32_t VFCurveDetailsIndex = CTL_VF_CURVE_DETAILS_SIMPLIFIED; VFCurveDetailsIndex < CTL_VF_CURVE_DETAILS_MAX; VFCurveDetailsIndex++) + { + NumVFPoints = 0; + VFCurveDetails = (ctl_vf_curve_details_t)VFCurveDetailsIndex; + Status = ctlOverclockReadVFCurve(hDAhandle, VFCurveType, VFCurveDetails, &NumVFPoints, nullptr); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_LIVE, %s, ctlOverclockReadVFCurve Pass 1, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + return; + } + else + { + PRINT_LOGS("\n\nCTL_VF_CURVE_TYPE_LIVE, %s, ctlOverclockReadVFCurve Pass 1, NumVFPoints: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), NumVFPoints); + pVFCurveTable = (ctl_voltage_frequency_point_t *)malloc(sizeof(ctl_voltage_frequency_point_t) * NumVFPoints); + + if (pVFCurveTable == NULL) + { + free(pVFCurveTable); + goto Exit; + } + + Status = ctlOverclockReadVFCurve(hDAhandle, VFCurveType, VFCurveDetails, &NumVFPoints, pVFCurveTable); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => CTL_VF_CURVE_TYPE_LIVE, %s, ctlOverclockReadVFCurve Pass 2, Error: %s, ErrorCode: 0x%x", DecodeVFCurveDetails(VFCurveDetails).c_str(), + DecodeRetCode(Status).c_str(), Status); + free(pVFCurveTable); + goto Exit; + } + for (uint32_t i = 0; i < NumVFPoints; i++) + { + PRINT_LOGS("\nCTL_VF_CURVE_TYPE_LIVE, %s, ctlOverclockReadVFCurve Pass 2, VFPoint: %lu, Frequency: %lu, Voltage: %lu", DecodeVFCurveDetails(VFCurveDetails).c_str(), i, + pVFCurveTable[i].Frequency, pVFCurveTable[i].Voltage); + } + free(pVFCurveTable); + } + } + +Exit: + pVFCurveTable = nullptr; + + PRINT_LOGS("\n================================== STEP 4 ========================================"); + // Step 4: Reset all OC controls (FrequencyOffset, VoltageOffset, PowerLimit, TemperatureLimit, VramMemSpeedLimit including VFCurve) + Status = ctlOverclockResetToDefault(hDAhandle); + if (Status != ctl_result_t::CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nOverclockVFCurveReadWrite => ctlOverclockResetToDefault, Error: %s, ErrorCode: 0x%x", DecodeRetCode(Status).c_str(), Status); + return; + } + PRINT_LOGS("\nctlOverclockResetToDefault to reset all OC controls (FrequencyOffset, VoltageOffset, PowerLimit, TemperatureLimit, VramMemSpeedLimit including VFCurve) is successful !\n"); } /*************************************************************** - * @brief Main Function + * @brief OverclockPowerTelemetry * * Overclock Power Temeletry: The function ctlPowerTelemetryGet allows * to retrieve all the available metrics from the adapter in one @@ -652,6 +880,7 @@ void OverclockPowerTelemetry(ctl_device_adapter_handle_t hDAhandle) { ctl_power_telemetry_t pPowerTelemetry = {}; pPowerTelemetry.Size = sizeof(ctl_power_telemetry_t); + pPowerTelemetry.Version = 1; ctl_result_t Status = ctlPowerTelemetryGet(hDAhandle, &pPowerTelemetry); @@ -659,105 +888,174 @@ void OverclockPowerTelemetry(ctl_device_adapter_handle_t hDAhandle) { PRINT_LOGS("\nTelemetry Success\n \n"); - PRINT_LOGS("\nTimeStamp"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.timeStamp.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits %s", printUnits(pPowerTelemetry.timeStamp.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.timeStamp.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.timeStamp.value.datadouble); - - PRINT_LOGS("\nGpu Energy Counter:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.gpuEnergyCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits:%s", printUnits(pPowerTelemetry.gpuEnergyCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuEnergyCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.gpuEnergyCounter.value.datadouble); - - PRINT_LOGS("\nGpu Voltage:"); - PRINT_LOGS("\n Supported : %s", ((pPowerTelemetry.gpuVoltage.bSupported) ? " true " : " false ")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuVoltage.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuVoltage.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.gpuVoltage.value.datadouble); - - PRINT_LOGS("\nGpu Current Frequency:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.gpuCurrentClockFrequency.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuCurrentClockFrequency.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuCurrentClockFrequency.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.gpuCurrentClockFrequency.value.datadouble); - - PRINT_LOGS("\nGpu Current Temperature:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.gpuCurrentTemperature.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuCurrentTemperature.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuCurrentTemperature.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.gpuCurrentTemperature.value.datadouble); - - PRINT_LOGS("\nGpu Activity Counter:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.globalActivityCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.globalActivityCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.globalActivityCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.globalActivityCounter.value.datadouble); - - PRINT_LOGS("\nRender Activity Counter:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.renderComputeActivityCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.renderComputeActivityCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.renderComputeActivityCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.renderComputeActivityCounter.value.datadouble); - - PRINT_LOGS("\nMedia Activity Counter:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.mediaActivityCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.mediaActivityCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.mediaActivityCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.mediaActivityCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Energy Counter:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramEnergyCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramEnergyCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramEnergyCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.vramEnergyCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Voltage:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramVoltage.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramVoltage.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramVoltage.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.vramVoltage.value.datadouble); - - PRINT_LOGS("\nVRAM Frequency:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramCurrentClockFrequency.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramCurrentClockFrequency.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramCurrentClockFrequency.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.vramCurrentClockFrequency.value.datadouble); - - PRINT_LOGS("\nVRAM Effective Frequency:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramCurrentEffectiveFrequency.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramCurrentEffectiveFrequency.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramCurrentEffectiveFrequency.type)); - PRINT_LOGS("\nValue: %f \n", pPowerTelemetry.vramCurrentEffectiveFrequency.value.datadouble); - - PRINT_LOGS("\nVRAM Read Bandwidth:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramReadBandwidthCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramReadBandwidthCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramReadBandwidthCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.vramReadBandwidthCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Write Bandwidth:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramWriteBandwidthCounter.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramWriteBandwidthCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramWriteBandwidthCounter.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.vramWriteBandwidthCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Temperature:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.vramCurrentTemperature.bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramCurrentTemperature.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramCurrentTemperature.type)); - PRINT_LOGS("\nValue: %f\n", pPowerTelemetry.vramCurrentTemperature.value.datadouble); - - PRINT_LOGS("\nFan Speed:"); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", (pPowerTelemetry.fanSpeed[0].bSupported) ? "true" : "false"); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.fanSpeed[0].units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.fanSpeed[0].type)); - PRINT_LOGS("\nValue: %f \n \n", pPowerTelemetry.fanSpeed[0].value.datadouble); + if (pPowerTelemetry.timeStamp.bSupported) + { + PRINT_LOGS("\nTimeStamp: %f (%s) Datatype:(%s)", pPowerTelemetry.timeStamp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.timeStamp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.timeStamp.type).c_str()); + } + + if (pPowerTelemetry.gpuEnergyCounter.bSupported) + { + PRINT_LOGS("\nGpu Energy Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuEnergyCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuEnergyCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuEnergyCounter.type).c_str()); + } + + if (pPowerTelemetry.vramEnergyCounter.bSupported) + { + PRINT_LOGS("\nVRAM Energy Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.vramEnergyCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramEnergyCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramEnergyCounter.type).c_str()); + } + + if (pPowerTelemetry.totalCardEnergyCounter.bSupported) + { + PRINT_LOGS("\nCard Energy Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.totalCardEnergyCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.totalCardEnergyCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.totalCardEnergyCounter.type).c_str()); + } + + if (pPowerTelemetry.gpuVoltage.bSupported) + { + PRINT_LOGS("\nGpu Voltage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuVoltage.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuVoltage.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuVoltage.type).c_str()); + } + + if (pPowerTelemetry.gpuCurrentClockFrequency.bSupported) + { + PRINT_LOGS("\nGpu Current Frequency: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuCurrentClockFrequency.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.gpuCurrentClockFrequency.units).c_str(), DecodeCtlDataType(pPowerTelemetry.gpuCurrentClockFrequency.type).c_str()); + } + + if (pPowerTelemetry.gpuCurrentTemperature.bSupported) + { + PRINT_LOGS("\nGpu Current Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuCurrentTemperature.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuCurrentTemperature.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuCurrentTemperature.type).c_str()); + } + + if (pPowerTelemetry.globalActivityCounter.bSupported) + { + PRINT_LOGS("\nGpu Activity Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.globalActivityCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.globalActivityCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.globalActivityCounter.type).c_str()); + } + + if (pPowerTelemetry.renderComputeActivityCounter.bSupported) + { + PRINT_LOGS("\nRender Activity Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.renderComputeActivityCounter.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.renderComputeActivityCounter.units).c_str(), DecodeCtlDataType(pPowerTelemetry.renderComputeActivityCounter.type).c_str()); + } + + if (pPowerTelemetry.mediaActivityCounter.bSupported) + { + PRINT_LOGS("\nMedia Activity Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.mediaActivityCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.mediaActivityCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.mediaActivityCounter.type).c_str()); + } + + if (pPowerTelemetry.vramVoltage.bSupported) + { + PRINT_LOGS("\nVRAM Voltage: %f (%s) Datatype:(%s)", pPowerTelemetry.vramVoltage.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramVoltage.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramVoltage.type).c_str()); + } + + if (pPowerTelemetry.vramCurrentClockFrequency.bSupported) + { + PRINT_LOGS("\nVRAM Frequency: %f (%s) Datatype:(%s)", pPowerTelemetry.vramCurrentClockFrequency.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramCurrentClockFrequency.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramCurrentClockFrequency.type).c_str()); + } + + if (pPowerTelemetry.vramReadBandwidthCounter.bSupported) + { + PRINT_LOGS("\nVRAM Read Bandwidth Counter: %llu (%s) Datatype:(%s)", pPowerTelemetry.vramReadBandwidthCounter.value.datau64, + DecodeCtlUnits(pPowerTelemetry.vramReadBandwidthCounter.units).c_str(), DecodeCtlDataType(pPowerTelemetry.vramReadBandwidthCounter.type).c_str()); + } + + if (pPowerTelemetry.vramWriteBandwidthCounter.bSupported) + { + PRINT_LOGS("\nVRAM Write Bandwidth Counter: %llu (%s) Datatype:(%s)", pPowerTelemetry.vramWriteBandwidthCounter.value.datau64, + DecodeCtlUnits(pPowerTelemetry.vramWriteBandwidthCounter.units).c_str(), DecodeCtlDataType(pPowerTelemetry.vramWriteBandwidthCounter.type).c_str()); + } + + if (pPowerTelemetry.vramCurrentEffectiveFrequency.bSupported) + { + PRINT_LOGS("\nVRAM Effective Frequency: %f (%s) Datatype:(%s)", pPowerTelemetry.vramCurrentEffectiveFrequency.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.vramCurrentEffectiveFrequency.units).c_str(), DecodeCtlDataType(pPowerTelemetry.vramCurrentEffectiveFrequency.type).c_str()); + } + + if (pPowerTelemetry.vramCurrentTemperature.bSupported) + { + PRINT_LOGS("\nVRAM Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.vramCurrentTemperature.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramCurrentTemperature.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramCurrentTemperature.type).c_str()); + } + + if (pPowerTelemetry.vramReadBandwidth.bSupported) + { + PRINT_LOGS("\nVRAM Read Bandwidth: %f (%s) Datatype:(%s)", pPowerTelemetry.vramReadBandwidth.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramReadBandwidth.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramReadBandwidth.type).c_str()); + } + + if (pPowerTelemetry.vramWriteBandwidth.bSupported) + { + PRINT_LOGS("\nVRAM Write Bandwidth: %f (%s) Datatype:(%s)", pPowerTelemetry.vramWriteBandwidth.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramWriteBandwidth.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramWriteBandwidth.type).c_str()); + } + + if (pPowerTelemetry.gpuVrTemp.bSupported) + { + PRINT_LOGS("\nGPU VR Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuVrTemp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuVrTemp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuVrTemp.type).c_str()); + } + + if (pPowerTelemetry.vramVrTemp.bSupported) + { + PRINT_LOGS("\nVRAM VR Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.vramVrTemp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramVrTemp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramVrTemp.type).c_str()); + } + + if (pPowerTelemetry.saVrTemp.bSupported) + { + PRINT_LOGS("\nSA VR Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.saVrTemp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.saVrTemp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.saVrTemp.type).c_str()); + } + + if (pPowerTelemetry.gpuEffectiveClock.bSupported) + { + PRINT_LOGS("\nEffective frequency of the GPU: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuEffectiveClock.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuEffectiveClock.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuEffectiveClock.type).c_str()); + } + + if (pPowerTelemetry.gpuOverVoltagePercent.bSupported) + { + PRINT_LOGS("\nGPU Overvoltage Percentage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuOverVoltagePercent.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.gpuOverVoltagePercent.units).c_str(), DecodeCtlDataType(pPowerTelemetry.gpuOverVoltagePercent.type).c_str()); + } + + if (pPowerTelemetry.gpuPowerPercent.bSupported) + { + PRINT_LOGS("\nGPU Power Percentage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuPowerPercent.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuPowerPercent.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuPowerPercent.type).c_str()); + } + + if (pPowerTelemetry.gpuTemperaturePercent.bSupported) + { + PRINT_LOGS("\nGPU Temperature Percentage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuTemperaturePercent.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.gpuTemperaturePercent.units).c_str(), DecodeCtlDataType(pPowerTelemetry.gpuTemperaturePercent.type).c_str()); + } + + for (int i = 0; i < CTL_FAN_COUNT; i++) + { + if (pPowerTelemetry.fanSpeed[i].bSupported) + { + PRINT_LOGS("\nFan[%d] Speed: %f (%s) Datatype:(%s)", i, pPowerTelemetry.fanSpeed[i].value.datadouble, DecodeCtlUnits(pPowerTelemetry.fanSpeed[i].units).c_str(), + DecodeCtlDataType(pPowerTelemetry.fanSpeed[i].type).c_str()); + } + } + + PRINT_LOGS("\ngpuPowerLimited: %s", DecodeBoolean(pPowerTelemetry.gpuPowerLimited).c_str()); + PRINT_LOGS("\ngpuTemperatureLimited: %s", DecodeBoolean(pPowerTelemetry.gpuTemperatureLimited).c_str()); + PRINT_LOGS("\ngpuCurrentLimited: %s", DecodeBoolean(pPowerTelemetry.gpuCurrentLimited).c_str()); + PRINT_LOGS("\ngpuVoltageLimited: %s", DecodeBoolean(pPowerTelemetry.gpuVoltageLimited).c_str()); + PRINT_LOGS("\ngpuUtilizationLimited: %s", DecodeBoolean(pPowerTelemetry.gpuUtilizationLimited).c_str()); } else { - PRINT_LOGS("\nError: %s \n \n", DecodeRetCode(Status).c_str()); + PRINT_LOGS("\nOverclockPowerTelemetry => ctlPowerTelemetryGet Result Error: %s, ErrorCode: 0x%x \n \n", DecodeRetCode(Status).c_str(), Status); } } @@ -765,7 +1063,6 @@ int main() { ctl_result_t Result = CTL_RESULT_SUCCESS; ctl_device_adapter_handle_t *hDevices = nullptr; - ctl_display_output_handle_t *hDisplayOutput = nullptr; ctl_device_adapter_properties_t StDeviceAdapterProperties = { 0 }; ctl_init_args_t CtlInitArgs; ctl_api_handle_t hAPIHandle; @@ -781,13 +1078,29 @@ int main() CtlInitArgs.Version = 0; ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { @@ -798,7 +1111,15 @@ int main() goto Exit; } - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } if (CTL_RESULT_SUCCESS != Result) @@ -833,11 +1154,7 @@ int main() if (CTL_DEVICE_TYPE_GRAPHICS != StDeviceAdapterProperties.device_type) { PRINT_LOGS("This is not a Graphics device \n"); - - if (NULL != StDeviceAdapterProperties.pDeviceID) - { - free(StDeviceAdapterProperties.pDeviceID); - } + CTL_FREE_MEM(StDeviceAdapterProperties.pDeviceID); continue; } @@ -857,21 +1174,29 @@ int main() PRINT_LOGS("Rev id 0x%X\n", StDeviceAdapterProperties.rev_id); } - OverclockProperties(hDevices[Index]); - OverclockFrequencyOffset(hDevices[Index]); - OverclockVoltageOffset(hDevices[Index]); - OverclockLockFrequency(hDevices[Index]); - OverclockPowerLimit(hDevices[Index]); - OverclockTemperatureLimit(hDevices[Index]); - - // Telemetry - // Polling during 1 second at 100 ms - for (uint32_t i = 0; i < 10; i++) + try { - OverclockPowerTelemetry(hDevices[Index]); - Sleep(100); + OverclockProperties(hDevices[Index]); + OverclockFrequencyOffset(hDevices[Index]); + OverclockVoltageOffset(hDevices[Index]); + OverclockLockFrequency(hDevices[Index]); + OverclockPowerLimit(hDevices[Index]); + OverclockTemperatureLimit(hDevices[Index]); + OverclockVramMemSpeedLimit(hDevices[Index]); + OverclockVFCurveReadWrite(hDevices[Index]); + + // Telemetry + // Polling for 4 seconds with 200 ms sampling interval + for (uint32_t i = 0; i < 20; i++) + { + OverclockPowerTelemetry(hDevices[Index]); + Sleep(200); + } + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); } - CTL_FREE_MEM(StDeviceAdapterProperties.pDeviceID); } } @@ -879,131 +1204,7 @@ int main() Exit: - if (ctlClose(hAPIHandle) != ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nError: %s", DecodeRetCode(ctlClose(hAPIHandle)).c_str()); - return 0; - } - - CTL_FREE_MEM(hDisplayOutput); + ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); return 0; } - -// Decoding the return code for the most common error codes. -std::string DecodeRetCode(ctl_result_t Res) -{ - switch (Res) - { - case CTL_RESULT_SUCCESS: - { - return std::string("[CTL_RESULT_SUCCESS]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_GENERIC_START: - { - return std::string("[CTL_RESULT_ERROR_GENERIC_START]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET]"); - } - case CTL_RESULT_ERROR_NOT_INITIALIZED: - { - return std::string("[CTL_RESULT_ERROR_NOT_INITIALIZED]"); - } - case CTL_RESULT_ERROR_ALREADY_INITIALIZED: - { - return std::string("[CTL_RESULT_ERROR_ALREADY_INITIALIZED]"); - } - case CTL_RESULT_ERROR_DEVICE_LOST: - { - return std::string("[CTL_RESULT_ERROR_DEVICE_LOST]"); - } - case CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS: - { - return std::string("[CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS]"); - } - case CTL_RESULT_ERROR_NOT_AVAILABLE: - { - return std::string("[CTL_RESULT_ERROR_NOT_AVAILABLE]"); - } - case CTL_RESULT_ERROR_UNINITIALIZED: - { - return std::string("[CTL_RESULT_ERROR_UNINITIALIZED]"); - } - case CTL_RESULT_ERROR_UNSUPPORTED_VERSION: - { - return std::string("[CTL_RESULT_ERROR_UNSUPPORTED_VERSION]"); - } - case CTL_RESULT_ERROR_UNSUPPORTED_FEATURE: - { - return std::string("[CTL_RESULT_ERROR_UNSUPPORTED_FEATURE]"); - } - case CTL_RESULT_ERROR_INVALID_ARGUMENT: - { - return std::string("[CTL_RESULT_ERROR_INVALID_ARGUMENT]"); - } - case CTL_RESULT_ERROR_INVALID_NULL_HANDLE: - { - return std::string("[CTL_RESULT_ERROR_INVALID_NULL_HANDLE]"); - } - case CTL_RESULT_ERROR_INVALID_NULL_POINTER: - { - return std::string("[CTL_RESULT_ERROR_INVALID_NULL_POINTER]"); - } - case CTL_RESULT_ERROR_INVALID_SIZE: - { - return std::string("[CTL_RESULT_ERROR_INVALID_SIZE]"); - } - case CTL_RESULT_ERROR_UNSUPPORTED_SIZE: - { - return std::string("[CTL_RESULT_ERROR_UNSUPPORTED_SIZE]"); - } - case CTL_RESULT_ERROR_NOT_IMPLEMENTED: - { - return std::string("[CTL_RESULT_ERROR_NOT_IMPLEMENTED]"); - } - case CTL_RESULT_ERROR_ZE_LOADER: - { - return std::string("[CTL_RESULT_ERROR_ZE_LOADER]"); - } - case CTL_RESULT_ERROR_INVALID_OPERATION_TYPE: - { - return std::string("[CTL_RESULT_ERROR_INVALID_OPERATION_TYPE]"); - } - case CTL_RESULT_ERROR_UNKNOWN: - { - return std::string("[CTL_RESULT_ERROR_UNKNOWN]"); - } - default: - return std::string("[Unknown Error]"); - } -} \ No newline at end of file diff --git a/Samples/Panel_descriptor_Samples/CMakeLists.txt b/Samples/Panel_descriptor_Samples/CMakeLists.txt index 1fa2b74..4f1f3b0 100644 --- a/Samples/Panel_descriptor_Samples/CMakeLists.txt +++ b/Samples/Panel_descriptor_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Panel_descriptor_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Panel_descriptor_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Panel_descriptor_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Panel_descriptor_Samples/Panel_descriptor_Sample_App.cpp b/Samples/Panel_descriptor_Samples/Panel_descriptor_Sample_App.cpp index 71857cd..4481c98 100644 --- a/Samples/Panel_descriptor_Samples/Panel_descriptor_Sample_App.cpp +++ b/Samples/Panel_descriptor_Samples/Panel_descriptor_Sample_App.cpp @@ -43,7 +43,7 @@ ctl_result_t GetPanelDescriptor(ctl_display_output_handle_t hDisplayOutput, ctl_ // Print the descriptor data size DescriptorDataSize = pPanelDescArgs->DescriptorDataSize; - printf("DescriptorDataSize = : %d\n", DescriptorDataSize); + APP_LOG_INFO("DescriptorDataSize = : %d", DescriptorDataSize); // Once we have the size of the descriptor data, do another call to ctlPanelDescriptorAccess with DescriptorDataSize as the value derived from 1st ctlPanelDescriptorAccess // call. @@ -58,10 +58,13 @@ ctl_result_t GetPanelDescriptor(ctl_display_output_handle_t hDisplayOutput, ctl_ Result = ctlPanelDescriptorAccess(hDisplayOutput, pPanelDescArgs); LOG_AND_EXIT_ON_ERROR(Result, "ctlPanelDescriptorAccess"); - printf("Panel Descriptor Data: \n"); - for (uint32_t j = 0; j < pPanelDescArgs->DescriptorDataSize; j++) + APP_LOG_INFO("Panel Descriptor Data on block %d: ", pPanelDescArgs->BlockNumber); + for (uint32_t i = 0; i < pPanelDescArgs->DescriptorDataSize; i += 16) { - printf("[%d] = : 0x%X\n", j, pPanelDescArgs->pDescriptorData[j]); + for (uint32_t j = i; j < (i + 16); j++) + { + APP_LOG_INFO("0x%02X ", pPanelDescArgs->pDescriptorData[j]); + } } // EXTENSION BLOCKS READ : For EDID, Need to get the number of extensions blocks from 127th byte of base block @@ -69,7 +72,7 @@ ctl_result_t GetPanelDescriptor(ctl_display_output_handle_t hDisplayOutput, ctl_ if (0 == NumberOfExtnBlocks) { - printf("No Extn Block found \n"); + APP_LOG_ERROR("No Extn Block found "); goto Exit; } @@ -90,14 +93,14 @@ ctl_result_t GetPanelDescriptor(ctl_display_output_handle_t hDisplayOutput, ctl_ // Print the descriptor data size ExtBlockDescriptorDataSize = ExtBlockPanelDescArgs.DescriptorDataSize; - printf("DescriptorDataSize for extension block = : %d\n", ExtBlockDescriptorDataSize); + APP_LOG_INFO("DescriptorDataSize for extension block = : %d", ExtBlockDescriptorDataSize); // Once we have the size of the descriptor data, do another call to ctlPanelDescriptorAccess with DescriptorDataSize as the value derived from 1st // ctlPanelDescriptorAcces call. ExtBlockPanelDescArgs = { 0 }; ExtBlockPanelDescArgs.Size = sizeof(ctl_panel_descriptor_access_args_t); ExtBlockPanelDescArgs.OpType = CTL_OPERATION_TYPE_READ; // Currently only Read operation is supported. Write operationnot supported. - ExtBlockPanelDescArgs.BlockNumber = BlockIndex; // Block number + ExtBlockPanelDescArgs.BlockNumber = BlockIndex + 1; // Block number ExtBlockPanelDescArgs.DescriptorDataSize = ExtBlockDescriptorDataSize; ExtBlockPanelDescArgs.pDescriptorData = (uint8_t *)malloc(ExtBlockDescriptorDataSize * sizeof(uint8_t)); // Allocate memory for the descriptor data @@ -107,15 +110,18 @@ ctl_result_t GetPanelDescriptor(ctl_display_output_handle_t hDisplayOutput, ctl_ if (CTL_RESULT_SUCCESS != Result) { - printf("ctlPanelDescriptorAccess for extension block %d returned failure code: 0x%X\n", BlockIndex, Result); + APP_LOG_ERROR("ctlPanelDescriptorAccess for extension block %d returned failure code: 0x%X", BlockIndex, Result); CTL_FREE_MEM(ExtBlockPanelDescArgs.pDescriptorData); goto Exit; } - printf("Panel Descriptor Data: \n"); - for (uint32_t j = 0; j < pPanelDescArgs->DescriptorDataSize; j++) + APP_LOG_INFO("Panel Descriptor Data on block %d: ", ExtBlockPanelDescArgs.BlockNumber); + for (uint32_t i = 0; i < pPanelDescArgs->DescriptorDataSize; i += 16) { - printf("[%d] = : 0x%X\n", j, ExtBlockPanelDescArgs.pDescriptorData[j]); + for (uint32_t j = i; j < (i + 16); j++) + { + APP_LOG_INFO("0x%02X ", ExtBlockPanelDescArgs.pDescriptorData[j]); + } } CTL_FREE_MEM(ExtBlockPanelDescArgs.pDescriptorData); @@ -139,7 +145,7 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput if (0 == DisplayCount) { - printf("Invalid Display Count \n"); + APP_LOG_ERROR("Invalid Display Count "); goto Exit; } @@ -156,7 +162,7 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput if (FALSE == IsDisplayAttached) { - printf("Display %d is not attached, skipping the call for this display\n", DisplayIndex); + APP_LOG_WARN("Display %d is not attached, skipping the call for this display", DisplayIndex); continue; } @@ -203,13 +209,13 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); continue; } @@ -220,7 +226,7 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -230,7 +236,7 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateDisplayHandles returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateDisplayHandles returned failure code: 0x%X", Result); } CTL_FREE_MEM(hDisplayOutput); @@ -265,31 +271,52 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = EnumerateTargetDisplays(AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateTargetDisplays returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } Exit: ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } \ No newline at end of file diff --git a/Samples/Power_Feature_Samples/CMakeLists.txt b/Samples/Power_Feature_Samples/CMakeLists.txt index f2b4642..6c2eeec 100644 --- a/Samples/Power_Feature_Samples/CMakeLists.txt +++ b/Samples/Power_Feature_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Power_Feature_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Power_Feature_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/PowerFeature_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Power_Feature_Samples/PowerFeature_Sample_App.cpp b/Samples/Power_Feature_Samples/PowerFeature_Sample_App.cpp index 42cb4de..8c0cf3d 100644 --- a/Samples/Power_Feature_Samples/PowerFeature_Sample_App.cpp +++ b/Samples/Power_Feature_Samples/PowerFeature_Sample_App.cpp @@ -45,12 +45,15 @@ ctl_result_t TestPSRPowerFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_settings_t NewPowerSettings = { 0 }; PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_PSR; AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; AppliedPowerSettings.PowerOptimizationPlan = CTL_POWER_OPTIMIZATION_PLAN_BALANCED; NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_PSR; NewPowerSettings.Enable = TRUE; NewPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; @@ -62,12 +65,12 @@ ctl_result_t TestPSRPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (CTL_POWER_OPTIMIZATION_FLAG_PSR != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_PSR)) { - printf("PSR is not supported\n"); + APP_LOG_WARN("PSR is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } - printf("PSR is supported\n"); + APP_LOG_INFO("PSR is supported"); // Set Current PowerFeature Result = ctlSetPowerOptimizationSetting(hDisplayOutput, &NewPowerSettings); @@ -76,7 +79,7 @@ ctl_result_t TestPSRPowerFeature(ctl_display_output_handle_t hDisplayOutput) // Get Applied PowerFeature Result = ctlGetPowerOptimizationSetting(hDisplayOutput, &AppliedPowerSettings); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationSetting (PSR)"); - printf("PSR Enable = %d\n", AppliedPowerSettings.Enable); + APP_LOG_INFO("PSR Enable = %d", AppliedPowerSettings.Enable); Exit: return Result; @@ -96,7 +99,9 @@ ctl_result_t TestDPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_caps_t PowerCaps = { 0 }; PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; AppliedPowerSettings.PowerOptimizationPlan = CTL_POWER_OPTIMIZATION_PLAN_BALANCED; @@ -106,7 +111,7 @@ ctl_result_t TestDPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (CTL_POWER_OPTIMIZATION_FLAG_DPST != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_DPST)) { - printf("DPST is not supported\n"); + APP_LOG_WARN("DPST is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } @@ -116,23 +121,24 @@ ctl_result_t TestDPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (CTL_POWER_OPTIMIZATION_DPST_FLAG_BKLT != (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.SupportedFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_BKLT)) { - printf("BKLT is not supported\n"); + APP_LOG_WARN("BKLT is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } - printf("DPST is supported\n"); - printf("DPST Enable = %d\n", AppliedPowerSettings.Enable); - printf("DPST MinLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); - printf("DPST MaxLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); + APP_LOG_INFO("DPST is supported"); + APP_LOG_INFO("DPST Enable = %d", AppliedPowerSettings.Enable); + APP_LOG_INFO("DPST MinLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); + APP_LOG_INFO("DPST MaxLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_EPSM) { - printf("DPST EPSM enabled\n"); + APP_LOG_INFO("DPST EPSM enabled"); } uint8_t Levels[2] = { AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel, AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel }; NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; NewPowerSettings.Enable = TRUE; NewPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_EPSM | CTL_POWER_OPTIMIZATION_DPST_FLAG_BKLT; // BKLT bit should be set to enable Intel DPST @@ -153,7 +159,7 @@ ctl_result_t TestDPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level != NewPowerSettings.FeatureSpecificData.DPSTInfo.Level) { - printf("Current and Applied levels mismatched: %d, %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); + APP_LOG_ERROR("Current and Applied levels mismatched: %d, %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); } } @@ -175,7 +181,9 @@ ctl_result_t TestOPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_caps_t PowerCaps = { 0 }; PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; AppliedPowerSettings.PowerOptimizationPlan = CTL_POWER_OPTIMIZATION_PLAN_BALANCED; @@ -189,17 +197,18 @@ ctl_result_t TestOPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) if ((CTL_POWER_OPTIMIZATION_FLAG_DPST != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_DPST)) || (CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST != (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.SupportedFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST))) { - printf("OPST is not supported\n"); + APP_LOG_WARN("OPST is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } - printf("OPST is supported\n"); - printf("GetPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST\n"); - printf("OPST MinLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); - printf("OPST MaxLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); + APP_LOG_INFO("OPST is supported"); + APP_LOG_INFO("GetPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST"); + APP_LOG_INFO("OPST MinLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); + APP_LOG_INFO("OPST MaxLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; NewPowerSettings.Enable = TRUE; NewPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST; @@ -222,7 +231,7 @@ ctl_result_t TestOPSTPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level != NewPowerSettings.FeatureSpecificData.DPSTInfo.Level) { - printf("Current and Applied levels mismatched: %d, %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); + APP_LOG_ERROR("Current and Applied levels mismatched: %d, %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); } } @@ -244,7 +253,9 @@ ctl_result_t TestELPPowerFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_caps_t PowerCaps = { 0 }; PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; AppliedPowerSettings.PowerOptimizationPlan = CTL_POWER_OPTIMIZATION_PLAN_BALANCED; @@ -258,17 +269,18 @@ ctl_result_t TestELPPowerFeature(ctl_display_output_handle_t hDisplayOutput) if ((CTL_POWER_OPTIMIZATION_FLAG_DPST != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_DPST)) || (CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP != (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.SupportedFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP))) { - printf("ELP is not supported\n"); + APP_LOG_WARN("ELP is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } - printf("GetPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP\n"); - printf("ELP MinLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); - printf("ELP MaxLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); + APP_LOG_INFO("GetPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP"); + APP_LOG_INFO("ELP MinLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); + APP_LOG_INFO("ELP MaxLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); uint8_t Levels[2] = { AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel, AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel }; NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; NewPowerSettings.Enable = TRUE; NewPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP; @@ -288,7 +300,7 @@ ctl_result_t TestELPPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level != NewPowerSettings.FeatureSpecificData.DPSTInfo.Level) { - printf("Current and Applied levels mismatched: %d, %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); + APP_LOG_ERROR("Current and Applied levels mismatched: %d, %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); } } @@ -349,11 +361,11 @@ ctl_result_t TestBrightnessControl(ctl_display_output_handle_t hDisplayOutput) if (AppliedBrightnessSettings.TargetBrightness != NewBrightnessSettings.TargetBrightness) { - printf("Current and Applied TargetBrightness mismatched: %d, %d\n", AppliedBrightnessSettings.TargetBrightness, NewBrightnessSettings.TargetBrightness); + APP_LOG_ERROR("Current and Applied TargetBrightness mismatched: %d, %d", AppliedBrightnessSettings.TargetBrightness, NewBrightnessSettings.TargetBrightness); } - printf("Current brightness = %d\n", AppliedBrightnessSettings.CurrentBrightness); - printf("Target brightness = %d\n", AppliedBrightnessSettings.TargetBrightness); + APP_LOG_INFO("Current brightness = %d", AppliedBrightnessSettings.CurrentBrightness); + APP_LOG_INFO("Target brightness = %d", AppliedBrightnessSettings.TargetBrightness); } else { @@ -378,7 +390,9 @@ ctl_result_t TestApdPowerFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_caps_t PowerCaps = { 0 }; PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; @@ -391,17 +405,18 @@ ctl_result_t TestApdPowerFeature(ctl_display_output_handle_t hDisplayOutput) if ((CTL_POWER_OPTIMIZATION_FLAG_DPST != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_DPST)) || (CTL_POWER_OPTIMIZATION_DPST_FLAG_APD != (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.SupportedFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_APD))) { - printf("APD is not supported\n"); + APP_LOG_WARN("APD is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } - printf("APD MinLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); - printf("APD MaxLevel = %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); + APP_LOG_INFO("APD MinLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); + APP_LOG_INFO("APD MaxLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); uint8_t Levels[2] = { AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel, AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel }; NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; NewPowerSettings.Enable = TRUE; NewPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_APD; @@ -420,7 +435,7 @@ ctl_result_t TestApdPowerFeature(ctl_display_output_handle_t hDisplayOutput) if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level != NewPowerSettings.FeatureSpecificData.DPSTInfo.Level) { - printf("Current and Applied levels mismatched: %d, %d\n", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); + APP_LOG_ERROR("Current and Applied levels mismatched: %d, %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); } } @@ -442,7 +457,9 @@ ctl_result_t TestPixOptixPowerFeature(ctl_display_output_handle_t hDisplayOutput ctl_power_optimization_caps_t PowerCaps = { 0 }; PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; @@ -455,12 +472,13 @@ ctl_result_t TestPixOptixPowerFeature(ctl_display_output_handle_t hDisplayOutput if ((CTL_POWER_OPTIMIZATION_FLAG_DPST != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_DPST)) || (CTL_POWER_OPTIMIZATION_DPST_FLAG_PIXOPTIX != (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.SupportedFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_PIXOPTIX))) { - printf("PIXOPTIX is not supported\n"); + APP_LOG_WARN("PIXOPTIX is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; NewPowerSettings.Enable = TRUE; NewPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_PIXOPTIX; @@ -474,11 +492,11 @@ ctl_result_t TestPixOptixPowerFeature(ctl_display_output_handle_t hDisplayOutput if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_PIXOPTIX) { - printf("PIXOPTIX is enabled"); + APP_LOG_INFO("PIXOPTIX is enabled"); } else { - printf("PIXOPTIX is not enabled"); + APP_LOG_ERROR("PIXOPTIX is not enabled"); } Exit: @@ -497,8 +515,9 @@ ctl_result_t TestAlrrFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_caps_t PowerOptimizationCaps = { 0 }; ctl_power_optimization_settings_t PowerOptimizationSetting = { 0 }; - PowerOptimizationCaps.Size = sizeof(ctl_pfnGetPowerOptimizationCaps_t); - Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerOptimizationCaps); + PowerOptimizationCaps.Size = sizeof(ctl_pfnGetPowerOptimizationCaps_t); + PowerOptimizationCaps.Version = 1; + Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerOptimizationCaps); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationCaps (ALRR)"); @@ -512,11 +531,11 @@ ctl_result_t TestAlrrFeature(ctl_display_output_handle_t hDisplayOutput) if (PowerOptimizationSetting.FeatureSpecificData.LRRInfo.CurrentLRRTypes & CTL_POWER_OPTIMIZATION_LRR_FLAG_ALRR) { - printf("ALRR is enabled"); + APP_LOG_INFO("ALRR is enabled"); } else { - printf("ALRR is not enabled"); + APP_LOG_WARN("ALRR is not enabled"); } } @@ -536,29 +555,100 @@ ctl_result_t TestFbcPowerFeature(ctl_display_output_handle_t hDisplayOutput) ctl_power_optimization_caps_t PowerOptimizationCaps = { 0 }; ctl_power_optimization_settings_t PowerOptimizationSetting = { 0 }; - PowerOptimizationCaps.Size = sizeof(ctl_pfnGetPowerOptimizationCaps_t); - Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerOptimizationCaps); + PowerOptimizationCaps.Size = sizeof(ctl_pfnGetPowerOptimizationCaps_t); + PowerOptimizationCaps.Version = 1; + Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerOptimizationCaps); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationCaps (FBC)"); if (CTL_POWER_OPTIMIZATION_FLAG_FBC != (PowerOptimizationCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_FBC)) { - printf("FBC is not supported\n"); + APP_LOG_WARN("FBC is not supported"); Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; goto Exit; } else { - printf("FBC is supported\n"); + APP_LOG_INFO("FBC is supported"); } if (PowerOptimizationCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_FBC) { PowerOptimizationSetting.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_FBC; PowerOptimizationSetting.Size = sizeof(ctl_power_optimization_settings_t); + PowerOptimizationSetting.Version = 1; Result = ctlGetPowerOptimizationSetting(hDisplayOutput, &PowerOptimizationSetting); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationSetting"); - printf("FBC Enable Status= %d\n", PowerOptimizationSetting.Enable); + APP_LOG_INFO("FBC Enable Status= %d", PowerOptimizationSetting.Enable); + } + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * Power feature Test for CABC + * @param hDisplayOutput + * @return ctl_result_t + ***************************************************************/ +ctl_result_t TestCABCPowerFeature(ctl_display_output_handle_t hDisplayOutput) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_power_optimization_settings_t NewPowerSettings = { 0 }; + ctl_power_optimization_settings_t AppliedPowerSettings = { 0 }; + ctl_power_optimization_caps_t PowerCaps = { 0 }; + + PowerCaps.Size = sizeof(ctl_power_optimization_caps_t); + PowerCaps.Version = 1; + AppliedPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + AppliedPowerSettings.Version = 1; + AppliedPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; + AppliedPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; + AppliedPowerSettings.PowerOptimizationPlan = CTL_POWER_OPTIMIZATION_PLAN_BALANCED; + + Result = ctlGetPowerOptimizationCaps(hDisplayOutput, &PowerCaps); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationCaps (CABC)"); + + Result = ctlGetPowerOptimizationSetting(hDisplayOutput, &AppliedPowerSettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationSetting (CABC)"); + + if ((CTL_POWER_OPTIMIZATION_FLAG_DPST != (PowerCaps.SupportedFeatures & CTL_POWER_OPTIMIZATION_FLAG_DPST)) || + (CTL_POWER_OPTIMIZATION_DPST_FLAG_PANEL_CABC != (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.SupportedFeatures & CTL_POWER_OPTIMIZATION_DPST_FLAG_PANEL_CABC))) + { + APP_LOG_WARN("CABC is not supported"); + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + goto Exit; + } + + APP_LOG_INFO("GetPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_PANEL_CABC"); + APP_LOG_INFO("CABC MinLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel); + APP_LOG_INFO("CABC MaxLevel = %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel); + + uint8_t Levels[2] = { AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MinLevel, AppliedPowerSettings.FeatureSpecificData.DPSTInfo.MaxLevel }; + NewPowerSettings.Size = sizeof(ctl_power_optimization_settings_t); + NewPowerSettings.Version = 1; + NewPowerSettings.PowerOptimizationFeature = CTL_POWER_OPTIMIZATION_FLAG_DPST; + NewPowerSettings.Enable = TRUE; + NewPowerSettings.FeatureSpecificData.DPSTInfo.EnabledFeatures = CTL_POWER_OPTIMIZATION_DPST_FLAG_PANEL_CABC; + NewPowerSettings.PowerSource = CTL_POWER_SOURCE_DC; + NewPowerSettings.PowerOptimizationPlan = CTL_POWER_OPTIMIZATION_PLAN_BALANCED; + + for (uint8_t Count = 0; Count < 2; Count++) + { + // Set PowerFeature + NewPowerSettings.FeatureSpecificData.DPSTInfo.Level = Levels[Count]; + + Result = ctlSetPowerOptimizationSetting(hDisplayOutput, &NewPowerSettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlSetPowerOptimizationSetting (CABC)"); + + Result = ctlGetPowerOptimizationSetting(hDisplayOutput, &AppliedPowerSettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationSetting (CABC)"); + + if (AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level != NewPowerSettings.FeatureSpecificData.DPSTInfo.Level) + { + APP_LOG_ERROR("Current and Applied levels mismatched: %d, %d", AppliedPowerSettings.FeatureSpecificData.DPSTInfo.Level, NewPowerSettings.FeatureSpecificData.DPSTInfo.Level); + } } Exit: @@ -591,12 +681,12 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput if (FALSE == IsDisplayAttached) { - printf("Display %d is not attached, skipping the call for this display\n", DisplayIndex); + APP_LOG_WARN("Display %d is not attached, skipping the call for this display", DisplayIndex); continue; } else { - printf("Attached Display Count: %d\n", DisplayIndex); + APP_LOG_INFO("Attached Display Count: %d", DisplayIndex); } // NOTE: Currently DPST/ELP/OPST combination is not supported @@ -635,6 +725,10 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput Result = TestFbcPowerFeature(hDisplayOutput[DisplayIndex]); STORE_AND_RESET_ERROR(Result); + + Result = TestCABCPowerFeature(hDisplayOutput[DisplayIndex]); + + STORE_AND_RESET_ERROR(Result); } Exit: @@ -662,13 +756,13 @@ ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", AdapterIndex); continue; } @@ -680,7 +774,7 @@ ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -690,7 +784,7 @@ ctl_result_t EnumerateTargetDisplays(ctl_display_output_handle_t *hDisplayOutput if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateDisplayHandles returned failure code: 0x%X\n", Result); + APP_LOG_WARN("EnumerateDisplayHandles returned failure code: 0x%X", Result); } CTL_FREE_MEM(hDisplayOutput); @@ -726,25 +820,46 @@ int main() CtlInitArgs.Version = 0; ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = EnumerateTargetDisplays(hDisplayOutput, AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateTargetDisplays returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -753,6 +868,6 @@ int main() ctlClose(hAPIHandle); CTL_FREE_MEM(hDisplayOutput); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } diff --git a/Samples/Scaling_Samples/CMakeLists.txt b/Samples/Scaling_Samples/CMakeLists.txt index cdcce6b..0a74eab 100644 --- a/Samples/Scaling_Samples/CMakeLists.txt +++ b/Samples/Scaling_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Scaling_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Scaling_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Scaling_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Scaling_Samples/Scaling_App.cpp b/Samples/Scaling_Samples/Scaling_App.cpp index 48c1986..9cc55a0 100644 --- a/Samples/Scaling_Samples/Scaling_App.cpp +++ b/Samples/Scaling_Samples/Scaling_App.cpp @@ -33,7 +33,7 @@ ctl_result_t GResult = CTL_RESULT_SUCCESS; * @param hDevices * @return ctl_result_t ***************************************************************/ -ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) +ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices, uint8_t ScaleType, uint32_t PerX = 0, uint32_t PerY = 0) { ctl_display_output_handle_t *hDisplayOutput = NULL; uint32_t DisplayCount = 0; @@ -53,7 +53,7 @@ ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) Result = ctlGetSupportedRetroScalingCapability(hDevices, &RetroScalingCaps); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSupportedRetroScalingCapability"); - printf("ctlGetSupportedRetroScalingCapability returned Caps: 0x%X\n", RetroScalingCaps.SupportedRetroScaling); + APP_LOG_INFO("ctlGetSupportedRetroScalingCapability returned Caps: 0x%X", RetroScalingCaps.SupportedRetroScaling); // Test Integer Scaling RetroScalingSettings.Enable = true; @@ -72,7 +72,7 @@ ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) Result = ctlGetSetRetroScaling(hDevices, &RetroScalingSettings); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetRetroScaling"); - printf("ctlGetSetRetroScaling returned Enable: 0x%X type:0x%x\n", RetroScalingSettings.Enable, RetroScalingSettings.RetroScalingType); + APP_LOG_INFO("ctlGetSetRetroScaling returned Enable: 0x%X type:0x%x", RetroScalingSettings.Enable, RetroScalingSettings.RetroScalingType); // Enumerate all the possible target display's for the adapters Result = ctlEnumerateDisplayOutputs(hDevices, &DisplayCount, hDisplayOutput); @@ -80,7 +80,7 @@ ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) if (DisplayCount <= 0) { - printf("Invalid Display Count\n"); + APP_LOG_ERROR("Invalid Display Count"); goto Exit; } @@ -104,29 +104,54 @@ ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetSupportedScalingCapability returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlGetSupportedScalingCapability returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } - printf("ctlGetSupportedScalingCapability returned caps: 0x%X\n", ScalingCaps.SupportedScaling); + APP_LOG_INFO("ctlGetSupportedScalingCapability returned caps: 0x%X", ScalingCaps.SupportedScaling); + + PRINT_LOGS("******* Supported Scaling types ********"); + + if (CTL_SCALING_TYPE_FLAG_IDENTITY & ScalingCaps.SupportedScaling) + { + APP_LOG_INFO("CTL_SCALING_TYPE_FLAG_IDENTITY(1) is supported"); + } + if (CTL_SCALING_TYPE_FLAG_CENTERED & ScalingCaps.SupportedScaling) + { + APP_LOG_INFO("CTL_SCALING_TYPE_FLAG_CENTERED(2) is supported"); + } + if (CTL_SCALING_TYPE_FLAG_STRETCHED & ScalingCaps.SupportedScaling) + { + APP_LOG_INFO("CTL_SCALING_TYPE_FLAG_STRETCHED(4) is supported"); + } + if (CTL_SCALING_TYPE_FLAG_ASPECT_RATIO_CENTERED_MAX & ScalingCaps.SupportedScaling) + { + APP_LOG_INFO("CTL_SCALING_TYPE_FLAG_ASPECT_RATIO_CENTERED_MAX(8) is supported"); + } + if (CTL_SCALING_TYPE_FLAG_CUSTOM & ScalingCaps.SupportedScaling) + { + APP_LOG_INFO("CTL_SCALING_TYPE_FLAG_CUSTOM(16) is supported"); + } if (0 != ScalingCaps.SupportedScaling) { - ScalingSetting.Size = sizeof(ctl_scaling_settings_t); - Result = ctlGetCurrentScaling(hDisplayOutput[i], &ScalingSetting); + ScalingSetting.Size = sizeof(ctl_scaling_settings_t); + ScalingSetting.Version = 1; + Result = ctlGetCurrentScaling(hDisplayOutput[i], &ScalingSetting); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetCurrentScaling returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlGetCurrentScaling returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } - printf("ctlGetCurrentScaling returned Enable: 0x%X type:0x%x\n", ScalingSetting.Enable, ScalingSetting.ScalingType); + APP_LOG_INFO("ctlGetCurrentScaling returned Enable: 0x%X ScalingType:0x%x PreferredScalingType:0x%x", ScalingSetting.Enable, ScalingSetting.ScalingType, + ScalingSetting.PreferredScalingType); } // fill custom scaling details only if it is supported - if (0x1F == ScalingCaps.SupportedScaling) + if ((CTL_SCALING_TYPE_FLAG_CUSTOM & ScalingCaps.SupportedScaling) && (CTL_SCALING_TYPE_FLAG_CUSTOM == ScaleType)) { // check if hardware modeset required to apply custom scaling ModeSet = ((TRUE == ScalingSetting.Enable) && (CTL_SCALING_TYPE_FLAG_CUSTOM == ScalingSetting.ScalingType)) ? FALSE : TRUE; @@ -136,28 +161,52 @@ ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) ScalingSetting.ScalingType = CTL_SCALING_TYPE_FLAG_CUSTOM; ScalingSetting.Size = sizeof(ctl_scaling_settings_t); ScalingSetting.HardwareModeSet = (TRUE == ModeSet) ? TRUE : FALSE; - ScalingSetting.CustomScalingX = 1000; - ScalingSetting.CustomScalingY = 1000; + ScalingSetting.Version = 1; + + APP_LOG_INFO("*** PerX:%d PerY:%d ***", PerX, PerY); + + ScalingSetting.CustomScalingX = PerX; + ScalingSetting.CustomScalingY = PerY; + } + else + { + // filling custom scaling details + ScalingSetting = { 0 }; + ScalingSetting.Enable = true; + ScalingSetting.ScalingType = ScaleType; + ScalingSetting.Size = sizeof(ctl_scaling_settings_t); + ScalingSetting.Version = 1; } + + APP_LOG_INFO("ScalingSetting.ScalingType:%d", ScalingSetting.ScalingType); + Result = ctlSetCurrentScaling(hDisplayOutput[i], &ScalingSetting); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlSetCurrentScaling returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlSetCurrentScaling returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } // check if the applied scaling was successful - ScalingSetting = { 0 }; - ScalingSetting.Size = sizeof(ctl_scaling_settings_t); - Result = ctlGetCurrentScaling(hDisplayOutput[i], &ScalingSetting); + ScalingSetting = { 0 }; + ScalingSetting.Size = sizeof(ctl_scaling_settings_t); + ScalingSetting.Version = 1; + Result = ctlGetCurrentScaling(hDisplayOutput[i], &ScalingSetting); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetCurrentScaling returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlGetCurrentScaling returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } - printf("ctlGetCurrentScaling returned Enable: 0x%X type:0x%x\n", ScalingSetting.Enable, ScalingSetting.ScalingType); + + APP_LOG_INFO("ctlGetCurrentScaling returned Enable: 0x%X ScalingType:0x%x PreferredScalingType:0x%x", ScalingSetting.Enable, ScalingSetting.ScalingType, ScalingSetting.PreferredScalingType); + + if (CTL_SCALING_TYPE_FLAG_CUSTOM == ScalingSetting.ScalingType) + { + APP_LOG_INFO("ScalingSetting.CustomScalingX:%d", ScalingSetting.CustomScalingX); + APP_LOG_INFO("ScalingSetting.CustomScalingY:%d", ScalingSetting.CustomScalingY); + } } Exit: @@ -171,8 +220,31 @@ ctl_result_t ScalingTest(ctl_device_adapter_handle_t hDevices) * @param * @return ***************************************************************/ -int main() +int main(int argc, char *pArgv[]) { + uint8_t ScaleType = 0; + uint32_t X = 0, Y = 0; + + if (argc < 2) + { + APP_LOG_ERROR("Enter Scale type!\""); + return 0; + } + + // Converting string type to integer type + // using function "atoi( argument)" + + if (2 == argc) + { + ScaleType = atoi(pArgv[1]); + } + else if (4 == argc) + { + ScaleType = atoi(pArgv[1]); + X = atoi(pArgv[2]); + Y = atoi(pArgv[3]); + } + ctl_result_t Result = CTL_RESULT_SUCCESS; ctl_device_adapter_handle_t *hDevices = NULL; // Get a handle to the DLL module. @@ -194,27 +266,48 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } for (uint32_t i = 0; i < AdapterCount; i++) { - Result = ScalingTest(hDevices[i]); + Result = ScalingTest(hDevices[i], ScaleType, X, Y); if (CTL_RESULT_SUCCESS != Result) { - printf("ctlGetCurrentScaling returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlGetCurrentScaling returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } @@ -224,6 +317,6 @@ int main() ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; } \ No newline at end of file diff --git a/Samples/ScdcRead/CMakeLists.txt b/Samples/ScdcRead/CMakeLists.txt index 71a199d..5564a48 100644 --- a/Samples/ScdcRead/CMakeLists.txt +++ b/Samples/ScdcRead/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME ScdcRead) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(ScdcRead VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/ScdcReadApp.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/ScdcRead/ScdcReadApp.cpp b/Samples/ScdcRead/ScdcReadApp.cpp index 9bd980b..899404d 100644 --- a/Samples/ScdcRead/ScdcReadApp.cpp +++ b/Samples/ScdcRead/ScdcReadApp.cpp @@ -180,19 +180,40 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } Result = EnumerateTargetDisplays(AdapterCount, hDevices, &hDisplayOutput, &DisplayCount); diff --git a/Samples/Telemetry_Samples/CMakeLists.txt b/Samples/Telemetry_Samples/CMakeLists.txt index 16d6077..ca97af6 100644 --- a/Samples/Telemetry_Samples/CMakeLists.txt +++ b/Samples/Telemetry_Samples/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME Telemetry_Samples) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(Telemetry_Samples VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/Sample_TelemetryAPP.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/Telemetry_Samples/README.md b/Samples/Telemetry_Samples/README.md index da2c0ba..c7dea1d 100644 --- a/Samples/Telemetry_Samples/README.md +++ b/Samples/Telemetry_Samples/README.md @@ -1 +1 @@ -Sample Application for the Telemetry interface \ No newline at end of file +Sample Application for the Telemetry interface. \ No newline at end of file diff --git a/Samples/Telemetry_Samples/Sample_TelemetryAPP.cpp b/Samples/Telemetry_Samples/Sample_TelemetryAPP.cpp index ab1aa6a..8197a24 100644 --- a/Samples/Telemetry_Samples/Sample_TelemetryAPP.cpp +++ b/Samples/Telemetry_Samples/Sample_TelemetryAPP.cpp @@ -22,182 +22,197 @@ #include #include #include - -#include #include - -#include -#include #include "igcl_api.h" #include "GenericIGCLApp.h" +#include -std::string DecodeRetCode(ctl_result_t Res); void CtlTemperatureTest(ctl_device_adapter_handle_t hDAhandle); void CtlFrequencyTest(ctl_device_adapter_handle_t hDAhandle); void CtlPowerTest(ctl_device_adapter_handle_t hDAhandle); +void CtlFanTest_FanGetConfig(ctl_fan_handle_t hFanHandle); void CtlFanTest(ctl_device_adapter_handle_t hDAhandle); void CtlPciTest(ctl_device_adapter_handle_t hDAhandle); void CtlMemoryTest(ctl_device_adapter_handle_t hDAhandle); void CtlEngineTest(ctl_device_adapter_handle_t hDAhandle); -void CtlOverclockPropertiesTest(ctl_device_adapter_handle_t hDAhandle); -void CtlOverclockFrequencyOffsetTest(ctl_device_adapter_handle_t hDAhandle, double FreqOffset); -void CtlOverclockFrequencyAndVoltageOffsetTest(ctl_device_adapter_handle_t hDAhandle); -void CtlOverclockPowerTest(ctl_device_adapter_handle_t hDAhandle); -void CtlOverclockTemperatureTest(ctl_device_adapter_handle_t hDAhandle); +void CtlLedTest(ctl_device_adapter_handle_t hDAhandle); +void CtlEccTest(ctl_device_adapter_handle_t hDAhandle); void CtlPowerTelemetryTest(ctl_device_adapter_handle_t hDAhandle); -const char *printType(ctl_data_type_t Type) +std::string DecodeCtlDataType(ctl_data_type_t Type) +{ + static const std::map dataTypeStringMap = { { CTL_DATA_TYPE_INT8, "INT8" }, + { CTL_DATA_TYPE_UINT8, "UINT8" }, + { CTL_DATA_TYPE_INT16, "INT16" }, + { CTL_DATA_TYPE_UINT16, "UINT16" }, + { CTL_DATA_TYPE_INT32, "INT32" }, + { CTL_DATA_TYPE_UINT32, "UINT32" }, + { CTL_DATA_TYPE_INT64, "INT64" }, + { CTL_DATA_TYPE_UINT64, "UINT64" }, + { CTL_DATA_TYPE_FLOAT, "FLOAT" }, + { CTL_DATA_TYPE_DOUBLE, "DOUBLE" }, + { CTL_DATA_TYPE_STRING_ASCII, "STRING_ASCII" }, + { CTL_DATA_TYPE_STRING_UTF16, "STRING_UTF16" }, + { CTL_DATA_TYPE_STRING_UTF132, "STRING_UTF132" } }; + + auto it = dataTypeStringMap.find(Type); + if (it != dataTypeStringMap.end()) + { + return it->second; + } + return "Unknown datatype"; +} + +std::string DecodeCtlUnits(ctl_units_t Units) { - switch (Type) + static const std::map unitsStringMap = { { CTL_UNITS_FREQUENCY_MHZ, "Frequency in MHz" }, + { CTL_UNITS_OPERATIONS_GTS, "GigaOperations per Second" }, + { CTL_UNITS_OPERATIONS_MTS, "MegaOperations per Second" }, + { CTL_UNITS_VOLTAGE_VOLTS, "Voltage in Volts" }, + { CTL_UNITS_POWER_WATTS, "Power in Watts" }, + { CTL_UNITS_TEMPERATURE_CELSIUS, "Temperature in Celsius" }, + { CTL_UNITS_ENERGY_JOULES, "Energy in Joules" }, + { CTL_UNITS_TIME_SECONDS, "Time in Seconds" }, + { CTL_UNITS_MEMORY_BYTES, "Memory in Bytes" }, + { CTL_UNITS_ANGULAR_SPEED_RPM, "Angular Speed in RPM" }, + { CTL_UNITS_POWER_MILLIWATTS, "Power in Milli Watts" }, + { CTL_UNITS_PERCENT, "Units in Percentage" }, + { CTL_UNITS_MEM_SPEED_GBPS, "Units in Gigabyte Per Second" }, + { CTL_UNITS_VOLTAGE_MILLIVOLTS, "Voltage in MilliVolts" }, + { CTL_UNITS_BANDWIDTH_MBPS, "Bandwidth in MegaBytes Per Second" } }; + + auto it = unitsStringMap.find(Units); + if (it != unitsStringMap.end()) + { + return it->second; + } + return "Unknown unit"; +} + +std::string DecodeTemperatureSensor(ctl_temp_sensors_t tempSensor) +{ + static const std::map tempSensorStringMap = { { CTL_TEMP_SENSORS_GLOBAL, "GLOBAL" }, { CTL_TEMP_SENSORS_GPU, "GPU" }, { CTL_TEMP_SENSORS_MEMORY, "MEMORY" } }; + + auto it = tempSensorStringMap.find(tempSensor); + if (it != tempSensorStringMap.end()) { - case ctl_data_type_t::CTL_DATA_TYPE_INT8: - { - return "CTL_DATA_TYPE_INT8"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT8: - { - return "CTL_DATA_TYPE_UINT8"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_INT16: - { - return "CTL_DATA_TYPE_INT16"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT16: - { - return "CTL_DATA_TYPE_UINT16"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_INT32: - { - return "CTL_DATA_TYPE_INT32"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT32: - { - return "CTL_DATA_TYPE_UINT32"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_INT64: - { - return "CTL_DATA_TYPE_INT64"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_UINT64: - { - return "CTL_DATA_TYPE_UINT64"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_FLOAT: - { - return "CTL_DATA_TYPE_FLOAT"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_DOUBLE: - { - return "CTL_DATA_TYPE_DOUBLE"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_STRING_ASCII: - { - return "CTL_DATA_TYPE_STRING_ASCII"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_STRING_UTF16: - { - return "CTL_DATA_TYPE_STRING_UTF16"; - } - break; - case ctl_data_type_t::CTL_DATA_TYPE_STRING_UTF132: - { - return "CTL_DATA_TYPE_STRING_UTF132"; - } - break; - default: - return "Unknown units"; + return it->second; } + return "Unknown temperature sensor"; } -const char *printUnits(ctl_units_t Units) +std::string DecodeFrequencyDomain(ctl_freq_domain_t freqDomain) { - switch (Units) + static const std::map freqDomainStringMap = { { CTL_FREQ_DOMAIN_GPU, "GPU" }, { CTL_FREQ_DOMAIN_MEMORY, "MEMORY" }, { CTL_FREQ_DOMAIN_MEDIA, "MEDIA" } }; + + auto it = freqDomainStringMap.find(freqDomain); + if (it != freqDomainStringMap.end()) { - case ctl_units_t::CTL_UNITS_FREQUENCY_MHZ: - { - return "Frequency in MHz"; - } - break; - case ctl_units_t::CTL_UNITS_OPERATIONS_GTS: - { - return "GigaOperations per Second"; - } - break; - case ctl_units_t::CTL_UNITS_OPERATIONS_MTS: - { - return "MegaOperations per Second"; - } - break; - case ctl_units_t::CTL_UNITS_VOLTAGE_VOLTS: - { - return "Voltage in Volts"; - } - break; - case ctl_units_t::CTL_UNITS_POWER_WATTS: - { - return "Power in Watts"; - } - break; - case ctl_units_t::CTL_UNITS_TEMPERATURE_CELSIUS: - { - return "Temperature in Celsius"; - } - break; - case ctl_units_t::CTL_UNITS_ENERGY_JOULES: - { - return "Energy in Joules"; - } - break; - case ctl_units_t::CTL_UNITS_TIME_SECONDS: - { - return "Time in Seconds"; - } - break; - case ctl_units_t::CTL_UNITS_MEMORY_BYTES: - { - return "Memory in Bytes"; - } - break; - case ctl_units_t::CTL_UNITS_ANGULAR_SPEED_RPM: - { - return "Angular Speed in RPM"; - } - break; - case ctl_units_t::CTL_UNITS_POWER_MILLIWATTS: - { - return "Power in Milli Watts"; - } - break; - case ctl_units_t::CTL_UNITS_PERCENT: - { - return "Units in Percentage"; - } - break; - case ctl_units_t::CTL_UNITS_MEM_SPEED_GBPS: - { - return "Units in Gigabyte Per Second"; - } - break; - case ctl_units_t::CTL_UNITS_VOLTAGE_MILLIVOLTS: - { - return "Voltage in MilliVolts"; - } - break; - default: - return "Unknown units"; + return it->second; + } + return "Unknown frequency domain"; +} + +std::string DecodeFanSpeedUnits(ctl_fan_speed_units_t Units) +{ + static const std::map unitsStringMap = { { CTL_FAN_SPEED_UNITS_RPM, "RPM" }, { CTL_FAN_SPEED_UNITS_PERCENT, "PERCENT" } }; + + auto it = unitsStringMap.find(Units); + if (it != unitsStringMap.end()) + { + return it->second; + } + return "Unknown fan speed unit"; +} + +std::string DecodeFanSpeedMode(ctl_fan_speed_mode_t fanSpeedMode) +{ + static const std::map fanSpeedModeStringMap = { { CTL_FAN_SPEED_MODE_DEFAULT, "DEFAULT/STOCK FAN TABLE" }, + { CTL_FAN_SPEED_MODE_FIXED, "FIXED SPEED" }, + { CTL_FAN_SPEED_MODE_TABLE, "USER FAN TABLE" } }; + + auto it = fanSpeedModeStringMap.find(fanSpeedMode); + if (it != fanSpeedModeStringMap.end()) + { + return it->second; + } + return "Unknown fan speed mode"; +} + +std::string DecodeEngineGroup(ctl_engine_group_t engineGroup) +{ + static const std::map engineGroupStringMap = { { CTL_ENGINE_GROUP_GT, "GT" }, { CTL_ENGINE_GROUP_RENDER, "RENDER" }, { CTL_ENGINE_GROUP_MEDIA, "MEDIA" } }; + + auto it = engineGroupStringMap.find(engineGroup); + if (it != engineGroupStringMap.end()) + { + return it->second; + } + return "Unknown engine group"; +} + +std::string DecodeBoolean(bool Value) +{ + return Value ? "true" : "false"; +} + +std::string DecodeEccState(ctl_ecc_state_t eccState) +{ + static const std::map eccStateStringMap = { { CTL_ECC_STATE_ECC_DEFAULT_STATE, "default" }, + { CTL_ECC_STATE_ECC_ENABLED_STATE, "enabled" }, + { CTL_ECC_STATE_ECC_DISABLED_STATE, "disabled" } }; + + auto it = eccStateStringMap.find(eccState); + if (it != eccStateStringMap.end()) + { + return it->second; } + return "Unknown Ecc state"; +} + +// Decoding the return code for the most common error codes. +std::string DecodeRetCode(ctl_result_t Res) +{ + static const std::map retCodeMap = { { CTL_RESULT_SUCCESS, "[CTL_RESULT_SUCCESS]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE]" }, + { CTL_RESULT_ERROR_GENERIC_START, "[CTL_RESULT_ERROR_GENERIC_START]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET]" }, + { CTL_RESULT_ERROR_NOT_INITIALIZED, "[CTL_RESULT_ERROR_NOT_INITIALIZED]" }, + { CTL_RESULT_ERROR_ALREADY_INITIALIZED, "[CTL_RESULT_ERROR_ALREADY_INITIALIZED]" }, + { CTL_RESULT_ERROR_DEVICE_LOST, "[CTL_RESULT_ERROR_DEVICE_LOST]" }, + { CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, "[CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS]" }, + { CTL_RESULT_ERROR_NOT_AVAILABLE, "[CTL_RESULT_ERROR_NOT_AVAILABLE]" }, + { CTL_RESULT_ERROR_UNINITIALIZED, "[CTL_RESULT_ERROR_UNINITIALIZED]" }, + { CTL_RESULT_ERROR_UNSUPPORTED_VERSION, "[CTL_RESULT_ERROR_UNSUPPORTED_VERSION]" }, + { CTL_RESULT_ERROR_UNSUPPORTED_FEATURE, "[CTL_RESULT_ERROR_UNSUPPORTED_FEATURE]" }, + { CTL_RESULT_ERROR_INVALID_ARGUMENT, "[CTL_RESULT_ERROR_INVALID_ARGUMENT]" }, + { CTL_RESULT_ERROR_INVALID_NULL_HANDLE, "[CTL_RESULT_ERROR_INVALID_NULL_HANDLE]" }, + { CTL_RESULT_ERROR_INVALID_NULL_POINTER, "[CTL_RESULT_ERROR_INVALID_NULL_POINTER]" }, + { CTL_RESULT_ERROR_INVALID_SIZE, "[CTL_RESULT_ERROR_INVALID_SIZE]" }, + { CTL_RESULT_ERROR_UNSUPPORTED_SIZE, "[CTL_RESULT_ERROR_UNSUPPORTED_SIZE]" }, + { CTL_RESULT_ERROR_NOT_IMPLEMENTED, "[CTL_RESULT_ERROR_NOT_IMPLEMENTED]" }, + { CTL_RESULT_ERROR_ZE_LOADER, "[CTL_RESULT_ERROR_ZE_LOADER]" }, + { CTL_RESULT_ERROR_INVALID_OPERATION_TYPE, "[CTL_RESULT_ERROR_INVALID_OPERATION_TYPE]" }, + { CTL_RESULT_ERROR_DATA_READ, "[CTL_RESULT_ERROR_DATA_READ]" }, + { CTL_RESULT_ERROR_DATA_WRITE, "[CTL_RESULT_ERROR_DATA_WRITE]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_INVALID_CUSTOM_VF_CURVE, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_INVALID_CUSTOM_VF_CURVE]" }, + { CTL_RESULT_ERROR_UNKNOWN, "[CTL_RESULT_ERROR_UNKNOWN]" }, + { CTL_RESULT_ERROR_CORE_OVERCLOCK_DEPRECATED_API, "[CTL_RESULT_ERROR_CORE_OVERCLOCK_DEPRECATED_API]" } }; + + auto it = retCodeMap.find(Res); + if (it != retCodeMap.end()) + { + return it->second; + } + return "[Unknown Error]"; } + /*************************************************************** * @brief * place_holder_for_Detailed_desc @@ -247,10 +262,7 @@ void CtlTemperatureTest(ctl_device_adapter_handle_t hDAhandle) else { PRINT_LOGS("\n[Temperature] Max temp [%u]", (uint32_t)temperatureProperties.maxTemperature); - PRINT_LOGS("\n[Temperature] Sensor type [%s]", ((temperatureProperties.type == CTL_TEMP_SENSORS_GLOBAL) ? "Global" : - (temperatureProperties.type == CTL_TEMP_SENSORS_GPU) ? "Gpu" : - (temperatureProperties.type == CTL_TEMP_SENSORS_MEMORY) ? "Memory" : - "Unknown")); + PRINT_LOGS("\n[Temperature] Sensor type [%s]", DecodeTemperatureSensor(temperatureProperties.type).c_str()); } PRINT_LOGS("\n[Temperature] Get Temperature state:"); @@ -322,7 +334,7 @@ void CtlFrequencyTest(ctl_device_adapter_handle_t hDAhandle) PRINT_LOGS("\n[Frequency] Min [%f]] MHz", freqProperties.min); PRINT_LOGS("\n[Frequency] Max [%f]] MHz", freqProperties.max); PRINT_LOGS("\n[Frequency] Can Control Frequency? [%u]]", (uint32_t)freqProperties.canControl); - PRINT_LOGS("\n[Frequency] Frequency Domain [%s]]", ((freqProperties.type == CTL_FREQ_DOMAIN_GPU) ? "GPU" : "MEMORY")); + PRINT_LOGS("\n[Frequency] Frequency Domain [%s]]", DecodeFrequencyDomain(freqProperties.type).c_str()); } PRINT_LOGS("\n\n[Frequency] State:"); @@ -376,10 +388,12 @@ void CtlFrequencyTest(ctl_device_adapter_handle_t hDAhandle) clocks = new double[numClocks]; res = ctlFrequencyGetAvailableClocks(pFrequencyHandle[i], &numClocks, clocks); - - for (uint32_t i = 0; i < numClocks; i++) + if (CTL_RESULT_SUCCESS == res) { - PRINT_LOGS("\n[Frequency] Clock [%u] Freq[%f] MHz", i, clocks[i]); + for (uint32_t i = 0; i < numClocks; i++) + { + PRINT_LOGS("\n[Frequency] Clock [%u] Freq[%f] MHz", i, clocks[i]); + } } delete[] clocks; @@ -462,7 +476,8 @@ void CtlPowerTest(ctl_device_adapter_handle_t hDAhandle) } else { - PRINT_LOGS("\n[Power] Can Control [%u]", (uint32_t)properties.canControl); + PRINT_LOGS("\n[Power] Can Control [%s]", DecodeBoolean(properties.canControl).c_str()); + PRINT_LOGS("\n[Power] Default Power Limit [%u]", (uint32_t)properties.defaultLimit); PRINT_LOGS("\n[Power] Max Power Limit [%i] mW", properties.maxLimit); PRINT_LOGS("\n[Power] Min Power Limit [%i] mW", properties.minLimit); } @@ -495,10 +510,10 @@ void CtlPowerTest(ctl_device_adapter_handle_t hDAhandle) } else { - PRINT_LOGS("\n[Power] Sustained Power Limit Enabled [%u]", (uint32_t)powerLimits.sustainedPowerLimit.enabled); + PRINT_LOGS("\n[Power] Sustained Power Limit Enabled [%s]", DecodeBoolean(powerLimits.sustainedPowerLimit.enabled).c_str()); PRINT_LOGS("\n[Power] Sustained Power (PL1) Value [%i] mW", powerLimits.sustainedPowerLimit.power); PRINT_LOGS("\n[Power] Sustained Power (PL1 Tau) Time Window [%i] ms", powerLimits.sustainedPowerLimit.interval); - PRINT_LOGS("\n[Power] Burst Power Limit Enabled [%u]", (uint32_t)powerLimits.burstPowerLimit.enabled); + PRINT_LOGS("\n[Power] Burst Power Limit Enabled [%s]", DecodeBoolean(powerLimits.burstPowerLimit.enabled).c_str()); PRINT_LOGS("\n[Power] Burst Power (PL2) Value [%i] mW", powerLimits.burstPowerLimit.power); PRINT_LOGS("\n[Power] Peak Power (PL4) AC Value [%i] mW", powerLimits.peakPowerLimits.powerAC); PRINT_LOGS("\n[Power] Peak Power (PL4) DC Value [%i] mW", powerLimits.peakPowerLimits.powerDC); @@ -523,6 +538,49 @@ void CtlPowerTest(ctl_device_adapter_handle_t hDAhandle) pPowerHandle = nullptr; } +/*************************************************************** + * @brief + * place_holder_for_Detailed_desc + * @param + * @return + ***************************************************************/ +void CtlFanTest_FanGetConfig(ctl_fan_handle_t hFanHandle) +{ + PRINT_LOGS("\n[Fan] Fan get Config:"); + + ctl_fan_config_t FanConfig = {}; + FanConfig.Size = sizeof(ctl_fan_config_t); + ctl_result_t res = ctlFanGetConfig(hFanHandle, &FanConfig); + + if (res != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\n %s from Fan get Config.", DecodeRetCode(res).c_str()); + } + else + { + PRINT_LOGS("\n[Fan] Fan Config Mode [%s]", DecodeFanSpeedMode(FanConfig.mode).c_str()); + if (CTL_FAN_SPEED_MODE_DEFAULT == FanConfig.mode) + { + PRINT_LOGS("\n[Fan] Fan Config Mode: Default/Stock"); + } + else if (CTL_FAN_SPEED_MODE_FIXED == FanConfig.mode) + { + PRINT_LOGS("\n[Fan] Fan Config Fixed Speed [%u]", FanConfig.speedFixed.speed); + PRINT_LOGS("\n[Fan] Fan Config Fixed Speed Unit [%s]", DecodeFanSpeedUnits(FanConfig.speedFixed.units).c_str()); + } + else if (CTL_FAN_SPEED_MODE_TABLE == FanConfig.mode) + { + PRINT_LOGS("\n[Fan] Fan Config Fan Table NumPoints [%u]", FanConfig.speedTable.numPoints); + for (int32_t numPoints = 0; numPoints < FanConfig.speedTable.numPoints; numPoints++) + { + PRINT_LOGS("\n[Fan] Fan Config Fan Table Point Speed Unit [%s]", DecodeFanSpeedUnits(FanConfig.speedTable.table[numPoints].speed.units).c_str()); + PRINT_LOGS("\n[Fan] Fan Config Fan Table Point Speed [%u]", FanConfig.speedTable.table[numPoints].speed.speed); + PRINT_LOGS("\n[Fan] Fan Config Fan Table Point Temperature [%u]", FanConfig.speedTable.table[numPoints].temperature); + } + } + } +} + /*************************************************************** * @brief * place_holder_for_Detailed_desc @@ -570,42 +628,14 @@ void CtlFanTest(ctl_device_adapter_handle_t hDAhandle) } else { - PRINT_LOGS("\n[Fan] Can Control [%u]", (uint32_t)Fan_properties.canControl); + PRINT_LOGS("\n[Fan] Can Control [%s]", DecodeBoolean(Fan_properties.canControl).c_str()); PRINT_LOGS("\n[Fan] Max Points [%i]", Fan_properties.maxPoints); PRINT_LOGS("\n[Fan] Max RPM [%i]", Fan_properties.maxRPM); PRINT_LOGS("\n[Fan] Supported Modes [%u]", Fan_properties.supportedModes); PRINT_LOGS("\n[Fan] Supported Units [%u]", Fan_properties.supportedUnits); } - PRINT_LOGS("\n[Fan] Fan get Config:"); - - ctl_fan_config_t FanConfig = {}; - FanConfig.Size = sizeof(ctl_fan_config_t); - res = ctlFanGetConfig(pFanHandle[i], &FanConfig); - - if (res != CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\n %s from Fan get Config.", DecodeRetCode(res).c_str()); - } - else - { - PRINT_LOGS("\n[Fan] Fan Config Mode [%u]", FanConfig.mode); - if (CTL_FAN_SPEED_MODE_FIXED == FanConfig.mode) - { - PRINT_LOGS("\n[Fan] Fan Config Fixed Speed [%u]", FanConfig.speedFixed.speed); - PRINT_LOGS("\n[Fan] Fan Config Fixed Speed Unit [%u]", FanConfig.speedFixed.units); - } - else if (CTL_FAN_SPEED_MODE_TABLE == FanConfig.mode) - { - PRINT_LOGS("\n[Fan] Fan Config Fan Table NumPoints [%u]", FanConfig.speedTable.numPoints); - for (int32_t numPoints = 0; numPoints < FanConfig.speedTable.numPoints; numPoints++) - { - PRINT_LOGS("\n[Fan] Fan Config Fan Table Point Speed Unit [%u]", FanConfig.speedTable.table[numPoints].speed.units); - PRINT_LOGS("\n[Fan] Fan Config Fan Table Point Speed [%u]", FanConfig.speedTable.table[numPoints].speed.speed); - PRINT_LOGS("\n[Fan] Fan Config Fan Table Point Temperature [%u]", FanConfig.speedTable.table[numPoints].temperature); - } - } - } + CtlFanTest_FanGetConfig(pFanHandle[i]); PRINT_LOGS("\n[Fan] Fan get state:"); @@ -626,6 +656,47 @@ void CtlFanTest(ctl_device_adapter_handle_t hDAhandle) Sleep(100); } + + ctl_fan_speed_table_t FanTable = {}; + FanTable.Size = sizeof(ctl_fan_speed_table_t); + FanTable.numPoints = 10; + FanTable.Version = 0; + + for (uint32_t index = 0; index < 10; index++) + { + FanTable.table[index] = { 0 }; + FanTable.table[index].Version = 0; + FanTable.table[index].Size = sizeof(ctl_fan_temp_speed_t); + FanTable.table[index].temperature = (index + 1) * 10; + FanTable.table[index].speed.Size = sizeof(ctl_fan_speed_t); + FanTable.table[index].speed.Version = 0; + FanTable.table[index].speed.units = CTL_FAN_SPEED_UNITS_PERCENT; + FanTable.table[index].speed.speed = index * 10; + } + + res = ctlFanSetSpeedTableMode(pFanHandle[i], &FanTable); + if (res != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\n %s from Fan Set Speed Table Mode.", DecodeRetCode(res).c_str()); + } + else + { + PRINT_LOGS("\n[Fan] Set Speed Table Mode Success"); + } + + CtlFanTest_FanGetConfig(pFanHandle[i]); + + res = ctlFanSetDefaultMode(pFanHandle[i]); + if (res != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\n %s from Fan Set DEFAULT Speed Table Mode.", DecodeRetCode(res).c_str()); + } + else + { + PRINT_LOGS("\n[Fan] Set DEFAULT Speed Table Mode Success"); + } + + CtlFanTest_FanGetConfig(pFanHandle[i]); } cleanUp: @@ -820,10 +891,7 @@ void CtlEngineTest(ctl_device_adapter_handle_t hDAhandle) } else { - PRINT_LOGS("\n[Engine] Engine type [%s]", ((engineProperties.type == CTL_ENGINE_GROUP_GT) ? "Gt" : - (engineProperties.type == CTL_ENGINE_GROUP_RENDER) ? "Render" : - (engineProperties.type == CTL_ENGINE_GROUP_MEDIA) ? "Media" : - "Unknown")); + PRINT_LOGS("\n[Engine] Engine type [%s]", DecodeEngineGroup(engineProperties.type).c_str()); } ctl_engine_stats_t engineStats = { 0 }; @@ -865,612 +933,592 @@ void CtlEngineTest(ctl_device_adapter_handle_t hDAhandle) } /*************************************************************** - * @brief + * @brief Main Function * place_holder_for_Detailed_desc * @param * @return ***************************************************************/ -void CtlOverclockPropertiesTest(ctl_device_adapter_handle_t hDAhandle) +void CtlLedTest(ctl_device_adapter_handle_t hDAhandle) { + PRINT_LOGS("\n::::::::::::::Print Led Properties::::::::::::::\n"); - ctl_oc_properties_t OcProperties = {}; - OcProperties.Size = sizeof(ctl_oc_properties_t); - ctl_result_t status = ctlOverclockGetProperties(hDAhandle, &OcProperties); - - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - - PRINT_LOGS("\nOc Supported? %s", ((OcProperties.bSupported) ? "true" : "false")); - - PRINT_LOGS("\nGpu Frequency Offset Supported? %s", ((OcProperties.gpuFrequencyOffset.bSupported) ? "true" : "false")); - PRINT_LOGS("\nGpu Frequency Offset Is Relative? %s", ((OcProperties.gpuFrequencyOffset.bRelative) ? "true" : "false")); - PRINT_LOGS("\nGpu Frequency Offset Have Reference? %s", ((OcProperties.gpuFrequencyOffset.bReference) ? "true" : "false")); - PRINT_LOGS("\nGpu Frequency Offset Default: %f", OcProperties.gpuFrequencyOffset.Default); - PRINT_LOGS("\nGpu Frequency Offset Min: %f", OcProperties.gpuFrequencyOffset.min); - PRINT_LOGS("\nGpu Frequency Offset Max: %f", OcProperties.gpuFrequencyOffset.max); - PRINT_LOGS("\nGpu Frequency Offset Reference: %f", OcProperties.gpuFrequencyOffset.reference); - PRINT_LOGS("\nGpu Frequency Offset Step: %f", OcProperties.gpuFrequencyOffset.step); - PRINT_LOGS("\nGpu Frequency Offset Units: %s", printUnits(OcProperties.gpuFrequencyOffset.units)); - - PRINT_LOGS("\nGpu Voltage Offset Supported? %s", ((OcProperties.gpuVoltageOffset.bSupported) ? "true" : "false")); - PRINT_LOGS("\nGpu Voltage Offset Is Relative? %s", ((OcProperties.gpuVoltageOffset.bRelative) ? "true" : "false")); - PRINT_LOGS("\nGpu Voltage Offset Have Reference? %s", ((OcProperties.gpuVoltageOffset.bReference) ? "true" : "false")); - PRINT_LOGS("\nGpu Voltage Offset Default: %f", OcProperties.gpuVoltageOffset.Default); - PRINT_LOGS("\nGpu Voltage Offset Min: %f", OcProperties.gpuVoltageOffset.min); - PRINT_LOGS("\nGpu Voltage Offset Max: %f", OcProperties.gpuVoltageOffset.max); - PRINT_LOGS("\nGpu Voltage Offset Reference: %f", OcProperties.gpuVoltageOffset.reference); - PRINT_LOGS("\nGpu Voltage Offset Step: %f", OcProperties.gpuVoltageOffset.step); - PRINT_LOGS("\nGpu Voltage Offset Units: %s", printUnits(OcProperties.gpuVoltageOffset.units)); - - PRINT_LOGS("\nPower Limit Supported? %s", ((OcProperties.powerLimit.bSupported) ? "true" : "false")); - PRINT_LOGS("\nPower Limit Is Relative? %s", ((OcProperties.powerLimit.bRelative) ? "true" : "false")); - PRINT_LOGS("\nPower Limit Have Reference? %s", ((OcProperties.powerLimit.bReference) ? "true" : "false")); - PRINT_LOGS("\nPower Limit Default: %f", OcProperties.powerLimit.Default); - PRINT_LOGS("\nPower Limit Min: %f", OcProperties.powerLimit.min); - PRINT_LOGS("\nPower Limit Max: %f", OcProperties.powerLimit.max); - PRINT_LOGS("\nPower Limit Reference: %f", OcProperties.powerLimit.reference); - PRINT_LOGS("\nPower Limit Step: %f", OcProperties.powerLimit.step); - PRINT_LOGS("\nPower Limit Units: %s", printUnits(OcProperties.powerLimit.units)); - - PRINT_LOGS("\nTemperature Limit Supported? %s", ((OcProperties.temperatureLimit.bSupported) ? "true" : "false")); - PRINT_LOGS("\nTemperature Limit Is Relative? %s", ((OcProperties.temperatureLimit.bRelative) ? "true" : "false")); - PRINT_LOGS("\nTemperature Limit Have Reference? %s", ((OcProperties.temperatureLimit.bReference) ? "true" : "false")); - PRINT_LOGS("\nTemperature Limit Default: %f", OcProperties.temperatureLimit.Default); - PRINT_LOGS("\nTemperature Limit Min: %f", OcProperties.temperatureLimit.min); - PRINT_LOGS("\nTemperature Limit Max: %f", OcProperties.temperatureLimit.max); - PRINT_LOGS("\nTemperature Limit Reference: %f", OcProperties.temperatureLimit.reference); - PRINT_LOGS("\nTemperature Limit Step: %f", OcProperties.temperatureLimit.step); - PRINT_LOGS("\nTemperature Limit Units: %s", printUnits(OcProperties.temperatureLimit.units)); - } - else - { - PRINT_LOGS("\nError: %s", DecodeRetCode(status).c_str()); - } - - PRINT_LOGS("\n \n"); -} + ctl_result_t Result = CTL_RESULT_SUCCESS; + uint32_t LedCount = 0; + ctl_led_handle_t *pLedHandle = nullptr; + uint32_t Index = 0; -/*************************************************************** - * @brief - * place_holder_for_Detailed_desc - * @param - * @return - ***************************************************************/ -void CtlOverclockFrequencyOffsetTest(ctl_device_adapter_handle_t hDAhandle, double FreqOffset) -{ - double GPUFrequencyOffset = 0.0; - double VrelOffset = 0.0; - PRINT_LOGS("\n::::::::::::::Overclocking Tests::::::::::::::\n"); - PRINT_LOGS("\n::::::::::::::1.0 Frequency Offset::::::::::::::\n"); - PRINT_LOGS("\n::::::::::::::1.1 Get Frequency Offset::::::::::::::\n"); - PRINT_LOGS("\n1.1.1 Get Frequency Offset:::::::::::::::\n"); - ctl_result_t status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + Result = ctlEnumLeds(hDAhandle, &LedCount, pLedHandle); + if ((Result != CTL_RESULT_SUCCESS) || LedCount == 0) { - if (GPUFrequencyOffset == 0.0) - { - PRINT_LOGS("\nResult: Overclocking disabled, Frequency Offset is 0"); - } - else - { - PRINT_LOGS("\nResult: Overclocking enabled, Frequency Offset is:%f", GPUFrequencyOffset); - } + PRINT_LOGS("\nLed component not supported. Result: %s, LedCount %d", DecodeRetCode(Result).c_str(), LedCount); + return; } else { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + PRINT_LOGS("\nNumber of Led Handles [%u]", LedCount); } - GPUFrequencyOffset = FreqOffset; // Setting Offset to FreqOffset MHz - - PRINT_LOGS("\nSet Frequency Offset with: %f MHz", GPUFrequencyOffset); - status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET) - { - PRINT_LOGS("\nResult: Correctly returned: %s", DecodeRetCode(status).c_str()); - } - else + pLedHandle = (ctl_led_handle_t *)malloc(sizeof(ctl_led_handle_t) * LedCount); + if (pLedHandle == nullptr) { - PRINT_LOGS("\nResult: Incorrectly returned: %s", DecodeRetCode(status).c_str()); + PRINT_LOGS("\nNull pointer after malloc\n"); + return; } - status = ctlOverclockWaiverSet(hDAhandle); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Waiver Called correctly"); - } - else + Result = ctlEnumLeds(hDAhandle, &LedCount, pLedHandle); + if (Result != CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + PRINT_LOGS("\nError: %s for Led handle.", DecodeRetCode(Result).c_str()); + goto cleanUp; } - PRINT_LOGS("\nSet Frequency Offset with: %f MHz", GPUFrequencyOffset); - status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Frequency Offset Set Correctly "); - } - else + for (Index = 0; Index < LedCount; Index++) { - PRINT_LOGS("\nResult: Incorrectly returned: %s", DecodeRetCode(status).c_str()); - } + if (NULL != pLedHandle[Index]) + { + PRINT_LOGS("\n\n[Led] For pLedHandle[%u] = 0x%p\n", Index, pLedHandle[Index]); - status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking enabled, Frequency Offset is:%f", GPUFrequencyOffset); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + PRINT_LOGS("\n[Led] Get Led properties:"); - status = ctlOverclockGpuVoltageOffsetGet(hDAhandle, &VrelOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking enabled, Voltage Offset is:%f", VrelOffset); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + ctl_led_properties_t LedProperties = { 0 }; + LedProperties.Size = sizeof(ctl_led_properties_t); + Result = ctlLedGetProperties(pLedHandle[Index], &LedProperties); - GPUFrequencyOffset = 0.0; // Setting Offset to 0 MHz - VrelOffset = 0.0; + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Led get properties.\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Led] Can Control [%s]", DecodeBoolean(LedProperties.canControl).c_str()); + PRINT_LOGS("\n[Led] Is I2C [%s]", DecodeBoolean(LedProperties.isI2C).c_str()); + PRINT_LOGS("\n[Led] Is PWM [%s]", DecodeBoolean(LedProperties.isPWM).c_str()); + PRINT_LOGS("\n[Led] Have RGB [%s]", DecodeBoolean(LedProperties.haveRGB).c_str()); + } - status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Frequency Offset successfully Set to 0"); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + PRINT_LOGS("\n\n[Led] Get Led state:"); - status = ctlOverclockGpuVoltageOffsetSet(hDAhandle, VrelOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Voltage Offset successfully Set to 0"); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } - status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking disabled, Frequency Offset is:%f", GPUFrequencyOffset); + ctl_led_state_t ledState = { 0 }; + ledState.Size = sizeof(ctl_led_state_t); + Result = ctlLedGetState(pLedHandle[Index], &ledState); + + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Led get state.\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Led] Get Led State successful"); + PRINT_LOGS("\n[Led] IsOn [%s]", DecodeBoolean(ledState.isOn).c_str()); + PRINT_LOGS("\n[Led] PWM: Led On/Off Ratio [%f]", ledState.pwm); + PRINT_LOGS("\n[Led] Red color of Led [%f]", ledState.color.red); + PRINT_LOGS("\n[Led] Green color of Led [%f]", ledState.color.green); + PRINT_LOGS("\n[Led] Blue color of Led [%f]", ledState.color.blue); + } + + PRINT_LOGS("\n\n[Led] Set Led state:"); + + void *pBuffer = &ledState; + uint32_t bufferSize = sizeof(ctl_led_state_t); + Result = ctlLedSetState(pLedHandle[Index], pBuffer, bufferSize); + + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Led Set State\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Led] Successfully Set Led State\n"); + } + } } - else + +cleanUp: + if (pLedHandle != nullptr) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + free(pLedHandle); + pLedHandle = nullptr; } - status = ctlOverclockGpuVoltageOffsetGet(hDAhandle, &VrelOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + return; +} + +/*************************************************************** + * @brief Main Function + * place_holder_for_Detailed_desc + * @param + * @return + ***************************************************************/ +void CtlEccTest(ctl_device_adapter_handle_t hDAhandle) +{ + PRINT_LOGS("\n::::::::::::::Print Ecc Properties::::::::::::::\n"); + + // Get ECC Properites + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_ecc_properties_t EccProperties = { 0 }; + EccProperties.Size = sizeof(ctl_ecc_properties_t); + Result = ctlEccGetProperties(hDAhandle, &EccProperties); + + PRINT_LOGS("\n[Ecc] Get Ecc properties:"); + if (Result != CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Overclocking disabled, Voltage Offset is: %f", VrelOffset); + PRINT_LOGS("\nEcc component not supported. Result: %s", DecodeRetCode(Result).c_str()); + return; } else { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + PRINT_LOGS("\n[Ecc] Is Supported [%s]", DecodeBoolean(EccProperties.isSupported).c_str()); + PRINT_LOGS("\n[Ecc] Can Control [%s]", DecodeBoolean(EccProperties.canControl).c_str()); } - GPUFrequencyOffset = -FreqOffset; // Setting Offset to -FreqOffset MHz - status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + if (EccProperties.isSupported) { - PRINT_LOGS("\nResult: Overclocking enabled, Frequency Offset is:%f", GPUFrequencyOffset); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + // Get ECC State + ctl_ecc_state_desc_t eccState = { 0 }; + eccState.Size = sizeof(ctl_ecc_state_t); + Result = ctlEccGetState(hDAhandle, &eccState); + PRINT_LOGS("\n\n[Ecc] Get Ecc state:"); + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Ecc Get state.\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Ecc] Ecc Get State successful"); + PRINT_LOGS("\n[Ecc] Current Ecc State [%s]", DecodeEccState(eccState.currentEccState).c_str()); + PRINT_LOGS("\n[Ecc] Pending Ecc State [%s]", DecodeEccState(eccState.pendingEccState).c_str()); + } - status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking enabled, Frequency Offset is: %f", GPUFrequencyOffset); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + if (eccState.currentEccState != eccState.pendingEccState) + { + PRINT_LOGS("\n[Ecc] Pending Ecc State[%s] is not applied yet from previous Ecc Set Call. Please reboot the system for it to take affect.", + DecodeEccState(eccState.pendingEccState).c_str()); + return; + } + else + { + PRINT_LOGS("\n[Ecc] Pending Ecc State [%s] from previous Ecc Set Call applied and ECC state toggled successfully.", DecodeEccState(eccState.pendingEccState).c_str()); + } - GPUFrequencyOffset = 0.0; // Setting Offset to 0 MHz + if (EccProperties.canControl) + { + // Disabling ECC State if current ECC State is enabled and there is nothing to apply (currentEccState == pendingEccState) + if (eccState.currentEccState == CTL_ECC_STATE_ECC_ENABLED_STATE && eccState.currentEccState == eccState.pendingEccState) + { + eccState.currentEccState = CTL_ECC_STATE_ECC_DISABLED_STATE; + Result = ctlEccSetState(hDAhandle, &eccState); + PRINT_LOGS("\n\n[Ecc] Set Ecc state:"); + PRINT_LOGS("\n\n[Ecc] Disabling Ecc state [%s]", DecodeEccState(eccState.currentEccState).c_str()); + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Ecc Set State\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Ecc] Ecc Set State call successful\n"); + PRINT_LOGS("\n[Ecc] Pending Ecc State to be applied from Ecc Set State call [%s]", DecodeEccState(eccState.pendingEccState).c_str()); + } + } + // Enabling ECC State if current ECC State if disabled and there is nothing to apply (currentEccState == pendingEccState) + else if (eccState.currentEccState == CTL_ECC_STATE_ECC_DISABLED_STATE && eccState.currentEccState == eccState.pendingEccState) + { + eccState.currentEccState = CTL_ECC_STATE_ECC_ENABLED_STATE; + Result = ctlEccSetState(hDAhandle, &eccState); + PRINT_LOGS("\n\n[Ecc] Set Ecc state:"); + PRINT_LOGS("\n\n[Ecc] Enabling Ecc state [%s]", DecodeEccState(eccState.currentEccState).c_str()); + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Ecc Set State\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Ecc] Ecc Set State call successful\n"); + PRINT_LOGS("\n[Ecc] Pending Ecc State to be applied from Ecc Set State call [%s]", DecodeEccState(eccState.pendingEccState).c_str()); + } + } - status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Offset successfully Set to 0"); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + // Retrieving back ECC State after Ecc Set State call to determine if currentEccState == pendingEccState + Result = ctlEccGetState(hDAhandle, &eccState); + PRINT_LOGS("\n\n[Ecc] Get Ecc state again:"); + if (Result != CTL_RESULT_SUCCESS) + { + PRINT_LOGS("\nError: %s from Ecc Get state.\n", DecodeRetCode(Result).c_str()); + } + else + { + PRINT_LOGS("\n[Ecc] Ecc Get State successful"); + PRINT_LOGS("\n[Ecc] Current Ecc State [%s]", DecodeEccState(eccState.currentEccState).c_str()); + PRINT_LOGS("\n[Ecc] Pending Ecc State [%s]", DecodeEccState(eccState.pendingEccState).c_str()); + } - status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking disabled, Frequency Offset is:%f", GPUFrequencyOffset); + // System reboot is needed always if currentEccState != pendingEccState for the pendingEccState to be applied + if (eccState.currentEccState != eccState.pendingEccState) + { + PRINT_LOGS("\n[Ecc] Pending Ecc State [%s] is not applied yet after the Ecc Set State call. Please reboot the system for it to take affect.", + DecodeEccState(eccState.pendingEccState).c_str()); + } + } + else + { + PRINT_LOGS("\n[Ecc] Ecc state cannot be changed on this system."); + } } else { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + PRINT_LOGS("\n[Ecc] ECC is not supported on this system."); } - PRINT_LOGS("\n \n"); + return; } -/*************************************************************** - * @brief - * place_holder_for_Detailed_desc - * @param - * @return - ***************************************************************/ -void CtlOverclockFrequencyAndVoltageOffsetTest(ctl_device_adapter_handle_t hDAhandle) +void CtlPowerTelemetryTest(ctl_device_adapter_handle_t hDAhandle) { - double GPUFrequencyOffset = 0.0; - double VrelOffset = 0.0; + ctl_power_telemetry_t pPowerTelemetry = {}; + pPowerTelemetry.Size = sizeof(ctl_power_telemetry_t); + pPowerTelemetry.Version = 1; - GPUFrequencyOffset = 100.0; - VrelOffset = 50; // in mV + ctl_result_t Status = ctlPowerTelemetryGet(hDAhandle, &pPowerTelemetry); - PRINT_LOGS("\nSet Frequency Offset with: %f MHz Vrel Offset: %f", GPUFrequencyOffset, VrelOffset); + static bool firstSample = true; + double timeDiff = 0.0; - ctl_result_t status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Frequency Offset Set Correctly "); - } - else + if (Status == ctl_result_t::CTL_RESULT_SUCCESS) { - PRINT_LOGS("\nResult: Incorrectly returned: %s", DecodeRetCode(status).c_str()); - } + PRINT_LOGS("\nTelemetry Success\n \n"); - status = ctlOverclockGpuVoltageOffsetSet(hDAhandle, VrelOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Vrel Offset Set Correctly "); - } - else - { - PRINT_LOGS("\nResult: Incorrectly returned: %s", DecodeRetCode(status).c_str()); - } - PRINT_LOGS("\n2.1.4 Get Modified Frequency and Vrel Offset:::::::::::::::\n"); - if (ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset) == ctl_result_t::CTL_RESULT_SUCCESS && - ctlOverclockGpuVoltageOffsetGet(hDAhandle, &VrelOffset) == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking enabled, Frequency Offset is: %f Vrel Offset is: %f", GPUFrequencyOffset, VrelOffset); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + if (pPowerTelemetry.timeStamp.bSupported) + { + PRINT_LOGS("\nTimeStamp: %f (%s) Datatype:(%s)", pPowerTelemetry.timeStamp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.timeStamp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.timeStamp.type).c_str()); - PRINT_LOGS("\n2.1.5 Set Frequency Offset to 0 MHz and Vrel Offset to 0 v to disable OC:::::::::::::::\n"); - GPUFrequencyOffset = 0.0; // Setting Offset to 0 MHz - VrelOffset = 0.0; + // Calculate time difference between current and previous timestamp + static double prevTimeStamp = 0.0; + if (!firstSample) + { + timeDiff = pPowerTelemetry.timeStamp.value.datadouble - prevTimeStamp; + } + prevTimeStamp = pPowerTelemetry.timeStamp.value.datadouble; + } - status = ctlOverclockGpuFrequencyOffsetSet(hDAhandle, GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Frequency Offset successfully Set to 0"); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + if (pPowerTelemetry.gpuEnergyCounter.bSupported) + { + PRINT_LOGS("\nGpu Energy Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuEnergyCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuEnergyCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuEnergyCounter.type).c_str()); - status = ctlOverclockGpuVoltageOffsetSet(hDAhandle, VrelOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Voltage Offset successfully Set to 0"); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + // Calculate and display power based on energy counter if we have previous values + static double prevGpuEnergyCounter = 0.0; + if (!firstSample && pPowerTelemetry.timeStamp.bSupported) + { + double energyDiff = pPowerTelemetry.gpuEnergyCounter.value.datadouble - prevGpuEnergyCounter; + if (timeDiff > 0.0) + { + double powerWatts = energyDiff / timeDiff; + PRINT_LOGS("GPU Power (calculated): %f Watts", powerWatts); + } + } + prevGpuEnergyCounter = pPowerTelemetry.gpuEnergyCounter.value.datadouble; + } - PRINT_LOGS("\n2.1.6 Reading Back Frequency Offset to confirm OC is disabled:::::::::::::::\n"); - status = ctlOverclockGpuFrequencyOffsetGet(hDAhandle, &GPUFrequencyOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking disabled, Frequency Offset is:%f", GPUFrequencyOffset); - } - else - { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); - } + if (pPowerTelemetry.vramEnergyCounter.bSupported) + { + PRINT_LOGS("\nVRAM Energy Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.vramEnergyCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramEnergyCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramEnergyCounter.type).c_str()); - status = ctlOverclockGpuVoltageOffsetGet(hDAhandle, &VrelOffset); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nResult: Overclocking disabled, Voltage Offset is: %f", VrelOffset); + // Calculate and display VRAM power based on energy counter if we have previous values + static double prevVramEnergyCounter = 0.0; + if (!firstSample && pPowerTelemetry.timeStamp.bSupported) + { + double energyDiff = pPowerTelemetry.vramEnergyCounter.value.datadouble - prevVramEnergyCounter; + if (timeDiff > 0.0) + { + double powerWatts = energyDiff / timeDiff; + PRINT_LOGS("VRAM Power (calculated): %f Watts", powerWatts); + } + } + prevVramEnergyCounter = pPowerTelemetry.vramEnergyCounter.value.datadouble; + } + + if (pPowerTelemetry.totalCardEnergyCounter.bSupported) + { + PRINT_LOGS("\nCard Energy Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.totalCardEnergyCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.totalCardEnergyCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.totalCardEnergyCounter.type).c_str()); + + // Calculate and display total card power based on energy counter if we have previous values + static double prevTotalCardEnergyCounter = 0.0; + if (!firstSample && pPowerTelemetry.timeStamp.bSupported) + { + double energyDiff = pPowerTelemetry.totalCardEnergyCounter.value.datadouble - prevTotalCardEnergyCounter; + if (timeDiff > 0.0) + { + double powerWatts = energyDiff / timeDiff; + PRINT_LOGS("Total Card Power (calculated): %f Watts", powerWatts); + } + } + prevTotalCardEnergyCounter = pPowerTelemetry.totalCardEnergyCounter.value.datadouble; + } + + if (pPowerTelemetry.gpuVoltage.bSupported) + { + PRINT_LOGS("\nGpu Voltage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuVoltage.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuVoltage.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuVoltage.type).c_str()); + } + + if (pPowerTelemetry.gpuCurrentClockFrequency.bSupported) + { + PRINT_LOGS("\nGpu Current Frequency: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuCurrentClockFrequency.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.gpuCurrentClockFrequency.units).c_str(), DecodeCtlDataType(pPowerTelemetry.gpuCurrentClockFrequency.type).c_str()); + } + + if (pPowerTelemetry.gpuCurrentTemperature.bSupported) + { + PRINT_LOGS("\nGpu Current Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuCurrentTemperature.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuCurrentTemperature.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuCurrentTemperature.type).c_str()); + } + + if (pPowerTelemetry.globalActivityCounter.bSupported) + { + PRINT_LOGS("\nGpu Activity Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.globalActivityCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.globalActivityCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.globalActivityCounter.type).c_str()); + + // Calculate and display GPU utilization based on global activity counter + static double prevGlobalActivityCounter = 0.0; + if (!firstSample && pPowerTelemetry.timeStamp.bSupported) + { + double activityDiff = pPowerTelemetry.globalActivityCounter.value.datadouble - prevGlobalActivityCounter; + if (timeDiff > 0.0) + { + double utilization = (activityDiff / timeDiff) * 100.0; // Convert to percentage + PRINT_LOGS("GPU Utilization (calculated): %f%%", utilization); + } + } + prevGlobalActivityCounter = pPowerTelemetry.globalActivityCounter.value.datadouble; + } + + if (pPowerTelemetry.renderComputeActivityCounter.bSupported) + { + PRINT_LOGS("\nRender Activity Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.renderComputeActivityCounter.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.renderComputeActivityCounter.units).c_str(), DecodeCtlDataType(pPowerTelemetry.renderComputeActivityCounter.type).c_str()); + + // Calculate and display renderCompute utilization based on renderCompute activity counter + static double prevRenderComputeActivityCounter = 0.0; + if (!firstSample && pPowerTelemetry.timeStamp.bSupported) + { + double activityDiff = pPowerTelemetry.renderComputeActivityCounter.value.datadouble - prevRenderComputeActivityCounter; + if (timeDiff > 0.0) + { + double utilization = (activityDiff / timeDiff) * 100.0; // Convert to percentage + PRINT_LOGS("RenderCompute Utilization (calculated): %f%%", utilization); + } + } + prevRenderComputeActivityCounter = pPowerTelemetry.renderComputeActivityCounter.value.datadouble; + } + + if (pPowerTelemetry.mediaActivityCounter.bSupported) + { + PRINT_LOGS("\nMedia Activity Counter: %f (%s) Datatype:(%s)", pPowerTelemetry.mediaActivityCounter.value.datadouble, DecodeCtlUnits(pPowerTelemetry.mediaActivityCounter.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.mediaActivityCounter.type).c_str()); + + // Calculate and display media utilization based on media activity counter + static double prevMediaActivityCounter = 0.0; + if (!firstSample && pPowerTelemetry.timeStamp.bSupported) + { + double activityDiff = pPowerTelemetry.mediaActivityCounter.value.datadouble - prevMediaActivityCounter; + if (timeDiff > 0.0) + { + double utilization = (activityDiff / timeDiff) * 100.0; // Convert to percentage + PRINT_LOGS("Media Utilization (calculated): %f%%", utilization); + } + } + prevMediaActivityCounter = pPowerTelemetry.mediaActivityCounter.value.datadouble; + } + + if (pPowerTelemetry.vramVoltage.bSupported) + { + PRINT_LOGS("\nVRAM Voltage: %f (%s) Datatype:(%s)", pPowerTelemetry.vramVoltage.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramVoltage.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramVoltage.type).c_str()); + } + + if (pPowerTelemetry.vramCurrentClockFrequency.bSupported) + { + PRINT_LOGS("\nVRAM Frequency: %f (%s) Datatype:(%s)", pPowerTelemetry.vramCurrentClockFrequency.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramCurrentClockFrequency.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramCurrentClockFrequency.type).c_str()); + } + + if (pPowerTelemetry.vramReadBandwidthCounter.bSupported) + { + PRINT_LOGS("\nVRAM Read Bandwidth Counter: %llu (%s) Datatype:(%s)", pPowerTelemetry.vramReadBandwidthCounter.value.datau64, + DecodeCtlUnits(pPowerTelemetry.vramReadBandwidthCounter.units).c_str(), DecodeCtlDataType(pPowerTelemetry.vramReadBandwidthCounter.type).c_str()); + } + + if (pPowerTelemetry.vramWriteBandwidthCounter.bSupported) + { + PRINT_LOGS("\nVRAM Write Bandwidth Counter: %llu (%s) Datatype:(%s)", pPowerTelemetry.vramWriteBandwidthCounter.value.datau64, + DecodeCtlUnits(pPowerTelemetry.vramWriteBandwidthCounter.units).c_str(), DecodeCtlDataType(pPowerTelemetry.vramWriteBandwidthCounter.type).c_str()); + } + + if (pPowerTelemetry.vramCurrentEffectiveFrequency.bSupported) + { + PRINT_LOGS("\nVRAM Effective Frequency: %f (%s) Datatype:(%s)", pPowerTelemetry.vramCurrentEffectiveFrequency.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.vramCurrentEffectiveFrequency.units).c_str(), DecodeCtlDataType(pPowerTelemetry.vramCurrentEffectiveFrequency.type).c_str()); + } + + if (pPowerTelemetry.vramCurrentTemperature.bSupported) + { + PRINT_LOGS("\nVRAM Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.vramCurrentTemperature.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramCurrentTemperature.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramCurrentTemperature.type).c_str()); + } + + if (pPowerTelemetry.vramReadBandwidth.bSupported) + { + PRINT_LOGS("\nVRAM Read Bandwidth: %f (%s) Datatype:(%s)", pPowerTelemetry.vramReadBandwidth.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramReadBandwidth.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramReadBandwidth.type).c_str()); + } + + if (pPowerTelemetry.vramWriteBandwidth.bSupported) + { + PRINT_LOGS("\nVRAM Write Bandwidth: %f (%s) Datatype:(%s)", pPowerTelemetry.vramWriteBandwidth.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramWriteBandwidth.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramWriteBandwidth.type).c_str()); + } + + if (pPowerTelemetry.gpuVrTemp.bSupported) + { + PRINT_LOGS("\nGPU VR Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuVrTemp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuVrTemp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuVrTemp.type).c_str()); + } + + if (pPowerTelemetry.vramVrTemp.bSupported) + { + PRINT_LOGS("\nVRAM VR Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.vramVrTemp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.vramVrTemp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.vramVrTemp.type).c_str()); + } + + if (pPowerTelemetry.saVrTemp.bSupported) + { + PRINT_LOGS("\nSA VR Temperature: %f (%s) Datatype:(%s)", pPowerTelemetry.saVrTemp.value.datadouble, DecodeCtlUnits(pPowerTelemetry.saVrTemp.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.saVrTemp.type).c_str()); + } + + if (pPowerTelemetry.gpuEffectiveClock.bSupported) + { + PRINT_LOGS("\nEffective frequency of the GPU: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuEffectiveClock.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuEffectiveClock.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuEffectiveClock.type).c_str()); + } + + if (pPowerTelemetry.gpuOverVoltagePercent.bSupported) + { + PRINT_LOGS("\nGPU Overvoltage Percentage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuOverVoltagePercent.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.gpuOverVoltagePercent.units).c_str(), DecodeCtlDataType(pPowerTelemetry.gpuOverVoltagePercent.type).c_str()); + } + + if (pPowerTelemetry.gpuPowerPercent.bSupported) + { + PRINT_LOGS("\nGPU Power Percentage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuPowerPercent.value.datadouble, DecodeCtlUnits(pPowerTelemetry.gpuPowerPercent.units).c_str(), + DecodeCtlDataType(pPowerTelemetry.gpuPowerPercent.type).c_str()); + } + + if (pPowerTelemetry.gpuTemperaturePercent.bSupported) + { + PRINT_LOGS("\nGPU Temperature Percentage: %f (%s) Datatype:(%s)", pPowerTelemetry.gpuTemperaturePercent.value.datadouble, + DecodeCtlUnits(pPowerTelemetry.gpuTemperaturePercent.units).c_str(), DecodeCtlDataType(pPowerTelemetry.gpuTemperaturePercent.type).c_str()); + } + + for (int i = 0; i < CTL_FAN_COUNT; i++) + { + if (pPowerTelemetry.fanSpeed[i].bSupported) + { + PRINT_LOGS("\nFan[%d] Speed: %f (%s) Datatype:(%s)", i, pPowerTelemetry.fanSpeed[i].value.datadouble, DecodeCtlUnits(pPowerTelemetry.fanSpeed[i].units).c_str(), + DecodeCtlDataType(pPowerTelemetry.fanSpeed[i].type).c_str()); + } + } + + PRINT_LOGS("\ngpuPowerLimited: %s", DecodeBoolean(pPowerTelemetry.gpuPowerLimited).c_str()); + PRINT_LOGS("\ngpuTemperatureLimited: %s", DecodeBoolean(pPowerTelemetry.gpuTemperatureLimited).c_str()); + PRINT_LOGS("\ngpuCurrentLimited: %s", DecodeBoolean(pPowerTelemetry.gpuCurrentLimited).c_str()); + PRINT_LOGS("\ngpuVoltageLimited: %s", DecodeBoolean(pPowerTelemetry.gpuVoltageLimited).c_str()); + PRINT_LOGS("\ngpuUtilizationLimited: %s", DecodeBoolean(pPowerTelemetry.gpuUtilizationLimited).c_str()); + + firstSample = false; } else { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + PRINT_LOGS("\nCtlPowerTelemetryTest => ctlPowerTelemetryGet Result Error: %s, ErrorCode: 0x%x \n \n", DecodeRetCode(Status).c_str(), Status); } - - PRINT_LOGS("\n \n"); } -/*************************************************************** - * @brief Main Function - * - * place_holder_for_Detailed_desc - * @param - * @return - ***************************************************************/ -void CtlOverclockPowerTest(ctl_device_adapter_handle_t hDAhandle) +void PerComponentTest(ctl_device_adapter_handle_t hDAhandle) { - PRINT_LOGS("\n::::::::::::::Print Power Limit::::::::::::::\n"); - - ctl_oc_properties_t OcProperties = {}; - OcProperties.Size = sizeof(ctl_oc_properties_t); - ctl_result_t status = ctlOverclockGetProperties(hDAhandle, &OcProperties); - - if (status != ctl_result_t::CTL_RESULT_SUCCESS) + try { - PRINT_LOGS("\nError Getting Properties%s", DecodeRetCode(status).c_str()); - return; + CtlPowerTest(hDAhandle); } - - PRINT_LOGS("\nGetting current Power Limit\n"); - double CurrentPowerLimit = 0.0; - - status = ctlOverclockPowerLimitGet(hDAhandle, &CurrentPowerLimit); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nCurrent Sustained Power Limit: %f", CurrentPowerLimit); + printf("%s \n", e.what()); } - else + try { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + CtlFrequencyTest(hDAhandle); } - - PRINT_LOGS("\n\nSetting current Power Limit outside limits:"); - - // Convert to mW and get min -1 W to be out of bounds - CurrentPowerLimit = OcProperties.powerLimit.min * 1000.0 - 1000.0; - - status = ctlOverclockPowerLimitSet(hDAhandle, CurrentPowerLimit); - if (status == ctl_result_t::CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE) + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nCorrectly returned out of bounds."); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n\nSetting current Power Limit inside limits:\n"); - // Convert to mW and get min + 1 W to be in bounds. - CurrentPowerLimit = OcProperties.powerLimit.min * 1000.0 + 1000.0; - - status = ctlOverclockPowerLimitSet(hDAhandle, CurrentPowerLimit); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + try { - PRINT_LOGS("\nPower Limit set correctly."); + CtlEngineTest(hDAhandle); } - else + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n\nGetting the now current Power Limit:\n"); - - double NewCurrentPowerLimit = 0.0; - - status = ctlOverclockPowerLimitGet(hDAhandle, &NewCurrentPowerLimit); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + try { - PRINT_LOGS("\nCurrent Sustained Power Limit: %f", NewCurrentPowerLimit); - PRINT_LOGS("\nRequested Sustained Power Limit: %f", CurrentPowerLimit); + CtlTemperatureTest(hDAhandle); } - else + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n \n"); -} - -/*************************************************************** - * @brief Main Function - * - * place_holder_for_Detailed_desc - * @param - * @return - ***************************************************************/ -void CtlOverclockTemperatureTest(ctl_device_adapter_handle_t hDAhandle) -{ - PRINT_LOGS("\n::::::::::::::Print Temperature Limit::::::::::::::\n"); - - ctl_oc_properties_t OcProperties = {}; - OcProperties.Size = sizeof(ctl_oc_properties_t); - ctl_result_t status = ctlOverclockGetProperties(hDAhandle, &OcProperties); - - if (status != ctl_result_t::CTL_RESULT_SUCCESS) + try { - PRINT_LOGS("\nError Getting Properties %s", DecodeRetCode(status).c_str()); - return; + CtlMemoryTest(hDAhandle); } - - PRINT_LOGS("\nGetting current Temperature Limit \n"); - double CurrentTemperatureLimit = 0.0; - - status = ctlOverclockTemperatureLimitGet(hDAhandle, &CurrentTemperatureLimit); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nCurrent Temperature Limit: %f", CurrentTemperatureLimit); + printf("%s \n", e.what()); } - else + try { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + CtlPciTest(hDAhandle); } - - PRINT_LOGS("\n\nSetting current Temperature Limit outside limits: \n"); - - CurrentTemperatureLimit = OcProperties.temperatureLimit.min - 1.0; - - status = ctlOverclockTemperatureLimitSet(hDAhandle, CurrentTemperatureLimit); - if (status == ctl_result_t::CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE) + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nCorrectly returned out of bounds."); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n\nSetting current Temperature Limit inside limits: \n"); - - CurrentTemperatureLimit = OcProperties.temperatureLimit.min + 1.0; - - status = ctlOverclockTemperatureLimitSet(hDAhandle, CurrentTemperatureLimit); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + try { - PRINT_LOGS("\nTemperature Limit set correctly."); + CtlFanTest(hDAhandle); } - else + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n\nGetting the now current Temperature Limit: \n"); - - double NewCurrentTemperatureLimit = 0.0; - - status = ctlOverclockTemperatureLimitGet(hDAhandle, &NewCurrentTemperatureLimit); - if (status == ctl_result_t::CTL_RESULT_SUCCESS) + try { - PRINT_LOGS("\nCurrent Temperature Limit: %f", NewCurrentTemperatureLimit); - PRINT_LOGS("\nRequested Temperature Limit: %f", CurrentTemperatureLimit); + CtlLedTest(hDAhandle); } - else + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nResult: Error %s", DecodeRetCode(status).c_str()); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n \n"); -} - -/*************************************************************** - * @brief Main Function - * - * place_holder_for_Detailed_desc - * @param - * @return - ***************************************************************/ -void CtlPowerTelemetryTest(ctl_device_adapter_handle_t hDAhandle) -{ - PRINT_LOGS("\n:: :: :: :: :: :: ::Print Telemetry:: :: :: :: :: :: ::\n"); - - ctl_power_telemetry_t pPowerTelemetry = {}; - pPowerTelemetry.Size = sizeof(ctl_power_telemetry_t); - ctl_result_t status = ctlPowerTelemetryGet(hDAhandle, &pPowerTelemetry); - - if (status == ctl_result_t::CTL_RESULT_SUCCESS) - { - PRINT_LOGS("\nTelemetry Success \n"); - - PRINT_LOGS("\nTimeStamp:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.timeStamp.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.timeStamp.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.timeStamp.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.timeStamp.value.datadouble); - - PRINT_LOGS("\nGpu Energy Counter:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.gpuEnergyCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuEnergyCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuEnergyCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.gpuEnergyCounter.value.datadouble); - - PRINT_LOGS("\nGpu Voltage:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.gpuVoltage.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuVoltage.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuVoltage.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.gpuVoltage.value.datadouble); - - PRINT_LOGS("\nGpu Current Frequency:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.gpuCurrentClockFrequency.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuCurrentClockFrequency.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuCurrentClockFrequency.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.gpuCurrentClockFrequency.value.datadouble); - - PRINT_LOGS("\nGpu Current Temperature:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.gpuCurrentTemperature.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.gpuCurrentTemperature.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.gpuCurrentTemperature.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.gpuCurrentTemperature.value.datadouble); - - PRINT_LOGS("\nGpu Activity Counter:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.globalActivityCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.globalActivityCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.globalActivityCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.globalActivityCounter.value.datadouble); - - PRINT_LOGS("\nRender Activity Counter:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.renderComputeActivityCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.renderComputeActivityCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.renderComputeActivityCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.renderComputeActivityCounter.value.datadouble); - - PRINT_LOGS("\nMedia Activity Counter:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.mediaActivityCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.mediaActivityCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.mediaActivityCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.mediaActivityCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Energy Counter:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramEnergyCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramEnergyCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramEnergyCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramEnergyCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Voltage:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramVoltage.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramVoltage.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramVoltage.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramVoltage.value.datadouble); - - PRINT_LOGS("\nVRAM Frequency:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramCurrentClockFrequency.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramCurrentClockFrequency.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramCurrentClockFrequency.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramCurrentClockFrequency.value.datadouble); - - PRINT_LOGS("\nVRAM Effective Frequency:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramCurrentEffectiveFrequency.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramCurrentEffectiveFrequency.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramCurrentEffectiveFrequency.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramCurrentEffectiveFrequency.value.datadouble); - - PRINT_LOGS("\nVRAM Read Bandwidth:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramReadBandwidthCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramReadBandwidthCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramReadBandwidthCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramReadBandwidthCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Write Bandwidth:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramWriteBandwidthCounter.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramWriteBandwidthCounter.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramWriteBandwidthCounter.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramWriteBandwidthCounter.value.datadouble); - - PRINT_LOGS("\nVRAM Temperature:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.vramCurrentTemperature.bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.vramCurrentTemperature.units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.vramCurrentTemperature.type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.vramCurrentTemperature.value.datadouble); - - PRINT_LOGS("\nFan Speed:"); - PRINT_LOGS("\nSupported: %s", ((pPowerTelemetry.fanSpeed[0].bSupported) ? "true" : "false")); - PRINT_LOGS("\nUnits: %s", printUnits(pPowerTelemetry.fanSpeed[0].units)); - PRINT_LOGS("\nType: %s", printType(pPowerTelemetry.fanSpeed[0].type)); - PRINT_LOGS("\nValue: %f", pPowerTelemetry.fanSpeed[0].value.datadouble); + try + { + CtlEccTest(hDAhandle); } - else + catch (const std::bad_array_new_length &e) { - PRINT_LOGS("\nError: %s", DecodeRetCode(status).c_str()); + printf("%s \n", e.what()); } - - PRINT_LOGS("\n \n"); } /*************************************************************** @@ -1496,18 +1544,34 @@ int main() ctl_init_args_t CtlInitArgs; ctl_api_handle_t hAPIHandle; CtlInitArgs.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION); - CtlInitArgs.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO; + CtlInitArgs.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO | CTL_INIT_FLAG_IGSC_FUL; CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; ZeroMemory(&CtlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); - Result = ctlInit(&CtlInitArgs, &hAPIHandle); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } if (CTL_RESULT_SUCCESS == Result) { @@ -1516,12 +1580,20 @@ int main() { return ERROR; } - Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &Adapter_count, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } } if (CTL_RESULT_SUCCESS != Result) { printf("ctlEnumerateDevices returned failure code: 0x%X\n", Result); - goto free_exit; + goto Exit; } for (Index = 0; Index < Adapter_count; Index++) @@ -1550,11 +1622,7 @@ int main() if (CTL_DEVICE_TYPE_GRAPHICS != StDeviceAdapterProperties.device_type) { printf("This is not a Graphics device \n"); - - if (NULL != StDeviceAdapterProperties.pDeviceID) - { - free(StDeviceAdapterProperties.pDeviceID); - } + CTL_FREE_MEM(StDeviceAdapterProperties.pDeviceID); continue; } @@ -1575,180 +1643,32 @@ int main() } // Per Component Tests - CtlPowerTest(hDevices[Index]); - CtlFrequencyTest(hDevices[Index]); - CtlEngineTest(hDevices[Index]); - CtlTemperatureTest(hDevices[Index]); - CtlMemoryTest(hDevices[Index]); - CtlPciTest(hDevices[Index]); - CtlFanTest(hDevices[Index]); - - // Overclocking Test - CtlOverclockPropertiesTest(hDevices[Index]); - - std::vector vFrequencies; - vFrequencies.push_back(10.0); - vFrequencies.push_back(30.0); - vFrequencies.push_back(50.0); - vFrequencies.push_back(75.0); - vFrequencies.push_back(100.0); - vFrequencies.push_back(150.0); - vFrequencies.push_back(200.0); - vFrequencies.push_back(250.0); - - for (uint32_t ci = 0; ci < vFrequencies.size(); ci++) - { - CtlOverclockFrequencyOffsetTest(hDevices[Index], vFrequencies[ci]); - } - - CtlOverclockFrequencyAndVoltageOffsetTest(hDevices[Index]); - - CtlOverclockPowerTest(hDevices[Index]); - CtlOverclockTemperatureTest(hDevices[Index]); + PerComponentTest(hDevices[Index]); // Telemetry Test // Polling during 1 second at 20 ms for (uint32_t i = 0; i < 50; i++) { - CtlPowerTelemetryTest(hDevices[Index]); + try + { + CtlPowerTelemetryTest(hDevices[Index]); + } + catch (const std::bad_array_new_length &e) + { + printf("%s \n", e.what()); + } Sleep(20); } - if (NULL != StDeviceAdapterProperties.pDeviceID) - { - free(StDeviceAdapterProperties.pDeviceID); - } + CTL_FREE_MEM(StDeviceAdapterProperties.pDeviceID); } } } -free_exit: +Exit: ctlClose(hAPIHandle); - - if (hDevices != nullptr) - { - free(hDevices); - hDevices = nullptr; - } + CTL_FREE_MEM(hDevices); return 0; -} - -// Decoding the return code for the most common error codes. -std::string DecodeRetCode(ctl_result_t Res) -{ - switch (Res) - { - case CTL_RESULT_SUCCESS: - { - return std::string("[CTL_RESULT_SUCCESS]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE]"); - } - case CTL_RESULT_ERROR_GENERIC_START: - { - return std::string("[CTL_RESULT_ERROR_GENERIC_START]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED]"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE"); - } - case CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET: - { - return std::string("[CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET]"); - } - case CTL_RESULT_ERROR_NOT_INITIALIZED: - { - return std::string("[CTL_RESULT_ERROR_NOT_INITIALIZED]"); - } - case CTL_RESULT_ERROR_ALREADY_INITIALIZED: - { - return std::string("[CTL_RESULT_ERROR_ALREADY_INITIALIZED]"); - } - case CTL_RESULT_ERROR_DEVICE_LOST: - { - return std::string("[CTL_RESULT_ERROR_DEVICE_LOST]"); - } - case CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS: - { - return std::string("[CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS]"); - } - case CTL_RESULT_ERROR_NOT_AVAILABLE: - { - return std::string("[CTL_RESULT_ERROR_NOT_AVAILABLE]"); - } - case CTL_RESULT_ERROR_UNINITIALIZED: - { - return std::string("[CTL_RESULT_ERROR_UNINITIALIZED]"); - } - case CTL_RESULT_ERROR_UNSUPPORTED_VERSION: - { - return std::string("[CTL_RESULT_ERROR_UNSUPPORTED_VERSION]"); - } - case CTL_RESULT_ERROR_UNSUPPORTED_FEATURE: - { - return std::string("[CTL_RESULT_ERROR_UNSUPPORTED_FEATURE]"); - } - case CTL_RESULT_ERROR_INVALID_ARGUMENT: - { - return std::string("[CTL_RESULT_ERROR_INVALID_ARGUMENT]"); - } - case CTL_RESULT_ERROR_INVALID_NULL_HANDLE: - { - return std::string("[CTL_RESULT_ERROR_INVALID_NULL_HANDLE]"); - } - case CTL_RESULT_ERROR_INVALID_NULL_POINTER: - { - return std::string("[CTL_RESULT_ERROR_INVALID_NULL_POINTER]"); - } - case CTL_RESULT_ERROR_INVALID_SIZE: - { - return std::string("[CTL_RESULT_ERROR_INVALID_SIZE]"); - } - case CTL_RESULT_ERROR_UNSUPPORTED_SIZE: - { - return std::string("[CTL_RESULT_ERROR_UNSUPPORTED_SIZE]"); - } - case CTL_RESULT_ERROR_NOT_IMPLEMENTED: - { - return std::string("[CTL_RESULT_ERROR_NOT_IMPLEMENTED]"); - } - case CTL_RESULT_ERROR_ZE_LOADER: - { - return std::string("[CTL_RESULT_ERROR_ZE_LOADER]"); - } - case CTL_RESULT_ERROR_INVALID_OPERATION_TYPE: - { - return std::string("[CTL_RESULT_ERROR_INVALID_OPERATION_TYPE]"); - } - case CTL_RESULT_ERROR_UNKNOWN: - { - return std::string("[CTL_RESULT_ERROR_UNKNOWN]"); - } - default: - return std::string("[Unknown Error]"); - } -} +} \ No newline at end of file diff --git a/Samples/ToothNClawWrapper/CMakeLists.txt b/Samples/ToothNClawWrapper/CMakeLists.txt new file mode 100644 index 0000000..7384b98 --- /dev/null +++ b/Samples/ToothNClawWrapper/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.9) + +get_filename_component(ROOT_DIR ../../ ABSOLUTE) +set(project "IGCL_Wrapper") + +set(all_file + "Wrapper.cpp" + "ColorAlgorithms_App.cpp" + ${ROOT_DIR}/Source/cApiWrapper.cpp +) + +set(BUILD_SHARED_LIBS true) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true) + +include_directories(${ROOT_DIR}/include) +include_directories(${ROOT_DIR}/Samples/inc) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +add_library(${project} ${all_file}) \ No newline at end of file diff --git a/Samples/ToothNClawWrapper/CMakeSettings.json b/Samples/ToothNClawWrapper/CMakeSettings.json new file mode 100644 index 0000000..0c5fbf9 --- /dev/null +++ b/Samples/ToothNClawWrapper/CMakeSettings.json @@ -0,0 +1,27 @@ +{ + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "" + }, + { + "name": "x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [] + } + ] +} \ No newline at end of file diff --git a/Samples/ToothNClawWrapper/ColorAlgorithms.cpp b/Samples/ToothNClawWrapper/ColorAlgorithms.cpp new file mode 100644 index 0000000..b3daac2 --- /dev/null +++ b/Samples/ToothNClawWrapper/ColorAlgorithms.cpp @@ -0,0 +1,229 @@ +//=========================================================================== +// +// Copyright (c) Intel Corporation (2021-2022) +// +// INTEL MAKES NO WARRANTY OF ANY KIND REGARDING THE CODE. THIS CODE IS LICENSED +// ON AN "AS IS" BASIS AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, +// INSTALLATION, TRAINING OR OTHER SERVICES. INTEL DOES NOT PROVIDE ANY UPDATES, +// ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY WARRANTY OF +// MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR ANY PARTICULAR PURPOSE, OR ANY +// OTHER WARRANTY. Intel disclaims all liability, including liability for +// infringement of any proprietary rights, relating to use of the code. No license, +// express or implied, by estoppel or otherwise, to any intellectual property +// rights is granted herein. +// +//-------------------------------------------------------------------------- + +/** + * + * @file ColorAlgorithms.cpp + * @brief This file contains the algorithms for Color Sample APP. + * + */ + +#include "ColorAlgorithms.h" + +/*************************************************************** + * @brief + * MatrixMult3x3With3x1 + * @param Matrix1, Matrix2, Result + * @return void + ***************************************************************/ +void MatrixMult3x3With3x1(const double Matrix1[3][3], const double Matrix2[3], double Result[3]) +{ + double Tmp[3]; + + Tmp[0] = Matrix1[0][0] * Matrix2[0] + Matrix1[0][1] * Matrix2[1] + Matrix1[0][2] * Matrix2[2]; + Tmp[1] = Matrix1[1][0] * Matrix2[0] + Matrix1[1][1] * Matrix2[1] + Matrix1[1][2] * Matrix2[2]; + Tmp[2] = Matrix1[2][0] * Matrix2[0] + Matrix1[2][1] * Matrix2[1] + Matrix1[2][2] * Matrix2[2]; + + Result[0] = Tmp[0]; + Result[1] = Tmp[1]; + Result[2] = Tmp[2]; +} + +/*************************************************************** + * @brief + * MatrixMult3x3 + * @param Matrix1[3][3], Matrix2[3][3], Result[3][3] + * @return void + ***************************************************************/ +void MatrixMult3x3(const double Matrix1[3][3], const double Matrix2[3][3], double Result[3][3]) +{ + double Tmp[3][3]; + + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + Tmp[y][x] = Matrix1[y][0] * Matrix2[0][x] + Matrix1[y][1] * Matrix2[1][x] + Matrix1[y][2] * Matrix2[2][x]; + } + } + + memcpy_s(Result, sizeof(Tmp), Tmp, sizeof(Tmp)); +} + +/*************************************************************** + * @brief + * MatrixDeterminant3x3 + * @param Matrix[3][3] + * @return void + ***************************************************************/ +double MatrixDeterminant3x3(const double Matrix[3][3]) +{ + double Result; + + Result = Matrix[0][0] * (Matrix[1][1] * Matrix[2][2] - Matrix[1][2] * Matrix[2][1]); + Result -= Matrix[0][1] * (Matrix[1][0] * Matrix[2][2] - Matrix[1][2] * Matrix[2][0]); + Result += Matrix[0][2] * (Matrix[1][0] * Matrix[2][1] - Matrix[1][1] * Matrix[2][0]); + + return Result; +} + +/*************************************************************** + * @brief + * MatrixInverse3x3 + * @param Matrix[3][3], Result[3][3] + * @return void + ***************************************************************/ +void MatrixInverse3x3(const double Matrix[3][3], double Result[3][3]) +{ + double Tmp[3][3]; + double Determinant = MatrixDeterminant3x3(Matrix); + + if (0 != Determinant) + { + Tmp[0][0] = (Matrix[1][1] * Matrix[2][2] - Matrix[1][2] * Matrix[2][1]) / Determinant; + Tmp[0][1] = (Matrix[0][2] * Matrix[2][1] - Matrix[2][2] * Matrix[0][1]) / Determinant; + Tmp[0][2] = (Matrix[0][1] * Matrix[1][2] - Matrix[0][2] * Matrix[1][1]) / Determinant; + Tmp[1][0] = (Matrix[1][2] * Matrix[2][0] - Matrix[1][0] * Matrix[2][2]) / Determinant; + Tmp[1][1] = (Matrix[0][0] * Matrix[2][2] - Matrix[0][2] * Matrix[2][0]) / Determinant; + Tmp[1][2] = (Matrix[0][2] * Matrix[1][0] - Matrix[0][0] * Matrix[1][2]) / Determinant; + Tmp[2][0] = (Matrix[1][0] * Matrix[2][1] - Matrix[1][1] * Matrix[2][0]) / Determinant; + Tmp[2][1] = (Matrix[0][1] * Matrix[2][0] - Matrix[0][0] * Matrix[2][1]) / Determinant; + Tmp[2][2] = (Matrix[0][0] * Matrix[1][1] - Matrix[0][1] * Matrix[1][0]) / Determinant; + + Result[0][0] = Tmp[0][0]; + Result[0][1] = Tmp[0][1]; + Result[0][2] = Tmp[0][2]; + Result[1][0] = Tmp[1][0]; + Result[1][1] = Tmp[1][1]; + Result[1][2] = Tmp[1][2]; + Result[2][0] = Tmp[2][0]; + Result[2][1] = Tmp[2][1]; + Result[2][2] = Tmp[2][2]; + } +} + +/*************************************************************** + * @brief + * MatrixMultScalar3x3 + * @param Matrix[3][3], double + * @return void + ***************************************************************/ +void MatrixMultScalar3x3(double Matrix[3][3], double Multiplier) +{ + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + Matrix[y][x] *= Multiplier; + } + } +} + +/*************************************************************** + * @brief + * MatrixMaxSumOfRow3x3 + * @param Matrix[3][3] + * @return void + ***************************************************************/ +double MatrixMaxSumOfRow3x3(const double Matrix[3][3]) +{ + double Val, MaxVal = -10.0; + + for (int y = 0; y < 3; y++) + { + Val = Matrix[y][0] + Matrix[y][1] + Matrix[y][2]; + MaxVal = max(Val, MaxVal); + } + + return MaxVal; +} + +/*************************************************************** + * @brief + * MatrixNormalize3x3 + * @param Mat[3][3] + * @return void + ***************************************************************/ +void MatrixNormalize3x3(double Mat[3][3]) +{ + double Val = 0; + double Maxrow = MatrixMaxSumOfRow3x3(Mat); + + if (Maxrow > 1) + { + MatrixMultScalar3x3(Mat, (1.0 / Maxrow)); + } +} + +/*************************************************************** + * @brief + * CreateRGB2XYZMatrix + * @param ColorSpace, RGB2XYZ[3][3] + * return void + ***************************************************************/ +void CreateRGB2XYZMatrix(ColorSpace Cspace, double RGB2XYZ[3][3]) +{ + double XYZsum[3]; + double Z[4]; + double XYZw[3]; + + Z[0] = 1 - Cspace.White.CIEx - Cspace.White.CIEy; + Z[1] = 1 - Cspace.Red.CIEx - Cspace.Red.CIEy; + Z[2] = 1 - Cspace.Green.CIEx - Cspace.Green.CIEy; + Z[3] = 1 - Cspace.Blue.CIEx - Cspace.Blue.CIEy; + + XYZw[0] = Cspace.White.CIEx / Cspace.White.CIEy; + XYZw[1] = 1; + XYZw[2] = Z[0] / Cspace.White.CIEy; + + double XYZRGB[3][3] = { { Cspace.Red.CIEx, Cspace.Green.CIEx, Cspace.Blue.CIEx }, { Cspace.Red.CIEy, Cspace.Green.CIEy, Cspace.Blue.CIEy }, { Z[1], Z[2], Z[3] } }; + double Mat1[3][3]; + + MatrixInverse3x3(XYZRGB, Mat1); + MatrixMult3x3With3x1(Mat1, XYZw, XYZsum); + + double Mat2[3][3] = { { XYZsum[0], 0, 0 }, { 0, XYZsum[1], 0 }, { 0, 0, XYZsum[2] } }; + + MatrixMult3x3(XYZRGB, Mat2, RGB2XYZ); +} + +/*************************************************************** + * @brief + * CreateMatrixForMappingPanelToSRGBColorSpace + * This funtion is called with PanelColorSpace which maps it with the SRGB color space + * @param ColorSpace, GeneratedOutputMatrix[3][3] + * @return void + ***************************************************************/ +void CreateMatrixForMappingPanelToSRGBColorSpace(ColorSpace PanelColorSpace, double GeneratedOutputMatrix[3][3]) +{ + // standard SRGB color space harcoded https://en.wikipedia.org/wiki/SRGB + static ColorSpace SRGBColorSpace = { + { 0.3127, 0.3290, 1.0 }, // white x,y,Y + { 0.64, 0.33, 0.2126 }, // red + { 0.30, 0.60, 0.7152 }, // green + { 0.15, 0.060, 0.0722 } // blue + }; + double RGB2XYZ_Target[3][3]; + double RGB2XYZ_Panel[3][3]; + double XYZ2RGB_Panel[3][3]; + + CreateRGB2XYZMatrix(SRGBColorSpace, RGB2XYZ_Target); // convert SRGB to XYZ + + CreateRGB2XYZMatrix(PanelColorSpace, RGB2XYZ_Panel); // convert Panel to XYZ + MatrixInverse3x3(RGB2XYZ_Panel, XYZ2RGB_Panel); + MatrixMult3x3(XYZ2RGB_Panel, RGB2XYZ_Target, GeneratedOutputMatrix); + MatrixNormalize3x3(GeneratedOutputMatrix); +} \ No newline at end of file diff --git a/Samples/ToothNClawWrapper/ColorAlgorithms.h b/Samples/ToothNClawWrapper/ColorAlgorithms.h new file mode 100644 index 0000000..3471c26 --- /dev/null +++ b/Samples/ToothNClawWrapper/ColorAlgorithms.h @@ -0,0 +1,53 @@ +//=========================================================================== +// +// Copyright (c) Intel Corporation (2021-2022) +// +// INTEL MAKES NO WARRANTY OF ANY KIND REGARDING THE CODE. THIS CODE IS LICENSED +// ON AN "AS IS" BASIS AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, +// INSTALLATION, TRAINING OR OTHER SERVICES. INTEL DOES NOT PROVIDE ANY UPDATES, +// ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY WARRANTY OF +// MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR ANY PARTICULAR PURPOSE, OR ANY +// OTHER WARRANTY. Intel disclaims all liability, including liability for +// infringement of any proprietary rights, relating to use of the code. No license, +// express or implied, by estoppel or otherwise, to any intellectual property +// rights is granted herein. +// +//-------------------------------------------------------------------------- + +/** + * + * @file ColorAlgorithms.h + * @brief + * + */ + +#pragma once + +#include +#include + +// https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space +typedef struct +{ + double CIEx; + double CIEy; + double CIELuminance; +} IPIXEL_xyY; + +typedef struct ColorSpace +{ + IPIXEL_xyY White; + IPIXEL_xyY Red; + IPIXEL_xyY Green; + IPIXEL_xyY Blue; +} ColorSpace; + +void MatrixMult3x3With3x1(const double Matrix1[3][3], const double Matrix2[3], double Result[3]); +void MatrixMult3x3(const double Matrix1[3][3], const double Matrix2[3][3], double Result[3][3]); +double MatrixDeterminant3x3(const double Matrix[3][3]); +void MatrixInverse3x3(const double Matrix[3][3], double Result[3][3]); +void MatrixMultScalar3x3(double Matrix[3][3], double Multiplier); +double MatrixMaxSumOfRow3x3(const double Matrix[3][3]); +void MatrixNormalize3x3(double Mat[3][3]); +void CreateRGB2XYZMatrix(ColorSpace Cspace, double RGB2XYZ[3][3]); +void CreateMatrixForMappingPanelToSRGBColorSpace(ColorSpace PanelColorSpace, double GeneratedOutputMatrix[3][3]); diff --git a/Samples/ToothNClawWrapper/ColorAlgorithms_App.cpp b/Samples/ToothNClawWrapper/ColorAlgorithms_App.cpp new file mode 100644 index 0000000..e390295 --- /dev/null +++ b/Samples/ToothNClawWrapper/ColorAlgorithms_App.cpp @@ -0,0 +1,213 @@ +//=========================================================================== +// Copyright (C) 2022 Intel Corporation +// +// +// +// SPDX-License-Identifier: MIT +//-------------------------------------------------------------------------- + +/** + * + * @file ColorAlgorithms_App.cpp + * @brief This file contains the algorithms for Color Sample APP. + * + */ + +#include "ColorAlgorithms_App.h" + +/*************************************************************** + * @brief + * MatrixMult3x3With3x1 + * @param Matrix1, Matrix2, Result + * @return void + ***************************************************************/ +void MatrixMult3x3With3x1(const double Matrix1[3][3], const double Matrix2[3], double Result[3]) +{ + double Tmp[3]; + + Tmp[0] = Matrix1[0][0] * Matrix2[0] + Matrix1[0][1] * Matrix2[1] + Matrix1[0][2] * Matrix2[2]; + Tmp[1] = Matrix1[1][0] * Matrix2[0] + Matrix1[1][1] * Matrix2[1] + Matrix1[1][2] * Matrix2[2]; + Tmp[2] = Matrix1[2][0] * Matrix2[0] + Matrix1[2][1] * Matrix2[1] + Matrix1[2][2] * Matrix2[2]; + + Result[0] = Tmp[0]; + Result[1] = Tmp[1]; + Result[2] = Tmp[2]; +} + +/*************************************************************** + * @brief + * MatrixMult3x3 + * @param Matrix1[3][3], Matrix2[3][3], Result[3][3] + * @return void + ***************************************************************/ +void MatrixMult3x3(const double Matrix1[3][3], const double Matrix2[3][3], double Result[3][3]) +{ + double Tmp[3][3]; + + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + Tmp[y][x] = Matrix1[y][0] * Matrix2[0][x] + Matrix1[y][1] * Matrix2[1][x] + Matrix1[y][2] * Matrix2[2][x]; + } + } + + memcpy_s(Result, sizeof(Tmp), Tmp, sizeof(Tmp)); +} + +/*************************************************************** + * @brief + * MatrixDeterminant3x3 + * @param Matrix[3][3] + * @return void + ***************************************************************/ +double MatrixDeterminant3x3(const double Matrix[3][3]) +{ + double Result; + + Result = Matrix[0][0] * (Matrix[1][1] * Matrix[2][2] - Matrix[1][2] * Matrix[2][1]); + Result -= Matrix[0][1] * (Matrix[1][0] * Matrix[2][2] - Matrix[1][2] * Matrix[2][0]); + Result += Matrix[0][2] * (Matrix[1][0] * Matrix[2][1] - Matrix[1][1] * Matrix[2][0]); + + return Result; +} + +/*************************************************************** + * @brief + * MatrixInverse3x3 + * @param Matrix[3][3], Result[3][3] + * @return void + ***************************************************************/ +void MatrixInverse3x3(const double Matrix[3][3], double Result[3][3]) +{ + double Tmp[3][3]; + double Determinant = MatrixDeterminant3x3(Matrix); + + if (0 != Determinant) + { + Tmp[0][0] = (Matrix[1][1] * Matrix[2][2] - Matrix[1][2] * Matrix[2][1]) / Determinant; + Tmp[0][1] = (Matrix[0][2] * Matrix[2][1] - Matrix[2][2] * Matrix[0][1]) / Determinant; + Tmp[0][2] = (Matrix[0][1] * Matrix[1][2] - Matrix[0][2] * Matrix[1][1]) / Determinant; + Tmp[1][0] = (Matrix[1][2] * Matrix[2][0] - Matrix[1][0] * Matrix[2][2]) / Determinant; + Tmp[1][1] = (Matrix[0][0] * Matrix[2][2] - Matrix[0][2] * Matrix[2][0]) / Determinant; + Tmp[1][2] = (Matrix[0][2] * Matrix[1][0] - Matrix[0][0] * Matrix[1][2]) / Determinant; + Tmp[2][0] = (Matrix[1][0] * Matrix[2][1] - Matrix[1][1] * Matrix[2][0]) / Determinant; + Tmp[2][1] = (Matrix[0][1] * Matrix[2][0] - Matrix[0][0] * Matrix[2][1]) / Determinant; + Tmp[2][2] = (Matrix[0][0] * Matrix[1][1] - Matrix[0][1] * Matrix[1][0]) / Determinant; + + Result[0][0] = Tmp[0][0]; + Result[0][1] = Tmp[0][1]; + Result[0][2] = Tmp[0][2]; + Result[1][0] = Tmp[1][0]; + Result[1][1] = Tmp[1][1]; + Result[1][2] = Tmp[1][2]; + Result[2][0] = Tmp[2][0]; + Result[2][1] = Tmp[2][1]; + Result[2][2] = Tmp[2][2]; + } +} + +/*************************************************************** + * @brief + * MatrixMultScalar3x3 + * @param Matrix[3][3], double + * @return void + ***************************************************************/ +void MatrixMultScalar3x3(double Matrix[3][3], double Multiplier) +{ + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + Matrix[y][x] *= Multiplier; + } + } +} + +/*************************************************************** + * @brief + * MatrixMaxSumOfRow3x3 + * @param Matrix[3][3] + * @return void + ***************************************************************/ +double MatrixMaxSumOfRow3x3(const double Matrix[3][3]) +{ + double Val, MaxVal = -10.0; + + for (int y = 0; y < 3; y++) + { + Val = Matrix[y][0] + Matrix[y][1] + Matrix[y][2]; + MaxVal = max(Val, MaxVal); + } + + return MaxVal; +} + +/*************************************************************** + * @brief + * MatrixNormalize3x3 + * @param Mat[3][3] + * @return void + ***************************************************************/ +void MatrixNormalize3x3(double Mat[3][3]) +{ + double Val = 0; + double Maxrow = MatrixMaxSumOfRow3x3(Mat); + + if (Maxrow > 1) + { + MatrixMultScalar3x3(Mat, (1.0 / Maxrow)); + } +} + +/*************************************************************** + * @brief + * CreateRGB2XYZMatrix + * @param ColorSpace, RGB2XYZ[3][3] + * return void + ***************************************************************/ +void CreateRGB2XYZMatrix(ColorSpace Cspace, double RGB2XYZ[3][3]) +{ + double XYZsum[3]; + double Z[4]; + double XYZw[3]; + + Z[0] = 1 - Cspace.White.CIEx - Cspace.White.CIEy; + Z[1] = 1 - Cspace.Red.CIEx - Cspace.Red.CIEy; + Z[2] = 1 - Cspace.Green.CIEx - Cspace.Green.CIEy; + Z[3] = 1 - Cspace.Blue.CIEx - Cspace.Blue.CIEy; + + XYZw[0] = Cspace.White.CIEx / Cspace.White.CIEy; + XYZw[1] = 1; + XYZw[2] = Z[0] / Cspace.White.CIEy; + + double XYZRGB[3][3] = { { Cspace.Red.CIEx, Cspace.Green.CIEx, Cspace.Blue.CIEx }, { Cspace.Red.CIEy, Cspace.Green.CIEy, Cspace.Blue.CIEy }, { Z[1], Z[2], Z[3] } }; + double Mat1[3][3]; + + MatrixInverse3x3(XYZRGB, Mat1); + MatrixMult3x3With3x1(Mat1, XYZw, XYZsum); + + double Mat2[3][3] = { { XYZsum[0], 0, 0 }, { 0, XYZsum[1], 0 }, { 0, 0, XYZsum[2] } }; + + MatrixMult3x3(XYZRGB, Mat2, RGB2XYZ); +} + +/*************************************************************** + * @brief + * CreateMatrixToScaleAndRotatePanelToContentColorSpace + * This funtion is called with PanelColorSpace which maps it with the Content color space + * @param ColorSpace,ContentColorSpace, GeneratedOutputMatrix[3][3] + * @return void + ***************************************************************/ +void CreateMatrixToScaleAndRotatePanelToContentColorSpace(ColorSpace PanelColorSpace, ColorSpace ContentColorSpace, double GeneratedOutputMatrix[3][3]) +{ + double RGB2XYZ_Content[3][3]; + double RGB2XYZ_Panel[3][3]; + double XYZ2RGB_Panel[3][3]; + + CreateRGB2XYZMatrix(ContentColorSpace, RGB2XYZ_Content); // convert ContentColorSpace to XYZ + CreateRGB2XYZMatrix(PanelColorSpace, RGB2XYZ_Panel); // convert Panel to XYZ + MatrixInverse3x3(RGB2XYZ_Panel, XYZ2RGB_Panel); + MatrixMult3x3(XYZ2RGB_Panel, RGB2XYZ_Content, GeneratedOutputMatrix); + MatrixNormalize3x3(GeneratedOutputMatrix); +} \ No newline at end of file diff --git a/Samples/ToothNClawWrapper/ColorAlgorithms_App.h b/Samples/ToothNClawWrapper/ColorAlgorithms_App.h new file mode 100644 index 0000000..110f75b --- /dev/null +++ b/Samples/ToothNClawWrapper/ColorAlgorithms_App.h @@ -0,0 +1,45 @@ +//=========================================================================== +// Copyright (C) 2022 Intel Corporation +// +// +// +// SPDX-License-Identifier: MIT +//-------------------------------------------------------------------------- + +/** + * + * @file ColorAlgorithms_App.h + * @brief + * + */ + +#pragma once + +#include +#include + +// https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space +typedef struct +{ + double CIEx; + double CIEy; + double CIELuminance; +} IPIXEL_xyY; + +typedef struct ColorSpace +{ + IPIXEL_xyY White; + IPIXEL_xyY Red; + IPIXEL_xyY Green; + IPIXEL_xyY Blue; +} ColorSpace; + +void MatrixMult3x3With3x1(const double Matrix1[3][3], const double Matrix2[3], double Result[3]); +void MatrixMult3x3(const double Matrix1[3][3], const double Matrix2[3][3], double Result[3][3]); +double MatrixDeterminant3x3(const double Matrix[3][3]); +void MatrixInverse3x3(const double Matrix[3][3], double Result[3][3]); +void MatrixMultScalar3x3(double Matrix[3][3], double Multiplier); +double MatrixMaxSumOfRow3x3(const double Matrix[3][3]); +void MatrixNormalize3x3(double Mat[3][3]); +void CreateRGB2XYZMatrix(ColorSpace Cspace, double RGB2XYZ[3][3]); +void CreateMatrixToScaleAndRotatePanelToContentColorSpace(ColorSpace PanelColorSpace, ColorSpace ContentColorSpace, double GeneratedOutputMatrix[3][3]); diff --git a/Samples/ToothNClawWrapper/README.md b/Samples/ToothNClawWrapper/README.md new file mode 100644 index 0000000..0cbceb8 --- /dev/null +++ b/Samples/ToothNClawWrapper/README.md @@ -0,0 +1,7 @@ +Tooth N Claw IGCL Wrapper + +# How to build +- Load the CMakeLists.txt in Visual Studio community edition +- Build as Release x64 +- Copy Samples\ToothNClawWrapper\out\build\x64-Release\IGCL_Wrapper.dll to the ToothNClaw projet in the following path +ToothNClaw\Tooth.Backend\Libraries \ No newline at end of file diff --git a/Samples/ToothNClawWrapper/Wrapper.cpp b/Samples/ToothNClawWrapper/Wrapper.cpp new file mode 100644 index 0000000..fa5d0c3 --- /dev/null +++ b/Samples/ToothNClawWrapper/Wrapper.cpp @@ -0,0 +1,2352 @@ +//=========================================================================== +// Copyright (C) 2022 Intel Corporation +// +// +// +// SPDX-License-Identifier: MIT +//-------------------------------------------------------------------------- + +/** + * + * @file Wrapper.cpp + * @brief This file contains the 'main' function. Program execution begins and ends there. + * + */ + +#define _CRTDBG_MAP_ALLOC +#include +#include +#include +#include +#include +using namespace std; + +#define CTL_APIEXPORT // caller of control API DLL shall define this before + // including igcl_api.h +#include "igcl_api.h" +#include "GenericIGCLApp.h" +#include "ColorAlgorithms_App.h" +#include "GenericIGCLApp.h" + + +/* -------------- Definitions and variables from Color_Sample_App.cpp ------------------*/ +ctl_result_t GResult = CTL_RESULT_SUCCESS; + +#define SATURATION_FACTOR_BASE 1.0 +#define DEFAULT_COLOR_SAT SATURATION_FACTOR_BASE +#define MIN_COLOR_SAT (SATURATION_FACTOR_BASE - 0.25) +#define MAX_COLOR_SAT (SATURATION_FACTOR_BASE + 0.25) +#define UV_MAX_POINT 0.4375 +#define UV_MIN_POINT1 0.0029297 +#define UV_MIN_POINT2 0.01074 +#define UV_MAX_VAL 255.0 +#define CLIP_DOUBLE(Val, Min, Max) (((Val) < (Min)) ? (Min) : (((Val) > (Max)) ? (Max) : (Val))) +#define ABS_DOUBLE(x) ((x) < 0 ? (-x) : (x)) +#define DEFAULT_GAMMA_VALUE 2.2 + +// Convert RGB to YUV +const double RGB2YCbCr709[3][3] = { { 0.2126, 0.7152, 0.0722 }, { -0.1146, -0.3854, 0.5000 }, { 0.5000, -0.4542, -0.0458 } }; + +// Convert YUV to RGB +const double YCbCr2RGB709[3][3] = { { 1.0000, 0.0000, 1.5748 }, { 1.0000, -0.1873, -0.4681 }, { 1.0000, 1.8556, 0.0000 } }; + +// convert RGB to XYZ +const double RGB2XYZ_709[3][3] = { { 0.41239080, 0.35758434, 0.18048079 }, { 0.21263901, 0.71516868, 0.07219232 }, { 0.01933082, 0.11919478, 0.95053215 } }; + +const double Pi = 3.1415926535897932; +const double Beta = 0.018053968510807; +const double Alpha = 1.09929682680944; + +typedef struct +{ + double R; + double G; + double B; +} IPIXELD; + +typedef struct +{ + double Y; + double Cb; + double Cr; +} IPIXELD_YCbCr; + +typedef enum HUE_ANCHOR +{ + HUE_ANCHOR_RED_SATURATION = 0, + HUE_ANCHOR_YELLOW_SATURATION = 1, + HUE_ANCHOR_GREEN_SATURATION = 2, + HUE_ANCHOR_CYAN_SATURATION = 3, + HUE_ANCHOR_BLUE_SATURATION = 4, + HUE_ANCHOR_MAGENTA_SATURATION = 5, + HUE_ANCHOR_COLOR_COUNT_SATURATION = 6 +} HUE_ANCHOR; + +typedef enum +{ + GAMMA_ENCODING_TYPE_SRGB = 0, // Gamma encoding SRGB + GAMMA_ENCODING_TYPE_REC709 = 1, // Gamma encoding REC709 + GAMMA_ENCODING_TYPE_REC2020 = 2, // Gamma encoding REC2020 +} GAMMA_ENCODING_TYPE; + +// https://en.wikipedia.org/wiki/CIE_1931_color_space +typedef struct +{ + double X; + double Y; + double Z; +} IPIXEL_XYZ; + +// https://en.wikipedia.org/wiki/CIELAB_color_space +typedef struct +{ + double L; + double A; + double B; +} IPIXEL_Lab; + +typedef struct +{ + double RedSat; + double YellowSat; + double GreenSat; + double CyanSat; + double BlueSat; + double MagentaSat; +} PARTIAL_SATURATION_WEIGHTS; + +const IPIXEL_XYZ RefWhitePointSRGB = { 95.0489, 100.0, 108.8840 }; + + +/* -------------------------------------------------------------- */ + +typedef struct ctl_telemetry_data +{ + // GPU TDP + bool gpuEnergySupported = false; + double gpuEnergyValue; + + // GPU Voltage + bool gpuVoltageSupported = false; + double gpuVoltagValue; + + // GPU Core Frequency + bool gpuCurrentClockFrequencySupported = false; + double gpuCurrentClockFrequencyValue; + + // GPU Core Temperature + bool gpuCurrentTemperatureSupported = false; + double gpuCurrentTemperatureValue; + + // GPU Usage + bool globalActivitySupported = false; + double globalActivityValue; + + // Render Engine Usage + bool renderComputeActivitySupported = false; + double renderComputeActivityValue; + + // Media Engine Usage + bool mediaActivitySupported = false; + double mediaActivityValue; + + // VRAM Power Consumption + bool vramEnergySupported = false; + double vramEnergyValue; + + // VRAM Voltage + bool vramVoltageSupported = false; + double vramVoltageValue; + + // VRAM Frequency + bool vramCurrentClockFrequencySupported = false; + double vramCurrentClockFrequencyValue; + + // VRAM Read Bandwidth + bool vramReadBandwidthSupported = false; + double vramReadBandwidthValue; + + // VRAM Write Bandwidth + bool vramWriteBandwidthSupported = false; + double vramWriteBandwidthValue; + + // VRAM Temperature + bool vramCurrentTemperatureSupported = false; + double vramCurrentTemperatureValue; + + // Fanspeed (n Fans) + bool fanSpeedSupported = false; + double fanSpeedValue; +}; + +typedef struct ctl_fps_limiter_t +{ + bool isLimiterEnabled = false; + int32_t fpsLimitValue = 30; +}; + +ctl_api_handle_t hAPIHandle; +ctl_device_adapter_handle_t* hDevices; + +extern "C" { + + double deltatimestamp = 0; + double prevtimestamp = 0; + double curtimestamp = 0; + double prevgpuEnergyCounter = 0; + double curgpuEnergyCounter = 0; + double curglobalActivityCounter = 0; + double prevglobalActivityCounter = 0; + double currenderComputeActivityCounter = 0; + double prevrenderComputeActivityCounter = 0; + double curmediaActivityCounter = 0; + double prevmediaActivityCounter = 0; + double curvramEnergyCounter = 0; + double prevvramEnergyCounter = 0; + double curvramReadBandwidthCounter = 0; + double prevvramReadBandwidthCounter = 0; + double curvramWriteBandwidthCounter = 0; + double prevvramWriteBandwidthCounter = 0; + + ctl_result_t GetRetroScalingCaps(ctl_device_adapter_handle_t hDevice, ctl_retro_scaling_caps_t* RetroScalingCaps) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + RetroScalingCaps->Size = sizeof(ctl_retro_scaling_caps_t); + + Result = ctlGetSupportedRetroScalingCapability(hDevice, RetroScalingCaps); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSupportedRetroScalingCapability"); + + cout << "======== GetRetroScalingCaps ========" << endl; + cout << "RetroScalingCaps.SupportedRetroScaling: " << RetroScalingCaps->SupportedRetroScaling << endl; + + Exit: + return Result; + } + + ctl_result_t GetRetroScalingSettings(ctl_device_adapter_handle_t hDevice, ctl_retro_scaling_settings_t* RetroScalingSettings) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + RetroScalingSettings->Get = TRUE; + RetroScalingSettings->Size = sizeof(ctl_retro_scaling_settings_t); + + Result = ctlGetSetRetroScaling(hDevice, RetroScalingSettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetRetroScaling"); + + cout << "======== GetRetroScalingSettings ========" << endl; + cout << "RetroScalingSettings.Get: " << RetroScalingSettings->Get << endl; + cout << "RetroScalingSettings.Enable: " << RetroScalingSettings->Enable << endl; + cout << "RetroScalingSettings.RetroScalingType: " << RetroScalingSettings->RetroScalingType << endl; + + Exit: + return Result; + } + + ctl_result_t SetRetroScalingSettings(ctl_device_adapter_handle_t hDevice, ctl_retro_scaling_settings_t RetroScalingSettings) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + RetroScalingSettings.Get = FALSE; + RetroScalingSettings.Size = sizeof(ctl_retro_scaling_settings_t); + + Result = ctlGetSetRetroScaling(hDevice, &RetroScalingSettings); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSetRetroScaling"); + + cout << "======== SetRetroScalingSettings ========" << endl; + cout << "RetroScalingSettings.Get: " << RetroScalingSettings.Get << endl; + cout << "RetroScalingSettings.Enable: " << RetroScalingSettings.Enable << endl; + cout << "RetroScalingSettings.RetroScalingType: " << RetroScalingSettings.RetroScalingType << endl; + + Exit: + return Result; + } + + ctl_result_t GetScalingCaps(ctl_device_adapter_handle_t hDevice, uint32_t idx, ctl_scaling_caps_t* ScalingCaps) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + ScalingCaps->Size = sizeof(ctl_scaling_caps_t); + + // Enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (DisplayCount <= 0) + { + printf("Invalid Display Count\n"); + goto Exit; + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + Result = ctlGetSupportedScalingCapability(hDisplayOutput[idx], ScalingCaps); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSupportedScalingCapability"); + + cout << "======== GetScalingCaps ========" << endl; + cout << "ScalingCaps.SupportedScaling: " << ScalingCaps->SupportedScaling << endl; + + Exit: + CTL_FREE_MEM(hDisplayOutput); + return Result; + } + + ctl_result_t GetScalingSettings(ctl_device_adapter_handle_t hDevice, uint32_t idx, ctl_scaling_settings_t* ScalingSetting) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + ctl_scaling_caps_t ScalingCaps = { 0 }; + ScalingSetting->Size = sizeof(ctl_scaling_settings_t); + + Result = GetScalingCaps(hDevice, idx, &ScalingCaps); + LOG_AND_EXIT_ON_ERROR(Result, "GetScalingCaps"); + + // Enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (DisplayCount <= 0) + { + printf("Invalid Display Count\n"); + goto Exit; + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (0 != ScalingCaps.SupportedScaling) + { + Result = ctlGetCurrentScaling(hDisplayOutput[idx], ScalingSetting); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetCurrentScaling"); + + cout << "======== GetScalingSettings ========" << endl; + cout << "ScalingSetting.Enable: " << ScalingSetting->Enable << endl; + cout << "ScalingSetting.ScalingType: " << ScalingSetting->ScalingType << endl; + cout << "ScalingSetting.HardwareModeSet: " << ScalingSetting->HardwareModeSet << endl; + cout << "ScalingSetting.CustomScalingX: " << ScalingSetting->CustomScalingX << endl; + cout << "ScalingSetting.CustomScalingY: " << ScalingSetting->CustomScalingY << endl; + } + + Exit: + CTL_FREE_MEM(hDisplayOutput); + return Result; + } + + ctl_result_t SetScalingSettings(ctl_device_adapter_handle_t hDevice, uint32_t idx, ctl_scaling_settings_t ScalingSetting) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + ctl_scaling_caps_t ScalingCaps = { 0 }; + bool ModeSet; + + Result = GetScalingCaps(hDevice, idx, &ScalingCaps); + LOG_AND_EXIT_ON_ERROR(Result, "GetScalingCaps"); + + // Enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (DisplayCount <= 0) + { + printf("Invalid Display Count\n"); + goto Exit; + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (0 != ScalingCaps.SupportedScaling) + { + // filling custom scaling details + ScalingSetting.Size = sizeof(ctl_scaling_settings_t); + + // fill custom scaling details only if it is supported + if (0x1F == ScalingCaps.SupportedScaling) + { + // check if hardware modeset required to apply custom scaling + ModeSet = ((TRUE == ScalingSetting.Enable) && (CTL_SCALING_TYPE_FLAG_CUSTOM == ScalingSetting.ScalingType)) ? FALSE : TRUE; + ScalingSetting.HardwareModeSet = (TRUE == ModeSet) ? TRUE : FALSE; + } + + cout << "======== SetScalingSettings ========" << endl; + cout << "ScalingSetting.Enable: " << ScalingSetting.Enable << endl; + cout << "ScalingSetting.ScalingType: " << ScalingSetting.ScalingType << endl; + cout << "ScalingSetting.HardwareModeSet: " << ScalingSetting.HardwareModeSet << endl; + cout << "ScalingSetting.CustomScalingX: " << ScalingSetting.CustomScalingX << endl; + cout << "ScalingSetting.CustomScalingY: " << ScalingSetting.CustomScalingY << endl; + } + + Result = ctlSetCurrentScaling(hDisplayOutput[idx], &ScalingSetting); + LOG_AND_EXIT_ON_ERROR(Result, "ctlSetCurrentScaling"); + + Exit: + CTL_FREE_MEM(hDisplayOutput); + return Result; + } + + ctl_result_t GetSharpnessCaps(ctl_device_adapter_handle_t hDevice, uint32_t idx, ctl_sharpness_caps_t* SharpnessCaps) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + SharpnessCaps->Size = sizeof(ctl_sharpness_caps_t); + + // Enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (DisplayCount <= 0) + { + printf("Invalid Display Count\n"); + goto Exit; + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + // Get Sharpness caps + Result = ctlGetSharpnessCaps(hDisplayOutput[idx], SharpnessCaps); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSharpnessCaps"); + + cout << "======== GetSharpnessCaps ========" << endl; + cout << "SharpnessCaps.SupportedFilterFlags: " << SharpnessCaps->SupportedFilterFlags << endl; + + Exit: + CTL_FREE_MEM(hDisplayOutput); + return Result; + } + + ctl_result_t GetSharpnessSettings(ctl_device_adapter_handle_t hDevice, uint32_t idx, ctl_sharpness_settings_t* GetSharpness) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + GetSharpness->Size = sizeof(ctl_sharpness_settings_t); + + // Enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (DisplayCount <= 0) + { + printf("Invalid Display Count\n"); + goto Exit; + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + Result = ctlGetCurrentSharpness(hDisplayOutput[idx], GetSharpness); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetCurrentSharpness"); + + cout << "======== GetSharpnessSettings ========" << endl; + cout << "GetSharpness.Enable: " << GetSharpness->Enable << endl; + cout << "GetSharpness.FilterType: " << GetSharpness->FilterType << endl; + cout << "GetSharpness.Intensity: " << GetSharpness->Intensity << endl; + + Exit: + CTL_FREE_MEM(hDisplayOutput); + return Result; + } + + ctl_result_t SetSharpnessSettings(ctl_device_adapter_handle_t hDevice, uint32_t idx, ctl_sharpness_settings_t SetSharpness) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + + // Enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + if (DisplayCount <= 0) + { + printf("Invalid Display Count\n"); + goto Exit; + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + cout << "======== SetSharpnessSettings ========" << endl; + cout << "SetSharpness.Enable: " << SetSharpness.Enable << endl; + cout << "SetSharpness.FilterType: " << SetSharpness.FilterType << endl; + cout << "SetSharpness.Intensity: " << SetSharpness.Intensity << endl; + + Result = ctlSetCurrentSharpness(hDisplayOutput[idx], &SetSharpness); + LOG_AND_EXIT_ON_ERROR(Result, "ctlSetCurrentSharpness"); + + Exit: + CTL_FREE_MEM(hDisplayOutput); + return Result; + } + + ctl_result_t GetEnduranceGamingCaps(ctl_device_adapter_handle_t hDevice, + ctl_endurance_gaming_caps_t* pCaps) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // --- First pass: get number of 3D features --- + ctl_3d_feature_caps_t FeatureCaps3D = { 0 }; + FeatureCaps3D.Size = sizeof(ctl_3d_feature_caps_t); + + Result = ctlGetSupported3DCapabilities(hDevice, &FeatureCaps3D); + if (Result != CTL_RESULT_SUCCESS) + { + APP_LOG_ERROR("ctlGetSupported3DCapabilities failed (pass 1): 0x%X", Result); + return Result; + } + + if (FeatureCaps3D.NumSupportedFeatures == 0) + { + APP_LOG_ERROR("No 3D features supported?"); + return CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + // --- Allocate details array and zero it --- + auto details = (ctl_3d_feature_details_t*) + malloc(sizeof(ctl_3d_feature_details_t) * FeatureCaps3D.NumSupportedFeatures); + if (!details) + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + + memset(details, 0, sizeof(ctl_3d_feature_details_t) * FeatureCaps3D.NumSupportedFeatures); + + // --- Second pass: fill in the details array --- + FeatureCaps3D.pFeatureDetails = details; + Result = ctlGetSupported3DCapabilities(hDevice, &FeatureCaps3D); + if (Result != CTL_RESULT_SUCCESS) + { + APP_LOG_ERROR("ctlGetSupported3DCapabilities failed (pass 2): 0x%X", Result); + free(details); + return Result; + } + + // --- Search for the Endurance Gaming feature --- + bool found = false; + for (uint32_t i = 0; i < FeatureCaps3D.NumSupportedFeatures; ++i) + { + auto& D = details[i]; + if (D.FeatureType == CTL_3D_FEATURE_ENDURANCE_GAMING) + { + // if it's a custom property, we need to allocate pCustomValue + if (D.ValueType == CTL_PROPERTY_VALUE_TYPE_CUSTOM && D.CustomValueSize > 0) + { + D.pCustomValue = malloc(D.CustomValueSize); + if (!D.pCustomValue) + { + Result = CTL_RESULT_ERROR_INVALID_NULL_POINTER; + break; + } + + // single-feature query to fill just this one custom block + ctl_3d_feature_caps_t single = { 0 }; + single.Size = sizeof(single); + single.Version = 0; + single.NumSupportedFeatures = 1; + single.pFeatureDetails = &D; + + Result = ctlGetSupported3DCapabilities(hDevice, &single); + if (Result != CTL_RESULT_SUCCESS) + { + APP_LOG_ERROR("Single-feature ctlGetSupported3DCapabilities failed: 0x%X", Result); + } + } + + if (Result == CTL_RESULT_SUCCESS) + { + // copy the filled‐in ctl_endurance_gaming_caps_t out + auto igclCaps = reinterpret_cast(D.pCustomValue); + *pCaps = *igclCaps; + found = true; + } + + // clean up + if (D.pCustomValue) + { + free(D.pCustomValue); + D.pCustomValue = nullptr; + } + + break; + } + } + + if (!found && Result == CTL_RESULT_SUCCESS) + Result = CTL_RESULT_ERROR_UNSUPPORTED_FEATURE; + + // final cleanup + free(details); + return Result; + } + + ctl_result_t GetEnduranceGamingSettings(ctl_device_adapter_handle_t hDevice, ctl_endurance_gaming_t* pSettings) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // zero out output + memset(pSettings, 0, sizeof(*pSettings)); + + // build the get structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = FALSE; // GET + Feature3D.FeatureType = CTL_3D_FEATURE_ENDURANCE_GAMING; + Feature3D.Size = sizeof(Feature3D); + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_CUSTOM; + Feature3D.CustomValueSize = sizeof(*pSettings); + Feature3D.pCustomValue = pSettings; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (GetEnduranceGamingSettings)"); + + // log for debug + cout << "======== GetEnduranceGamingSettings ========" << endl; + cout << "EGControl: " << pSettings->EGControl << endl; + cout << "EGMode: " << pSettings->EGMode << endl; + /* + cout << "IsFPRequired: " << pSettings->IsFPRequired << endl; + cout << "TargetFPS: " << pSettings->TargetFPS << endl; + cout << "RefreshRate: " << pSettings->RefreshRate << endl; + */ + + Exit: + return Result; + } + + ctl_result_t SetEnduranceGamingSettings(ctl_device_adapter_handle_t hDevice, ctl_endurance_gaming_t settings) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // pack into v2 struct so we can use same API + ctl_endurance_gaming_t eg2 = { 0 }; + eg2.EGControl = settings.EGControl; + eg2.EGMode = settings.EGMode; + + // build the set structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = TRUE; // SET + Feature3D.FeatureType = CTL_3D_FEATURE_ENDURANCE_GAMING; + Feature3D.Size = sizeof(Feature3D); + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_CUSTOM; + Feature3D.CustomValueSize = sizeof(eg2); + Feature3D.pCustomValue = &eg2; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (SetEnduranceGamingSettings)"); + + // log for debug + cout << "======== SetEnduranceGamingSettings ========" << endl; + cout << "EGControl now: " << eg2.EGControl << endl; + cout << "EGMode now: " << eg2.EGMode << endl; + + Exit: + return Result; + } + + + ctl_result_t SetFramesPerSecondLimit(ctl_device_adapter_handle_t hDevice, bool isEnabled, int32_t fpslimit) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // build the set structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = TRUE; + Feature3D.FeatureType = CTL_3D_FEATURE_FRAME_LIMIT; + Feature3D.Size = sizeof(Feature3D); + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_INT32; + Feature3D.CustomValueSize = 0; + Feature3D.pCustomValue = NULL; + Feature3D.Value.IntType.Enable = isEnabled; // Enable or Disable FPS limiter + Feature3D.Value.IntType.Value = fpslimit; // Set the actual frame limit + Feature3D.Version = 0; + + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (SetFramesPerSecondLimit)"); + + // log for debug + cout << "======== SetFramesPerSecondLimit ========" << endl; + cout << "IntType.Enable: " << isEnabled << endl; + cout << "IntType.Value: " << fpslimit << endl; + + Exit: + return Result; + } + + + ctl_result_t GetFramesPerSecondLimit(ctl_device_adapter_handle_t hDevice, ctl_fps_limiter_t* fpslimiter) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // build the get structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = FALSE; // GET + Feature3D.FeatureType = CTL_3D_FEATURE_FRAME_LIMIT; + Feature3D.Size = sizeof(Feature3D); + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_INT32; + Feature3D.CustomValueSize = 0; + Feature3D.pCustomValue = NULL; + Feature3D.Version = 0; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (GetFramesPerSecondLimit)"); + + // log for debug + cout << "======== GetFramesPerSecondLimit ========" << endl; + cout << "Value.IntType.Enable: " << Feature3D.Value.IntType.Enable << endl; + cout << "Value.IntType.Value: " << Feature3D.Value.IntType.Value << endl; + + fpslimiter->isLimiterEnabled = Feature3D.Value.IntType.Enable; + fpslimiter->fpsLimitValue = Feature3D.Value.IntType.Value; + + Exit: + return Result; + } + + + ctl_result_t SetLowLatencySetting(ctl_device_adapter_handle_t hDevice, ctl_3d_low_latency_types_t setting) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // build the set structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = TRUE; + Feature3D.FeatureType = CTL_3D_FEATURE_LOW_LATENCY; + Feature3D.Size = sizeof(Feature3D); + Feature3D.CustomValueSize = 0; + Feature3D.pCustomValue = NULL; + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Feature3D.Value.EnumType.EnableType = setting; // Set Low Latency Setting + Feature3D.Version = 0; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (SetLowLatencySetting)"); + + // log for debug + cout << "======== SetLowLatencySetting ========" << endl; + cout << "Value.EnumType.EnableType: " << setting << endl; + + + Exit: + return Result; + } + + + ctl_result_t GetLowLatencySetting(ctl_device_adapter_handle_t hDevice, ctl_3d_low_latency_types_t* setting) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // build the get structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = FALSE; // GET + Feature3D.FeatureType = CTL_3D_FEATURE_LOW_LATENCY; + Feature3D.Size = sizeof(Feature3D); + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Feature3D.CustomValueSize = 0; + Feature3D.pCustomValue = NULL; + Feature3D.Version = 0; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (GetFramesPerSecondLimit)"); + + // log for debug + cout << "======== GetFramesPerSecondLimit ========" << endl; + *setting = (ctl_3d_low_latency_types_t)Feature3D.Value.EnumType.EnableType; + cout << "Value.EnumType.EnableType: " << *setting << endl; + + Exit: + return Result; + } + + + ctl_result_t SetFrameSyncSetting(ctl_device_adapter_handle_t hDevice, ctl_gaming_flip_mode_flag_t setting) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // build the set structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = TRUE; + Feature3D.FeatureType = CTL_3D_FEATURE_GAMING_FLIP_MODES; + Feature3D.Size = sizeof(Feature3D); + Feature3D.CustomValueSize = 0; + Feature3D.pCustomValue = NULL; + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Feature3D.Value.EnumType.EnableType = setting; // Set Frame Sync Type + Feature3D.Version = 0; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (SetFrameSyncSetting)"); + + // log for debug + cout << "======== SetFrameSyncSetting ========" << endl; + cout << "Value.EnumType.EnableType: " << setting << endl; + + + Exit: + return Result; + } + + + ctl_result_t GetFrameSyncSetting(ctl_device_adapter_handle_t hDevice, ctl_gaming_flip_mode_flag_t* setting) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // build the get structure + ctl_3d_feature_getset_t Feature3D = { 0 }; + Feature3D.bSet = FALSE; // GET + Feature3D.FeatureType = CTL_3D_FEATURE_GAMING_FLIP_MODES; + Feature3D.Size = sizeof(Feature3D); + Feature3D.ValueType = CTL_PROPERTY_VALUE_TYPE_ENUM; + Feature3D.CustomValueSize = 0; + Feature3D.pCustomValue = NULL; + Feature3D.Version = 0; + + // issue the call + Result = ctlGetSet3DFeature(hDevice, &Feature3D); + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetSet3DFeature (GetFrameSyncSetting)"); + + // log for debug + cout << "======== GetFrameSyncSetting ========" << endl; + *setting = (ctl_gaming_flip_mode_flag_t)Feature3D.Value.EnumType.EnableType; + cout << "Value.EnumType.EnableType: " << *setting << endl; + + Exit: + return Result; + } + + // Get the list of Intel device handles + ctl_device_adapter_handle_t* EnumerateDevices(uint32_t* pAdapterCount) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + hDevices = NULL; + + // Get the number of Intel Adapters + Result = ctlEnumerateDevices(hAPIHandle, pAdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + + // Allocate memory for the device handles + hDevices = (ctl_device_adapter_handle_t*)malloc(sizeof(ctl_device_adapter_handle_t) * (*pAdapterCount)); + EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "EnumerateDevices"); + + // Get the device handles + Result = ctlEnumerateDevices(hAPIHandle, pAdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + + Exit: + return hDevices; + } + + /*************************************************************** + * @brief + * GenerateHueSaturationMatrix + * @param Hue, Saturation, CoEff[3][3] + * @return void + ***************************************************************/ + void GenerateHueSaturationMatrix(double Hue, double Saturation, double CoEff[3][3]) + { + double HueShift = Hue * Pi / 180.0; + double C = cos(HueShift); + double S = sin(HueShift); + double HueRotationMatrix[3][3] = { { 1.0, 0.0, 0.0 }, { 0.0, C, -S }, { 0.0, S, C } }; + double SaturationEnhancementMatrix[3][3] = { { 1.0, 0.0, 0.0 }, { 0.0, Saturation, 0.0 }, { 0.0, 0.0, Saturation } }; + double YCbCr2RGB709[3][3] = { { 1.0000, 0.0000, 1.5748 }, { 1.0000, -0.1873, -0.4681 }, { 1.0000, 1.8556, 0.0000 } }; + double RGB2YCbCr709[3][3] = { { 0.2126, 0.7152, 0.0722 }, { -0.1146, -0.3854, 0.5000 }, { 0.5000, -0.4542, -0.0458 } }; + + double Result[3][3]; + + // Use Bt.709 coefficients for RGB to YCbCr conversion + MatrixMult3x3(YCbCr2RGB709, SaturationEnhancementMatrix, Result); + MatrixMult3x3(Result, HueRotationMatrix, Result); + MatrixMult3x3(Result, RGB2YCbCr709, Result); + + memcpy_s(CoEff, sizeof(Result), Result, sizeof(Result)); + } + + /*************************************************************** + * @brief + * ApplyHueSaturation + * General steps for Hue Saturaion + * Create a CSC matrix based on mentioned algorithm for given hue-sat values + * Do a set CSC call with created matrix. + * Iterate through blocks PixTxCaps and find the CSC block. + * @param hDisplayOutput , pPixTxCaps, CscBlockIndex, Hue, Saturation + * @return ctl_result_t + ***************************************************************/ +ctl_result_t ApplyHueSaturation(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t *pPixTxCaps, int32_t CscBlockIndex, double Hue, double Saturation) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_pixtx_block_config_t CSCConfig = pPixTxCaps->pBlockConfigs[CscBlockIndex]; + CSCConfig.Size = sizeof(ctl_pixtx_block_config_t); + Saturation = CLIP_DOUBLE(Saturation, 0.0, 2.5); + Hue = CLIP_DOUBLE(Hue, 0, 359); + + if ((0 == Hue) && (0 == Saturation)) + { + // If Hue and Saturation both are set to default, CSC coefficients should be identity matrix. + memset(CSCConfig.Config.MatrixConfig.Matrix, 0, sizeof(CSCConfig.Config.MatrixConfig.Matrix)); + + CSCConfig.Config.MatrixConfig.Matrix[0][0] = CSCConfig.Config.MatrixConfig.Matrix[1][1] = CSCConfig.Config.MatrixConfig.Matrix[2][2] = 1.0; + } + else + { + // Below function generates CSC matrix(Non Linear) for given Hue and Satuartion values. + GenerateHueSaturationMatrix(Hue, Saturation, CSCConfig.Config.MatrixConfig.Matrix); + } + + ctl_pixtx_pipe_set_config_t SetPixTxArgs = { 0 }; + SetPixTxArgs.Size = sizeof(ctl_pixtx_pipe_set_config_t); + SetPixTxArgs.OpertaionType = CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM; + SetPixTxArgs.NumBlocks = 1; // We are trying to set only one block + SetPixTxArgs.pBlockConfigs = &CSCConfig; // for CSC block + SetPixTxArgs.pBlockConfigs->BlockId = pPixTxCaps->pBlockConfigs[CscBlockIndex].BlockId; + + Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationSetConfig"); + +Exit: + return Result; +} + +/*************************************************************** + * @brief + * GetSRGBDecodingValue + * @param Input + * @return double + ***************************************************************/ +double GetSRGBDecodingValue(double Input) +{ + + // https://en.wikipedia.org/wiki/SRGB#Transfer_function_(%22gamma%22) + + double Output; + + if (Input <= 0.04045) + { + Output = Input / 12.92; + } + else + { + Output = pow(((Input + 0.055) / 1.055), 2.4); + } + + return Output; +} + +/*************************************************************** + * @brief + * GetSRGBEncodingValue + * @param Input + * @return double + ***************************************************************/ +double GetSRGBEncodingValue(double Input) +{ + /* + https://en.wikipedia.org/wiki/SRGB#The_forward_transformation_.28CIE_xyY_or_CIE_XYZ_to_sRGB.29 + */ + + double Output; + + if (Input <= 0.0031308) + { + Output = Input * 12.92; + } + else + { + Output = (1.055 * pow(Input, 1.0 / 2.4)) - 0.055; + } + + return Output; +} + + +/*************************************************************** + * @brief + * Set DeGamma Lut + * @param hDisplayOutput + * @param *pPixTxCaps + * @param DGLUTIndex + * @return + ***************************************************************/ +ctl_result_t SetDeGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t* pPixTxCaps, int32_t DGLUTIndex) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + if (nullptr == hDisplayOutput) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (nullptr == pPixTxCaps) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + + ctl_pixtx_pipe_set_config_t SetPixTxArgs = { 0 }; + ctl_pixtx_block_config_t LutConfig = pPixTxCaps->pBlockConfigs[DGLUTIndex]; + LutConfig.Size = sizeof(ctl_pixtx_block_config_t); + LutConfig.Config.OneDLutConfig.pSamplePositions = NULL; + double* pLut; + + // Create a valid 1D LUT. + const uint32_t LutSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; + LutConfig.Config.OneDLutConfig.pSampleValues = (double*)malloc(LutSize * sizeof(double)); + + EXIT_ON_MEM_ALLOC_FAILURE(LutConfig.Config.OneDLutConfig.pSampleValues, " LutConfig.Config.OneDLutConfig.pSampleValues"); + + memset(LutConfig.Config.OneDLutConfig.pSampleValues, 0, LutSize * sizeof(double)); + + SetPixTxArgs.Size = sizeof(ctl_pixtx_pipe_set_config_t); + SetPixTxArgs.OpertaionType = CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM; + SetPixTxArgs.NumBlocks = 1; // We are enabling only one block + SetPixTxArgs.pBlockConfigs = &LutConfig; // for 1DLUT block + + pLut = LutConfig.Config.OneDLutConfig.pSampleValues; + + for (uint32_t i = 0; i < (LutSize / LutConfig.Config.OneDLutConfig.NumChannels); i++) + { + double Input = (double)i / (double)(LutSize - 1); + pLut[i] = GetSRGBDecodingValue(Input); + // pLut[i] = Input; // unity + } + + Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); + + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlPixelTransformationSetConfig"); + +Exit: + CTL_FREE_MEM(LutConfig.Config.OneDLutConfig.pSampleValues); + return Result; +} + +/*************************************************************** + * @brief + * Get DeGamma + * @param ctl_display_output_handle_t ,ctl_pixtx_pipe_get_config_t, int32_t + * @return + ***************************************************************/ +ctl_result_t GetDeGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t* pPixTxCaps, int32_t DGLUTIndex) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + if (nullptr == hDisplayOutput) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (nullptr == pPixTxCaps) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + + ctl_pixtx_pipe_get_config_t GetPixTxCurrentArgs = { 0 }; + GetPixTxCurrentArgs.Size = sizeof(ctl_pixtx_pipe_get_config_t); + ctl_pixtx_block_config_t LutConfig = pPixTxCaps->pBlockConfigs[DGLUTIndex]; + + GetPixTxCurrentArgs.QueryType = CTL_PIXTX_CONFIG_QUERY_TYPE_CURRENT; + GetPixTxCurrentArgs.NumBlocks = 1; // We are trying to query only one block + GetPixTxCurrentArgs.pBlockConfigs = &LutConfig; // Providing Lut config + LutConfig.Config.OneDLutConfig.pSampleValues = (double*)malloc(LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels * sizeof(double)); + + EXIT_ON_MEM_ALLOC_FAILURE(LutConfig.Config.OneDLutConfig.pSampleValues, "LutConfig.Config.OneDLutConfig.pSampleValues"); + + memset(LutConfig.Config.OneDLutConfig.pSampleValues, 0, LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels * sizeof(double)); + + Result = ctlPixelTransformationGetConfig(hDisplayOutput, &GetPixTxCurrentArgs); + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig"); + + APP_LOG_INFO("DEGamma values : LutConfig.Config.OneDLutConfig.pSampleValues"); + + uint32_t LutDataSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; + APP_LOG_INFO("LutDataSize = %d ", LutDataSize); + + APP_LOG_INFO("DeGamma values : LutConfig.Config.OneDLutConfig.pSampleValues"); + + for (uint32_t i = 0; i < LutDataSize; i++) + { + APP_LOG_INFO("[%d] = %f", i, LutConfig.Config.OneDLutConfig.pSampleValues[i]); + } + +Exit: + CTL_FREE_MEM(LutConfig.Config.OneDLutConfig.pSampleValues); + return Result; +} + +/*************************************************************** + * @brief + * SetGammaLut + * @param hDisplayOutput ,pPixTxCaps, OneDLUTIndex + * @return ctl_result_t + ***************************************************************/ +ctl_result_t SetGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t* pPixTxCaps, int32_t OneDLUTIndex) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_pixtx_block_config_t LutConfig = pPixTxCaps->pBlockConfigs[OneDLUTIndex]; + + LutConfig.Size = sizeof(ctl_pixtx_block_config_t); + LutConfig.Config.OneDLutConfig.SamplingType = CTL_PIXTX_LUT_SAMPLING_TYPE_UNIFORM; + LutConfig.Config.OneDLutConfig.NumChannels = 3; + LutConfig.Config.OneDLutConfig.pSamplePositions = NULL; + + ctl_pixtx_pipe_set_config_t SetPixTxArgs = { 0 }; + SetPixTxArgs.Size = sizeof(ctl_pixtx_pipe_set_config_t); + SetPixTxArgs.OpertaionType = CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM; + SetPixTxArgs.NumBlocks = 1; // We are enabling only one block + SetPixTxArgs.pBlockConfigs = &LutConfig; // for 1DLUT block + + double* pRedLut, * pGreenLut, * pBlueLut; + double LutMultiplier; + + // Create a valid 1D LUT. + const uint32_t LutSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; + LutConfig.Config.OneDLutConfig.pSampleValues = (double*)malloc(LutSize * sizeof(double)); + + EXIT_ON_MEM_ALLOC_FAILURE(LutConfig.Config.OneDLutConfig.pSampleValues, " LutConfig.Config.OneDLutConfig.pSampleValues"); + + pRedLut = LutConfig.Config.OneDLutConfig.pSampleValues; + pGreenLut = pRedLut + LutConfig.Config.OneDLutConfig.NumSamplesPerChannel; + pBlueLut = pGreenLut + LutConfig.Config.OneDLutConfig.NumSamplesPerChannel; + + // Applying a LUT which reduces the Red channel values by 30%.in linear format + // Based on the Pixel Encoding type , encode the multiplier 0.7 with the same function + // For example if Encoding is ST2084 then OETF2084(0.7) -> 0.962416136 + // if Encoding is SRGB then sRGB(0.7) -> 0.854305832 + + if (CTL_PIXTX_GAMMA_ENCODING_TYPE_ST2084 == pPixTxCaps->OutputPixelFormat.EncodingType) + { + LutMultiplier = 0.962416136; + } + else if (CTL_PIXTX_GAMMA_ENCODING_TYPE_SRGB == pPixTxCaps->OutputPixelFormat.EncodingType) + { + LutMultiplier = 0.854305832; + } + else + { + LutMultiplier = 1.0; + } + + // When calling Set for just OneDLUT the LUT is expected to be a Relative Correction LUT + for (uint32_t i = 0; i < LutConfig.Config.OneDLutConfig.NumSamplesPerChannel; i++) + { + double Input = (double)i / (double)(LutConfig.Config.OneDLutConfig.NumSamplesPerChannel - 1); + pRedLut[i] = pGreenLut[i] = pBlueLut[i] = Input; + pRedLut[i] *= LutMultiplier; + } + + Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlPixelTransformationSetConfig"); + +Exit: + CTL_FREE_MEM(LutConfig.Config.OneDLutConfig.pSampleValues); + return Result; +} + +/*************************************************************** + * @brief + * GetGammaLut + * @param hDisplayOutput ,pPixTxCaps, OneDLUTIndex + * @return ctl_result_t + ***************************************************************/ +ctl_result_t GetGammaLut(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t* pPixTxCaps, int32_t OneDLUTIndex) +{ + ctl_pixtx_pipe_get_config_t GetPixTxCurrentArgs = { 0 }; + GetPixTxCurrentArgs.Size = sizeof(ctl_pixtx_pipe_get_config_t); + ctl_pixtx_block_config_t LutConfig = pPixTxCaps->pBlockConfigs[OneDLUTIndex]; + ctl_result_t Result = CTL_RESULT_SUCCESS; + + GetPixTxCurrentArgs.QueryType = CTL_PIXTX_CONFIG_QUERY_TYPE_CURRENT; + GetPixTxCurrentArgs.NumBlocks = 1; // We are trying to query only one block + GetPixTxCurrentArgs.pBlockConfigs = &LutConfig; // Providing Lut config + LutConfig.Config.OneDLutConfig.pSampleValues = (double*)malloc(LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels * sizeof(double)); + + EXIT_ON_MEM_ALLOC_FAILURE(LutConfig.Config.OneDLutConfig.pSampleValues, "LutConfig.Config.OneDLutConfig.pSampleValues"); + + memset(LutConfig.Config.OneDLutConfig.pSampleValues, 0, LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels * sizeof(double)); + + Result = ctlPixelTransformationGetConfig(hDisplayOutput, &GetPixTxCurrentArgs); + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig"); + + uint32_t LutDataSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; + APP_LOG_INFO("LutDataSize = %d ", LutDataSize); + + APP_LOG_INFO("Gamma values : LutConfig.Config.OneDLutConfig.pSampleValues"); + + for (uint32_t i = 0; i < LutDataSize; i++) + { + APP_LOG_INFO("[%d] = %f", i, LutConfig.Config.OneDLutConfig.pSampleValues[i]); + } + +Exit: + CTL_FREE_MEM(LutConfig.Config.OneDLutConfig.pSampleValues); + return Result; +} + +/*************************************************************** + * @brief + * Get Set DeGamma + * Iterate through blocks PixTxCaps and find the LUT. + * @param ctl_display_output_handle_t ,ctl_pixtx_pipe_get_config_t + * @return + ***************************************************************/ +void GetSetDeGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t *pPixTxCaps) +{ + // One approach could be check for CSC with offsets block, the block right before CSC with offset block is DGLUT. + + ctl_result_t Result = CTL_RESULT_SUCCESS; + int32_t DGLUTIndex = -1; + + for (uint32_t i = 0; i < pPixTxCaps->NumBlocks; i++) + { + if ((CTL_PIXTX_BLOCK_TYPE_1D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) && (CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS == pPixTxCaps->pBlockConfigs[i + 1].BlockType)) + { + DGLUTIndex = i; + break; + } + } + + if (DGLUTIndex < 0) + { + APP_LOG_ERROR("Invalid DGLut Index"); + goto Exit; + } + + // Set DeGamma + Result = SetDeGammaLut(hDisplayOutput, pPixTxCaps, DGLUTIndex); + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("SetDeGammaLut call failed"); + STORE_AND_RESET_ERROR(Result); + } + else + { + // Get DeGamma + Result = GetDeGammaLut(hDisplayOutput, pPixTxCaps, DGLUTIndex); + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("GetDeGamma call failed"); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "GetDeGammaLut"); + } + } + +Exit: + return; +} + +/*************************************************************** + * @brief + * Get Set Gamma + * Iterate through blocks PixTxCaps and find the LUT. + * @param ctl_display_output_handle_t ,ctl_pixtx_pipe_get_config_t + * @return + ***************************************************************/ +void GetSetGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t *pPixTxCaps) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + // One approach could be check for CSC with offsets block, the block right after CSC with offset block is GLUT. + // In HDR mode only one 1DLUT block will be reported and that is of GLUT. So, need to take last occurrence of 1DLUT block in consideration. + + int32_t OneDLUTIndex = -1; + + for (uint8_t i = 0; i < pPixTxCaps->NumBlocks; i++) + { + // Need to consider the last 1DLUT block for Gamma + if (CTL_PIXTX_BLOCK_TYPE_1D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) + { + OneDLUTIndex = i; + } + } + + if (OneDLUTIndex < 0) + { + APP_LOG_ERROR("Invalid OneDLut Index"); + goto Exit; + } + + // Set Gamma + Result = SetGammaLut(hDisplayOutput, pPixTxCaps, OneDLUTIndex); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_ERROR("SetGammaLut call failed"); + STORE_AND_RESET_ERROR(Result); + } + else + { + // Get Gamma + Result = GetGammaLut(hDisplayOutput, pPixTxCaps, OneDLUTIndex); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "GetGammaLut"); + } + +Exit: + return; +} + +/*************************************************************** + * @brief + * ApplyLinearCSC DGLUT->CSC->GLUT + * @param hDisplayOutput + * @param pPixTxCaps + * @return + ***************************************************************/ +ctl_result_t ApplyLinearCSC(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t *pPixTxCaps) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + if (nullptr == hDisplayOutput) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + + if (nullptr == pPixTxCaps) + { + return CTL_RESULT_ERROR_INVALID_NULL_POINTER; + } + + // One approach could be check for CSC with offsets block, the block right before CSC with offset block is DGLUT and the Block Right after CSC with Offsets block is GLUT. + + // In HDR mode only one 1DLUT block will be reported and that is of GLUT. So, need to take last occurrence of 1DLUT block in consideration. + + int32_t DGLUTIndex, CscIndex, GLUTIndex; + DGLUTIndex = CscIndex = GLUTIndex = -1; + uint32_t OneDLutOccurances = 0; + + for (uint32_t i = 0; i < pPixTxCaps->NumBlocks; i++) + { + if (CTL_PIXTX_BLOCK_TYPE_1D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) + { + if ((CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS == pPixTxCaps->pBlockConfigs[i + 1].BlockType) && (CTL_PIXTX_BLOCK_TYPE_1D_LUT == pPixTxCaps->pBlockConfigs[i + 2].BlockType)) + { + DGLUTIndex = i; + CscIndex = i + 1; + GLUTIndex = i + 2; + } + break; + } + } + + if (DGLUTIndex < 0 || CscIndex < 0 || GLUTIndex < 0) + { + APP_LOG_ERROR("Invalid Index for DGLUT/CSC/GLUT"); + return CTL_RESULT_ERROR_INVALID_ARGUMENT; + } + + ctl_pixtx_block_config_t DGLUTConfig = pPixTxCaps->pBlockConfigs[DGLUTIndex]; + ctl_pixtx_block_config_t CSCConfig = pPixTxCaps->pBlockConfigs[CscIndex]; + ctl_pixtx_block_config_t GLUTConfig = pPixTxCaps->pBlockConfigs[GLUTIndex]; + + ctl_pixtx_pipe_set_config_t SetPixTxArgs = { 0 }; + SetPixTxArgs.Size = sizeof(ctl_pixtx_pipe_set_config_t); + SetPixTxArgs.OpertaionType = CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM; + SetPixTxArgs.NumBlocks = 3; // We are trying to set only one block + SetPixTxArgs.pBlockConfigs = (ctl_pixtx_block_config_t *)malloc(SetPixTxArgs.NumBlocks * sizeof(ctl_pixtx_block_config_t)); + EXIT_ON_MEM_ALLOC_FAILURE(SetPixTxArgs.pBlockConfigs, " SetPixTxArgs.pBlockConfigs"); + + memset(SetPixTxArgs.pBlockConfigs, 0, SetPixTxArgs.NumBlocks * sizeof(ctl_pixtx_block_config_t)); + + // DGLUT values + const uint32_t DGLutSize = DGLUTConfig.Config.OneDLutConfig.NumSamplesPerChannel * DGLUTConfig.Config.OneDLutConfig.NumChannels; + SetPixTxArgs.pBlockConfigs[0].BlockId = DGLUTConfig.BlockId; + SetPixTxArgs.pBlockConfigs[0].BlockType = DGLUTConfig.BlockType; + SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.NumChannels = DGLUTConfig.Config.OneDLutConfig.NumChannels; + SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.NumSamplesPerChannel = DGLUTConfig.Config.OneDLutConfig.NumSamplesPerChannel; + SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.SamplingType = DGLUTConfig.Config.OneDLutConfig.SamplingType; + SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.pSampleValues = (double *)malloc(DGLutSize * sizeof(double)); + + EXIT_ON_MEM_ALLOC_FAILURE(SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.pSampleValues, " SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.pSampleValues"); + + memset(SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.pSampleValues, 0, DGLutSize * sizeof(double)); + + for (uint32_t i = 0; i < (DGLutSize / DGLUTConfig.Config.OneDLutConfig.NumChannels); i++) + { + double Input = (double)i / (double)(DGLutSize - 1); + SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.pSampleValues[i] = GetSRGBDecodingValue(Input); + } + + // CSC Values + double PostOffsets[3] = { 0, 0, 0 }; + double PreOffsets[3] = { 0, 0, 0 }; + double Matrix[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; // Identity Matrix + // double Matrix[3][3] = { { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } }; // Red Blue swap Matrix + SetPixTxArgs.pBlockConfigs[1].BlockId = CSCConfig.BlockId; + SetPixTxArgs.pBlockConfigs[1].BlockType = CSCConfig.BlockType; + + // Create a valid CSC Matrix. + for (uint32_t i = 0; i < 3; i++) + { + CSCConfig.Config.MatrixConfig.PreOffsets[i] = PreOffsets[i]; + } + for (uint32_t i = 0; i < 3; i++) + { + CSCConfig.Config.MatrixConfig.PostOffsets[i] = PostOffsets[i]; + } + + memcpy_s(SetPixTxArgs.pBlockConfigs[1].Config.MatrixConfig.Matrix, sizeof(SetPixTxArgs.pBlockConfigs[1].Config.MatrixConfig.Matrix), Matrix, sizeof(Matrix)); + + // GLUT Values + // Create a valid 1D LUT. + const uint32_t GLutSize = GLUTConfig.Config.OneDLutConfig.NumSamplesPerChannel * GLUTConfig.Config.OneDLutConfig.NumChannels; + SetPixTxArgs.pBlockConfigs[2].BlockId = GLUTConfig.BlockId; + SetPixTxArgs.pBlockConfigs[2].BlockType = GLUTConfig.BlockType; + SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.NumChannels = GLUTConfig.Config.OneDLutConfig.NumChannels; + SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.NumSamplesPerChannel = GLUTConfig.Config.OneDLutConfig.NumSamplesPerChannel; + SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.SamplingType = GLUTConfig.Config.OneDLutConfig.SamplingType; + SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.pSampleValues = (double *)malloc(GLutSize * sizeof(double)); + + EXIT_ON_MEM_ALLOC_FAILURE(SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.pSampleValues, " SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.pSampleValues"); + + memset(SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.pSampleValues, 0, GLutSize * sizeof(double)); + + double *pRedLut = SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.pSampleValues; + double *pGreenLut = pRedLut + SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.NumSamplesPerChannel; + double *pBlueLut = pGreenLut + SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.NumSamplesPerChannel; + + for (uint32_t i = 0; i < (GLutSize / SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.NumChannels); i++) + { + double Input = (double)i / (double)((GLutSize / SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.NumChannels) - 1); + pRedLut[i] = pGreenLut[i] = pBlueLut[i] = GetSRGBEncodingValue(Input); + } + + Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlPixelTransformationSetConfig"); + +Exit: + if (NULL != SetPixTxArgs.pBlockConfigs) + { + CTL_FREE_MEM(SetPixTxArgs.pBlockConfigs[0].Config.OneDLutConfig.pSampleValues); + CTL_FREE_MEM(SetPixTxArgs.pBlockConfigs[2].Config.OneDLutConfig.pSampleValues); + } + CTL_FREE_MEM(SetPixTxArgs.pBlockConfigs); + return Result; +} + + +/*************************************************************** + * @brief + * GetPixTxCapability + * @param hDisplayOutput ,pPixTxCaps + * @return ctl_result_t + ***************************************************************/ +ctl_result_t GetPixTxCapability(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t *pPixTxCaps) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + Result = ctlPixelTransformationGetConfig(hDisplayOutput, pPixTxCaps); + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig for query type capability"); + + // Number of blocks + APP_LOG_INFO("GetPixTxCapsArgs.NumBlocks = %d", pPixTxCaps->NumBlocks); + + if (NULL == pPixTxCaps->pBlockConfigs) + { + goto Exit; + } + + for (uint8_t i = 0; i < pPixTxCaps->NumBlocks; i++) + { + ctl_pixtx_1dlut_config_t *pOneDLutConfig = &pPixTxCaps->pBlockConfigs[i].Config.OneDLutConfig; + + // Block specific information + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].BlockId = %d", i, pPixTxCaps->pBlockConfigs[i].BlockId); + if (CTL_PIXTX_BLOCK_TYPE_1D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) + { + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_1D_LUT"); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.NumChannels = %d", i, pOneDLutConfig->NumChannels); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.NumSamplesPerChannel = %d", i, pOneDLutConfig->NumSamplesPerChannel); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.OneDLutConfig.SamplingType = %d", i, pOneDLutConfig->SamplingType); + } + else if (CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX == pPixTxCaps->pBlockConfigs[i].BlockType) + { + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX"); + } + else if (CTL_PIXTX_BLOCK_TYPE_3D_LUT == pPixTxCaps->pBlockConfigs[i].BlockType) + { + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_3D_LUT"); + APP_LOG_INFO("pPixTxCaps->pBlockConfigs[%d].Config.ThreeDLutConfig.NumSamplesPerChannel = %d", i, pPixTxCaps->pBlockConfigs[i].Config.ThreeDLutConfig.NumSamplesPerChannel); + } + else if (CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS == pPixTxCaps->pBlockConfigs[i].BlockType) + { + APP_LOG_INFO("Block type is CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS"); + } + } + +Exit: + return Result; +} + + + ctl_result_t GetDeviceProperties(ctl_device_adapter_handle_t hDevice, ctl_device_adapter_properties_t* StDeviceAdapterProperties) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + StDeviceAdapterProperties->Size = sizeof(ctl_device_adapter_properties_t); + StDeviceAdapterProperties->pDeviceID = malloc(sizeof(LUID)); + StDeviceAdapterProperties->device_id_size = sizeof(LUID); + StDeviceAdapterProperties->Version = 2; + + Result = ctlGetDeviceProperties(hDevice, StDeviceAdapterProperties); + + if (CTL_RESULT_ERROR_UNSUPPORTED_VERSION == Result) // reduce version if required & recheck + { + printf("ctlGetDeviceProperties() version mismatch - Reducing version to 0 and retrying\n"); + StDeviceAdapterProperties->Version = 0; + Result = ctlGetDeviceProperties(hDevice, StDeviceAdapterProperties); + } + + cout << "======== GetDeviceProperties ========" << endl; + cout << "StDeviceAdapterProperties.Name: " << StDeviceAdapterProperties->name << endl; + + LOG_AND_EXIT_ON_ERROR(Result, "ctlGetDeviceProperties"); + + Exit: + return Result; + } + + ctl_result_t GetTelemetryData(ctl_device_adapter_handle_t hDevice, ctl_telemetry_data* TelemetryData) + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_power_telemetry_t pPowerTelemetry = {}; + pPowerTelemetry.Size = sizeof(ctl_power_telemetry_t); + + Result = ctlPowerTelemetryGet(hDevice, &pPowerTelemetry); + if (Result != CTL_RESULT_SUCCESS) + goto Exit; + + prevtimestamp = curtimestamp; + curtimestamp = pPowerTelemetry.timeStamp.value.datadouble; + deltatimestamp = curtimestamp - prevtimestamp; + + if (pPowerTelemetry.gpuEnergyCounter.bSupported) + { + TelemetryData->gpuEnergySupported = true; + prevgpuEnergyCounter = curgpuEnergyCounter; + curgpuEnergyCounter = pPowerTelemetry.gpuEnergyCounter.value.datadouble; + + TelemetryData->gpuEnergyValue = (curgpuEnergyCounter - prevgpuEnergyCounter) / deltatimestamp; + } + + TelemetryData->gpuVoltageSupported = pPowerTelemetry.gpuVoltage.bSupported; + TelemetryData->gpuVoltagValue = pPowerTelemetry.gpuVoltage.value.datadouble; + + TelemetryData->gpuCurrentClockFrequencySupported = pPowerTelemetry.gpuCurrentClockFrequency.bSupported; + TelemetryData->gpuCurrentClockFrequencyValue = pPowerTelemetry.gpuCurrentClockFrequency.value.datadouble; + + TelemetryData->gpuCurrentTemperatureSupported = pPowerTelemetry.gpuCurrentTemperature.bSupported; + TelemetryData->gpuCurrentTemperatureValue = pPowerTelemetry.gpuCurrentTemperature.value.datadouble; + + if (pPowerTelemetry.globalActivityCounter.bSupported) + { + TelemetryData->globalActivitySupported = true; + prevglobalActivityCounter = curglobalActivityCounter; + curglobalActivityCounter = pPowerTelemetry.globalActivityCounter.value.datadouble; + + TelemetryData->globalActivityValue = 100 * (curglobalActivityCounter - prevglobalActivityCounter) / deltatimestamp; + } + + if (pPowerTelemetry.renderComputeActivityCounter.bSupported) + { + TelemetryData->renderComputeActivitySupported = true; + prevrenderComputeActivityCounter = currenderComputeActivityCounter; + currenderComputeActivityCounter = pPowerTelemetry.renderComputeActivityCounter.value.datadouble; + + TelemetryData->renderComputeActivityValue = 100 * (currenderComputeActivityCounter - prevrenderComputeActivityCounter) / deltatimestamp; + } + + if (pPowerTelemetry.mediaActivityCounter.bSupported) + { + TelemetryData->mediaActivitySupported = true; + prevmediaActivityCounter = curmediaActivityCounter; + curmediaActivityCounter = pPowerTelemetry.mediaActivityCounter.value.datadouble; + + TelemetryData->mediaActivityValue = 100 * (curmediaActivityCounter - prevmediaActivityCounter) / deltatimestamp; + } + + if (pPowerTelemetry.vramEnergyCounter.bSupported) + { + TelemetryData->vramEnergySupported = true; + prevvramEnergyCounter = curvramEnergyCounter; + curvramEnergyCounter = pPowerTelemetry.vramEnergyCounter.value.datadouble; + + TelemetryData->vramEnergyValue = (curvramEnergyCounter - prevvramEnergyCounter) / deltatimestamp; + } + + TelemetryData->vramVoltageSupported = pPowerTelemetry.vramVoltage.bSupported; + TelemetryData->vramVoltageValue = pPowerTelemetry.vramVoltage.value.datadouble; + + TelemetryData->vramCurrentClockFrequencySupported = pPowerTelemetry.vramCurrentClockFrequency.bSupported; + TelemetryData->vramCurrentClockFrequencyValue = pPowerTelemetry.vramCurrentClockFrequency.value.datadouble; + + if (pPowerTelemetry.vramReadBandwidthCounter.bSupported) + { + TelemetryData->vramReadBandwidthSupported = true; + prevvramReadBandwidthCounter = curvramReadBandwidthCounter; + curvramReadBandwidthCounter = pPowerTelemetry.vramReadBandwidthCounter.value.datadouble; + + TelemetryData->vramReadBandwidthValue = (curvramReadBandwidthCounter - prevvramReadBandwidthCounter) / deltatimestamp; + } + + if (pPowerTelemetry.vramWriteBandwidthCounter.bSupported) + { + TelemetryData->vramWriteBandwidthSupported = true; + prevvramWriteBandwidthCounter = curvramWriteBandwidthCounter; + curvramWriteBandwidthCounter = pPowerTelemetry.vramWriteBandwidthCounter.value.datadouble; + + TelemetryData->vramWriteBandwidthValue = (curvramWriteBandwidthCounter - prevvramWriteBandwidthCounter) / deltatimestamp; + } + + TelemetryData->vramCurrentTemperatureSupported = pPowerTelemetry.vramCurrentTemperature.bSupported; + TelemetryData->vramCurrentTemperatureValue = pPowerTelemetry.vramCurrentTemperature.value.datadouble; + + TelemetryData->fanSpeedSupported = pPowerTelemetry.fanSpeed[0].bSupported; + TelemetryData->fanSpeedValue = pPowerTelemetry.fanSpeed[0].value.datadouble; + + Exit: + return Result; + } + + ctl_result_t IntializeIgcl() + { + ctl_result_t Result = CTL_RESULT_SUCCESS; + + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + + ctl_init_args_t ctlInitArgs; + ctlInitArgs.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION); + ctlInitArgs.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO; + ctlInitArgs.Size = sizeof(ctlInitArgs); + ctlInitArgs.Version = 0; + ZeroMemory(&ctlInitArgs.ApplicationUID, sizeof(ctl_application_id_t)); + Result = ctlInit(&ctlInitArgs, &hAPIHandle); + + return Result; + } + + void CloseIgcl() + { + ctlClose(hAPIHandle); + + if (hDevices != nullptr) + { + free(hDevices); + hDevices = nullptr; + } + } + +/*************************************************************** + * @brief + * SetCsc + * Iterate through blocks PixTxCaps and find the CSC block. + * @param hDisplayOutput, pPixTxCaps, CscBlockIndex + * @return ctl_result_t + ***************************************************************/ +ctl_result_t SetCsc(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_pipe_get_config_t *pPixTxCaps, int32_t CscBlockIndex) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_pixtx_block_config_t CSCConfig = pPixTxCaps->pBlockConfigs[CscBlockIndex]; + CSCConfig.Size = sizeof(ctl_pixtx_block_config_t); + CSCConfig.BlockType = CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX; + double PostOffsets[3] = { 1, 0, 0 }; + double PreOffsets[3] = { 1, 0, 0 }; + double Matrix[3][3] = { { 1.2, 0, 0 }, { 0, 1.2, 0 }, { 0, 0, 1.2 } }; // Contrast enhancement by 20% + + // Create a valid CSC Matrix. + for (uint8_t i = 0; i < 3; i++) + { + CSCConfig.Config.MatrixConfig.PreOffsets[i] = PreOffsets[i]; + } + + for (uint8_t i = 0; i < 3; i++) + { + CSCConfig.Config.MatrixConfig.PostOffsets[i] = PostOffsets[i]; + } + + memcpy_s(CSCConfig.Config.MatrixConfig.Matrix, sizeof(CSCConfig.Config.MatrixConfig.Matrix), Matrix, sizeof(Matrix)); + + ctl_pixtx_pipe_set_config_t SetPixTxArgs = { 0 }; + SetPixTxArgs.Size = sizeof(ctl_pixtx_pipe_set_config_t); + SetPixTxArgs.OpertaionType = CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM; + SetPixTxArgs.NumBlocks = 1; // We are trying to set only one block + SetPixTxArgs.pBlockConfigs = &CSCConfig; // for CSC block + SetPixTxArgs.pBlockConfigs->BlockId = pPixTxCaps->pBlockConfigs[CscBlockIndex].BlockId; + + Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlPixelTransformationSetConfig"); + + return Result; +} + +/*************************************************************** + * @brief + * CIELabTxFn + * @param Input + * @return double + ***************************************************************/ +double CIELabTxFn(double Input) +{ + double RetVal = 0; + + /* + https://en.wikipedia.org/wiki/CIELAB_color_space#From_CIEXYZ_to_CIELAB + */ + + if (Input > pow(6.0 / 29.0, 3.0)) + { + RetVal = pow(Input, (1.0 / 3.0)); + } + else + { + RetVal = Input * (pow(29.0 / 6.0, 2.0) / 3.0) + (4.0 / 29.0); + } + + return RetVal; +} + +/*************************************************************** + * @brief + * GetCIELab + * @param Color, WhitePoint, ColorLab + * @return void + ***************************************************************/ +void GetCIELab(IPIXEL_XYZ Color, IPIXEL_XYZ WhitePoint, IPIXEL_Lab& ColorLab) +{ + /* + https://en.wikipedia.org/wiki/CIELAB_color_space#From_CIEXYZ_to_CIELAB + */ + + Color.X /= WhitePoint.X; + Color.Y /= WhitePoint.Y; + Color.Z /= WhitePoint.Z; + + ColorLab.L = 116.0 * (CIELabTxFn(Color.Y)) - 16; + ColorLab.A = 500.0 * (CIELabTxFn(Color.X) - CIELabTxFn(Color.Y)); + ColorLab.B = 200.0 * (CIELabTxFn(Color.Y) - CIELabTxFn(Color.Z)); +} + +/*************************************************************** + * @brief + * CalculateColorAngle + * @param R,G,B + * @return void + ***************************************************************/ +double CalculateColorAngle(double R, double G, double B) +{ + double RGB[3] = { 0 }; + IPIXEL_XYZ XYZ; + IPIXEL_Lab Lab; + + RGB[0] = GetSRGBDecodingValue(R); + RGB[1] = GetSRGBDecodingValue(G); + RGB[2] = GetSRGBDecodingValue(B); + + MatrixMult3x3With3x1(RGB2XYZ_709, RGB, (double*)&XYZ); + + XYZ.X *= 100.0; + XYZ.Y *= 100.0; + XYZ.Z *= 100.0; + + GetCIELab(XYZ, RefWhitePointSRGB, Lab); + + double Angle = atan2(Lab.B, Lab.A); // https://en.wikipedia.org/wiki/Hue + + // convert [-Pi, Pi] range to [0, 2 * Pi] range + if (Angle < 0) + { + Angle = 2.0 * Pi - (ABS_DOUBLE(Angle)); + } + + Angle /= (2.0 * Pi); + + return Angle; +} + +/*************************************************************** + * @brief + * InterpolateSaturationFactor + * @param ColorAngle, pBasicColors, pColorSaturation + * @return double + ***************************************************************/ +double InterpolateSaturationFactor(double ColorAngle, double* pBasicColors, double* pColorSaturation) +{ + double SatFactor = SATURATION_FACTOR_BASE; + double Slope, SatFactor1, SatFactor2, Diff; + + // ColorIndex1 represents index of anchor color previous to colorAngle + // ColorIndex2 represents index of anchor color next to colorAngle + HUE_ANCHOR ColorIndex1, ColorIndex2; + ColorIndex1 = (HUE_ANCHOR)((uint8_t)HUE_ANCHOR_COLOR_COUNT_SATURATION - 1); + + for (uint8_t i = 0; i < (uint8_t)HUE_ANCHOR_COLOR_COUNT_SATURATION; i++) + { + if (pBasicColors[i] <= ColorAngle) + { + ColorIndex1 = (HUE_ANCHOR)i; + } + } + + ColorIndex2 = (HUE_ANCHOR)((ColorIndex1 + 1) % HUE_ANCHOR_COLOR_COUNT_SATURATION); + + SatFactor1 = pColorSaturation[(uint8_t)ColorIndex1]; + SatFactor2 = pColorSaturation[(uint8_t)ColorIndex2]; + + if ((uint8_t)ColorIndex1 <= 4 || ColorAngle >= pBasicColors[(uint8_t)ColorIndex1]) + { + Diff = ColorAngle - pBasicColors[ColorIndex1]; + Slope = (SatFactor2 - SatFactor1) / (pBasicColors[ColorIndex2] - pBasicColors[ColorIndex1]); + } + else + { + Diff = ColorAngle - pBasicColors[ColorIndex1] + 1.0; + Slope = (SatFactor2 - SatFactor1) / (pBasicColors[ColorIndex2] - pBasicColors[ColorIndex1] + 1.0); + } + + SatFactor = SatFactor1 + Slope * Diff; + + return SatFactor; +} + +/*************************************************************** + * @brief + * PerformRGB2YCbCr: Conversion of RGB to YCbCr + * @param InPixel, OutPixel + * @return void + ***************************************************************/ +void PerformRGB2YCbCr(ctl_pixtx_3dlut_sample_t InPixel, IPIXELD_YCbCr& OutPixel) +{ + // Numbers used are BT 701 coefficients used for RGB to YCbCr conversion. + // https://en.wikipedia.org/wiki/YUV#Conversion_to/from_RGB + + OutPixel.Y = RGB2YCbCr709[0][0] * InPixel.Red + RGB2YCbCr709[0][1] * InPixel.Green + RGB2YCbCr709[0][2] * InPixel.Blue; + OutPixel.Cb = RGB2YCbCr709[1][0] * InPixel.Red + RGB2YCbCr709[1][1] * InPixel.Green + RGB2YCbCr709[1][2] * InPixel.Blue; + OutPixel.Cr = RGB2YCbCr709[2][0] * InPixel.Red + RGB2YCbCr709[2][1] * InPixel.Green + RGB2YCbCr709[2][2] * InPixel.Blue; +} + + +/*************************************************************** + * @brief + * PerformYCbCr2RGB: Conversion of YCbCr to RGB + * @param InPixel, OutPixel + * @return void + ***************************************************************/ +void PerformYCbCr2RGB(IPIXELD_YCbCr InPixel, ctl_pixtx_3dlut_sample_t& OutPixel) +{ + // BT 701 coefficients + // Numbers used are BT 701 coefficients used for YCbCr to RGB conversion. + // https://en.wikipedia.org/wiki/YUV#Conversion_to/from_RGB + + OutPixel.Red = InPixel.Y + YCbCr2RGB709[0][2] * InPixel.Cr; + OutPixel.Green = InPixel.Y + YCbCr2RGB709[1][1] * InPixel.Cb + YCbCr2RGB709[1][2] * InPixel.Cr; + OutPixel.Blue = InPixel.Y + YCbCr2RGB709[2][1] * InPixel.Cb; + + OutPixel.Red = CLIP_DOUBLE(OutPixel.Red, 0.0, 1.0); + OutPixel.Green = CLIP_DOUBLE(OutPixel.Green, 0.0, 1.0); + OutPixel.Blue = CLIP_DOUBLE(OutPixel.Blue, 0.0, 1.0); +} + +/*************************************************************** + * @brief + * ChangePixelSaturation + * @param PixelRGB, pBasicColors, pSatWeights + * @return void + ***************************************************************/ +void ChangePixelSaturation(ctl_pixtx_3dlut_sample_t& PixelRGB, double* pBasicColors, double* pSatWeights) +{ + double SatFactor = SATURATION_FACTOR_BASE; + double ColorAngle = 0; + IPIXELD_YCbCr PixelYCbCr; + + if ((PixelRGB.Red == PixelRGB.Green) && (PixelRGB.Green == PixelRGB.Blue)) + { + return; // Do not process Grey pixels + } + + PerformRGB2YCbCr(PixelRGB, PixelYCbCr); + + ColorAngle = CalculateColorAngle(PixelRGB.Red, PixelRGB.Green, PixelRGB.Blue); + + //--- Calculate Sat Factor (Step 1) --- + SatFactor = InterpolateSaturationFactor(ColorAngle, pBasicColors, pSatWeights); + + //--- Over Saturation Limiter (Step 2) --- + double UVmax = max((PixelYCbCr.Cb), ABS_DOUBLE(PixelYCbCr.Cr)); + UVmax *= 2.0; + + if ((UVmax >= UV_MAX_POINT) && (SatFactor > SATURATION_FACTOR_BASE)) + { + SatFactor = SATURATION_FACTOR_BASE; + } + else if (SatFactor > SATURATION_FACTOR_BASE) + { + // Limit SatFactor according to original saturation + double a = (SatFactor - SATURATION_FACTOR_BASE) * (UV_MAX_POINT - UVmax) / UV_MAX_POINT; + SatFactor = SATURATION_FACTOR_BASE + a; + } + + //--- Grey Pixels Saturation Limiter (Step 3) --- + if (SatFactor > SATURATION_FACTOR_BASE) + { + double dSat = SatFactor - SATURATION_FACTOR_BASE; + + if (UV_MIN_POINT1 >= UVmax) + { + dSat = 0; + } + else if (UV_MIN_POINT1 < UVmax && UVmax <= UV_MIN_POINT2) + { + dSat *= (UVmax - UV_MIN_POINT1); + } + + SatFactor = SATURATION_FACTOR_BASE + dSat; + } + + //--- Calculate New U,V values --- + PixelYCbCr.Cb = SatFactor * PixelYCbCr.Cb; + PixelYCbCr.Cr = SatFactor * PixelYCbCr.Cr; + + PerformYCbCr2RGB(PixelYCbCr, PixelRGB); + +} + +/*************************************************************** + * @brief + * CreateDefault3DLut + * @param pLUT, LutDepth, pSamplingPosition + * @return void + ***************************************************************/ +void CreateDefault3DLut(ctl_pixtx_3dlut_sample_t* pLUT, uint8_t LutDepth, double* pSamplingPosition) +{ + for (uint8_t R = 0; R < LutDepth; R++) + { + for (uint8_t G = 0; G < LutDepth; G++) + { + for (uint8_t B = 0; B < LutDepth; B++) + { + pLUT->Red = pSamplingPosition[R]; + pLUT->Green = pSamplingPosition[G]; + pLUT->Blue = pSamplingPosition[B]; + pLUT++; + } + } + } +} + + +/*************************************************************** + * @brief + * InitializePartialSaturationAnchorValues + * @param pBasicColors + * @return void + ***************************************************************/ +void InitializePartialSaturationAnchorValues(double* pBasicColors) +{ + pBasicColors[HUE_ANCHOR_RED_SATURATION] = 0.11111097848067050; // Output of CalculateColorAngle() with pure red input (1.0, 0, 0); + pBasicColors[HUE_ANCHOR_YELLOW_SATURATION] = 0.28571682845597457; // Output of CalculateColorAngle() with pure yellow input (1.0, 1.0, 0); + pBasicColors[HUE_ANCHOR_GREEN_SATURATION] = 0.37782403959790056; // Output of CalculateColorAngle() with pure green input (0, 1.0, 0); + pBasicColors[HUE_ANCHOR_CYAN_SATURATION] = 0.54552642779786065; // Output of CalculateColorAngle() with pure cyan input (0, 1.0, 1.0); + pBasicColors[HUE_ANCHOR_BLUE_SATURATION] = 0.85079006538296154; // Output of CalculateColorAngle() with pure blue input (0, 0, 1.0); + pBasicColors[HUE_ANCHOR_MAGENTA_SATURATION] = 0.91174274251260268; // Output of CalculateColorAngle() with pure magenta input (1.0, 0, 1.0); +} + + +/*************************************************************** + * @brief + * IsDefaultPartialSaturationSettings + * @param pSatWeights + * @return bool + ***************************************************************/ +bool IsDefaultPartialSaturationSettings(double* pSatWeights) +{ + for (uint8_t i = 0; i < 6; i++) + { + if (DEFAULT_COLOR_SAT != pSatWeights[i]) + { + return false; + } + } + + return true; +} + + +/*************************************************************** + * @brief + * Generate3DLutFromPSWeights + * @param pLUT, LutDepth, pSatWeights + * @return ctl_result_t + ***************************************************************/ +ctl_result_t Generate3DLutFromPSWeights(ctl_pixtx_3dlut_sample_t *pLUT, uint8_t LutDepth, double *pSatWeights) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + + ctl_pixtx_3dlut_sample_t Pix; + double BasicColors[HUE_ANCHOR_COLOR_COUNT_SATURATION]; + + bool IsDefaultConfig = IsDefaultPartialSaturationSettings(pSatWeights); + + InitializePartialSaturationAnchorValues(BasicColors); + + double *pSamplingPosition = (double *)malloc(LutDepth * sizeof(double)); + EXIT_ON_MEM_ALLOC_FAILURE(pSamplingPosition, "pSamplingPosition"); + + for (uint8_t i = 0; i < LutDepth; i++) + { + pSamplingPosition[i] = (double)i / (double)(LutDepth - 1); + } + + if (IsDefaultConfig) + { + CreateDefault3DLut(pLUT, LutDepth, pSamplingPosition); + goto Exit; + } + + for (uint8_t R = 0; R < LutDepth; R++) + { + for (uint8_t G = 0; G < LutDepth; G++) + { + for (uint8_t B = 0; B < LutDepth; B++) + { + Pix.Red = pSamplingPosition[R]; + Pix.Green = pSamplingPosition[G]; + Pix.Blue = pSamplingPosition[B]; + + ChangePixelSaturation(Pix, BasicColors, pSatWeights); + + *pLUT++ = Pix; + } + } + } + +Exit: + CTL_FREE_MEM(pSamplingPosition); + return Result; +} + + + +/*************************************************************** + * @brief + * Generate OneDLut From brightness, contrast, gamma values + * @param pOneDLutConfig, Contrast, PanelGamma, Brightness + * @return void + ***************************************************************/ +void CreateOneDLutFromBCG(ctl_pixtx_1dlut_config_t *pOneDLutConfig, IPIXELD Contrast, IPIXELD PanelGamma, IPIXELD Brightness) +{ + IPIXELD RelativeGamma; + double *pRedLut, *pGreenLut, *pBlueLut; + double NormalizedOutputR, NormalizedOutputG, NormalizedOutputB; + double NormalizedInput; + double NormalizedOutputContrastBrightnessGammaR, NormalizedOutputContrastBrightnessGammaG, NormalizedOutputContrastBrightnessGammaB; + + RelativeGamma.R = PanelGamma.R; + RelativeGamma.G = PanelGamma.G; + RelativeGamma.B = PanelGamma.B; + + // Adjust inputs such that output is somewhat visible + Contrast.R = CLIP_DOUBLE(Contrast.R, 0.25, 1.75); + Contrast.G = CLIP_DOUBLE(Contrast.G, 0.25, 1.75); + Contrast.B = CLIP_DOUBLE(Contrast.B, 0.25, 1.75); + + // Adjust inputs such that output is somewhat visible + RelativeGamma.R = CLIP_DOUBLE(RelativeGamma.R, 0.3, 2.8); + RelativeGamma.G = CLIP_DOUBLE(RelativeGamma.G, 0.3, 2.8); + RelativeGamma.B = CLIP_DOUBLE(RelativeGamma.B, 0.3, 2.8); + + // Adjust inputs such that output is somewhat visible + Brightness.R = CLIP_DOUBLE(Brightness.R, -0.25, 0.25); + Brightness.G = CLIP_DOUBLE(Brightness.G, -0.25, 0.25); + Brightness.B = CLIP_DOUBLE(Brightness.B, -0.25, 0.25); + + // Create 1DLUT from given input + pRedLut = pOneDLutConfig->pSampleValues; + pGreenLut = pRedLut + pOneDLutConfig->NumSamplesPerChannel; + pBlueLut = pGreenLut + pOneDLutConfig->NumSamplesPerChannel; + + for (uint32_t i = 0; i < pOneDLutConfig->NumSamplesPerChannel; i++) + { + NormalizedInput = (double)i / (double)(pOneDLutConfig->NumSamplesPerChannel - 1); + + NormalizedOutputR = ((NormalizedInput * Contrast.R) + Brightness.R); + NormalizedOutputG = ((NormalizedInput * Contrast.G) + Brightness.G); + NormalizedOutputB = ((NormalizedInput * Contrast.B) + Brightness.B); + + NormalizedOutputR = CLIP_DOUBLE(NormalizedOutputR, 0.0, 1.0); + NormalizedOutputG = CLIP_DOUBLE(NormalizedOutputG, 0.0, 1.0); + NormalizedOutputB = CLIP_DOUBLE(NormalizedOutputB, 0.0, 1.0); + + NormalizedOutputContrastBrightnessGammaR = pow(NormalizedOutputR, RelativeGamma.R); + NormalizedOutputContrastBrightnessGammaG = pow(NormalizedOutputG, RelativeGamma.G); + NormalizedOutputContrastBrightnessGammaB = pow(NormalizedOutputB, RelativeGamma.B); + + pRedLut[i] = NormalizedOutputContrastBrightnessGammaR; + pGreenLut[i] = NormalizedOutputContrastBrightnessGammaG; + pBlueLut[i] = NormalizedOutputContrastBrightnessGammaB; + } +} + + +/*************************************************************** + * @brief + * ApplyBrightnessContrastGamma + * @param hDisplayOutput, pBlockConfig, Contrast, Gamma, Brightness + * @return ctl_result_t + ***************************************************************/ +ctl_result_t ApplyBrightnessContrastGamma(ctl_display_output_handle_t hDisplayOutput, ctl_pixtx_block_config_t *pBlockConfig, IPIXELD Contrast, IPIXELD Gamma, IPIXELD Brightness) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_pixtx_block_config_t LutConfig = *pBlockConfig; + LutConfig.Size = sizeof(ctl_pixtx_block_config_t); + const uint32_t LutSize = LutConfig.Config.OneDLutConfig.NumSamplesPerChannel * LutConfig.Config.OneDLutConfig.NumChannels; + // this is the cause of the crash, NumChannels one channel only ! + LutConfig.Config.OneDLutConfig.pSampleValues = (double *)malloc(LutSize * sizeof(double)); + + ctl_pixtx_pipe_set_config_t SetPixTxArgs = { 0 }; + SetPixTxArgs.Size = sizeof(ctl_pixtx_pipe_set_config_t); + SetPixTxArgs.OpertaionType = CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM; + SetPixTxArgs.NumBlocks = 1; // We are enabling only one block + SetPixTxArgs.pBlockConfigs = &LutConfig; // for 1DLUT block + + EXIT_ON_MEM_ALLOC_FAILURE(LutConfig.Config.OneDLutConfig.pSampleValues, "LutConfig.Config.OneDLutConfig.pSampleValues"); + + + CreateOneDLutFromBCG(&LutConfig.Config.OneDLutConfig, Contrast, Gamma, Brightness); + + Result = ctlPixelTransformationSetConfig(hDisplayOutput, &SetPixTxArgs); + + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationSetConfig"); + +Exit: + CTL_FREE_MEM(LutConfig.Config.OneDLutConfig.pSampleValues); + return Result; +} + +ctl_result_t SetBrightnessContrastGammaValues(ctl_device_adapter_handle_t hDevice, double contrast, double panelGamma, double brightness) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_output_handle_t *hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + + + // enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, NULL); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + } + else if (DisplayCount <= 0) + { + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", 0); + } + + hDisplayOutput = (ctl_display_output_handle_t *)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + // Todo: use Display Index in future, currently only Apply Hue Saturation on Display 0; + ctl_display_output_handle_t display = hDisplayOutput[0]; + + // 1st query about the number of blocks supported (pass PixTxCaps.pBlockConfigs as NULL to get number of blocks supported) and then allocate memeory accordingly in second call to get details of + // each pBlockConfigs + ctl_pixtx_pipe_get_config_t PixTxCaps = { 0 }; + PixTxCaps.Size = sizeof(ctl_pixtx_pipe_get_config_t); + PixTxCaps.QueryType = CTL_PIXTX_CONFIG_QUERY_TYPE_CAPABILITY; + + Result = GetPixTxCapability(display, &PixTxCaps); // API call will return the number of blocks supported in PixTxCaps.NumBlocks. + + if (0 == PixTxCaps.NumBlocks) + { + Result = CTL_RESULT_ERROR_INVALID_SIZE; + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig for query type capability"); + } + + const uint8_t NumBlocksToQuery = PixTxCaps.NumBlocks; // Query about the blocks in the pipeline + + // Allocate required memory as per number of blocks supported. + PixTxCaps.pBlockConfigs = (ctl_pixtx_block_config_t*)malloc(NumBlocksToQuery * sizeof(ctl_pixtx_block_config_t)); + EXIT_ON_MEM_ALLOC_FAILURE(PixTxCaps.pBlockConfigs, "PixTxCaps.pBlockConfigs"); + + memset(PixTxCaps.pBlockConfigs, 0, NumBlocksToQuery * sizeof(ctl_pixtx_block_config_t)); + + // Query capability of each block, number of blocks etc + Result = GetPixTxCapability(display, &PixTxCaps); + + int32_t DesktopGammaBlockIndex = -1; + for (uint8_t i = 0; i < PixTxCaps.NumBlocks; i++) + { + // Need to consider the last 1DLUT block for Gamma + if (CTL_PIXTX_BLOCK_TYPE_1D_LUT == PixTxCaps.pBlockConfigs[i].BlockType) + { + // Make sure it's 3 Channels for the 1D LUT and it's not the Gamma LUT Block + if ((3 == PixTxCaps.pBlockConfigs[i].Config.OneDLutConfig.NumChannels)) + { + DesktopGammaBlockIndex = i; + break; + } + } + } + + if (DesktopGammaBlockIndex < 0) + { + APP_LOG_ERROR("ctlPixelTransformationGetConfig did not report 1DLUT capability"); + STORE_AND_RESET_ERROR(Result); + } + else + { + double brightness_mapped = (brightness - 50.0) / 50.0 * 0.25; + double contrast_mapped = 1.0 + ((contrast - 50.0) / 50.0) * 0.75; + + + + IPIXELD Contrast = { 0 }; + IPIXELD PanelGamma = { 0 }; + IPIXELD Brightness = { 0 }; + + Contrast.R = contrast_mapped; + Contrast.G = contrast_mapped; + Contrast.B = contrast_mapped; + + PanelGamma.R = panelGamma; + PanelGamma.G = panelGamma; + PanelGamma.B = panelGamma; + + Brightness.R = brightness_mapped; + Brightness.G = brightness_mapped; + Brightness.B = brightness_mapped; + + Result = ApplyBrightnessContrastGamma(display, &PixTxCaps.pBlockConfigs[DesktopGammaBlockIndex], Contrast, PanelGamma, Brightness); + LOG_AND_EXIT_ON_ERROR(Result, "ApplyBrightnessContrastGamma"); + + // log for debug + cout << "======== SetBrightnessContrastGammaValues ========" << endl; + cout << "Contrast: " << contrast_mapped << endl; + cout << "PanelGamma: " << panelGamma << endl; + cout << "Brightness: " << brightness_mapped << endl; + } + +Exit: + return Result; +} + +double MapSaturation(int sliderValue) { + return 0.01 + sliderValue * 0.02; +} + +double MapHue(double sliderValue) { + double driverHue = fmod(sliderValue + 360.0, 360.0); + if (driverHue < 0.0) // handle negative wrap (just in case) + driverHue += 360.0; + return driverHue; +} + +ctl_result_t SetHueSaturationValues(ctl_device_adapter_handle_t hDevice, double Hue, double Saturation) +{ + ctl_result_t Result = CTL_RESULT_SUCCESS; + ctl_display_output_handle_t* hDisplayOutput = NULL; + uint32_t DisplayCount = 0; + + + // enumerate all the possible target display's for the adapters + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, NULL); + + if (CTL_RESULT_SUCCESS != Result) + { + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); + STORE_AND_RESET_ERROR(Result); + } + else if (DisplayCount <= 0) + { + APP_LOG_WARN("Invalid Display Count. skipping display enumration for adapter:%d", 0); + } + + hDisplayOutput = (ctl_display_output_handle_t*)malloc(sizeof(ctl_display_output_handle_t) * DisplayCount); + EXIT_ON_MEM_ALLOC_FAILURE(hDisplayOutput, "hDisplayOutput"); + + Result = ctlEnumerateDisplayOutputs(hDevice, &DisplayCount, hDisplayOutput); + LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, "ctlEnumerateDisplayOutputs"); + + // Todo: use Display Index in future, currently only Apply Hue Saturation on Display 0; + ctl_display_output_handle_t display = hDisplayOutput[0]; + + // 1st query about the number of blocks supported (pass PixTxCaps.pBlockConfigs as NULL to get number of blocks supported) and then allocate memeory accordingly in second call to get details of + // each pBlockConfigs + ctl_pixtx_pipe_get_config_t PixTxCaps = { 0 }; + PixTxCaps.Size = sizeof(ctl_pixtx_pipe_get_config_t); + PixTxCaps.QueryType = CTL_PIXTX_CONFIG_QUERY_TYPE_CAPABILITY; + + Result = GetPixTxCapability(display, &PixTxCaps); // API call will return the number of blocks supported in PixTxCaps.NumBlocks. + + if (0 == PixTxCaps.NumBlocks) + { + Result = CTL_RESULT_ERROR_INVALID_SIZE; + LOG_AND_EXIT_ON_ERROR(Result, "ctlPixelTransformationGetConfig for query type capability"); + } + + const uint8_t NumBlocksToQuery = PixTxCaps.NumBlocks; // Query about the blocks in the pipeline + + // Allocate required memory as per number of blocks supported. + PixTxCaps.pBlockConfigs = (ctl_pixtx_block_config_t*)malloc(NumBlocksToQuery * sizeof(ctl_pixtx_block_config_t)); + EXIT_ON_MEM_ALLOC_FAILURE(PixTxCaps.pBlockConfigs, "PixTxCaps.pBlockConfigs"); + + memset(PixTxCaps.pBlockConfigs, 0, NumBlocksToQuery * sizeof(ctl_pixtx_block_config_t)); + + // Query capability of each block, number of blocks etc + Result = GetPixTxCapability(display, &PixTxCaps); + + // Apply Hue Saturation + int32_t HueSatBlockIndex = -1; + + for (uint8_t i = 0; i < PixTxCaps.NumBlocks; i++) + { + if (CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX == PixTxCaps.pBlockConfigs[i].BlockType) + { + HueSatBlockIndex = i; + break; + } + } + + // issue the call + Result = ApplyHueSaturation(display, &PixTxCaps, HueSatBlockIndex, MapHue(Hue), MapSaturation(Saturation)); + LOG_AND_EXIT_ON_ERROR(Result, "ctl_result_t (ApplyHueSaturation)"); + + // log for debug + cout << "======== SetHueSaturationValues ========" << endl; + cout << "Hue: " << MapHue(Hue) << endl; + cout << "Saturation: " << MapSaturation(Saturation) << endl; + +Exit: + return Result; +} + +} \ No newline at end of file diff --git a/Samples/UBRR_Sample/CMakeLists.txt b/Samples/UBRR_Sample/CMakeLists.txt index 1b661e6..b5f0bf0 100644 --- a/Samples/UBRR_Sample/CMakeLists.txt +++ b/Samples/UBRR_Sample/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13.4 FATAL_ERROR) set(TARGET_NAME UBRR_Sample) get_filename_component(ROOT_DIR ../../ ABSOLUTE) project(UBRR_Sample VERSION 1.0) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/UBRR_Sample_App.cpp - ${ROOT_DIR}/wrapper/cApiWrapper.cpp + ${ROOT_DIR}/Source/cApiWrapper.cpp ) if(MSVC) @@ -18,5 +18,5 @@ if(MSVC) ADD_DEFINITIONS(-D_UNICODE) endif() -include_directories(${ROOT_DIR}/includes) +include_directories(${ROOT_DIR}/include) include_directories(${ROOT_DIR}/Samples/inc) \ No newline at end of file diff --git a/Samples/UBRR_Sample/UBRR_Sample_App.cpp b/Samples/UBRR_Sample/UBRR_Sample_App.cpp index ba2c3a6..4ff25bb 100644 --- a/Samples/UBRR_Sample/UBRR_Sample_App.cpp +++ b/Samples/UBRR_Sample/UBRR_Sample_App.cpp @@ -40,7 +40,7 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput if (0 == DisplayCount) { - printf("Invalid Display Count \n"); + APP_LOG_ERROR("Invalid Display Count "); goto Exit; } @@ -56,8 +56,9 @@ ctl_result_t EnumerateDisplayHandles(ctl_display_output_handle_t *hDisplayOutput continue; } - PowerOptimizationCaps.Size = sizeof(ctl_pfnGetPowerOptimizationCaps_t); - Result = ctlGetPowerOptimizationCaps(hDisplayOutput[DisplayIndex], &PowerOptimizationCaps); + PowerOptimizationCaps.Size = sizeof(ctl_pfnGetPowerOptimizationCaps_t); + PowerOptimizationCaps.Version = 1; + Result = ctlGetPowerOptimizationCaps(hDisplayOutput[DisplayIndex], &PowerOptimizationCaps); LOG_AND_EXIT_ON_ERROR(Result, "ctlGetPowerOptimizationCaps"); @@ -115,13 +116,13 @@ ctl_result_t EnumerateTargetDisplays(uint32_t AdapterCount, ctl_device_adapter_h if (CTL_RESULT_SUCCESS != Result) { - printf("ctlEnumerateDisplayOutputs returned failure code: 0x%X\n", Result); + APP_LOG_WARN("ctlEnumerateDisplayOutputs returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); continue; } else if (DisplayCount <= 0) { - printf("Invalid Display Count. skipping display enumration for adapter:%d\n", AdapterIndex); + APP_LOG_WARN("Invalid Display Count. skipping display enumeration for adapter:%d", AdapterIndex); continue; } @@ -170,25 +171,46 @@ int main() CtlInitArgs.Size = sizeof(CtlInitArgs); CtlInitArgs.Version = 0; - Result = ctlInit(&CtlInitArgs, &hAPIHandle); - LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + try + { + Result = ctlInit(&CtlInitArgs, &hAPIHandle); + LOG_AND_EXIT_ON_ERROR(Result, "ctlInit"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } // Initialization successful // Get the list of Intel Adapters - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } hDevices = (ctl_device_adapter_handle_t *)malloc(sizeof(ctl_device_adapter_handle_t) * AdapterCount); EXIT_ON_MEM_ALLOC_FAILURE(hDevices, "hDevices"); - Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); - LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + try + { + Result = ctlEnumerateDevices(hAPIHandle, &AdapterCount, hDevices); + LOG_AND_EXIT_ON_ERROR(Result, "ctlEnumerateDevices"); + } + catch (const std::bad_array_new_length &e) + { + APP_LOG_ERROR("%s ", e.what()); + } Result = EnumerateTargetDisplays(AdapterCount, hDevices); if (CTL_RESULT_SUCCESS != Result) { - printf("EnumerateTargetDisplays returned failure code: 0x%X\n", Result); + APP_LOG_ERROR("EnumerateTargetDisplays returned failure code: 0x%X", Result); STORE_AND_RESET_ERROR(Result); } @@ -196,6 +218,6 @@ int main() ctlClose(hAPIHandle); CTL_FREE_MEM(hDevices); - printf("Overrall test result is 0x%X\n", GResult); + APP_LOG_INFO("Overrall test result is 0x%X", GResult); return GResult; -} \ No newline at end of file +} diff --git a/Samples/inc/GenericIGCLApp.h b/Samples/inc/GenericIGCLApp.h index 121e90b..b7d1012 100644 --- a/Samples/inc/GenericIGCLApp.h +++ b/Samples/inc/GenericIGCLApp.h @@ -38,29 +38,36 @@ if (CTL_RESULT_SUCCESS != Result) \ goto Exit; -#define LOG_AND_EXIT_ON_ERROR(Result, ErrRtrndByFunc) \ - if (CTL_RESULT_SUCCESS != Result) \ - { \ - printf("%s returned failure code: 0x%X\n", ErrRtrndByFunc, Result); \ - goto Exit; \ +#define LOG_AND_EXIT_ON_ERROR(Result, ErrRtrndByFunc) \ + if (CTL_RESULT_SUCCESS != Result) \ + { \ + printf("[ERROR] %s returned failure code: 0x%X\n", ErrRtrndByFunc, Result); \ + goto Exit; \ } -#define EXIT_ON_MEM_ALLOC_FAILURE(Ptr, AllocatedVarName) \ - if (NULL == Ptr) \ - { \ - Result = CTL_RESULT_ERROR_INVALID_NULL_POINTER; \ - printf("Memory Allocation Failed: %s \n", AllocatedVarName); \ - goto Exit; \ +#define EXIT_ON_MEM_ALLOC_FAILURE(Ptr, AllocatedVarName) \ + if (NULL == Ptr) \ + { \ + Result = CTL_RESULT_ERROR_INVALID_NULL_POINTER; \ + printf("[ERROR] Memory Allocation Failed: %s \n", AllocatedVarName); \ + goto Exit; \ } -#define LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, ErrRtrndByFunc) \ - if (CTL_RESULT_SUCCESS != Result) \ - { \ - printf("%s returned failure code: 0x%X\n", ErrRtrndByFunc, Result); \ - STORE_AND_RESET_ERROR(Result); \ +#define LOG_AND_STORE_RESET_RESULT_ON_ERROR(Result, ErrRtrndByFunc) \ + if (CTL_RESULT_SUCCESS != Result) \ + { \ + printf("[ERROR] %s returned failure code: 0x%X\n", ErrRtrndByFunc, Result); \ + STORE_AND_RESET_ERROR(Result); \ } -#define PRINT_LOGS(...) printf(__VA_ARGS__) +// Application logging macro +#define APP_LOG_INFO(fmt, ...) printf("[INFO] " fmt "\n", ##__VA_ARGS__) +#define APP_LOG_WARN(fmt, ...) printf("[WARN] " fmt "\n", ##__VA_ARGS__) +#define APP_LOG_ERROR(fmt, ...) printf("[ERROR] " fmt "\n", ##__VA_ARGS__) + +#define PRINT_LOGS(...) \ + printf(__VA_ARGS__); \ + printf("\n") #define CONTROL_BIT(_i) (1 << _i) @@ -109,6 +116,12 @@ inline char *Get3DFeatureName(ctl_3d_feature_t FeatureType) return "VRR windowed blt"; case CTL_3D_FEATURE_GLOBAL_OR_PER_APP: return "global or per app settings"; + case CTL_3D_FEATURE_LOW_LATENCY: + return "Low Latency"; + case CTL_3D_FEATURE_FRAME_GENERATION: + return "XeSS Frame Generation"; + case CTL_3D_FEATURE_PREBUILT_SHADER_DOWNLOAD: + return "Prebuilt Shader Download"; default: return "No Name"; } @@ -172,19 +185,19 @@ inline void Print3DFeatureSupport(ctl_3d_feature_details_t *pFeatureDetails) FeatureSupport = pFeatureDetails->FeatureMiscSupport; if (CTL_3D_FEATURE_MISC_FLAG_DX11 & FeatureSupport) { - printf(" pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_DX11\n"); + printf("[INFO] pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_DX11\n"); } if (CTL_3D_FEATURE_MISC_FLAG_DX12 & FeatureSupport) { - printf(" pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_DX12\n"); + printf("[INFO] pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_DX12\n"); } if (CTL_3D_FEATURE_MISC_FLAG_VULKAN & FeatureSupport) { - printf(" pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_VULKAN\n"); + printf("[INFO] pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_VULKAN\n"); } if (CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE & FeatureSupport) { - printf(" pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE\n"); + printf("[INFO] pFeatureDetails->FeatureMiscSupport = CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE\n"); } return; } @@ -200,17 +213,17 @@ inline void PrintEnduranceGamingControl(uint32_t Control) switch (Control) { case CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_OFF: - printf(" pEGCaps->EGControlCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_OFF\n"); + printf("[INFO] pEGCaps->EGControlCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_OFF\n"); break; case CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_ON: - printf(" pEGCaps->EGControlCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_ON\n"); + printf("[INFO] pEGCaps->EGControlCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_ON\n"); break; case CTL_3D_ENDURANCE_GAMING_CONTROL_AUTO: - printf(" pEGCaps->EGControlCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_CONTROL_AUTO\n"); + printf("[INFO] pEGCaps->EGControlCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_CONTROL_AUTO\n"); break; @@ -230,17 +243,17 @@ inline void PrintEnduranceGamingMode(uint32_t Mode) switch (Mode) { case CTL_3D_ENDURANCE_GAMING_MODE_BETTER_PERFORMANCE: - printf(" pEGCaps->EGModeCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_MODE_BETTER_PERFORMANCE\n"); + printf("[INFO] pEGCaps->EGModeCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_MODE_BETTER_PERFORMANCE\n"); break; case CTL_3D_ENDURANCE_GAMING_MODE_BALANCED: - printf(" pEGCaps->EGModeCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_MODE_BALANCED\n"); + printf("[INFO] pEGCaps->EGModeCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_MODE_BALANCED\n"); break; case CTL_3D_ENDURANCE_GAMING_MODE_MAXIMUM_BATTERY: - printf(" pEGCaps->EGModeCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_MODE_MAXIMUM_BATTERY\n"); + printf("[INFO] pEGCaps->EGModeCaps.SupportedTypes = CTL_3D_ENDURANCE_GAMING_MODE_MAXIMUM_BATTERY\n"); break; @@ -309,44 +322,44 @@ inline void Print3DFeatureDetail(ctl_3d_feature_details_t *pFeatureDetails) { if (pFeatureDetails) { - printf("3D Feature supported: %s (%d)\n", Get3DFeatureName(pFeatureDetails->FeatureType), pFeatureDetails->FeatureType); - printf(" Feature conflict mask flag: 0x%llX\n", pFeatureDetails->ConflictingFeatures); - printf(" Supported per application: %d\n", pFeatureDetails->PerAppSupport); - printf(" Supports live change: %s\n", (pFeatureDetails->FeatureMiscSupport & CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE) ? "Yes" : "No"); + printf("[INFO] 3D Feature supported: %s (%d)\n", Get3DFeatureName(pFeatureDetails->FeatureType), pFeatureDetails->FeatureType); + printf("[INFO] Feature conflict mask flag: 0x%llX\n", pFeatureDetails->ConflictingFeatures); + printf("[INFO] Supported per application: %d\n", pFeatureDetails->PerAppSupport); + printf("[INFO] Supports live change: %s\n", (pFeatureDetails->FeatureMiscSupport & CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE) ? "Yes" : "No"); Print3DFeatureSupport(pFeatureDetails); switch (pFeatureDetails->ValueType) { case CTL_PROPERTY_VALUE_TYPE_ENUM: { - printf(" Default value: %d\n", pFeatureDetails->Value.EnumType.DefaultType); + printf("[INFO] Default value: %d\n", pFeatureDetails->Value.EnumType.DefaultType); if (CTL_3D_FEATURE_GAMING_FLIP_MODES == pFeatureDetails->FeatureType) { ctl_gaming_flip_mode_flags_t GamingflipCaps = (ctl_gaming_flip_mode_flags_t)pFeatureDetails->Value.EnumType.SupportedTypes; if (CTL_GAMING_FLIP_MODE_FLAG_APPLICATION_DEFAULT & GamingflipCaps) { - printf(" pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_APPLICATION_DEFAULT\n"); + printf("[INFO] pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_APPLICATION_DEFAULT\n"); } if (CTL_GAMING_FLIP_MODE_FLAG_VSYNC_OFF & GamingflipCaps) { - printf(" pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_VSYNC_OFF\n"); + printf("[INFO] pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_VSYNC_OFF\n"); } if (CTL_GAMING_FLIP_MODE_FLAG_VSYNC_ON & GamingflipCaps) { - printf(" pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_VSYNC_ON\n"); + printf("[INFO] pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_VSYNC_ON\n"); } if (CTL_GAMING_FLIP_MODE_FLAG_SMOOTH_SYNC & GamingflipCaps) { - printf(" pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_SMOOTH_SYNC\n"); + printf("[INFO] pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_SMOOTH_SYNC\n"); } if (CTL_GAMING_FLIP_MODE_FLAG_SPEED_FRAME & GamingflipCaps) { - printf(" pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_SPEED_FRAME\n"); + printf("[INFO] pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_SPEED_FRAME\n"); } if (CTL_GAMING_FLIP_MODE_FLAG_CAPPED_FPS & GamingflipCaps) { - printf(" pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_CAPPED_FPS\n"); + printf("[INFO] pFeatureDetails->Value.EnumType.SupportedTypes = CTL_GAMING_FLIP_MODE_FLAG_CAPPED_FPS\n"); } } // printf(" Enabled value: %d\n", pFeatureDetails->Value.EnumType.EnableType); @@ -354,25 +367,25 @@ inline void Print3DFeatureDetail(ctl_3d_feature_details_t *pFeatureDetails) break; case CTL_PROPERTY_VALUE_TYPE_BOOL: { - printf(" Default value: %d\n", pFeatureDetails->Value.BoolType.DefaultState); + printf("[INFO] Default value: %d\n", pFeatureDetails->Value.BoolType.DefaultState); // printf(" Enabled value: %d\n", pFeatureDetails->Value.BoolType.Enable); } break; case CTL_PROPERTY_VALUE_TYPE_FLOAT: { - printf(" Min possible value: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.min_possible_value); - printf(" Max possible value: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.max_possible_value); - printf(" Step size: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.step_size); - printf(" Default value: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.default_value); + printf("[INFO] Min possible value: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.min_possible_value); + printf("[INFO] Max possible value: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.max_possible_value); + printf("[INFO] Step size: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.step_size); + printf("[INFO] Default value: %f\n", pFeatureDetails->Value.FloatType.RangeInfo.default_value); // printf(" Current value: %f\n", pFeatureDetails->Value.FloatType.Value); } break; case CTL_PROPERTY_VALUE_TYPE_INT32: { - printf(" Min possible value: %d\n", pFeatureDetails->Value.IntType.RangeInfo.min_possible_value); - printf(" Max possible value: %d\n", pFeatureDetails->Value.IntType.RangeInfo.max_possible_value); - printf(" Step size: %d\n", pFeatureDetails->Value.IntType.RangeInfo.step_size); - printf(" Default value: %d\n", pFeatureDetails->Value.IntType.RangeInfo.default_value); + printf("[INFO] Min possible value: %d\n", pFeatureDetails->Value.IntType.RangeInfo.min_possible_value); + printf("[INFO] Max possible value: %d\n", pFeatureDetails->Value.IntType.RangeInfo.max_possible_value); + printf("[INFO] Step size: %d\n", pFeatureDetails->Value.IntType.RangeInfo.step_size); + printf("[INFO] Default value: %d\n", pFeatureDetails->Value.IntType.RangeInfo.default_value); // printf(" Current value: %d\n", pFeatureDetails->Value.IntType.Value); } break; @@ -380,7 +393,7 @@ inline void Print3DFeatureDetail(ctl_3d_feature_details_t *pFeatureDetails) { if (pFeatureDetails->pCustomValue == NULL) { - printf(" Empty custom data\n"); + printf("[WARN] Empty custom data\n"); break; } @@ -389,12 +402,12 @@ inline void Print3DFeatureDetail(ctl_3d_feature_details_t *pFeatureDetails) case CTL_3D_FEATURE_ADAPTIVE_SYNC_PLUS: { ctl_adaptivesync_caps_t *pASCaps = (ctl_adaptivesync_caps_t *)pFeatureDetails->pCustomValue; - printf(" AdaptiveBalanceSupported = %d\n", pASCaps->AdaptiveBalanceSupported); - printf(" AdaptiveBalanceStrengthCaps.DefaultEnable = %d\n", pASCaps->AdaptiveBalanceStrengthCaps.DefaultEnable); - printf(" AdaptiveBalanceStrengthCaps.RangeInfo.default_value = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.default_value); - printf(" AdaptiveBalanceStrengthCaps.RangeInfo.min_possible_value = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.min_possible_value); - printf(" AdaptiveBalanceStrengthCaps.RangeInfo.max_possible_value = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.max_possible_value); - printf(" AdaptiveBalanceStrengthCaps.RangeInfo.step_size = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.step_size); + printf("[INFO] AdaptiveBalanceSupported = %d\n", pASCaps->AdaptiveBalanceSupported); + printf("[INFO] AdaptiveBalanceStrengthCaps.DefaultEnable = %d\n", pASCaps->AdaptiveBalanceStrengthCaps.DefaultEnable); + printf("[INFO] AdaptiveBalanceStrengthCaps.RangeInfo.default_value = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.default_value); + printf("[INFO] AdaptiveBalanceStrengthCaps.RangeInfo.min_possible_value = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.min_possible_value); + printf("[INFO] AdaptiveBalanceStrengthCaps.RangeInfo.max_possible_value = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.max_possible_value); + printf("[INFO] AdaptiveBalanceStrengthCaps.RangeInfo.step_size = %f\n", pASCaps->AdaptiveBalanceStrengthCaps.RangeInfo.step_size); } break; @@ -403,24 +416,24 @@ inline void Print3DFeatureDetail(ctl_3d_feature_details_t *pFeatureDetails) ctl_endurance_gaming_caps_t *pEGCaps = (ctl_endurance_gaming_caps_t *)pFeatureDetails->pCustomValue; std::vector EGControls = { CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_OFF, CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_ON, CTL_3D_ENDURANCE_GAMING_CONTROL_AUTO }; std::vector EGModes = { CTL_3D_ENDURANCE_GAMING_MODE_BETTER_PERFORMANCE, CTL_3D_ENDURANCE_GAMING_MODE_BALANCED, CTL_3D_ENDURANCE_GAMING_MODE_MAXIMUM_BATTERY }; - printf(" pEGCaps->EGControlCaps.DefaultType = %d\n", pEGCaps->EGControlCaps.DefaultType); - printf(" pEGCaps->EGModeCaps.DefaultType = %d\n", pEGCaps->EGModeCaps.DefaultType); + printf("[INFO] pEGCaps->EGControlCaps.DefaultType = %d\n", pEGCaps->EGControlCaps.DefaultType); + printf("[INFO] pEGCaps->EGModeCaps.DefaultType = %d\n", pEGCaps->EGModeCaps.DefaultType); - Print3DFeatureSupportedSettings(pEGCaps->EGControlCaps.SupportedTypes, EGControls, ENDURANCE_GAMING_CONTROLS); - Print3DFeatureSupportedSettings(pEGCaps->EGModeCaps.SupportedTypes, EGModes, ENDURANCE_GAMING_MODES); + Print3DFeatureSupportedSettings(pEGCaps->EGControlCaps.SupportedTypes, move(EGControls), ENDURANCE_GAMING_CONTROLS); + Print3DFeatureSupportedSettings(pEGCaps->EGModeCaps.SupportedTypes, move(EGModes), ENDURANCE_GAMING_MODES); } break; case CTL_3D_FEATURE_APP_PROFILES: { ctl_3d_app_profiles_caps_t *pCaps = (ctl_3d_app_profiles_caps_t *)pFeatureDetails->pCustomValue; - printf(" pCaps->SupportedTierTypes = %s\n", GetProfileTypeName(pCaps->SupportedTierTypes)); + printf("[INFO] pCaps->SupportedTierTypes = %s\n", GetProfileTypeName(pCaps->SupportedTierTypes)); } break; default: { - printf(" Unknown feature type with custom capabilities! ERROR!!\n"); + printf("[ERROR] Unknown feature type with custom capabilities! ERROR!!\n"); } break; } @@ -432,3 +445,62 @@ inline void Print3DFeatureDetail(ctl_3d_feature_details_t *pFeatureDetails) } } } + +// Helper function to print ctl_std_display_feature_flags_t flags +void PrintStdDisplayFeatureFlags(ctl_std_display_feature_flags_t flags) +{ + printf("ctl_std_display_feature_flags_t: 0x%X\n", flags); + + // Example flag values, replace/add with actual flag definitions as needed + struct FlagInfo + { + ctl_std_display_feature_flags_t value; + const char *name; + }; + + static const FlagInfo flagInfos[] = { + { 0x00000001, "CTL_STD_DISPLAY_FEATURE_FLAG_HDCP" }, + { 0x00000002, "CTL_STD_DISPLAY_FEATURE_FLAG_HD_AUDIO" }, + { 0x00000004, "CTL_STD_DISPLAY_FEATURE_FLAG_PSR" }, + { 0x00000008, "CTL_STD_DISPLAY_FEATURE_FLAG_ADAPTIVESYNC_VRR" }, + { 0x00000010, "CTL_STD_DISPLAY_FEATURE_FLAG_VESA_COMPRESSION" }, + { 0x00000020, "CTL_STD_DISPLAY_FEATURE_FLAG_HDR" }, + { 0x00000040, "CTL_STD_DISPLAY_FEATURE_FLAG_HDMI_QMS" }, + { 0x00000080, "CTL_STD_DISPLAY_FEATURE_FLAG_HDR10_PLUS_CERTIFIED" }, + { 0x00000100, "CTL_STD_DISPLAY_FEATURE_FLAG_VESA_HDR_CERTIFIED" }, + // Add more flag definitions here as needed + }; + + for (const auto &info : flagInfos) + { + if (flags & info.value) + { + printf(" %s\n", info.name); + } + } +} + +void PrintIntelDisplayFeatureFlags(ctl_intel_display_feature_flags_t flags) +{ + printf("ctl_intel_display_feature_flags_t: 0x%X\n", flags); + // Example flag values, replace/add with actual flag definitions as needed + struct FlagInfo + { + ctl_intel_display_feature_flags_t value; + const char *name; + }; + static const FlagInfo flagInfos[] = { + { 0x00000001, "CTL_INTEL_DISPLAY_FEATURE_FLAG_DPST" }, + { 0x00000002, "CTL_INTEL_DISPLAY_FEATURE_FLAG_LACE" }, + { 0x00000004, "CTL_INTEL_DISPLAY_FEATURE_FLAG_DRRS" }, + { 0x00000008, "CTL_INTEL_DISPLAY_FEATURE_FLAG_ARC_ADAPTIVE_SYNC_CERTIFIED" }, + // Add more flag definitions here as needed + }; + for (const auto &info : flagInfos) + { + if (flags & info.value) + { + printf(" %s\n", info.name); + } + } +} diff --git a/wrapper/cApiWrapper.cpp b/Source/cApiWrapper.cpp similarity index 69% rename from wrapper/cApiWrapper.cpp rename to Source/cApiWrapper.cpp index 043b792..1b67f19 100644 --- a/wrapper/cApiWrapper.cpp +++ b/Source/cApiWrapper.cpp @@ -1,5 +1,5 @@ //=========================================================================== -//Copyright (C) 2022-23 Intel Corporation +//Copyright (C) 2025 Intel Corporation // // // @@ -19,6 +19,7 @@ #include #include +#include //#define CTL_APIEXPORT @@ -31,10 +32,16 @@ static HINSTANCE hinstLib = NULL; static ctl_runtime_path_args_t* pRuntimeArgs = NULL; +HINSTANCE GetLoaderHandle(void) +{ + return hinstLib; +} + /** * @brief Function to get DLL name based on app version * */ + #if defined(_WIN64) #define CTL_DLL_NAME L"ControlLib" #else @@ -54,10 +61,15 @@ ctl_result_t GetControlAPIDLLPath(ctl_init_args_t* pInitArgs, wchar_t* pwcDLLPat if (majorVersion > CTL_IMPL_MAJOR_VERSION) return CTL_RESULT_ERROR_UNSUPPORTED_VERSION; +#if (CTL_IMPL_MAJOR_VERSION > 1) if (majorVersion > 1) StringCbPrintfW(pwcDLLPath,CTL_DLL_PATH_LEN,L"%s%d.dll", CTL_DLL_NAME, majorVersion); else // just control_api.dll StringCbPrintfW(pwcDLLPath,CTL_DLL_PATH_LEN,L"%s.dll", CTL_DLL_NAME); +#else + StringCbPrintfW(pwcDLLPath,CTL_DLL_PATH_LEN,L"%s.dll", CTL_DLL_NAME); +#endif + } else if (pRuntimeArgs->pRuntimePath) { @@ -68,6 +80,7 @@ ctl_result_t GetControlAPIDLLPath(ctl_init_args_t* pInitArgs, wchar_t* pwcDLLPat } + /** * @brief Control Api Init * @@ -94,18 +107,27 @@ ctlInit( // special code - only for ctlInit() if (NULL == hinstLib) { - wchar_t strDLLPath[CTL_DLL_PATH_LEN]; - result = GetControlAPIDLLPath(pInitDesc, strDLLPath); + std::vector strDLLPath; + try + { + strDLLPath.resize(CTL_DLL_PATH_LEN); + } + catch (std::bad_alloc&) + { + return CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; + } + + result = GetControlAPIDLLPath(pInitDesc, strDLLPath.data()); if (result == CTL_RESULT_SUCCESS) { #ifdef WINDOWS_UWP - hinstLib = LoadPackagedLibrary(strDLLPath, 0); + hinstLib = LoadPackagedLibrary(strDLLPath.data(), 0); #else DWORD dwFlags = LOAD_LIBRARY_SEARCH_SYSTEM32; #ifdef _DEBUG dwFlags = dwFlags | LOAD_LIBRARY_SEARCH_APPLICATION_DIR; #endif - hinstLib = LoadLibraryExW(strDLLPath, NULL, dwFlags); + hinstLib = LoadLibraryExW(strDLLPath.data(), NULL, dwFlags); #endif if (NULL == hinstLib) { @@ -114,13 +136,15 @@ ctlInit( else if (pRuntimeArgs) { ctlSetRuntimePath(pRuntimeArgs); - } - } + } + } } - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnInit_t pfnInit = (ctl_pfnInit_t)GetProcAddress(hinstLib, "ctlInit"); + ctl_pfnInit_t pfnInit = (ctl_pfnInit_t)GetProcAddress(hinstLibPtr, "ctlInit"); if (pfnInit) { result = pfnInit(pInitDesc, phAPIHandle); @@ -154,9 +178,11 @@ ctlClose( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnClose_t pfnClose = (ctl_pfnClose_t)GetProcAddress(hinstLib, "ctlClose"); + ctl_pfnClose_t pfnClose = (ctl_pfnClose_t)GetProcAddress(hinstLibPtr, "ctlClose"); if (pfnClose) { result = pfnClose(hAPIHandle); @@ -164,14 +190,14 @@ ctlClose( } // special code - only for ctlClose() - // might get CTL_RESULT_SUCCESS_STILL_OPEN_BY_ANOTHER_CALLER - // if its open by another caller do not free the instance handle + // might get CTL_RESULT_SUCCESS_STILL_OPEN_BY_ANOTHER_CALLER + // if its open by another caller do not free the instance handle if( result == CTL_RESULT_SUCCESS) { if (NULL != hinstLib) { FreeLibrary(hinstLib); - hinstLib = NULL; + hinstLib = NULL; } } // set runtime args back to NULL @@ -207,9 +233,11 @@ ctlSetRuntimePath( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetRuntimePath_t pfnSetRuntimePath = (ctl_pfnSetRuntimePath_t)GetProcAddress(hinstLib, "ctlSetRuntimePath"); + ctl_pfnSetRuntimePath_t pfnSetRuntimePath = (ctl_pfnSetRuntimePath_t)GetProcAddress(hinstLibPtr, "ctlSetRuntimePath"); if (pfnSetRuntimePath) { result = pfnSetRuntimePath(pArgs); @@ -217,12 +245,12 @@ ctlSetRuntimePath( } // special code - only for ctlSetRuntimePath() - // might get CTL_RESULT_SUCCESS_STILL_OPEN_BY_ANOTHER_CALLER - // if its open by another caller do not free the instance handle + // might get CTL_RESULT_SUCCESS_STILL_OPEN_BY_ANOTHER_CALLER + // if its open by another caller do not free the instance handle else if (pArgs->pRuntimePath) { // this is a case where the caller app is interested in loading a RT directly - // IMPORTANT NOTE: Free pArgs and pArgs->pRuntimePath only after ctlInit() call + // IMPORTANT NOTE: Free pArgs and pArgs->pRuntimePath only after ctlInit() call pRuntimeArgs = pArgs; result = CTL_RESULT_SUCCESS; } @@ -256,9 +284,11 @@ ctlWaitForPropertyChange( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnWaitForPropertyChange_t pfnWaitForPropertyChange = (ctl_pfnWaitForPropertyChange_t)GetProcAddress(hinstLib, "ctlWaitForPropertyChange"); + ctl_pfnWaitForPropertyChange_t pfnWaitForPropertyChange = (ctl_pfnWaitForPropertyChange_t)GetProcAddress(hinstLibPtr, "ctlWaitForPropertyChange"); if (pfnWaitForPropertyChange) { result = pfnWaitForPropertyChange(hDeviceAdapter, pArgs); @@ -294,9 +324,11 @@ ctlReservedCall( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnReservedCall_t pfnReservedCall = (ctl_pfnReservedCall_t)GetProcAddress(hinstLib, "ctlReservedCall"); + ctl_pfnReservedCall_t pfnReservedCall = (ctl_pfnReservedCall_t)GetProcAddress(hinstLibPtr, "ctlReservedCall"); if (pfnReservedCall) { result = pfnReservedCall(hDeviceAdapter, pArgs); @@ -332,9 +364,11 @@ ctlGetSupported3DCapabilities( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSupported3DCapabilities_t pfnGetSupported3DCapabilities = (ctl_pfnGetSupported3DCapabilities_t)GetProcAddress(hinstLib, "ctlGetSupported3DCapabilities"); + ctl_pfnGetSupported3DCapabilities_t pfnGetSupported3DCapabilities = (ctl_pfnGetSupported3DCapabilities_t)GetProcAddress(hinstLibPtr, "ctlGetSupported3DCapabilities"); if (pfnGetSupported3DCapabilities) { result = pfnGetSupported3DCapabilities(hDAhandle, pFeatureCaps); @@ -370,9 +404,11 @@ ctlGetSet3DFeature( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSet3DFeature_t pfnGetSet3DFeature = (ctl_pfnGetSet3DFeature_t)GetProcAddress(hinstLib, "ctlGetSet3DFeature"); + ctl_pfnGetSet3DFeature_t pfnGetSet3DFeature = (ctl_pfnGetSet3DFeature_t)GetProcAddress(hinstLibPtr, "ctlGetSet3DFeature"); if (pfnGetSet3DFeature) { result = pfnGetSet3DFeature(hDAhandle, pFeature); @@ -406,9 +442,11 @@ ctlCheckDriverVersion( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnCheckDriverVersion_t pfnCheckDriverVersion = (ctl_pfnCheckDriverVersion_t)GetProcAddress(hinstLib, "ctlCheckDriverVersion"); + ctl_pfnCheckDriverVersion_t pfnCheckDriverVersion = (ctl_pfnCheckDriverVersion_t)GetProcAddress(hinstLibPtr, "ctlCheckDriverVersion"); if (pfnCheckDriverVersion) { result = pfnCheckDriverVersion(hDeviceAdapter, version_info); @@ -452,9 +490,11 @@ ctlEnumerateDevices( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumerateDevices_t pfnEnumerateDevices = (ctl_pfnEnumerateDevices_t)GetProcAddress(hinstLib, "ctlEnumerateDevices"); + ctl_pfnEnumerateDevices_t pfnEnumerateDevices = (ctl_pfnEnumerateDevices_t)GetProcAddress(hinstLibPtr, "ctlEnumerateDevices"); if (pfnEnumerateDevices) { result = pfnEnumerateDevices(hAPIHandle, pCount, phDevices); @@ -497,9 +537,11 @@ ctlEnumerateDisplayOutputs( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumerateDisplayOutputs_t pfnEnumerateDisplayOutputs = (ctl_pfnEnumerateDisplayOutputs_t)GetProcAddress(hinstLib, "ctlEnumerateDisplayOutputs"); + ctl_pfnEnumerateDisplayOutputs_t pfnEnumerateDisplayOutputs = (ctl_pfnEnumerateDisplayOutputs_t)GetProcAddress(hinstLibPtr, "ctlEnumerateDisplayOutputs"); if (pfnEnumerateDisplayOutputs) { result = pfnEnumerateDisplayOutputs(hDeviceAdapter, pCount, phDisplayOutputs); @@ -546,9 +588,11 @@ ctlEnumerateI2CPinPairs( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumerateI2CPinPairs_t pfnEnumerateI2CPinPairs = (ctl_pfnEnumerateI2CPinPairs_t)GetProcAddress(hinstLib, "ctlEnumerateI2CPinPairs"); + ctl_pfnEnumerateI2CPinPairs_t pfnEnumerateI2CPinPairs = (ctl_pfnEnumerateI2CPinPairs_t)GetProcAddress(hinstLibPtr, "ctlEnumerateI2CPinPairs"); if (pfnEnumerateI2CPinPairs) { result = pfnEnumerateI2CPinPairs(hDeviceAdapter, pCount, phI2cPinPairs); @@ -584,9 +628,11 @@ ctlGetDeviceProperties( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetDeviceProperties_t pfnGetDeviceProperties = (ctl_pfnGetDeviceProperties_t)GetProcAddress(hinstLib, "ctlGetDeviceProperties"); + ctl_pfnGetDeviceProperties_t pfnGetDeviceProperties = (ctl_pfnGetDeviceProperties_t)GetProcAddress(hinstLibPtr, "ctlGetDeviceProperties"); if (pfnGetDeviceProperties) { result = pfnGetDeviceProperties(hDAhandle, pProperties); @@ -622,9 +668,11 @@ ctlGetDisplayProperties( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetDisplayProperties_t pfnGetDisplayProperties = (ctl_pfnGetDisplayProperties_t)GetProcAddress(hinstLib, "ctlGetDisplayProperties"); + ctl_pfnGetDisplayProperties_t pfnGetDisplayProperties = (ctl_pfnGetDisplayProperties_t)GetProcAddress(hinstLibPtr, "ctlGetDisplayProperties"); if (pfnGetDisplayProperties) { result = pfnGetDisplayProperties(hDisplayOutput, pProperties); @@ -660,9 +708,11 @@ ctlGetAdaperDisplayEncoderProperties( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetAdaperDisplayEncoderProperties_t pfnGetAdaperDisplayEncoderProperties = (ctl_pfnGetAdaperDisplayEncoderProperties_t)GetProcAddress(hinstLib, "ctlGetAdaperDisplayEncoderProperties"); + ctl_pfnGetAdaperDisplayEncoderProperties_t pfnGetAdaperDisplayEncoderProperties = (ctl_pfnGetAdaperDisplayEncoderProperties_t)GetProcAddress(hinstLibPtr, "ctlGetAdaperDisplayEncoderProperties"); if (pfnGetAdaperDisplayEncoderProperties) { result = pfnGetAdaperDisplayEncoderProperties(hDisplayOutput, pProperties); @@ -701,9 +751,11 @@ ctlGetZeDevice( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetZeDevice_t pfnGetZeDevice = (ctl_pfnGetZeDevice_t)GetProcAddress(hinstLib, "ctlGetZeDevice"); + ctl_pfnGetZeDevice_t pfnGetZeDevice = (ctl_pfnGetZeDevice_t)GetProcAddress(hinstLibPtr, "ctlGetZeDevice"); if (pfnGetZeDevice) { result = pfnGetZeDevice(hDAhandle, pZeDevice, hInstance); @@ -739,9 +791,11 @@ ctlGetSharpnessCaps( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSharpnessCaps_t pfnGetSharpnessCaps = (ctl_pfnGetSharpnessCaps_t)GetProcAddress(hinstLib, "ctlGetSharpnessCaps"); + ctl_pfnGetSharpnessCaps_t pfnGetSharpnessCaps = (ctl_pfnGetSharpnessCaps_t)GetProcAddress(hinstLibPtr, "ctlGetSharpnessCaps"); if (pfnGetSharpnessCaps) { result = pfnGetSharpnessCaps(hDisplayOutput, pSharpnessCaps); @@ -777,9 +831,11 @@ ctlGetCurrentSharpness( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetCurrentSharpness_t pfnGetCurrentSharpness = (ctl_pfnGetCurrentSharpness_t)GetProcAddress(hinstLib, "ctlGetCurrentSharpness"); + ctl_pfnGetCurrentSharpness_t pfnGetCurrentSharpness = (ctl_pfnGetCurrentSharpness_t)GetProcAddress(hinstLibPtr, "ctlGetCurrentSharpness"); if (pfnGetCurrentSharpness) { result = pfnGetCurrentSharpness(hDisplayOutput, pSharpnessSettings); @@ -815,9 +871,11 @@ ctlSetCurrentSharpness( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetCurrentSharpness_t pfnSetCurrentSharpness = (ctl_pfnSetCurrentSharpness_t)GetProcAddress(hinstLib, "ctlSetCurrentSharpness"); + ctl_pfnSetCurrentSharpness_t pfnSetCurrentSharpness = (ctl_pfnSetCurrentSharpness_t)GetProcAddress(hinstLibPtr, "ctlSetCurrentSharpness"); if (pfnSetCurrentSharpness) { result = pfnSetCurrentSharpness(hDisplayOutput, pSharpnessSettings); @@ -832,7 +890,8 @@ ctlSetCurrentSharpness( * @brief I2C Access * * @details -* - Interface to access I2C using display handle as identifier. +* - Interface to access I2C using display handle as identifier. I2C +* driver override flags are supported only for HDMI displays. * * @returns * - CTL_RESULT_SUCCESS @@ -861,9 +920,11 @@ ctlI2CAccess( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnI2CAccess_t pfnI2CAccess = (ctl_pfnI2CAccess_t)GetProcAddress(hinstLib, "ctlI2CAccess"); + ctl_pfnI2CAccess_t pfnI2CAccess = (ctl_pfnI2CAccess_t)GetProcAddress(hinstLibPtr, "ctlI2CAccess"); if (pfnI2CAccess) { result = pfnI2CAccess(hDisplayOutput, pI2cAccessArgs); @@ -910,9 +971,11 @@ ctlI2CAccessOnPinPair( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnI2CAccessOnPinPair_t pfnI2CAccessOnPinPair = (ctl_pfnI2CAccessOnPinPair_t)GetProcAddress(hinstLib, "ctlI2CAccessOnPinPair"); + ctl_pfnI2CAccessOnPinPair_t pfnI2CAccessOnPinPair = (ctl_pfnI2CAccessOnPinPair_t)GetProcAddress(hinstLibPtr, "ctlI2CAccessOnPinPair"); if (pfnI2CAccessOnPinPair) { result = pfnI2CAccessOnPinPair(hI2cPinPair, pI2cAccessArgs); @@ -958,9 +1021,11 @@ ctlAUXAccess( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnAUXAccess_t pfnAUXAccess = (ctl_pfnAUXAccess_t)GetProcAddress(hinstLib, "ctlAUXAccess"); + ctl_pfnAUXAccess_t pfnAUXAccess = (ctl_pfnAUXAccess_t)GetProcAddress(hinstLibPtr, "ctlAUXAccess"); if (pfnAUXAccess) { result = pfnAUXAccess(hDisplayOutput, pAuxAccessArgs); @@ -996,9 +1061,11 @@ ctlGetPowerOptimizationCaps( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetPowerOptimizationCaps_t pfnGetPowerOptimizationCaps = (ctl_pfnGetPowerOptimizationCaps_t)GetProcAddress(hinstLib, "ctlGetPowerOptimizationCaps"); + ctl_pfnGetPowerOptimizationCaps_t pfnGetPowerOptimizationCaps = (ctl_pfnGetPowerOptimizationCaps_t)GetProcAddress(hinstLibPtr, "ctlGetPowerOptimizationCaps"); if (pfnGetPowerOptimizationCaps) { result = pfnGetPowerOptimizationCaps(hDisplayOutput, pPowerOptimizationCaps); @@ -1036,9 +1103,11 @@ ctlGetPowerOptimizationSetting( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetPowerOptimizationSetting_t pfnGetPowerOptimizationSetting = (ctl_pfnGetPowerOptimizationSetting_t)GetProcAddress(hinstLib, "ctlGetPowerOptimizationSetting"); + ctl_pfnGetPowerOptimizationSetting_t pfnGetPowerOptimizationSetting = (ctl_pfnGetPowerOptimizationSetting_t)GetProcAddress(hinstLibPtr, "ctlGetPowerOptimizationSetting"); if (pfnGetPowerOptimizationSetting) { result = pfnGetPowerOptimizationSetting(hDisplayOutput, pPowerOptimizationSettings); @@ -1077,9 +1146,11 @@ ctlSetPowerOptimizationSetting( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetPowerOptimizationSetting_t pfnSetPowerOptimizationSetting = (ctl_pfnSetPowerOptimizationSetting_t)GetProcAddress(hinstLib, "ctlSetPowerOptimizationSetting"); + ctl_pfnSetPowerOptimizationSetting_t pfnSetPowerOptimizationSetting = (ctl_pfnSetPowerOptimizationSetting_t)GetProcAddress(hinstLibPtr, "ctlSetPowerOptimizationSetting"); if (pfnSetPowerOptimizationSetting) { result = pfnSetPowerOptimizationSetting(hDisplayOutput, pPowerOptimizationSettings); @@ -1119,9 +1190,11 @@ ctlSetBrightnessSetting( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetBrightnessSetting_t pfnSetBrightnessSetting = (ctl_pfnSetBrightnessSetting_t)GetProcAddress(hinstLib, "ctlSetBrightnessSetting"); + ctl_pfnSetBrightnessSetting_t pfnSetBrightnessSetting = (ctl_pfnSetBrightnessSetting_t)GetProcAddress(hinstLibPtr, "ctlSetBrightnessSetting"); if (pfnSetBrightnessSetting) { result = pfnSetBrightnessSetting(hDisplayOutput, pSetBrightnessSetting); @@ -1160,9 +1233,11 @@ ctlGetBrightnessSetting( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetBrightnessSetting_t pfnGetBrightnessSetting = (ctl_pfnGetBrightnessSetting_t)GetProcAddress(hinstLib, "ctlGetBrightnessSetting"); + ctl_pfnGetBrightnessSetting_t pfnGetBrightnessSetting = (ctl_pfnGetBrightnessSetting_t)GetProcAddress(hinstLibPtr, "ctlGetBrightnessSetting"); if (pfnGetBrightnessSetting) { result = pfnGetBrightnessSetting(hDisplayOutput, pGetBrightnessSetting); @@ -1212,9 +1287,11 @@ ctlPixelTransformationGetConfig( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPixelTransformationGetConfig_t pfnPixelTransformationGetConfig = (ctl_pfnPixelTransformationGetConfig_t)GetProcAddress(hinstLib, "ctlPixelTransformationGetConfig"); + ctl_pfnPixelTransformationGetConfig_t pfnPixelTransformationGetConfig = (ctl_pfnPixelTransformationGetConfig_t)GetProcAddress(hinstLibPtr, "ctlPixelTransformationGetConfig"); if (pfnPixelTransformationGetConfig) { result = pfnPixelTransformationGetConfig(hDisplayOutput, pPixTxGetConfigArgs); @@ -1265,9 +1342,11 @@ ctlPixelTransformationSetConfig( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPixelTransformationSetConfig_t pfnPixelTransformationSetConfig = (ctl_pfnPixelTransformationSetConfig_t)GetProcAddress(hinstLib, "ctlPixelTransformationSetConfig"); + ctl_pfnPixelTransformationSetConfig_t pfnPixelTransformationSetConfig = (ctl_pfnPixelTransformationSetConfig_t)GetProcAddress(hinstLibPtr, "ctlPixelTransformationSetConfig"); if (pfnPixelTransformationSetConfig) { result = pfnPixelTransformationSetConfig(hDisplayOutput, pPixTxSetConfigArgs); @@ -1310,9 +1389,11 @@ ctlPanelDescriptorAccess( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPanelDescriptorAccess_t pfnPanelDescriptorAccess = (ctl_pfnPanelDescriptorAccess_t)GetProcAddress(hinstLib, "ctlPanelDescriptorAccess"); + ctl_pfnPanelDescriptorAccess_t pfnPanelDescriptorAccess = (ctl_pfnPanelDescriptorAccess_t)GetProcAddress(hinstLibPtr, "ctlPanelDescriptorAccess"); if (pfnPanelDescriptorAccess) { result = pfnPanelDescriptorAccess(hDisplayOutput, pPanelDescriptorAccessArgs); @@ -1348,9 +1429,11 @@ ctlGetSupportedRetroScalingCapability( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSupportedRetroScalingCapability_t pfnGetSupportedRetroScalingCapability = (ctl_pfnGetSupportedRetroScalingCapability_t)GetProcAddress(hinstLib, "ctlGetSupportedRetroScalingCapability"); + ctl_pfnGetSupportedRetroScalingCapability_t pfnGetSupportedRetroScalingCapability = (ctl_pfnGetSupportedRetroScalingCapability_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedRetroScalingCapability"); if (pfnGetSupportedRetroScalingCapability) { result = pfnGetSupportedRetroScalingCapability(hDAhandle, pRetroScalingCaps); @@ -1387,9 +1470,11 @@ ctlGetSetRetroScaling( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSetRetroScaling_t pfnGetSetRetroScaling = (ctl_pfnGetSetRetroScaling_t)GetProcAddress(hinstLib, "ctlGetSetRetroScaling"); + ctl_pfnGetSetRetroScaling_t pfnGetSetRetroScaling = (ctl_pfnGetSetRetroScaling_t)GetProcAddress(hinstLibPtr, "ctlGetSetRetroScaling"); if (pfnGetSetRetroScaling) { result = pfnGetSetRetroScaling(hDAhandle, pGetSetRetroScalingType); @@ -1425,9 +1510,11 @@ ctlGetSupportedScalingCapability( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSupportedScalingCapability_t pfnGetSupportedScalingCapability = (ctl_pfnGetSupportedScalingCapability_t)GetProcAddress(hinstLib, "ctlGetSupportedScalingCapability"); + ctl_pfnGetSupportedScalingCapability_t pfnGetSupportedScalingCapability = (ctl_pfnGetSupportedScalingCapability_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedScalingCapability"); if (pfnGetSupportedScalingCapability) { result = pfnGetSupportedScalingCapability(hDisplayOutput, pScalingCaps); @@ -1463,9 +1550,11 @@ ctlGetCurrentScaling( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetCurrentScaling_t pfnGetCurrentScaling = (ctl_pfnGetCurrentScaling_t)GetProcAddress(hinstLib, "ctlGetCurrentScaling"); + ctl_pfnGetCurrentScaling_t pfnGetCurrentScaling = (ctl_pfnGetCurrentScaling_t)GetProcAddress(hinstLibPtr, "ctlGetCurrentScaling"); if (pfnGetCurrentScaling) { result = pfnGetCurrentScaling(hDisplayOutput, pGetCurrentScalingType); @@ -1501,9 +1590,11 @@ ctlSetCurrentScaling( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetCurrentScaling_t pfnSetCurrentScaling = (ctl_pfnSetCurrentScaling_t)GetProcAddress(hinstLib, "ctlSetCurrentScaling"); + ctl_pfnSetCurrentScaling_t pfnSetCurrentScaling = (ctl_pfnSetCurrentScaling_t)GetProcAddress(hinstLibPtr, "ctlSetCurrentScaling"); if (pfnSetCurrentScaling) { result = pfnSetCurrentScaling(hDisplayOutput, pSetScalingType); @@ -1540,9 +1631,11 @@ ctlGetLACEConfig( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetLACEConfig_t pfnGetLACEConfig = (ctl_pfnGetLACEConfig_t)GetProcAddress(hinstLib, "ctlGetLACEConfig"); + ctl_pfnGetLACEConfig_t pfnGetLACEConfig = (ctl_pfnGetLACEConfig_t)GetProcAddress(hinstLibPtr, "ctlGetLACEConfig"); if (pfnGetLACEConfig) { result = pfnGetLACEConfig(hDisplayOutput, pLaceConfig); @@ -1579,9 +1672,11 @@ ctlSetLACEConfig( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetLACEConfig_t pfnSetLACEConfig = (ctl_pfnSetLACEConfig_t)GetProcAddress(hinstLib, "ctlSetLACEConfig"); + ctl_pfnSetLACEConfig_t pfnSetLACEConfig = (ctl_pfnSetLACEConfig_t)GetProcAddress(hinstLibPtr, "ctlSetLACEConfig"); if (pfnSetLACEConfig) { result = pfnSetLACEConfig(hDisplayOutput, pLaceConfig); @@ -1621,9 +1716,11 @@ ctlSoftwarePSR( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSoftwarePSR_t pfnSoftwarePSR = (ctl_pfnSoftwarePSR_t)GetProcAddress(hinstLib, "ctlSoftwarePSR"); + ctl_pfnSoftwarePSR_t pfnSoftwarePSR = (ctl_pfnSoftwarePSR_t)GetProcAddress(hinstLibPtr, "ctlSoftwarePSR"); if (pfnSoftwarePSR) { result = pfnSoftwarePSR(hDisplayOutput, pSoftwarePsrSetting); @@ -1659,9 +1756,11 @@ ctlGetIntelArcSyncInfoForMonitor( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetIntelArcSyncInfoForMonitor_t pfnGetIntelArcSyncInfoForMonitor = (ctl_pfnGetIntelArcSyncInfoForMonitor_t)GetProcAddress(hinstLib, "ctlGetIntelArcSyncInfoForMonitor"); + ctl_pfnGetIntelArcSyncInfoForMonitor_t pfnGetIntelArcSyncInfoForMonitor = (ctl_pfnGetIntelArcSyncInfoForMonitor_t)GetProcAddress(hinstLibPtr, "ctlGetIntelArcSyncInfoForMonitor"); if (pfnGetIntelArcSyncInfoForMonitor) { result = pfnGetIntelArcSyncInfoForMonitor(hDisplayOutput, pIntelArcSyncMonitorParams); @@ -1672,129 +1771,6 @@ ctlGetIntelArcSyncInfoForMonitor( } -/** -* @brief Enumerate Display MUX Devices on this system across adapters -* -* @details -* - The application enumerates all MUX devices in the system -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hAPIHandle` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCount` -* + `nullptr == phMuxDevices` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlEnumerateMuxDevices( - ctl_api_handle_t hAPIHandle, ///< [in][release] Applications should pass the Control API handle returned - ///< by the CtlInit function - uint32_t* pCount, ///< [in,out][release] pointer to the number of MUX device instances. If - ///< input count is zero, then the api will update the value with the total - ///< number of MUX devices available and return the Count value. If input - ///< count is non-zero, then the api will only retrieve the number of MUX Devices. - ///< If count is larger than the number of MUX devices available, then the - ///< api will update the value with the correct number of MUX devices available. - ctl_mux_output_handle_t* phMuxDevices ///< [out][range(0, *pCount)] array of MUX device instance handles - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - if (NULL != hinstLib) - { - ctl_pfnEnumerateMuxDevices_t pfnEnumerateMuxDevices = (ctl_pfnEnumerateMuxDevices_t)GetProcAddress(hinstLib, "ctlEnumerateMuxDevices"); - if (pfnEnumerateMuxDevices) - { - result = pfnEnumerateMuxDevices(hAPIHandle, pCount, phMuxDevices); - } - } - - return result; -} - - -/** -* @brief Get Display Mux properties -* -* @details -* - Get the propeties of the Mux device -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hMuxDevice` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pMuxProperties` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetMuxProperties( - ctl_mux_output_handle_t hMuxDevice, ///< [in] MUX device instance handle - ctl_mux_properties_t* pMuxProperties ///< [in,out] MUX device properties - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - if (NULL != hinstLib) - { - ctl_pfnGetMuxProperties_t pfnGetMuxProperties = (ctl_pfnGetMuxProperties_t)GetProcAddress(hinstLib, "ctlGetMuxProperties"); - if (pfnGetMuxProperties) - { - result = pfnGetMuxProperties(hMuxDevice, pMuxProperties); - } - } - - return result; -} - - -/** -* @brief Switch Mux output -* -* @details -* - Switches the MUX output -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hMuxDevice` -* + `nullptr == hInactiveDisplayOutput` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlSwitchMux( - ctl_mux_output_handle_t hMuxDevice, ///< [in] MUX device instance handle - ctl_display_output_handle_t hInactiveDisplayOutput ///< [out] Input selection for this MUX, which if active will drive the - ///< output of this MUX device. This should be one of the display output - ///< handles reported under this MUX device's properties. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - if (NULL != hinstLib) - { - ctl_pfnSwitchMux_t pfnSwitchMux = (ctl_pfnSwitchMux_t)GetProcAddress(hinstLib, "ctlSwitchMux"); - if (pfnSwitchMux) - { - result = pfnSwitchMux(hMuxDevice, hInactiveDisplayOutput); - } - } - - return result; -} - - /** * @brief Get Intel Arc Sync profile * @@ -1820,9 +1796,11 @@ ctlGetIntelArcSyncProfile( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetIntelArcSyncProfile_t pfnGetIntelArcSyncProfile = (ctl_pfnGetIntelArcSyncProfile_t)GetProcAddress(hinstLib, "ctlGetIntelArcSyncProfile"); + ctl_pfnGetIntelArcSyncProfile_t pfnGetIntelArcSyncProfile = (ctl_pfnGetIntelArcSyncProfile_t)GetProcAddress(hinstLibPtr, "ctlGetIntelArcSyncProfile"); if (pfnGetIntelArcSyncProfile) { result = pfnGetIntelArcSyncProfile(hDisplayOutput, pIntelArcSyncProfileParams); @@ -1860,9 +1838,11 @@ ctlSetIntelArcSyncProfile( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnSetIntelArcSyncProfile_t pfnSetIntelArcSyncProfile = (ctl_pfnSetIntelArcSyncProfile_t)GetProcAddress(hinstLib, "ctlSetIntelArcSyncProfile"); + ctl_pfnSetIntelArcSyncProfile_t pfnSetIntelArcSyncProfile = (ctl_pfnSetIntelArcSyncProfile_t)GetProcAddress(hinstLibPtr, "ctlSetIntelArcSyncProfile"); if (pfnSetIntelArcSyncProfile) { result = pfnSetIntelArcSyncProfile(hDisplayOutput, pIntelArcSyncProfileParams); @@ -1909,9 +1889,11 @@ ctlEdidManagement( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEdidManagement_t pfnEdidManagement = (ctl_pfnEdidManagement_t)GetProcAddress(hinstLib, "ctlEdidManagement"); + ctl_pfnEdidManagement_t pfnEdidManagement = (ctl_pfnEdidManagement_t)GetProcAddress(hinstLibPtr, "ctlEdidManagement"); if (pfnEdidManagement) { result = pfnEdidManagement(hDisplayOutput, pEdidManagementArgs); @@ -1961,9 +1943,11 @@ ctlGetSetCustomMode( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSetCustomMode_t pfnGetSetCustomMode = (ctl_pfnGetSetCustomMode_t)GetProcAddress(hinstLib, "ctlGetSetCustomMode"); + ctl_pfnGetSetCustomMode_t pfnGetSetCustomMode = (ctl_pfnGetSetCustomMode_t)GetProcAddress(hinstLibPtr, "ctlGetSetCustomMode"); if (pfnGetSetCustomMode) { result = pfnGetSetCustomMode(hDisplayOutput, pCustomModeArgs); @@ -2017,9 +2001,11 @@ ctlGetSetCombinedDisplay( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSetCombinedDisplay_t pfnGetSetCombinedDisplay = (ctl_pfnGetSetCombinedDisplay_t)GetProcAddress(hinstLib, "ctlGetSetCombinedDisplay"); + ctl_pfnGetSetCombinedDisplay_t pfnGetSetCombinedDisplay = (ctl_pfnGetSetCombinedDisplay_t)GetProcAddress(hinstLibPtr, "ctlGetSetCombinedDisplay"); if (pfnGetSetCombinedDisplay) { result = pfnGetSetCombinedDisplay(hDeviceAdapter, pCombinedDisplayArgs); @@ -2063,9 +2049,11 @@ ctlGetSetDisplayGenlock( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSetDisplayGenlock_t pfnGetSetDisplayGenlock = (ctl_pfnGetSetDisplayGenlock_t)GetProcAddress(hinstLib, "ctlGetSetDisplayGenlock"); + ctl_pfnGetSetDisplayGenlock_t pfnGetSetDisplayGenlock = (ctl_pfnGetSetDisplayGenlock_t)GetProcAddress(hinstLibPtr, "ctlGetSetDisplayGenlock"); if (pfnGetSetDisplayGenlock) { result = pfnGetSetDisplayGenlock(hDeviceAdapter, pGenlockArgs, AdapterCount, hFailureDeviceAdapter); @@ -2107,9 +2095,11 @@ ctlGetVblankTimestamp( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetVblankTimestamp_t pfnGetVblankTimestamp = (ctl_pfnGetVblankTimestamp_t)GetProcAddress(hinstLib, "ctlGetVblankTimestamp"); + ctl_pfnGetVblankTimestamp_t pfnGetVblankTimestamp = (ctl_pfnGetVblankTimestamp_t)GetProcAddress(hinstLibPtr, "ctlGetVblankTimestamp"); if (pfnGetVblankTimestamp) { result = pfnGetVblankTimestamp(hDisplayOutput, pVblankTSArgs); @@ -2150,9 +2140,11 @@ ctlLinkDisplayAdapters( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnLinkDisplayAdapters_t pfnLinkDisplayAdapters = (ctl_pfnLinkDisplayAdapters_t)GetProcAddress(hinstLib, "ctlLinkDisplayAdapters"); + ctl_pfnLinkDisplayAdapters_t pfnLinkDisplayAdapters = (ctl_pfnLinkDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlLinkDisplayAdapters"); if (pfnLinkDisplayAdapters) { result = pfnLinkDisplayAdapters(hPrimaryAdapter, pLdaArgs); @@ -2189,9 +2181,11 @@ ctlUnlinkDisplayAdapters( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnUnlinkDisplayAdapters_t pfnUnlinkDisplayAdapters = (ctl_pfnUnlinkDisplayAdapters_t)GetProcAddress(hinstLib, "ctlUnlinkDisplayAdapters"); + ctl_pfnUnlinkDisplayAdapters_t pfnUnlinkDisplayAdapters = (ctl_pfnUnlinkDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlUnlinkDisplayAdapters"); if (pfnUnlinkDisplayAdapters) { result = pfnUnlinkDisplayAdapters(hPrimaryAdapter); @@ -2232,9 +2226,11 @@ ctlGetLinkedDisplayAdapters( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetLinkedDisplayAdapters_t pfnGetLinkedDisplayAdapters = (ctl_pfnGetLinkedDisplayAdapters_t)GetProcAddress(hinstLib, "ctlGetLinkedDisplayAdapters"); + ctl_pfnGetLinkedDisplayAdapters_t pfnGetLinkedDisplayAdapters = (ctl_pfnGetLinkedDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlGetLinkedDisplayAdapters"); if (pfnGetLinkedDisplayAdapters) { result = pfnGetLinkedDisplayAdapters(hPrimaryAdapter, pLdaArgs); @@ -2250,7 +2246,10 @@ ctlGetLinkedDisplayAdapters( * * @details * - To get the DCE feature status and, if feature is enabled, returns the -* current histogram, or to set the brightness at the phase-in speed +* current histogram, or to set the brightness at the phase-in speed. +* This is a reserved capability. By default, DCE is not supported/will +* not be enabled, need application to activate it, please contact Intel +* for activation. * * @returns * - CTL_RESULT_SUCCESS @@ -2279,9 +2278,11 @@ ctlGetSetDynamicContrastEnhancement( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSetDynamicContrastEnhancement_t pfnGetSetDynamicContrastEnhancement = (ctl_pfnGetSetDynamicContrastEnhancement_t)GetProcAddress(hinstLib, "ctlGetSetDynamicContrastEnhancement"); + ctl_pfnGetSetDynamicContrastEnhancement_t pfnGetSetDynamicContrastEnhancement = (ctl_pfnGetSetDynamicContrastEnhancement_t)GetProcAddress(hinstLibPtr, "ctlGetSetDynamicContrastEnhancement"); if (pfnGetSetDynamicContrastEnhancement) { result = pfnGetSetDynamicContrastEnhancement(hDisplayOutput, pDceArgs); @@ -2293,46 +2294,44 @@ ctlGetSetDynamicContrastEnhancement( /** -* @brief Get handle of engine groups +* @brief Get/Set Color Format and Color Depth * * @details -* - The application may call this function from simultaneous threads. -* - The implementation of this function should be lock-free. +* - Get and Set the Color Format and Color Depth of a target * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDAhandle` +* + `nullptr == hDisplayOutput` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCount` +* + `nullptr == pGetSetWireFormatSetting` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid data passed as argument, WireFormat is not supported" +* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_NULL_OS_DISPLAY_OUTPUT_HANDLE - "Null OS display output handle" +* - ::CTL_RESULT_ERROR_NULL_OS_INTERFACE - "Null OS interface" +* - ::CTL_RESULT_ERROR_NULL_OS_ADAPATER_HANDLE - "Null OS adapter handle" */ ctl_result_t CTL_APICALL -ctlEnumEngineGroups( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter - uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. - ///< if count is zero, then the driver shall update the value with the - ///< total number of components of this type that are available. - ///< if count is greater than the number of components of this type that - ///< are available, then the driver shall update the value with the correct - ///< number of components. - ctl_engine_handle_t* phEngine ///< [in,out][optional][range(0, *pCount)] array of handle of components of - ///< this type. - ///< if count is less than the number of components of this type that are - ///< available, then the driver shall only retrieve that number of - ///< component handles. +ctlGetSetWireFormat( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_get_set_wire_format_config_t* pGetSetWireFormatSetting ///< [in][release] Get/Set Wire Format settings to be fetched/applied ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumEngineGroups_t pfnEnumEngineGroups = (ctl_pfnEnumEngineGroups_t)GetProcAddress(hinstLib, "ctlEnumEngineGroups"); - if (pfnEnumEngineGroups) + ctl_pfnGetSetWireFormat_t pfnGetSetWireFormat = (ctl_pfnGetSetWireFormat_t)GetProcAddress(hinstLibPtr, "ctlGetSetWireFormat"); + if (pfnGetSetWireFormat) { - result = pfnEnumEngineGroups(hDAhandle, pCount, phEngine); + result = pfnGetSetWireFormat(hDisplayOutput, pGetSetWireFormatSetting); } } @@ -2341,36 +2340,47 @@ ctlEnumEngineGroups( /** -* @brief Get engine group properties +* @brief Get/Set Display settings * * @details -* - The application may call this function from simultaneous threads. -* - The implementation of this function should be lock-free. +* - To get/set end display settings like low latency, HDR10+ signaling +* etc. which are controlled via info-frames/secondary data packets * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hEngine` +* + `nullptr == hDisplayOutput` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` +* + `nullptr == pDisplaySettings` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_NULL_OS_DISPLAY_OUTPUT_HANDLE - "Null OS display output handle" +* - ::CTL_RESULT_ERROR_NULL_OS_INTERFACE - "Null OS interface" +* - ::CTL_RESULT_ERROR_NULL_OS_ADAPATER_HANDLE - "Null OS adapter handle" +* - ::CTL_RESULT_ERROR_KMD_CALL - "Kernel mode driver call failure" +* - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid or Null handle passed" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" */ ctl_result_t CTL_APICALL -ctlEngineGetProperties( - ctl_engine_handle_t hEngine, ///< [in] Handle for the component. - ctl_engine_properties_t* pProperties ///< [in,out] The properties for the specified engine group. +ctlGetSetDisplaySettings( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_display_settings_t* pDisplaySettings ///< [in,out] End display capabilities ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEngineGetProperties_t pfnEngineGetProperties = (ctl_pfnEngineGetProperties_t)GetProcAddress(hinstLib, "ctlEngineGetProperties"); - if (pfnEngineGetProperties) + ctl_pfnGetSetDisplaySettings_t pfnGetSetDisplaySettings = (ctl_pfnGetSetDisplaySettings_t)GetProcAddress(hinstLibPtr, "ctlGetSetDisplaySettings"); + if (pfnGetSetDisplaySettings) { - result = pfnEngineGetProperties(hEngine, pProperties); + result = pfnGetSetDisplaySettings(hDisplayOutput, pDisplaySettings); } } @@ -2379,7 +2389,7 @@ ctlEngineGetProperties( /** -* @brief Get the activity stats for an engine group +* @brief Get ECC properties. * * @details * - The application may call this function from simultaneous threads. @@ -2390,26 +2400,27 @@ ctlEngineGetProperties( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hEngine` +* + `nullptr == hDAhandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pStats` +* + `nullptr == pProperties` */ ctl_result_t CTL_APICALL -ctlEngineGetActivity( - ctl_engine_handle_t hEngine, ///< [in] Handle for the component. - ctl_engine_stats_t* pStats ///< [in,out] Will contain a snapshot of the engine group activity - ///< counters. +ctlEccGetProperties( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_ecc_properties_t* pProperties ///< [in,out] Will contain ECC properties. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEngineGetActivity_t pfnEngineGetActivity = (ctl_pfnEngineGetActivity_t)GetProcAddress(hinstLib, "ctlEngineGetActivity"); - if (pfnEngineGetActivity) + ctl_pfnEccGetProperties_t pfnEccGetProperties = (ctl_pfnEccGetProperties_t)GetProcAddress(hinstLibPtr, "ctlEccGetProperties"); + if (pfnEccGetProperties) { - result = pfnEngineGetActivity(hEngine, pStats); + result = pfnEccGetProperties(hDAhandle, pProperties); } } @@ -2418,7 +2429,7 @@ ctlEngineGetActivity( /** -* @brief Get handle of fans +* @brief Get ECC state. * * @details * - The application may call this function from simultaneous threads. @@ -2431,33 +2442,29 @@ ctlEngineGetActivity( * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE * + `nullptr == hDAhandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCount` +* + `nullptr == pState` +* - CTL_RESULT_ERROR_INVALID_ENUMERATION +* + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->currentEccState` +* + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->pendingEccState` */ ctl_result_t CTL_APICALL -ctlEnumFans( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to the adapter - uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. - ///< if count is zero, then the driver shall update the value with the - ///< total number of components of this type that are available. - ///< if count is greater than the number of components of this type that - ///< are available, then the driver shall update the value with the correct - ///< number of components. - ctl_fan_handle_t* phFan ///< [in,out][optional][range(0, *pCount)] array of handle of components of - ///< this type. - ///< if count is less than the number of components of this type that are - ///< available, then the driver shall only retrieve that number of - ///< component handles. +ctlEccGetState( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_ecc_state_desc_t* pState ///< [in,out] Will contain the current ECC state and pending ECC state to + ///< be applied from previous ctlEccSetState() call. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumFans_t pfnEnumFans = (ctl_pfnEnumFans_t)GetProcAddress(hinstLib, "ctlEnumFans"); - if (pfnEnumFans) + ctl_pfnEccGetState_t pfnEccGetState = (ctl_pfnEccGetState_t)GetProcAddress(hinstLibPtr, "ctlEccGetState"); + if (pfnEccGetState) { - result = pfnEnumFans(hDAhandle, pCount, phFan); + result = pfnEccGetState(hDAhandle, pState); } } @@ -2466,7 +2473,8 @@ ctlEnumFans( /** -* @brief Get fan properties +* @brief Set ECC state. Setting CTL_ECC_STATE_ECC_DEFAULT_STATE will reset the +* ECC state to the factory settings. * * @details * - The application may call this function from simultaneous threads. @@ -2477,25 +2485,35 @@ ctlEnumFans( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFan` +* + `nullptr == hDAhandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` +* + `nullptr == pState` +* - CTL_RESULT_ERROR_INVALID_ENUMERATION +* + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->currentEccState` +* + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->pendingEccState` */ ctl_result_t CTL_APICALL -ctlFanGetProperties( - ctl_fan_handle_t hFan, ///< [in] Handle for the component. - ctl_fan_properties_t* pProperties ///< [in,out] Will contain the properties of the fan. +ctlEccSetState( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_ecc_state_desc_t* pState ///< [in,out] Will contain the new ECC state and pending ECC state from + ///< ctlEccSetState() call. + ///< New ECC State can be set only if isSupported is true and canControl is true. + ///< ctlEccGetState() can be called to determine if the currentEccState is + ///< not equal to pendingEccState, then system reboot is needed for the + ///< pendingEccState to be applied. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFanGetProperties_t pfnFanGetProperties = (ctl_pfnFanGetProperties_t)GetProcAddress(hinstLib, "ctlFanGetProperties"); - if (pfnFanGetProperties) + ctl_pfnEccSetState_t pfnEccSetState = (ctl_pfnEccSetState_t)GetProcAddress(hinstLibPtr, "ctlEccSetState"); + if (pfnEccSetState) { - result = pfnFanGetProperties(hFan, pProperties); + result = pfnEccSetState(hDAhandle, pState); } } @@ -2504,8 +2522,7 @@ ctlFanGetProperties( /** -* @brief Get fan configurations and the current fan speed mode (default, fixed, -* temp-speed table) +* @brief Get handle of engine groups * * @details * - The application may call this function from simultaneous threads. @@ -2516,25 +2533,37 @@ ctlFanGetProperties( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFan` +* + `nullptr == hDAhandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pConfig` +* + `nullptr == pCount` */ ctl_result_t CTL_APICALL -ctlFanGetConfig( - ctl_fan_handle_t hFan, ///< [in] Handle for the component. - ctl_fan_config_t* pConfig ///< [in,out] Will contain the current configuration of the fan. +ctlEnumEngineGroups( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< if count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< if count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_engine_handle_t* phEngine ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ///< this type. + ///< if count is less than the number of components of this type that are + ///< available, then the driver shall only retrieve that number of + ///< component handles. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFanGetConfig_t pfnFanGetConfig = (ctl_pfnFanGetConfig_t)GetProcAddress(hinstLib, "ctlFanGetConfig"); - if (pfnFanGetConfig) + ctl_pfnEnumEngineGroups_t pfnEnumEngineGroups = (ctl_pfnEnumEngineGroups_t)GetProcAddress(hinstLibPtr, "ctlEnumEngineGroups"); + if (pfnEnumEngineGroups) { - result = pfnFanGetConfig(hFan, pConfig); + result = pfnEnumEngineGroups(hDAhandle, pCount, phEngine); } } @@ -2543,8 +2572,7 @@ ctlFanGetConfig( /** -* @brief Configure the fan to run with hardware factory settings (set mode to -* ::CTL_FAN_SPEED_MODE_DEFAULT) +* @brief Get engine group properties * * @details * - The application may call this function from simultaneous threads. @@ -2555,24 +2583,27 @@ ctlFanGetConfig( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFan` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. +* + `nullptr == hEngine` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` */ ctl_result_t CTL_APICALL -ctlFanSetDefaultMode( - ctl_fan_handle_t hFan ///< [in] Handle for the component. +ctlEngineGetProperties( + ctl_engine_handle_t hEngine, ///< [in] Handle for the component. + ctl_engine_properties_t* pProperties ///< [in,out] The properties for the specified engine group. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFanSetDefaultMode_t pfnFanSetDefaultMode = (ctl_pfnFanSetDefaultMode_t)GetProcAddress(hinstLib, "ctlFanSetDefaultMode"); - if (pfnFanSetDefaultMode) + ctl_pfnEngineGetProperties_t pfnEngineGetProperties = (ctl_pfnEngineGetProperties_t)GetProcAddress(hinstLibPtr, "ctlEngineGetProperties"); + if (pfnEngineGetProperties) { - result = pfnFanSetDefaultMode(hFan); + result = pfnEngineGetProperties(hEngine, pProperties); } } @@ -2581,8 +2612,7 @@ ctlFanSetDefaultMode( /** -* @brief Configure the fan to rotate at a fixed speed (set mode to -* ::CTL_FAN_SPEED_MODE_FIXED) +* @brief Get the activity stats for an engine group * * @details * - The application may call this function from simultaneous threads. @@ -2593,29 +2623,28 @@ ctlFanSetDefaultMode( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFan` +* + `nullptr == hEngine` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == speed` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. -* - ::CTL_RESULT_ERROR_UNSUPPORTED_FEATURE -* + Fixing the fan speed not supported by the hardware or the fan speed units are not supported. See ::ctl_fan_properties_t.supportedModes and ::ctl_fan_properties_t.supportedUnits. +* + `nullptr == pStats` */ ctl_result_t CTL_APICALL -ctlFanSetFixedSpeedMode( - ctl_fan_handle_t hFan, ///< [in] Handle for the component. - const ctl_fan_speed_t* speed ///< [in] The fixed fan speed setting +ctlEngineGetActivity( + ctl_engine_handle_t hEngine, ///< [in] Handle for the component. + ctl_engine_stats_t* pStats ///< [in,out] Will contain a snapshot of the engine group activity + ///< counters. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFanSetFixedSpeedMode_t pfnFanSetFixedSpeedMode = (ctl_pfnFanSetFixedSpeedMode_t)GetProcAddress(hinstLib, "ctlFanSetFixedSpeedMode"); - if (pfnFanSetFixedSpeedMode) + ctl_pfnEngineGetActivity_t pfnEngineGetActivity = (ctl_pfnEngineGetActivity_t)GetProcAddress(hinstLibPtr, "ctlEngineGetActivity"); + if (pfnEngineGetActivity) { - result = pfnFanSetFixedSpeedMode(hFan, speed); + result = pfnEngineGetActivity(hEngine, pStats); } } @@ -2624,8 +2653,7 @@ ctlFanSetFixedSpeedMode( /** -* @brief Configure the fan to adjust speed based on a temperature/speed table -* (set mode to ::CTL_FAN_SPEED_MODE_TABLE) +* @brief Get handle of fans * * @details * - The application may call this function from simultaneous threads. @@ -2636,31 +2664,37 @@ ctlFanSetFixedSpeedMode( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFan` +* + `nullptr == hDAhandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == speedTable` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. -* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT -* + The temperature/speed pairs in the array are not sorted on temperature from lowest to highest. -* - ::CTL_RESULT_ERROR_UNSUPPORTED_FEATURE -* + Fan speed table not supported by the hardware or the fan speed units are not supported. See ::ctl_fan_properties_t.supportedModes and ::ctl_fan_properties_t.supportedUnits. +* + `nullptr == pCount` */ ctl_result_t CTL_APICALL -ctlFanSetSpeedTableMode( - ctl_fan_handle_t hFan, ///< [in] Handle for the component. - const ctl_fan_speed_table_t* speedTable ///< [in] A table containing temperature/speed pairs. +ctlEnumFans( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to the adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< if count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< if count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_fan_handle_t* phFan ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ///< this type. + ///< if count is less than the number of components of this type that are + ///< available, then the driver shall only retrieve that number of + ///< component handles. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFanSetSpeedTableMode_t pfnFanSetSpeedTableMode = (ctl_pfnFanSetSpeedTableMode_t)GetProcAddress(hinstLib, "ctlFanSetSpeedTableMode"); - if (pfnFanSetSpeedTableMode) + ctl_pfnEnumFans_t pfnEnumFans = (ctl_pfnEnumFans_t)GetProcAddress(hinstLibPtr, "ctlEnumFans"); + if (pfnEnumFans) { - result = pfnFanSetSpeedTableMode(hFan, speedTable); + result = pfnEnumFans(hDAhandle, pCount, phFan); } } @@ -2669,7 +2703,7 @@ ctlFanSetSpeedTableMode( /** -* @brief Get current state of a fan - current mode and speed +* @brief Get fan properties * * @details * - The application may call this function from simultaneous threads. @@ -2681,31 +2715,26 @@ ctlFanSetSpeedTableMode( * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE * + `nullptr == hFan` -* - CTL_RESULT_ERROR_INVALID_ENUMERATION -* + `::CTL_FAN_SPEED_UNITS_PERCENT < units` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSpeed` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_FEATURE -* + The requested fan speed units are not supported. See ::ctl_fan_properties_t.supportedUnits. +* + `nullptr == pProperties` */ ctl_result_t CTL_APICALL -ctlFanGetState( +ctlFanGetProperties( ctl_fan_handle_t hFan, ///< [in] Handle for the component. - ctl_fan_speed_units_t units, ///< [in] The units in which the fan speed should be returned. - int32_t* pSpeed ///< [in,out] Will contain the current speed of the fan in the units - ///< requested. A value of -1 indicates that the fan speed cannot be - ///< measured. + ctl_fan_properties_t* pProperties ///< [in,out] Will contain the properties of the fan. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFanGetState_t pfnFanGetState = (ctl_pfnFanGetState_t)GetProcAddress(hinstLib, "ctlFanGetState"); - if (pfnFanGetState) + ctl_pfnFanGetProperties_t pfnFanGetProperties = (ctl_pfnFanGetProperties_t)GetProcAddress(hinstLibPtr, "ctlFanGetProperties"); + if (pfnFanGetProperties) { - result = pfnFanGetState(hFan, units, pSpeed); + result = pfnFanGetProperties(hFan, pProperties); } } @@ -2714,7 +2743,8 @@ ctlFanGetState( /** -* @brief Get handle of frequency domains +* @brief Get fan configurations and the current fan speed mode (default, fixed, +* temp-speed table) * * @details * - The application may call this function from simultaneous threads. @@ -2725,35 +2755,27 @@ ctlFanGetState( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDAhandle` +* + `nullptr == hFan` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCount` +* + `nullptr == pConfig` */ ctl_result_t CTL_APICALL -ctlEnumFrequencyDomains( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. - ///< if count is zero, then the driver shall update the value with the - ///< total number of components of this type that are available. - ///< if count is greater than the number of components of this type that - ///< are available, then the driver shall update the value with the correct - ///< number of components. - ctl_freq_handle_t* phFrequency ///< [in,out][optional][range(0, *pCount)] array of handle of components of - ///< this type. - ///< if count is less than the number of components of this type that are - ///< available, then the driver shall only retrieve that number of - ///< component handles. +ctlFanGetConfig( + ctl_fan_handle_t hFan, ///< [in] Handle for the component. + ctl_fan_config_t* pConfig ///< [in,out] Will contain the current configuration of the fan. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumFrequencyDomains_t pfnEnumFrequencyDomains = (ctl_pfnEnumFrequencyDomains_t)GetProcAddress(hinstLib, "ctlEnumFrequencyDomains"); - if (pfnEnumFrequencyDomains) + ctl_pfnFanGetConfig_t pfnFanGetConfig = (ctl_pfnFanGetConfig_t)GetProcAddress(hinstLibPtr, "ctlFanGetConfig"); + if (pfnFanGetConfig) { - result = pfnEnumFrequencyDomains(hDAhandle, pCount, phFrequency); + result = pfnFanGetConfig(hFan, pConfig); } } @@ -2762,7 +2784,8 @@ ctlEnumFrequencyDomains( /** -* @brief Get frequency properties - available frequencies +* @brief Configure the fan to run with hardware factory settings (set mode to +* ::CTL_FAN_SPEED_MODE_DEFAULT) * * @details * - The application may call this function from simultaneous threads. @@ -2773,25 +2796,26 @@ ctlEnumFrequencyDomains( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` +* + `nullptr == hFan` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. */ ctl_result_t CTL_APICALL -ctlFrequencyGetProperties( - ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. - ctl_freq_properties_t* pProperties ///< [in,out] The frequency properties for the specified domain. +ctlFanSetDefaultMode( + ctl_fan_handle_t hFan ///< [in] Handle for the component. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFrequencyGetProperties_t pfnFrequencyGetProperties = (ctl_pfnFrequencyGetProperties_t)GetProcAddress(hinstLib, "ctlFrequencyGetProperties"); - if (pfnFrequencyGetProperties) + ctl_pfnFanSetDefaultMode_t pfnFanSetDefaultMode = (ctl_pfnFanSetDefaultMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetDefaultMode"); + if (pfnFanSetDefaultMode) { - result = pfnFrequencyGetProperties(hFrequency, pProperties); + result = pfnFanSetDefaultMode(hFan); } } @@ -2800,12 +2824,10 @@ ctlFrequencyGetProperties( /** -* @brief Get available non-overclocked hardware clock frequencies for the -* frequency domain +* @brief Configure the fan to rotate at a fixed speed (set mode to +* ::CTL_FAN_SPEED_MODE_FIXED) * * @details -* - The list of available frequencies is returned in order of slowest to -* fastest. * - The application may call this function from simultaneous threads. * - The implementation of this function should be lock-free. * @@ -2814,33 +2836,31 @@ ctlFrequencyGetProperties( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` +* + `nullptr == hFan` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCount` +* + `nullptr == speed` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. +* - ::CTL_RESULT_ERROR_UNSUPPORTED_FEATURE +* + Fixing the fan speed not supported by the hardware or the fan speed units are not supported. See ::ctl_fan_properties_t.supportedModes and ::ctl_fan_properties_t.supportedUnits. */ ctl_result_t CTL_APICALL -ctlFrequencyGetAvailableClocks( - ctl_freq_handle_t hFrequency, ///< [in] Device handle of the device. - uint32_t* pCount, ///< [in,out] pointer to the number of frequencies. - ///< if count is zero, then the driver shall update the value with the - ///< total number of frequencies that are available. - ///< if count is greater than the number of frequencies that are available, - ///< then the driver shall update the value with the correct number of frequencies. - double* phFrequency ///< [in,out][optional][range(0, *pCount)] array of frequencies in units of - ///< MHz and sorted from slowest to fastest. - ///< if count is less than the number of frequencies that are available, - ///< then the driver shall only retrieve that number of frequencies. +ctlFanSetFixedSpeedMode( + ctl_fan_handle_t hFan, ///< [in] Handle for the component. + const ctl_fan_speed_t* speed ///< [in] The fixed fan speed setting ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFrequencyGetAvailableClocks_t pfnFrequencyGetAvailableClocks = (ctl_pfnFrequencyGetAvailableClocks_t)GetProcAddress(hinstLib, "ctlFrequencyGetAvailableClocks"); - if (pfnFrequencyGetAvailableClocks) + ctl_pfnFanSetFixedSpeedMode_t pfnFanSetFixedSpeedMode = (ctl_pfnFanSetFixedSpeedMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetFixedSpeedMode"); + if (pfnFanSetFixedSpeedMode) { - result = pfnFrequencyGetAvailableClocks(hFrequency, pCount, phFrequency); + result = pfnFanSetFixedSpeedMode(hFan, speed); } } @@ -2849,7 +2869,8 @@ ctlFrequencyGetAvailableClocks( /** -* @brief Get current frequency limits +* @brief Configure the fan to adjust speed based on a temperature/speed table +* (set mode to ::CTL_FAN_SPEED_MODE_TABLE) * * @details * - The application may call this function from simultaneous threads. @@ -2860,26 +2881,33 @@ ctlFrequencyGetAvailableClocks( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` +* + `nullptr == hFan` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLimits` +* + `nullptr == speedTable` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT +* + The temperature/speed pairs in the array are not sorted on temperature from lowest to highest. +* - ::CTL_RESULT_ERROR_UNSUPPORTED_FEATURE +* + Fan speed table not supported by the hardware or the fan speed units are not supported. See ::ctl_fan_properties_t.supportedModes and ::ctl_fan_properties_t.supportedUnits. */ ctl_result_t CTL_APICALL -ctlFrequencyGetRange( - ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. - ctl_freq_range_t* pLimits ///< [in,out] The range between which the hardware can operate for the - ///< specified domain. +ctlFanSetSpeedTableMode( + ctl_fan_handle_t hFan, ///< [in] Handle for the component. + const ctl_fan_speed_table_t* speedTable ///< [in] A table containing temperature/speed pairs. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFrequencyGetRange_t pfnFrequencyGetRange = (ctl_pfnFrequencyGetRange_t)GetProcAddress(hinstLib, "ctlFrequencyGetRange"); - if (pfnFrequencyGetRange) + ctl_pfnFanSetSpeedTableMode_t pfnFanSetSpeedTableMode = (ctl_pfnFanSetSpeedTableMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetSpeedTableMode"); + if (pfnFanSetSpeedTableMode) { - result = pfnFrequencyGetRange(hFrequency, pLimits); + result = pfnFanSetSpeedTableMode(hFan, speedTable); } } @@ -2888,7 +2916,7 @@ ctlFrequencyGetRange( /** -* @brief Set frequency range between which the hardware can operate. +* @brief Get current state of a fan - current mode and speed * * @details * - The application may call this function from simultaneous threads. @@ -2899,28 +2927,34 @@ ctlFrequencyGetRange( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` +* + `nullptr == hFan` +* - CTL_RESULT_ERROR_INVALID_ENUMERATION +* + `::CTL_FAN_SPEED_UNITS_PERCENT < units` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLimits` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. +* + `nullptr == pSpeed` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_FEATURE +* + The requested fan speed units are not supported. See ::ctl_fan_properties_t.supportedUnits. */ ctl_result_t CTL_APICALL -ctlFrequencySetRange( - ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. - const ctl_freq_range_t* pLimits ///< [in] The limits between which the hardware can operate for the - ///< specified domain. +ctlFanGetState( + ctl_fan_handle_t hFan, ///< [in] Handle for the component. + ctl_fan_speed_units_t units, ///< [in] The units in which the fan speed should be returned. + int32_t* pSpeed ///< [in,out] Will contain the current speed of the fan in the units + ///< requested. A value of -1 indicates that the fan speed cannot be + ///< measured. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFrequencySetRange_t pfnFrequencySetRange = (ctl_pfnFrequencySetRange_t)GetProcAddress(hinstLib, "ctlFrequencySetRange"); - if (pfnFrequencySetRange) + ctl_pfnFanGetState_t pfnFanGetState = (ctl_pfnFanGetState_t)GetProcAddress(hinstLibPtr, "ctlFanGetState"); + if (pfnFanGetState) { - result = pfnFrequencySetRange(hFrequency, pLimits); + result = pfnFanGetState(hFan, units, pSpeed); } } @@ -2929,37 +2963,39 @@ ctlFrequencySetRange( /** -* @brief Get current frequency state - frequency request, actual frequency, TDP -* limits +* @brief Get base firmware properties * * @details -* - The application may call this function from simultaneous threads. -* - The implementation of this function should be lock-free. +* - The application gets properties of base firmware * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` +* + `nullptr == hDeviceAdapter` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pState` -*/ +* + `nullptr == pProperties` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ ctl_result_t CTL_APICALL -ctlFrequencyGetState( - ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. - ctl_freq_state_t* pState ///< [in,out] Frequency state for the specified domain. +ctlGetFirmwareProperties( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_firmware_properties_t* pProperties ///< [in,out] Pointer to an array that will hold properties of the base + ///< firmware. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFrequencyGetState_t pfnFrequencyGetState = (ctl_pfnFrequencyGetState_t)GetProcAddress(hinstLib, "ctlFrequencyGetState"); - if (pfnFrequencyGetState) + ctl_pfnGetFirmwareProperties_t pfnGetFirmwareProperties = (ctl_pfnGetFirmwareProperties_t)GetProcAddress(hinstLibPtr, "ctlGetFirmwareProperties"); + if (pfnGetFirmwareProperties) { - result = pfnFrequencyGetState(hFrequency, pState); + result = pfnGetFirmwareProperties(hDeviceAdapter, pProperties); } } @@ -2968,37 +3004,51 @@ ctlFrequencyGetState( /** -* @brief Get frequency throttle time +* @brief Get handle of various firmware components * * @details -* - The application may call this function from simultaneous threads. -* - The implementation of this function should be lock-free. +* - The application enumerates all firmware components on an Intel +* Discrete Graphics device. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` +* + `nullptr == hDeviceAdapter` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pThrottleTime` +* + `nullptr == pCount` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid handle" +* - ::CTL_RESULT_ERROR_KMD_CALL - "KMD call failed" */ ctl_result_t CTL_APICALL -ctlFrequencyGetThrottleTime( - ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. - ctl_freq_throttle_time_t* pThrottleTime ///< [in,out] Will contain a snapshot of the throttle time counters for the - ///< specified domain. +ctlEnumerateFirmwareComponents( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< if count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< if count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_firmware_component_handle_t* phFirmware ///< [in,out][optional][release][range(0, *pCount)] array of handle of + ///< firmware components. + ///< If count is less than the number of firmware components that are + ///< available, then the driver shall only retrieve that number of firmware + ///< component handles. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnFrequencyGetThrottleTime_t pfnFrequencyGetThrottleTime = (ctl_pfnFrequencyGetThrottleTime_t)GetProcAddress(hinstLib, "ctlFrequencyGetThrottleTime"); - if (pfnFrequencyGetThrottleTime) + ctl_pfnEnumerateFirmwareComponents_t pfnEnumerateFirmwareComponents = (ctl_pfnEnumerateFirmwareComponents_t)GetProcAddress(hinstLibPtr, "ctlEnumerateFirmwareComponents"); + if (pfnEnumerateFirmwareComponents) { - result = pfnFrequencyGetThrottleTime(hFrequency, pThrottleTime); + result = pfnEnumerateFirmwareComponents(hDeviceAdapter, pCount, phFirmware); } } @@ -3007,36 +3057,41 @@ ctlFrequencyGetThrottleTime( /** -* @brief Get Video Processing capabilities +* @brief Get firmware component properties * * @details -* - The application gets Video Processing properties +* - The application gets properties of individual firmware components * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDAhandle` +* + `nullptr == hFirmware` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pFeatureCaps` +* + `nullptr == pProperties` * - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid handle" +* - ::CTL_RESULT_ERROR_KMD_CALL - "KMD call failed" */ ctl_result_t CTL_APICALL -ctlGetSupportedVideoProcessingCapabilities( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_video_processing_feature_caps_t* pFeatureCaps ///< [in,out][release] Video Processing properties +ctlGetFirmwareComponentProperties( + ctl_firmware_component_handle_t hFirmware, ///< [in] Handle for the firmware component. + ctl_firmware_component_properties_t* pProperties///< [in,out] Pointer to an array that will hold properties of the firmware + ///< component. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSupportedVideoProcessingCapabilities_t pfnGetSupportedVideoProcessingCapabilities = (ctl_pfnGetSupportedVideoProcessingCapabilities_t)GetProcAddress(hinstLib, "ctlGetSupportedVideoProcessingCapabilities"); - if (pfnGetSupportedVideoProcessingCapabilities) + ctl_pfnGetFirmwareComponentProperties_t pfnGetFirmwareComponentProperties = (ctl_pfnGetFirmwareComponentProperties_t)GetProcAddress(hinstLibPtr, "ctlGetFirmwareComponentProperties"); + if (pfnGetFirmwareComponentProperties) { - result = pfnGetSupportedVideoProcessingCapabilities(hDAhandle, pFeatureCaps); + result = pfnGetFirmwareComponentProperties(hFirmware, pProperties); } } @@ -3045,36 +3100,50 @@ ctlGetSupportedVideoProcessingCapabilities( /** -* @brief Get/Set Video Processing feature details +* @brief Allows/Blocks discrete graphics device firmware's capability to train +* PCI-E link at higher speeds on compatible compatible hosts * * @details -* - Video Processing feature details +* - This API allows caller to allow/block a compatible discrete graphics +* card's firmware train PCIE links at higher speeds on compatible hosts. +* - System needs to be powered off and restarted for the new state to take +* affect. The new state will not be applied on only a warm reboot of the +* system. +* - This is a reserved capability. By default, this capability will not be +* enabled, need application to activate it, please contact Intel for +* activation. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDAhandle` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pFeature` +* + `nullptr == hDeviceAdapter` * - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid handle" +* - ::CTL_RESULT_ERROR_KMD_CALL - "KMD call failed" */ ctl_result_t CTL_APICALL -ctlGetSetVideoProcessingFeature( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_video_processing_feature_getset_t* pFeature ///< [in][release] Video Processing feature get/set parameter +ctlAllowPCIeLinkSpeedUpdate( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + bool AllowPCIeLinkSpeedUpdate ///< [in] When set configures the device firmware to train PCI-E link at + ///< higher speeds, else this will block the device firmware from training + ///< at higher PCI-E link speeds on compatible hosts. + ///< This API modifies a flash persistant setting of the device firmware to + ///< allow/block training PCI-E link at higher speeds. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnGetSetVideoProcessingFeature_t pfnGetSetVideoProcessingFeature = (ctl_pfnGetSetVideoProcessingFeature_t)GetProcAddress(hinstLib, "ctlGetSetVideoProcessingFeature"); - if (pfnGetSetVideoProcessingFeature) + ctl_pfnAllowPCIeLinkSpeedUpdate_t pfnAllowPCIeLinkSpeedUpdate = (ctl_pfnAllowPCIeLinkSpeedUpdate_t)GetProcAddress(hinstLibPtr, "ctlAllowPCIeLinkSpeedUpdate"); + if (pfnAllowPCIeLinkSpeedUpdate) { - result = pfnGetSetVideoProcessingFeature(hDAhandle, pFeature); + result = pfnAllowPCIeLinkSpeedUpdate(hDeviceAdapter, AllowPCIeLinkSpeedUpdate); } } @@ -3083,7 +3152,7 @@ ctlGetSetVideoProcessingFeature( /** -* @brief Get handle of memory modules +* @brief Get handle of frequency domains * * @details * - The application may call this function from simultaneous threads. @@ -3099,7 +3168,7 @@ ctlGetSetVideoProcessingFeature( * + `nullptr == pCount` */ ctl_result_t CTL_APICALL -ctlEnumMemoryModules( +ctlEnumFrequencyDomains( ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. ///< if count is zero, then the driver shall update the value with the @@ -3107,7 +3176,7 @@ ctlEnumMemoryModules( ///< if count is greater than the number of components of this type that ///< are available, then the driver shall update the value with the correct ///< number of components. - ctl_mem_handle_t* phMemory ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ctl_freq_handle_t* phFrequency ///< [in,out][optional][range(0, *pCount)] array of handle of components of ///< this type. ///< if count is less than the number of components of this type that are ///< available, then the driver shall only retrieve that number of @@ -3117,12 +3186,14 @@ ctlEnumMemoryModules( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumMemoryModules_t pfnEnumMemoryModules = (ctl_pfnEnumMemoryModules_t)GetProcAddress(hinstLib, "ctlEnumMemoryModules"); - if (pfnEnumMemoryModules) + ctl_pfnEnumFrequencyDomains_t pfnEnumFrequencyDomains = (ctl_pfnEnumFrequencyDomains_t)GetProcAddress(hinstLibPtr, "ctlEnumFrequencyDomains"); + if (pfnEnumFrequencyDomains) { - result = pfnEnumMemoryModules(hDAhandle, pCount, phMemory); + result = pfnEnumFrequencyDomains(hDAhandle, pCount, phFrequency); } } @@ -3131,7 +3202,7 @@ ctlEnumMemoryModules( /** -* @brief Get memory properties +* @brief Get frequency properties - available frequencies * * @details * - The application may call this function from simultaneous threads. @@ -3142,25 +3213,27 @@ ctlEnumMemoryModules( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hMemory` +* + `nullptr == hFrequency` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER * + `nullptr == pProperties` */ ctl_result_t CTL_APICALL -ctlMemoryGetProperties( - ctl_mem_handle_t hMemory, ///< [in] Handle for the component. - ctl_mem_properties_t* pProperties ///< [in,out] Will contain memory properties. +ctlFrequencyGetProperties( + ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. + ctl_freq_properties_t* pProperties ///< [in,out] The frequency properties for the specified domain. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnMemoryGetProperties_t pfnMemoryGetProperties = (ctl_pfnMemoryGetProperties_t)GetProcAddress(hinstLib, "ctlMemoryGetProperties"); - if (pfnMemoryGetProperties) + ctl_pfnFrequencyGetProperties_t pfnFrequencyGetProperties = (ctl_pfnFrequencyGetProperties_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetProperties"); + if (pfnFrequencyGetProperties) { - result = pfnMemoryGetProperties(hMemory, pProperties); + result = pfnFrequencyGetProperties(hFrequency, pProperties); } } @@ -3169,9 +3242,12 @@ ctlMemoryGetProperties( /** -* @brief Get memory state - health, allocated +* @brief Get available non-overclocked hardware clock frequencies for the +* frequency domain * * @details +* - The list of available frequencies is returned in order of slowest to +* fastest. * - The application may call this function from simultaneous threads. * - The implementation of this function should be lock-free. * @@ -3180,25 +3256,35 @@ ctlMemoryGetProperties( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hMemory` +* + `nullptr == hFrequency` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pState` +* + `nullptr == pCount` */ ctl_result_t CTL_APICALL -ctlMemoryGetState( - ctl_mem_handle_t hMemory, ///< [in] Handle for the component. - ctl_mem_state_t* pState ///< [in,out] Will contain the current health and allocated memory. +ctlFrequencyGetAvailableClocks( + ctl_freq_handle_t hFrequency, ///< [in] Device handle of the device. + uint32_t* pCount, ///< [in,out] pointer to the number of frequencies. + ///< if count is zero, then the driver shall update the value with the + ///< total number of frequencies that are available. + ///< if count is greater than the number of frequencies that are available, + ///< then the driver shall update the value with the correct number of frequencies. + double* phFrequency ///< [in,out][optional][range(0, *pCount)] array of frequencies in units of + ///< MHz and sorted from slowest to fastest. + ///< if count is less than the number of frequencies that are available, + ///< then the driver shall only retrieve that number of frequencies. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnMemoryGetState_t pfnMemoryGetState = (ctl_pfnMemoryGetState_t)GetProcAddress(hinstLib, "ctlMemoryGetState"); - if (pfnMemoryGetState) + ctl_pfnFrequencyGetAvailableClocks_t pfnFrequencyGetAvailableClocks = (ctl_pfnFrequencyGetAvailableClocks_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetAvailableClocks"); + if (pfnFrequencyGetAvailableClocks) { - result = pfnMemoryGetState(hMemory, pState); + result = pfnFrequencyGetAvailableClocks(hFrequency, pCount, phFrequency); } } @@ -3207,7 +3293,7 @@ ctlMemoryGetState( /** -* @brief Get memory bandwidth +* @brief Get current frequency limits * * @details * - The application may call this function from simultaneous threads. @@ -3218,28 +3304,28 @@ ctlMemoryGetState( * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hMemory` +* + `nullptr == hFrequency` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pBandwidth` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to query this telemetry. +* + `nullptr == pLimits` */ ctl_result_t CTL_APICALL -ctlMemoryGetBandwidth( - ctl_mem_handle_t hMemory, ///< [in] Handle for the component. - ctl_mem_bandwidth_t* pBandwidth ///< [in,out] Will contain the current health, free memory, total memory - ///< size. +ctlFrequencyGetRange( + ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. + ctl_freq_range_t* pLimits ///< [in,out] The range between which the hardware can operate for the + ///< specified domain. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnMemoryGetBandwidth_t pfnMemoryGetBandwidth = (ctl_pfnMemoryGetBandwidth_t)GetProcAddress(hinstLib, "ctlMemoryGetBandwidth"); - if (pfnMemoryGetBandwidth) + ctl_pfnFrequencyGetRange_t pfnFrequencyGetRange = (ctl_pfnFrequencyGetRange_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetRange"); + if (pfnFrequencyGetRange) { - result = pfnMemoryGetBandwidth(hMemory, pBandwidth); + result = pfnFrequencyGetRange(hFrequency, pLimits); } } @@ -3248,32 +3334,41 @@ ctlMemoryGetBandwidth( /** -* @brief Get overclock properties - available properties. +* @brief Set frequency range between which the hardware can operate. +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` +* + `nullptr == hFrequency` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pOcProperties` +* + `nullptr == pLimits` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. */ ctl_result_t CTL_APICALL -ctlOverclockGetProperties( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - ctl_oc_properties_t* pOcProperties ///< [in,out] The overclocking properties for the specified domain. +ctlFrequencySetRange( + ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. + const ctl_freq_range_t* pLimits ///< [in] The limits between which the hardware can operate for the + ///< specified domain. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGetProperties_t pfnOverclockGetProperties = (ctl_pfnOverclockGetProperties_t)GetProcAddress(hinstLib, "ctlOverclockGetProperties"); - if (pfnOverclockGetProperties) + ctl_pfnFrequencySetRange_t pfnFrequencySetRange = (ctl_pfnFrequencySetRange_t)GetProcAddress(hinstLibPtr, "ctlFrequencySetRange"); + if (pfnFrequencySetRange) { - result = pfnOverclockGetProperties(hDeviceHandle, pOcProperties); + result = pfnFrequencySetRange(hFrequency, pLimits); } } @@ -3282,42 +3377,39 @@ ctlOverclockGetProperties( /** -* @brief Overclock Waiver - Warranty Waiver. +* @brief Get current frequency state - frequency request, actual frequency, TDP +* limits * * @details -* - Most of the overclock functions will return an error if the waiver is -* not set. This is because most overclock settings will increase the -* electric/thermal stress on the part and thus reduce its lifetime. -* - By setting the waiver, the user is indicate that they are accepting a -* reduction in the lifetime of the part. -* - It is the responsibility of overclock applications to notify each user -* at least once with a popup of the dangers and requiring acceptance. -* - Only once the user has accepted should this function be called by the -* application. -* - It is acceptable for the application to cache the user choice and call -* this function on future executions without issuing the popup. +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` +* + `nullptr == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pState` */ ctl_result_t CTL_APICALL -ctlOverclockWaiverSet( - ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter +ctlFrequencyGetState( + ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. + ctl_freq_state_t* pState ///< [in,out] Frequency state for the specified domain. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockWaiverSet_t pfnOverclockWaiverSet = (ctl_pfnOverclockWaiverSet_t)GetProcAddress(hinstLib, "ctlOverclockWaiverSet"); - if (pfnOverclockWaiverSet) + ctl_pfnFrequencyGetState_t pfnFrequencyGetState = (ctl_pfnFrequencyGetState_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetState"); + if (pfnFrequencyGetState) { - result = pfnOverclockWaiverSet(hDeviceHandle); + result = pfnFrequencyGetState(hFrequency, pState); } } @@ -3326,40 +3418,39 @@ ctlOverclockWaiverSet( /** -* @brief Get the Overclock Frequency Offset for the GPU in MHz. +* @brief Get frequency throttle time * * @details -* - Determine the current frequency offset in effect (refer to -* ::ctlOverclockGpuFrequencyOffsetSet() for details). -* - The value returned may be different from the value that was previously -* set by the application depending on hardware limitations or if the -* function ::ctlOverclockGpuFrequencyOffsetSet() has been called or -* another application that has changed the value. +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` +* + `nullptr == hFrequency` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pOcFrequencyOffset` +* + `nullptr == pThrottleTime` */ ctl_result_t CTL_APICALL -ctlOverclockGpuFrequencyOffsetGet( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pOcFrequencyOffset ///< [in,out] The Turbo Overclocking Frequency Desired in MHz. +ctlFrequencyGetThrottleTime( + ctl_freq_handle_t hFrequency, ///< [in] Handle for the component. + ctl_freq_throttle_time_t* pThrottleTime ///< [in,out] Will contain a snapshot of the throttle time counters for the + ///< specified domain. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGpuFrequencyOffsetGet_t pfnOverclockGpuFrequencyOffsetGet = (ctl_pfnOverclockGpuFrequencyOffsetGet_t)GetProcAddress(hinstLib, "ctlOverclockGpuFrequencyOffsetGet"); - if (pfnOverclockGpuFrequencyOffsetGet) + ctl_pfnFrequencyGetThrottleTime_t pfnFrequencyGetThrottleTime = (ctl_pfnFrequencyGetThrottleTime_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetThrottleTime"); + if (pfnFrequencyGetThrottleTime) { - result = pfnOverclockGpuFrequencyOffsetGet(hDeviceHandle, pOcFrequencyOffset); + result = pfnFrequencyGetThrottleTime(hFrequency, pThrottleTime); } } @@ -3368,54 +3459,619 @@ ctlOverclockGpuFrequencyOffsetGet( /** -* @brief Set the Overclock Frequency Offset for the GPU in MHZ. +* @brief Get handle of Leds * * @details -* - The purpose of this function is to increase/decrease the frequency at -* which typical workloads will run within the same thermal budget. -* - The frequency offset is expressed in units of ±1MHz. -* - The actual operating frequency for each workload is not guaranteed to -* change exactly by the specified offset. -* - For positive frequency offsets, the factory maximum frequency may -* increase by up to the specified amount. -* - For negative frequency offsets, the overclock waiver must have been -* set since this can result in running the part at voltages beyond the -* part warrantee limits. An error is returned if the waiver has not been -* set. -* - Specifying large values for the frequency offset can lead to -* instability. It is recommended that changes are made in small -* increments and stability/performance measured running intense GPU -* workloads before increasing further. -* - This setting is not persistent through system reboots or driver -* resets/hangs. It is up to the overclock application to reapply the -* settings in those cases. -* - This setting can cause system/device instability. It is up to the -* overclock application to detect if the system has rebooted -* unexpectedly or the device was restarted. When this occurs, the -* application should not reapply the overclock settings automatically -* but instead return to previously known good settings or notify the -* user that the settings are not being applied. +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` +* + `nullptr == hDAhandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pCount` */ ctl_result_t CTL_APICALL -ctlOverclockGpuFrequencyOffsetSet( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double ocFrequencyOffset ///< [in] The Turbo Overclocking Frequency Desired in MHz. +ctlEnumLeds( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< If count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< If count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_led_handle_t* phLed ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ///< this type. + ///< If count is less than the number of components of this type that are + ///< available, then the driver shall only retrieve that number of + ///< component handles. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGpuFrequencyOffsetSet_t pfnOverclockGpuFrequencyOffsetSet = (ctl_pfnOverclockGpuFrequencyOffsetSet_t)GetProcAddress(hinstLib, "ctlOverclockGpuFrequencyOffsetSet"); - if (pfnOverclockGpuFrequencyOffsetSet) + ctl_pfnEnumLeds_t pfnEnumLeds = (ctl_pfnEnumLeds_t)GetProcAddress(hinstLibPtr, "ctlEnumLeds"); + if (pfnEnumLeds) + { + result = pfnEnumLeds(hDAhandle, pCount, phLed); + } + } + + return result; +} + + +/** +* @brief Get Led properties +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hLed` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +*/ +ctl_result_t CTL_APICALL +ctlLedGetProperties( + ctl_led_handle_t hLed, ///< [in] Handle for the component. + ctl_led_properties_t* pProperties ///< [in,out] Will contain Led properties. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnLedGetProperties_t pfnLedGetProperties = (ctl_pfnLedGetProperties_t)GetProcAddress(hinstLibPtr, "ctlLedGetProperties"); + if (pfnLedGetProperties) + { + result = pfnLedGetProperties(hLed, pProperties); + } + } + + return result; +} + + +/** +* @brief Get Led state +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hLed` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pState` +*/ +ctl_result_t CTL_APICALL +ctlLedGetState( + ctl_led_handle_t hLed, ///< [in] Handle for the component. + ctl_led_state_t* pState ///< [in,out] Will contain the current Led state. + ///< Returns Led state if canControl is true and isI2C is false. + ///< pwm and color structure members of ::ctl_led_state_t will be returned + ///< only if supported by Led, else they will be returned as 0. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnLedGetState_t pfnLedGetState = (ctl_pfnLedGetState_t)GetProcAddress(hinstLibPtr, "ctlLedGetState"); + if (pfnLedGetState) + { + result = pfnLedGetState(hLed, pState); + } + } + + return result; +} + + +/** +* @brief Set Led state +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* - This API is rate-limited by 500 milliseconds, If this API is called +* too frequently ::CTL_ERROR_CORE_LED_TOO_FREQUENT_SET_REQUESTS error +* will be returned +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hLed` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pBuffer` +*/ +ctl_result_t CTL_APICALL +ctlLedSetState( + ctl_led_handle_t hLed, ///< [in] Handle for the component. + void* pBuffer, ///< [in] Led State buffer. + ///< If isI2C is true, the pBuffer and bufferSize will be passed to the I2C + ///< Interface. pBuffer format in this case is OEM defined. + ///< If isI2C is false, the pBuffer will be typecasted to + ///< ::ctl_led_state_t* and bufferSize needs to be sizeof + ///< ::ctl_led_state_t. pwm and color structure members of + ///< ::ctl_led_state_t will be set only if supported by Led, else they will + ///< be ignored. + uint32_t bufferSize ///< [in] Led State buffer size. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnLedSetState_t pfnLedSetState = (ctl_pfnLedSetState_t)GetProcAddress(hinstLibPtr, "ctlLedSetState"); + if (pfnLedSetState) + { + result = pfnLedSetState(hLed, pBuffer, bufferSize); + } + } + + return result; +} + + +/** +* @brief Get Video Processing capabilities +* +* @details +* - The application gets Video Processing properties +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDAhandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pFeatureCaps` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetSupportedVideoProcessingCapabilities( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_video_processing_feature_caps_t* pFeatureCaps ///< [in,out][release] Video Processing properties + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSupportedVideoProcessingCapabilities_t pfnGetSupportedVideoProcessingCapabilities = (ctl_pfnGetSupportedVideoProcessingCapabilities_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedVideoProcessingCapabilities"); + if (pfnGetSupportedVideoProcessingCapabilities) + { + result = pfnGetSupportedVideoProcessingCapabilities(hDAhandle, pFeatureCaps); + } + } + + return result; +} + + +/** +* @brief Get/Set Video Processing feature details +* +* @details +* - Video Processing feature details +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDAhandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pFeature` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetSetVideoProcessingFeature( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_video_processing_feature_getset_t* pFeature ///< [in][release] Video Processing feature get/set parameter + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetVideoProcessingFeature_t pfnGetSetVideoProcessingFeature = (ctl_pfnGetSetVideoProcessingFeature_t)GetProcAddress(hinstLibPtr, "ctlGetSetVideoProcessingFeature"); + if (pfnGetSetVideoProcessingFeature) + { + result = pfnGetSetVideoProcessingFeature(hDAhandle, pFeature); + } + } + + return result; +} + + +/** +* @brief Get handle of memory modules +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDAhandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pCount` +*/ +ctl_result_t CTL_APICALL +ctlEnumMemoryModules( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< if count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< if count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_mem_handle_t* phMemory ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ///< this type. + ///< if count is less than the number of components of this type that are + ///< available, then the driver shall only retrieve that number of + ///< component handles. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumMemoryModules_t pfnEnumMemoryModules = (ctl_pfnEnumMemoryModules_t)GetProcAddress(hinstLibPtr, "ctlEnumMemoryModules"); + if (pfnEnumMemoryModules) + { + result = pfnEnumMemoryModules(hDAhandle, pCount, phMemory); + } + } + + return result; +} + + +/** +* @brief Get memory properties +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hMemory` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +*/ +ctl_result_t CTL_APICALL +ctlMemoryGetProperties( + ctl_mem_handle_t hMemory, ///< [in] Handle for the component. + ctl_mem_properties_t* pProperties ///< [in,out] Will contain memory properties. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnMemoryGetProperties_t pfnMemoryGetProperties = (ctl_pfnMemoryGetProperties_t)GetProcAddress(hinstLibPtr, "ctlMemoryGetProperties"); + if (pfnMemoryGetProperties) + { + result = pfnMemoryGetProperties(hMemory, pProperties); + } + } + + return result; +} + + +/** +* @brief Get memory state - health, allocated +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hMemory` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pState` +*/ +ctl_result_t CTL_APICALL +ctlMemoryGetState( + ctl_mem_handle_t hMemory, ///< [in] Handle for the component. + ctl_mem_state_t* pState ///< [in,out] Will contain the current health and allocated memory. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnMemoryGetState_t pfnMemoryGetState = (ctl_pfnMemoryGetState_t)GetProcAddress(hinstLibPtr, "ctlMemoryGetState"); + if (pfnMemoryGetState) + { + result = pfnMemoryGetState(hMemory, pState); + } + } + + return result; +} + + +/** +* @brief Get memory bandwidth +* +* @details +* - The application may call this function from simultaneous threads. +* - The implementation of this function should be lock-free. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hMemory` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pBandwidth` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to query this telemetry. +*/ +ctl_result_t CTL_APICALL +ctlMemoryGetBandwidth( + ctl_mem_handle_t hMemory, ///< [in] Handle for the component. + ctl_mem_bandwidth_t* pBandwidth ///< [in,out] Will contain the current health, free memory, total memory + ///< size. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnMemoryGetBandwidth_t pfnMemoryGetBandwidth = (ctl_pfnMemoryGetBandwidth_t)GetProcAddress(hinstLibPtr, "ctlMemoryGetBandwidth"); + if (pfnMemoryGetBandwidth) + { + result = pfnMemoryGetBandwidth(hMemory, pBandwidth); + } + } + + return result; +} + + +/** +* @brief Get overclock properties - available properties. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pOcProperties` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGetProperties( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + ctl_oc_properties_t* pOcProperties ///< [in,out] The overclocking properties for the specified domain. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGetProperties_t pfnOverclockGetProperties = (ctl_pfnOverclockGetProperties_t)GetProcAddress(hinstLibPtr, "ctlOverclockGetProperties"); + if (pfnOverclockGetProperties) + { + result = pfnOverclockGetProperties(hDeviceHandle, pOcProperties); + } + } + + return result; +} + + +/** +* @brief Overclock Waiver - Warranty Waiver. +* +* @details +* - Most of the overclock functions will return an error if the waiver is +* not set. This is because most overclock settings will increase the +* electric/thermal stress on the part and thus reduce its lifetime. +* - By setting the waiver, the user is indicate that they are accepting a +* reduction in the lifetime of the part. +* - It is the responsibility of overclock applications to notify each user +* at least once with a popup of the dangers and requiring acceptance. +* - Only once the user has accepted should this function be called by the +* application. +* - It is acceptable for the application to cache the user choice and call +* this function on future executions without issuing the popup. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockWaiverSet( + ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockWaiverSet_t pfnOverclockWaiverSet = (ctl_pfnOverclockWaiverSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockWaiverSet"); + if (pfnOverclockWaiverSet) + { + result = pfnOverclockWaiverSet(hDeviceHandle); + } + } + + return result; +} + + +/** +* @brief Get the Overclock Frequency Offset for the GPU in MHz. +* +* @details +* - Determine the current frequency offset in effect (refer to +* ::ctlOverclockGpuFrequencyOffsetSet() for details). +* - The value returned may be different from the value that was previously +* set by the application depending on hardware limitations or if the +* function ::ctlOverclockGpuFrequencyOffsetSet() has been called or +* another application that has changed the value. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pOcFrequencyOffset` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGpuFrequencyOffsetGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pOcFrequencyOffset ///< [in,out] The Turbo Overclocking Frequency Desired in MHz. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuFrequencyOffsetGet_t pfnOverclockGpuFrequencyOffsetGet = (ctl_pfnOverclockGpuFrequencyOffsetGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetGet"); + if (pfnOverclockGpuFrequencyOffsetGet) + { + result = pfnOverclockGpuFrequencyOffsetGet(hDeviceHandle, pOcFrequencyOffset); + } + } + + return result; +} + + +/** +* @brief Set the Overclock Frequency Offset for the GPU in MHZ. +* +* @details +* - The purpose of this function is to increase/decrease the frequency at +* which typical workloads will run within the same thermal budget. +* - The frequency offset is expressed in units of ±1MHz. +* - The actual operating frequency for each workload is not guaranteed to +* change exactly by the specified offset. +* - For positive frequency offsets, the factory maximum frequency may +* increase by up to the specified amount. +* - For negative frequency offsets, the overclock waiver must have been +* set since this can result in running the part at voltages beyond the +* part warrantee limits. An error is returned if the waiver has not been +* set. +* - Specifying large values for the frequency offset can lead to +* instability. It is recommended that changes are made in small +* increments and stability/performance measured running intense GPU +* workloads before increasing further. +* - This setting is not persistent through system reboots or driver +* resets/hangs. It is up to the overclock application to reapply the +* settings in those cases. +* - This setting can cause system/device instability. It is up to the +* overclock application to detect if the system has rebooted +* unexpectedly or the device was restarted. When this occurs, the +* application should not reapply the overclock settings automatically +* but instead return to previously known good settings or notify the +* user that the settings are not being applied. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGpuFrequencyOffsetSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double ocFrequencyOffset ///< [in] The Turbo Overclocking Frequency Desired in MHz. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuFrequencyOffsetSet_t pfnOverclockGpuFrequencyOffsetSet = (ctl_pfnOverclockGpuFrequencyOffsetSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetSet"); + if (pfnOverclockGpuFrequencyOffsetSet) { result = pfnOverclockGpuFrequencyOffsetSet(hDeviceHandle, ocFrequencyOffset); } @@ -3426,15 +4082,429 @@ ctlOverclockGpuFrequencyOffsetSet( /** -* @brief Get the Overclock Gpu Voltage Offset in mV. +* @brief Get the Overclock Gpu Voltage Offset in mV. +* +* @details +* - Determine the current voltage offset in effect on the hardware (refer +* to ::ctlOverclockGpuVoltageOffsetSet for details). +* - The value returned may be different from the value that was previously +* set by the application depending on hardware limitations or if the +* function ::ctlOverclockGpuVoltageOffsetSet has been called or another +* application that has changed the value. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pOcVoltageOffset` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGpuVoltageOffsetGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pOcVoltageOffset ///< [in,out] The Turbo Overclocking Frequency Desired in mV. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuVoltageOffsetGet_t pfnOverclockGpuVoltageOffsetGet = (ctl_pfnOverclockGpuVoltageOffsetGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuVoltageOffsetGet"); + if (pfnOverclockGpuVoltageOffsetGet) + { + result = pfnOverclockGpuVoltageOffsetGet(hDeviceHandle, pOcVoltageOffset); + } + } + + return result; +} + + +/** +* @brief Set the Overclock Gpu Voltage Offset in mV. +* +* @details +* - The purpose of this function is to attempt to run the GPU up to higher +* voltages beyond the part warrantee limits. This can permit running at +* even higher frequencies than can be obtained using the frequency +* offset setting, but at the risk of reducing the lifetime of the part. +* - The voltage offset is expressed in units of ±millivolts with values +* permitted down to a resolution of 1 millivolt. +* - The overclock waiver must be set before calling this function +* otherwise and error will be returned. +* - There is no guarantee that a workload can operate at the higher +* frequencies permitted by this setting. Significantly more heat will be +* generated at these high frequencies/voltages which will necessitate a +* good cooling solution. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGpuVoltageOffsetSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double ocVoltageOffset ///< [in] The Turbo Overclocking Frequency Desired in mV. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuVoltageOffsetSet_t pfnOverclockGpuVoltageOffsetSet = (ctl_pfnOverclockGpuVoltageOffsetSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuVoltageOffsetSet"); + if (pfnOverclockGpuVoltageOffsetSet) + { + result = pfnOverclockGpuVoltageOffsetSet(hDeviceHandle, ocVoltageOffset); + } + } + + return result; +} + + +/** +* @brief Gets the Locked GPU Voltage for Overclocking in mV. +* +* @details +* - The purpose of this function is to determine if the current values of +* the frequency/voltage lock. +* - If the lock is not currently active, will return 0 for frequency and +* voltage. +* - Note that the operating frequency/voltage may be lower than these +* settings if power/thermal limits are exceeded. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pVfPair` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGpuLockGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + ctl_oc_vf_pair_t* pVfPair ///< [out] The current locked voltage and frequency. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuLockGet_t pfnOverclockGpuLockGet = (ctl_pfnOverclockGpuLockGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuLockGet"); + if (pfnOverclockGpuLockGet) + { + result = pfnOverclockGpuLockGet(hDeviceHandle, pVfPair); + } + } + + return result; +} + + +/** +* @brief Locks the GPU voltage for Overclocking in mV. +* +* @details +* - The purpose of this function is to provide an interface for scanners +* to lock the frequency and voltage to fixed values. +* - The frequency is expressed in units of MHz with a resolution of 1MHz. +* - The voltage is expressed in units of ±millivolts with values +* permitted down to a resolution of 1 millivolt. +* - The overclock waiver must be set since fixing the voltage at a high +* value puts unnecessary stress on the part. +* - The actual frequency may reduce depending on power/thermal +* limitations. +* - Requesting a frequency and/or voltage of 0 will return the hardware to +* dynamic frequency/voltage management with any previous frequency +* offset or voltage offset settings reapplied. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockGpuLockSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + ctl_oc_vf_pair_t vFPair ///< [in] The current locked voltage and frequency. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuLockSet_t pfnOverclockGpuLockSet = (ctl_pfnOverclockGpuLockSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuLockSet"); + if (pfnOverclockGpuLockSet) + { + result = pfnOverclockGpuLockSet(hDeviceHandle, vFPair); + } + } + + return result; +} + + +/** +* @brief Get the current Vram Frequency Offset in GT/s. +* +* @details +* - The purpose of this function is to return the current VRAM frequency +* offset in units of GT/s. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pOcFrequencyOffset` +*/ +ctl_result_t CTL_APICALL +ctlOverclockVramFrequencyOffsetGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pOcFrequencyOffset ///< [in,out] The current Memory Frequency in GT/s. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockVramFrequencyOffsetGet_t pfnOverclockVramFrequencyOffsetGet = (ctl_pfnOverclockVramFrequencyOffsetGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramFrequencyOffsetGet"); + if (pfnOverclockVramFrequencyOffsetGet) + { + result = pfnOverclockVramFrequencyOffsetGet(hDeviceHandle, pOcFrequencyOffset); + } + } + + return result; +} + + +/** +* @brief Set the desired Vram frquency Offset in GT/s +* +* @details +* - The purpose of this function is to increase/decrease the frequency of +* VRAM. +* - The frequency offset is expressed in units of GT/s with a minimum step +* size given by ::ctlOverclockGetProperties. +* - The actual operating frequency for each workload is not guaranteed to +* change exactly by the specified offset. +* - The waiver must be set using clibOverclockWaiverSet() before this +* function can be called. +* - This setting is not persistent through system reboots or driver +* resets/hangs. It is up to the overclock application to reapply the +* settings in those cases. +* - This setting can cause system/device instability. It is up to the +* overclock application to detect if the system has rebooted +* unexpectedly or the device was restarted. When this occurs, the +* application should not reapply the overclock settings automatically +* but instead return to previously known good settings or notify the +* user that the settings are not being applied. +* - If the memory controller doesn't support changes to frequency on the +* fly, one of the following return codes will be given: +* - ::CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory +* overclock will be applied when the device is reset or the system is +* rebooted. In this case, the overclock software should check if the +* overclock request was applied after the reset/reboot. If it was and +* when the overclock application shuts down gracefully and if the +* overclock application wants the setting to be persistent, the +* application should request the same overclock settings again so that +* they will be applied on the next reset/reboot. If this is not done, +* then every time the device is reset and overclock is requested, the +* device needs to be reset a second time. +* - ::CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory +* overclock will be applied when the system is rebooted. In this case, +* the overclock software should check if the overclock request was +* applied after the reboot. If it was and when the overclock application +* shuts down gracefully and if the overclock application wants the +* setting to be persistent, the application should request the same +* overclock settings again so that they will be applied on the next +* reset/reboot. If this is not done and the overclock setting is +* requested after the reboot has occurred, a second reboot will be +* required. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockVramFrequencyOffsetSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double ocFrequencyOffset ///< [in] The desired Memory Frequency in GT/s. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockVramFrequencyOffsetSet_t pfnOverclockVramFrequencyOffsetSet = (ctl_pfnOverclockVramFrequencyOffsetSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramFrequencyOffsetSet"); + if (pfnOverclockVramFrequencyOffsetSet) + { + result = pfnOverclockVramFrequencyOffsetSet(hDeviceHandle, ocFrequencyOffset); + } + } + + return result; +} + + +/** +* @brief Get the Overclock Vram Voltage Offset in mV. +* +* @details +* - The purpose of this function is to increase/decrease the voltage of +* VRAM. +* - The voltage offset is expressed in units of millivolts with a minimum +* step size given by ::ctlOverclockGetProperties. +* - The waiver must be set using ::ctlOverclockWaiverSet before this +* function can be called. +* - This setting is not persistent through system reboots or driver +* resets/hangs. It is up to the overclock application to reapply the +* settings in those cases. +* - This setting can cause system/device instability. It is up to the +* overclock application to detect if the system has rebooted +* unexpectedly or the device was restarted. When this occurs, the +* application should not reapply the overclock settings automatically +* but instead return to previously known good settings or notify the +* user that the settings are not being applied. +* - If the memory controller doesn't support changes to voltage on the +* fly, one of the following return codes will be given: +* - ::CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory +* overclock will be applied when the device is reset or the system is +* rebooted. In this case, the overclock software should check if the +* overclock request was applied after the reset/reboot. If it was and +* when the overclock application shuts down gracefully and if the +* overclock application wants the setting to be persistent, the +* application should request the same overclock settings again so that +* they will be applied on the next reset/reboot. If this is not done, +* then every time the device is reset and overclock is requested, the +* device needs to be reset a second time. +* - ::CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory +* overclock will be applied when the system is rebooted. In this case, +* the overclock software should check if the overclock request was +* applied after the reboot. If it was and when the overclock application +* shuts down gracefully and if the overclock application wants the +* setting to be persistent, the application should request the same +* overclock settings again so that they will be applied on the next +* reset/reboot. If this is not done and the overclock setting is +* requested after the reboot has occurred, a second reboot will be +* required. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pVoltage` +*/ +ctl_result_t CTL_APICALL +ctlOverclockVramVoltageOffsetGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pVoltage ///< [out] The current locked voltage in mV. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockVramVoltageOffsetGet_t pfnOverclockVramVoltageOffsetGet = (ctl_pfnOverclockVramVoltageOffsetGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramVoltageOffsetGet"); + if (pfnOverclockVramVoltageOffsetGet) + { + result = pfnOverclockVramVoltageOffsetGet(hDeviceHandle, pVoltage); + } + } + + return result; +} + + +/** +* @brief Set the Overclock Vram Voltage Offset in mV. * * @details -* - Determine the current voltage offset in effect on the hardware (refer -* to ::ctlOverclockGpuVoltageOffsetSet for details). -* - The value returned may be different from the value that was previously -* set by the application depending on hardware limitations or if the -* function ::ctlOverclockGpuVoltageOffsetSet has been called or another -* application that has changed the value. +* - The purpose of this function is to set the maximum sustained power +* limit. If the average GPU power averaged over a few seconds exceeds +* this value, the frequency of the GPU will be throttled. +* - Set a value of 0 to disable this power limit. In this case, the GPU +* frequency will not throttle due to average power but may hit other +* limits. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockVramVoltageOffsetSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double voltage ///< [in] The voltage to be locked in mV. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockVramVoltageOffsetSet_t pfnOverclockVramVoltageOffsetSet = (ctl_pfnOverclockVramVoltageOffsetSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramVoltageOffsetSet"); + if (pfnOverclockVramVoltageOffsetSet) + { + result = pfnOverclockVramVoltageOffsetSet(hDeviceHandle, voltage); + } + } + + return result; +} + + +/** +* @brief Get the sustained power limit in mW. +* +* @details +* - The purpose of this function is to read the current sustained power +* limit. +* - A value of 0 means that the limit is disabled - the GPU frequency can +* run as high as possible until other limits are hit. * * @returns * - CTL_RESULT_SUCCESS @@ -3443,23 +4513,25 @@ ctlOverclockGpuFrequencyOffsetSet( * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE * + `nullptr == hDeviceHandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pOcVoltageOffset` +* + `nullptr == pSustainedPowerLimit` */ ctl_result_t CTL_APICALL -ctlOverclockGpuVoltageOffsetGet( +ctlOverclockPowerLimitGet( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pOcVoltageOffset ///< [in,out] The Turbo Overclocking Frequency Desired in mV. + double* pSustainedPowerLimit ///< [in,out] The current sustained power limit in mW. ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGpuVoltageOffsetGet_t pfnOverclockGpuVoltageOffsetGet = (ctl_pfnOverclockGpuVoltageOffsetGet_t)GetProcAddress(hinstLib, "ctlOverclockGpuVoltageOffsetGet"); - if (pfnOverclockGpuVoltageOffsetGet) + ctl_pfnOverclockPowerLimitGet_t pfnOverclockPowerLimitGet = (ctl_pfnOverclockPowerLimitGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitGet"); + if (pfnOverclockPowerLimitGet) { - result = pfnOverclockGpuVoltageOffsetGet(hDeviceHandle, pOcVoltageOffset); + result = pfnOverclockPowerLimitGet(hDeviceHandle, pSustainedPowerLimit); } } @@ -3468,21 +4540,15 @@ ctlOverclockGpuVoltageOffsetGet( /** -* @brief Set the Overclock Gpu Voltage Offset in mV. +* @brief Set the sustained power limit in mW. * * @details -* - The purpose of this function is to attempt to run the GPU up to higher -* voltages beyond the part warrantee limits. This can permit running at -* even higher frequencies than can be obtained using the frequency -* offset setting, but at the risk of reducing the lifetime of the part. -* - The voltage offset is expressed in units of ±millivolts with values -* permitted down to a resolution of 1 millivolt. -* - The overclock waiver must be set before calling this function -* otherwise and error will be returned. -* - There is no guarantee that a workload can operate at the higher -* frequencies permitted by this setting. Significantly more heat will be -* generated at these high frequencies/voltages which will necessitate a -* good cooling solution. +* - The purpose of this function is to set the maximum sustained power +* limit. If the average GPU power averaged over a few seconds exceeds +* this value, the frequency of the GPU will be throttled. +* - Set a value of 0 to disable this power limit. In this case, the GPU +* frequency will not throttle due to average power but may hit other +* limits. * * @returns * - CTL_RESULT_SUCCESS @@ -3492,20 +4558,180 @@ ctlOverclockGpuVoltageOffsetGet( * + `nullptr == hDeviceHandle` */ ctl_result_t CTL_APICALL -ctlOverclockGpuVoltageOffsetSet( +ctlOverclockPowerLimitSet( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double ocVoltageOffset ///< [in] The Turbo Overclocking Frequency Desired in mV. + double sustainedPowerLimit ///< [in] The desired sustained power limit in mW. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockPowerLimitSet_t pfnOverclockPowerLimitSet = (ctl_pfnOverclockPowerLimitSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitSet"); + if (pfnOverclockPowerLimitSet) + { + result = pfnOverclockPowerLimitSet(hDeviceHandle, sustainedPowerLimit); + } + } + + return result; +} + + +/** +* @brief Get the current temperature limit in Celsius. +* +* @details +* - The purpose of this function is to read the current thermal limit. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pTemperatureLimit` +*/ +ctl_result_t CTL_APICALL +ctlOverclockTemperatureLimitGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pTemperatureLimit ///< [in,out] The current temperature limit in Celsius. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockTemperatureLimitGet_t pfnOverclockTemperatureLimitGet = (ctl_pfnOverclockTemperatureLimitGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitGet"); + if (pfnOverclockTemperatureLimitGet) + { + result = pfnOverclockTemperatureLimitGet(hDeviceHandle, pTemperatureLimit); + } + } + + return result; +} + + +/** +* @brief Set the temperature limit in Celsius. +* +* @details +* - The purpose of this function is to change the maximum thermal limit. +* When the GPU temperature exceeds this value, the GPU frequency will be +* throttled. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockTemperatureLimitSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double temperatureLimit ///< [in] The desired temperature limit in Celsius. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockTemperatureLimitSet_t pfnOverclockTemperatureLimitSet = (ctl_pfnOverclockTemperatureLimitSet_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitSet"); + if (pfnOverclockTemperatureLimitSet) + { + result = pfnOverclockTemperatureLimitSet(hDeviceHandle, temperatureLimit); + } + } + + return result; +} + + +/** +* @brief Get Power Telemetry. +* +* @details +* - Limited rate of 50 ms, any call under 50 ms will return the same +* information. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pTelemetryInfo` +*/ +ctl_result_t CTL_APICALL +ctlPowerTelemetryGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + ctl_power_telemetry_t* pTelemetryInfo ///< [out] The overclocking properties for the specified domain. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPowerTelemetryGet_t pfnPowerTelemetryGet = (ctl_pfnPowerTelemetryGet_t)GetProcAddress(hinstLibPtr, "ctlPowerTelemetryGet"); + if (pfnPowerTelemetryGet) + { + result = pfnPowerTelemetryGet(hDeviceHandle, pTelemetryInfo); + } + } + + return result; +} + + +/** +* @brief Reset all Overclock Settings to stock +* +* @details +* - Reset all Overclock setting to default using single API call +* - This request resets any changes made to GpuFrequencyOffset, +* GpuVoltageOffset, PowerLimit, TemperatureLimit, GpuLock +* - This Doesn't reset any Fan Curve Changes. It can be reset using +* ctlFanSetDefaultMode +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockResetToDefault( + ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGpuVoltageOffsetSet_t pfnOverclockGpuVoltageOffsetSet = (ctl_pfnOverclockGpuVoltageOffsetSet_t)GetProcAddress(hinstLib, "ctlOverclockGpuVoltageOffsetSet"); - if (pfnOverclockGpuVoltageOffsetSet) + ctl_pfnOverclockResetToDefault_t pfnOverclockResetToDefault = (ctl_pfnOverclockResetToDefault_t)GetProcAddress(hinstLibPtr, "ctlOverclockResetToDefault"); + if (pfnOverclockResetToDefault) { - result = pfnOverclockGpuVoltageOffsetSet(hDeviceHandle, ocVoltageOffset); + result = pfnOverclockResetToDefault(hDeviceHandle); } } @@ -3514,15 +4740,16 @@ ctlOverclockGpuVoltageOffsetSet( /** -* @brief Gets the Locked GPU Voltage for Overclocking in mV. +* @brief Get the Current Overclock GPU Frequency Offset * * @details -* - The purpose of this function is to determine if the current values of -* the frequency/voltage lock. -* - If the lock is not currently active, will return 0 for frequency and -* voltage. -* - Note that the operating frequency/voltage may be lower than these -* settings if power/thermal limits are exceeded. +* - Determine the current frequency offset in effect (refer to +* ::ctlOverclockGpuFrequencyOffsetSetV2() for details). +* - The unit of the value returned is given in +* ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from +* ::ctlOverclockGetProperties() +* - The unit of the value returned can be different for different +* generation of graphics product * * @returns * - CTL_RESULT_SUCCESS @@ -3531,23 +4758,27 @@ ctlOverclockGpuVoltageOffsetSet( * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE * + `nullptr == hDeviceHandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pVfPair` +* + `nullptr == pOcFrequencyOffset` */ ctl_result_t CTL_APICALL -ctlOverclockGpuLockGet( +ctlOverclockGpuFrequencyOffsetGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - ctl_oc_vf_pair_t* pVfPair ///< [out] The current locked voltage and frequency. + double* pOcFrequencyOffset ///< [in,out] Current GPU Overclock Frequency Offset in units given in + ///< ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGpuLockGet_t pfnOverclockGpuLockGet = (ctl_pfnOverclockGpuLockGet_t)GetProcAddress(hinstLib, "ctlOverclockGpuLockGet"); - if (pfnOverclockGpuLockGet) + ctl_pfnOverclockGpuFrequencyOffsetGetV2_t pfnOverclockGpuFrequencyOffsetGetV2 = (ctl_pfnOverclockGpuFrequencyOffsetGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetGetV2"); + if (pfnOverclockGpuFrequencyOffsetGetV2) { - result = pfnOverclockGpuLockGet(hDeviceHandle, pVfPair); + result = pfnOverclockGpuFrequencyOffsetGetV2(hDeviceHandle, pOcFrequencyOffset); } } @@ -3556,21 +4787,32 @@ ctlOverclockGpuLockGet( /** -* @brief Locks the GPU voltage for Overclocking in mV. +* @brief Set the Overclock Frequency Offset for the GPU * * @details -* - The purpose of this function is to provide an interface for scanners -* to lock the frequency and voltage to fixed values. -* - The frequency is expressed in units of MHz with a resolution of 1MHz. -* - The voltage is expressed in units of ±millivolts with values -* permitted down to a resolution of 1 millivolt. -* - The overclock waiver must be set since fixing the voltage at a high -* value puts unnecessary stress on the part. -* - The actual frequency may reduce depending on power/thermal -* limitations. -* - Requesting a frequency and/or voltage of 0 will return the hardware to -* dynamic frequency/voltage management with any previous frequency -* offset or voltage offset settings reapplied. +* - The purpose of this function is to increase/decrease the frequency +* offset at which typical workloads will run within the same thermal +* budget. +* - The frequency offset is expressed in units given in +* ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from +* ::ctlOverclockGetProperties() +* - The actual operating frequency for each workload is not guaranteed to +* change exactly by the specified offset. +* - For positive frequency offsets, the factory maximum frequency may +* increase by up to the specified amount. +* - Specifying large values for the frequency offset can lead to +* instability. It is recommended that changes are made in small +* increments and stability/performance measured running intense GPU +* workloads before increasing further. +* - This setting is not persistent through system reboots or driver +* resets/hangs. It is up to the overclock application to reapply the +* settings in those cases. +* - This setting can cause system/device instability. It is up to the +* overclock application to detect if the system has rebooted +* unexpectedly or the device was restarted. When this occurs, the +* application should not reapply the overclock settings automatically +* but instead return to previously known good settings or notify the +* user that the settings are not being applied. * * @returns * - CTL_RESULT_SUCCESS @@ -3580,20 +4822,24 @@ ctlOverclockGpuLockGet( * + `nullptr == hDeviceHandle` */ ctl_result_t CTL_APICALL -ctlOverclockGpuLockSet( +ctlOverclockGpuFrequencyOffsetSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - ctl_oc_vf_pair_t vFPair ///< [in] The current locked voltage and frequency. + double ocFrequencyOffset ///< [in] The GPU Overclocking Frequency Offset Desired in units given in + ///< ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockGpuLockSet_t pfnOverclockGpuLockSet = (ctl_pfnOverclockGpuLockSet_t)GetProcAddress(hinstLib, "ctlOverclockGpuLockSet"); - if (pfnOverclockGpuLockSet) + ctl_pfnOverclockGpuFrequencyOffsetSetV2_t pfnOverclockGpuFrequencyOffsetSetV2 = (ctl_pfnOverclockGpuFrequencyOffsetSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetSetV2"); + if (pfnOverclockGpuFrequencyOffsetSetV2) { - result = pfnOverclockGpuLockSet(hDeviceHandle, vFPair); + result = pfnOverclockGpuFrequencyOffsetSetV2(hDeviceHandle, ocFrequencyOffset); } } @@ -3602,11 +4848,16 @@ ctlOverclockGpuLockSet( /** -* @brief Get the current Vram Frequency Offset in GT/s. +* @brief Get the Current Overclock Voltage Offset for the GPU * * @details -* - The purpose of this function is to return the current VRAM frequency -* offset in units of GT/s. +* - Determine the current maximum voltage offset in effect on the hardware +* (refer to ::ctlOverclockGpuMaxVoltageOffsetSetV2 for details). +* - The unit of the value returned is given in +* ::ctl_oc_properties_t::gpuVoltageOffset::units returned from +* ::ctlOverclockGetProperties() +* - The unit of the value returned can be different for different +* generation of graphics product * * @returns * - CTL_RESULT_SUCCESS @@ -3615,23 +4866,27 @@ ctlOverclockGpuLockSet( * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE * + `nullptr == hDeviceHandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pOcFrequencyOffset` +* + `nullptr == pOcMaxVoltageOffset` */ ctl_result_t CTL_APICALL -ctlOverclockVramFrequencyOffsetGet( +ctlOverclockGpuMaxVoltageOffsetGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pOcFrequencyOffset ///< [in,out] The current Memory Frequency in GT/s. + double* pOcMaxVoltageOffset ///< [in,out] Current Overclock GPU Voltage Offset in Units given in + ///< ::ctl_oc_properties_t::gpuVoltageOffset::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockVramFrequencyOffsetGet_t pfnOverclockVramFrequencyOffsetGet = (ctl_pfnOverclockVramFrequencyOffsetGet_t)GetProcAddress(hinstLib, "ctlOverclockVramFrequencyOffsetGet"); - if (pfnOverclockVramFrequencyOffsetGet) + ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t pfnOverclockGpuMaxVoltageOffsetGetV2 = (ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuMaxVoltageOffsetGetV2"); + if (pfnOverclockGpuMaxVoltageOffsetGetV2) { - result = pfnOverclockVramFrequencyOffsetGet(hDeviceHandle, pOcFrequencyOffset); + result = pfnOverclockGpuMaxVoltageOffsetGetV2(hDeviceHandle, pOcMaxVoltageOffset); } } @@ -3640,48 +4895,22 @@ ctlOverclockVramFrequencyOffsetGet( /** -* @brief Set the desired Vram frquency Offset in GT/s +* @brief Set the Overclock Voltage Offset for the GPU * * @details -* - The purpose of this function is to increase/decrease the frequency of -* VRAM. -* - The frequency offset is expressed in units of GT/s with a minimum step -* size given by ::ctlOverclockGetProperties. -* - The actual operating frequency for each workload is not guaranteed to -* change exactly by the specified offset. -* - The waiver must be set using clibOverclockWaiverSet() before this -* function can be called. -* - This setting is not persistent through system reboots or driver -* resets/hangs. It is up to the overclock application to reapply the -* settings in those cases. -* - This setting can cause system/device instability. It is up to the -* overclock application to detect if the system has rebooted -* unexpectedly or the device was restarted. When this occurs, the -* application should not reapply the overclock settings automatically -* but instead return to previously known good settings or notify the -* user that the settings are not being applied. -* - If the memory controller doesn't support changes to frequency on the -* fly, one of the following return codes will be given: -* - ::CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory -* overclock will be applied when the device is reset or the system is -* rebooted. In this case, the overclock software should check if the -* overclock request was applied after the reset/reboot. If it was and -* when the overclock application shuts down gracefully and if the -* overclock application wants the setting to be persistent, the -* application should request the same overclock settings again so that -* they will be applied on the next reset/reboot. If this is not done, -* then every time the device is reset and overclock is requested, the -* device needs to be reset a second time. -* - ::CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory -* overclock will be applied when the system is rebooted. In this case, -* the overclock software should check if the overclock request was -* applied after the reboot. If it was and when the overclock application -* shuts down gracefully and if the overclock application wants the -* setting to be persistent, the application should request the same -* overclock settings again so that they will be applied on the next -* reset/reboot. If this is not done and the overclock setting is -* requested after the reboot has occurred, a second reboot will be -* required. +* - The purpose of this function is to attempt to run the GPU up to higher +* voltages beyond the part warrantee limits. This can permit running at +* even higher frequencies than can be obtained using the frequency +* offset setting, but at the risk of reducing the lifetime of the part. +* - The voltage offset is expressed in units given in +* ::ctl_oc_properties_t::gpuVoltageOffset::units returned from +* ::ctlOverclockGetProperties() +* - The overclock waiver must be set before calling this function +* otherwise error will be returned. +* - There is no guarantee that a workload can operate at the higher +* frequencies permitted by this setting. Significantly more heat will be +* generated at these high frequencies/voltages which will necessitate a +* good cooling solution. * * @returns * - CTL_RESULT_SUCCESS @@ -3691,20 +4920,24 @@ ctlOverclockVramFrequencyOffsetGet( * + `nullptr == hDeviceHandle` */ ctl_result_t CTL_APICALL -ctlOverclockVramFrequencyOffsetSet( +ctlOverclockGpuMaxVoltageOffsetSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double ocFrequencyOffset ///< [in] The desired Memory Frequency in GT/s. + double ocMaxVoltageOffset ///< [in] The Overclocking Maximum Voltage Desired in units given in + ///< ::ctl_oc_properties_t::gpuVoltageOffset::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockVramFrequencyOffsetSet_t pfnOverclockVramFrequencyOffsetSet = (ctl_pfnOverclockVramFrequencyOffsetSet_t)GetProcAddress(hinstLib, "ctlOverclockVramFrequencyOffsetSet"); - if (pfnOverclockVramFrequencyOffsetSet) + ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t pfnOverclockGpuMaxVoltageOffsetSetV2 = (ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuMaxVoltageOffsetSetV2"); + if (pfnOverclockGpuMaxVoltageOffsetSetV2) { - result = pfnOverclockVramFrequencyOffsetSet(hDeviceHandle, ocFrequencyOffset); + result = pfnOverclockGpuMaxVoltageOffsetSetV2(hDeviceHandle, ocMaxVoltageOffset); } } @@ -3713,46 +4946,16 @@ ctlOverclockVramFrequencyOffsetSet( /** -* @brief Get the Overclock Vram Voltage Offset in mV. +* @brief Get the current Overclock Vram Memory Speed * * @details -* - The purpose of this function is to increase/decrease the voltage of -* VRAM. -* - The voltage offset is expressed in units of millivolts with a minimum -* step size given by ::ctlOverclockGetProperties. -* - The waiver must be set using ::ctlOverclockWaiverSet before this -* function can be called. -* - This setting is not persistent through system reboots or driver -* resets/hangs. It is up to the overclock application to reapply the -* settings in those cases. -* - This setting can cause system/device instability. It is up to the -* overclock application to detect if the system has rebooted -* unexpectedly or the device was restarted. When this occurs, the -* application should not reapply the overclock settings automatically -* but instead return to previously known good settings or notify the -* user that the settings are not being applied. -* - If the memory controller doesn't support changes to voltage on the -* fly, one of the following return codes will be given: -* - ::CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory -* overclock will be applied when the device is reset or the system is -* rebooted. In this case, the overclock software should check if the -* overclock request was applied after the reset/reboot. If it was and -* when the overclock application shuts down gracefully and if the -* overclock application wants the setting to be persistent, the -* application should request the same overclock settings again so that -* they will be applied on the next reset/reboot. If this is not done, -* then every time the device is reset and overclock is requested, the -* device needs to be reset a second time. -* - ::CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory -* overclock will be applied when the system is rebooted. In this case, -* the overclock software should check if the overclock request was -* applied after the reboot. If it was and when the overclock application -* shuts down gracefully and if the overclock application wants the -* setting to be persistent, the application should request the same -* overclock settings again so that they will be applied on the next -* reset/reboot. If this is not done and the overclock setting is -* requested after the reboot has occurred, a second reboot will be -* required. +* - The purpose of this function is to return the current VRAM Memory +* Speed +* - The unit of the value returned is given in +* ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from +* ::ctlOverclockGetProperties() +* - The unit of the value returned can be different for different +* generation of graphics product * * @returns * - CTL_RESULT_SUCCESS @@ -3761,23 +4964,27 @@ ctlOverclockVramFrequencyOffsetSet( * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE * + `nullptr == hDeviceHandle` * - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pVoltage` +* + `nullptr == pOcVramMemSpeedLimit` */ ctl_result_t CTL_APICALL -ctlOverclockVramVoltageOffsetGet( +ctlOverclockVramMemSpeedLimitGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pVoltage ///< [out] The current locked voltage in mV. + double* pOcVramMemSpeedLimit ///< [in,out] The current VRAM Memory Speed in units given in + ///< ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockVramVoltageOffsetGet_t pfnOverclockVramVoltageOffsetGet = (ctl_pfnOverclockVramVoltageOffsetGet_t)GetProcAddress(hinstLib, "ctlOverclockVramVoltageOffsetGet"); - if (pfnOverclockVramVoltageOffsetGet) + ctl_pfnOverclockVramMemSpeedLimitGetV2_t pfnOverclockVramMemSpeedLimitGetV2 = (ctl_pfnOverclockVramMemSpeedLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramMemSpeedLimitGetV2"); + if (pfnOverclockVramMemSpeedLimitGetV2) { - result = pfnOverclockVramVoltageOffsetGet(hDeviceHandle, pVoltage); + result = pfnOverclockVramMemSpeedLimitGetV2(hDeviceHandle, pOcVramMemSpeedLimit); } } @@ -3786,15 +4993,49 @@ ctlOverclockVramVoltageOffsetGet( /** -* @brief Set the Overclock Vram Voltage Offset in mV. +* @brief Set the desired Overclock Vram Memory Speed * * @details -* - The purpose of this function is to set the maximum sustained power -* limit. If the average GPU power averaged over a few seconds exceeds -* this value, the frequency of the GPU will be throttled. -* - Set a value of 0 to disable this power limit. In this case, the GPU -* frequency will not throttle due to average power but may hit other -* limits. +* - The purpose of this function is to increase/decrease the Speed of +* VRAM. +* - The Memory Speed is expressed in units given in +* ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from +* ::ctlOverclockGetProperties() with a minimum step size given by +* ::ctlOverclockGetProperties(). +* - The actual Memory Speed for each workload is not guaranteed to change +* exactly by the specified offset. +* - This setting is not persistent through system reboots or driver +* resets/hangs. It is up to the overclock application to reapply the +* settings in those cases. +* - This setting can cause system/device instability. It is up to the +* overclock application to detect if the system has rebooted +* unexpectedly or the device was restarted. When this occurs, the +* application should not reapply the overclock settings automatically +* but instead return to previously known good settings or notify the +* user that the settings are not being applied. +* - If the memory controller doesn't support changes to memory speed on +* the fly, one of the following return codes will be given: +* - CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory overclock +* will be applied when the device is reset or the system is rebooted. In +* this case, the overclock software should check if the overclock +* request was applied after the reset/reboot. If it was and when the +* overclock application shuts down gracefully and if the overclock +* application wants the setting to be persistent, the application should +* request the same overclock settings again so that they will be applied +* on the next reset/reboot. If this is not done, then every time the +* device is reset and overclock is requested, the device needs to be +* reset a second time. +* - CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory overclock +* will be applied when the system is rebooted. In this case, the +* overclock software should check if the overclock request was applied +* after the reboot. If it was and when the overclock application shuts +* down gracefully and if the overclock application wants the setting to +* be persistent, the application should request the same overclock +* settings again so that they will be applied on the next reset/reboot. +* If this is not done and the overclock setting is requested after the +* reboot has occurred, a second reboot will be required. +* - CTL_RESULT_ERROR_UNSUPPORTED_FEATURE: The Memory Speed Get / Set +* Feature is currently not available or Unsupported in current platform * * @returns * - CTL_RESULT_SUCCESS @@ -3804,20 +5045,24 @@ ctlOverclockVramVoltageOffsetGet( * + `nullptr == hDeviceHandle` */ ctl_result_t CTL_APICALL -ctlOverclockVramVoltageOffsetSet( +ctlOverclockVramMemSpeedLimitSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double voltage ///< [in] The voltage to be locked in mV. + double ocVramMemSpeedLimit ///< [in] The desired Memory Speed in units given in + ///< ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockVramVoltageOffsetSet_t pfnOverclockVramVoltageOffsetSet = (ctl_pfnOverclockVramVoltageOffsetSet_t)GetProcAddress(hinstLib, "ctlOverclockVramVoltageOffsetSet"); - if (pfnOverclockVramVoltageOffsetSet) + ctl_pfnOverclockVramMemSpeedLimitSetV2_t pfnOverclockVramMemSpeedLimitSetV2 = (ctl_pfnOverclockVramMemSpeedLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramMemSpeedLimitSetV2"); + if (pfnOverclockVramMemSpeedLimitSetV2) { - result = pfnOverclockVramVoltageOffsetSet(hDeviceHandle, voltage); + result = pfnOverclockVramMemSpeedLimitSetV2(hDeviceHandle, ocVramMemSpeedLimit); } } @@ -3826,13 +5071,16 @@ ctlOverclockVramVoltageOffsetSet( /** -* @brief Get the sustained power limit in mW. +* @brief Get the Current Sustained power limit * * @details * - The purpose of this function is to read the current sustained power * limit. -* - A value of 0 means that the limit is disabled - the GPU frequency can -* run as high as possible until other limits are hit. +* - The unit of the value returned is given in +* ::ctl_oc_properties_t::powerLimit::units returned from +* ::ctlOverclockGetProperties() +* - The unit of the value returned can be different for different +* generation of graphics product * * @returns * - CTL_RESULT_SUCCESS @@ -3844,20 +5092,24 @@ ctlOverclockVramVoltageOffsetSet( * + `nullptr == pSustainedPowerLimit` */ ctl_result_t CTL_APICALL -ctlOverclockPowerLimitGet( +ctlOverclockPowerLimitGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pSustainedPowerLimit ///< [in,out] The current sustained power limit in mW. + double* pSustainedPowerLimit ///< [in,out] The current Sustained Power limit in Units given in + ///< ::ctl_oc_properties_t::powerLimit::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockPowerLimitGet_t pfnOverclockPowerLimitGet = (ctl_pfnOverclockPowerLimitGet_t)GetProcAddress(hinstLib, "ctlOverclockPowerLimitGet"); - if (pfnOverclockPowerLimitGet) + ctl_pfnOverclockPowerLimitGetV2_t pfnOverclockPowerLimitGetV2 = (ctl_pfnOverclockPowerLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitGetV2"); + if (pfnOverclockPowerLimitGetV2) { - result = pfnOverclockPowerLimitGet(hDeviceHandle, pSustainedPowerLimit); + result = pfnOverclockPowerLimitGetV2(hDeviceHandle, pSustainedPowerLimit); } } @@ -3866,7 +5118,7 @@ ctlOverclockPowerLimitGet( /** -* @brief Set the sustained power limit in mW. +* @brief Set the Sustained power limit * * @details * - The purpose of this function is to set the maximum sustained power @@ -3875,6 +5127,11 @@ ctlOverclockPowerLimitGet( * - Set a value of 0 to disable this power limit. In this case, the GPU * frequency will not throttle due to average power but may hit other * limits. +* - The unit of the PowerLimit to be set is given in +* ::ctl_oc_properties_t::powerLimit::units returned from +* ::ctlOverclockGetProperties() +* - The unit of the value returned can be different for different +* generation of graphics product * * @returns * - CTL_RESULT_SUCCESS @@ -3884,20 +5141,24 @@ ctlOverclockPowerLimitGet( * + `nullptr == hDeviceHandle` */ ctl_result_t CTL_APICALL -ctlOverclockPowerLimitSet( +ctlOverclockPowerLimitSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double sustainedPowerLimit ///< [in] The desired sustained power limit in mW. + double sustainedPowerLimit ///< [in] The desired sustained power limit in Units given in + ///< ::ctl_oc_properties_t::powerLimit::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockPowerLimitSet_t pfnOverclockPowerLimitSet = (ctl_pfnOverclockPowerLimitSet_t)GetProcAddress(hinstLib, "ctlOverclockPowerLimitSet"); - if (pfnOverclockPowerLimitSet) + ctl_pfnOverclockPowerLimitSetV2_t pfnOverclockPowerLimitSetV2 = (ctl_pfnOverclockPowerLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitSetV2"); + if (pfnOverclockPowerLimitSetV2) { - result = pfnOverclockPowerLimitSet(hDeviceHandle, sustainedPowerLimit); + result = pfnOverclockPowerLimitSetV2(hDeviceHandle, sustainedPowerLimit); } } @@ -3906,10 +5167,16 @@ ctlOverclockPowerLimitSet( /** -* @brief Get the current temperature limit in Celsius. +* @brief Get the current temperature limit * * @details -* - The purpose of this function is to read the current thermal limit. +* - The purpose of this function is to read the current thermal limit used +* for Overclocking +* - The unit of the value returned is given in +* ::ctl_oc_properties_t::temperatureLimit::units returned from +* ::ctlOverclockGetProperties() +* - The unit of the value returned can be different for different +* generation of graphics product * * @returns * - CTL_RESULT_SUCCESS @@ -3921,20 +5188,24 @@ ctlOverclockPowerLimitSet( * + `nullptr == pTemperatureLimit` */ ctl_result_t CTL_APICALL -ctlOverclockTemperatureLimitGet( +ctlOverclockTemperatureLimitGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pTemperatureLimit ///< [in,out] The current temperature limit in Celsius. + double* pTemperatureLimit ///< [in,out] The current temperature limit in Units given in + ///< ::ctl_oc_properties_t::temperatureLimit::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockTemperatureLimitGet_t pfnOverclockTemperatureLimitGet = (ctl_pfnOverclockTemperatureLimitGet_t)GetProcAddress(hinstLib, "ctlOverclockTemperatureLimitGet"); - if (pfnOverclockTemperatureLimitGet) + ctl_pfnOverclockTemperatureLimitGetV2_t pfnOverclockTemperatureLimitGetV2 = (ctl_pfnOverclockTemperatureLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitGetV2"); + if (pfnOverclockTemperatureLimitGetV2) { - result = pfnOverclockTemperatureLimitGet(hDeviceHandle, pTemperatureLimit); + result = pfnOverclockTemperatureLimitGetV2(hDeviceHandle, pTemperatureLimit); } } @@ -3943,12 +5214,15 @@ ctlOverclockTemperatureLimitGet( /** -* @brief Set the temperature limit in Celsius. +* @brief Set the temperature limit * * @details * - The purpose of this function is to change the maximum thermal limit. * When the GPU temperature exceeds this value, the GPU frequency will be * throttled. +* - The unit of the value to be set is given in +* ::ctl_oc_properties_t::temperatureLimit::units returned from +* ::ctlOverclockGetProperties() * * @returns * - CTL_RESULT_SUCCESS @@ -3958,20 +5232,24 @@ ctlOverclockTemperatureLimitGet( * + `nullptr == hDeviceHandle` */ ctl_result_t CTL_APICALL -ctlOverclockTemperatureLimitSet( +ctlOverclockTemperatureLimitSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double temperatureLimit ///< [in] The desired temperature limit in Celsius. + double temperatureLimit ///< [in] The desired temperature limit in Units given in + ///< ::ctl_oc_properties_t::temperatureLimit::units returned from + ///< ::ctlOverclockGetProperties() ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockTemperatureLimitSet_t pfnOverclockTemperatureLimitSet = (ctl_pfnOverclockTemperatureLimitSet_t)GetProcAddress(hinstLib, "ctlOverclockTemperatureLimitSet"); - if (pfnOverclockTemperatureLimitSet) + ctl_pfnOverclockTemperatureLimitSetV2_t pfnOverclockTemperatureLimitSetV2 = (ctl_pfnOverclockTemperatureLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitSetV2"); + if (pfnOverclockTemperatureLimitSetV2) { - result = pfnOverclockTemperatureLimitSet(hDeviceHandle, temperatureLimit); + result = pfnOverclockTemperatureLimitSetV2(hDeviceHandle, temperatureLimit); } } @@ -3980,36 +5258,48 @@ ctlOverclockTemperatureLimitSet( /** -* @brief Get Power Telemetry. +* @brief Read VF Curve * * @details -* - Limited rate of 50 ms, any call under 50 ms will return the same -* information. +* - Read the Voltage-Frequency Curve * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pTelemetryInfo` +* + `nullptr == hDeviceAdapter` +* - CTL_RESULT_ERROR_INVALID_ENUMERATION +* + `::CTL_VF_CURVE_TYPE_LIVE < VFCurveType` +* + `::CTL_VF_CURVE_DETAILS_ELABORATE < VFCurveDetail` +* - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" */ ctl_result_t CTL_APICALL -ctlPowerTelemetryGet( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - ctl_power_telemetry_t* pTelemetryInfo ///< [out] The overclocking properties for the specified domain. +ctlOverclockReadVFCurve( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter + ctl_vf_curve_type_t VFCurveType, ///< [in] Type of Curve to read + ctl_vf_curve_details_t VFCurveDetail, ///< [in] Detail of Curve to read + uint32_t * pNumPoints, ///< [in][out] Number of points in the custom VF curve. If the NumPoints is + ///< zero, then the api will update the value with total number of Points + ///< based on requested VFCurveType and VFCurveDetail. If the NumPoints is + ///< non-zero, then the api will read and update the VF points in + ///< pVFCurveTable buffer provided. If the NumPoints doesn't match what the + ///< api returned in the first call, it will return an error. + ctl_voltage_frequency_point_t * pVFCurveTable ///< [in][out] Pointer to array of VF points, to copy the VF curve being + ///< read ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPowerTelemetryGet_t pfnPowerTelemetryGet = (ctl_pfnPowerTelemetryGet_t)GetProcAddress(hinstLib, "ctlPowerTelemetryGet"); - if (pfnPowerTelemetryGet) + ctl_pfnOverclockReadVFCurve_t pfnOverclockReadVFCurve = (ctl_pfnOverclockReadVFCurve_t)GetProcAddress(hinstLibPtr, "ctlOverclockReadVFCurve"); + if (pfnOverclockReadVFCurve) { - result = pfnPowerTelemetryGet(hDeviceHandle, pTelemetryInfo); + result = pfnOverclockReadVFCurve(hDeviceAdapter, VFCurveType, VFCurveDetail, pNumPoints, pVFCurveTable); } } @@ -4018,36 +5308,50 @@ ctlPowerTelemetryGet( /** -* @brief Reset all Overclock Settings to stock +* @brief Write Custom VF curve * * @details -* - Reset all Overclock setting to default using single API call -* - This request resets any changes made to GpuFrequencyOffset, -* GpuVoltageOffset, PowerLimit, TemperatureLimit, GpuLock -* - This Doesn't reset any Fan Curve Changes. It can be reset using -* ctlFanSetDefaultMode +* - Modify the Voltage-Frequency Curve used by GPU +* - Valid Voltage-Frequency Curve shall have Voltage and Frequency Points +* in increasing order +* - Recommended to create Custom V-F Curve from reading Current V-F Curve +* using ::ctlOverclockReadVFCurve (Read-Modify-Write) +* - If Custom V-F curve write request is Successful, the Applied VF Curve +* might be slightly different than what is originally requested, +* recommended to update the UI by reading the V-F curve again using +* ctlOverclockReadVFCurve (with ctl_vf_curve_type_t::LIVE as input) +* - The overclock waiver must be set before calling this function +* otherwise error will be returned. * * @returns * - CTL_RESULT_SUCCESS * - CTL_RESULT_ERROR_UNINITIALIZED * - CTL_RESULT_ERROR_DEVICE_LOST * - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` +* + `nullptr == hDeviceAdapter` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pCustomVFCurveTable` +* - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" */ ctl_result_t CTL_APICALL -ctlOverclockResetToDefault( - ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter +ctlOverclockWriteCustomVFCurve( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter + uint32_t NumPoints, ///< [in] Number of points in the custom VF curve + ctl_voltage_frequency_point_t* pCustomVFCurveTable ///< [in] Pointer to an array of VF Points containing 'NumPoints' Custom VF + ///< points ) { ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnOverclockResetToDefault_t pfnOverclockResetToDefault = (ctl_pfnOverclockResetToDefault_t)GetProcAddress(hinstLib, "ctlOverclockResetToDefault"); - if (pfnOverclockResetToDefault) + ctl_pfnOverclockWriteCustomVFCurve_t pfnOverclockWriteCustomVFCurve = (ctl_pfnOverclockWriteCustomVFCurve_t)GetProcAddress(hinstLibPtr, "ctlOverclockWriteCustomVFCurve"); + if (pfnOverclockWriteCustomVFCurve) { - result = pfnOverclockResetToDefault(hDeviceHandle); + result = pfnOverclockWriteCustomVFCurve(hDeviceAdapter, NumPoints, pCustomVFCurveTable); } } @@ -4080,9 +5384,11 @@ ctlPciGetProperties( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPciGetProperties_t pfnPciGetProperties = (ctl_pfnPciGetProperties_t)GetProcAddress(hinstLib, "ctlPciGetProperties"); + ctl_pfnPciGetProperties_t pfnPciGetProperties = (ctl_pfnPciGetProperties_t)GetProcAddress(hinstLibPtr, "ctlPciGetProperties"); if (pfnPciGetProperties) { result = pfnPciGetProperties(hDAhandle, pProperties); @@ -4118,9 +5424,11 @@ ctlPciGetState( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPciGetState_t pfnPciGetState = (ctl_pfnPciGetState_t)GetProcAddress(hinstLib, "ctlPciGetState"); + ctl_pfnPciGetState_t pfnPciGetState = (ctl_pfnPciGetState_t)GetProcAddress(hinstLibPtr, "ctlPciGetState"); if (pfnPciGetState) { result = pfnPciGetState(hDAhandle, pState); @@ -4166,9 +5474,11 @@ ctlEnumPowerDomains( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumPowerDomains_t pfnEnumPowerDomains = (ctl_pfnEnumPowerDomains_t)GetProcAddress(hinstLib, "ctlEnumPowerDomains"); + ctl_pfnEnumPowerDomains_t pfnEnumPowerDomains = (ctl_pfnEnumPowerDomains_t)GetProcAddress(hinstLibPtr, "ctlEnumPowerDomains"); if (pfnEnumPowerDomains) { result = pfnEnumPowerDomains(hDAhandle, pCount, phPower); @@ -4204,9 +5514,11 @@ ctlPowerGetProperties( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPowerGetProperties_t pfnPowerGetProperties = (ctl_pfnPowerGetProperties_t)GetProcAddress(hinstLib, "ctlPowerGetProperties"); + ctl_pfnPowerGetProperties_t pfnPowerGetProperties = (ctl_pfnPowerGetProperties_t)GetProcAddress(hinstLibPtr, "ctlPowerGetProperties"); if (pfnPowerGetProperties) { result = pfnPowerGetProperties(hPower, pProperties); @@ -4243,9 +5555,11 @@ ctlPowerGetEnergyCounter( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPowerGetEnergyCounter_t pfnPowerGetEnergyCounter = (ctl_pfnPowerGetEnergyCounter_t)GetProcAddress(hinstLib, "ctlPowerGetEnergyCounter"); + ctl_pfnPowerGetEnergyCounter_t pfnPowerGetEnergyCounter = (ctl_pfnPowerGetEnergyCounter_t)GetProcAddress(hinstLibPtr, "ctlPowerGetEnergyCounter"); if (pfnPowerGetEnergyCounter) { result = pfnPowerGetEnergyCounter(hPower, pEnergy); @@ -4279,9 +5593,11 @@ ctlPowerGetLimits( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPowerGetLimits_t pfnPowerGetLimits = (ctl_pfnPowerGetLimits_t)GetProcAddress(hinstLib, "ctlPowerGetLimits"); + ctl_pfnPowerGetLimits_t pfnPowerGetLimits = (ctl_pfnPowerGetLimits_t)GetProcAddress(hinstLibPtr, "ctlPowerGetLimits"); if (pfnPowerGetLimits) { result = pfnPowerGetLimits(hPower, pPowerLimits); @@ -4319,9 +5635,11 @@ ctlPowerSetLimits( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnPowerSetLimits_t pfnPowerSetLimits = (ctl_pfnPowerSetLimits_t)GetProcAddress(hinstLib, "ctlPowerSetLimits"); + ctl_pfnPowerSetLimits_t pfnPowerSetLimits = (ctl_pfnPowerSetLimits_t)GetProcAddress(hinstLibPtr, "ctlPowerSetLimits"); if (pfnPowerSetLimits) { result = pfnPowerSetLimits(hPower, pPowerLimits); @@ -4367,9 +5685,11 @@ ctlEnumTemperatureSensors( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnEnumTemperatureSensors_t pfnEnumTemperatureSensors = (ctl_pfnEnumTemperatureSensors_t)GetProcAddress(hinstLib, "ctlEnumTemperatureSensors"); + ctl_pfnEnumTemperatureSensors_t pfnEnumTemperatureSensors = (ctl_pfnEnumTemperatureSensors_t)GetProcAddress(hinstLibPtr, "ctlEnumTemperatureSensors"); if (pfnEnumTemperatureSensors) { result = pfnEnumTemperatureSensors(hDAhandle, pCount, phTemperature); @@ -4405,9 +5725,11 @@ ctlTemperatureGetProperties( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnTemperatureGetProperties_t pfnTemperatureGetProperties = (ctl_pfnTemperatureGetProperties_t)GetProcAddress(hinstLib, "ctlTemperatureGetProperties"); + ctl_pfnTemperatureGetProperties_t pfnTemperatureGetProperties = (ctl_pfnTemperatureGetProperties_t)GetProcAddress(hinstLibPtr, "ctlTemperatureGetProperties"); if (pfnTemperatureGetProperties) { result = pfnTemperatureGetProperties(hTemperature, pProperties); @@ -4444,9 +5766,11 @@ ctlTemperatureGetState( ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - if (NULL != hinstLib) + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) { - ctl_pfnTemperatureGetState_t pfnTemperatureGetState = (ctl_pfnTemperatureGetState_t)GetProcAddress(hinstLib, "ctlTemperatureGetState"); + ctl_pfnTemperatureGetState_t pfnTemperatureGetState = (ctl_pfnTemperatureGetState_t)GetProcAddress(hinstLibPtr, "ctlTemperatureGetState"); if (pfnTemperatureGetState) { result = pfnTemperatureGetState(hTemperature, pTemperature); diff --git a/includes/igcl_api.h b/include/igcl_api.h similarity index 83% rename from includes/igcl_api.h rename to include/igcl_api.h index ff83226..c40a0e9 100644 --- a/includes/igcl_api.h +++ b/include/igcl_api.h @@ -1,5 +1,5 @@ //=========================================================================== -// Copyright (C) 2022-23 Intel Corporation +// Copyright (C) 2025 Intel Corporation // This software and the related documents are Intel copyrighted materials, and // your use of them is governed by the express license under which they were // provided to you ("License"). Unless the License provides otherwise, you may @@ -120,6 +120,9 @@ typedef enum _ctl_init_flag_t { CTL_INIT_FLAG_USE_LEVEL_ZERO = CTL_BIT(0), ///< Use Level0 or not. This is usually required for telemetry, ///< performance, frequency related APIs + CTL_INIT_FLAG_IGSC_FUL = CTL_BIT(1), ///< Enable IGSC(Intel Graphics System Firmware Update Library) full + ///< functionality mode, which may include advanced graphics and compute + ///< capabilities CTL_INIT_FLAG_MAX = 0x80000000 } ctl_init_flag_t; @@ -144,6 +147,10 @@ typedef struct _ctl_temp_handle_t *ctl_temp_handle_t; /// @brief Handle for a device frequency domain typedef struct _ctl_freq_handle_t *ctl_freq_handle_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle for a device led +typedef struct _ctl_led_handle_t *ctl_led_handle_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of a power device. typedef struct _ctl_pwr_handle_t *ctl_pwr_handle_t; @@ -387,6 +394,8 @@ typedef enum _ctl_result_t CTL_RESULT_ERROR_LOAD = 0x40000026, ///< Library load failure CTL_RESULT_ERROR_UNKNOWN = 0x4000FFFF, ///< Unknown or internal error CTL_RESULT_ERROR_RETRY_OPERATION = 0x40010000, ///< Operation failed, retry previous operation again + CTL_RESULT_ERROR_IGSC_LOADER = 0x40010001, ///< IGSC library loader not found + CTL_RESULT_ERROR_RESTRICTED_APPLICATION = 0x40010002, ///< Unsupported application CTL_RESULT_ERROR_GENERIC_END = 0x4000FFFF, ///< "Generic error code end value, not to be used ///< " CTL_RESULT_ERROR_CORE_START = 0x44000000, ///< Core error code starting value, not to be used @@ -394,11 +403,24 @@ typedef enum _ctl_result_t CTL_RESULT_ERROR_CORE_OVERCLOCK_VOLTAGE_OUTSIDE_RANGE = 0x44000002, ///< The Voltage exceeds the acceptable min/max. CTL_RESULT_ERROR_CORE_OVERCLOCK_FREQUENCY_OUTSIDE_RANGE = 0x44000003, ///< The Frequency exceeds the acceptable min/max. CTL_RESULT_ERROR_CORE_OVERCLOCK_POWER_OUTSIDE_RANGE = 0x44000004, ///< The Power exceeds the acceptable min/max. - CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE = 0x44000005, ///< The Power exceeds the acceptable min/max. + CTL_RESULT_ERROR_CORE_OVERCLOCK_TEMPERATURE_OUTSIDE_RANGE = 0x44000005, ///< The Temperature exceeds the acceptable min/max. CTL_RESULT_ERROR_CORE_OVERCLOCK_IN_VOLTAGE_LOCKED_MODE = 0x44000006,///< The Overclock is in voltage locked mode. CTL_RESULT_ERROR_CORE_OVERCLOCK_RESET_REQUIRED = 0x44000007,///< It indicates that the requested change will not be applied until the ///< device is reset. CTL_RESULT_ERROR_CORE_OVERCLOCK_WAIVER_NOT_SET = 0x44000008,///< The $OverclockWaiverSet function has not been called. + CTL_RESULT_ERROR_CORE_OVERCLOCK_DEPRECATED_API = 0x44000009,///< The error indicates to switch to newer API version if applicable. + CTL_RESULT_ERROR_CORE_LED_GET_STATE_NOT_SUPPORTED_FOR_I2C_LED = 0x4400000a, ///< The error indicates that driver cannot get Led state if Led is i2c + ///< supported + CTL_RESULT_ERROR_CORE_LED_SET_STATE_NOT_SUPPORTED_FOR_I2C_LED = 0x4400000b, ///< The error indicates that driver cannot set Led state if Led is i2c + ///< supported + CTL_RESULT_ERROR_CORE_LED_TOO_FREQUENT_SET_REQUESTS = 0x4400000c, ///< The error indicates that Set Led State request is called too + ///< frequently too fast + CTL_RESULT_ERROR_CORE_OVERCLOCK_VRAM_MEMORY_SPEED_OUTSIDE_RANGE = 0x4400000d, ///< The VRAM Memory Speed exceeds the acceptable min/max. + CTL_RESULT_ERROR_CORE_OVERCLOCK_INVALID_CUSTOM_VF_CURVE = 0x4400000e, ///< Invalid Custom VF Curve applied using OverclockWriteCustomVFCurve. + ///< Valid VF Curve contains VF Curve Points which are within min/max of + ///< gpuVFCurveVoltageLimit, gpuVFCurveFrequencyLimit parameters in + ///< ctl_oc_properties_t structure and VFCurve points with distinct volages + ///< in ascending order, frequencies in ascending order. CTL_RESULT_ERROR_CORE_END = 0x0440FFFF, ///< "Core error code end value, not to be used ///< " CTL_RESULT_ERROR_3D_START = 0x60000000, ///< 3D error code starting value, not to be used @@ -456,7 +478,7 @@ typedef enum _ctl_result_t /////////////////////////////////////////////////////////////////////////////// #ifndef CTL_MAX_RESERVED_SIZE /// @brief Maximum reserved size for future members. -#define CTL_MAX_RESERVED_SIZE 112 +#define CTL_MAX_RESERVED_SIZE 108 #endif // CTL_MAX_RESERVED_SIZE /////////////////////////////////////////////////////////////////////////////// @@ -475,8 +497,9 @@ typedef enum _ctl_units_t CTL_UNITS_ANGULAR_SPEED_RPM = 9, ///< Type is Angular Speed with units in Revolutions per Minute. CTL_UNITS_POWER_MILLIWATTS = 10, ///< Type is Power with units in MilliWatts. CTL_UNITS_PERCENT = 11, ///< Type is Percentage. - CTL_UNITS_MEM_SPEED_GBPS = 12, ///< Type is Memory Speed in Gigabyte per Seconds (Gbps) + CTL_UNITS_MEM_SPEED_GBPS = 12, ///< Type is Memory Speed in Gigabytes per second (GBps). CTL_UNITS_VOLTAGE_MILLIVOLTS = 13, ///< Type is Voltage with units in milliVolts. + CTL_UNITS_BANDWIDTH_MBPS = 14, ///< Type is Bandwidth in Megabytes per second (MBps). CTL_UNITS_UNKNOWN = 0x4800FFFF, ///< Type of units unknown. CTL_UNITS_MAX @@ -729,7 +752,7 @@ typedef struct _ctl_device_adapter_properties_t ctl_device_type_t device_type; ///< [out] Device Type ctl_supported_functions_flags_t supported_subfunction_flags;///< [out] Supported functions uint64_t driver_version; ///< [out] Driver version - ctl_firmware_version_t firmware_version; ///< [out] Firmware version + ctl_firmware_version_t firmware_version; ///< [out] Global Firmware version for discrete adapters. Not implemented uint32_t pci_vendor_id; ///< [out] PCI Vendor ID uint32_t pci_device_id; ///< [out] PCI Device ID uint32_t rev_id; ///< [out] PCI Revision ID @@ -738,10 +761,13 @@ typedef struct _ctl_device_adapter_properties_t uint32_t num_slices; ///< [out] Number of slices char name[CTL_MAX_DEVICE_NAME_LEN]; ///< [out] Device name ctl_adapter_properties_flags_t graphics_adapter_properties; ///< [out] Graphics Adapter Properties - uint32_t Frequency; ///< [out] Clock frequency for this device. Supported only for Version > 0 + uint32_t Frequency; ///< [out] This represents the average frequency an end user may see in the + ///< typical gaming workload. Also referred as Graphics Clock. Supported + ///< only for Version > 0 uint16_t pci_subsys_id; ///< [out] PCI SubSys ID, Supported only for Version > 1 uint16_t pci_subsys_vendor_id; ///< [out] PCI SubSys Vendor ID, Supported only for Version > 1 ctl_adapter_bdf_t adapter_bdf; ///< [out] Pci Bus, Device, Function. Supported only for Version > 1 + uint32_t num_xe_cores; ///< [out] Number of Xe Cores. Supported only for Version > 2 char reserved[CTL_MAX_RESERVED_SIZE]; ///< [out] Reserved } ctl_device_adapter_properties_t; @@ -1169,10 +1195,6 @@ typedef struct _ctl_sw_psr_settings_t ctl_sw_psr_settings_t; /// @brief Forward-declare ctl_intel_arc_sync_monitor_params_t typedef struct _ctl_intel_arc_sync_monitor_params_t ctl_intel_arc_sync_monitor_params_t; -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_mux_properties_t -typedef struct _ctl_mux_properties_t ctl_mux_properties_t; - /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ctl_intel_arc_sync_profile_params_t typedef struct _ctl_intel_arc_sync_profile_params_t ctl_intel_arc_sync_profile_params_t; @@ -1229,6 +1251,26 @@ typedef struct _ctl_lda_args_t ctl_lda_args_t; /// @brief Forward-declare ctl_dce_args_t typedef struct _ctl_dce_args_t ctl_dce_args_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_wire_format_t +typedef struct _ctl_wire_format_t ctl_wire_format_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_get_set_wire_format_config_t +typedef struct _ctl_get_set_wire_format_config_t ctl_get_set_wire_format_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_display_settings_t +typedef struct _ctl_display_settings_t ctl_display_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_ecc_properties_t +typedef struct _ctl_ecc_properties_t ctl_ecc_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_ecc_state_desc_t +typedef struct _ctl_ecc_state_desc_t ctl_ecc_state_desc_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ctl_engine_properties_t typedef struct _ctl_engine_properties_t ctl_engine_properties_t; @@ -1257,6 +1299,14 @@ typedef struct _ctl_fan_properties_t ctl_fan_properties_t; /// @brief Forward-declare ctl_fan_config_t typedef struct _ctl_fan_config_t ctl_fan_config_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_firmware_properties_t +typedef struct _ctl_firmware_properties_t ctl_firmware_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_firmware_component_properties_t +typedef struct _ctl_firmware_component_properties_t ctl_firmware_component_properties_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ctl_freq_properties_t typedef struct _ctl_freq_properties_t ctl_freq_properties_t; @@ -1273,6 +1323,18 @@ typedef struct _ctl_freq_state_t ctl_freq_state_t; /// @brief Forward-declare ctl_freq_throttle_time_t typedef struct _ctl_freq_throttle_time_t ctl_freq_throttle_time_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_led_properties_t +typedef struct _ctl_led_properties_t ctl_led_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_led_color_t +typedef struct _ctl_led_color_t ctl_led_color_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_led_state_t +typedef struct _ctl_led_state_t ctl_led_state_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ctl_video_processing_super_resolution_info_t typedef struct _ctl_video_processing_super_resolution_info_t ctl_video_processing_super_resolution_info_t; @@ -1361,6 +1423,10 @@ typedef struct _ctl_psu_info_t ctl_psu_info_t; /// @brief Forward-declare ctl_power_telemetry_t typedef struct _ctl_power_telemetry_t ctl_power_telemetry_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_voltage_frequency_point_t +typedef struct _ctl_voltage_frequency_point_t ctl_voltage_frequency_point_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ctl_pci_address_t typedef struct _ctl_pci_address_t ctl_pci_address_t; @@ -1445,6 +1511,9 @@ typedef enum _ctl_3d_feature_t CTL_3D_FEATURE_EMULATED_TYPED_64BIT_ATOMICS = 13, ///< Emulated Typed 64bit Atomics support in DG2 CTL_3D_FEATURE_VRR_WINDOWED_BLT = 14, ///< VRR windowed blt. Control VRR for windowed mode game CTL_3D_FEATURE_GLOBAL_OR_PER_APP = 15, ///< Set global settings or per application settings + CTL_3D_FEATURE_LOW_LATENCY = 16, ///< Low latency mode. Contains generic enum type fields + CTL_3D_FEATURE_FRAME_GENERATION = 17, ///< Frame Generation + CTL_3D_FEATURE_PREBUILT_SHADER_DOWNLOAD = 18, ///< Download prebuilt shaders. Contains generic bool type fields CTL_3D_FEATURE_MAX } ctl_3d_feature_t; @@ -1454,10 +1523,11 @@ typedef enum _ctl_3d_feature_t typedef uint32_t ctl_3d_feature_misc_flags_t; typedef enum _ctl_3d_feature_misc_flag_t { - CTL_3D_FEATURE_MISC_FLAG_DX11 = CTL_BIT(0), ///< Feature supported on DX11 - CTL_3D_FEATURE_MISC_FLAG_DX12 = CTL_BIT(1), ///< Feature supported on DX12 - CTL_3D_FEATURE_MISC_FLAG_VULKAN = CTL_BIT(2), ///< Feature supported on VULKAN - CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE = CTL_BIT(3), ///< User can change feature live without restarting the game + CTL_3D_FEATURE_MISC_FLAG_DX9 = CTL_BIT(0), ///< Feature supported on DX9 + CTL_3D_FEATURE_MISC_FLAG_DX11 = CTL_BIT(1), ///< Feature supported on DX11 + CTL_3D_FEATURE_MISC_FLAG_DX12 = CTL_BIT(2), ///< Feature supported on DX12 + CTL_3D_FEATURE_MISC_FLAG_VULKAN = CTL_BIT(3), ///< Feature supported on VULKAN + CTL_3D_FEATURE_MISC_FLAG_LIVE_CHANGE = CTL_BIT(4), ///< User can change feature live without restarting the game CTL_3D_FEATURE_MISC_FLAG_MAX = 0x80000000 } ctl_3d_feature_misc_flag_t; @@ -1520,6 +1590,17 @@ typedef enum _ctl_3d_endurance_gaming_mode_t } ctl_3d_endurance_gaming_mode_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Low latency mode values possible +typedef enum _ctl_3d_low_latency_types_t +{ + CTL_3D_LOW_LATENCY_TYPES_TURN_OFF = 0, ///< Low latency mode disable + CTL_3D_LOW_LATENCY_TYPES_TURN_ON = 1, ///< Low latency mode enable + CTL_3D_LOW_LATENCY_TYPES_TURN_ON_BOOST_MODE_ON = 2, ///< Low latency mode enable with boost + CTL_3D_LOW_LATENCY_TYPES_MAX + +} ctl_3d_low_latency_types_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Cmaa values possible typedef enum _ctl_3d_cmaa_types_t @@ -1571,11 +1652,14 @@ typedef uint32_t ctl_gaming_flip_mode_flags_t; typedef enum _ctl_gaming_flip_mode_flag_t { CTL_GAMING_FLIP_MODE_FLAG_APPLICATION_DEFAULT = CTL_BIT(0), ///< Application Default - CTL_GAMING_FLIP_MODE_FLAG_VSYNC_OFF = CTL_BIT(1), ///< Convert all sync flips to async on the next possible scanline. + CTL_GAMING_FLIP_MODE_FLAG_VSYNC_OFF = CTL_BIT(1), ///< Convert all sync flips to async on the next possible scanline for + ///< Intel Verified application profile. CTL_GAMING_FLIP_MODE_FLAG_VSYNC_ON = CTL_BIT(2),///< Convert all async flips to sync flips. CTL_GAMING_FLIP_MODE_FLAG_SMOOTH_SYNC = CTL_BIT(3), ///< Reduce tearing effect with async flips CTL_GAMING_FLIP_MODE_FLAG_SPEED_FRAME = CTL_BIT(4), ///< Application unaware triple buffering CTL_GAMING_FLIP_MODE_FLAG_CAPPED_FPS = CTL_BIT(5), ///< Limit the game FPS to panel RR + CTL_GAMING_FLIP_MODE_FLAG_VSYNC_OFF_IGNORE_ALLOW_LIST = CTL_BIT(6), ///< Convert all sync flips to async on the next possible scanline without + ///< application filtering. CTL_GAMING_FLIP_MODE_FLAG_MAX = 0x80000000 } ctl_gaming_flip_mode_flag_t; @@ -2029,6 +2113,8 @@ typedef enum _ctl_std_display_feature_flag_t CTL_STD_DISPLAY_FEATURE_FLAG_VESA_COMPRESSION = CTL_BIT(4), ///< [out] Is display compression (VESA DSC) supported CTL_STD_DISPLAY_FEATURE_FLAG_HDR = CTL_BIT(5), ///< [out] Is HDR supported CTL_STD_DISPLAY_FEATURE_FLAG_HDMI_QMS = CTL_BIT(6), ///< [out] Is HDMI QMS supported + CTL_STD_DISPLAY_FEATURE_FLAG_HDR10_PLUS_CERTIFIED = CTL_BIT(7), ///< [out] Is HDR10+ certified + CTL_STD_DISPLAY_FEATURE_FLAG_VESA_HDR_CERTIFIED = CTL_BIT(8), ///< [out] Is VESA HDR certified - for future use CTL_STD_DISPLAY_FEATURE_FLAG_MAX = 0x80000000 } ctl_std_display_feature_flag_t; @@ -2042,6 +2128,7 @@ typedef enum _ctl_intel_display_feature_flag_t CTL_INTEL_DISPLAY_FEATURE_FLAG_DPST = CTL_BIT(0), ///< [out] Is DPST supported CTL_INTEL_DISPLAY_FEATURE_FLAG_LACE = CTL_BIT(1), ///< [out] Is LACE supported CTL_INTEL_DISPLAY_FEATURE_FLAG_DRRS = CTL_BIT(2), ///< [out] Is DRRS supported + CTL_INTEL_DISPLAY_FEATURE_FLAG_ARC_ADAPTIVE_SYNC_CERTIFIED = CTL_BIT(3),///< [out] Is Intel Arc certified adaptive sync display CTL_INTEL_DISPLAY_FEATURE_FLAG_MAX = 0x80000000 } ctl_intel_display_feature_flag_t; @@ -2452,6 +2539,10 @@ typedef enum _ctl_i2c_flag_t CTL_I2C_FLAG_SPEED_FAST = CTL_BIT(5), ///< If no Speed Flag is set, defaults to Best Option possible. CTL_I2C_FLAG_SPEED_BIT_BASH = CTL_BIT(6), ///< Uses Slower access using SW bit bashing method. If no Speed Flag is ///< set, defaults to Best Option possible. + CTL_I2C_FLAG_DRIVER_OVERRIDE = CTL_BIT(7), ///< If set, overrides the driver I2C flags with those provided by IGCL + CTL_I2C_FLAG_START = CTL_BIT(8), ///< I2C Start driver override flag + CTL_I2C_FLAG_STOP = CTL_BIT(9), ///< I2C Stop driver override flags + CTL_I2C_FLAG_RESTART = CTL_BIT(10), ///< I2C Restart driver override flag CTL_I2C_FLAG_MAX = 0x80000000 } ctl_i2c_flag_t; @@ -2478,7 +2569,8 @@ typedef struct _ctl_i2c_access_args_t /// @brief I2C Access /// /// @details -/// - Interface to access I2C using display handle as identifier. +/// - Interface to access I2C using display handle as identifier. I2C +/// driver override flags are supported only for HDMI displays. /// /// @returns /// - CTL_RESULT_SUCCESS @@ -3406,14 +3498,21 @@ typedef struct _ctl_scaling_settings_t uint32_t Size; ///< [in] size of this structure uint8_t Version; ///< [in] version of this structure bool Enable; ///< [in,out] State of the scaler - ctl_scaling_type_flags_t ScalingType; ///< [in,out] Requested scaling types. Refer ::ctl_scaling_type_flag_t - uint32_t CustomScalingX; ///< [in,out] Custom Scaling X resolution - uint32_t CustomScalingY; ///< [in,out] Custom Scaling Y resolution + ctl_scaling_type_flags_t ScalingType; ///< [in,out] Requested scaling type. In Get call this field indicates + ///< 'currunt' scaling set. Refer ::ctl_scaling_type_flag_t + uint32_t CustomScalingX; ///< [in,out] Custom Scaling X in percentage. This is percentage of current + ///< OS resolution. Valid values are 0 to 100. Up to 11% of native + ///< resolution can be downscaled + uint32_t CustomScalingY; ///< [in,out] Custom Scaling Y in percentage. This is percentage of current + ///< OS resolution. Valid values are 0 to 100. Up to 11% of native + ///< resolution can be downscaled bool HardwareModeSet; ///< [in] Flag to indicate hardware modeset should be done to apply the ///< scaling.Setting this to true would result in a flash on the screen. If ///< this flag is set to false , API will request the OS to do a virtual ///< modeset , but the OS can ignore this request and do a hardware modeset ///< in some instances + ctl_scaling_type_flags_t PreferredScalingType; ///< [out] Indicates OS persisted scaling type. This field is only valid + ///< when version > 0. Refer ::ctl_scaling_type_flag_t } ctl_scaling_settings_t; @@ -3678,105 +3777,6 @@ ctlGetIntelArcSyncInfoForMonitor( ctl_intel_arc_sync_monitor_params_t* pIntelArcSyncMonitorParams ///< [in,out][release] Intel Arc Sync params for monitor ); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a MUX output instance -typedef struct _ctl_mux_output_handle_t *ctl_mux_output_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Enumerate Display MUX Devices on this system across adapters -/// -/// @details -/// - The application enumerates all MUX devices in the system -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hAPIHandle` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pCount` -/// + `nullptr == phMuxDevices` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEnumerateMuxDevices( - ctl_api_handle_t hAPIHandle, ///< [in][release] Applications should pass the Control API handle returned - ///< by the CtlInit function - uint32_t* pCount, ///< [in,out][release] pointer to the number of MUX device instances. If - ///< input count is zero, then the api will update the value with the total - ///< number of MUX devices available and return the Count value. If input - ///< count is non-zero, then the api will only retrieve the number of MUX Devices. - ///< If count is larger than the number of MUX devices available, then the - ///< api will update the value with the correct number of MUX devices available. - ctl_mux_output_handle_t* phMuxDevices ///< [out][range(0, *pCount)] array of MUX device instance handles - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display MUX device properties -typedef struct _ctl_mux_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint8_t MuxId; ///< [out] MUX ID of this MUX device enumerated - uint32_t Count; ///< [in,out] Pointer to the number of display output instances this MUX - ///< object can drive. If count is zero, then the api will update the value - ///< with the total - ///< number of outputs available. If count is non-zero, then the api will - ///< only retrieve the number of outputs. - ///< If count is larger than the number of display outputs MUX can drive, - ///< then the api will update the value with the correct number of display - ///< outputs MUX can driver. - ctl_display_output_handle_t* phDisplayOutputs; ///< [in,out][range(0, *pCount)] Array of display output instance handles - ///< this MUX device can drive - uint8_t IndexOfDisplayOutputOwningMux; ///< [out] [range(0, (Count-1))] This is the index into the - ///< phDisplayOutputs list to the display output which currently owns the - ///< MUX output. This doesn't mean display is active - -} ctl_mux_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Display Mux properties -/// -/// @details -/// - Get the propeties of the Mux device -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hMuxDevice` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pMuxProperties` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetMuxProperties( - ctl_mux_output_handle_t hMuxDevice, ///< [in] MUX device instance handle - ctl_mux_properties_t* pMuxProperties ///< [in,out] MUX device properties - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Switch Mux output -/// -/// @details -/// - Switches the MUX output -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hMuxDevice` -/// + `nullptr == hInactiveDisplayOutput` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSwitchMux( - ctl_mux_output_handle_t hMuxDevice, ///< [in] MUX device instance handle - ctl_display_output_handle_t hInactiveDisplayOutput ///< [out] Input selection for this MUX, which if active will drive the - ///< output of this MUX device. This should be one of the display output - ///< handles reported under this MUX device's properties. - ); - /////////////////////////////////////////////////////////////////////////////// /// @brief Intel Arc Sync profile typedef enum _ctl_intel_arc_sync_profile_t @@ -4373,7 +4373,10 @@ typedef struct _ctl_dce_args_t /// /// @details /// - To get the DCE feature status and, if feature is enabled, returns the -/// current histogram, or to set the brightness at the phase-in speed +/// current histogram, or to set the brightness at the phase-in speed. +/// This is a reserved capability. By default, DCE is not supported/will +/// not be enabled, need application to activate it, please contact Intel +/// for activation. /// /// @returns /// - CTL_RESULT_SUCCESS @@ -4398,182 +4401,532 @@ ctlGetSetDynamicContrastEnhancement( ctl_dce_args_t* pDceArgs ///< [in,out] Dynamic Contrast Enhancement arguments ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Color model +typedef enum _ctl_wire_format_color_model_t +{ + CTL_WIRE_FORMAT_COLOR_MODEL_RGB = 0, ///< Color model RGB + CTL_WIRE_FORMAT_COLOR_MODEL_YCBCR_420 = 1, ///< Color model YCBCR 420 + CTL_WIRE_FORMAT_COLOR_MODEL_YCBCR_422 = 2, ///< Color model YCBCR 422 + CTL_WIRE_FORMAT_COLOR_MODEL_YCBCR_444 = 3, ///< Color model YCBCR 444 + CTL_WIRE_FORMAT_COLOR_MODEL_MAX + +} ctl_wire_format_color_model_t; -#if !defined(__GNUC__) -#pragma endregion // display -#endif -// Intel 'ctlApi' for Device Adapter - Engine groups -#if !defined(__GNUC__) -#pragma region engine -#endif /////////////////////////////////////////////////////////////////////////////// -/// @brief Accelerator engine groups -typedef enum _ctl_engine_group_t +/// @brief Operation type +typedef enum _ctl_wire_format_operation_type_t { - CTL_ENGINE_GROUP_GT = 0, ///< Access information about all engines combined. - CTL_ENGINE_GROUP_RENDER = 1, ///< Access information about all render and compute engines combined. - CTL_ENGINE_GROUP_MEDIA = 2, ///< Access information about all media engines combined. - CTL_ENGINE_GROUP_MAX + CTL_WIRE_FORMAT_OPERATION_TYPE_GET = 0, ///< Get request + CTL_WIRE_FORMAT_OPERATION_TYPE_SET = 1, ///< Set request + CTL_WIRE_FORMAT_OPERATION_TYPE_RESTORE_DEFAULT = 2, ///< Restore to default values + CTL_WIRE_FORMAT_OPERATION_TYPE_MAX -} ctl_engine_group_t; +} ctl_wire_format_operation_type_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Engine group properties -typedef struct _ctl_engine_properties_t +/// @brief Wire Format +typedef struct _ctl_wire_format_t { uint32_t Size; ///< [in] size of this structure uint8_t Version; ///< [in] version of this structure - ctl_engine_group_t type; ///< [out] The engine group + ctl_wire_format_color_model_t ColorModel; ///< [in,out] Color model + ctl_output_bpc_flags_t ColorDepth; ///< [in,out] Color Depth -} ctl_engine_properties_t; +} ctl_wire_format_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Engine activity counters -/// -/// @details -/// - Percent utilization is calculated by taking two snapshots (s1, s2) and -/// using the equation: %util = (s2.activeTime - s1.activeTime) / -/// (s2.timestamp - s1.timestamp) -typedef struct _ctl_engine_stats_t +#ifndef CTL_MAX_WIREFORMAT_COLOR_MODELS_SUPPORTED +/// @brief Maximum Wire Formats Supported +#define CTL_MAX_WIREFORMAT_COLOR_MODELS_SUPPORTED 4 +#endif // CTL_MAX_WIREFORMAT_COLOR_MODELS_SUPPORTED + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Set Wire Format +typedef struct _ctl_get_set_wire_format_config_t { uint32_t Size; ///< [in] size of this structure uint8_t Version; ///< [in] version of this structure - uint64_t activeTime; ///< [out] Monotonic counter for time in microseconds that this resource is - ///< actively running workloads. - uint64_t timestamp; ///< [out] Monotonic timestamp counter in microseconds when activeTime - ///< counter was sampled. - ///< This timestamp should only be used to calculate delta time between - ///< snapshots of this structure. - ///< Never take the delta of this timestamp with the timestamp from a - ///< different structure since they are not guaranteed to have the same base. - ///< The absolute value of the timestamp is only valid during within the - ///< application and may be different on the next execution. + ctl_wire_format_operation_type_t Operation; ///< [in] Get/Set Operation + ctl_wire_format_t SupportedWireFormat[CTL_MAX_WIREFORMAT_COLOR_MODELS_SUPPORTED]; ///< [out] Array of WireFormats supported + ctl_wire_format_t WireFormat; ///< [in,out] Current/Requested WireFormat based on Operation. During SET + ///< Operation, if multiple bpc is set, the MIN bpc will be applied -} ctl_engine_stats_t; +} ctl_get_set_wire_format_config_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Get handle of engine groups +/// @brief Get/Set Color Format and Color Depth /// /// @details -/// - The application may call this function from simultaneous threads. -/// - The implementation of this function should be lock-free. +/// - Get and Set the Color Format and Color Depth of a target /// /// @returns /// - CTL_RESULT_SUCCESS /// - CTL_RESULT_ERROR_UNINITIALIZED /// - CTL_RESULT_ERROR_DEVICE_LOST /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDAhandle` +/// + `nullptr == hDisplayOutput` /// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pCount` +/// + `nullptr == pGetSetWireFormatSetting` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid data passed as argument, WireFormat is not supported" +/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_NULL_OS_DISPLAY_OUTPUT_HANDLE - "Null OS display output handle" +/// - ::CTL_RESULT_ERROR_NULL_OS_INTERFACE - "Null OS interface" +/// - ::CTL_RESULT_ERROR_NULL_OS_ADAPATER_HANDLE - "Null OS adapter handle" CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEnumEngineGroups( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter - uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. - ///< if count is zero, then the driver shall update the value with the - ///< total number of components of this type that are available. - ///< if count is greater than the number of components of this type that - ///< are available, then the driver shall update the value with the correct - ///< number of components. - ctl_engine_handle_t* phEngine ///< [in,out][optional][range(0, *pCount)] array of handle of components of - ///< this type. - ///< if count is less than the number of components of this type that are - ///< available, then the driver shall only retrieve that number of - ///< component handles. +ctlGetSetWireFormat( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_get_set_wire_format_config_t* pGetSetWireFormatSetting ///< [in][release] Get/Set Wire Format settings to be fetched/applied ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Get engine group properties -/// -/// @details -/// - The application may call this function from simultaneous threads. -/// - The implementation of this function should be lock-free. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hEngine` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEngineGetProperties( - ctl_engine_handle_t hEngine, ///< [in] Handle for the component. - ctl_engine_properties_t* pProperties ///< [in,out] The properties for the specified engine group. - ); +/// @brief Various display settings +typedef uint32_t ctl_display_setting_flags_t; +typedef enum _ctl_display_setting_flag_t +{ + CTL_DISPLAY_SETTING_FLAG_LOW_LATENCY = CTL_BIT(0), ///< Low latency + CTL_DISPLAY_SETTING_FLAG_SOURCE_TM = CTL_BIT(1),///< Source tone mapping + CTL_DISPLAY_SETTING_FLAG_CONTENT_TYPE = CTL_BIT(2), ///< Content type + CTL_DISPLAY_SETTING_FLAG_QUANTIZATION_RANGE = CTL_BIT(3), ///< Quantization range, full range or limited range + CTL_DISPLAY_SETTING_FLAG_PICTURE_AR = CTL_BIT(4), ///< Picture aspect ratio + CTL_DISPLAY_SETTING_FLAG_AUDIO = CTL_BIT(5), ///< Audio settings + CTL_DISPLAY_SETTING_FLAG_MAX = 0x80000000 + +} ctl_display_setting_flag_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Get the activity stats for an engine group +/// @brief Low latency setting +typedef enum _ctl_display_setting_low_latency_t +{ + CTL_DISPLAY_SETTING_LOW_LATENCY_DEFAULT = 0, ///< Default + CTL_DISPLAY_SETTING_LOW_LATENCY_DISABLED = 1, ///< Disabled + CTL_DISPLAY_SETTING_LOW_LATENCY_ENABLED = 2, ///< Enabled + CTL_DISPLAY_SETTING_LOW_LATENCY_MAX + +} ctl_display_setting_low_latency_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Source tone mapping setting +typedef enum _ctl_display_setting_sourcetm_t +{ + CTL_DISPLAY_SETTING_SOURCETM_DEFAULT = 0, ///< Default + CTL_DISPLAY_SETTING_SOURCETM_DISABLED = 1, ///< Disabled + CTL_DISPLAY_SETTING_SOURCETM_ENABLED = 2, ///< Enabled + CTL_DISPLAY_SETTING_SOURCETM_MAX + +} ctl_display_setting_sourcetm_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Content type settings +typedef enum _ctl_display_setting_content_type_t +{ + CTL_DISPLAY_SETTING_CONTENT_TYPE_DEFAULT = 0, ///< Default content type used by driver. Driver will use internal + ///< techniques to determine content type and indicate to panel + CTL_DISPLAY_SETTING_CONTENT_TYPE_DISABLED = 1, ///< Content type indication is disabled + CTL_DISPLAY_SETTING_CONTENT_TYPE_DESKTOP = 2, ///< Typical desktop with a mix of text and graphics + CTL_DISPLAY_SETTING_CONTENT_TYPE_MEDIA = 3, ///< Video or media content + CTL_DISPLAY_SETTING_CONTENT_TYPE_GAMING = 4, ///< Gaming content + CTL_DISPLAY_SETTING_CONTENT_TYPE_MAX + +} ctl_display_setting_content_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Quantization range +typedef enum _ctl_display_setting_quantization_range_t +{ + CTL_DISPLAY_SETTING_QUANTIZATION_RANGE_DEFAULT = 0, ///< Default based on video format + CTL_DISPLAY_SETTING_QUANTIZATION_RANGE_LIMITED_RANGE = 1, ///< Limited range + CTL_DISPLAY_SETTING_QUANTIZATION_RANGE_FULL_RANGE = 2, ///< Full range + CTL_DISPLAY_SETTING_QUANTIZATION_RANGE_MAX + +} ctl_display_setting_quantization_range_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Picture aspect ratio +typedef uint32_t ctl_display_setting_picture_ar_flags_t; +typedef enum _ctl_display_setting_picture_ar_flag_t +{ + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_DEFAULT = CTL_BIT(0), ///< Default picture aspect ratio + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_DISABLED = CTL_BIT(1), ///< Picture aspect ratio indication is explicitly disabled + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_AR_4_3 = CTL_BIT(2),///< Aspect ratio of 4:3 + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_AR_16_9 = CTL_BIT(3), ///< Aspect ratio of 16:9 + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_AR_64_27 = CTL_BIT(4), ///< Aspect ratio of 64:27 or 21:9 anamorphic + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_AR_256_135 = CTL_BIT(5),///< Aspect ratio of 256:135 + CTL_DISPLAY_SETTING_PICTURE_AR_FLAG_MAX = 0x80000000 + +} ctl_display_setting_picture_ar_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Audio settings +typedef enum _ctl_display_setting_audio_t +{ + CTL_DISPLAY_SETTING_AUDIO_DEFAULT = 0, ///< Default audio settings, always enumerated and enabled if display + ///< supports it + CTL_DISPLAY_SETTING_AUDIO_DISABLED = 1, ///< Forcefully disable display audio end point enumeration to OS + CTL_DISPLAY_SETTING_AUDIO_MAX + +} ctl_display_setting_audio_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set end display settings +typedef struct _ctl_display_settings_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool Set; ///< [in] Flag to indicate Set or Get operation. Default option for all + ///< features are reserved for Set=true calls, which will reset the setting + ///< to driver defaults. + ctl_display_setting_flags_t SupportedFlags; ///< [out] Display setting flags supported by the display. + ctl_display_setting_flags_t ControllableFlags; ///< [out] Display setting flags which can be controlled by the caller. + ///< Features which doesn't have this flag set cannot be changed by caller. + ctl_display_setting_flags_t ValidFlags; ///< [in,out] Display setting flags which caller can use to indicate the + ///< features it's interested in. This cannot have a bit set which is not + ///< supported by SupportedFlags and ControllableFlags. + ctl_display_setting_low_latency_t LowLatency; ///< [in,out] Low latency state of panel. For HDR10+ Gaming this need to be + ///< in ENABLED state. + ctl_display_setting_sourcetm_t SourceTM; ///< [in,out] Source tone mapping state known to panel. For HDR10+ Gaming + ///< this need to be in ENABLED state. + ctl_display_setting_content_type_t ContentType; ///< [in,out] Source content type known to panel. + ctl_display_setting_quantization_range_t QuantizationRange; ///< [in,out] Quantization range + ctl_display_setting_picture_ar_flags_t SupportedPictureAR; ///< [out] Supported Picture aspect ratios + ctl_display_setting_picture_ar_flag_t PictureAR;///< [in,out] Picture aspect ratio + ctl_display_setting_audio_t AudioSettings; ///< [in,out] Audio settings + uint32_t Reserved[25]; ///< [out] Reserved fields for future enumerations + +} ctl_display_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Display settings /// /// @details -/// - The application may call this function from simultaneous threads. -/// - The implementation of this function should be lock-free. +/// - To get/set end display settings like low latency, HDR10+ signaling +/// etc. which are controlled via info-frames/secondary data packets /// /// @returns /// - CTL_RESULT_SUCCESS /// - CTL_RESULT_ERROR_UNINITIALIZED /// - CTL_RESULT_ERROR_DEVICE_LOST /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hEngine` +/// + `nullptr == hDisplayOutput` /// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pStats` +/// + `nullptr == pDisplaySettings` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_NULL_OS_DISPLAY_OUTPUT_HANDLE - "Null OS display output handle" +/// - ::CTL_RESULT_ERROR_NULL_OS_INTERFACE - "Null OS interface" +/// - ::CTL_RESULT_ERROR_NULL_OS_ADAPATER_HANDLE - "Null OS adapter handle" +/// - ::CTL_RESULT_ERROR_KMD_CALL - "Kernel mode driver call failure" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid or Null handle passed" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEngineGetActivity( - ctl_engine_handle_t hEngine, ///< [in] Handle for the component. - ctl_engine_stats_t* pStats ///< [in,out] Will contain a snapshot of the engine group activity - ///< counters. +ctlGetSetDisplaySettings( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_display_settings_t* pDisplaySettings ///< [in,out] End display capabilities ); #if !defined(__GNUC__) -#pragma endregion // engine +#pragma endregion // display #endif -// Intel 'ctlApi' for Device Adapter- Fan management +// Intel 'ctlApi' for Device Adapter - ECC #if !defined(__GNUC__) -#pragma region fan +#pragma region ecc #endif /////////////////////////////////////////////////////////////////////////////// -/// @brief Fan resource speed mode -typedef enum _ctl_fan_speed_mode_t +/// @brief ECC properties. +typedef struct _ctl_ecc_properties_t { - CTL_FAN_SPEED_MODE_DEFAULT = 0, ///< The fan speed is operating using the hardware default settings - CTL_FAN_SPEED_MODE_FIXED = 1, ///< The fan speed is currently set to a fixed value - CTL_FAN_SPEED_MODE_TABLE = 2, ///< The fan speed is currently controlled dynamically by hardware based on - ///< a temp/speed table - CTL_FAN_SPEED_MODE_MAX + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool isSupported; ///< [out] Indicates if ECC support is available. + bool canControl; ///< [out] Indicates if software can control the ECC assuming the user has + ///< permissions. -} ctl_fan_speed_mode_t; +} ctl_ecc_properties_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Fan speed units -typedef enum _ctl_fan_speed_units_t +/// @brief ECC state. +typedef enum _ctl_ecc_state_t { - CTL_FAN_SPEED_UNITS_RPM = 0, ///< The fan speed is in units of revolutions per minute (rpm) - CTL_FAN_SPEED_UNITS_PERCENT = 1, ///< The fan speed is a percentage of the maximum speed of the fan - CTL_FAN_SPEED_UNITS_MAX + CTL_ECC_STATE_ECC_DEFAULT_STATE = 0, ///< ECC Default State + CTL_ECC_STATE_ECC_ENABLED_STATE = 1, ///< ECC Enabled State + CTL_ECC_STATE_ECC_DISABLED_STATE = 2, ///< ECC Disabled State + CTL_ECC_STATE_MAX -} ctl_fan_speed_units_t; +} ctl_ecc_state_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Fan speed -typedef struct _ctl_fan_speed_t +/// @brief ECC state descriptor. If the currentEccState is not equal to +/// pendingEccState, then system reboot is needed for the pendingEccState +/// to be applied. +typedef struct _ctl_ecc_state_desc_t { uint32_t Size; ///< [in] size of this structure uint8_t Version; ///< [in] version of this structure - int32_t speed; ///< [in,out] The speed of the fan. On output, a value of -1 indicates that - ///< there is no fixed fan speed setting. - ctl_fan_speed_units_t units; ///< [in,out] The units that the fan speed is expressed in. On output, if - ///< fan speed is -1 then units should be ignored. + ctl_ecc_state_t currentEccState; ///< [in,out] Indicates the ECC state. + ///< A valid input can be one of the ::ctl_ecc_state_t enum values. + ///< A valid output will be either CTL_ECC_STATE_ECC_ENABLED_STATE or CTL_ECC_STATE_ECC_DISABLED_STATE. + ctl_ecc_state_t pendingEccState; ///< [out] Indicates the pending ECC state from ctlEccSetState() call. A + ///< valid output will be either CTL_ECC_STATE_ECC_ENABLED_STATE or + ///< CTL_ECC_STATE_ECC_DISABLED_STATE. -} ctl_fan_speed_t; +} ctl_ecc_state_desc_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Fan temperature/speed pair -typedef struct _ctl_fan_temp_speed_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure +/// @brief Get ECC properties. +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDAhandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEccGetProperties( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_ecc_properties_t* pProperties ///< [in,out] Will contain ECC properties. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get ECC state. +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDAhandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pState` +/// - CTL_RESULT_ERROR_INVALID_ENUMERATION +/// + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->currentEccState` +/// + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->pendingEccState` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEccGetState( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_ecc_state_desc_t* pState ///< [in,out] Will contain the current ECC state and pending ECC state to + ///< be applied from previous ctlEccSetState() call. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set ECC state. Setting CTL_ECC_STATE_ECC_DEFAULT_STATE will reset the +/// ECC state to the factory settings. +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDAhandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pState` +/// - CTL_RESULT_ERROR_INVALID_ENUMERATION +/// + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->currentEccState` +/// + `::CTL_ECC_STATE_ECC_DISABLED_STATE < pState->pendingEccState` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEccSetState( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_ecc_state_desc_t* pState ///< [in,out] Will contain the new ECC state and pending ECC state from + ///< ctlEccSetState() call. + ///< New ECC State can be set only if isSupported is true and canControl is true. + ///< ctlEccGetState() can be called to determine if the currentEccState is + ///< not equal to pendingEccState, then system reboot is needed for the + ///< pendingEccState to be applied. + ); + + +#if !defined(__GNUC__) +#pragma endregion // ecc +#endif +// Intel 'ctlApi' for Device Adapter - Engine groups +#if !defined(__GNUC__) +#pragma region engine +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Accelerator engine groups +typedef enum _ctl_engine_group_t +{ + CTL_ENGINE_GROUP_GT = 0, ///< Access information about all engines combined. + CTL_ENGINE_GROUP_RENDER = 1, ///< Access information about all render and compute engines combined. + CTL_ENGINE_GROUP_MEDIA = 2, ///< Access information about all media engines combined. + CTL_ENGINE_GROUP_MAX + +} ctl_engine_group_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Engine group properties +typedef struct _ctl_engine_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_engine_group_t type; ///< [out] The engine group + +} ctl_engine_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Engine activity counters +/// +/// @details +/// - Percent utilization is calculated by taking two snapshots (s1, s2) and +/// using the equation: %util = (s2.activeTime - s1.activeTime) / +/// (s2.timestamp - s1.timestamp) +typedef struct _ctl_engine_stats_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint64_t activeTime; ///< [out] Monotonic counter for time in microseconds that this resource is + ///< actively running workloads. + uint64_t timestamp; ///< [out] Monotonic timestamp counter in microseconds when activeTime + ///< counter was sampled. + ///< This timestamp should only be used to calculate delta time between + ///< snapshots of this structure. + ///< Never take the delta of this timestamp with the timestamp from a + ///< different structure since they are not guaranteed to have the same base. + ///< The absolute value of the timestamp is only valid during within the + ///< application and may be different on the next execution. + +} ctl_engine_stats_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of engine groups +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDAhandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCount` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEnumEngineGroups( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< if count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< if count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_engine_handle_t* phEngine ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ///< this type. + ///< if count is less than the number of components of this type that are + ///< available, then the driver shall only retrieve that number of + ///< component handles. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get engine group properties +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hEngine` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEngineGetProperties( + ctl_engine_handle_t hEngine, ///< [in] Handle for the component. + ctl_engine_properties_t* pProperties ///< [in,out] The properties for the specified engine group. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the activity stats for an engine group +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hEngine` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pStats` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEngineGetActivity( + ctl_engine_handle_t hEngine, ///< [in] Handle for the component. + ctl_engine_stats_t* pStats ///< [in,out] Will contain a snapshot of the engine group activity + ///< counters. + ); + + +#if !defined(__GNUC__) +#pragma endregion // engine +#endif +// Intel 'ctlApi' for Device Adapter- Fan management +#if !defined(__GNUC__) +#pragma region fan +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan resource speed mode +typedef enum _ctl_fan_speed_mode_t +{ + CTL_FAN_SPEED_MODE_DEFAULT = 0, ///< The fan speed is operating using the hardware default settings + CTL_FAN_SPEED_MODE_FIXED = 1, ///< The fan speed is currently set to a fixed value + CTL_FAN_SPEED_MODE_TABLE = 2, ///< The fan speed is currently controlled dynamically by hardware based on + ///< a temp/speed table + CTL_FAN_SPEED_MODE_MAX + +} ctl_fan_speed_mode_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan speed units +typedef enum _ctl_fan_speed_units_t +{ + CTL_FAN_SPEED_UNITS_RPM = 0, ///< The fan speed is in units of revolutions per minute (rpm) + CTL_FAN_SPEED_UNITS_PERCENT = 1, ///< The fan speed is a percentage of the maximum speed of the fan + CTL_FAN_SPEED_UNITS_MAX + +} ctl_fan_speed_units_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan speed +typedef struct _ctl_fan_speed_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + int32_t speed; ///< [in,out] The speed of the fan. On output, a value of -1 indicates that + ///< there is no fixed fan speed setting. + ctl_fan_speed_units_t units; ///< [in,out] The units that the fan speed is expressed in. On output, if + ///< fan speed is -1 then units should be ignored. + +} ctl_fan_speed_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan temperature/speed pair +typedef struct _ctl_fan_temp_speed_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure uint32_t temperature; ///< [in,out] Temperature in degrees Celsius. ctl_fan_speed_t speed; ///< [in,out] The speed of the fan @@ -4812,35 +5165,229 @@ ctlFanGetState( #if !defined(__GNUC__) #pragma endregion // fan #endif -// Intel 'ctlApi' for Device Adapter - Frequency domains +// Intel 'ctlApi' for Device Adapter - Firmware management #if !defined(__GNUC__) -#pragma region frequency +#pragma region firmware #endif /////////////////////////////////////////////////////////////////////////////// -/// @brief Frequency domains. -typedef enum _ctl_freq_domain_t +#ifndef CTL_FIRMWARE_PROPERTY_STR_SIZE +/// @brief Maximum number of characters in firmware name/version string +#define CTL_FIRMWARE_PROPERTY_STR_SIZE 64 +#endif // CTL_FIRMWARE_PROPERTY_STR_SIZE + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle for a device firmware component +typedef struct _ctl_firmware_component_handle_t *ctl_firmware_component_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAX_FIRMWARE_PROPERTIES_RESERVED_SIZE +/// @brief Maximum reserved size for future firmware component property members. +#define CTL_MAX_FIRMWARE_PROPERTIES_RESERVED_SIZE 16 +#endif // CTL_MAX_FIRMWARE_PROPERTIES_RESERVED_SIZE + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAX_FIRMWARE_COMPONENT_PROPERTIES_RESERVED_SIZE +/// @brief Maximum reserved size for future firmware component property members. +#define CTL_MAX_FIRMWARE_COMPONENT_PROPERTIES_RESERVED_SIZE 20 +#endif // CTL_MAX_FIRMWARE_COMPONENT_PROPERTIES_RESERVED_SIZE + +/////////////////////////////////////////////////////////////////////////////// +/// @brief [out] Firmware configuration flags +typedef uint32_t ctl_firmware_config_flags_t; +typedef enum _ctl_firmware_config_flag_t { - CTL_FREQ_DOMAIN_GPU = 0, ///< GPU Core Domain. - CTL_FREQ_DOMAIN_MEMORY = 1, ///< Local Memory Domain. - CTL_FREQ_DOMAIN_MAX + CTL_FIRMWARE_CONFIG_FLAG_IS_DEVICE_LINK_SPEED_DOWNGRADE_CAPABLE = CTL_BIT(0), ///< [out] Is the device firmware capable of downgrading to lower PCIE link + ///< speed from higher PCIE link speeds automatically on incompatible hosts. + CTL_FIRMWARE_CONFIG_FLAG_IS_DEVICE_LINK_SPEED_DOWNGRADE_ACTIVE = CTL_BIT(1),///< [out] This bit indicates if the discrete GPU host was capable of + ///< running at higher PCIE link speeds but the card firmware failed to + ///< train PCIE link at higher speeds + ///< due to non-compliant hosts. So device firmware did a fall back to + ///< lower link speeds. + CTL_FIRMWARE_CONFIG_FLAG_MAX = 0x80000000 -} ctl_freq_domain_t; +} ctl_firmware_config_flag_t; /////////////////////////////////////////////////////////////////////////////// -/// @brief Frequency properties -typedef struct _ctl_freq_properties_t +/// @brief Base firmware properties +typedef struct _ctl_firmware_properties_t { uint32_t Size; ///< [in] size of this structure uint8_t Version; ///< [in] version of this structure - ctl_freq_domain_t type; ///< [out] The hardware block that this frequency domain controls (GPU, - ///< memory, ...) - bool canControl; ///< [out] Indicates if software can control the frequency of this domain - ///< assuming the user has permissions - double min; ///< [out] The minimum hardware clock frequency in units of MHz. - double max; ///< [out] The maximum non-overclock hardware clock frequency in units of - ///< MHz. + char name[CTL_FIRMWARE_PROPERTY_STR_SIZE]; ///< [out] NULL terminated string value for the name of the firmware + ///< component. 'unknown' will be returned if this property cannot be + ///< determined. + char version[CTL_FIRMWARE_PROPERTY_STR_SIZE]; ///< [out] NULL terminated string value for the device version of the + ///< firmware component. 'unknown' will be returned if this property cannot + ///< be determined. + ctl_firmware_config_flags_t FirmwareConfig; ///< [out] This bit indicates various firmware supported configurations and + ///< capabilities. + char reserved[CTL_MAX_FIRMWARE_PROPERTIES_RESERVED_SIZE]; ///< [out] Reserved -} ctl_freq_properties_t; +} ctl_firmware_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Individual firmware component properties +typedef struct _ctl_firmware_component_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + char name[CTL_FIRMWARE_PROPERTY_STR_SIZE]; ///< [out] NULL terminated string value for the name of the firmware + ///< component. 'unknown' will be returned if this property cannot be + ///< determined. + char version[CTL_FIRMWARE_PROPERTY_STR_SIZE]; ///< [out] NULL terminated string value for the device version of the + ///< firmware component. 'unknown' will be returned if this property cannot + ///< be determined. + char reserved[CTL_MAX_FIRMWARE_COMPONENT_PROPERTIES_RESERVED_SIZE]; ///< [out] Reserved + +} ctl_firmware_component_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get base firmware properties +/// +/// @details +/// - The application gets properties of base firmware +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceAdapter` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetFirmwareProperties( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_firmware_properties_t* pProperties ///< [in,out] Pointer to an array that will hold properties of the base + ///< firmware. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of various firmware components +/// +/// @details +/// - The application enumerates all firmware components on an Intel +/// Discrete Graphics device. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceAdapter` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCount` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid handle" +/// - ::CTL_RESULT_ERROR_KMD_CALL - "KMD call failed" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEnumerateFirmwareComponents( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< if count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< if count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_firmware_component_handle_t* phFirmware ///< [in,out][optional][release][range(0, *pCount)] array of handle of + ///< firmware components. + ///< If count is less than the number of firmware components that are + ///< available, then the driver shall only retrieve that number of firmware + ///< component handles. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get firmware component properties +/// +/// @details +/// - The application gets properties of individual firmware components +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hFirmware` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid handle" +/// - ::CTL_RESULT_ERROR_KMD_CALL - "KMD call failed" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetFirmwareComponentProperties( + ctl_firmware_component_handle_t hFirmware, ///< [in] Handle for the firmware component. + ctl_firmware_component_properties_t* pProperties///< [in,out] Pointer to an array that will hold properties of the firmware + ///< component. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Allows/Blocks discrete graphics device firmware's capability to train +/// PCI-E link at higher speeds on compatible compatible hosts +/// +/// @details +/// - This API allows caller to allow/block a compatible discrete graphics +/// card's firmware train PCIE links at higher speeds on compatible hosts. +/// - System needs to be powered off and restarted for the new state to take +/// affect. The new state will not be applied on only a warm reboot of the +/// system. +/// - This is a reserved capability. By default, this capability will not be +/// enabled, need application to activate it, please contact Intel for +/// activation. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceAdapter` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid handle" +/// - ::CTL_RESULT_ERROR_KMD_CALL - "KMD call failed" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlAllowPCIeLinkSpeedUpdate( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + bool AllowPCIeLinkSpeedUpdate ///< [in] When set configures the device firmware to train PCI-E link at + ///< higher speeds, else this will block the device firmware from training + ///< at higher PCI-E link speeds on compatible hosts. + ///< This API modifies a flash persistant setting of the device firmware to + ///< allow/block training PCI-E link at higher speeds. + ); + + +#if !defined(__GNUC__) +#pragma endregion // firmware +#endif +// Intel 'ctlApi' for Device Adapter - Frequency domains +#if !defined(__GNUC__) +#pragma region frequency +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Frequency domains. +typedef enum _ctl_freq_domain_t +{ + CTL_FREQ_DOMAIN_GPU = 0, ///< GPU Core Domain. + CTL_FREQ_DOMAIN_MEMORY = 1, ///< Local Memory Domain. + CTL_FREQ_DOMAIN_MEDIA = 2, ///< Media Domain + CTL_FREQ_DOMAIN_MAX + +} ctl_freq_domain_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Frequency properties +typedef struct _ctl_freq_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_freq_domain_t type; ///< [out] The hardware block that this frequency domain controls (GPU, + ///< memory, ...) + bool canControl; ///< [out] Indicates if software can control the frequency of this domain + ///< assuming the user has permissions + double min; ///< [out] The minimum hardware clock frequency in units of MHz. + double max; ///< [out] The maximum non-overclock hardware clock frequency in units of + ///< MHz. + +} ctl_freq_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Frequency range between which the hardware can operate. The limits can @@ -4852,14 +5399,17 @@ typedef struct _ctl_freq_range_t uint8_t Version; ///< [in] version of this structure double min; ///< [in,out] The min frequency in MHz below which hardware frequency ///< management will not request frequencies. On input, setting to 0 will - ///< permit the frequency to go down to the hardware minimum. On output, a - ///< negative value indicates that no external minimum frequency limit is - ///< in effect. + ///< permit the frequency to go down to the hardware minimum while setting + ///< to -1 will return the min frequency limit to the factory value (can be + ///< larger than the hardware min). On output, a negative value indicates + ///< that no external minimum frequency limit is in effect. double max; ///< [in,out] The max frequency in MHz above which hardware frequency ///< management will not request frequencies. On input, setting to 0 or a ///< very big number will permit the frequency to go all the way up to the - ///< hardware maximum. On output, a negative number indicates that no - ///< external maximum frequency limit is in effect. + ///< hardware maximum while setting to -1 will return the max frequency to + ///< the factory value (which can be less than the hardware max). On + ///< output, a negative number indicates that no external maximum frequency + ///< limit is in effect. } ctl_freq_range_t; @@ -5104,6 +5654,167 @@ ctlFrequencyGetThrottleTime( #if !defined(__GNUC__) #pragma endregion // frequency #endif +// Intel 'ctlApi' for Device Adapter - Led Control +#if !defined(__GNUC__) +#pragma region led +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Led properties +typedef struct _ctl_led_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool canControl; ///< [out] Indicates if software can control the Led assuming the user has + ///< permissions. + bool isI2C; ///< [out] Indicates support for control via I2C interface. + bool isPWM; ///< [out] Returns a valid value if canControl is true and isI2C is false. + ///< Indicates if the Led is PWM capable. If isPWM is false, only turn Led + ///< on/off is supported. + bool haveRGB; ///< [out] Returns a valid value if canControl is true and isI2C is false. + ///< Indicates if the Led is RGB capable. + +} ctl_led_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Led color +typedef struct _ctl_led_color_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + double red; ///< [in,out][range(0.0, 1.0)] The Led red value. On output, a value less + ///< than 0.0 indicates that the color is not known. + double green; ///< [in,out][range(0.0, 1.0)] The Led green value. On output, a value less + ///< than 0.0 indicates that the color is not known. + double blue; ///< [in,out][range(0.0, 1.0)] The Led blue value. On output, a value less + ///< than 0.0 indicates that the color is not known. + +} ctl_led_color_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Led state +typedef struct _ctl_led_state_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool isOn; ///< [in,out] Indicates if the Led is on or off. + double pwm; ///< [in,out] Led On/Off Ratio, PWM range(0.0, 1.0). A value greater than + ///< 1.0 is capped at 1.0. + ctl_led_color_t color; ///< [in,out] Color of the Led. + +} ctl_led_state_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of Leds +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDAhandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCount` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEnumLeds( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + uint32_t* pCount, ///< [in,out] pointer to the number of components of this type. + ///< If count is zero, then the driver shall update the value with the + ///< total number of components of this type that are available. + ///< If count is greater than the number of components of this type that + ///< are available, then the driver shall update the value with the correct + ///< number of components. + ctl_led_handle_t* phLed ///< [in,out][optional][range(0, *pCount)] array of handle of components of + ///< this type. + ///< If count is less than the number of components of this type that are + ///< available, then the driver shall only retrieve that number of + ///< component handles. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Led properties +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hLed` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlLedGetProperties( + ctl_led_handle_t hLed, ///< [in] Handle for the component. + ctl_led_properties_t* pProperties ///< [in,out] Will contain Led properties. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Led state +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hLed` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pState` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlLedGetState( + ctl_led_handle_t hLed, ///< [in] Handle for the component. + ctl_led_state_t* pState ///< [in,out] Will contain the current Led state. + ///< Returns Led state if canControl is true and isI2C is false. + ///< pwm and color structure members of ::ctl_led_state_t will be returned + ///< only if supported by Led, else they will be returned as 0. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Led state +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// - This API is rate-limited by 500 milliseconds, If this API is called +/// too frequently ::CTL_ERROR_CORE_LED_TOO_FREQUENT_SET_REQUESTS error +/// will be returned +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hLed` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pBuffer` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlLedSetState( + ctl_led_handle_t hLed, ///< [in] Handle for the component. + void* pBuffer, ///< [in] Led State buffer. + ///< If isI2C is true, the pBuffer and bufferSize will be passed to the I2C + ///< Interface. pBuffer format in this case is OEM defined. + ///< If isI2C is false, the pBuffer will be typecasted to + ///< ::ctl_led_state_t* and bufferSize needs to be sizeof + ///< ::ctl_led_state_t. pwm and color structure members of + ///< ::ctl_led_state_t will be set only if supported by Led, else they will + ///< be ignored. + uint32_t bufferSize ///< [in] Led State buffer size. + ); + + +#if !defined(__GNUC__) +#pragma endregion // led +#endif // Intel 'ctlApi' for Device Adapter #if !defined(__GNUC__) #pragma region media @@ -5699,12 +6410,18 @@ typedef struct _ctl_oc_properties_t uint32_t Size; ///< [in] size of this structure uint8_t Version; ///< [in] version of this structure bool bSupported; ///< [out] Indicates if the adapter supports overclocking. - ctl_oc_control_info_t gpuFrequencyOffset; ///< [out] related to function ::ctlOverclockGpuFrequencyOffsetSet - ctl_oc_control_info_t gpuVoltageOffset; ///< [out] related to function ::ctlOverclockGpuVoltageOffsetSet + ctl_oc_control_info_t gpuFrequencyOffset; ///< [out] related to function ::ctlOverclockGpuFrequencyOffsetSetV2 + ctl_oc_control_info_t gpuVoltageOffset; ///< [out] related to function ::ctlOverclockGpuMaxVoltageOffsetSetV2 ctl_oc_control_info_t vramFrequencyOffset; ///< [out] Property Field Deprecated / No Longer Supported ctl_oc_control_info_t vramVoltageOffset; ///< [out] Property Field Deprecated / No Longer Supported - ctl_oc_control_info_t powerLimit; ///< [out] related to function ::ctlOverclockPowerLimitSet - ctl_oc_control_info_t temperatureLimit; ///< [out] related to function ::ctlOverclockTemperatureLimitSet + ctl_oc_control_info_t powerLimit; ///< [out] related to function ::ctlOverclockPowerLimitSetV2 + ctl_oc_control_info_t temperatureLimit; ///< [out] related to function ::ctlOverclockTemperatureLimitSetV2 + ctl_oc_control_info_t vramMemSpeedLimit; ///< [out] related to function ::ctlOverclockVramMemSpeedLimitSetV2 + ///< Supported only for Version > 0 + ctl_oc_control_info_t gpuVFCurveVoltageLimit; ///< [out] related to function ::ctlOverclockWriteCustomVFCurve Supported + ///< only for Version > 0 + ctl_oc_control_info_t gpuVFCurveFrequencyLimit; ///< [out] related to function ::ctlOverclockWriteCustomVFCurve Supported + ///< only for Version > 0 } ctl_oc_properties_t; @@ -5793,20 +6510,20 @@ typedef struct _ctl_power_telemetry_t ///< percentage utilization of all media blocks in the GPU. bool gpuPowerLimited; ///< [out] Instantaneous indication that the desired GPU frequency is being ///< throttled because the GPU chip is exceeding the maximum power limits. - ///< Increasing the power limits using ::ctlOverclockPowerLimitSet() is one - ///< way to remove this limitation. + ///< Increasing the power limits using ::ctlOverclockPowerLimitSetV2() is + ///< one way to remove this limitation. bool gpuTemperatureLimited; ///< [out] Instantaneous indication that the desired GPU frequency is being ///< throttled because the GPU chip is exceeding the temperature limits. ///< Increasing the temperature limits using - ///< ::ctlOverclockTemperatureLimitSet() is one way to reduce this + ///< ::ctlOverclockTemperatureLimitSetV2() is one way to reduce this ///< limitation. Improving the cooling solution is another way. bool gpuCurrentLimited; ///< [out] Instantaneous indication that the desired GPU frequency is being ///< throttled because the GPU chip has exceeded the power supply current ///< limits. A better power supply is required to reduce this limitation. bool gpuVoltageLimited; ///< [out] Instantaneous indication that the GPU frequency cannot be ///< increased because the voltage limits have been reached. Increase the - ///< voltage offset using ::ctlOverclockGpuVoltageOffsetSet() is one way to - ///< reduce this limitation. + ///< voltage offset using ::ctlOverclockGpuMaxVoltageOffsetSetV2() is one + ///< way to reduce this limitation. bool gpuUtilizationLimited; ///< [out] Instantaneous indication that due to lower GPU utilization, the ///< hardware has lowered the GPU frequency. ctl_oc_telemetry_item_t vramEnergyCounter; ///< [out] Snapshot of the monotonic energy counter maintained by hardware. @@ -5827,24 +6544,33 @@ typedef struct _ctl_power_telemetry_t ///< the write traffic to the memory modules. By taking the delta between ///< two snapshots and dividing by the delta time in seconds, an ///< application can compute the average write bandwidth. - ctl_oc_telemetry_item_t vramCurrentTemperature; ///< [out] Instantaneous snapshot of the GPU chip temperature, read from - ///< the sensor reporting the highest value. - bool vramPowerLimited; ///< [out] Instantaneous indication that the memory frequency is being - ///< throttled because the memory modules are exceeding the maximum power - ///< limits. - bool vramTemperatureLimited; ///< [out] Instantaneous indication that the memory frequency is being - ///< throttled because the memory modules are exceeding the temperature - ///< limits. - bool vramCurrentLimited; ///< [out] Instantaneous indication that the memory frequency is being - ///< throttled because the memory modules have exceeded the power supply - ///< current limits. - bool vramVoltageLimited; ///< [out] Instantaneous indication that the memory frequency cannot be - ///< increased because the voltage limits have been reached. - bool vramUtilizationLimited; ///< [out] Instantaneous indication that due to lower memory traffic, the - ///< hardware has lowered the memory frequency. + ctl_oc_telemetry_item_t vramCurrentTemperature; ///< [out] Instantaneous snapshot of the memory modules temperature, read + ///< from the sensor reporting the highest value. + bool vramPowerLimited; ///< [out] Deprecated / Not-supported, will always returns false + bool vramTemperatureLimited; ///< [out] Deprecated / Not-supported, will always returns false + bool vramCurrentLimited; ///< [out] Deprecated / Not-supported, will always returns false + bool vramVoltageLimited; ///< [out] Deprecated / Not-supported, will always returns false + bool vramUtilizationLimited; ///< [out] Deprecated / Not-supported, will always returns false ctl_oc_telemetry_item_t totalCardEnergyCounter; ///< [out] Total Card Energy Counter. ctl_psu_info_t psu[CTL_PSU_COUNT]; ///< [out] PSU voltage and power. ctl_oc_telemetry_item_t fanSpeed[CTL_FAN_COUNT];///< [out] Fan speed. + ctl_oc_telemetry_item_t gpuVrTemp; ///< [out] GPU VR temperature. Supported for Version > 0. + ctl_oc_telemetry_item_t vramVrTemp; ///< [out] VRAM VR temperature. Supported for Version > 0. + ctl_oc_telemetry_item_t saVrTemp; ///< [out] SA VR temperature. Supported for Version > 0. + ctl_oc_telemetry_item_t gpuEffectiveClock; ///< [out] Effective frequency of the GPU. Supported for Version > 0. + ctl_oc_telemetry_item_t gpuOverVoltagePercent; ///< [out] OverVoltage as a percent between 0 and 100. Positive values + ///< represent fraction of the maximum over-voltage increment being + ///< currently applied. Zero indicates operation at or below default + ///< maximum frequency. Supported for Version > 0. + ctl_oc_telemetry_item_t gpuPowerPercent; ///< [out] GPUPower expressed as a percent representing the fraction of the + ///< default maximum power being drawn currently. Values greater than 100 + ///< indicate power draw beyond default limits. Values above OC Power limit + ///< imply throttling due to power. Supported for Version > 0. + ctl_oc_telemetry_item_t gpuTemperaturePercent; ///< [out] GPUTemperature expressed as a percent of the thermal margin. + ///< Values of 100 or greater indicate thermal throttling and 0 indicates + ///< device at 0 degree Celcius. Supported for Version > 0. + ctl_oc_telemetry_item_t vramReadBandwidth; ///< [out] VRAM Read Bandwidth. Supported for Version > 0. + ctl_oc_telemetry_item_t vramWriteBandwidth; ///< [out] VRAM Write Bandwidth. Supported for Version > 0. } ctl_power_telemetry_t; @@ -6138,52 +6864,389 @@ ctlOverclockVramFrequencyOffsetGet( /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDeviceHandle` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockVramFrequencyOffsetSet( +ctlOverclockVramFrequencyOffsetSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double ocFrequencyOffset ///< [in] The desired Memory Frequency in GT/s. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the Overclock Vram Voltage Offset in mV. +/// +/// @details +/// - The purpose of this function is to increase/decrease the voltage of +/// VRAM. +/// - The voltage offset is expressed in units of millivolts with a minimum +/// step size given by ::ctlOverclockGetProperties. +/// - The waiver must be set using ::ctlOverclockWaiverSet before this +/// function can be called. +/// - This setting is not persistent through system reboots or driver +/// resets/hangs. It is up to the overclock application to reapply the +/// settings in those cases. +/// - This setting can cause system/device instability. It is up to the +/// overclock application to detect if the system has rebooted +/// unexpectedly or the device was restarted. When this occurs, the +/// application should not reapply the overclock settings automatically +/// but instead return to previously known good settings or notify the +/// user that the settings are not being applied. +/// - If the memory controller doesn't support changes to voltage on the +/// fly, one of the following return codes will be given: +/// - ::CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory +/// overclock will be applied when the device is reset or the system is +/// rebooted. In this case, the overclock software should check if the +/// overclock request was applied after the reset/reboot. If it was and +/// when the overclock application shuts down gracefully and if the +/// overclock application wants the setting to be persistent, the +/// application should request the same overclock settings again so that +/// they will be applied on the next reset/reboot. If this is not done, +/// then every time the device is reset and overclock is requested, the +/// device needs to be reset a second time. +/// - ::CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory +/// overclock will be applied when the system is rebooted. In this case, +/// the overclock software should check if the overclock request was +/// applied after the reboot. If it was and when the overclock application +/// shuts down gracefully and if the overclock application wants the +/// setting to be persistent, the application should request the same +/// overclock settings again so that they will be applied on the next +/// reset/reboot. If this is not done and the overclock setting is +/// requested after the reboot has occurred, a second reboot will be +/// required. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pVoltage` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockVramVoltageOffsetGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pVoltage ///< [out] The current locked voltage in mV. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the Overclock Vram Voltage Offset in mV. +/// +/// @details +/// - The purpose of this function is to set the maximum sustained power +/// limit. If the average GPU power averaged over a few seconds exceeds +/// this value, the frequency of the GPU will be throttled. +/// - Set a value of 0 to disable this power limit. In this case, the GPU +/// frequency will not throttle due to average power but may hit other +/// limits. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockVramVoltageOffsetSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double voltage ///< [in] The voltage to be locked in mV. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the sustained power limit in mW. +/// +/// @details +/// - The purpose of this function is to read the current sustained power +/// limit. +/// - A value of 0 means that the limit is disabled - the GPU frequency can +/// run as high as possible until other limits are hit. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSustainedPowerLimit` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockPowerLimitGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pSustainedPowerLimit ///< [in,out] The current sustained power limit in mW. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the sustained power limit in mW. +/// +/// @details +/// - The purpose of this function is to set the maximum sustained power +/// limit. If the average GPU power averaged over a few seconds exceeds +/// this value, the frequency of the GPU will be throttled. +/// - Set a value of 0 to disable this power limit. In this case, the GPU +/// frequency will not throttle due to average power but may hit other +/// limits. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockPowerLimitSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double sustainedPowerLimit ///< [in] The desired sustained power limit in mW. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the current temperature limit in Celsius. +/// +/// @details +/// - The purpose of this function is to read the current thermal limit. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pTemperatureLimit` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockTemperatureLimitGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pTemperatureLimit ///< [in,out] The current temperature limit in Celsius. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the temperature limit in Celsius. +/// +/// @details +/// - The purpose of this function is to change the maximum thermal limit. +/// When the GPU temperature exceeds this value, the GPU frequency will be +/// throttled. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockTemperatureLimitSet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double temperatureLimit ///< [in] The desired temperature limit in Celsius. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Power Telemetry. +/// +/// @details +/// - Limited rate of 50 ms, any call under 50 ms will return the same +/// information. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pTelemetryInfo` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPowerTelemetryGet( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + ctl_power_telemetry_t* pTelemetryInfo ///< [out] The overclocking properties for the specified domain. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reset all Overclock Settings to stock +/// +/// @details +/// - Reset all Overclock setting to default using single API call +/// - This request resets any changes made to GpuFrequencyOffset, +/// GpuVoltageOffset, PowerLimit, TemperatureLimit, GpuLock +/// - This Doesn't reset any Fan Curve Changes. It can be reset using +/// ctlFanSetDefaultMode +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockResetToDefault( + ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief VF Curve Detail +typedef enum _ctl_vf_curve_details_t +{ + CTL_VF_CURVE_DETAILS_SIMPLIFIED = 0, ///< Read minimum num of VF points for simplified VF curve view + CTL_VF_CURVE_DETAILS_MEDIUM = 1, ///< Read medium num of VF points for more points than simplified view + CTL_VF_CURVE_DETAILS_ELABORATE = 2, ///< Read Maximum num of VF points for detailed VF curve View + CTL_VF_CURVE_DETAILS_MAX + +} ctl_vf_curve_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief VF Curve type +typedef enum _ctl_vf_curve_type_t +{ + CTL_VF_CURVE_TYPE_STOCK = 0, ///< Read default VF curve + CTL_VF_CURVE_TYPE_LIVE = 1, ///< Read Live VF Curve + CTL_VF_CURVE_TYPE_MAX + +} ctl_vf_curve_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Overclock Voltage Frequency Point +typedef struct _ctl_voltage_frequency_point_t +{ + uint32_t Voltage; ///< [in][out] in milliVolts + uint32_t Frequency; ///< [in][out] in MHz + +} ctl_voltage_frequency_point_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the Current Overclock GPU Frequency Offset +/// +/// @details +/// - Determine the current frequency offset in effect (refer to +/// ::ctlOverclockGpuFrequencyOffsetSetV2() for details). +/// - The unit of the value returned is given in +/// ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from +/// ::ctlOverclockGetProperties() +/// - The unit of the value returned can be different for different +/// generation of graphics product +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pOcFrequencyOffset` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockGpuFrequencyOffsetGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pOcFrequencyOffset ///< [in,out] Current GPU Overclock Frequency Offset in units given in + ///< ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from + ///< ::ctlOverclockGetProperties() + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the Overclock Frequency Offset for the GPU +/// +/// @details +/// - The purpose of this function is to increase/decrease the frequency +/// offset at which typical workloads will run within the same thermal +/// budget. +/// - The frequency offset is expressed in units given in +/// ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from +/// ::ctlOverclockGetProperties() +/// - The actual operating frequency for each workload is not guaranteed to +/// change exactly by the specified offset. +/// - For positive frequency offsets, the factory maximum frequency may +/// increase by up to the specified amount. +/// - Specifying large values for the frequency offset can lead to +/// instability. It is recommended that changes are made in small +/// increments and stability/performance measured running intense GPU +/// workloads before increasing further. +/// - This setting is not persistent through system reboots or driver +/// resets/hangs. It is up to the overclock application to reapply the +/// settings in those cases. +/// - This setting can cause system/device instability. It is up to the +/// overclock application to detect if the system has rebooted +/// unexpectedly or the device was restarted. When this occurs, the +/// application should not reapply the overclock settings automatically +/// but instead return to previously known good settings or notify the +/// user that the settings are not being applied. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockGpuFrequencyOffsetSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double ocFrequencyOffset ///< [in] The GPU Overclocking Frequency Offset Desired in units given in + ///< ::ctl_oc_properties_t::gpuFrequencyOffset::units returned from + ///< ::ctlOverclockGetProperties() + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the Current Overclock Voltage Offset for the GPU +/// +/// @details +/// - Determine the current maximum voltage offset in effect on the hardware +/// (refer to ::ctlOverclockGpuMaxVoltageOffsetSetV2 for details). +/// - The unit of the value returned is given in +/// ::ctl_oc_properties_t::gpuVoltageOffset::units returned from +/// ::ctlOverclockGetProperties() +/// - The unit of the value returned can be different for different +/// generation of graphics product +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pOcMaxVoltageOffset` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockGpuMaxVoltageOffsetGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double* pOcMaxVoltageOffset ///< [in,out] Current Overclock GPU Voltage Offset in Units given in + ///< ::ctl_oc_properties_t::gpuVoltageOffset::units returned from + ///< ::ctlOverclockGetProperties() + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set the Overclock Voltage Offset for the GPU +/// +/// @details +/// - The purpose of this function is to attempt to run the GPU up to higher +/// voltages beyond the part warrantee limits. This can permit running at +/// even higher frequencies than can be obtained using the frequency +/// offset setting, but at the risk of reducing the lifetime of the part. +/// - The voltage offset is expressed in units given in +/// ::ctl_oc_properties_t::gpuVoltageOffset::units returned from +/// ::ctlOverclockGetProperties() +/// - The overclock waiver must be set before calling this function +/// otherwise error will be returned. +/// - There is no guarantee that a workload can operate at the higher +/// frequencies permitted by this setting. Significantly more heat will be +/// generated at these high frequencies/voltages which will necessitate a +/// good cooling solution. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockGpuMaxVoltageOffsetSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double ocFrequencyOffset ///< [in] The desired Memory Frequency in GT/s. + double ocMaxVoltageOffset ///< [in] The Overclocking Maximum Voltage Desired in units given in + ///< ::ctl_oc_properties_t::gpuVoltageOffset::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Get the Overclock Vram Voltage Offset in mV. +/// @brief Get the current Overclock Vram Memory Speed /// /// @details -/// - The purpose of this function is to increase/decrease the voltage of -/// VRAM. -/// - The voltage offset is expressed in units of millivolts with a minimum -/// step size given by ::ctlOverclockGetProperties. -/// - The waiver must be set using ::ctlOverclockWaiverSet before this -/// function can be called. -/// - This setting is not persistent through system reboots or driver -/// resets/hangs. It is up to the overclock application to reapply the -/// settings in those cases. -/// - This setting can cause system/device instability. It is up to the -/// overclock application to detect if the system has rebooted -/// unexpectedly or the device was restarted. When this occurs, the -/// application should not reapply the overclock settings automatically -/// but instead return to previously known good settings or notify the -/// user that the settings are not being applied. -/// - If the memory controller doesn't support changes to voltage on the -/// fly, one of the following return codes will be given: -/// - ::CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory -/// overclock will be applied when the device is reset or the system is -/// rebooted. In this case, the overclock software should check if the -/// overclock request was applied after the reset/reboot. If it was and -/// when the overclock application shuts down gracefully and if the -/// overclock application wants the setting to be persistent, the -/// application should request the same overclock settings again so that -/// they will be applied on the next reset/reboot. If this is not done, -/// then every time the device is reset and overclock is requested, the -/// device needs to be reset a second time. -/// - ::CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory -/// overclock will be applied when the system is rebooted. In this case, -/// the overclock software should check if the overclock request was -/// applied after the reboot. If it was and when the overclock application -/// shuts down gracefully and if the overclock application wants the -/// setting to be persistent, the application should request the same -/// overclock settings again so that they will be applied on the next -/// reset/reboot. If this is not done and the overclock setting is -/// requested after the reboot has occurred, a second reboot will be -/// required. +/// - The purpose of this function is to return the current VRAM Memory +/// Speed +/// - The unit of the value returned is given in +/// ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from +/// ::ctlOverclockGetProperties() +/// - The unit of the value returned can be different for different +/// generation of graphics product /// /// @returns /// - CTL_RESULT_SUCCESS @@ -6192,23 +7255,59 @@ ctlOverclockVramFrequencyOffsetSet( /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDeviceHandle` /// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pVoltage` +/// + `nullptr == pOcVramMemSpeedLimit` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockVramVoltageOffsetGet( +ctlOverclockVramMemSpeedLimitGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pVoltage ///< [out] The current locked voltage in mV. + double* pOcVramMemSpeedLimit ///< [in,out] The current VRAM Memory Speed in units given in + ///< ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Set the Overclock Vram Voltage Offset in mV. +/// @brief Set the desired Overclock Vram Memory Speed /// /// @details -/// - The purpose of this function is to set the maximum sustained power -/// limit. If the average GPU power averaged over a few seconds exceeds -/// this value, the frequency of the GPU will be throttled. -/// - Set a value of 0 to disable this power limit. In this case, the GPU -/// frequency will not throttle due to average power but may hit other -/// limits. +/// - The purpose of this function is to increase/decrease the Speed of +/// VRAM. +/// - The Memory Speed is expressed in units given in +/// ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from +/// ::ctlOverclockGetProperties() with a minimum step size given by +/// ::ctlOverclockGetProperties(). +/// - The actual Memory Speed for each workload is not guaranteed to change +/// exactly by the specified offset. +/// - This setting is not persistent through system reboots or driver +/// resets/hangs. It is up to the overclock application to reapply the +/// settings in those cases. +/// - This setting can cause system/device instability. It is up to the +/// overclock application to detect if the system has rebooted +/// unexpectedly or the device was restarted. When this occurs, the +/// application should not reapply the overclock settings automatically +/// but instead return to previously known good settings or notify the +/// user that the settings are not being applied. +/// - If the memory controller doesn't support changes to memory speed on +/// the fly, one of the following return codes will be given: +/// - CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED: The requested memory overclock +/// will be applied when the device is reset or the system is rebooted. In +/// this case, the overclock software should check if the overclock +/// request was applied after the reset/reboot. If it was and when the +/// overclock application shuts down gracefully and if the overclock +/// application wants the setting to be persistent, the application should +/// request the same overclock settings again so that they will be applied +/// on the next reset/reboot. If this is not done, then every time the +/// device is reset and overclock is requested, the device needs to be +/// reset a second time. +/// - CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED: The requested memory overclock +/// will be applied when the system is rebooted. In this case, the +/// overclock software should check if the overclock request was applied +/// after the reboot. If it was and when the overclock application shuts +/// down gracefully and if the overclock application wants the setting to +/// be persistent, the application should request the same overclock +/// settings again so that they will be applied on the next reset/reboot. +/// If this is not done and the overclock setting is requested after the +/// reboot has occurred, a second reboot will be required. +/// - CTL_RESULT_ERROR_UNSUPPORTED_FEATURE: The Memory Speed Get / Set +/// Feature is currently not available or Unsupported in current platform /// /// @returns /// - CTL_RESULT_SUCCESS @@ -6217,19 +7316,24 @@ ctlOverclockVramVoltageOffsetGet( /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDeviceHandle` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockVramVoltageOffsetSet( +ctlOverclockVramMemSpeedLimitSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double voltage ///< [in] The voltage to be locked in mV. + double ocVramMemSpeedLimit ///< [in] The desired Memory Speed in units given in + ///< ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Get the sustained power limit in mW. +/// @brief Get the Current Sustained power limit /// /// @details /// - The purpose of this function is to read the current sustained power /// limit. -/// - A value of 0 means that the limit is disabled - the GPU frequency can -/// run as high as possible until other limits are hit. +/// - The unit of the value returned is given in +/// ::ctl_oc_properties_t::powerLimit::units returned from +/// ::ctlOverclockGetProperties() +/// - The unit of the value returned can be different for different +/// generation of graphics product /// /// @returns /// - CTL_RESULT_SUCCESS @@ -6240,13 +7344,15 @@ ctlOverclockVramVoltageOffsetSet( /// - CTL_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pSustainedPowerLimit` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockPowerLimitGet( +ctlOverclockPowerLimitGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pSustainedPowerLimit ///< [in,out] The current sustained power limit in mW. + double* pSustainedPowerLimit ///< [in,out] The current Sustained Power limit in Units given in + ///< ::ctl_oc_properties_t::powerLimit::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Set the sustained power limit in mW. +/// @brief Set the Sustained power limit /// /// @details /// - The purpose of this function is to set the maximum sustained power @@ -6255,6 +7361,11 @@ ctlOverclockPowerLimitGet( /// - Set a value of 0 to disable this power limit. In this case, the GPU /// frequency will not throttle due to average power but may hit other /// limits. +/// - The unit of the PowerLimit to be set is given in +/// ::ctl_oc_properties_t::powerLimit::units returned from +/// ::ctlOverclockGetProperties() +/// - The unit of the value returned can be different for different +/// generation of graphics product /// /// @returns /// - CTL_RESULT_SUCCESS @@ -6263,16 +7374,24 @@ ctlOverclockPowerLimitGet( /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDeviceHandle` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockPowerLimitSet( +ctlOverclockPowerLimitSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double sustainedPowerLimit ///< [in] The desired sustained power limit in mW. + double sustainedPowerLimit ///< [in] The desired sustained power limit in Units given in + ///< ::ctl_oc_properties_t::powerLimit::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Get the current temperature limit in Celsius. +/// @brief Get the current temperature limit /// /// @details -/// - The purpose of this function is to read the current thermal limit. +/// - The purpose of this function is to read the current thermal limit used +/// for Overclocking +/// - The unit of the value returned is given in +/// ::ctl_oc_properties_t::temperatureLimit::units returned from +/// ::ctlOverclockGetProperties() +/// - The unit of the value returned can be different for different +/// generation of graphics product /// /// @returns /// - CTL_RESULT_SUCCESS @@ -6283,18 +7402,23 @@ ctlOverclockPowerLimitSet( /// - CTL_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pTemperatureLimit` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockTemperatureLimitGet( +ctlOverclockTemperatureLimitGetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double* pTemperatureLimit ///< [in,out] The current temperature limit in Celsius. + double* pTemperatureLimit ///< [in,out] The current temperature limit in Units given in + ///< ::ctl_oc_properties_t::temperatureLimit::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Set the temperature limit in Celsius. +/// @brief Set the temperature limit /// /// @details /// - The purpose of this function is to change the maximum thermal limit. /// When the GPU temperature exceeds this value, the GPU frequency will be /// throttled. +/// - The unit of the value to be set is given in +/// ::ctl_oc_properties_t::temperatureLimit::units returned from +/// ::ctlOverclockGetProperties() /// /// @returns /// - CTL_RESULT_SUCCESS @@ -6303,51 +7427,75 @@ ctlOverclockTemperatureLimitGet( /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDeviceHandle` CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockTemperatureLimitSet( +ctlOverclockTemperatureLimitSetV2( ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double temperatureLimit ///< [in] The desired temperature limit in Celsius. + double temperatureLimit ///< [in] The desired temperature limit in Units given in + ///< ::ctl_oc_properties_t::temperatureLimit::units returned from + ///< ::ctlOverclockGetProperties() ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Get Power Telemetry. +/// @brief Read VF Curve /// /// @details -/// - Limited rate of 50 ms, any call under 50 ms will return the same -/// information. +/// - Read the Voltage-Frequency Curve /// /// @returns /// - CTL_RESULT_SUCCESS /// - CTL_RESULT_ERROR_UNINITIALIZED /// - CTL_RESULT_ERROR_DEVICE_LOST /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDeviceHandle` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pTelemetryInfo` +/// + `nullptr == hDeviceAdapter` +/// - CTL_RESULT_ERROR_INVALID_ENUMERATION +/// + `::CTL_VF_CURVE_TYPE_LIVE < VFCurveType` +/// + `::CTL_VF_CURVE_DETAILS_ELABORATE < VFCurveDetail` +/// - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPowerTelemetryGet( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - ctl_power_telemetry_t* pTelemetryInfo ///< [out] The overclocking properties for the specified domain. +ctlOverclockReadVFCurve( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter + ctl_vf_curve_type_t VFCurveType, ///< [in] Type of Curve to read + ctl_vf_curve_details_t VFCurveDetail, ///< [in] Detail of Curve to read + uint32_t * pNumPoints, ///< [in][out] Number of points in the custom VF curve. If the NumPoints is + ///< zero, then the api will update the value with total number of Points + ///< based on requested VFCurveType and VFCurveDetail. If the NumPoints is + ///< non-zero, then the api will read and update the VF points in + ///< pVFCurveTable buffer provided. If the NumPoints doesn't match what the + ///< api returned in the first call, it will return an error. + ctl_voltage_frequency_point_t * pVFCurveTable ///< [in][out] Pointer to array of VF points, to copy the VF curve being + ///< read ); /////////////////////////////////////////////////////////////////////////////// -/// @brief Reset all Overclock Settings to stock +/// @brief Write Custom VF curve /// /// @details -/// - Reset all Overclock setting to default using single API call -/// - This request resets any changes made to GpuFrequencyOffset, -/// GpuVoltageOffset, PowerLimit, TemperatureLimit, GpuLock -/// - This Doesn't reset any Fan Curve Changes. It can be reset using -/// ctlFanSetDefaultMode +/// - Modify the Voltage-Frequency Curve used by GPU +/// - Valid Voltage-Frequency Curve shall have Voltage and Frequency Points +/// in increasing order +/// - Recommended to create Custom V-F Curve from reading Current V-F Curve +/// using ::ctlOverclockReadVFCurve (Read-Modify-Write) +/// - If Custom V-F curve write request is Successful, the Applied VF Curve +/// might be slightly different than what is originally requested, +/// recommended to update the UI by reading the V-F curve again using +/// ctlOverclockReadVFCurve (with ctl_vf_curve_type_t::LIVE as input) +/// - The overclock waiver must be set before calling this function +/// otherwise error will be returned. /// /// @returns /// - CTL_RESULT_SUCCESS /// - CTL_RESULT_ERROR_UNINITIALIZED /// - CTL_RESULT_ERROR_DEVICE_LOST /// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDeviceHandle` +/// + `nullptr == hDeviceAdapter` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCustomVFCurveTable` +/// - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockResetToDefault( - ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter +ctlOverclockWriteCustomVFCurve( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter + uint32_t NumPoints, ///< [in] Number of points in the custom VF curve + ctl_voltage_frequency_point_t* pCustomVFCurveTable ///< [in] Pointer to an array of VF Points containing 'NumPoints' Custom VF + ///< points ); @@ -7115,31 +8263,6 @@ typedef ctl_result_t (CTL_APICALL *ctl_pfnGetIntelArcSyncInfoForMonitor_t)( ); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumerateMuxDevices -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateMuxDevices_t)( - ctl_api_handle_t, - uint32_t*, - ctl_mux_output_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetMuxProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetMuxProperties_t)( - ctl_mux_output_handle_t, - ctl_mux_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSwitchMux -typedef ctl_result_t (CTL_APICALL *ctl_pfnSwitchMux_t)( - ctl_mux_output_handle_t, - ctl_display_output_handle_t - ); - - /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for ctlGetIntelArcSyncProfile typedef ctl_result_t (CTL_APICALL *ctl_pfnGetIntelArcSyncProfile_t)( @@ -7229,6 +8352,46 @@ typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetDynamicContrastEnhancement_t)( ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetWireFormat +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetWireFormat_t)( + ctl_display_output_handle_t, + ctl_get_set_wire_format_config_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetDisplaySettings +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetDisplaySettings_t)( + ctl_display_output_handle_t, + ctl_display_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEccGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnEccGetProperties_t)( + ctl_device_adapter_handle_t, + ctl_ecc_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEccGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnEccGetState_t)( + ctl_device_adapter_handle_t, + ctl_ecc_state_desc_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEccSetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnEccSetState_t)( + ctl_device_adapter_handle_t, + ctl_ecc_state_desc_t* + ); + + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for ctlEnumEngineGroups typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumEngineGroups_t)( @@ -7311,6 +8474,39 @@ typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetState_t)( ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetFirmwareProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetFirmwareProperties_t)( + ctl_device_adapter_handle_t, + ctl_firmware_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumerateFirmwareComponents +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateFirmwareComponents_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_firmware_component_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetFirmwareComponentProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetFirmwareComponentProperties_t)( + ctl_firmware_component_handle_t, + ctl_firmware_component_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlAllowPCIeLinkSpeedUpdate +typedef ctl_result_t (CTL_APICALL *ctl_pfnAllowPCIeLinkSpeedUpdate_t)( + ctl_device_adapter_handle_t, + bool + ); + + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for ctlEnumFrequencyDomains typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumFrequencyDomains_t)( @@ -7369,6 +8565,40 @@ typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetThrottleTime_t)( ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumLeds +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumLeds_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_led_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlLedGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnLedGetProperties_t)( + ctl_led_handle_t, + ctl_led_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlLedGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnLedGetState_t)( + ctl_led_handle_t, + ctl_led_state_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlLedSetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnLedSetState_t)( + ctl_led_handle_t, + void*, + uint32_t + ); + + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for ctlGetSupportedVideoProcessingCapabilities typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupportedVideoProcessingCapabilities_t)( @@ -7560,6 +8790,106 @@ typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockResetToDefault_t)( ); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuFrequencyOffsetGetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuFrequencyOffsetGetV2_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuFrequencyOffsetSetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuFrequencyOffsetSetV2_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuMaxVoltageOffsetGetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuMaxVoltageOffsetSetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockVramMemSpeedLimitGetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramMemSpeedLimitGetV2_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockVramMemSpeedLimitSetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramMemSpeedLimitSetV2_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockPowerLimitGetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockPowerLimitGetV2_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockPowerLimitSetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockPowerLimitSetV2_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockTemperatureLimitGetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockTemperatureLimitGetV2_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockTemperatureLimitSetV2 +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockTemperatureLimitSetV2_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockReadVFCurve +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockReadVFCurve_t)( + ctl_device_adapter_handle_t, + ctl_vf_curve_type_t, + ctl_vf_curve_details_t, + uint32_t *, + ctl_voltage_frequency_point_t * + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockWriteCustomVFCurve +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockWriteCustomVFCurve_t)( + ctl_device_adapter_handle_t, + uint32_t, + ctl_voltage_frequency_point_t* + ); + + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for ctlPciGetProperties typedef ctl_result_t (CTL_APICALL *ctl_pfnPciGetProperties_t)(